Commit 6bb448e9292bae32f3e6bce4dbe21fe34a38efb3

Authored by ailsoncgt
2 parents dd804021 f62d479d

Merge

Showing 48 changed files with 948 additions and 473 deletions   Show diff stats
courses/templates/category/create.html
... ... @@ -37,34 +37,46 @@
37 37 </ul>
38 38 </div>
39 39 </div>
  40 +
  41 + <div class="panel panel-primary navigation">
  42 + <div class="panel-heading">
  43 + <h3 class="panel-title">Category</h3>
  44 + </div>
  45 + <div class="panel-body">
  46 + <ul class="nav nav-pills nav-stacked">
  47 + <li><a href="{% url 'course:create_cat' %}">Create Category</a></li>
  48 + <li><a href="{% url 'course:manage_cat' %}">List Category</a></li>
  49 + </ul>
  50 + </div>
  51 + </div>
40 52 {% endif %}
41 53  
42 54 {% endblock %}
43 55  
44 56 {% block content %}
45   -
46   - <form method="post" action="">
47   - {% csrf_token %}
48   - {% for field in form %}
49   - <div class="form-group {% if form.has_error %}has-error{% endif %}">
50   - <label for="{{ field.auto_id }}">{{ field.label }}</label>
51   - {% render_field field class='form-control input-sm' %}
52   - </div>
53   - <span id="helpBlock" class="help-block">{{ field.help_text }}</span>
54   - {% if field.errors.length > 0 %}
55   - <div class="alert alert-danger alert-dismissible" role="alert">
56   - <button type="button" class="close" data-dismiss="alert" aria-label="Close">
57   - <span aria-hidden="true">&times;</span>
58   - </button>
59   - <ul>
60   - {% for error in field.errors %}
61   - <li>{{ error }}</li>
62   - {% endfor %}
63   - </ul>
64   - </div>
  57 + <div class="card card-content">
  58 + <div class="card-body">
  59 + <form method="post" action="">{% csrf_token %}
  60 + {% for field in form %}
  61 + <div class="form-group {% if form.has_error %}has-error{% endif %}">
  62 + <label for="{{ field.auto_id }}">{{ field.label }}</label>
  63 + {% render_field field class='form-control input-sm' %}
  64 + </div>
  65 + {% if field.errors.length > 0 %}
  66 + <div class="alert alert-danger alert-dismissible" role="alert">
  67 + <ul>
  68 + {% for error in field.errors %}
  69 + <li>{{ error }}</li>
  70 + {% endfor %}
  71 + </ul>
  72 + </div>
  73 + </div>
  74 + {% endif %}
  75 + {% endfor %}
  76 + <div class="row text-center">
  77 + <input type="submit" value="{% trans 'Save' %}" class="btn btn-sm btn-success" />
  78 + </div>
  79 + </form>
65 80 </div>
66   - {% endif %}
67   - {% endfor %}
68   - <input type="submit" value="{% trans 'Save' %}" class="btn btn-sm btn-success" />
69   - </form>
  81 + </div>
70 82 {% endblock %}
... ...
courses/templates/category/delete.html
1 1 {% extends 'app/base.html' %}
2 2  
3 3 {% load static i18n %}
  4 +{% load static i18n permission_tags %}
4 5  
5 6 {% block breadcrumbs %}
6 7 <ol class="breadcrumb">
... ... @@ -10,21 +11,54 @@
10 11 {% endblock %}
11 12  
12 13 {% block sidebar %}
13   - <div class="list-group">
14   - <a href="{% url 'course:manage_cat' %}" class="list-group-item active">
15   - {% trans 'Categories' %}
16   - </a>
17   - <a href="{% url 'course:create_cat' %}" class="list-group-item">
18   - {% trans 'Create Category' %}
19   - </a>
  14 + <div class="panel panel-primary navigation">
  15 + <div class="panel-heading">
  16 + <h5>{% trans 'Menu' %}</h5>
  17 + </div>
  18 + <div class="panel-body">
  19 + <ul class="nav nav-pills nav-stacked">
  20 + <li><a href="{% url 'users:profile' %}">{% trans 'Profile' %}</a></li>
  21 + <li><a href="{% url 'course:manage' %}">{% trans 'My Courses' %}</a></li>
  22 + </ul>
  23 + </div>
  24 + </div>
  25 +
  26 +{% if user|has_role:'professor, system_admin' %}
  27 +
  28 + <div class="panel panel-primary navigation">
  29 + <div class="panel-heading">
  30 + <h3 class="panel-title">Actions</h3>
  31 + </div>
  32 + <div class="panel-body">
  33 + <ul class="nav nav-pills nav-stacked">
  34 + <li><a href="javascript:void(0)">Replicate Course</a></li>
  35 + <li><a href="{% url 'course:create' %}">Create Course</a></li>
  36 + <li><a href="{% url 'course:create_cat' %}">Create Category</a></li>
  37 + </ul>
  38 + </div>
20 39 </div>
  40 + <div class="panel panel-primary navigation">
  41 + <div class="panel-heading">
  42 + <h3 class="panel-title">Category</h3>
  43 + </div>
  44 + <div class="panel-body">
  45 + <ul class="nav nav-pills nav-stacked">
  46 + <li><a href="{% url 'course:create_cat' %}">Create Category</a></li>
  47 + <li><a href="{% url 'course:manage_cat' %}">List Category</a></li>
  48 + </ul>
  49 + </div>
  50 + </div>
  51 +{% endif %}
21 52 {% endblock %}
22 53  
23 54 {% block content %}
24   - <form action="" method="post">
25   - {% csrf_token %}
26   - <p>{% trans 'Are you sure you want to delete the category' %} "{{ object }}"?</p>
27   - <input type="submit" class="btn btn-success btn-sm" value="{% trans 'Yes' %}" />
28   - <a href="{% url 'course:manage' %}" class="btn btn-danger btn-sm">{% trans 'No' %}</a>
29   - </form>
  55 + <div class="card card-content">
  56 + <div class="card-body">
  57 + <form action="" method="post">{% csrf_token %}
  58 + <h1>{% trans 'Are you sure you want to delete the category' %} "{{ object }}"?</h1>
  59 + <input type="submit" class="btn btn-success btn-sm" value="{% trans 'Yes' %}" />
  60 + <a href="{% url 'course:manage_cat' %}" class="btn btn-danger btn-sm">{% trans 'No' %}</a>
  61 + </form>
  62 + </div>
  63 + </div>
30 64 {% endblock %}
... ...
courses/templates/category/index.html
1 1 {% extends 'app/base.html' %}
2 2  
3 3 {% load static i18n %}
  4 +{% load static i18n permission_tags %}
  5 +{% load widget_tweaks %}
4 6  
5 7 {% block breadcrumbs %}
6 8 <ol class="breadcrumb">
... ... @@ -10,14 +12,45 @@
10 12 {% endblock %}
11 13  
12 14 {% block sidebar %}
13   - <div class="list-group">
14   - <a href="{% url 'course:manage_cat' %}" class="list-group-item active">
15   - {% trans 'Categories' %}
16   - </a>
17   - <a href="{% url 'course:create_cat' %}" class="list-group-item">
18   - {% trans 'Create Category' %}
19   - </a>
  15 + <div class="panel panel-primary navigation">
  16 + <div class="panel-heading">
  17 + <h5>{% trans 'Menu' %}</h5>
  18 + </div>
  19 + <div class="panel-body">
  20 + <ul class="nav nav-pills nav-stacked">
  21 + <li><a href="{% url 'users:profile' %}">{% trans 'Profile' %}</a></li>
  22 + <li><a href="{% url 'course:manage' %}">{% trans 'My Courses' %}</a></li>
  23 + </ul>
  24 + </div>
  25 + </div>
  26 +
  27 + {% if user|has_role:'professor, system_admin' %}
  28 +
  29 + <div class="panel panel-primary navigation">
  30 + <div class="panel-heading">
  31 + <h3 class="panel-title">Actions</h3>
  32 + </div>
  33 + <div class="panel-body">
  34 + <ul class="nav nav-pills nav-stacked">
  35 + <li><a href="javascript:void(0)">Replicate Course</a></li>
  36 + <li><a href="{% url 'course:create' %}">Create Course</a></li>
  37 + <li><a href="{% url 'course:create_cat' %}">Create Category</a></li>
  38 + </ul>
  39 + </div>
  40 + </div>
  41 +
  42 + <div class="panel panel-primary navigation">
  43 + <div class="panel-heading">
  44 + <h3 class="panel-title">Category</h3>
  45 + </div>
  46 + <div class="panel-body">
  47 + <ul class="nav nav-pills nav-stacked">
  48 + <li><a href="{% url 'course:create_cat' %}">Create Category</a></li>
  49 + <li><a href="{% url 'course:manage_cat' %}">List Category</a></li>
  50 + </ul>
  51 + </div>
20 52 </div>
  53 +{% endif %}
21 54 {% endblock %}
22 55  
23 56 {% block content %}
... ...
courses/templates/category/update.html
1 1 {% extends 'app/base.html' %}
2 2  
3 3 {% load static i18n %}
  4 +{% load static i18n permission_tags %}
4 5 {% load widget_tweaks %}
5 6  
6 7 {% block breadcrumbs %}
... ... @@ -11,43 +12,84 @@
11 12 {% endblock %}
12 13  
13 14 {% block sidebar %}
14   - <div class="list-group">
15   - <a href="{% url 'course:manage_cat' %}" class="list-group-item">
16   - {% trans 'Categories' %}
17   - </a>
  15 + <div class="panel panel-primary navigation">
  16 + <div class="panel-heading">
  17 + <h5>{% trans 'Menu' %}</h5>
  18 + </div>
  19 + <div class="panel-body">
  20 + <ul class="nav nav-pills nav-stacked">
  21 + <li><a href="{% url 'users:profile' %}">{% trans 'Profile' %}</a></li>
  22 + <li><a href="{% url 'course:manage' %}">{% trans 'My Courses' %}</a></li>
  23 + </ul>
  24 + </div>
  25 + </div>
  26 +
  27 +{% if user|has_role:'professor, system_admin' %}
  28 +
  29 + <div class="panel panel-primary navigation">
  30 + <div class="panel-heading">
  31 + <h3 class="panel-title">Actions</h3>
  32 + </div>
  33 + <div class="panel-body">
  34 + <ul class="nav nav-pills nav-stacked">
  35 + <li><a href="javascript:void(0)">Replicate Course</a></li>
  36 + <li><a href="{% url 'course:create' %}">Create Course</a></li>
  37 + <li><a href="{% url 'course:create_cat' %}">Create Category</a></li>
  38 + </ul>
  39 + </div>
  40 + </div>
  41 + <div class="panel panel-primary navigation">
  42 + <div class="panel-heading">
  43 + <h3 class="panel-title">Category</h3>
  44 + </div>
  45 + <div class="panel-body">
  46 + <ul class="nav nav-pills nav-stacked">
  47 + <li><a href="{% url 'course:create_cat' %}">Create Category</a></li>
  48 + <li><a href="{% url 'course:manage_cat' %}">List Category</a></li>
  49 + </ul>
  50 + </div>
18 51 </div>
  52 +{% endif %}
