Commit 753af621682a731955e3c03a5a08203ef6a0bc44
Exists in
master
and in
5 other branches
Merge branch 'dev' of https://github.com/amadeusproject/amadeuslms into dev
Showing
10 changed files
with
314 additions
and
190 deletions
Show diff stats
courses/models.py
@@ -65,9 +65,11 @@ class Course(models.Model): | @@ -65,9 +65,11 @@ class Course(models.Model): | ||
65 | 65 | ||
66 | def show_subscribe(self): | 66 | def show_subscribe(self): |
67 | today = datetime.date.today() | 67 | today = datetime.date.today() |
68 | - | ||
69 | return today >= self.init_register_date and today <= self.end_register_date | 68 | return today >= self.init_register_date and today <= self.end_register_date |
70 | 69 | ||
70 | + def duration(self): | ||
71 | + return self.end_date - self.init_date | ||
72 | + | ||
71 | class Subject(models.Model): | 73 | class Subject(models.Model): |
72 | 74 | ||
73 | name = models.CharField(_('Name'), max_length = 100) | 75 | name = models.CharField(_('Name'), max_length = 100) |
courses/static/js/course.js
1 | /* | 1 | /* |
2 | * | 2 | * |
3 | +* Function to get a cookie stored on browser | ||
4 | +* | ||
5 | +*/ | ||
6 | +function getCookie(name) { | ||
7 | + var cookieValue = null; | ||
8 | + if (document.cookie && document.cookie !== '') { | ||
9 | + var cookies = document.cookie.split(';'); | ||
10 | + for (var i = 0; i < cookies.length; i++) { | ||
11 | + var cookie = jQuery.trim(cookies[i]); | ||
12 | + // Does this cookie string begin with the name we want? | ||
13 | + if (cookie.substring(0, name.length + 1) === (name + '=')) { | ||
14 | + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); | ||
15 | + break; | ||
16 | + } | ||
17 | + } | ||
18 | + } | ||
19 | + return cookieValue; | ||
20 | +} | ||
21 | +/* | ||
22 | +* | ||
3 | * Function to subscribe (works for courses and subjects) | 23 | * Function to subscribe (works for courses and subjects) |
4 | * | 24 | * |
5 | */ | 25 | */ |
@@ -19,4 +39,42 @@ function subscribe(elem, url, id, confirm_message) { | @@ -19,4 +39,42 @@ function subscribe(elem, url, id, confirm_message) { | ||
19 | } | 39 | } |
20 | }); | 40 | }); |
21 | }); | 41 | }); |
42 | +} | ||
43 | + | ||
44 | +/* | ||
45 | +* | ||
46 | +* Function to delete a course | ||
47 | +* | ||
48 | +*/ | ||
49 | +function delete_course(url, course, message, return_url) { | ||
50 | + alertify.confirm(message, function(){ | ||
51 | + var csrftoken = getCookie('csrftoken'); | ||
52 | + | ||
53 | + $.ajax({ | ||
54 | + method: 'post', | ||
55 | + beforeSend: function (request) { | ||
56 | + request.setRequestHeader('X-CSRFToken', csrftoken); | ||
57 | + }, | ||
58 | + url: url, | ||
59 | + success: function(data) { | ||
60 | + alertify.alert('Remove Course', 'Course removed successfully!', function(){ | ||
61 | + window.location.href = return_url; | ||
62 | + }); | ||
63 | + } | ||
64 | + }); | ||
65 | + }); | ||
66 | +} | ||
67 | +/* | ||
68 | +* | ||
69 | +* Function to load create course's form | ||
70 | +* | ||
71 | +*/ | ||
72 | +function replicate_course(url, course) { | ||
73 | + $.ajax({ | ||
74 | + url: url, | ||
75 | + data: {'form': course}, | ||
76 | + success: function(data) { | ||
77 | + $(".course_replicate_form").html(data); | ||
78 | + } | ||
79 | + }); | ||
22 | } | 80 | } |
23 | \ No newline at end of file | 81 | \ No newline at end of file |
courses/templates/category/index.html
@@ -80,11 +80,9 @@ | @@ -80,11 +80,9 @@ | ||
80 | <td>{{ category }}</td> | 80 | <td>{{ category }}</td> |
81 | <td>{{ category.slug }}</td> | 81 | <td>{{ category.slug }}</td> |
82 | <td class="text-center"> | 82 | <td class="text-center"> |
83 | - <a href="{% url 'course:view_cat' category.slug %}" class="btn btn-info btn-sm"><span class="glyphicon glyphicon-eye-open"></span></a> | ||
84 | - <a href="{% url 'course:update_cat' category.slug %}" class="btn btn-primary btn-sm"><span class="glyphicon glyphicon-edit"></span></a> | ||
85 | - <a href="javascript:modal.get('{% url 'course:delete_cat' category.slug %}','#category','#modal_category');" class="btn btn-danger btn-sm"><span class="glyphicon glyphicon-trash"></span></a> | ||
86 | - | ||
87 | - </td> | 83 | + <a href="{% url 'course:update_cat' category.slug %}" class="btn btn-primary btn-sm"><span class="glyphicon glyphicon-edit"></span></a> |
84 | + <a href="javascript:modal.get('{% url 'course:delete_cat' category.slug %}','#category','#modal_category');" class="btn btn-danger btn-sm"><span class="glyphicon glyphicon-trash"></span></a> | ||
85 | + </td> | ||
88 | </tr> | 86 | </tr> |
89 | {% endfor %} | 87 | {% endfor %} |
90 | {% else %} | 88 | {% else %} |
courses/templates/category/view.html
@@ -1,69 +0,0 @@ | @@ -1,69 +0,0 @@ | ||
1 | -{% extends 'base.html' %} | ||
2 | - | ||
3 | -{% load static i18n permission_tags %} | ||
4 | -{% load widget_tweaks %} | ||
5 | -{% load static i18n %} | ||
6 | - | ||
7 | - | ||
8 | -{% block breadcrumbs %} | ||
9 | - <ol class="breadcrumb"> | ||
10 | - <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li> | ||
11 | - <li class="active">{{ category }}</li> | ||
12 | - </ol> | ||
13 | -{% endblock %} | ||
14 | - | ||
15 | -{% block sidebar %} | ||
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' or user|has_role:'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 %} | ||
56 | -{% endblock %} | ||
57 | - | ||
58 | -{% block content %} | ||
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> | ||
67 | - </div> | ||
68 | - </div> | ||
69 | -{% endblock %} |
courses/templates/course/course_card.html
1 | {% load static i18n permission_tags %} | 1 | {% load static i18n permission_tags %} |
2 | {% load django_bootstrap_breadcrumbs %} | 2 | {% load django_bootstrap_breadcrumbs %} |
3 | 3 | ||
4 | -<div class="panel-group ui-accordion ui-widget ui-helper-reset ui-sortable" id="accordion" role="tablist" aria-multiselectable="false"> | ||
5 | - <div class="group"> | ||
6 | - <div class="panel panel-info"> | ||
7 | - <div class="panel-heading" role="tab"> | ||
8 | - <div class="row"> | ||
9 | - <div class="col-xs-9 col-md-10 titleTopic"> | ||
10 | - <a role="button" data-toggle="collapse" data-parent="#accordion" href=".collapseOne" aria-expanded="false" aria-controls="collapseOne" class="collapsed"> | ||
11 | - <h4 style="color:white">{{course.name}}</h4> | ||
12 | - </a> | ||
13 | - </div> | ||
14 | - {% if user|has_role:'professor' or user|has_role:'system_admin' %} | ||
15 | - <div class="col-xs-4 col-md-2" id="divMoreActions"> | ||
16 | - <div class="btn-group"> | ||
17 | - <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | ||
18 | - <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i> | ||
19 | - </button> | ||
20 | - <ul class="dropdown-menu" aria-labelledby="moreActions"> | ||
21 | - <li><a href="javascript:void(0)" data-toggle="modal" data-target="#myModal4"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i> Replicate</a></li> | ||
22 | - <li><a href="javascript:void(0)" data-toggle="modal" data-target="#removeCourse"><i class="fa fa-trash fa-fw" aria-hidden="true"></i> Remove</a></li> | ||
23 | - </ul> | ||
24 | - </div> | ||
25 | - </div> | ||
26 | - {% endif %} | ||
27 | - </div> | ||
28 | - </div> | ||
29 | - <div class="panel-collapse collapseOne collapse in" role="tabpanel" aria-labelledby="headingOne" aria-expanded="true" aria-hidden="false" tabindex="0"> | ||
30 | - <div class="panel-body"> | ||
31 | - <p><b>Course Name: </b>{{course.name}}</p> | ||
32 | - <p><b>Coordinator: </b>{{course.professors.all.0}}</p> | ||
33 | - <p> | ||
34 | - <b>Description:</b> | ||
35 | - <i> | ||
36 | - {{course.description}} | ||
37 | - </i> | ||
38 | - </p> | ||
39 | - <a href="{% url 'course:view' course.slug %}" class="btn btn-raised btn-default center-block">{% trans 'View Course' %}<div class="ripple-container"></div></a> | ||
40 | - </div> | ||
41 | - </div> | ||
42 | - </div> | ||
43 | - </div> | ||
44 | - </div> | ||
45 | \ No newline at end of file | 4 | \ No newline at end of file |
5 | +<div class="panel-group ui-accordion ui-widget ui-helper-reset ui-sortable" id="accordion-{{course.slug}}" role="tablist" aria-multiselectable="false"> | ||
6 | + <div class="group"> | ||
7 | + <div class="panel panel-info"> | ||
8 | + <div class="panel-heading" role="tab"> | ||
9 | + <div class="row"> | ||
10 | + <div class="col-xs-9 col-md-10 titleTopic"> | ||
11 | + <a role="button" data-toggle="collapse" data-parent="#accordion-{{course.slug}}" href=".collapseOne-{{course.slug}}" aria-expanded="false" aria-controls="collapseOne-{{course.slug}}" class="collapsed"> | ||
12 | + <h4 style="color:white">{{course.name}}</h4> | ||
13 | + </a> | ||
14 | + </div> | ||
15 | + {% if user|has_role:'professor' or user|has_role:'system_admin' %} | ||
16 | + <div class="col-xs-4 col-md-2" id="divMoreActions"> | ||
17 | + <div class="btn-group"> | ||
18 | + <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | ||
19 | + <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i> | ||
20 | + </button> | ||
21 | + <ul class="dropdown-menu" aria-labelledby="moreActions"> | ||
22 | + <li><a href="{% url 'course:replicate_course' course.slug %}"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i>{% trans 'Replicate' %}</a></li> | ||
23 | + <li><a href="javascript:delete_course('{% url 'course:delete' course.slug %}', '{{ course.slug }}', '{% trans "Are you sure you want to delete this course?" %}', '{% url 'course:manage' %}')"><i class="fa fa-trash fa-fw" aria-hidden="true"></i>{% trans 'Remove' %}</a></li> | ||
24 | + </ul> | ||
25 | + </div> | ||
26 | + </div> | ||
27 | + {% endif %} | ||
28 | + </div> | ||
29 | + </div> | ||
30 | + <div class="panel-collapse collapseOne-{{course.slug}} collapse in" role="tabpanel" aria-labelledby="headingOne" aria-expanded="true" aria-hidden="false" tabindex="0"> | ||
31 | + <div class="panel-body"> | ||
32 | + <p><b>Course Name: </b>{{course.name}}</p> | ||
33 | + <p><b>Coordinator: </b>{{course.professors.all.0}}</p> | ||
34 | + <p> | ||
35 | + <b>Description:</b> | ||
36 | + <i> | ||
37 | + {{course.content}} | ||
38 | + </i> | ||
39 | + </p> | ||
40 | + <a href="{% url 'course:view' course.slug %}" class="btn btn-raised btn-default center-block">{% trans 'View Course' %}<div class="ripple-container"></div></a> | ||
41 | + </div> | ||
42 | + </div> | ||
43 | + </div> | ||
44 | + </div> | ||
45 | +</div> | ||
46 | + | ||
47 | +<div class="modal fade" id="replicateCourse" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> | ||
48 | + <div class="modal-dialog" role="document"> | ||
49 | + <div class="modal-content"> | ||
50 | + <div class="modal-header"> | ||
51 | + <h4 class="modal-title" id="myModalLabel">{% trans 'Repicate Course' %}</h4> | ||
52 | + </div> | ||
53 | + <div class="modal-body"> | ||
54 | + <section> | ||
55 | + <div class="course_replicate_form"></div> | ||
56 | + </section> | ||
57 | + </div> | ||
58 | + <div class="modal-footer"> | ||
59 | + <button type="button" class="btn btn-danger btn-raised" data-dismiss="modal">{% trans 'Close' %}</button> | ||
60 | + <button type="button" onclick="$('#course_replicate').submit();" class="btn btn-primary btn-raised">{% trans 'Create' %}</button> | ||
61 | + </div> | ||
62 | + </div> | ||
63 | + </div> | ||
64 | +</div> | ||
46 | \ No newline at end of file | 65 | \ No newline at end of file |
courses/templates/course/index.html
@@ -41,6 +41,21 @@ | @@ -41,6 +41,21 @@ | ||
41 | </ul> | 41 | </ul> |
42 | </div> | 42 | </div> |
43 | </div> | 43 | </div> |
44 | + | ||
45 | + {% if user|has_role:'professor' or user|has_role:'system_admin' %} | ||
46 | + | ||
47 | + <div class="panel panel-primary navigation"> | ||
48 | + <div class="panel-heading"> | ||
49 | + <h3 class="panel-title">Category</h3> | ||
50 | + </div> | ||
51 | + <div class="panel-body"> | ||
52 | + <ul class="nav nav-pills nav-stacked"> | ||
53 | + <li><a href="{% url 'course:create_cat' %}">Create Category</a></li> | ||
54 | + <li><a href="{% url 'course:manage_cat' %}">List Category</a></li> | ||
55 | + </ul> | ||
56 | + </div> | ||
57 | + </div> | ||
58 | + {% endif %} | ||
44 | {% endblock %} | 59 | {% endblock %} |
45 | 60 | ||
46 | {% block content %} | 61 | {% block content %} |
@@ -81,74 +96,13 @@ | @@ -81,74 +96,13 @@ | ||
81 | {% for course in courses_category %} | 96 | {% for course in courses_category %} |
82 | {% if course.category.name == request.GET.category %} | 97 | {% if course.category.name == request.GET.category %} |
83 | <!-- Put your content here! --> | 98 | <!-- Put your content here! --> |
84 | - <div class="panel-group ui-accordion ui-widget ui-helper-reset ui-sortable" id="accordion" role="tablist" aria-multiselectable="false"> | ||
85 | - <div class="group"> | ||
86 | - <div class="panel panel-info"> | ||
87 | - <div class="panel-heading" role="tab"> | ||
88 | - <div class="row"> | ||
89 | - <div class="col-xs-9 col-md-9 titleTopic"> | ||
90 | - <a role="button" data-toggle="collapse" data-parent="#accordion" href=".collapseOne" aria-expanded="false" aria-controls="collapseOne" class="collapsed"> | ||
91 | - <h4 style="color:white">{{course.name}}</h4> | ||
92 | - </a> | ||
93 | - </div> | ||
94 | - {% if user|has_role:'professor' or user|has_role:'system_admin' %} | ||
95 | - <div class="col-xs-4 col-md-3" id="divMoreActions"> | ||
96 | - <div class="btn-group"> | ||
97 | - <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | ||
98 | - <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i> | ||
99 | - </button> | ||
100 | - <ul class="dropdown-menu" aria-labelledby="moreActions"> | ||
101 | - <li><a href="javascript:void(0)" data-toggle="modal" data-target="#myModal4"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i> Replicate</a></li> | ||
102 | - <li><a href="javascript:void(0)" data-toggle="modal" data-target="#removeCourse"><i class="fa fa-trash fa-fw" aria-hidden="true"></i> Remove</a></li> | ||
103 | - </ul> | ||
104 | - </div> | ||
105 | - </div> | ||
106 | - {% endif %} | ||
107 | - </div> | ||
108 | - </div> | ||
109 | - <div class="panel-collapse collapseOne collapse in" role="tabpanel" aria-labelledby="headingOne" aria-expanded="true" aria-hidden="false" tabindex="0"> | ||
110 | - <div class="panel-body"> | ||
111 | - <p><b>Course Name: </b>{{course.name}}</p> | ||
112 | - <p><b>Duration (in semesters): </b>09</p> | ||
113 | - <p><b>Coordinator: </b>{{course.professors}}</p> | ||
114 | - <p> | ||
115 | - <b>Description:</b> | ||
116 | - <i> | ||
117 | - {{course.description}} | ||
118 | - </i> | ||
119 | - </p> | ||
120 | - <a href="{% url 'course:view' course.slug %}" class="btn btn-raised btn-default center-block">{% trans 'View Course' %}<div class="ripple-container"></div></a> | ||
121 | - </div> | ||
122 | - </div> | ||
123 | - </div> | ||
124 | - </div> | ||
125 | - </div> | 99 | + {% include "course/course_card.html" %} |
126 | {% endif %} | 100 | {% endif %} |
127 | {% endfor %} | 101 | {% endfor %} |
128 | {% endif %} | 102 | {% endif %} |
129 | {% else %} | 103 | {% else %} |
130 | {% trans 'No courses found' %} | 104 | {% trans 'No courses found' %} |
131 | {% endif %} | 105 | {% endif %} |
132 | - <div class="group"> | ||
133 | - <div class="modal" id="removeCourse"> | ||
134 | - <div class="modal-dialog"> | ||
135 | - <div class="modal-content"> | ||
136 | - <div class="modal-header"> | ||
137 | - <button type="button" class="close" data-dismiss="modal" aria-hidden="true">X</button> | ||
138 | - <h4 class="modal-title"></h4> | ||
139 | - </div> | ||
140 | - <div class="modal-body"> | ||
141 | - <p>Delete your course?</p> | ||
142 | - </div> | ||
143 | - <div class="modal-footer"> | ||
144 | - | ||
145 | - <a href="http://127.0.0.1:8080/html/screens/users/profile_user.html" target="_self"><button type="button" class="btn btn-primary">Confirm</button></a> | ||
146 | - | ||
147 | - </div> | ||
148 | - </div> | ||
149 | - </div> | ||
150 | - </div> | ||
151 | - </div> | ||
152 | </div> | 106 | </div> |
153 | <div class="col-md-12"> | 107 | <div class="col-md-12"> |
154 | <nav aria-label="Page navigation"> | 108 | <nav aria-label="Page navigation"> |
@@ -171,4 +125,6 @@ | @@ -171,4 +125,6 @@ | ||
171 | </ul> | 125 | </ul> |
172 | </nav> | 126 | </nav> |
173 | </div> | 127 | </div> |
128 | + | ||
129 | + <script type="text/javascript" src="{% static 'js/course.js' %}"></script> | ||
174 | {% endblock %} | 130 | {% endblock %} |
@@ -0,0 +1,135 @@ | @@ -0,0 +1,135 @@ | ||
1 | +{% extends 'course/view.html' %} | ||
2 | + | ||
3 | +{% load static i18n %} | ||
4 | +{% load widget_tweaks %} | ||
5 | + | ||
6 | +{% block breadcrumbs %} | ||
7 | + <ol class="breadcrumb"> | ||
8 | + <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li> | ||
9 | + <li class="active">{% trans 'Replicate Course' %}</li> | ||
10 | + </ol> | ||
11 | +{% endblock %} | ||
12 | + | ||
13 | +{% block content %} | ||
14 | +<div class="card card-content"> | ||
15 | + <div class="card-body"> | ||
16 | + <form method="post" action="" enctype="multipart/form-data">{% csrf_token %} | ||
17 | + <div class="form-group is-fileinput"> | ||
18 | + <label for="id_name">Name</label> | ||
19 | + | ||
20 | + | ||
21 | + <input class="form-control" id="id_name" maxlength="100" name="name" type="text" required="" value="{{course.name}}"> | ||
22 | + | ||
23 | + <span class="help-block">Course name</span> | ||
24 | + | ||
25 | + </div> | ||
26 | + | ||
27 | + <div class="form-group is-fileinput"> | ||
28 | + <label for="id_objectivies">Objectives</label> | ||
29 | + | ||
30 | + <textarea class="form-control" cols="80" id="id_objectivies" name="objectivies" rows="5">{{course.objectivies}}</textarea> | ||
31 | + | ||
32 | + <span class="help-block">Course objective</span> | ||
33 | + | ||
34 | + </div> | ||
35 | + | ||
36 | + <div class="form-group is-fileinput"> | ||
37 | + <label for="id_content">Content</label> | ||
38 | + | ||
39 | + | ||
40 | + <textarea class="form-control" cols="80" id="id_content" name="content" rows="5">{{course.content}}</textarea> | ||
41 | + | ||
42 | + <span class="help-block">Course modules</span> | ||
43 | + | ||
44 | + </div> | ||
45 | + | ||
46 | + <div class="form-group is-fileinput"> | ||
47 | + <label for="id_max_students">Number of studets maximum</label> | ||
48 | + | ||
49 | + | ||
50 | + <input class="form-control" id="id_max_students" min="0" name="max_students" type="number" value="{{course.max_students}}"> | ||
51 | + | ||
52 | + <span class="help-block">Max number of students that a class can have</span> | ||
53 | + | ||
54 | + </div> | ||
55 | + | ||
56 | + <div class="form-group is-fileinput"> | ||
57 | + <label for="id_init_register_date">Course registration start date</label> | ||
58 | + | ||
59 | + | ||
60 | + <input type="date" class="form-control" name="init_register_date" value="None" min="2016-10-24"> | ||
61 | + | ||
62 | + <span class="help-block">Date that starts the registration period of the course (dd/mm/yyyy)</span> | ||
63 | + | ||
64 | + </div> | ||
65 | + | ||
66 | + <div class="form-group is-fileinput"> | ||
67 | + <label for="id_end_register_date">Course registration end date</label> | ||
68 | + | ||
69 | + | ||
70 | + <input type="date" class="form-control" name="end_register_date" value="None" min="2016-10-24"> | ||
71 | + | ||
72 | + <span class="help-block">Date that ends the registration period of the course (dd/mm/yyyy)</span> | ||
73 | + | ||
74 | + </div> | ||
75 | + | ||
76 | + <div class="form-group is-fileinput"> | ||
77 | + <label for="id_init_date">Course start date</label> | ||
78 | + | ||
79 | + | ||
80 | + <input type="date" class="form-control" name="init_date" value="None" min="2016-10-24"> | ||
81 | + | ||
82 | + <span class="help-block">Date that the course starts (dd/mm/yyyy)</span> | ||
83 | + | ||
84 | + </div> | ||
85 | + | ||
86 | + <div class="form-group is-fileinput"> | ||
87 | + <label for="id_end_date">Course end date</label> | ||
88 | + | ||
89 | + | ||
90 | + <input type="date" class="form-control" name="end_date" value="None" min="2016-10-24"> | ||
91 | + | ||
92 | + <span class="help-block">Date that the course ends (dd/mm/yyyy)</span> | ||
93 | + | ||
94 | + </div> | ||
95 | + | ||
96 | + <div class="form-group is-fileinput"> | ||
97 | + <label for="id_image">Imagem</label> | ||
98 | + | ||
99 | + | ||
100 | + <input class="form-control" id="id_image" name="image" type="file"> | ||
101 | + <div class="input-group"> | ||
102 | + <input type="text" readonly="" class="form-control" placeholder="Choose your photo..."> | ||
103 | + <span class="input-group-btn input-group-sm"> | ||
104 | + <button type="button" class="btn btn-fab btn-fab-mini"> | ||
105 | + <i class="material-icons">attach_file</i> | ||
106 | + </button> | ||
107 | + </span> | ||
108 | + </div> | ||
109 | + | ||
110 | + <span class="help-block">Representative image of the course</span> | ||
111 | + | ||
112 | + </div> | ||
113 | + | ||
114 | + <div class="form-group is-fileinput"> | ||
115 | + <label for="id_category">CourseCategory</label> | ||
116 | + | ||
117 | + | ||
118 | + <select class="form-control" id="id_category" name="category" required=""> | ||
119 | + {% for category in categorys_courses %} | ||
120 | + <option value="{{category.id}}">{{category}}</option> | ||
121 | + {% endfor %} | ||
122 | + </select> | ||
123 | + | ||
124 | + <span class="help-block">CourseCategory which the course belongs</span> | ||
125 | + | ||
126 | + </div> | ||
127 | + | ||
128 | + <div class="row text-center"> | ||
129 | + <input type="submit" value="Create" class="btn btn-primary"> | ||
130 | + </div> | ||
131 | + </form> | ||
132 | + </div> | ||
133 | +</div> | ||
134 | +</br> | ||
135 | +{% endblock %} | ||
0 | \ No newline at end of file | 136 | \ No newline at end of file |
courses/templates/course/view.html
courses/urls.py
@@ -4,6 +4,7 @@ from . import views | @@ -4,6 +4,7 @@ from . import views | ||
4 | urlpatterns = [ | 4 | urlpatterns = [ |
5 | url(r'^$', views.IndexView.as_view(), name='manage'), | 5 | url(r'^$', views.IndexView.as_view(), name='manage'), |
6 | url(r'^create/$', views.CreateCourseView.as_view(), name='create'), | 6 | url(r'^create/$', views.CreateCourseView.as_view(), name='create'), |
7 | + url(r'^replicate_course/(?P<slug>[\w_-]+)/$', views.ReplicateCourseView.as_view(), name='replicate_course'), | ||
7 | url(r'^edit/(?P<slug>[\w_-]+)/$', views.UpdateCourseView.as_view(), name='update'), | 8 | url(r'^edit/(?P<slug>[\w_-]+)/$', views.UpdateCourseView.as_view(), name='update'), |
8 | url(r'^(?P<slug>[\w_-]+)/$', views.CourseView.as_view(), name='view'), | 9 | url(r'^(?P<slug>[\w_-]+)/$', views.CourseView.as_view(), name='view'), |
9 | url(r'^delete/(?P<slug>[\w_-]+)/$', views.DeleteCourseView.as_view(), name='delete'), | 10 | url(r'^delete/(?P<slug>[\w_-]+)/$', views.DeleteCourseView.as_view(), name='delete'), |
@@ -12,7 +13,6 @@ urlpatterns = [ | @@ -12,7 +13,6 @@ urlpatterns = [ | ||
12 | url(r'^categories/view/$', views.IndexCatView.as_view(), name='manage_cat'), | 13 | url(r'^categories/view/$', views.IndexCatView.as_view(), name='manage_cat'), |
13 | url(r'^categories/create/$', views.CreateCatView.as_view(), name="create_cat"), | 14 | url(r'^categories/create/$', views.CreateCatView.as_view(), name="create_cat"), |
14 | url(r'^categories/edit/(?P<slug>[\w_-]+)/$', views.UpdateCatView.as_view(), name='update_cat'), | 15 | url(r'^categories/edit/(?P<slug>[\w_-]+)/$', views.UpdateCatView.as_view(), name='update_cat'), |
15 | - url(r'^categories/(?P<slug>[\w_-]+)/$', views.ViewCat.as_view(), name='view_cat'), | ||
16 | url(r'^categories/delete/(?P<slug>[\w_-]+)/$', views.DeleteCatView.as_view(), name='delete_cat'), | 16 | url(r'^categories/delete/(?P<slug>[\w_-]+)/$', views.DeleteCatView.as_view(), name='delete_cat'), |
17 | url(r'^subjects/(?P<slug>[\w_-]+)/$', views.SubjectsView.as_view(), name='view_subject'), | 17 | url(r'^subjects/(?P<slug>[\w_-]+)/$', views.SubjectsView.as_view(), name='view_subject'), |
18 | url(r'^subjects/create/(?P<slug>[\w_-]+)/$', views.CreateSubjectView.as_view(), name='create_subject'), | 18 | url(r'^subjects/create/(?P<slug>[\w_-]+)/$', views.CreateSubjectView.as_view(), name='create_subject'), |
courses/views.py
@@ -36,9 +36,12 @@ class IndexView(LoginRequiredMixin, NotificationMixin, generic.ListView): | @@ -36,9 +36,12 @@ class IndexView(LoginRequiredMixin, NotificationMixin, generic.ListView): | ||
36 | context = super(IndexView, self).get_context_data(**kwargs) | 36 | context = super(IndexView, self).get_context_data(**kwargs) |
37 | list_courses = None | 37 | list_courses = None |
38 | categorys_courses = None | 38 | categorys_courses = None |
39 | - if has_role(self.request.user,'professor') or has_role(self.request.user,'system_admin'): | 39 | + if has_role(self.request.user,'professor'): |
40 | list_courses = Course.objects.filter(Q(professors = True)|Q(professors__name = self.request.user.name)).order_by('name') | 40 | list_courses = Course.objects.filter(Q(professors = True)|Q(professors__name = self.request.user.name)).order_by('name') |
41 | categorys_courses = CourseCategory.objects.filter(course_category__professors__name = self.request.user.name).distinct() | 41 | categorys_courses = CourseCategory.objects.filter(course_category__professors__name = self.request.user.name).distinct() |
42 | + elif has_role(self.request.user,'system_admin'): | ||
43 | + list_courses = queryset.order_by('name') | ||
44 | + categorys_courses = CourseCategory.objects.all() | ||
42 | else: | 45 | else: |
43 | list_courses = Course.objects.filter(Q(students = True)|Q(students__name = self.request.user.name)).order_by('name') | 46 | list_courses = Course.objects.filter(Q(students = True)|Q(students__name = self.request.user.name)).order_by('name') |
44 | categorys_courses = CourseCategory.objects.filter(course_category__students__name = self.request.user.name).distinct() | 47 | categorys_courses = CourseCategory.objects.filter(course_category__students__name = self.request.user.name).distinct() |
@@ -102,6 +105,38 @@ class CreateCourseView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,gener | @@ -102,6 +105,38 @@ class CreateCourseView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,gener | ||
102 | context['now'] = date.today() | 105 | context['now'] = date.today() |
103 | return context | 106 | return context |
104 | 107 | ||
108 | +class ReplicateCourseView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,generic.edit.CreateView): | ||
109 | + | ||
110 | + allowed_roles = ['professor', 'system_admin'] | ||
111 | + login_url = reverse_lazy("core:home") | ||
112 | + redirect_field_name = 'next' | ||
113 | + template_name = 'course/replicate.html' | ||
114 | + form_class = CourseForm | ||
115 | + success_url = reverse_lazy('course:manage') | ||
116 | + | ||
117 | + def form_valid(self, form): | ||
118 | + self.object = form.save() | ||
119 | + self.object.professors.add(self.request.user) | ||
120 | + return super(ReplicateCourseView, self).form_valid(form) | ||
121 | + | ||
122 | + def get_context_data(self, **kwargs): | ||
123 | + context = super(ReplicateCourseView, self).get_context_data(**kwargs) | ||
124 | + course = get_object_or_404(Course, slug = self.kwargs.get('slug')) | ||
125 | + if has_role(self.request.user,'system_admin'): | ||
126 | + courses = Course.objects.all() | ||
127 | + elif has_role(self.request.user,'professor'): | ||
128 | + courses = self.request.user.courses.all() | ||
129 | + categorys_courses = CourseCategory.objects.all() | ||
130 | + context['courses'] = courses | ||
131 | + context['course'] = course | ||
132 | + context['categorys_courses'] = categorys_courses | ||
133 | + context['title'] = _("Replicate Course") | ||
134 | + context['now'] = date.today() | ||
135 | + return context | ||
136 | + | ||
137 | + def get_success_url(self): | ||
138 | + return reverse_lazy('course:view', kwargs={'slug' : self.object.slug}) | ||
139 | + | ||
105 | class UpdateCourseView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): | 140 | class UpdateCourseView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): |
106 | 141 | ||
107 | allowed_roles = ['professor', 'system_admin'] | 142 | allowed_roles = ['professor', 'system_admin'] |
@@ -133,8 +168,6 @@ class UpdateCourseView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): | @@ -133,8 +168,6 @@ class UpdateCourseView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): | ||
133 | def get_success_url(self): | 168 | def get_success_url(self): |
134 | return reverse_lazy('course:view', kwargs={'slug' : self.object.slug}) | 169 | return reverse_lazy('course:view', kwargs={'slug' : self.object.slug}) |
135 | 170 | ||
136 | - | ||
137 | - | ||
138 | class DeleteCourseView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): | 171 | class DeleteCourseView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): |
139 | 172 | ||
140 | allowed_roles = ['professor', 'system_admin'] | 173 | allowed_roles = ['professor', 'system_admin'] |
@@ -297,13 +330,6 @@ class UpdateCatView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): | @@ -297,13 +330,6 @@ class UpdateCatView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): | ||
297 | messages.success(self.request, _('Category updated successfully!')) | 330 | messages.success(self.request, _('Category updated successfully!')) |
298 | return reverse_lazy('course:update_cat', kwargs={'slug' : self.object.slug}) | 331 | return reverse_lazy('course:update_cat', kwargs={'slug' : self.object.slug}) |
299 | 332 | ||
300 | -class ViewCat(LoginRequiredMixin, generic.DetailView): | ||
301 | - login_url = reverse_lazy("core:home") | ||
302 | - redirect_field_name = 'next' | ||
303 | - model = CourseCategory | ||
304 | - template_name = 'category/view.html' | ||
305 | - context_object_name = 'category' | ||
306 | - | ||
307 | class DeleteCatView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): | 333 | class DeleteCatView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): |
308 | 334 | ||
309 | allowed_roles = ['professor', 'system_admin'] | 335 | allowed_roles = ['professor', 'system_admin'] |