19 53 {% endblock %}
20 54  
21 55 {% block content %}
22   - <div class="alert alert-info alert-dismissible" role="alert">
23   - <button type="button" class="close" data-dismiss="alert" aria-label="Close">
24   - <span aria-hidden="true">&times;</span>
25   - </button>
26   - <p>{% trans 'All fields are required' %}</p>
27   - </div>
28   -
29   - <form method="post" action="">
30   - {% csrf_token %}
31   - {% for field in form %}
32   - <div class="form-group {% if form.has_error %}has-error{% endif %}">
33   - <label for="{{ field.auto_id }}">{{ field.label }}</label>
34   - {% render_field field class='form-control input-sm' %}
  56 + {% if messages %}
  57 + {% for message in messages %}
  58 + <div class="alert alert-success alert-dismissible" role="alert">
  59 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  60 + <span aria-hidden="true">&times;</span>
  61 + </button>
  62 + <p>{{ message }}</p>
35 63 </div>
36   - <span id="helpBlock" class="help-block">{{ field.help_text }}</span>
37   - {% if field.errors.length > 0 %}
38   - <div class="alert alert-danger alert-dismissible" role="alert">
39   - <button type="button" class="close" data-dismiss="alert" aria-label="Close">
40   - <span aria-hidden="true">&times;</span>
41   - </button>
42   - <ul>
43   - {% for error in field.errors %}
44   - <li>{{ error }}</li>
45   - {% endfor %}
46   - </ul>
47   - </div>
48   - </div>
49   - {% endif %}
50 64 {% endfor %}
51   - <input type="submit" value="{% trans 'Save' %}" class="btn btn-sm btn-success" />
52   - </form>
  65 + {% endif %}
  66 + <div class="card card-content">
  67 + <div class="card-body">
  68 + <form method="post" action="">
  69 + {% csrf_token %}
  70 + {% for field in form %}
  71 + <div class="form-group {% if form.has_error %}has-error{% endif %}">
  72 + <label for="{{ field.auto_id }}">{{ field.label }}</label>
  73 + {% render_field field class='form-control input-sm' %}
  74 + </div>
  75 + {% if field.errors.length > 0 %}
  76 + <div class="alert alert-danger alert-dismissible" role="alert">
  77 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  78 + <span aria-hidden="true">&times;</span>
  79 + </button>
  80 + <ul>
  81 + {% for error in field.errors %}
  82 + <li>{{ error }}</li>
  83 + {% endfor %}
  84 + </ul>
  85 + </div>
  86 + </div>
  87 + {% endif %}
  88 + {% endfor %}
  89 + <div class="row text-center">
  90 + <input type="submit" value="{% trans 'Save' %}" class="btn btn-sm btn-success" />
  91 + </div>
  92 + </form>
  93 + </div>
  94 + </div>
53 95 {% endblock %}
... ...
courses/templates/category/view.html
1 1 {% extends 'app/base.html' %}
2 2  
  3 +{% load static i18n permission_tags %}
  4 +{% load widget_tweaks %}
3 5 {% load static i18n %}
4 6  
  7 +
5 8 {% block breadcrumbs %}
6 9 <ol class="breadcrumb">
7 10 <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li>
... ... @@ -10,27 +13,57 @@
10 13 {% endblock %}
11 14  
12 15 {% block sidebar %}
13   - <div class="list-group">
14   - <a href="{% url 'course:manage_cat' %}" class="list-group-item">
15   - {% trans 'Categories' %}
16   - </a>
17   - <a href="{% url 'course:create_cat' %}" class="list-group-item">
18   - {% trans 'Create Category' %}
19   - </a>
20   - <a href="" class="list-group-item">
21   - {% trans 'Edit Category' %}
22   - </a>
23   - <a href="" class="list-group-item">
24   - {% trans 'Remove Category' %}
25   - </a>
26   - </div>
  16 + <div class="panel panel-primary navigation">
  17 + <div class="panel-heading">
  18 + <h5>{% trans 'Menu' %}</h5>
  19 + </div>
  20 + <div class="panel-body">
  21 + <ul class="nav nav-pills nav-stacked">
  22 + <li><a href="{% url 'users:profile' %}">{% trans 'Profile' %}</a></li>
  23 + <li><a href="{% url 'course:manage' %}">{% trans 'My Courses' %}</a></li>
  24 + </ul>
  25 + </div>
  26 + </div>
  27 + {% if user|has_role:'professor, system_admin' %}
  28 +
  29 + <div class="panel panel-primary navigation">
  30 + <div class="panel-heading">
  31 + <h3 class="panel-title">Actions</h3>
  32 + </div>
  33 + <div class="panel-body">
  34 + <ul class="nav nav-pills nav-stacked">
  35 + <li><a href="javascript:void(0)">Replicate Course</a></li>
  36 + <li><a href="{% url 'course:create' %}">Create Course</a></li>
  37 + <li><a href="{% url 'course:create_cat' %}">Create Category</a></li>
  38 + </ul>
  39 + </div>
  40 + </div>
  41 +
  42 + <div class="panel panel-primary navigation">
  43 + <div class="panel-heading">
  44 + <h3 class="panel-title">Category</h3>
  45 + </div>
  46 + <div class="panel-body">
  47 + <ul class="nav nav-pills nav-stacked">
  48 + <li><a href="{% url 'course:create_cat' %}">Create Category</a></li>
  49 + <li><a href="{% url 'course:manage_cat' %}">List Category</a></li>
  50 + <li><a href="{% url 'course:delete_cat' category.slug %}">Remove Category</a></li>
  51 + <li><a href="{% url 'course:update_cat' category.slug %}">Update Category</a></li>
  52 + </ul>
  53 + </div>
  54 + </div>
  55 + {% endif %}
27 56 {% endblock %}
28 57  
29 58 {% block content %}
30   - <div class="row">
31   - <div class="col-sm-12">
32   - <p><b>{% trans 'Name:' %} </b> {{ category }}</p>
33   - <p><b>{% trans 'Slug:' %} </b> {{ category.slug }}</p>
  59 + <div class="card card-content">
  60 + <div class="card-body">
  61 + <div class="row">
  62 + <div class="col-sm-12">
  63 + <p><b>{% trans 'Name:' %} </b> {{ category }}</p>
  64 + <p><b>{% trans 'Slug:' %} </b> {{ category.slug }}</p>
  65 + </div>
  66 + </div>
34 67 </div>
35 68 </div>
36 69 {% endblock %}
... ...
courses/templates/course/index.html
... ... @@ -33,7 +33,18 @@
33 33 <ul class="nav nav-pills nav-stacked">
34 34 <li><a href="javascript:void(0)">Replicate Course</a></li>
35 35 <li><a href="{% url 'course:create' %}">Create Course</a></li>
  36 + </ul>
  37 + </div>
  38 + </div>
  39 +
  40 + <div class="panel panel-primary navigation">
  41 + <div class="panel-heading">
  42 + <h3 class="panel-title">Category</h3>
  43 + </div>
  44 + <div class="panel-body">
  45 + <ul class="nav nav-pills nav-stacked">
36 46 <li><a href="{% url 'course:create_cat' %}">Create Category</a></li>
  47 + <li><a href="{% url 'course:manage_cat' %}">List Category</a></li>
37 48 </ul>
38 49 </div>
39 50 </div>
... ... @@ -55,40 +66,32 @@
55 66 {% endif %}
56 67  
57 68 <div class="col-md-12">
58   - <div class="input-group">
59   - <div class="form-group is-empty"><input type="search" class="form-control" placeholder="Search Courses"></div>
60   - <span class="input-group-btn input-group-sm">
61   - <button type="button" class="btn btn-fab btn-fab-mini">
62   - <i class="material-icons">search</i>
63   - </button>
64   - </span>
65   - </div>
  69 + <form id="searchform" action="{% url 'course:manage' %}" method="get" accept-charset="utf-8">
  70 + <div class="input-group">
  71 + <div class="form-group is-empty">
  72 + <input type="search" class="form-control" placeholder="Search Courses" name="q" id="searchbox"></div>
  73 + <span class="input-group-btn input-group-sm">
  74 + <button type="button" class="btn btn-fab btn-fab-mini">
  75 + <i class="material-icons">search</i>
  76 + </button>
  77 + </span>
  78 + </div>
  79 + </form>
66 80 </div>
67 81 <div class="col-md-12">
68   - {% if user|has_role:'professor, system_admin' %}
69   - <div class="btn-group btn-group-justified btn-group-raised">
70   - <a href="?category=all" class="btn btn-raised btn-info">Todos</a>
71   - {% for category_course in categorys_courses_professor %}
72   - <a href="?category={{category_course.name}}" class="btn btn-raised btn-primary">{{category_course.name}}</a>
73   - {% endfor %}
74   - </div>
75   - {% else%}
76   - <div class="btn-group btn-group-justified btn-group-raised">
77   - <a href="?category=all" class="btn btn-raised btn-info">Todos</a>
78   - {% for category_course in categorys_courses %}
79   - <a href="?category={{category_course.name}}" class="btn btn-raised btn-primary">{{category_course.name}}</a>
80   - {% endfor %}
81   - </div>
82   - {% endif %}
  82 + <div class="btn-group btn-group-justified btn-group-raised">
  83 + <a href="?category=all" class="btn btn-raised btn-info">Todos</a>
  84 + {% for category_course in categorys_courses %}
  85 + <a href="?category={{category_course.name}}" class="btn btn-raised btn-primary">{{category_course.name}}</a>
  86 + {% endfor %}
  87 + </div>
83 88 </div>
84 89  
85 90 </fieldset>
86   -{% if user|has_role:'professor, system_admin' %}
87 91 <div class="col-md-12">
88 92 {% if courses|length > 0 %}
89 93 {% if request.GET.category == 'all' or none or request.GET.category == '' %}
90   - {% for course in courses_teacher %}
91   - <!-- Put your content here! -->
  94 + {% for course in list_courses %}
92 95 <div class="panel-group ui-accordion ui-widget ui-helper-reset ui-sortable" id="accordion" role="tablist" aria-multiselectable="false">
93 96 <div class="group">
94 97 <div class="panel panel-info">
... ... @@ -101,12 +104,6 @@
101 104 </div>
102 105 <div class="col-xs-4 col-md-3" id="divMoreActions">
103 106 <div class="btn-group">
104   - <button type="button" class="btn btn-default btn-sm eye" data-toggle="tooltip" data-placement="bottom" title="Visible">
105   - <i class="fa fa-eye fa-2x" aria-hidden="true"></i>
106   - </button>
107   -
108   - </div>
109   - <div class="btn-group">
110 107 <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
111 108 <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i>
112 109 </button>
... ... @@ -137,7 +134,7 @@
137 134 </div>
138 135 {% endfor %}
139 136 {% else %}
140   - {% for course in courses_teacher %}
  137 + {% for course in courses_category %}
141 138 {% if course.category.name == request.GET.category %}
142 139 <!-- Put your content here! -->
143 140 <div class="panel-group ui-accordion ui-widget ui-helper-reset ui-sortable" id="accordion" role="tablist" aria-multiselectable="false">
... ... @@ -210,125 +207,28 @@
210 207 </div>
211 208 </div>
212 209 </div>
213   - </div>
214 210 </div>
215 211 </div>
216   -{% else %}
217   - {% if courses|length > 0 %}
218   - {% if request.GET.category == 'all' or none or request.GET.category == '' %}
219   - {% for course in courses_student %}
220   - <div class="col-md-12">
221   - <div class="panel panel-info">
222   - <!--{% if course.image %}
223   - <img src="{{ course.image_url }}" class="img-responsive" />
224   - {% else %}
225   - <img src="" class="img-responsive" />
226   - {% endif %} -->
227   - <div class="panel-heading">
228   - <div class="row">
229   - <div class="col-md-9">
230   - <h3 class="panel-title">{{course.name}}</h3>
231   - </div>
232   - <div class="col-md-3">
233   - <span class="label label-info">{{ course.category }}</span>
234   - <span class="label label-warning">{{ course.max_students }} {% trans 'students tops' %}</span>
235   - </div>
236   - </div>
237   - </div>
238   - <div class="panel-body">
239   - <p><b>Course Name: </b>{{ course.name }}</p>
240   - <p><b>Duration (in semesters): </b>09</p>
241   - <p><b>Coordinator: </b>{{course.professors}}</p>
242   - <p>
243   - <b>Description:</b>
244   - <i>
245   - {% if couse.description %}
246   - {{course.description|linebreaks}}
247   - {% else %}
248   - {% trans 'No description' %}
249   - {% endif %}
250   - </i>
251   - </p>
252   -
253   - <!--{% if user|has_role:'professor, system_admin' %}
254   - <a href="{% url 'course:update' course.slug %}" class="btn btn-sm btn-primary">
255   - <span class="glyphicon glyphicon-edit"></span>
256   - </a>
257   - <a href="{% url 'course:delete' course.slug %}" class="btn btn-sm btn-danger">
258   - <span class="glyphicon glyphicon-trash"></span>
259   - </a>
260   - {% endif %}-->
261   -
262   - <a href="{% url 'course:view' course.slug %}" class="btn btn-raised btn-default center-block">View Course</a>
263   - </div>
264   - </div>
265   - </div>
266   - {% endfor %}
267   - {% else %}
268   - {% for course in courses_student %}
269   - {% if course.category.name == request.GET.category %}
270   - <div class="col-md-12">
271   - <div class="panel panel-info">
272   - <!--{% if course.image %}
273   - <img src="{{ course.image_url }}" class="img-responsive" />
274   - {% else %}
275   - <img src="" class="img-responsive" />
276   - {% endif %} -->
277   - <div class="panel-heading">
278   - <div class="row">
279   - <div class="col-md-9">
280   - <h3 class="panel-title">{{course.name}}</h3>
281   - </div>
282   - <div class="col-md-3">
283   - <span class="label label-info">{{ course.category }}</span>
284   - <span class="label label-warning">{{ course.max_students }} {% trans 'students tops' %}</span>
285   - </div>
286   - </div>
287   - </div>
288   - <div class="panel-body">
289   - <p><b>Course Name: </b>{{ course.name }}</p>
290   - <p><b>Duration (in semesters): </b>09</p>
291   - <p><b>Coordinator: </b>{{course.professors}}</p>
292   - <p>
293   - <b>Description:</b>
294   - <i>
295   - {% if couse.description %}
296   - {{course.description|linebreaks}}
297   - {% else %}
298   - {% trans 'No description' %}
299   - {% endif %}
300   - </i>
301   - </p>
302   -
303   - <!--{% if user|has_role:'professor, system_admin' %}
304   - <a href="{% url 'course:update' course.slug %}" class="btn btn-sm btn-primary">
305   - <span class="glyphicon glyphicon-edit"></span>
306   - </a>
307   - <a href="{% url 'course:delete' course.slug %}" class="btn btn-sm btn-danger">
308   - <span class="glyphicon glyphicon-trash"></span>
309   - </a>
310   - {% endif %}-->
311   -
312   - <a href="{% url 'course:view' course.slug %}" class="btn btn-raised btn-default center-block">View Course</a>
313   - </div>
314   - </div>
315   - </div>
  212 + </div>
  213 + <div class="col-md-12">
  214 + <nav aria-label="Page navigation">
  215 + <ul class="pagination">
  216 + {% if page_obj.has_previous %}
  217 + <li>
  218 + <a href="?page={{ page_obj.previous_page_number }}"><span><<</span></a>
  219 + </li>
316 220 {% endif %}
317   - {% endfor %}
318   - {% endif %}
319   -
320   - <nav aria-label="Page navigation">
321   - <ul class="pagination">
322   - {% for page_number in paginator.page_range %}
323   - <li{% if page_obj.number == page_number %} class="active"{% endif %}>
324   - <a href="?page={{ page_number }}">{{ page_number }}</a>
325   - </li>
326   - {% endfor %}
327   - </ul>
  221 + {% for page_number in paginator.page_range %}
  222 + <li{% if page_obj.number == page_number %} class="active"{% endif %}>
  223 + <a href="?page={{ page_number }}">{{ page_number }}</a>
  224 + </li>
  225 + {% endfor %}
  226 + {% if page_obj.has_next %}
  227 + <li>
  228 + <a href="?page={{ page_obj.next_page_number }}"><span>>></span></a>
  229 + </li>
  230 + {% endif %}
  231 + </ul>
328 232 </nav>
329   - {% else %}
330   - {% trans 'No courses found' %}
331   - {% endif %}
332   -{% endif %}
333   -
  233 + </div>
334 234 {% endblock %}
... ...
courses/templates/course/view.html
... ... @@ -55,19 +55,21 @@
55 55 <div class="col-xs-8 col-md-10 titleTopic">
56 56 <h4>{{course}}</h4>
57 57 </div>
58   - <div class="col-xs-4 col-md-2" id="divMoreActions">
59   - <div class="btn-group">
60   - <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
61   - <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i>
62   - <div class="ripple-container"></div></button>
63   - <ul class="dropdown-menu" aria-labelledby="moreActions">
64   - <li><a href="javascript:void(0)" data-toggle="modal" data-target="#createSubject"><i class="fa fa-plus-square-o" aria-hidden="true"></i>&nbsp; Create Subject</a></li>
65   - <li><a href="javascript:void(0)" data-toggle="modal" data-target="#myModal4"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i>&nbsp; Replicate</a></li>
66   - <li><a href="{% url 'course:update' course.slug %}"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i>&nbsp; Edit</a></li>
67   - <li><a href="javascript:void(0)" data-toggle="modal" data-target="#myModal2"><i class="fa fa-trash fa-fw" aria-hidden="true"></i>&nbsp; Remove</a></li>
68   - </ul>
  58 + {% if user|has_role:'professor, system_admin' %}
  59 + <div class="col-xs-4 col-md-2" id="divMoreActions">
  60 + <div class="btn-group">
  61 + <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  62 + <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i>
  63 + <div class="ripple-container"></div></button>
  64 + <ul class="dropdown-menu" aria-labelledby="moreActions">
  65 + <li><a href="javascript:void(0)" data-toggle="modal" data-target="#createSubject"><i class="fa fa-plus-square-o" aria-hidden="true"></i>&nbsp; Create Subject</a></li>
  66 + <li><a href="javascript:void(0)" data-toggle="modal" data-target="#myModal4"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i>&nbsp; Replicate</a></li>
  67 + <li><a href="{% url 'course:update' course.slug %}"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i>&nbsp; Edit</a></li>
  68 + <li><a href="javascript:void(0)" data-toggle="modal" data-target="#myModal2"><i class="fa fa-trash fa-fw" aria-hidden="true"></i>&nbsp; Remove</a></li>
  69 + </ul>
  70 + </div>
69 71 </div>
70   - </div>
  72 + {% endif %}
71 73 </div>
72 74 </div>
73 75 <div class="panel-body">
... ...
courses/templates/subject/form_view_student.html
... ... @@ -17,7 +17,8 @@
17 17 </div>
18 18 <div class="panel-body">
19 19 <p>{{topic.description|linebreaks}}</p>
20   - {% list_topic_foruns request topic %}
  20 + {% list_topic_foruns request topic %}
  21 + {% list_topic_poll request topic %}
21 22 </div>
22 23  
23 24 <div class="modal fade" id="forumModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
... ... @@ -37,4 +38,4 @@
37 38 </div>
38 39 </div>
39 40 </div>
40   -</div>
41 41 \ No newline at end of file
  42 +</div>
... ...
courses/templates/subject/form_view_teacher.html
1   -{% load static i18n list_topic_foruns %}
  1 +{% load static i18n list_topic_foruns%}
2 2  
3 3 {% block javascript %}
4 4 <script type="text/javascript" src="{% static 'js/forum.js' %}"></script>
... ... @@ -15,9 +15,11 @@
15 15 </div>
16 16 <div class="col-xs-3 col-md-2 divMoreActions">
17 17 <div class="btn-group">
18   - <button type="button" class="btn btn-default btn-sm eye" data-toggle="tooltip" data-placement="bottom" title="Visible">
  18 + <a href="{% url 'course:view_topic' topic.slug %}">
  19 + <button type="button" class="btn btn-default btn-sm eye" data-toggle="tooltip" data-placement="bottom" title="Visible">
19 20 <i class="fa fa-eye fa-2x" aria-hidden="true"></i>
20   - </button>
  21 + </button>
  22 + </a>
21 23 </div>
22 24 <div class="btn-group">
23 25 <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
... ... @@ -54,6 +56,7 @@
54 56 <ul>
55 57 <li><i class="material-icons">description</i> <a href="#" data-toggle="modal" data-target="#ActivityModal">Activitie 1</a></li>
56 58 <li><i class="material-icons">list</i> <a href="#" data-toggle="modal" data-target="#forumModal">Forum</a></li>
  59 + {% list_topic_poll request topic %}
57 60 </ul>
58 61  
59 62  
... ... @@ -426,7 +429,7 @@
426 429 </div>
427 430 <div class="modal-body">
428 431 <form class="form-horizontal">
429   -
  432 +
430 433 <fieldset>
431 434 <legend>Atividade Proposta</legend>
432 435 <div class="form-group is-empty">
... ... @@ -660,4 +663,4 @@
660 663 </div>
661 664 </div>
662 665 </div>
663   -</div>
664 666 \ No newline at end of file
  667 +</div>
... ...
courses/templates/subject/index.html
... ... @@ -36,16 +36,11 @@
36 36 <div class="panel panel-info">
37 37 <div class="panel-heading">
38 38 <div class="row">
39   - <div class="col-md-9 col-sm-7">
  39 + <div class="col-md-9 col-sm-9">
40 40 <h3>{{subject}}</h3>
41 41 </div>
42   - <div class="col-xs-4 col-md-3 divMoreActions">
43   - <div class="btn-group">
44   - <button type="button" class="btn btn-default btn-sm eye" data-toggle="tooltip" data-placement="bottom" title="Visible">
45   - <i class="fa fa-eye fa-2x" aria-hidden="true"></i>
46   - </button>
47   - </div>
48   - {% if user|has_role:'system_admin' or user in subject.professors %}
  42 + {% if user|has_role:'system_admin' or user in subject.professors %}
  43 + <div class="col-xs-4 col-md-3 divMoreActions">
49 44 <div class="btn-group">
50 45 <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
51 46 <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i>
... ... @@ -56,8 +51,8 @@
56 51 <li><a href="{% url 'course:delete_subject' subject.slug %}" data-toggle="modal" data-target="#removeSubject"><i class="fa fa-trash fa-fw" aria-hidden="true"></i>&nbsp; {% trans "Remove" %}</a></li>
57 52 </ul>
58 53 </div>
59   - {% endif %}
60   - </div>
  54 + </div>
  55 + {% endif %}
61 56 </div>
62 57 </div>
63 58 <div class="panel-body">
... ...
courses/templates/subject/poll_item_actions.html 0 → 100644
... ... @@ -0,0 +1,18 @@
  1 +{% load static i18n permission_tags%}
  2 +
  3 +<script src="{% static 'js/modals_requisitions.js'%}"></script>
  4 +<script src="{% static 'js/modal_poll.js'%}"></script>
  5 +
  6 +{% if request.user|has_role:'professor, system_admin'%}
  7 +{% for poll in polls %}
  8 + <li id="poll_{{poll.slug}}"><i class="material-icons">poll</i> <a href="javascript:get('{% url 'course:poll:update_poll' poll.slug %}','#poll','#modal_poll');">{{ poll.name }}</a><a href="javascript:get('{% url 'course:poll:delete_poll' poll.slug %}','#poll','#modal_poll');"><span class="glyphicon glyphicon-remove"></span></a></li>
  9 +{% endfor %}
  10 +<button class="btn btn-primary btn-raised" onclick="javascript:get('{% url 'course:poll:create_poll' topic.slug%}','#poll','#modal_poll');">{% trans '+ Create Poll' %}</button>
  11 +{% else %}
  12 +{% for poll in polls %}
  13 + <li id="poll_{{poll.slug}}"><i class="material-icons">poll</i> <a href="javascript:get('{% url 'course:poll:view_poll' poll.slug %}','#poll','#modal_poll');">{{ poll.name }}</a></li>
  14 +{% endfor %}
  15 +{% endif %}
  16 +<div class="row" id="modal_poll">
  17 +
  18 +</div>
... ...
courses/templates/topic/index.html
... ... @@ -12,7 +12,7 @@
12 12 {% else %}
13 13 <li class="active">{{ topic.name }}</li>
14 14 {% endif %}
15   -
  15 +
16 16 </ol>
17 17 {% endblock %}
18 18  
... ... @@ -103,7 +103,7 @@
103 103 <div class="panel-body">
104 104 <div class="row">
105 105 <div class="col-md-4">
106   - <i class="fa fa-file-archive-o fa-lg" aria-hidden="true">Atividade.doc</i>
  106 + <i class="fa fa-file-archive-o fa-lg" aria-hidden="true">Atividade.doc</i>
107 107 </div>
108 108 {% if user|has_role:'professor, system_admin' %}
109 109 <div class="col-md-4">
... ...
courses/templatetags/list_topic_foruns.py
1 1 from django import template
2 2  
3 3 from forum.models import Forum
4   -
  4 +from poll.models import Poll
5 5 register = template.Library()
6 6  
7 7 """
... ... @@ -16,4 +16,15 @@ def list_topic_foruns(request, topic):
16 16  
17 17 context['foruns'] = Forum.objects.filter(topic = topic)
18 18  
19   - return context
20 19 \ No newline at end of file
  20 + return context
  21 +
  22 +@register.inclusion_tag('subject/poll_item_actions.html')
  23 +def list_topic_poll(request, topic):
  24 + context = {
  25 + 'request': request,
  26 + }
  27 +
  28 + context['polls'] = Poll.objects.filter(topic = topic)
  29 + context['topic'] = topic
  30 +
  31 + return context
... ...
courses/urls.py
1 1 from django.conf.urls import url, include
2 2  
3 3 from . import views
  4 +from links import views as linkviews
4 5 urlpatterns = [
5 6 url(r'^$', views.IndexView.as_view(), name='manage'),
6 7 url(r'^create/$', views.CreateCourseView.as_view(), name='create'),
... ... @@ -19,9 +20,10 @@ urlpatterns = [
19 20 url(r'^subjects/delete/(?P<slug>[\w_-]+)/$', views.DeleteSubjectView.as_view(), name='delete_subject'),
20 21 url(r'^topics/create/(?P<slug>[\w_-]+)/$', views.CreateTopicView.as_view(), name='create_topic'),
21 22 url(r'^topics/update/(?P<slug>[\w_-]+)/$', views.UpdateTopicView.as_view(), name='update_topic'),
  23 + url(r'^topics/createlink/$', linkviews.CreateLink.as_view(),name = 'create_link'),
  24 + url(r'^topics/deletelink/(?P<linkname>[\w_-]+)/$', linkviews.deleteLink,name = 'delete_link'),
22 25 url(r'^topics/(?P<slug>[\w_-]+)/$', views.TopicsView.as_view(), name='view_topic'),
23 26 url(r'^subjects/categories$',views.IndexSubjectCategoryView.as_view(), name='subject_category_index'),
24   - url(r'^topics/update/(?P<slug>[\w_-]+)/createlink/', include('links.urls',namespace='links')),
25 27 url(r'^forum/', include('forum.urls', namespace = 'forum')),
26 28 url(r'^poll/', include('poll.urls', namespace = 'poll')),
27 29  
... ...
courses/views.py
... ... @@ -2,7 +2,7 @@ from django.shortcuts import render, get_object_or_404, redirect
2 2 from django.views import generic
3 3 from django.contrib import messages
4 4 from django.contrib.auth.decorators import login_required
5   -from django.core.paginator import Paginator, EmptyPage
  5 +from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
6 6 from django.contrib.auth.mixins import LoginRequiredMixin
7 7 from rolepermissions.mixins import HasRoleMixin
8 8 from django.core.urlresolvers import reverse_lazy
... ... @@ -10,6 +10,7 @@ from django.utils.translation import ugettext_lazy as _
10 10 from rolepermissions.verifications import has_role
11 11 from django.db.models import Q
12 12 from rolepermissions.verifications import has_object_permission
  13 +from django.http import HttpResponseRedirect
13 14  
14 15 from .forms import CourseForm, UpdateCourseForm, CategoryCourseForm, SubjectForm,TopicForm,ActivityForm
15 16 from .models import Course, Subject, CourseCategory,Topic, SubjectCategory,Activity
... ... @@ -25,23 +26,41 @@ class IndexView(LoginRequiredMixin, NotificationMixin, generic.ListView):
25 26 queryset = Course.objects.all()
26 27 template_name = 'course/index.html'
27 28 context_object_name = 'courses'
28   - paginate_by = 3
  29 + paginate_by = 2
29 30  
30 31 def get_context_data(self, **kwargs):
31 32 context = super(IndexView, self).get_context_data(**kwargs)
32   - context['categories'] = CourseCategory.objects.all()
33   - context['courses_teacher'] = Course.objects.filter(professors__name = self.request.user.name)
34   - context['courses_student'] = Course.objects.filter(students__name = self.request.user.name)
35   - context['categorys_courses'] = CourseCategory.objects.filter(course_category__students__name = self.request.user.name).distinct()
36   - context['categorys_courses_professor'] = CourseCategory.objects.filter(course_category__professors__name = self.request.user.name).distinct()
  33 + list_courses = None
  34 + categorys_courses = None
  35 + if has_role(self.request.user,'professor') or has_role(self.request.user,'system_admin'):
  36 + list_courses = Course.objects.filter(professors__name = self.request.user.name)
  37 + categorys_courses = CourseCategory.objects.filter(course_category__professors__name = self.request.user.name).distinct()
  38 + else:
  39 + list_courses = Course.objects.filter(students__name = self.request.user.name)
  40 + categorys_courses = CourseCategory.objects.filter(course_category__students__name = self.request.user.name).distinct()
  41 +
37 42 courses_category = Course.objects.filter(category__name = self.request.GET.get('category'))
38   - context['courses_category'] = courses_category
  43 +
39 44 none = None
40 45 q = self.request.GET.get('category', None)
41 46 if q is None:
42 47 none = True
43 48 context['none'] = none
44 49  
  50 + paginator = Paginator(list_courses, self.paginate_by)
  51 + page = self.request.GET.get('page')
  52 +
  53 + try:
  54 + list_courses = paginator.page(page)
  55 + except PageNotAnInteger:
  56 + list_courses = paginator.page(1)
  57 + except EmptyPage:
  58 + list_courses = paginator.page(paginator.num_pages)
  59 +
  60 + context['courses_category'] = courses_category
  61 + context['list_courses'] = list_courses
  62 + context['categorys_courses'] = categorys_courses
  63 +
45 64 return context
46 65  
47 66 class CreateCourseView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,generic.edit.CreateView):
... ... @@ -215,6 +234,10 @@ class CreateCatView(LoginRequiredMixin, HasRoleMixin, generic.edit.CreateView):
215 234 form_class = CategoryCourseForm
216 235 success_url = reverse_lazy('course:manage_cat')
217 236  
  237 + def get_success_url(self):
  238 + messages.success(self.request, _('Category created successfully!'))
  239 + return reverse_lazy('course:manage_cat')
  240 +
218 241 class UpdateCatView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView):
219 242  
220 243 allowed_roles = ['professor', 'system_admin']
... ... @@ -223,7 +246,10 @@ class UpdateCatView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView):
223 246 template_name = 'category/update.html'
224 247 model = CourseCategory
225 248 form_class = CategoryCourseForm
226   - success_url = reverse_lazy('course:manage_cat')
  249 +
  250 + def get_success_url(self):
  251 + messages.success(self.request, _('Category updated successfully!'))
  252 + return reverse_lazy('course:update_cat', kwargs={'slug' : self.object.slug})
227 253  
228 254 class ViewCat(LoginRequiredMixin, generic.DetailView):
229 255 login_url = reverse_lazy("core:home")
... ... @@ -239,12 +265,10 @@ class DeleteCatView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView):
239 265 redirect_field_name = 'next'
240 266 model = CourseCategory
241 267 template_name = 'category/delete.html'
242   - success_url = reverse_lazy('course:manage_cat')
243 268  
244   - def render_to_response(self, context, **response_kwargs):
  269 + def get_success_url(self):
245 270 messages.success(self.request, _('Category deleted successfully!'))
246   -
247   - return self.response_class(request=self.request, template=self.get_template_names(), context=context, using=self.template_engine)
  271 + return reverse_lazy('course:manage_cat')
248 272  
249 273 class SubjectsView(LoginRequiredMixin, generic.ListView):
250 274  
... ...
files/__init__.py 0 → 100644
files/admin.py 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +from django.contrib import admin
  2 +
  3 +# Register your models here.
... ...
files/apps.py 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +from django.apps import AppConfig
  2 +
  3 +
  4 +class FilesConfig(AppConfig):
  5 + name = 'files'
... ...
files/migrations/__init__.py 0 → 100644
files/models.py 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +from django.db import models
  2 +from django.utils.translation import ugettext_lazy as _
  3 +
  4 +from courses.models import Activity
  5 +
  6 +"""
  7 + Function to return the path where the file should be saved
  8 +"""
  9 +def file_path(instance, filename):
  10 + return '/'.join([instance.topic.subject.course.slug, instance.topic.subject.slug, instance.topic.slug, filename])
  11 +
  12 +
  13 +"""
  14 + It's one kind of activity available for a Topic.
  15 + It's like a support material for the students.
  16 +"""
  17 +class TopicFiles(Activity):
  18 + file_url = models.FileField(verbose_name = _("File"), upload_to = file_path)
  19 +
  20 + class Meta:
  21 + verbose_name = _("File")
  22 + verbose_name_plural = _("Files")
  23 +
  24 + def __str__(self):
  25 + return self.name
0 26 \ No newline at end of file
... ...
files/tests.py 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +from django.test import TestCase
  2 +
  3 +# Create your tests here.
... ...
files/views.py 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +from django.shortcuts import render
  2 +
  3 +# Create your views here.
... ...
forum/static/js/forum.js
... ... @@ -46,7 +46,7 @@ $(document).ready(function (){
46 46  
47 47 /*
48 48 *
49   -* Function to load create forum's form and set the submit function
  49 +* Function to load create forum's form
50 50 *
51 51 */
52 52 function createForum(url, topic) {
... ... @@ -57,35 +57,45 @@ function createForum(url, topic) {
57 57 $(".forum_form").html(data);
58 58 $("#id_topic").val(topic);
59 59  
60   - $('.date-picker').datepicker({
61   - format: 'dd/mm/yyyy',
62   - });
  60 + setForumCreateFormSubmit();
  61 + }
  62 + });
63 63  
64   - var frm = $('#forum_create');
65   - frm.submit(function () {
66   - $.ajax({
67   - type: frm.attr('method'),
68   - url: frm.attr('action'),
69   - data: frm.serialize(),
70   - success: function (data) {
71   - data = data.split('-');
  64 + $("#createForum").modal();
  65 +}
72 66  
73   - $('.foruns_list').append("<a id='forum_"+data[1]+"' href='"+data[0]+"'>"+data[2]+"<br /></a>");
  67 +/*
  68 +*
  69 +* Function to set the forum's create form submit function
  70 +*
  71 +*/
  72 +function setForumCreateFormSubmit() {
  73 + $('.date-picker').datepicker({
  74 + format: 'dd/mm/yyyy',
  75 + });
74 76  
75   - $("#createForum").modal('hide');
  77 + var frm = $('#forum_create');
  78 + frm.submit(function () {
  79 + $.ajax({
  80 + type: frm.attr('method'),
  81 + url: frm.attr('action'),
  82 + data: frm.serialize(),
  83 + success: function (data) {
  84 + data = data.split('-');
76 85  
77   - showForum(data[0], data[1]);
78   - },
79   - error: function(data) {
80   - $(".forum_form").html(data.responseText);
81   - }
82   - });
83   - return false;
84   - });
85   - }
86   - });
  86 + $('.foruns_list').append("<a id='forum_"+data[1]+"' href='"+data[0]+"'>"+data[2]+"<br /></a>");
87 87  
88   - $("#createForum").modal();
  88 + $("#createForum").modal('hide');
  89 +
  90 + showForum(data[0], data[1]);
  91 + },
  92 + error: function(data) {
  93 + $(".forum_form").html(data.responseText);
  94 + setForumCreateFormSubmit();
  95 + }
  96 + });
  97 + return false;
  98 + });
89 99 }
90 100  
91 101 /*
... ... @@ -100,29 +110,7 @@ function editForum(url, forum, success_message) {
100 110 success: function(data) {
101 111 $(".forum_form").html(data);
102 112  
103   - $('.date-picker').datepicker({
104   - format: 'dd/mm/yyyy',
105   - });
106   -
107   - var frm = $('#forum_create');
108   - frm.submit(function () {
109   - $.ajax({
110   - type: frm.attr('method'),
111   - url: frm.attr('action'),
112   - data: frm.serialize(),
113   - success: function (data) {
114   - $('.forum_view').html(data);
115   -
116   - alertify.success(success_message);
117   -
118   - $("#editForum").modal('hide');
119   - },
120   - error: function(data) {
121   - $(".forum_form").html(data.responseText);
122   - }
123   - });
124   - return false;
125   - });
  113 + setForumUpdateFormSubmit(success_message);
126 114 }
127 115 });
128 116  
... ... @@ -131,6 +119,39 @@ function editForum(url, forum, success_message) {
131 119  
132 120 /*
133 121 *
  122 +* Function to set the forum's update form submit function
  123 +*
  124 +*/
  125 +function setForumUpdateFormSubmit(success_message) {
  126 + $('.date-picker').datepicker({
  127 + format: 'dd/mm/yyyy',
  128 + });
  129 +
  130 + var frm = $('#forum_create');
  131 + frm.submit(function () {
  132 + $.ajax({
  133 + type: frm.attr('method'),
  134 + url: frm.attr('action'),
  135 + data: frm.serialize(),
  136 + success: function (data) {
  137 + $('.forum_view').html(data);
  138 +
  139 + alertify.success(success_message);
  140 +
  141 + $("#editForum").modal('hide');
  142 + },
  143 + error: function(data) {
  144 + $(".forum_form").html(data.responseText);
  145 +
  146 + setForumUpdateFormSubmit(success_message);
  147 + }
  148 + });
  149 + return false;
  150 + });
  151 +}
  152 +
  153 +/*
  154 +*
134 155 * Function to delete a forum
135 156 *
136 157 */
... ...
forum/templates/forum/forum_view.html
... ... @@ -50,7 +50,7 @@
50 50 {% endblock %}
51 51  
52 52 {% block content %}
53   - <div class="row panel panel-default">
  53 + <div class="panel panel-default">
54 54 <div class="panel-body">
55 55 <div class="comments-list">
56 56 <div class="section-heading forum_view">
... ...
forum/templates/post/post_list.html
... ... @@ -16,7 +16,7 @@
16 16 <a class="btn btn-default btn-xs dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
17 17 <i class="material-icons">more_horiz</i>
18 18 </a>
19   - <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
  19 + <ul class="dropdown-menu pull-right" aria-labelledby="dropdownMenu1">
20 20 <li><a href="javascript:edit_post('{% url 'course:forum:update_post' post.id %}', '{{ post.id }}', '{% trans 'Post edited successfully!' %}')"><i class="material-icons">create</i> {% trans 'Edit' %}</a></li>
21 21 <li><a href="javascript:javascript:delete_post('{% url 'course:forum:delete_post' post.id %}', '{{ post.id }}')"><i class="material-icons">delete_sweep</i> {% trans 'Remove' %}</a></li>
22 22 </ul>
... ...
forum/templates/post/post_render.html
... ... @@ -14,7 +14,7 @@
14 14 <a class="btn btn-default btn-xs dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
15 15 <i class="material-icons">more_horiz</i>
16 16 </a>
17   - <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
  17 + <ul class="dropdown-menu pull-right" aria-labelledby="dropdownMenu1">
18 18 <li><a href="javascript:edit_post('{% url 'course:forum:update_post' post.id %}', '{{ post.id }}', '{% trans 'Post edited successfully!' %}')"></li>
19 19 <li><a href="javascript:delete_post('{% url 'course:forum:delete_post' post.id %}', '{{ post.id }}')"><i class="material-icons">delete_sweep</i> {% trans 'Remove' %}</a></li>
20 20 </ul>
... ...
forum/templates/post_answers/post_answer_list.html
... ... @@ -13,7 +13,7 @@
13 13 <a class="btn btn-default btn-xs dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
14 14 <i class="material-icons">more_horiz</i>
15 15 </a>
16   - <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
  16 + <ul class="dropdown-menu pull-right" aria-labelledby="dropdownMenu1">
17 17 <li><a href="javascript:edit_post_answer('{% url 'course:forum:update_post_answer' answer.id %}', '{{ answer.id }}', '{% trans 'Answer edited sucessfully!' %}')"><i class="material-icons">create</i> {% trans 'Edit' %}</a></li>
18 18 <li><a href="javascript:delete_answer('{% url 'course:forum:delete_answer' answer.id %}', '{{ answer.id }}', '{% trans "Are you sure you want to delete this answer?" %}')"><i class="material-icons">delete_sweep</i> {% trans 'Remove' %}</a></li>
19 19 </ul>
... ...
forum/templates/post_answers/post_answer_render.html
... ... @@ -11,7 +11,7 @@
11 11 <a class="btn btn-default btn-xs dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
12 12 <i class="material-icons">more_horiz</i>
13 13 </a>
14   - <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
  14 + <ul class="dropdown-menu pull-right" aria-labelledby="dropdownMenu1">
15 15 <li><a href="javascript:edit_post_answer('{% url 'course:forum:update_post_answer' answer.id %}', '{{ answer.id }}', '{% trans 'Answer edited sucessfully!' %}')"><i class="material-icons">create</i> {% trans 'Edit' %}</a></li>
16 16 <li><a href="javascript:delete_answer('{% url 'course:forum:delete_answer' answer.id %}', '{{ answer.id }}', '{% trans "Are you sure you want to delete this answer?" %}')"><i class="material-icons">delete_sweep</i> {% trans 'Remove' %}</a></li>
17 17 </ul>
... ...
forum/tests/test_view_forum.py
... ... @@ -4,10 +4,10 @@ from django.core.urlresolvers import reverse
4 4 from rolepermissions.shortcuts import assign_role
5 5  
6 6 from users.models import User
7   -from courses.models import Category, Course, Subject, Topic
  7 +from courses.models import CourseCategory, Course, Subject, Topic
8 8 from forum.models import Forum
9 9  
10   -class ForumDetailViewTestCase (TestCase):
  10 +class ForumViewTestCase (TestCase):
11 11  
12 12 def setUp(self):
13 13 self.client = Client()
... ... @@ -21,7 +21,7 @@ class ForumDetailViewTestCase (TestCase):
21 21 )
22 22 assign_role(self.user, 'system_admin')
23 23  
24   - self.category = Category.objects.create(
  24 + self.category = CourseCategory.objects.create(
25 25 name = 'Category test',
26 26 slug = 'category_test'
27 27 )
... ... @@ -69,22 +69,78 @@ class ForumDetailViewTestCase (TestCase):
69 69 )
70 70 self.forum.save()
71 71  
72   - self.url = reverse('course:forum:view', kwargs={'slug':self.forum.slug})
73   -
74   - def test_view_ok (self):
  72 +
75 73 self.client.login(username='test', password='testing')
  74 + self.index_url = reverse('course:forum:view', kwargs={'slug':self.forum.slug})
  75 + self.create_url = reverse('course:forum:create')
  76 + self.update_url = reverse('course:forum:update', kwargs={'pk':self.forum.pk})
  77 +
  78 +######################### ForumDetailView #########################
76 79  
77   - response = self.client.get(self.url)
  80 + def test_ForumDetail_view_ok (self):
  81 + response = self.client.get(self.index_url)
78 82 self.assertEquals(response.status_code, 200)
79 83 self.assertTemplateUsed(response, 'forum/forum_view.html')
80 84  
81   - def test_context(self):
82   - self.client.login(username='test', password='testing')
  85 + def test_ForumDetail_context(self):
  86 + response = self.client.get(self.index_url)
  87 + self.assertTrue('forum' in response.context)
83 88  
84   - response = self.client.get(self.url)
  89 +######################### CreateForumView #########################
  90 +
  91 + def test_CreateForum_view_ok (self):
  92 + response = self.client.get(self.create_url)
  93 + self.assertEquals(response.status_code, 200)
  94 + self.assertTemplateUsed(response, 'forum/forum_form.html')
85 95  
  96 + def test_CreateForum_context(self):
  97 + response = self.client.get(self.create_url)
86 98 self.assertTrue('form' in response.context)
87   - self.assertTrue('forum' in response.context)
88   - self.assertTrue('title' in response.context)
89 99  
  100 + def test_CreateForum_form_error (self):
  101 + data = {'name':'', 'limit_date': '', 'description':'', 'topic':''}
  102 + response = self.client.post(self.create_url, data)
  103 + self.assertEquals (response.status_code, 400)
  104 +
  105 + def test_CreateForum_form_ok (self):
  106 + data = {
  107 + 'name':'Forum Test2',
  108 + 'limit_date': '2017-10-05',
  109 + 'description':'Test',
  110 + 'topic':str(self.topic.id)
  111 + }
  112 +
  113 + response = self.client.post(self.create_url, data)
  114 + self.assertEquals (response.status_code, 302)
  115 +
  116 + forum = Forum.objects.get(name='Forum Test2')
  117 +
  118 +######################### UpdateForumView #########################
  119 +
  120 + def test_UpdateForum_view_ok (self):
  121 + response = self.client.get(self.update_url)
  122 + self.assertEquals(response.status_code, 200)
  123 + self.assertTemplateUsed(response, 'forum/forum_form.html')
  124 +
  125 + def test_UpdateForum_context(self):
  126 + response = self.client.get(self.update_url)
  127 + self.assertTrue('form' in response.context)
  128 +
  129 + def test_UpdateForum_form_error (self):
  130 + data = {'name':'', 'limit_date': '', 'description':''}
  131 +
  132 + response = self.client.post(self.update_url, data)
  133 + self.assertEquals (response.status_code, 400)
  134 +
  135 + def test_UpdateForum_form_ok (self):
  136 + data = {
  137 + 'name':'Forum Updated',
  138 + 'limit_date': '2017-10-05',
  139 + 'description':'Test',
  140 + 'topic':str(self.topic.id)
  141 + }
  142 +
  143 + response = self.client.post(self.update_url, data)
  144 + self.assertEquals (response.status_code, 302)
90 145  
  146 + forum = Forum.objects.get(name='Forum Updated')
91 147 \ No newline at end of file
... ...
forum/views.py
... ... @@ -44,7 +44,10 @@ class CreateForumView(LoginRequiredMixin, generic.edit.CreateView):
44 44 form_class = ForumForm
45 45  
46 46 def form_invalid(self, form):
47   - return self.render_to_response(self.get_context_data(form = form), status = 400)
  47 + context = super(CreateForumView, self).form_invalid(form)
  48 + context.status_code = 400
  49 +
  50 + return context
48 51  
49 52 def get_success_url(self):
50 53 self.success_url = reverse('course:forum:render_forum', args = (self.object.id, ))
... ...
links/tests.py
... ... @@ -21,14 +21,28 @@ class LinkTestCase(TestCase):
21 21 self.client.login(username='user', password = 'testing')
22 22 links = Link.objects.all().count()
23 23 self.assertEqual(Link.objects.all().count(),links) #Before creating the link
24   - self.link = Link.objects.create(
25   - name = 'testinglink',
26   - description = 'testdescription',
27   - link = 'teste'
28   - )
  24 + url = reverse('course:create_link')
  25 + data = {
  26 + 'name' : 'testinglink',
  27 + "description" : 'testdescription',
  28 + "link" : 'teste.com'
  29 + }
  30 + response = self.client.post(url, data)
29 31 self.assertEqual(Link.objects.all().count(),links+1) #After creating one link, if OK, the link was created successfully.
  32 + self.assertEqual(response.status_code, 200)
30 33 self.assertTemplateUsed(template_name = 'links/link_modal.html')
31 34 # def test_update_link():
32 35 # pass
33   - # def test_delete_link():
34   - # pass
  36 + def test_delete_link(self):
  37 + self.link = Link.objects.create(
  38 + name = 'testinglink',
  39 + description = 'testdescription',
  40 + link = 'teste.com'
  41 + )
  42 + self.client.login(username='user', password = 'testing')
  43 + links = Link.objects.all().count()
  44 + url = reverse('course:delete_link',kwargs={'linkname': self.link.name})
  45 + self.assertEqual(Link.objects.all().count(),links)
  46 + response = self.client.get(url)
  47 + self.assertEqual(Link.objects.all().count(),links - 1)
  48 + self.assertEqual(response.status_code, 200)
... ...
links/views.py
... ... @@ -3,7 +3,7 @@ from django.views import generic
3 3 from django.core.urlresolvers import reverse_lazy
4 4 from django.contrib import messages
5 5 from django.utils.translation import ugettext_lazy as _
6   -
  6 +from django.shortcuts import get_object_or_404,redirect
7 7  
8 8 from .models import Link
9 9 from .forms import *
... ... @@ -25,8 +25,11 @@ class CreateLink(generic.CreateView):
25 25 return context
26 26  
27 27  
28   -class DeleteLink(generic.DeleteView):
29   - pass
  28 +def deleteLink(request,linkname):
  29 + link = get_object_or_404(Link,name = linkname)
  30 + link.delete()
  31 + messages.success(request,_("Link deleted Successfully!"))
  32 + return redirect('course:update_topic')
30 33 class UpdateLink(generic.UpdateView):
31 34 template_name = 'links/'
32 35 form_class = UpdateLinkForm
... ...
poll/admin.py
1 1 from django.contrib import admin
2 2  
3   -from .models import Poll, Answer
  3 +from .models import Poll, Answer, AnswersStudent
4 4  
5 5 class PollAdmin(admin.ModelAdmin):
6 6 list_display = ['name', 'slug','limit_date']
... ... @@ -10,5 +10,10 @@ class AnswerAdmin(admin.ModelAdmin):
10 10 list_display = ['answer','order']
11 11 search_fields = ['answer']
12 12  
  13 +class AnswersStudentAdmin(admin.ModelAdmin):
  14 + list_display = ['student','poll','answered_in']
  15 + search_fields = ['student','poll']
  16 +
13 17 admin.site.register(Poll, PollAdmin)
14 18 admin.site.register(Answer, AnswerAdmin)
  19 +admin.site.register(AnswersStudent, AnswersStudentAdmin)
... ...
poll/migrations/0002_answersstudent.py 0 → 100644
... ... @@ -0,0 +1,33 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-10-12 18:26
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.conf import settings
  6 +from django.db import migrations, models
  7 +import django.db.models.deletion
  8 +
  9 +
  10 +class Migration(migrations.Migration):
  11 +
  12 + dependencies = [
  13 + migrations.swappable_dependency(settings.AUTH_USER_MODEL),
  14 + ('poll', '0001_initial'),
  15 + ]
  16 +
  17 + operations = [
  18 + migrations.CreateModel(
  19 + name='AnswersStudent',
  20 + fields=[
  21 + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
  22 + ('status', models.BooleanField(default=False, verbose_name='Answered')),
  23 + ('answered_in', models.DateTimeField(auto_now=True, verbose_name='Answered Date')),
  24 + ('answer', models.ManyToManyField(related_name='answers_stundet', to='poll.Answer', verbose_name='Answers Students')),
  25 + ('poll', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='answers_stundet', to='poll.Poll', verbose_name='Answers')),
  26 + ('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='answers_stundent', to=settings.AUTH_USER_MODEL, verbose_name='Student')),
  27 + ],
  28 + options={
  29 + 'verbose_name': 'Answer Stundent',
  30 + 'verbose_name_plural': 'Answers Student',
  31 + },
  32 + ),
  33 + ]
... ...
poll/migrations/0003_auto_20161012_1638.py 0 → 100644
... ... @@ -0,0 +1,21 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-10-12 19:38
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.db import migrations, models
  6 +import django.db.models.deletion
  7 +
  8 +
  9 +class Migration(migrations.Migration):
  10 +
  11 + dependencies = [
  12 + ('poll', '0002_answersstudent'),
  13 + ]
  14 +
  15 + operations = [
  16 + migrations.AlterField(
  17 + model_name='answersstudent',
  18 + name='poll',
  19 + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='answers_stundet', to='poll.Poll', verbose_name='Poll'),
  20 + ),
  21 + ]
... ...
poll/models.py
... ... @@ -27,3 +27,17 @@ class Answer(models.Model):
27 27  
28 28 def __str__(self):
29 29 return str(self.answer) + str("/") + str(self.poll)
  30 +
  31 +class AnswersStudent(models.Model):
  32 + status = models.BooleanField(_("Answered"), default=False)
  33 + poll = models.ForeignKey(Poll, verbose_name = _('Poll'), related_name='answers_stundet')
  34 + answer = models.ManyToManyField(Answer,verbose_name = _('Answers Students'), related_name='answers_stundet')
  35 + student = models.ForeignKey(User, verbose_name = _('Student'), related_name='answers_stundent')
  36 + answered_in = models.DateTimeField(_("Answered Date"),auto_now=True)
  37 +
  38 + class Meta:
  39 + verbose_name = _('Answer Stundent')
  40 + verbose_name_plural = _('Answers Student')
  41 +
  42 + def __str__(self):
  43 + return str(self.student) + str("/") + str(self.poll)
... ...
poll/static/js/modal_poll.js 0 → 100644
... ... @@ -0,0 +1,42 @@
  1 +//controles do modal
  2 +$(window).ready(function() { // utilizado para abrir o modal quando tiver tido algum erro no preenchimento do formulario
  3 + if($('.not_submited').length){
  4 + $('#poll').modal('show');
  5 + }
  6 +});
  7 +var Answer = {
  8 + init: function(url) { // utilizado para adicionar um novo campo de resposta
  9 + $.get(url, function(data){
  10 + $("#form").append(data);
  11 + var cont = 1;
  12 + $("#form div div div input").each(function(){
  13 + $(this).attr('name',cont++);
  14 + });
  15 + });
  16 + }
  17 +};
  18 +
  19 +var Submite = {
  20 + post: function(url,dados){
  21 + $('#poll').modal('hide');
  22 + $.post(url,dados, function(data){
  23 + }).fail(function(data){
  24 + $("div.modal-backdrop.fade.in").remove();
  25 + $("#modal_poll").empty();
  26 + $("#modal_poll").append(data.responseText);
  27 + });
  28 + }
  29 + ,
  30 + remove: function(url,dados, id_li_link){
  31 + $('#poll').modal('hide');
  32 + $.post(url,dados, function(data){
  33 + $(id_li_link).remove();
  34 + $("#modal_poll").empty();
  35 + $("div.modal-backdrop.fade.in").remove();
  36 + }).fail(function(){
  37 + $("#modal_poll").empty();
  38 + $("#modal_poll").append(data);
  39 + $('#poll').modal('show');
  40 + });
  41 + }
  42 +}
... ...
poll/static/js/modals_requisitions.js 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +function get(url, id_modal, id_div_modal){
  2 + $.get(url, function(data){
  3 + if($(id_modal).length){
  4 + $(id_div_modal).empty();
  5 + $(id_div_modal).append(data);
  6 + } else {
  7 + $(id_div_modal).append(data);
  8 + }
  9 + $(id_modal).modal('show');
  10 + });
  11 +}
  12 +
  13 +// function remove(url, id_li_link){
  14 +// $.post(url, function(data){
  15 +// $(id_li_link).remove();
  16 +// }).fail(function(data){
  17 +// alert("Error ao excluir a enquete");
  18 +// alert(data);
  19 +// });
  20 +// }
... ...
poll/static/js/sortable_poll.js 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +//deve ser importado apenas depois do html
  2 +$( "#form" ).sortable({ // utilizado para fazer a re-organização das respostas
  3 + delay: 100,
  4 + distance: 5,
  5 + update: function( event, ui ) {
  6 + var cont = 1;
  7 + $("#form div div div input").each(function(){
  8 + $(this).attr('name',cont++);
  9 + });
  10 + },
  11 +});
... ...
poll/templates/poll/answer.html 0 → 100644
... ... @@ -0,0 +1,19 @@
  1 +
  2 +{% load i18n %}
  3 +
  4 +<div class="row form-group">
  5 + <div class="col-md-1">
  6 + </br>
  7 + <label><span class="glyphicon glyphicon-move"></span></label>
  8 + </div>
  9 + <div class="col-md-10">
  10 + <div class="has-success is-empty">
  11 + <input type="text" name="1" class="form-control" placeholder="{% trans 'Answer' %}">
  12 + <span class="help-block">{% trans "Possible answer for the question" %}</span>
  13 + </div>
  14 + </div>
  15 + <div class="col-md-1">
  16 + </br>
  17 + <label><span class="glyphicon glyphicon-remove" onclick="this.parentNode.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode.parentNode);"></span></label>
  18 + </div>
  19 +</div>
... ...
poll/templates/poll/answer_student.html 0 → 100644
... ... @@ -0,0 +1,34 @@
  1 +{% extends "poll/create.html" %}
  2 +
  3 +{% load i18n static dict_access %}
  4 +
  5 +{% block title_poll %}
  6 +<!-- Put your title here!!! -->
  7 +<h4 class="modal-title" id="myModalLabel">{{poll.name}}</h4>
  8 +{% endblock title_poll %}
  9 +
  10 +{% block content_poll %}
  11 +<form id="answer_form" class="" action="" method="post">
  12 + {% csrf_token %}
  13 + {% for key in keys %}
  14 + <div class="row form-group {% if form.has_error %} has-error {% endif %}">
  15 + <div class="col-md-10 col-sm-10 col-xs-10 col-lg-10">
  16 + <div class="checkbox">
  17 + <label>
  18 + <input type="checkbox" name="{{key}}"><span class="checkbox-material"><span class="check"></span></span> {{ answers|value:key }}
  19 + </label>
  20 + </div>
  21 + </div>
  22 + </div>
  23 + {% endfor %}
  24 +</form>
  25 +{% endblock content_poll %}
  26 +{% block button_save %}
  27 +<button type="submite" id="button" form="answer_form" class="btn btn-primary btn-raised">{% trans "Answer" %}</button>
  28 +<script>
  29 + $("#answer_form").submit(function(event) {
  30 + Submite.post("{% url 'course:poll:answer_student_poll' poll.slug %}",$(this).serialize());
  31 + event.preventDefault();
  32 + });
  33 +</script>
  34 +{% endblock button_save %}
... ...
poll/templates/poll/create.html
1   -{% extends "topic/index.html" %}
  1 +{# {% extends "topic/index.html" %} #}
2 2  
3 3 {% load i18n widget_tweaks dict_access static%}
4 4  
5   -{% block style %}
  5 +{# {% block style %} #}
6 6 <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
7   -{% endblock %}
  7 + <script src="{% static 'js/modal_poll.js' %}"></script>
8 8  
9   -{% block content %}
  9 +{# {% endblock %} #}
  10 +
  11 +{# {% block content %} #}
10 12 <!-- Modal (remember to change the ids!!!) -->
11 13 <div class="modal fade" id="poll" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
12 14 <div class="modal-dialog" role="document">
... ... @@ -56,7 +58,7 @@
56 58 <form id="form" class="" action="" method="post">
57 59 {% csrf_token %}
58 60 {% for key in keys %}
59   - <div class="row form-group">
  61 + <div class="row form-group {% if form.has_error %} has-error {% endif %}">
60 62 <div class="col-md-1">
61 63 </br>
62 64 <label><span class="glyphicon glyphicon-move"></span></label>
... ... @@ -73,7 +75,7 @@
73 75 </div>
74 76 </div>
75 77 {% empty %}
76   - <div class="row form-group">
  78 + <div class="row form-group {% if form.has_error %} has-error {% endif %}">
77 79 <div class="col-md-1">
78 80 </br>
79 81 <label><span class="glyphicon glyphicon-move"></span></label>
... ... @@ -94,10 +96,10 @@
94 96 </br>
95 97 </div>
96 98 <button type="button" id="add" class="btn btn-primary btn-block btn-sm">add</button>
97   - <div class="row form-group">
  99 + <div class="row form-group {% if form.has_error %} has-error {% endif %}">
98 100 <label for="{{ form.limit_date.auto_id }}">{{ form.limit_date.label }}</label>
99   - {% render_field form.limit_date class="form-control" form="form"%}
100   - {# <input form="form" class="form-control" type="date" name="{{form.limit_date.name}}" {% if form.limit_date.value != None %}value="{% if form.limit_date.value.year %}{{form.limit_date.value|date:'Y-m-d'}}{% else %}{{form.limit_date.value}}{% endif %}"{% endif %}>#}
  101 + {# {% render_field form.limit_date class="form-control" form="form"%} #}
  102 + <input form="form" class="form-control" type="date" name="{{form.limit_date.name}}" {% if form.limit_date.value != None %}value="{% if form.limit_date.value.year %}{{form.limit_date.value|date:'Y-m-d'}}{% else %}{{form.limit_date.value}}{% endif %}"{% endif %}>
101 103 {% if form.limit_date.errors %}
102 104 <div class="not_submited">
103 105 </br>
... ... @@ -115,11 +117,11 @@
115 117 {% endif %}
116 118 </div>
117 119  
118   - <div class="row form-group">
  120 + <div class="row form-group {% if form.has_error %} has-error {% endif %}">
119 121 <label for="{{ form.students.auto_id }}">{{ form.students.label }}</label>
120 122 {% render_field form.students class="form-control" form="form"%}
121 123 </div>
122   - <div class="row form-group">
  124 + <div class="row form-group {% if form.has_error %} has-error {% endif %}">
123 125 <div class="checkbox">
124 126 <label>
125 127 {% render_field form.all_students class="form-control" form="form" %}<span class="checkbox-material"><span class="check"></span></span> {{form.all_students.label }}
... ... @@ -159,48 +161,21 @@
159 161 </div>
160 162 </div>
161 163 </div>
  164 +<script src="{% static 'js/sortable_poll.js' %}">
  165 +// Este js tem que ficar aqui se não o sortable não vai funcionar
  166 +</script>
  167 +{% block script_poll %}
162 168 <script type="text/javascript">
163   -// Este js tem que ficar aqui se não a tag "trans" não vai funcionar
164   -$(window).ready(function() { // utilizado para abrir o modal quando tiver tido algum erro no preenchimento do formulario
165   - if($('.not_submited').length){
166   - $('#poll').modal('show');
167   - }
168   -});
169   -$( "#form" ).sortable({ // utilizado para fazer a re-organização das respostas
170   - delay: 100,
171   - distance: 5,
172   - update: function( event, ui ) {
173   - var cont = 1;
174   - $("#form div div div input").each(function(){
175   - $(this).attr('name',cont++);
176   - });
177   - },
178   -});
179   -name = 2;
180   -$("#add").click(function() { // utilizado para adicionar um novo campo de resposta
181   - //Obs: não funcionar se estiver importado no head, só funciona se estiver no final do arquivo
182   - $("#form").append('\
183   - <div class="row form-group">\
184   - <div class="col-md-1">\
185   - </br>\
186   - <label><span class="glyphicon glyphicon-move"></span></label>\
187   - </div>\
188   - <div class="col-md-10">\
189   - <div class="has-success is-empty">\
190   - <input type="text" name="1" class="form-control" placeholder="{% trans "Answer" %}">\
191   - <span class="help-block">{% trans "Possible answer for the question" %}</span>\
192   - </div>\
193   - </div>\
194   - <div class="col-md-1">\
195   - </br>\
196   - <label><span class="glyphicon glyphicon-remove" onclick="this.parentNode.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode.parentNode);"></span></label>\
197   - </div>\
198   - </div>');
199   - var cont = 1;
200   - $("#form div div div input").each(function(){
201   - $(this).attr('name',cont++);
  169 +// Este js tem que ficar aqui se não o button add não vai funcionar
  170 + $("#add").click(function (){
  171 + Answer.init('{% url "course:poll:answer_poll" %}');
  172 + });
  173 +
  174 + $("#form").submit(function(event) {
  175 + Submite.post("{% url 'course:poll:create_poll' topic.slug %}",$(this).serialize());
  176 + event.preventDefault();
202 177 });
203   -});
204 178 </script>
205   -<a href="" data-toggle="modal" data-target="#poll">modal</a>
206   -{% endblock content %}
  179 +{% endblock script_poll %}
  180 +{# <a href="" data-toggle="modal" data-target="#poll">modal</a> #}
  181 +{# {% endblock content %} #}
... ...
poll/templates/poll/remove.html
1 1 {% extends "poll/create.html" %}
2 2  
3   -{% load i18n %}
  3 +{% load i18n static%}
4 4  
5 5 {% block title_poll %}
6 6 <!-- Put your title here!!! -->
... ... @@ -8,14 +8,19 @@
8 8 {% endblock title_poll %}
9 9  
10 10 {% block content_poll %}
  11 +<script src="{% static 'js/modal_poll.js' %}"></script>
11 12 <!-- Put ONLY your content here!!! -->
12   -<form action="" method="post">
  13 +<form id="delete_form" action="" method="post">
13 14 {% csrf_token %}
14   - <h2>{% trans 'Are you sure you want to delete the subject' %} "{{poll}}"?</h2>
15   - <input type="submit" class="btn btn-raised btn-success btn-lg" value="{% trans 'Yes' %}" />
16   - <a href="" class="btn btn-raised btn-danger btn-lg">{% trans 'No' %}</a>
  15 + <p>{% trans 'Are you sure you want to delete the subject' %} "{{poll.name}}"?</p>
17 16 </form>
18 17 {% endblock content_poll %}
19   -
20 18 {% block button_save %}
  19 +<button type="submite" id="button" form="delete_form" class="btn btn-primary btn-raised">{% trans "Delete" %}</button>
  20 +<script>
  21 + $("#delete_form").submit(function(event) {
  22 + Submite.remove("{% url 'course:poll:delete_poll' poll.slug %}",$(this).serialize(),"#poll_{{poll.slug}}");
  23 + event.preventDefault();
  24 + });
  25 +</script>
21 26 {% endblock button_save %}
... ...
poll/templates/poll/update.html
... ... @@ -11,3 +11,17 @@
11 11 <!-- Put curtom buttons here!!! -->
12 12 <button type="submite" id="button" form="form" class="btn btn-primary btn-raised">{% trans "Update" %}</button>
13 13 {% endblock button_save %}
  14 +
  15 +{% block script_poll %}
  16 +<script type="text/javascript">
  17 +// Este js tem que ficar aqui se não o button add não vai funcionar
  18 + $("#add").click(function (){
  19 + Answer.init('{% url "course:poll:answer_poll" %}');
  20 + });
  21 +
  22 + $("#form").submit(function(event) {
  23 + Submite.post("{% url 'course:poll:update_poll' poll.slug %}",$(this).serialize());
  24 + event.preventDefault();
  25 + });
  26 +</script>
  27 +{% endblock script_poll %}
... ...
poll/templates/poll/view.html
... ... @@ -7,19 +7,29 @@
7 7  
8 8 {% block title_poll %}
9 9 <!-- Put your title here!!! -->
10   -<h4 class="modal-title" id="myModalLabel">{{poll}}</h4>
  10 +<h4 class="modal-title" id="myModalLabel">{{poll.name}}</h4>
11 11 {% endblock title_poll %}
12 12  
13 13 {% block content_poll %}
14 14 <!-- Put ONLY your content here!!! -->
15 15 <div class="row">
16 16 <div class="col-md-10 col-md-offset-1">
17   - <h3>{% trans "Limit date:" %} {{poll.limit_date|date:'d/m/y'}}</h3>
  17 + <p>{% trans "Limit date:" %} {{poll.limit_date|date:'d/m/y'}}</p>
  18 + </div>
  19 + <div class="col-md-10 col-md-offset-1">
  20 + <p>{% trans "Status:" %}
  21 + {% if status %}
  22 + {% trans "Poll answered" %}
  23 + {% else %}
  24 + {% trans "Poll don't yet answered" %}
  25 + {% endif %}
18 26 </div>
19 27 </div>
20 28 {% endblock content_poll %}
21 29  
22 30 {% block button_save %}
23 31 <!-- Put curtom buttons here!!! -->
24   -<button type="submite" id="button" form="form" class="btn btn-primary btn-raised">{% trans "Answer" %}</button>
  32 +{% if not status %}
  33 +<button type="button" onclick="javascript:get('{% url 'course:poll:answer_student_poll' poll.slug%}','#poll','#modal_poll');$('div.modal-backdrop.fade.in').remove();" class="btn btn-primary btn-raised">{% trans "Answer" %}</button>
  34 +{% endif %}
25 35 {% endblock button_save %}
... ...
poll/tests/poll.py
... ... @@ -5,7 +5,7 @@ from django.core.urlresolvers import reverse
5 5  
6 6 from rolepermissions.shortcuts import assign_role
7 7  
8   -from courses.models import Category, Course, Subject, Topic
  8 +from courses.models import CourseCategory, Course, Subject, Topic
9 9 from poll.models import Poll
10 10 from users.models import User
11 11  
... ... @@ -33,7 +33,7 @@ class PollTestCase(TestCase):
33 33 )
34 34 assign_role(self.user_student, 'student')
35 35  
36   - self.category = Category(
  36 + self.category = CourseCategory(
37 37 name = 'Categoria Teste',
38 38 )
39 39 self.category.save()
... ...
poll/urls.py
... ... @@ -7,5 +7,6 @@ urlpatterns = [
7 7 url(r'^create/(?P<slug>[\w\-_]+)/$', views.CreatePoll.as_view(), name='create_poll'), # topic slug
8 8 url(r'^update/(?P<slug>[\w\-_]+)/$', views.UpdatePoll.as_view(), name='update_poll'), # poll slug
9 9 url(r'^delete/(?P<slug>[\w\-_]+)/$', views.DeletePoll.as_view(), name='delete_poll'), # poll
10   -
  10 + url(r'^answer/$', views.AnswerPoll.as_view(), name='answer_poll'), # poll
  11 + url(r'^answer-poll/(?P<slug>[\w\-_]+)/$', views.AnswerStudentPoll.as_view(), name='answer_student_poll'), # poll slug
11 12 ]
... ...
poll/views.py
... ... @@ -12,7 +12,7 @@ from django.db.models import Q
12 12 # from django.views.generic.edit import FormMixin
13 13  
14 14 from .forms import PollForm
15   -from .models import Poll, Answer
  15 +from .models import Poll, Answer, AnswersStudent
16 16 from core.mixins import NotificationMixin
17 17 from users.models import User
18 18 from courses.models import Course, Topic
... ... @@ -26,48 +26,19 @@ class ViewPoll(LoginRequiredMixin,generic.DetailView):
26 26 def get_object(self, queryset=None):
27 27 return get_object_or_404(Poll, slug = self.kwargs.get('slug'))
28 28  
29   - def form_invalid(self, form,**kwargs):
30   - context = super(ViewPoll, self).form_invalid(form)
31   - answers = {}
32   - for key in self.request.POST:
33   - if(key != 'csrfmiddlewaretoken' and key != 'name' and key != 'limit_date' and key != 'all_students' and key != 'students'):
34   - answers[key] = self.request.POST[key]
35   -
36   - keys = sorted(answers)
37   - context.context_data['answers'] = answers
38   - context.context_data['keys'] = keys
39   - return context
40   -
41   - def form_valid(self, form):
42   - poll = self.object
43   - poll = form.save(commit = False)
44   - poll.answers.all().delete()
45   - poll.save()
46   -
47   -
48   - for key in self.request.POST:
49   - if(key != 'csrfmiddlewaretoken' and key != 'name' and key != 'limit_date' and key != 'all_students' and key != 'students'):
50   - answer = Answer(answer=self.request.POST[key],order=key,poll=poll)
51   - answer.save()
52   -
53   - return super(ViewPoll, self).form_valid(form)
54   -
55 29 def get_context_data(self, **kwargs):
56 30 context = super(ViewPoll, self).get_context_data(**kwargs)
57 31 poll = self.object
  32 + context["topic"] = poll.topic
58 33 context['course'] = poll.topic.subject.course
59 34 context['subject'] = poll.topic.subject
60 35 context['subjects'] = poll.topic.subject.course.subjects.all()
61   -
62   - answers = {}
63   - for answer in poll.answers.all():
64   - answers[answer.order] = answer.answer
65   -
66   - keys = sorted(answers)
67   - context['answers'] = answers
68   - context['keys'] = keys
69   -
70   - print (context)
  36 + answered = AnswersStudent.objects.filter(poll = poll, student=self.request.user)
  37 + print (answered)
  38 + if answered.count()<1:
  39 + context['status'] = False
  40 + else:
  41 + context['status'] = answered[0].status
71 42 return context
72 43  
73 44  
... ... @@ -80,7 +51,6 @@ class CreatePoll(LoginRequiredMixin,HasRoleMixin,generic.CreateView):
80 51 form_class = PollForm
81 52 context_object_name = 'poll'
82 53 template_name = 'poll/create.html'
83   - success_url = reverse_lazy('core:home')
84 54  
85 55 def form_invalid(self, form,**kwargs):
86 56 context = super(CreatePoll, self).form_invalid(form)
... ... @@ -92,6 +62,9 @@ class CreatePoll(LoginRequiredMixin,HasRoleMixin,generic.CreateView):
92 62 keys = sorted(answers)
93 63 context.context_data['answers'] = answers
94 64 context.context_data['keys'] = keys
  65 + context.context_data['form'] = form
  66 + context.status_code = 400
  67 + # return self.render_to_response(context, status = 400)
95 68 return context
96 69  
97 70 def form_valid(self, form):
... ... @@ -105,11 +78,12 @@ class CreatePoll(LoginRequiredMixin,HasRoleMixin,generic.CreateView):
105 78 answer = Answer(answer=self.request.POST[key],order=key,poll=self.object)
106 79 answer.save()
107 80  
108   - return super(CreatePoll, self).form_valid(form)
  81 + return self.render_to_response(self.get_context_data(form = form), status = 200)
109 82  
110 83 def get_context_data(self, **kwargs):
111 84 context = super(CreatePoll, self).get_context_data(**kwargs)
112 85 topic = get_object_or_404(Topic, slug = self.kwargs.get('slug'))
  86 + context["topic"] = topic
113 87 context['course'] = topic.subject.course
114 88 context['subject'] = topic.subject
115 89 context['subjects'] = topic.subject.course.subjects.all()
... ... @@ -145,6 +119,8 @@ class UpdatePoll(LoginRequiredMixin,HasRoleMixin,generic.UpdateView):
145 119 keys = sorted(answers)
146 120 context.context_data['answers'] = answers
147 121 context.context_data['keys'] = keys
  122 + context.context_data['form'] = form
  123 + context.status_code = 400
148 124 return context
149 125  
150 126 def form_valid(self, form):
... ... @@ -164,6 +140,7 @@ class UpdatePoll(LoginRequiredMixin,HasRoleMixin,generic.UpdateView):
164 140 def get_context_data(self, **kwargs):
165 141 context = super(UpdatePoll, self).get_context_data(**kwargs)
166 142 poll = self.object
  143 + context['topic'] = poll.topic
167 144 context['course'] = poll.topic.subject.course
168 145 context['subject'] = poll.topic.subject
169 146 context['subjects'] = poll.topic.subject.course.subjects.all()
... ... @@ -199,6 +176,7 @@ class DeletePoll(LoginRequiredMixin, HasRoleMixin, generic.DeleteView):
199 176 context['course'] = self.object.topic.subject.course
200 177 context['subject'] = self.object.topic.subject
201 178 context['poll'] = self.object
  179 + context["topic"] = self.object.topic
202 180 context['subjects'] = self.object.topic.subject.course.subjects.filter(Q(visible=True) | Q(professors__in=[self.request.user]))
203 181 if (has_role(self.request.user,'system_admin')):
204 182 context['subjects'] = self.object.topic.subject.course.subjects.all()
... ... @@ -206,3 +184,50 @@ class DeletePoll(LoginRequiredMixin, HasRoleMixin, generic.DeleteView):
206 184  
207 185 def get_success_url(self):
208 186 return reverse_lazy('course:view_topic', kwargs={'slug' : self.object.topic.slug})
  187 +
  188 +
  189 +class AnswerPoll(generic.TemplateView):
  190 + template_name = 'poll/answer.html'
  191 +
  192 +class AnswerStudentPoll(LoginRequiredMixin,generic.CreateView):
  193 +
  194 + model = AnswersStudent
  195 + fields = ['status']
  196 + context_object_name = 'answer'
  197 + template_name = 'poll/answer_student.html'
  198 +
  199 + def form_valid(self, form):
  200 + poll = get_object_or_404(Poll, slug = self.kwargs.get('slug'))
  201 + answers = AnswersStudent(
  202 + status = True,
  203 + poll = poll,
  204 + student = self.request.user,
  205 + )
  206 + answers.save()
  207 +
  208 + for key in self.request.POST:
  209 + if(key != 'csrfmiddlewaretoken'):
  210 + answers.answer.add(poll.answers.all().filter(order=key)[0])
  211 +
  212 + return self.render_to_response(self.get_context_data(form = form), status = 200)
  213 +
  214 + def get_context_data(self, **kwargs):
  215 + context = super(AnswerStudentPoll, self).get_context_data(**kwargs)
  216 + print (self.kwargs.get('slug'))
  217 + poll = get_object_or_404(Poll, slug = self.kwargs.get('slug'))
  218 + context['poll'] = poll
  219 + context['topic'] = poll.topic
  220 + context['course'] = poll.topic.subject.course
  221 + context['subject'] = poll.topic.subject
  222 + context['subjects'] = poll.topic.subject.course.subjects.all()
  223 +
  224 + print (self.request.method)
  225 + answers = {}
  226 + for answer in poll.answers.all():
  227 + answers[answer.order] = answer.answer
  228 +
  229 + keys = sorted(answers)
  230 + context['answers'] = answers
  231 + context['keys'] = keys
  232 +
  233 + return context
... ...