Commit 545ee28d64d146ce3b6ee478e3641fc3fa807dbc
Exists in
master
and in
5 other branches
Merge branch 'dev'
Showing
85 changed files
with
1180 additions
and
744 deletions
Show diff stats
.gitignore
README.md
... | ... | @@ -80,6 +80,40 @@ Para Classes que envolvem formulários: |
80 | 80 | * `CreateCourseForm` |
81 | 81 | * `UpdateCourseForm()` |
82 | 82 | |
83 | + | |
84 | +##API Description | |
85 | +We are using mostly viewsets ( http://www.django-rest-framework.org/api-guide/viewsets/) to build our API endpoints now, so all default methods and API points were kept. | |
86 | + | |
87 | +* model list(GET) = list all objects from that mode in pagination mode, each page has 10 | |
88 | +* model detail(GET) = give the details of the objects and most important fields of the ones objects its has relationships. | |
89 | +* model create | |
90 | + | |
91 | +**Courses (URL: coursesapi)** | |
92 | +* course list ("/coursesapi/") | |
93 | +* course detail ("/coursesapi/id") (id is a parameter) | |
94 | + | |
95 | +**Subject (URL: subjectapi)** | |
96 | +* subject list ("/subjectapi/") | |
97 | +* subject detail ("/subjectapi/id") (id is a parameter) | |
98 | + | |
99 | +**Topic (URL: topicsapi)** | |
100 | +* topics list ("/topicsapi/") | |
101 | +* topic detail ("/topicsapi/id") (id is a parameter) | |
102 | + | |
103 | +**logs (URL: logs)** | |
104 | +* logs list ("/logs/") | |
105 | +* log detail ("/logs/id") (id is a parameter) | |
106 | + | |
107 | +#Obtaining an Access Token | |
108 | +* First build an application o "amadeus/o/applications" following this tutorial: http://django-oauth-toolkit.readthedocs.io/en/latest/tutorial/tutorial_01.html#create-an-oauth2-client-application | |
109 | + | |
110 | +* Then request, using a valid user, an access token using the following template (you'll have to know how to translate a GET Method into a POST one) | |
111 | +curl -X POST -d "grant_type=password&username=<user_name>&password=<password>" -u"<client_id>:<client_secret>" http://amadeus/o/token/ | |
112 | + | |
113 | +* finally, with your access token you can use test using | |
114 | +curl -H "Authorization: Bearer <your_access_token>" -X POST -d"username=foo&password=bar" http://localhost:8000/users/ (inserting a new user) | |
115 | + | |
116 | + | |
83 | 117 | ## Link's úteis |
84 | 118 | [Git - Introdução e comandos básicos(PT-BR)](https://github.com/fernandomayer/git-rautu/blob/master/0_configuracao-inicial.md) |
85 | 119 | ... | ... |
amadeus/settings.py
... | ... | @@ -43,6 +43,7 @@ INSTALLED_APPS = [ |
43 | 43 | |
44 | 44 | 'widget_tweaks', |
45 | 45 | 'rolepermissions', |
46 | + 'oauth2_provider', | |
46 | 47 | 'rest_framework', |
47 | 48 | 'django_bootstrap_breadcrumbs', |
48 | 49 | 's3direct', |
... | ... | @@ -208,6 +209,22 @@ EMAIL_HOST_PASSWORD = 'amadeusteste' |
208 | 209 | # SMTP CONFIG |
209 | 210 | # EMAIL_BACKEND = 'core.smtp.AmadeusEmailBackend' |
210 | 211 | |
212 | +#API CONFIG STARTS | |
213 | +#TELL the rest framework to use a different backend | |
214 | +REST_FRAMEWORK = { | |
215 | + 'DEFAULT_AUTHENTICATION_CLASSES':( | |
216 | + 'oauth2_provider.ext.rest_framework.OAuth2Authentication',), | |
217 | + 'DEFAULT_PERMISSION_CLASSES':( | |
218 | + 'rest_framework.permissions.IsAuthenticated',), | |
219 | + 'PAGE_SIZE': 10, #pagination purposes | |
220 | +} | |
221 | + | |
222 | +OAUTH2_PROVIDER = { | |
223 | + 'SCOPES':{'read':'Read scope', 'write': 'Write scope'} | |
224 | +} | |
225 | +#API CONFIG ENDS | |
226 | + | |
227 | + | |
211 | 228 | #s3direct |
212 | 229 | |
213 | 230 | # AWS keys | ... | ... |
amadeus/uploads/ciencia-da-computacao/teorica/tipfef/Apresentacao_da_Cadidatura_a_Marketing_-_Matheus_Lins.pptx
No preview for this file type
amadeus/uploads/ciencia-da-computacao/teorica/tipfef/Cartao_Outubro.pdf
No preview for this file type
amadeus/uploads/django-summernote/2016-11-03/46bdc2b1-ba27-4385-b504-89916637edca.jpg
25.6 KB
amadeus/uploads/django-summernote/2016-11-03/bde587ad-9c4a-4e81-b07d-8f8aa5dced21.jpeg
12.2 KB
amadeus/uploads/django-summernote/2016-11-03/eaa22970-1d01-4deb-8232-60fd2be4f9fa.jpeg
12.2 KB
amadeus/uploads/links/default.jpg
19.5 KB
amadeus/uploads/sistemas-de-informacao/algoritmo/topico-1/Riachuelo_Outubro.pdf
No preview for this file type
amadeus/uploads/users/Captura_de_tela_de_2016-09-21_21-09-40.png
165 KB
amadeus/urls.py
... | ... | @@ -25,7 +25,8 @@ urlpatterns = [ |
25 | 25 | url(r'^users/', include('users.urls', namespace = 'users')), |
26 | 26 | url(r'^admin/', admin.site.urls), |
27 | 27 | url(r'^', include('core.urls', namespace = 'core')), |
28 | - | |
28 | + #API | |
29 | + url(r'^o/', include('oauth2_provider.urls', namespace='oauth2_provider')), | |
29 | 30 | #S3Direct |
30 | 31 | url(r'^s3direct/', include('s3direct.urls')), |
31 | 32 | url(r'^summernote/', include('django_summernote.urls')), | ... | ... |
app/forms.py
1 | 1 | from django import forms |
2 | +from django.core.validators import validate_email | |
2 | 3 | from .models import EmailBackend |
3 | 4 | from django.utils.translation import ugettext_lazy as _ |
4 | 5 | |
5 | 6 | class EmailBackendForm(forms.ModelForm): |
7 | + def clean_default_from_email(self): | |
8 | + default_email = self.cleaned_data['default_from_email'] | |
9 | + validate_email(default_email) | |
10 | + return default_email | |
6 | 11 | |
7 | 12 | class Meta: |
8 | 13 | model = EmailBackend | ... | ... |
app/templates/admin_settings.html
... | ... | @@ -19,10 +19,19 @@ |
19 | 19 | <!-- Nav tabs --> |
20 | 20 | <ul class="nav nav-tabs md-pills pills-ins" role="tablist"> |
21 | 21 | <li class="nav-item"> |
22 | + {% if form.safe_conection.errors or form.host.errors or form.default_from_email.errors %} | |
23 | + <a class="nav-link" data-toggle="tab" href="#panel1" role="tab"><i class="fa fa-cog"></i> {% trans "System" %}</a> | |
24 | + </li> | |
25 | + <li class="nav-item"> | |
26 | + <a class="nav-link active" data-toggle="tab" href="#panel2" role="tab"><i class="fa fa-envelope"></i> {% trans "Mail Sender" %}</a> | |
27 | + </li> | |
28 | + {% else %} | |
22 | 29 | <a class="nav-link active" data-toggle="tab" href="#panel1" role="tab"><i class="fa fa-cog"></i> {% trans "System" %}</a> |
23 | - </li> | |
30 | + </li> | |
24 | 31 | <li class="nav-item"> |
25 | - <a class="nav-link" data-toggle="tab" href="#panel2" role="tab"><i class="fa fa-envelope"></i> {% trans "Mail Sender" %}</a> | |
32 | + <a class="nav-link" data-toggle="tab" href="#panel2" role="tab"><i class="fa fa-envelope"></i> {% trans "Mail Sender" %}</a> | |
33 | + </li> | |
34 | + {% endif %} | |
26 | 35 | </li> |
27 | 36 | <li class="nav-item"> |
28 | 37 | <a class="nav-link" data-toggle="tab" href="#panel3" role="tab"><i class="fa fa-lock"></i> {% trans "Security" %}</a> |
... | ... | @@ -32,7 +41,11 @@ |
32 | 41 | <!-- Tab panels --> |
33 | 42 | <div class="tab-content"> |
34 | 43 | <!--Panel 1--> |
44 | + {% if form.errors %} | |
45 | + <div class="tab-pane fade" id="panel1" role="tabpanel"> | |
46 | + {% else %} | |
35 | 47 | <div class="tab-pane fade in active" id="panel1" role="tabpanel"> |
48 | + {% endif %} | |
36 | 49 | <div class="panel panel-default"> |
37 | 50 | <div class="panel-body"> |
38 | 51 | <h3><b>{% trans "General" %}</b></h3> |
... | ... | @@ -48,7 +61,11 @@ |
48 | 61 | <!--/.Panel 1--> |
49 | 62 | |
50 | 63 | <!--Panel 2--> |
64 | + {% if form.errors %} | |
65 | + <div class="tab-pane fade in active" id="panel2" role="tabpanel"> | |
66 | + {% else %} | |
51 | 67 | <div class="tab-pane fade" id="panel2" role="tabpanel"> |
68 | + {% endif %} | |
52 | 69 | <div class="panel panel-default"> |
53 | 70 | <form class="form-horizontal" method="post"> |
54 | 71 | {% csrf_token %} |
... | ... | @@ -59,7 +76,11 @@ |
59 | 76 | <h4><b>{% trans "Settings" %}</b></b></h4> |
60 | 77 | <hr> |
61 | 78 | <div class="form-group label-floating"> |
62 | - <label class="control-label" for="{{ form.description.auto_id }}">{{ form.description.label }}</label> | |
79 | + {% if form.description.field.required %} | |
80 | + <label class="control-label" for="{{ form.description.auto_id }}">{{ form.description.label }}<span>*</span></label> | |
81 | + {% else %} | |
82 | + <label class="control-label" for="{{ form.description.auto_id }}">{{ form.description.label }}</label> | |
83 | + {% endif %} | |
63 | 84 | {% render_field form.description class='form-control' %} |
64 | 85 | </div> |
65 | 86 | {% if form.description.errors %} |
... | ... | @@ -75,7 +96,11 @@ |
75 | 96 | </div> |
76 | 97 | {% endif %} |
77 | 98 | <div class="form-group label-floating"> |
78 | - <label class="control-label" for="{{ form.host.auto_id }}">{{ form.host.label }}</label> | |
99 | + {% if form.host.field.required %} | |
100 | + <label class="control-label" for="{{ form.host.auto_id }}">{{ form.host.label }}<span>*</span></label> | |
101 | + {% else %} | |
102 | + <label class="control-label" for="{{ form.host.auto_id }}">{{ form.host.label }}</label> | |
103 | + {% endif %} | |
79 | 104 | {% render_field form.host class='form-control' %} |
80 | 105 | </div> |
81 | 106 | {% if form.host.errors %} |
... | ... | @@ -91,7 +116,11 @@ |
91 | 116 | </div> |
92 | 117 | {% endif %} |
93 | 118 | <div class="form-group label-floating"> |
94 | - <label for="{{ form.port.auto_id }}" class="control-label">{{ form.port.label }}</label> | |
119 | + {% if form.port.field.required %} | |
120 | + <label class="control-label" for="{{ form.port.auto_id }}">{{ form.port.label }}<span>*</span></label> | |
121 | + {% else %} | |
122 | + <label class="control-label" for="{{ form.port.auto_id }}">{{ form.port.label }}</label> | |
123 | + {% endif %} | |
95 | 124 | <div class="col-md-2"> |
96 | 125 | {% render_field form.port class='form-control' onkeypress='campoNumerico(this,event);' %} |
97 | 126 | </div> |
... | ... | @@ -120,7 +149,11 @@ |
120 | 149 | <h4><b>{% trans "Security and authentication" %}</b></h4> |
121 | 150 | <hr> |
122 | 151 | <div class="form-group label-floating"> |
123 | - <label class="control-label" for="{{ form.username.auto_id }}">{{ form.username.label }}</label> | |
152 | + {% if form.username.field.required %} | |
153 | + <label class="control-label" for="{{ form.username.auto_id }}">{{ form.username.label }}<span>*</span></label> | |
154 | + {% else %} | |
155 | + <label class="control-label" for="{{ form.username.auto_id }}">{{ form.username.label }}</label> | |
156 | + {% endif %} | |
124 | 157 | {% render_field form.username class='form-control' %} |
125 | 158 | </div> |
126 | 159 | {% if form.username.errors %} |
... | ... | @@ -136,7 +169,11 @@ |
136 | 169 | </div> |
137 | 170 | {% endif %} |
138 | 171 | <div class="form-group label-floating"> |
139 | - <label class="control-label" for="{{ form.password.auto_id }}">{{ form.password.label }}</label> | |
172 | + {% if form.password.field.required %} | |
173 | + <label class="control-label" for="{{ form.password.auto_id }}">{{ form.password.label }}<span>*</span></label> | |
174 | + {% else %} | |
175 | + <label class="control-label" for="{{ form.password.auto_id }}">{{ form.password.label }}</label> | |
176 | + {% endif %} | |
140 | 177 | {% render_field form.password type='password' class='form-control' %} |
141 | 178 | </div> |
142 | 179 | {% if form.password.errors %} |
... | ... | @@ -152,7 +189,11 @@ |
152 | 189 | </div> |
153 | 190 | {% endif %} |
154 | 191 | <div class="form-group label-floating"> |
155 | - <label class="control-label" for="{{ form.default_from_email.auto_id }}">{{ form.default_from_email.label }}</label> | |
192 | + {% if form.default_from_email.field.required %} | |
193 | + <label class="control-label" for="{{ form.default_from_email.auto_id }}">{{ form.default_from_email.label }}<span>*</span></label> | |
194 | + {% else %} | |
195 | + <label class="control-label" for="{{ form.default_from_email.auto_id }}">{{ form.default_from_email.label }}</label> | |
196 | + {% endif %} | |
156 | 197 | {% render_field form.default_from_email class='form-control' %} |
157 | 198 | </div> |
158 | 199 | {% if form.default_from_email.errors %} |
... | ... | @@ -168,7 +209,11 @@ |
168 | 209 | </div> |
169 | 210 | {% endif %} |
170 | 211 | <div class="form-group"> |
171 | - <p><b>{{ form.safe.connection.label }}</b></p> | |
212 | + {% if form.safe_conection.fiel.required %} | |
213 | + <p><b>{{ form.safe_conection.label }}<span>*</span></b></p> | |
214 | + {% else %} | |
215 | + <p><b>{{ form.safe_conection.label }}</b></p> | |
216 | + {% endif %} | |
172 | 217 | <div class="col-md-10"> |
173 | 218 | <div class="radio radio-primary"> |
174 | 219 | {% for value, text in form.safe_conection.field.choices %} |
... | ... | @@ -186,13 +231,13 @@ |
186 | 231 | </div> |
187 | 232 | </div> |
188 | 233 | </div> |
189 | - {% if form.safe_connection.errors %} | |
234 | + {% if form.safe_conection.errors %} | |
190 | 235 | <div class="alert alert-danger alert-dismissible clearfix" role="alert"> |
191 | 236 | <button type="button" class="close" data-dismiss="alert" aria-label="Close"> |
192 | 237 | <span aria-hidden="true">×</span> |
193 | 238 | </button> |
194 | 239 | <ul> |
195 | - {% for error in form.safe_connection.errors %} | |
240 | + {% for error in form.safe_conection.errors %} | |
196 | 241 | <li>{{ error }}</li> |
197 | 242 | {% endfor %} |
198 | 243 | </ul> |
... | ... | @@ -200,7 +245,7 @@ |
200 | 245 | {% endif %} |
201 | 246 | </div> |
202 | 247 | </div> |
203 | - <button type="submit" class="btn btn-success btn-raised">{% trans "Save changes" %}</button> | |
248 | + <button type="submit" class="btn btn-success btn-raised" name="submit-settings">{% trans "Save changes" %}</button> | |
204 | 249 | </div> |
205 | 250 | </form> |
206 | 251 | </div> | ... | ... |
app/templates/home.html
... | ... | @@ -66,6 +66,7 @@ |
66 | 66 | {% breadcrumb 'Home' 'app:index' %} |
67 | 67 | {% endblock %} |
68 | 68 | |
69 | + | |
69 | 70 | {% block render_breadcrumbs %} |
70 | 71 | {% render_breadcrumbs %} |
71 | 72 | {% endblock %} |
... | ... | @@ -77,13 +78,10 @@ |
77 | 78 | </div> |
78 | 79 | <div class="panel-body"> |
79 | 80 | <ul class="nav nav-pills nav-stacked"> |
80 | - <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li> | |
81 | - <li><a href="{% url 'users:profile' %}">{% trans 'Profile' %}</a></li> | |
82 | 81 | {% if user|has_role:'student' or not user.is_staff %} |
83 | 82 | <li><a href="{% url 'course:manage' %}">{% trans 'My courses' %}</a></li> |
84 | 83 | <li><a href="{% url 'course:all_courses' %}">{% trans 'All Courses' %}</a></li> |
85 | 84 | {% endif %} |
86 | - <li><a href="{% url 'core:guest' %}">{% trans 'Courses' %}</a></li> | |
87 | 85 | {% if user|has_role:'system_admin' %} |
88 | 86 | <li> <a href="{% url 'users:manage' %}">{% trans 'Manage Users' %}</a></li> |
89 | 87 | <li> <a href="{% url 'app:settings' %}">{% trans 'Settings' %}</a></li> | ... | ... |
app/templates/home_professor.html
... | ... | @@ -15,18 +15,6 @@ |
15 | 15 | {% endblock %} |
16 | 16 | |
17 | 17 | {% block sidebar %} |
18 | - <div class="panel panel-primary"> | |
19 | - <div class="panel-heading"> | |
20 | - <h5>{% trans 'Menu' %}</h5> | |
21 | - </div> | |
22 | - <div class="panel-body"> | |
23 | - <ul class="nav nav-pills nav-stacked"> | |
24 | - <li><a href="javascript:void(0)">{% trans 'Pending tasks' %}</a></li> | |
25 | - <li><a href="{% url 'course:create' %}">{% trans 'Create Course' %}</a></li> | |
26 | - <li><a href="{% url 'course:manage' %}">{% trans 'Manage Course' %}</a></li> | |
27 | - </ul> | |
28 | - </div> | |
29 | - </div> | |
30 | 18 | {% endblock %} |
31 | 19 | |
32 | 20 | {% block content %} | ... | ... |
app/templates/home_student.html
... | ... | @@ -16,19 +16,6 @@ |
16 | 16 | |
17 | 17 | |
18 | 18 | {% block sidebar %} |
19 | - <div class="panel panel-primary"> | |
20 | - <div class="panel-heading"> | |
21 | - <h4>{% trans 'Menu' %}</h4> | |
22 | - </div> | |
23 | - <div class="panel-body"> | |
24 | - <ul class="nav nav-pills nav-stacked"> | |
25 | - <li><a href="{% url 'users:profile' %}">{% trans 'Profile' %}</a></li> | |
26 | - <li><a href="{% url 'course:manage' %}">{% trans 'My Courses' %}</a></li> | |
27 | - <li><a href="{% url 'course:all_courses' %}">{% trans 'All Courses' %}</a></li> | |
28 | - <li><a href="javascript:void(0)">{% trans 'Google accounts' %}</a></li> | |
29 | - </ul> | |
30 | - </div> | |
31 | - </div> | |
32 | 19 | {% endblock %} |
33 | 20 | |
34 | 21 | {% block content %} | ... | ... |
app/views.py
... | ... | @@ -75,11 +75,12 @@ class AmadeusSettings(LoginRequiredMixin, HasRoleMixin, generic.CreateView): |
75 | 75 | |
76 | 76 | def get_context_data(self, **kwargs): |
77 | 77 | context = super(AmadeusSettings, self).get_context_data(**kwargs) |
78 | - try: | |
79 | - setting = EmailBackend.objects.latest('id') | |
80 | - context['form'] = EmailBackendForm(instance = setting) | |
81 | - except: | |
82 | - pass | |
78 | + if not self.request.method == 'POST': | |
79 | + try: | |
80 | + setting = EmailBackend.objects.latest('id') | |
81 | + context['form'] = EmailBackendForm(instance = setting) | |
82 | + except: | |
83 | + pass | |
83 | 84 | return context |
84 | 85 | |
85 | 86 | ... | ... |
core/decorators.py
... | ... | @@ -38,7 +38,8 @@ def log_decorator(log_component = '', log_action = '', log_resource = ''): |
38 | 38 | log = Log() |
39 | 39 | log.user = request.user |
40 | 40 | log.component = log_component |
41 | - log.context = json.dumps(request.log_context) | |
41 | + #log.context = json.dumps(request.log_context) | |
42 | + log.context = request.log_context | |
42 | 43 | log.action_resource = action_resource |
43 | 44 | |
44 | 45 | log.save() | ... | ... |
core/forms.py
... | ... | @@ -16,7 +16,7 @@ class RegisterUserForm(forms.ModelForm): |
16 | 16 | |
17 | 17 | def validate_cpf(self, cpf): |
18 | 18 | cpf = ''.join(re.findall('\d', str(cpf))) |
19 | - | |
19 | + | |
20 | 20 | if cpfcnpj.validate(cpf): |
21 | 21 | return True |
22 | 22 | return False |
... | ... | @@ -38,8 +38,8 @@ class RegisterUserForm(forms.ModelForm): |
38 | 38 | cpf = self.cleaned_data['cpf'] |
39 | 39 | if User.objects.filter(cpf = cpf).exists(): |
40 | 40 | raise forms.ValidationError(_('There is already a registeres User with this CPF')) |
41 | - if not self.validate_cpf(cpf): | |
42 | - raise forms.ValidationError(_('Please enter a valid CPF')) | |
41 | + # if not self.validate_cpf(cpf): | |
42 | + # raise forms.ValidationError(_('Please enter a valid CPF')) | |
43 | 43 | return cpf |
44 | 44 | |
45 | 45 | def clean_password(self): |
... | ... | @@ -68,12 +68,12 @@ class RegisterUserForm(forms.ModelForm): |
68 | 68 | def save(self, commit=True): |
69 | 69 | super(RegisterUserForm, self).save(commit=False) |
70 | 70 | self.instance.set_password(self.cleaned_data['password']) |
71 | - | |
71 | + | |
72 | 72 | self.instance.save() |
73 | 73 | return self.instance |
74 | 74 | |
75 | 75 | class Meta: |
76 | 76 | model = User |
77 | 77 | # exclude = ['is_staff', 'is_active'] |
78 | - fields = ['username', 'name', 'email', 'city', 'state', 'gender', 'cpf', 'birth_date', 'phone', 'image', 'titration', | |
78 | + fields = ['username', 'name', 'email', 'city', 'state', 'gender', 'cpf', 'birth_date', 'phone', 'image', 'titration', | |
79 | 79 | 'year_titration', 'institution', 'curriculum',] |
80 | 80 | \ No newline at end of file | ... | ... |
core/middleware.py
1 | 1 | from datetime import datetime |
2 | +import time | |
3 | +from django.core.urlresolvers import resolve | |
2 | 4 | from django.shortcuts import get_object_or_404 |
3 | 5 | import json |
4 | 6 | |
... | ... | @@ -9,33 +11,24 @@ class TimeSpentMiddleware(object): |
9 | 11 | self.get_response = get_response |
10 | 12 | |
11 | 13 | def process_request(self, request): |
12 | - if not request.is_ajax(): | |
13 | - log_id = request.session.get('log_id', None) | |
14 | + app_names = resolve(request.path).app_names | |
14 | 15 | |
15 | - if not log_id is None: | |
16 | - log = get_object_or_404(Log, id = log_id) | |
16 | + if not 'admin' in app_names: | |
17 | + if not request.is_ajax(): | |
18 | + log_id = request.session.get('log_id', None) | |
17 | 19 | |
18 | - date_time_click = datetime.strptime(request.session.get('time_spent'), "%Y-%m-%d %H:%M:%S.%f") | |
19 | - _now = datetime.now() | |
20 | - | |
21 | - time_spent = _now - date_time_click | |
22 | - | |
23 | - secs = time_spent.total_seconds() | |
24 | - hours = int(secs / 3600) | |
25 | - minutes = int(secs / 60) % 60 | |
26 | - secs = secs % 60 | |
20 | + if not log_id is None: | |
21 | + log = get_object_or_404(Log, id = log_id) | |
27 | 22 | |
28 | - log_context = json.loads(log.context) | |
23 | + if type(log.context) == dict: | |
24 | + log_context = log.context | |
25 | + else: | |
26 | + log_context = json.loads(log.context) | |
29 | 27 | |
30 | - log_context['time_spent'] = {} | |
31 | - log_context['time_spent']['hours'] = hours | |
32 | - log_context['time_spent']['minutes'] = minutes | |
33 | - log_context['time_spent']['seconds'] = secs | |
28 | + log_context['timestamp_end'] = str(int(time.time())) | |
34 | 29 | |
35 | - log.context = json.dumps(log_context) | |
36 | - | |
37 | - log.save() | |
38 | - | |
39 | - request.session['log_id'] = None | |
30 | + log.context = log_context | |
40 | 31 | |
32 | + log.save() | |
41 | 33 | |
34 | + request.session['log_id'] = None | ... | ... |
core/mixins.py
core/models.py
... | ... | @@ -2,6 +2,7 @@ from django.db import models |
2 | 2 | from django.utils.translation import ugettext_lazy as _ |
3 | 3 | from users.models import User |
4 | 4 | from autoslug.fields import AutoSlugField |
5 | +from django.contrib.postgres.fields import JSONField | |
5 | 6 | # Create your models here. |
6 | 7 | |
7 | 8 | class MimeType(models.Model): |
... | ... | @@ -102,7 +103,7 @@ class Notification(models.Model): |
102 | 103 | |
103 | 104 | class Log(models.Model): |
104 | 105 | component = models.TextField(_('Component (Module / App)')) |
105 | - context = models.TextField(_('Context'), blank = True) | |
106 | + context = JSONField(_('Context'), blank = True) | |
106 | 107 | action_resource = models.ForeignKey(Action_Resource, verbose_name = _('Action_Resource')) |
107 | 108 | user = models.ForeignKey(User, verbose_name = _('Actor')) |
108 | 109 | datetime = models.DateTimeField(_("Date and Time of action"), auto_now_add = True) | ... | ... |
core/serializers.py
core/static/css/base/amadeus.css
... | ... | @@ -22,6 +22,9 @@ |
22 | 22 | position: absolute; |
23 | 23 | left: 30%; |
24 | 24 | } |
25 | +#btn-search{ | |
26 | + margin-bottom: 0px; | |
27 | + } | |
25 | 28 | .user-notification-img{ |
26 | 29 | width:40%; |
27 | 30 | } |
... | ... | @@ -427,7 +430,7 @@ ul, li { |
427 | 430 | .course-card-group{ |
428 | 431 | margin-bottom: 1%; |
429 | 432 | } |
430 | - | |
433 | +.data_register_course p{ color: grey; } | |
431 | 434 | .category-course-link{ |
432 | 435 | font-size: 24px; |
433 | 436 | color: black !important; |
... | ... | @@ -453,4 +456,4 @@ ul, li { |
453 | 456 | |
454 | 457 | #panel2 .col-md-2, #panel2 .col-md-10{ |
455 | 458 | padding-left: 0; |
456 | -} | |
457 | 459 | \ No newline at end of file |
460 | +} | ... | ... |
... | ... | @@ -0,0 +1,79 @@ |
1 | + | |
2 | +var x = 0; | |
3 | +$(".edit_card").on('click', function() { | |
4 | + $(".presentation").css('display','none'); | |
5 | + $(".editation").css('display','block'); | |
6 | +}) | |
7 | +$(".edit_card_end").on('click', function() { | |
8 | + $(".editation").css('display','none'); | |
9 | + $(".presentation").css('display','block'); | |
10 | +}) | |
11 | + | |
12 | +$("#bot").on('click', function(){ | |
13 | + x = x+1; | |
14 | + console.log(2) | |
15 | + if(x%2 == 0){ | |
16 | + console.log(0) | |
17 | + $("#down").attr('class', 'fa fa-caret-square-o-down'); | |
18 | +} | |
19 | +else{ | |
20 | + console.log(1) | |
21 | + $("#down").attr('class', 'fa fa-caret-square-o-up'); | |
22 | +} | |
23 | + | |
24 | +}) | |
25 | +$("#bot1").on('click', function(){ | |
26 | + x = x+1; | |
27 | + console.log(2) | |
28 | + if(x%2 == 0){ | |
29 | + console.log(0) | |
30 | + $("#down1").attr('class', 'fa fa-caret-square-o-down'); | |
31 | +} | |
32 | +else{ | |
33 | + console.log(1) | |
34 | + $("#down1").attr('class', 'fa fa-caret-square-o-up'); | |
35 | +} | |
36 | + | |
37 | +}) | |
38 | + | |
39 | +$("#bot2").on('click', function(){ | |
40 | + x = x+1; | |
41 | + console.log(2) | |
42 | + if(x%2 == 0){ | |
43 | + console.log(0) | |
44 | + $("#down2").attr('class', 'fa fa-caret-square-o-down'); | |
45 | +} | |
46 | +else{ | |
47 | + console.log(1) | |
48 | + $("#down2").attr('class', 'fa fa-caret-square-o-up'); | |
49 | +} | |
50 | + | |
51 | +}) | |
52 | + | |
53 | +$("#bot3").on('click', function(){ | |
54 | + x = x+1; | |
55 | + console.log(2) | |
56 | + if(x%2 == 0){ | |
57 | + console.log(0) | |
58 | + $("#down3").attr('class', 'fa fa-caret-square-o-down'); | |
59 | +} | |
60 | +else{ | |
61 | + console.log(1) | |
62 | + $("#down3").attr('class', 'fa fa-caret-square-o-up'); | |
63 | +} | |
64 | + | |
65 | +}) | |
66 | +$("#bot4").on('click', function(){ | |
67 | + x = x+1; | |
68 | + console.log(2) | |
69 | + if(x%2 == 0){ | |
70 | + console.log(0) | |
71 | + $("#down4").attr('class', 'fa fa-caret-square-o-down'); | |
72 | +} | |
73 | +else{ | |
74 | + console.log(1) | |
75 | + $("#down4").attr('class', 'fa fa-caret-square-o-up'); | |
76 | +} | |
77 | + | |
78 | +}) | |
79 | + | ... | ... |
core/templates/base.html
... | ... | @@ -54,6 +54,12 @@ |
54 | 54 | {% endblock %} |
55 | 55 | {% block javascript %} |
56 | 56 | {% endblock %} |
57 | + | |
58 | + <!-- Summernote --> | |
59 | + <script src="http://podivej.se/js/summernote.min.js" type="text/javascript"></script> | |
60 | + <link href="http://podivej.se/css/summernote.css" type="text/css" rel="stylesheet" /> | |
61 | + <link href="http://podivej.se/css/summernote-bs3.css" type="text/css" rel="stylesheet"> | |
62 | + | |
57 | 63 | </head> |
58 | 64 | <body> |
59 | 65 | {% block nav %} |
... | ... | @@ -66,20 +72,24 @@ |
66 | 72 | </button> |
67 | 73 | <a class="navbar-brand" href="{% url 'app:index' %}"><img class="logo" src="{% static 'img/topo-amadeus-white.png' %}" alt="Logo"/></a> |
68 | 74 | </div> |
69 | - <div class="navbar-collapse collapse navbar-responsive-collapse"> | |
75 | + <div class="navbar-collapse collapse navbar-responsive-collapse"> | |
70 | 76 | <div class="col-md-5 cards-content" id= 'NavBarSearch'> |
71 | 77 | <form id="SearchForm" action="{% url 'users:search' %}" method="get" accept-charset="utf-8"> |
72 | 78 | <div class="input-group"> |
73 | 79 | <div class="form-group is-empty" > |
74 | - <input type="text" class="form-control" placeholder="{% trans 'Search Files (.pdf, others) and/or activities' %}" name="search"></div> | |
80 | + <input type="text" class="form-control" placeholder="{% trans 'Search Files (.pdf, others) and/or activities' %}" name="search"> | |
81 | + </div> | |
75 | 82 | <span class="input-group-btn input-group-sm"> |
76 | - <button type="submit" class="btn btn-fab btn-fab-mini"> | |
77 | - <i class="glyphicon glyphicon-search" aria-hidden="true" style="color:#93C741"></i> | |
83 | + <button type="submit" class="btn btn-primary" id="btn-search"> | |
84 | + <i class="fa fa-search fa-2x" aria-hidden="true" style="color:#93C741"></i> | |
78 | 85 | </button> |
79 | - </span> | |
86 | + </span> | |
87 | + | |
88 | + | |
80 | 89 | </div> |
81 | 90 | </form> |
82 | 91 | </div> |
92 | + | |
83 | 93 | <ul class="nav navbar-nav navbar-right notifications"> |
84 | 94 | <li class="" data-toggle="tooltip" data-placement="bottom" title data-original-title="notifications"> |
85 | 95 | <a class="dropdown-toggle" data-toggle="dropdown"> <span id="notification-count" class="badge notification-count">{{notifications.count}}</span><i class="fa fa-bell" aria-hidden="true"></i></a> |
... | ... | @@ -109,53 +119,6 @@ |
109 | 119 | <div class="row"> |
110 | 120 | <div class="col-xs-2 col-sm-2 col-md-2 col-lg-2 col-xl-2"> |
111 | 121 | {% block sidebar %} |
112 | - <div class="panel panel-primary navigation"> | |
113 | - <div class="panel-heading"> | |
114 | - <h4>{% trans "Menu" %}</h4> | |
115 | - </div> | |
116 | - <div class="panel-body"> | |
117 | - <ul class="nav nav-pills nav-stacked"> | |
118 | - <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li> | |
119 | - <li><a href="{% url 'users:profile' %}">{% trans 'Profile' %}</a></li> | |
120 | - {% if user|has_role:'student' or not user.is_staff %} | |
121 | - <li><a href="{% url 'course:manage' %}">{% trans 'My courses' %}</a></li> | |
122 | - <li><a href="{% url 'core:all_courses' %}">{% trans 'All Courses' %}</a></li> | |
123 | - {% endif %} | |
124 | - <li><a href="{% url 'core:guest' %}">{% trans 'Courses' %}</a></li> | |
125 | - {% if user|has_role:'system_admin' %} | |
126 | - <li> <a href="{% url 'users:manage' %}">{% trans 'Manage Users' %}</a></li> | |
127 | - {% endif %} | |
128 | - {% if user|has_role:'system_admin' or user|has_role:'professor' %} | |
129 | - <li> | |
130 | - <a href="#courses_list" class="accordion" data-toggle="collapse">{% trans 'Manage Courses' %}</a> | |
131 | - <div id="courses_list" class="collapse"> | |
132 | - <ul class="nav nav-pill nav-stacked accordion_list"> | |
133 | - {% for course in courses_list %} | |
134 | - <li><a href="{% url 'course:view' course.slug %}">{{ course }}</a></li> | |
135 | - {% endfor %} | |
136 | - </ul> | |
137 | - </div> | |
138 | - </li> | |
139 | - {% endif %} | |
140 | - </ul> | |
141 | - </div> | |
142 | - </div> | |
143 | - | |
144 | - {% if user|has_role:'professor' or user|has_role:'system_admin' %} | |
145 | - | |
146 | - <div class="panel panel-primary navigation"> | |
147 | - <div class="panel-heading"> | |
148 | - <h3 class="panel-title">{% trans 'Category' %}</h3> | |
149 | - </div> | |
150 | - <div class="panel-body"> | |
151 | - <ul class="nav nav-pills nav-stacked"> | |
152 | - <li><a href="{% url 'course:create_cat' %}">{% trans 'Create Category'%}</a></li> | |
153 | - <li><a href="{% url 'course:manage_cat' %}">{% trans 'List Category' %}</a></li> | |
154 | - </ul> | |
155 | - </div> | |
156 | - </div> | |
157 | - | |
158 | - {% endif %} | |
159 | 122 | {% endblock %} |
160 | 123 | </div> |
161 | 124 | <div class="col-xs-10 col-sm-10 col-md-10 col-lg-10 col-xl-10"> | ... | ... |
core/urls.py
... | ... | @@ -3,6 +3,19 @@ from django.contrib.auth import views as auth_views |
3 | 3 | from django.contrib.auth.views import password_reset, password_reset_done,password_reset_confirm, password_reset_complete |
4 | 4 | from . import views |
5 | 5 | |
6 | +#API IMPORTS | |
7 | +from rest_framework import routers | |
8 | + | |
9 | +from users.views import UserViewSet | |
10 | +from courses.views import CourseViewSet, TopicViewSet, SubjectViewSet | |
11 | + | |
12 | +#API CODE | |
13 | +router = routers.DefaultRouter() | |
14 | +router.register(r'logs', views.LogViewSet) | |
15 | +router.register(r'usersapi', UserViewSet) | |
16 | +router.register(r'coursesapi', CourseViewSet) | |
17 | +router.register(r'topicsapi', TopicViewSet) | |
18 | +router.register(r'subjectapi', SubjectViewSet) | |
6 | 19 | |
7 | 20 | urlpatterns = [ |
8 | 21 | url(r'^$', views.login, name='home'), |
... | ... | @@ -14,7 +27,8 @@ urlpatterns = [ |
14 | 27 | url(r'^guest/$', views.GuestView.as_view(), name='guest'), |
15 | 28 | |
16 | 29 | #API REST |
17 | - url(r'^logs/$', views.get_log), | |
30 | + url(r'^', include(router.urls)), | |
31 | + #url(r'^logs/$', views.get_log), | |
18 | 32 | |
19 | 33 | #Reset Password |
20 | 34 | |
... | ... | @@ -30,3 +44,5 @@ urlpatterns = [ |
30 | 44 | url(r'^done/$', password_reset_complete,{'template_name':'registration/passwor_reset_complete.html'}), |
31 | 45 | |
32 | 46 | ] |
47 | + | |
48 | + | ... | ... |
core/views.py
... | ... | @@ -16,8 +16,9 @@ from rolepermissions.shortcuts import assign_role |
16 | 16 | from django.contrib.auth.decorators import login_required |
17 | 17 | #API REST IMPORTS |
18 | 18 | from .serializers import LogSerializer |
19 | -from rest_framework.renderers import JSONRenderer | |
20 | -from rest_framework.parsers import JSONParser | |
19 | +from rest_framework import status, serializers, permissions, viewsets | |
20 | +from rest_framework.response import Response | |
21 | +from rest_framework.decorators import api_view | |
21 | 22 | |
22 | 23 | from .forms import RegisterUserForm |
23 | 24 | from .decorators import log_decorator, notification_decorator |
... | ... | @@ -135,19 +136,10 @@ class GuestView (ListView): |
135 | 136 | context['categorys_courses'] = CourseCategory.objects.all() |
136 | 137 | return context |
137 | 138 | |
138 | -class JSONResponse(HttpResponse): | |
139 | - """ | |
140 | - An HttpResponse that renders its content into JSON. | |
141 | - """ | |
142 | - def __init__(self, data, **kwargs): | |
143 | - content = JSONRenderer().render(data) | |
144 | - kwargs['content_type'] = 'application/json' | |
145 | - super(JSONResponse, self).__init__(content, **kwargs) | |
139 | + | |
146 | 140 | |
147 | 141 | #REST API VIEWS |
148 | -@login_required | |
149 | -def get_log(request): | |
150 | - if request.method == 'GET': | |
151 | - logs = Log.objects.all() | |
152 | - serializer = LogSerializer(logs, many=True) | |
153 | - return JSONResponse(serializer.data) | |
142 | +class LogViewSet(viewsets.ModelViewSet): | |
143 | + permission_classes = [permissions.IsAuthenticated] | |
144 | + queryset = Log.objects.all() | |
145 | + serializer_class = LogSerializer | ... | ... |
courses/forms.py
... | ... | @@ -51,34 +51,37 @@ class CourseForm(forms.ModelForm): |
51 | 51 | class Meta: |
52 | 52 | model = Course |
53 | 53 | fields = ('name', 'objectivies', 'content', 'max_students', 'init_register_date', 'end_register_date', |
54 | - 'init_date', 'end_date', 'category',) | |
54 | + 'init_date', 'end_date', 'category', 'coordenator') | |
55 | 55 | labels = { |
56 | - 'name': _('Name'), | |
57 | - 'objectivies': _('Objectives'), | |
58 | - 'content': _('Content'), | |
59 | - 'max_students': _('Number of studets maximum'), | |
60 | - 'init_register_date': _('Course registration start date'), | |
61 | - 'end_register_date': _('Course registration end date'), | |
62 | - 'init_date': _('Course start date'), | |
63 | - 'end_date': _('Course end date'), | |
64 | - 'category': _('CourseCategory'), | |
56 | + 'name': _('Name'), | |
57 | + 'objectivies': _('Objectives'), | |
58 | + 'content': _('Content'), | |
59 | + 'max_students': _('Number of studets maximum'), | |
60 | + 'init_register_date': _('Course registration start date'), | |
61 | + 'end_register_date': _('Course registration end date'), | |
62 | + 'init_date': _('Course start date'), | |
63 | + 'end_date': _('Course end date'), | |
64 | + 'category': _('CourseCategory'), | |
65 | + 'coordenator': _('Coordenator'), | |
65 | 66 | } |
66 | 67 | help_texts = { |
67 | - 'name': _('Course name'), | |
68 | - 'objectivies': _('Course objective'), | |
69 | - 'content': _('Course modules'), | |
70 | - 'max_students': _('Max number of students that a class can have'), | |
71 | - 'init_register_date': _('Date that starts the registration period of the course (dd/mm/yyyy)'), | |
72 | - 'end_register_date': _('Date that ends the registration period of the course (dd/mm/yyyy)'), | |
73 | - 'init_date': _('Date that the course starts (dd/mm/yyyy)'), | |
74 | - 'end_date': _('Date that the course ends (dd/mm/yyyy)'), | |
75 | - 'category': _('CourseCategory which the course belongs'), | |
68 | + 'name': _('Course name'), | |
69 | + 'objectivies': _('Course objective'), | |
70 | + 'content': _('Course modules'), | |
71 | + 'max_students': _('Max number of students that a class can have'), | |
72 | + 'init_register_date': _('Date that starts the registration period of the course (dd/mm/yyyy)'), | |
73 | + 'end_register_date': _('Date that ends the registration period of the course (dd/mm/yyyy)'), | |
74 | + 'init_date': _('Date that the course starts (dd/mm/yyyy)'), | |
75 | + 'end_date': _('Date that the course ends (dd/mm/yyyy)'), | |
76 | + 'category': _('CourseCategory which the course belongs'), | |
77 | + 'coordenator': _('Course Coordenator'), | |
76 | 78 | } |
77 | 79 | |
78 | 80 | widgets = { |
79 | - 'categoy': forms.Select(), | |
80 | - 'objectivies': SummernoteWidget(attrs={'cols': 80, 'rows': 5}), | |
81 | - 'content': SummernoteWidget(attrs={'cols': 80, 'rows': 5}), | |
81 | + 'categoy': forms.Select(), | |
82 | + 'coordenator': forms.Select(), | |
83 | + 'objectivies': SummernoteWidget(attrs={'cols': 80, 'rows': 5}), | |
84 | + 'content': SummernoteWidget(attrs={'cols': 80, 'rows': 5}), | |
82 | 85 | } |
83 | 86 | |
84 | 87 | class UpdateCourseForm(CourseForm): |
... | ... | @@ -89,35 +92,38 @@ class UpdateCourseForm(CourseForm): |
89 | 92 | class Meta: |
90 | 93 | model = Course |
91 | 94 | fields = ('name', 'objectivies', 'content', 'max_students', 'init_register_date', 'end_register_date', |
92 | - 'init_date', 'end_date', 'category','students',) | |
95 | + 'init_date', 'end_date', 'category','students', 'coordenator') | |
93 | 96 | labels = { |
94 | - 'name': _('Name'), | |
95 | - 'objectivies': _('Objectives'), | |
96 | - 'content': _('Content'), | |
97 | - 'max_students': _('Number of studets maximum'), | |
98 | - 'init_register_date': _('Course registration start date'), | |
99 | - 'end_register_date': _('Course registration end date'), | |
100 | - 'init_date': _('Course start date'), | |
101 | - 'end_date': _('Course end date'), | |
102 | - 'category': _('CourseCategory'), | |
103 | - 'students': _('Student'), | |
97 | + 'name': _('Name'), | |
98 | + 'objectivies': _('Objectives'), | |
99 | + 'content': _('Content'), | |
100 | + 'max_students': _('Number of studets maximum'), | |
101 | + 'init_register_date': _('Course registration start date'), | |
102 | + 'end_register_date': _('Course registration end date'), | |
103 | + 'init_date': _('Course start date'), | |
104 | + 'end_date': _('Course end date'), | |
105 | + 'category': _('CourseCategory'), | |
106 | + 'coordenator': _('Coordenator'), | |
107 | + 'students': _('Student'), | |
104 | 108 | } |
105 | 109 | help_texts = { |
106 | - 'name': _('Course name'), | |
107 | - 'objectivies': _('Course objective'), | |
108 | - 'content': _('Course modules'), | |
109 | - 'max_students': _('Max number of students that a class can have'), | |
110 | - 'init_register_date': _('Date that starts the registration period of the course (dd/mm/yyyy)'), | |
111 | - 'end_register_date': _('Date that ends the registration period of the course (dd/mm/yyyy)'), | |
112 | - 'init_date': _('Date that the course starts (dd/mm/yyyy)'), | |
113 | - 'end_date': _('Date that the course ends (dd/mm/yyyy)'), | |
114 | - 'category': _('CourseCategory which the course belongs'), | |
115 | - 'students': _("Course's Students"), | |
110 | + 'name': _('Course name'), | |
111 | + 'objectivies': _('Course objective'), | |
112 | + 'content': _('Course modules'), | |
113 | + 'max_students': _('Max number of students that a class can have'), | |
114 | + 'init_register_date': _('Date that starts the registration period of the course (dd/mm/yyyy)'), | |
115 | + 'end_register_date': _('Date that ends the registration period of the course (dd/mm/yyyy)'), | |
116 | + 'init_date': _('Date that the course starts (dd/mm/yyyy)'), | |
117 | + 'end_date': _('Date that the course ends (dd/mm/yyyy)'), | |
118 | + 'category': _('CourseCategory which the course belongs'), | |
119 | + 'coordenator': _('Course Coordenator'), | |
120 | + 'students': _("Course's Students"), | |
116 | 121 | } |
117 | 122 | widgets = { |
118 | - 'categoy': forms.Select(), | |
119 | - 'objectivies': SummernoteWidget(attrs={'cols': 80, 'rows': 5}), | |
120 | - 'content': SummernoteWidget(attrs={'cols': 80, 'rows': 5}), | |
123 | + 'categoy': forms.Select(), | |
124 | + 'coordenator': forms.Select(), | |
125 | + 'objectivies': SummernoteWidget(attrs={'cols': 80, 'rows': 5}), | |
126 | + 'content': SummernoteWidget(attrs={'cols': 80, 'rows': 5}), | |
121 | 127 | } |
122 | 128 | |
123 | 129 | class SubjectForm(forms.ModelForm): | ... | ... |
... | ... | @@ -0,0 +1,23 @@ |
1 | +# -*- coding: utf-8 -*- | |
2 | +# Generated by Django 1.10 on 2016-11-08 15:00 | |
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 | + ('courses', '0003_remove_course_image'), | |
15 | + ] | |
16 | + | |
17 | + operations = [ | |
18 | + migrations.AddField( | |
19 | + model_name='course', | |
20 | + name='coordenator', | |
21 | + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='course_coordenator', to=settings.AUTH_USER_MODEL, verbose_name='Coordenator'), | |
22 | + ), | |
23 | + ] | ... | ... |
courses/models.py
... | ... | @@ -47,6 +47,7 @@ class Course(models.Model): |
47 | 47 | init_date = models.DateField(_('Begin of Course Date')) |
48 | 48 | end_date = models.DateField(_('End of Course Date')) |
49 | 49 | category = models.ForeignKey(CourseCategory, verbose_name = _('Category'), related_name='course_category') |
50 | + coordenator = models.ForeignKey(User, verbose_name = _('Coordenator'), related_name ='course_coordenator', null = True) | |
50 | 51 | professors = models.ManyToManyField(User,verbose_name=_('Professors'), related_name='courses_professors') |
51 | 52 | students = models.ManyToManyField(User,verbose_name=_('Students'), related_name='courses_student', blank = True) |
52 | 53 | public = models.BooleanField(_('Public'), default=False) | ... | ... |
... | ... | @@ -0,0 +1,22 @@ |
1 | +from rest_framework import serializers | |
2 | +from .models import Course, Subject, Topic | |
3 | +from users.serializers import UserSerializer | |
4 | + | |
5 | +class CourseSerializer(serializers.ModelSerializer): | |
6 | + #The set comes from the ManyToMany Relationship in django | |
7 | + class Meta: | |
8 | + model = Course | |
9 | + fields = ('name', 'slug', 'objectivies', 'content', 'max_students', 'create_date', | |
10 | + 'init_register_date', 'end_register_date', 'init_date', 'end_date', 'public', 'category' ,'students', 'professors') | |
11 | + | |
12 | +class SubjectSerializer(serializers.ModelSerializer): | |
13 | + class Meta: | |
14 | + model = Subject | |
15 | + fields = ('name','slug','description','visible','init_date','course','category','professors','course','students') | |
16 | + | |
17 | +class TopicSerializer(serializers.ModelSerializer): | |
18 | + class Meta: | |
19 | + model = Topic | |
20 | + fields = ('name', 'slug','description','create_date','update_date','visible','owner','subject') | |
21 | + | |
22 | + | ... | ... |
courses/static/js/modal_category.js
... | ... | @@ -16,16 +16,16 @@ var Submite = { |
16 | 16 | } |
17 | 17 | } |
18 | 18 | |
19 | -var modal = { | |
20 | - get: function (url, id_modal, id_div_modal){ | |
21 | - $.get(url, function(data){ | |
22 | - if($(id_modal).length){ | |
23 | - $(id_div_modal).empty(); | |
24 | - $(id_div_modal).append(data); | |
25 | - } else { | |
26 | - $(id_div_modal).append(data); | |
27 | - } | |
28 | - $(id_modal).modal('show'); | |
29 | - }); | |
30 | - } | |
31 | -}; | |
32 | 19 | \ No newline at end of file |
20 | +// var modal = { | |
21 | +// get: function (url, id_modal, id_div_modal){ | |
22 | +// $.get(url, function(data){ | |
23 | +// if($(id_modal).length){ | |
24 | +// $(id_div_modal).empty(); | |
25 | +// $(id_div_modal).append(data); | |
26 | +// } else { | |
27 | +// $(id_div_modal).append(data); | |
28 | +// } | |
29 | +// $(id_modal).modal('show'); | |
30 | +// }); | |
31 | +// } | |
32 | +// }; | ... | ... |
courses/static/js/topic_editation_presentation.js
1 | + | |
1 | 2 | $(document).ready(function(){ |
2 | - $(".editation").hide(); | |
3 | + $(".editation").hide(); | |
3 | 4 | }); |
5 | + | |
4 | 6 | function show_editation(id_topic){ |
5 | 7 | $(".presentation_"+ id_topic).hide(); |
6 | 8 | $(".editation_"+ id_topic).show(); |
9 | + $('#summernote').summernote({height: 300}); | |
7 | 10 | }; |
8 | 11 | |
9 | 12 | function show_presentation(id_topic){ |
10 | 13 | $(".editation_"+ id_topic).hide(); |
11 | 14 | $(".presentation_"+ id_topic).show(); |
12 | 15 | }; |
13 | - | |
14 | - | ... | ... |
courses/templates/category/create.html
1 | -{% extends 'base.html' %} | |
1 | +{% extends 'home.html' %} | |
2 | 2 | |
3 | 3 | {% load static i18n permission_tags %} |
4 | 4 | {% load widget_tweaks %} |
... | ... | @@ -11,17 +11,7 @@ |
11 | 11 | {% endblock %} |
12 | 12 | |
13 | 13 | {% block sidebar %} |
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> | |
14 | +{{block.super}} | |
25 | 15 | |
26 | 16 | {% if user|has_role:'professor' or user|has_role:'system_admin' %} |
27 | 17 | ... | ... |
courses/templates/category/index.html
1 | -{% extends 'base.html' %} | |
1 | +{% extends 'home.html' %} | |
2 | 2 | |
3 | 3 | {% load static i18n %} |
4 | 4 | {% load static i18n permission_tags %} |
... | ... | @@ -12,17 +12,7 @@ |
12 | 12 | {% endblock %} |
13 | 13 | |
14 | 14 | {% block sidebar %} |
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> | |
15 | +{{block.super}} | |
26 | 16 | |
27 | 17 | {% if user|has_role:'professor' or user|has_role:'system_admin' %} |
28 | 18 | |
... | ... | @@ -83,7 +73,7 @@ |
83 | 73 | </ul> |
84 | 74 | </div> |
85 | 75 | </div> |
86 | - | |
76 | + | |
87 | 77 | </div> |
88 | 78 | </div> |
89 | 79 | </div> | ... | ... |
courses/templates/category/update.html
1 | -{% extends 'base.html' %} | |
1 | +{% extends 'Home.html' %} | |
2 | 2 | |
3 | 3 | {% load static i18n %} |
4 | 4 | {% load static i18n permission_tags %} |
... | ... | @@ -12,17 +12,7 @@ |
12 | 12 | {% endblock %} |
13 | 13 | |
14 | 14 | {% block sidebar %} |
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> | |
15 | +{{block.super}} | |
26 | 16 | |
27 | 17 | {% if user|has_role:'professor' or user|has_role:'system_admin' %} |
28 | 18 | ... | ... |
courses/templates/course/course_card.html
... | ... | @@ -34,6 +34,7 @@ |
34 | 34 | <div class="panel-collapse collapseOne-{{course.slug}} collapse in" role="tabpanel" aria-labelledby="headingOne" aria-expanded="true" aria-hidden="false" tabindex="0"> |
35 | 35 | <div class="panel-body"> |
36 | 36 | <p><b>{% trans 'Course Name' %}: </b>{{course.name}}</p> |
37 | + <p><b>{% trans 'Coordenator' %}: </b>{{course.coordenator}}</p> | |
37 | 38 | <p><b>{% trans 'Professor' %}: </b>{{course.professors.all.0}}</p> |
38 | 39 | <p> |
39 | 40 | <b>{% trans 'Description' %}:</b> |
... | ... | @@ -41,6 +42,14 @@ |
41 | 42 | {{course.content | safe }} |
42 | 43 | </i> |
43 | 44 | </p> |
45 | + <div class="row"> | |
46 | + <div class="col-xs-6 col-md-6 data_register_course"> | |
47 | + <p><b>{% trans 'Init register' %}: </b>{{course.init_register_date}}</p> | |
48 | + </div> | |
49 | + <div class="col-xs-6 col-md-6 data_register_course"> | |
50 | + <p><b>{% trans 'End register' %}: </b>{{course.end_register_date}}</p> | |
51 | + </div> | |
52 | + </div> | |
44 | 53 | </div> |
45 | 54 | </div> |
46 | 55 | </div> | ... | ... |
courses/templates/course/create.html
... | ... | @@ -12,41 +12,48 @@ |
12 | 12 | |
13 | 13 | {% block content %} |
14 | 14 | <div class="card card-content"> |
15 | - <div class="card-body"> | |
16 | - <form method="post" action="" enctype="multipart/form-data"> | |
17 | - {% csrf_token %} | |
18 | - {% for field in form %} | |
19 | - <div class="form-group {% if form.has_error %} has-error {% endif %} is-fileinput"> | |
20 | - <label for="{{ field.auto_id }}">{{ field.label }}</label> | |
21 | - {% if field.auto_id == 'id_init_register_date' or field.auto_id == 'id_end_register_date' or field.auto_id == 'id_init_date' or field.auto_id == 'id_end_date'%} | |
22 | - <input type="text" class="form-control date-picker" name="{{field.name}}" value="{{field.value|date:'SHORT_DATE_FORMAT'}}" min="{{now|date:'SHORT_DATE_FORMAT'}}"> | |
15 | + <div class="card-body"> | |
16 | + <form method="post" action="" enctype="multipart/form-data"> | |
17 | + {% csrf_token %} | |
18 | + {% for field in form %} | |
19 | + <div class="form-group {% if form.has_error %} has-error {% endif %} is-fileinput"> | |
20 | + <label for="{{ field.auto_id }}">{{ field.label }}</label> | |
21 | + {% if field.auto_id == 'id_init_register_date' or field.auto_id == 'id_end_register_date' or field.auto_id == 'id_init_date' or field.auto_id == 'id_end_date'%} | |
22 | + <input type="text" class="form-control date-picker" name="{{field.name}}" value="{{field.value|date:'SHORT_DATE_FORMAT'}}" min="{{now|date:'SHORT_DATE_FORMAT'}}"> | |
23 | 23 | |
24 | - {% else %} | |
25 | - {% render_field field class='form-control' %} | |
26 | - {% endif %} | |
27 | - <span class="help-block">{{ field.help_text }}</span> | |
28 | - {% if field.errors %} | |
29 | - <div class="row"> | |
30 | - </br> | |
31 | - <div class="alert alert-danger alert-dismissible" role="alert"> | |
32 | - <button type="button" class="close" data-dismiss="alert" aria-label="Close"> | |
33 | - <span aria-hidden="true">×</span> | |
34 | - </button> | |
35 | - <ul> | |
36 | - {% for error in field.errors %} | |
37 | - <li>{{ error }}</li> | |
38 | - {% endfor %} | |
39 | - </ul> | |
40 | - </div> | |
41 | - </div> | |
42 | - {% endif %} | |
24 | + {% else %} | |
25 | + {% render_field field class='form-control' %} | |
26 | + {% endif %} | |
27 | + <span class="help-block">{{ field.help_text }}</span> | |
28 | + {% if field.errors %} | |
29 | + <div class="row"> | |
30 | + </br> | |
31 | + <div class="alert alert-danger alert-dismissible" role="alert"> | |
32 | + <button type="button" class="close" data-dismiss="alert" aria-label="Close"> | |
33 | + <span aria-hidden="true">×</span> | |
34 | + </button> | |
35 | + <ul> | |
36 | + {% for error in field.errors %} | |
37 | + <li>{{ error }}</li> | |
38 | + {% endfor %} | |
39 | + </ul> | |
43 | 40 | </div> |
44 | - {% endfor %} | |
45 | - <div class="row text-center"> | |
46 | - <input type="submit" value="{% trans 'Create' %}" class="btn btn-primary" /> | |
47 | - </div> | |
48 | - </form> | |
49 | - </div> | |
41 | + </div> | |
42 | + {% endif %} | |
43 | + </div> | |
44 | + {% endfor %} | |
45 | + <div class="row text-center"> | |
46 | + <input type="submit" value="{% trans 'Create' %}" class="btn btn-primary" /> | |
47 | + </div> | |
48 | + </form> | |
49 | + </div> | |
50 | 50 | </div> |
51 | 51 | </br> |
52 | +<script type="text/javascript"> | |
53 | + var locale = navigator.language || navigator.userLanguage; | |
54 | + | |
55 | + $('.date-picker').datepicker({ | |
56 | + language: locale, | |
57 | + }); | |
58 | +</script> | |
52 | 59 | {% endblock %} | ... | ... |
courses/templates/course/index.html
1 | -{% extends 'home_professor.html' %} | |
1 | +{% extends 'home.html' %} | |
2 | 2 | |
3 | 3 | {% load static i18n permission_tags %} |
4 | 4 | {% load django_bootstrap_breadcrumbs %} |
... | ... | @@ -11,37 +11,7 @@ |
11 | 11 | {% endblock %} |
12 | 12 | |
13 | 13 | {% block sidebar %} |
14 | - <div class="panel panel-primary"> | |
15 | - <div class="panel-heading"> | |
16 | - <h4>{% trans 'Menu' %}</h4> | |
17 | - </div> | |
18 | - <div class="panel-body"> | |
19 | - <ul class="nav nav-pills nav-stacked"> | |
20 | - <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li> | |
21 | - <li><a href="{% url 'users:profile' %}">{% trans 'Profile' %}</a></li> | |
22 | - {% if user|has_role:'student' or not user.is_staff %} | |
23 | - <li><a href="{% url 'course:manage' %}">{% trans 'My courses' %}</a></li> | |
24 | - <li><a href="{% url 'course:all_courses' %}">{% trans 'All Courses' %}</a></li> | |
25 | - {% endif %} | |
26 | - <li><a href="{% url 'core:guest' %}">{% trans 'Courses' %}</a></li> | |
27 | - {% if user|has_role:'system_admin' %} | |
28 | - <li> <a href="{% url 'users:manage' %}">{% trans 'Manage Users' %}</a></li> | |
29 | - {% endif %} | |
30 | - {% if user|has_role:'system_admin' or user|has_role:'professor' %} | |
31 | - <li> | |
32 | - <a href="#courses_list" class="accordion" data-toggle="collapse">{% trans 'Manage Courses' %}</a> | |
33 | - <div id="courses_list" class="collapse"> | |
34 | - <ul class="nav nav-pill nav-stacked accordion_list"> | |
35 | - {% for course in courses_list %} | |
36 | - <li><a href="{% url 'course:view' course.slug %}">{{ course }}</a></li> | |
37 | - {% endfor %} | |
38 | - </ul> | |
39 | - </div> | |
40 | - </li> | |
41 | - {% endif %} | |
42 | - </ul> | |
43 | - </div> | |
44 | - </div> | |
14 | +{{block.super}} | |
45 | 15 | {% if user|has_role:'professor' or user|has_role:'system_admin' %} |
46 | 16 | <div class="panel panel-primary"> |
47 | 17 | <div class="panel-heading"> |
... | ... | @@ -130,8 +100,8 @@ |
130 | 100 | </div> |
131 | 101 | </div> |
132 | 102 | </div> |
133 | - | |
134 | - | |
103 | + | |
104 | + | |
135 | 105 | {% endfor %} |
136 | 106 | </div> |
137 | 107 | {% if user|has_role:'professor' or user|has_role:'system_admin' %} | ... | ... |
courses/templates/course/update.html
... | ... | @@ -49,4 +49,11 @@ |
49 | 49 | </br> |
50 | 50 | </br> |
51 | 51 | </br> |
52 | +<script type="text/javascript"> | |
53 | + var locale = navigator.language || navigator.userLanguage; | |
54 | + | |
55 | + $('.date-picker').datepicker({ | |
56 | + language: locale, | |
57 | + }); | |
58 | +</script> | |
52 | 59 | {% endblock %} |
53 | 60 | \ No newline at end of file | ... | ... |
courses/templates/course/view.html
... | ... | @@ -22,37 +22,7 @@ |
22 | 22 | {% endblock %} |
23 | 23 | |
24 | 24 | {% block sidebar %} |
25 | - <div class="panel panel-primary"> | |
26 | - <div class="panel-heading"> | |
27 | - <h4>{% trans 'Menu' %}</h4> | |
28 | - </div> | |
29 | - <div class="panel-body"> | |
30 | - <ul class="nav nav-pills nav-stacked"> | |
31 | - <li><a href="{% url 'core:home' %}">{% trans "Home" %}</a></li> | |
32 | - <li><a href="{% url 'users:profile' %}">{% trans 'Profile' %}</a></li> | |
33 | - <li><a href="{% url 'course:manage' %}">{% trans 'My Courses' %}</a></li> | |
34 | - <li><a href="{% url 'course:all_courses' %}">{% trans 'All Courses' %}</a></li> | |
35 | - <li><a href="{% url 'core:guest' %}">{% trans 'Courses' %}</a></li> | |
36 | - {# <li><a href="{% url 'course:participants' %}">{% trans 'Participants' %}</a></li> #} | |
37 | - {% if user|has_role:'system_admin' %} | |
38 | - <li> <a href="{% url 'users:manage' %}">{% trans 'Manage Users' %}</a></li> | |
39 | - {% endif %} | |
40 | - {% if user|has_role:'system_admin' or user|has_role:'professor' %} | |
41 | - <li> | |
42 | - <a href="#courses_list" class="accordion" data-toggle="collapse">{% trans 'Manage Courses' %}</a> | |
43 | - <div id="courses_list" class="collapse"> | |
44 | - <ul class="nav nav-pill nav-stacked accordion_list"> | |
45 | - {% for course in courses_list %} | |
46 | - <li><a href="{% url 'course:view' course.slug %}">{{ course }}</a></li> | |
47 | - {% endfor %} | |
48 | - </ul> | |
49 | - </div> | |
50 | - </li> | |
51 | - {% endif %} | |
52 | - </ul> | |
53 | - </div> | |
54 | - </div> | |
55 | - | |
25 | +{{ block.super}} | |
56 | 26 | <div class="panel panel-primary"> |
57 | 27 | <div class="panel-heading"> |
58 | 28 | <h5>{% trans 'Categories' %}</h5> |
... | ... | @@ -94,15 +64,22 @@ |
94 | 64 | </div> |
95 | 65 | </div> |
96 | 66 | <div class="panel-body"> |
97 | - <p><b>{% trans 'Coordinator' %}: </b>{% for professor in course.professors.all %}{% if not forloop.first %},{% endif %} | |
98 | - {{professor}}{% if forloop.last %}.{% endif %}{% endfor %}</p> | |
67 | + <p><b>{% trans 'Coordinator' %}: </b>{{course.coordenator}}</p> | |
68 | + <p><b>{% trans 'Teacher' %}: </b>{{course.professors.all.0}}</p> | |
99 | 69 | <p> |
100 | 70 | <b>{% trans 'Description' %}:</b> |
101 | 71 | <i> |
102 | 72 | {{ course.objectivies |safe }} |
103 | 73 | </i> |
104 | 74 | </p> |
105 | - | |
75 | + <div class="row"> | |
76 | + <div class="col-xs-6 col-md-6 data_register_course"> | |
77 | + <p><b>{% trans 'Begin of Course Date' %}: </b>{{course.init_date}}</p> | |
78 | + </div> | |
79 | + <div class="col-xs-6 col-md-6 data_register_course"> | |
80 | + <p><b>{% trans 'End of Course Date' %}: </b>{{course.end_date}}</p> | |
81 | + </div> | |
82 | + </div> | |
106 | 83 | </div> |
107 | 84 | </div> |
108 | 85 | |
... | ... | @@ -151,9 +128,11 @@ |
151 | 128 | <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i> |
152 | 129 | </button> |
153 | 130 | <ul class="dropdown-menu pull-right" aria-labelledby="moreActions"> |
154 | - <li><a href="{% url 'course:replicate_subject' subject.slug %}" data-toggle="modal" data-target="#myModal3"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i> {% trans 'Replicate' %}</a></li> | |
155 | - <li><a href="javascript:delete_subject.get('{% url 'course:delete_subject' subject.slug %}','#subject','#modal_subject')" data-toggle="modal" data-target="#removeSubject"><i class="fa fa-trash fa-fw" aria-hidden="true"></i> {% trans 'Remove' %}</a></li> | |
131 | + <li><a href="{% url 'course:replicate_subject' subject.slug %}"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i> {% trans "Replicate" %}</a></li> | |
132 | + <li><a href="{% url 'course:update_subject' subject.slug %}"> <i class="fa fa-pencil fa-fw" aria-hidden="true"></i> {% trans "Edit" %}</a></li> | |
133 | + <li><a href="{% url 'course:delete_subject' subject.slug %}" ><i class="fa fa-trash fa-fw" aria-hidden="true"></i> {% trans "Remove" %}</a></li> | |
156 | 134 | </ul> |
135 | + | |
157 | 136 | </div> |
158 | 137 | </div> |
159 | 138 | {% endif %} | ... | ... |
courses/templates/subject/form_view_teacher.html
1 | 1 | {% load static i18n list_topic_foruns permission_tags widget_tweaks professor_access%} |
2 | 2 | |
3 | -{% block javascript %} | |
4 | - <script type="text/javascript" src="{% static 'js/forum.js' %}"></script> | |
5 | - <script src="{% static 'js/file.js' %}"></script> | |
6 | - <script type="text/javascript" src="{% static 'js/material.js' %}"></script> | |
7 | - <script type = "text/javascript" src="{% static 'js/topic_editation_presentation.js' %}"></script> | |
8 | - <script type = "text/javascript" src="{% static 'js/links.js' %}"></script> | |
9 | -{% endblock %} | |
10 | 3 | <div class="panel panel-default cards-detail"> |
11 | 4 | <div class="panel-heading topic"> |
12 | 5 | <div class="row"> |
... | ... | @@ -23,6 +16,8 @@ |
23 | 16 | <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> |
24 | 17 | <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i> |
25 | 18 | </button> |
19 | + | |
20 | + {# dropdown de topic com as opções de replicar, editar e deletar #} | |
26 | 21 | {% professor_subject topic.subject user as dropdown_topic %} |
27 | 22 | {% if dropdown_topic %} |
28 | 23 | <ul class="dropdown-menu pull-right" aria-labelledby="moreActions"> |
... | ... | @@ -30,13 +25,17 @@ |
30 | 25 | <li><a href="javascript:show_editation('{{topic.slug}}')"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i> {% trans "Edit" %}</a></li> |
31 | 26 | <li><a href="javascript:void(0)" data-toggle="modal" data-target="#removeTopic"><i class="fa fa-trash fa-fw" aria-hidden="true"></i> {% trans "Remove" %}</a></li> |
32 | 27 | </ul> |
28 | + | |
29 | + | |
33 | 30 | {% endif %} |
34 | 31 | </div> |
35 | - </div><!--column--> | |
36 | - </div><!--row--> | |
32 | + </div> | |
33 | + </div> | |
37 | 34 | </div> |
38 | 35 | <div class="panel-collapse collapseTopic-{{topic.slug}} topic_{{ topic.id }} collapse in" role="tabpanel" aria-labelledby="heading_{{topic.id}}" aria-expanded="true" aria-hidden="false"> |
39 | 36 | <div class="panel-body"> |
37 | + | |
38 | + {# dados do tópico no modo de visualização #} | |
40 | 39 | <div class="presentation_{{topic.slug}}"> |
41 | 40 | <p> |
42 | 41 | <i> |
... | ... | @@ -44,66 +43,94 @@ |
44 | 43 | </i> |
45 | 44 | </p> |
46 | 45 | </div> |
46 | + | |
47 | + {# dados dos topicos no modo de edição #} | |
47 | 48 | <div class="form-group editation editation_{{topic.slug}}"> |
48 | 49 | <label class="control-label" for="focusedInput2">{% trans 'Name Topic' %}</label> |
49 | 50 | <input type="text" class="form-control" value="{{topic}}"> |
50 | 51 | </div> |
51 | 52 | <div class="form-group editation editation_{{topic.slug}}"> |
52 | 53 | <label class="control-label" for="focusedInput2">{% trans 'Description' %}</label> |
53 | - <textarea class="form-control" rows="3" id="textArea">{{topic.description}}</textarea> | |
54 | + <textarea class="form-control" rows="3" id="summernote">{{topic.description}}</textarea> | |
54 | 55 | </div> |
56 | + | |
57 | + {# materiais do topico#} | |
55 | 58 | <div class="row"> |
56 | 59 | <div class="col-xs-6 col-md-6"> |
57 | 60 | <div class="resource_inline"> |
58 | 61 | <h4>{% trans 'Material' %}</h4> |
59 | 62 | </div> |
60 | 63 | <div class="resource_inline"> |
64 | + | |
65 | + {# dropdown de create material #} | |
61 | 66 | <div class="dropdown"> |
62 | 67 | <a href="#" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-plus-circle fa-lg" aria-hidden="true"></i></a> |
63 | 68 | <ul class="dropdown-menu" aria-labelledby="dLabel"> |
64 | - <li><a href="javascript:get_modal_link('{% url 'course:links:create_link' topic.slug %}', '#createLinksModal','#divModalLink') ">{% trans 'Create a Link' %}</a></li> | |
65 | - <li><a href="javascript:get_modal_file('{% url 'course:file:create_file' topic.slug %}', '#fileModal', '#divModalFile')">{% trans "Create a file" %}</a></li> | |
69 | + <li><a href="javascript:modal.get('{% url 'course:links:create_link' topic.slug %}', '#createLinksModal','#requisicoes_ajax') ">{% trans 'Create a Link' %}</a></li> | |
70 | + <li><a href="javascript:modal.get('{% url 'course:file:create_file' topic.slug %}', '#fileModal', '#requisicoes_ajax')">{% trans "Create a file" %}</a></li> | |
66 | 71 | </ul> |
67 | 72 | </div> |
68 | 73 | </div> |
69 | 74 | <div class="presentation_{{topic.slug}}"> |
75 | + | |
76 | + {# materiais do tópico no modo de visualização #} | |
70 | 77 | <ul> |
71 | 78 | {% list_topic_file request topic %} |
72 | 79 | {% list_topic_link request topic%} |
73 | 80 | </ul> |
74 | 81 | </div> |
75 | 82 | <div class="editation editation_{{topic.slug}}"> |
83 | + | |
84 | + {# materiais do tópico no modo de edição #} | |
76 | 85 | <ul> |
77 | 86 | {% list_topic_file_edit request topic %} |
78 | 87 | {% list_topic_link_edit request topic%} |
79 | 88 | </ul> |
80 | 89 | </div> |
81 | 90 | </div> |
91 | + | |
92 | + {# avaliações do topico #} | |
82 | 93 | <div class="col-xs-4 col-md-4"> |
83 | 94 | <div class="resource_inline"> |
84 | 95 | <h4>{% trans 'Activities' %}</h4> |
85 | 96 | </div> |
86 | 97 | <div class="resource_inline"> |
98 | + | |
99 | + {# dropdown de avaliações #} | |
87 | 100 | <div class="dropdown"> |
88 | 101 | <a href="#" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-plus-circle fa-lg" aria-hidden="true"></i></a> |
89 | 102 | <ul class="dropdown-menu" aria-labelledby="dLabel"> |
90 | 103 | <li><a href="javascript:createForum('{% url 'course:forum:create' %}', '{{ topic.id }}')">{% trans 'Create Forum' %}</a></li> |
91 | - <li><a href="javascript:modal.get('{% url 'course:poll:create_poll' topic.slug%}','#poll','#modal_poll');">{% trans 'Create Poll' %}</a></li> | |
92 | - <li><a href="javascript:modal.get('{% url 'course:exam:create_exam' topic.slug%}','#exam','#modal_exam');">{% trans 'Create Exam' %}</a></li> | |
104 | + | |
105 | + <li><a href="javascript:modal.get('{% url 'course:poll:create_poll' topic.slug%}','#poll','#requisicoes_ajax');">{% trans 'Create Poll' %}</a></li> | |
93 | 106 | </ul> |
94 | 107 | </div> |
95 | 108 | </div> |
96 | - <ul> | |
97 | - {% list_topic_exam request topic %} | |
98 | - {% list_topic_poll request topic %} | |
99 | - {% list_topic_foruns request topic %} | |
100 | - </ul> | |
109 | + <div class="presentation_{{topic.slug}}"> | |
110 | + | |
111 | + {# avaliações do tópico no modo de visualização #} | |
112 | + <ul> | |
113 | + {% list_topic_poll request topic %} | |
114 | + {% list_topic_foruns request topic %} | |
115 | + </ul> | |
116 | + </div> | |
117 | + <div class="editation editation_{{topic.slug}}"> | |
118 | + | |
119 | + {# avaliações do tópico no modo de edição #} | |
120 | + <ul> | |
121 | + {% list_topic_poll_teacher request topic %} | |
122 | + {% list_topic_foruns request topic %} | |
123 | + </ul> | |
124 | + </div> | |
125 | + | |
101 | 126 | </div> |
102 | 127 | </div> |
128 | + | |
129 | + {# opções de cancelar e editar no modo de edição #} | |
103 | 130 | <div class="form-group editation editation_{{topic.slug}}"> |
104 | 131 | <div class="col-md-10"> |
105 | - <a href="javascript:show_presentation('{{topic.slug}}')" class="btn btn-raised btn-default">{% trans 'Cancel' %}</a> | |
106 | - <a href="javascript:show_presentation('{{topic.slug}}')" class="btn btn-raised btn-primary">{% trans 'Submit' %}</a> | |
132 | + <a href="javascript:show_presentation('{{topic.slug}}')" class="btn btn-raised btn-default">{% trans 'Back' %}</a> | |
133 | + {# <a href="javascript:show_presentation('{{topic.slug}}')" class="btn btn-raised btn-primary">{% trans 'Submit' %}</a>#} | |
107 | 134 | </div> |
108 | 135 | </div> |
109 | 136 | </div> |
... | ... | @@ -114,7 +141,7 @@ |
114 | 141 | |
115 | 142 | |
116 | 143 | <!-- MODAL REMOVE TOPIC --> |
117 | -<div class="modal" id="removeTopic"> | |
144 | +<div class="modal" id="{{topic.slug}}"> | |
118 | 145 | <div class="modal-dialog"> |
119 | 146 | <div class="modal-content"> |
120 | 147 | <div class="modal-header"> |
... | ... | @@ -154,18 +181,18 @@ |
154 | 181 | <label for="textArea" class="col-md-2 control-label">{% trans 'Code' %}:</label> |
155 | 182 | |
156 | 183 | <div class="col-md-10"> |
157 | - <textarea class="form-control" rows="2" id="textArea"></textarea> | |
158 | - <span class="help-block">{% trans 'Material description' %}</span> | |
184 | + <textarea class="form-control" rows="2" id="textArea"></textarea> | |
185 | + <span class="help-block">{% trans 'Material description' %}</span> | |
159 | 186 | </div> |
160 | 187 | </div> |
161 | 188 | <div class="form-group is-empty"> |
162 | - <label for="number" class="col-md-2 control-label">{% trans 'Height' %}</label> | |
189 | + <label for="number" class="col-md-2 control-label">{% trans 'Height' %}</label> | |
163 | 190 | <div class="col-md-4"> |
164 | 191 | <input type="number" class="form-control" id="inputNumber" placeholder="Heiht"> |
165 | 192 | </div> |
166 | 193 | </div> |
167 | 194 | <div class="form-group is-empty"> |
168 | - <label for="number" class="col-md-2 control-label">{% trans 'Weight' %}</label> | |
195 | + <label for="number" class="col-md-2 control-label">{% trans 'Weight' %}</label> | |
169 | 196 | <div class="col-md-4"> |
170 | 197 | <input type="number" class="form-control" id="inputNumber" placeholder="Weight"> |
171 | 198 | </div> |
... | ... | @@ -175,7 +202,7 @@ |
175 | 202 | </div> |
176 | 203 | <div class="modal-footer"> |
177 | 204 | <!-- Don't remove that!!! |
178 | - <button type="button" class="btn btn-danger btn-raised" data-dismiss="modal">Close</button>--> | |
205 | + {# <button type="button" class="btn btn-danger btn-raised" data-dismiss="modal">Close</button>-->#} | |
179 | 206 | |
180 | 207 | <!-- Put curtom buttons here!!! --> |
181 | 208 | <button type="button" class="btn btn-primary btn-raised">{% trans 'Confirm' %}</button> |
... | ... | @@ -185,85 +212,4 @@ |
185 | 212 | </div> |
186 | 213 | <!-- EndModal --> |
187 | 214 | |
188 | -<!-- MODAL ACTIVITIES--> | |
189 | -<div class="modal fade" id="ActivityModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> | |
190 | - <div class="modal-dialog" role="document"> | |
191 | - <div class="modal-content"> | |
192 | - <div class="modal-header"> | |
193 | - <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> | |
194 | - <h4 class="modal-title" id="myModalLabel"></h4> | |
195 | - </div> | |
196 | - <div class="modal-body"> | |
197 | - <form class="form-horizontal"> | |
198 | 215 | |
199 | - <fieldset> | |
200 | - <legend>{% trans 'Proposal Activity' %}</legend> | |
201 | - <div class="form-group is-empty"> | |
202 | - <label for="NameIn" class="col-md-2 control-label">{% trans 'Name' %}:</label> | |
203 | - <div class="col-md-10"> | |
204 | - <input type="text" id="NameIn" class="form-control"> | |
205 | - </div> | |
206 | - </div> | |
207 | - <div class="form-group is-empty"> | |
208 | - <label for="DescIn" class="col-md-2 control-label">{% trans 'Describe' %}:</label> | |
209 | - <div class="col-md-10"> | |
210 | - <textarea class="form-control" id="DescIn" rows="2"></textarea> | |
211 | - </div> | |
212 | - </div> | |
213 | - <div class="form-group is-empty"> | |
214 | - <label for="DateIn" class="col-md-2 control-label">{% trans 'Opening' %}: </label> | |
215 | - <div class="col-md-10"> | |
216 | - <input type="text" id="DateIn" class="form-control date-picker" requerid=""> | |
217 | - </div> | |
218 | - </div> | |
219 | - <div class="form-group is-empty"> | |
220 | - <label for="DateIn" class="col-md-2 control-label">{% trans 'Ending' %}: </label> | |
221 | - <div class="col-md-10"> | |
222 | - <input type="text" id="DateIn" class="form-control date-picker" requerid=""> | |
223 | - </div> | |
224 | - </div> | |
225 | - <div class="form-group" style="margin-top: 0;"> | |
226 | - <div class="col-md-offset-2 col-md-10"> | |
227 | - <div class="checkbox"> | |
228 | - <label> | |
229 | - <input type="checkbox"><span class="checkbox-material"><span class="check"></span></span> {% trans 'Send Later' %} | |
230 | - </label> | |
231 | - </div> | |
232 | - </div> | |
233 | - </div> | |
234 | - <div class="form-group"> | |
235 | - <div class="col-md-10 col-md-offset-2"> | |
236 | - <button type="button" class="btn btn-default">{% trans 'Cancel' %}</button> | |
237 | - <button type="submit" class="btn btn-primary">{% trans 'Submit' %}</button> | |
238 | - </div> | |
239 | - </div> | |
240 | - | |
241 | - | |
242 | - </fieldset> | |
243 | - </form> | |
244 | - </div> | |
245 | - </div> | |
246 | - </div> | |
247 | -</div> | |
248 | -<!--EndModal--> | |
249 | - | |
250 | - | |
251 | - | |
252 | -<div class="modal fade" id="createForum" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> | |
253 | - <div class="modal-dialog" role="document"> | |
254 | - <div class="modal-content"> | |
255 | - <div class="modal-header"> | |
256 | - <h4 class="modal-title" id="myModalLabel">{% trans 'Forum' %}</h4> | |
257 | - </div> | |
258 | - <div class="modal-body"> | |
259 | - <section> | |
260 | - <div class="forum_form"></div> | |
261 | - </section> | |
262 | - </div> | |
263 | - <div class="modal-footer"> | |
264 | - <button type="button" class="btn btn-danger btn-raised" data-dismiss="modal">{% trans 'Close' %}</button> | |
265 | - <button type="button" onclick="$('#forum_create').submit();" class="btn btn-primary btn-raised">{% trans 'Create' %}</button> | |
266 | - </div> | |
267 | - </div> | |
268 | - </div> | |
269 | -</div> | ... | ... |
courses/templates/subject/index.html
1 | -{% extends 'base.html' %} | |
1 | +{% extends 'home.html' %} | |
2 | 2 | |
3 | 3 | {% load static i18n permission_tags professor_access %} |
4 | 4 | |
5 | +{% block javascript %} | |
6 | + <script type="text/javascript" src="{% static 'js/forum.js' %}"></script> | |
7 | + <script src="{% static 'js/file.js' %}"></script> | |
8 | + <script type="text/javascript" src="{% static 'js/material.js' %}"></script> | |
9 | + <script type="text/javascript" src="{% static 'js/modals_requisitions.js' %}"></script> | |
10 | + <script type = "text/javascript" src="{% static 'js/topic_editation_presentation.js' %}"></script> | |
11 | + <script type = "text/javascript" src="{% static 'js/links.js' %}"></script> | |
12 | + <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> | |
13 | + <script src="{% static 'js/modal_poll.js' %}"></script> | |
14 | +{% endblock %} | |
15 | + | |
5 | 16 | {% block breadcrumbs %} |
6 | -<ol class="breadcrumb"> | |
7 | - <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li> | |
8 | - <li><a href="{% url 'course:manage' %}">{% trans 'Courses' %}</a></li> | |
9 | - <li><a href="{% url 'course:view' course.slug %}">{{ course }}</a></li> | |
10 | - <li class="active">{{ subject }}</li> | |
11 | -</ol> | |
17 | + <ol class="breadcrumb"> | |
18 | + <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li> | |
19 | + <li><a href="{% url 'course:manage' %}">{% trans 'Courses' %}</a></li> | |
20 | + <li><a href="{% url 'course:view' course.slug %}">{{ course }}</a></li> | |
21 | + <li class="active">{{ subject }}</li> | |
22 | + </ol> | |
12 | 23 | {% endblock %} |
13 | 24 | {% block sidebar %} |
14 | -<div class="panel panel-primary"> | |
15 | - <div class="panel-heading"> | |
16 | - <h4>{% trans 'Menu' %}</h4> | |
17 | - </div> | |
18 | - <div class="panel-body"> | |
19 | - <ul class="nav nav-pills nav-stacked"> | |
20 | - <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li> | |
21 | - <li><a href="{% url 'users:profile' %}">{% trans 'Profile' %}</a></li> | |
22 | - {% if user|has_role:'student' or not user.is_staff %} | |
23 | - <li><a href="{% url 'course:manage' %}">{% trans 'My courses' %}</a></li> | |
24 | - <li><a href="{% url 'core:guest' %}">{% trans 'All Courses' %}</a></li> | |
25 | - {% endif %} | |
26 | - <li><a href="{% url 'core:guest' %}">{% trans 'Courses' %}</a></li> | |
27 | - {% if user|has_role:'system_admin' %} | |
28 | - <li> <a href="{% url 'users:manage' %}">{% trans 'Manage Users' %}</a></li> | |
29 | - {% endif %} | |
30 | - {% if user|has_role:'system_admin' or user|has_role:'professor' %} | |
31 | - <li> | |
32 | - <a href="#courses_list" class="accordion" data-toggle="collapse">{% trans 'Manage Courses' %}</a> | |
33 | - <div id="courses_list" class="collapse"> | |
34 | - <ul class="nav nav-pill nav-stacked accordion_list"> | |
35 | - {% for course in courses_list %} | |
36 | - <li><a href="{% url 'course:view' course.slug %}">{{ course }}</a></li> | |
37 | - {% endfor %} | |
38 | - </ul> | |
39 | - </div> | |
40 | - </li> | |
41 | - {% endif %} | |
42 | - </ul> | |
43 | - </div> | |
44 | -</div> | |
25 | +{{block.super}} | |
45 | 26 | |
46 | 27 | |
47 | 28 | {% endblock %} |
48 | 29 | |
49 | 30 | {% block content %} |
50 | - <div class="panel panel-info"> | |
51 | - <div class="panel-heading course-detail"> | |
31 | + <div class="panel panel-info"> | |
32 | + <div class="panel-heading course-detail"> | |
52 | 33 | <div class="row"> |
53 | - <div class="col-md-10 col-sm-10"> | |
54 | - <h4>{{subject}}</h4> | |
55 | - </div> | |
56 | - <div class="col-xs-4 col-md-2 divMoreActions"> | |
57 | - {% professor_subject subject user as subject_professor%} | |
58 | - {% if subject_professor %} | |
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 | - </button> | |
63 | - <ul class="dropdown-menu pull-right" aria-labelledby="moreActions"> | |
64 | - <li><a href="{% url 'course:replicate_subject' subject.slug %}"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i> {% trans "Replicate" %}</a></li> | |
65 | - <li><a href="{% url 'course:update_subject' subject.slug %}" <i class="fa fa-pencil fa-fw" aria-hidden="true"></i> {% trans "Edit" %}</a></li> | |
66 | - <li><a href="{% url 'course:delete_subject' subject.slug %}" ><i class="fa fa-trash fa-fw" aria-hidden="true"></i> {% trans "Remove" %}</a></li> | |
67 | - </ul> | |
68 | - </div> | |
69 | - {% endif %} | |
70 | - </div> | |
71 | - </div> | |
72 | - </div> | |
73 | - <div class="panel-body"> | |
74 | - <p><b>{% trans "Professor" %}:</b> {% for professor in subject.professors.all %}{% if not forloop.first %},{% endif %} | |
75 | - {{professor}}{% if forloop.last %}.{% endif %}{% endfor %}</p> | |
76 | - <p> | |
77 | - <b>{% trans "Description" %}:</b> | |
78 | - {{subject.description|safe}} | |
79 | - </p> | |
80 | - <div class="row"> | |
81 | - <div class="col-xs-6 col-md-6"> | |
82 | - <p><b>{% trans "Beginning" %}:</b> {{subject.init_date}}</p> | |
83 | - </div> | |
84 | - <div class="col-xs-6 col-md-6"> | |
85 | - <p><b>{% trans "End" %}:</b> {{subject.end_date}}</p> | |
86 | - </div> | |
34 | + <div class="col-md-10 col-sm-10"> | |
35 | + <h4>{{subject}}</h4> | |
36 | + </div> | |
37 | + | |
38 | + {# dropdown de subject com as opções de replicar, editar e deletar #} | |
39 | + <div class="col-xs-4 col-md-2 divMoreActions"> | |
40 | + {% professor_subject subject user as subject_professor%} | |
41 | + {% if subject_professor %} | |
42 | + <div class="btn-group"> | |
43 | + <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | |
44 | + <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i> | |
45 | + </button> | |
46 | + <ul class="dropdown-menu pull-right" aria-labelledby="moreActions"> | |
47 | + <li><a href="{% url 'course:replicate_subject' subject.slug %}"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i> {% trans "Replicate" %}</a></li> | |
48 | + <li><a href="{% url 'course:update_subject' subject.slug %}"> <i class="fa fa-pencil fa-fw" aria-hidden="true"></i> {% trans "Edit" %}</a></li> | |
49 | + <li><a href="{% url 'course:delete_subject' subject.slug %}" ><i class="fa fa-trash fa-fw" aria-hidden="true"></i> {% trans "Remove" %}</a></li> | |
50 | + </ul> | |
87 | 51 | </div> |
88 | - </div> | |
52 | + {% endif %} | |
53 | + </div> | |
54 | + | |
55 | + </div> | |
89 | 56 | </div> |
90 | - {% for topic in topics %} | |
91 | - {% professor_subject topic.subject user as topic_professor%} | |
92 | - {% if topic_professor %} | |
93 | - {% include "subject/form_view_teacher.html" %} | |
94 | - {% else %} | |
95 | - {% include "subject/form_view_student.html" %} | |
96 | - {% endif %} | |
97 | - {% endfor %} | |
98 | - {% professor_subject subject user as professor_sub %} | |
99 | - {% if professor_sub %} | |
100 | - <div class="form-group"> | |
101 | - <a href="{% url 'course:create_topic' subject.slug %}" data-toggle="modal" data-target="" class="btn btn-primary btn-lg btn-block btn-raised" name="create_topic">{% trans "Create Topic" %}<div class="ripple-container"></div></a> | |
57 | + | |
58 | + {# informações do subject(professor, descrição etc) #} | |
59 | + <div class="panel-body"> | |
60 | + <p><b>{% trans "Professor" %}:</b> {% for professor in subject.professors.all %}{% if not forloop.first %},{% endif %} | |
61 | + {{professor}}{% if forloop.last %}.{% endif %}{% endfor %}</p> | |
62 | + <p> | |
63 | + <b>{% trans "Description" %}:</b> | |
64 | + {{subject.description|safe}} | |
65 | + </p> | |
66 | + <div class="row"> | |
67 | + <div class="col-xs-6 col-md-6"> | |
68 | + <p><b>{% trans "Beginning" %}:</b> {{subject.init_date}}</p> | |
69 | + </div> | |
70 | + <div class="col-xs-6 col-md-6"> | |
71 | + <p><b>{% trans "End" %}:</b> {{subject.end_date}}</p> | |
72 | + </div> | |
73 | + </div> | |
74 | + </div> | |
75 | + | |
76 | + </div> | |
77 | + | |
78 | + {# lista de tópicos #} | |
79 | + {% for topic in topics %} | |
80 | + {% professor_subject topic.subject user as topic_professor%} | |
81 | + {% if topic_professor %} | |
82 | + {% include "subject/form_view_teacher.html" %} | |
83 | + {% else %} | |
84 | + {% include "subject/form_view_student.html" %} | |
85 | + {% endif %} | |
86 | + {% endfor %} | |
87 | + | |
88 | + {# botão create topic #} | |
89 | + {% professor_subject subject user as professor_sub %} | |
90 | + {% if professor_sub %} | |
91 | + <div class="form-group"> | |
92 | + <a href="{% url 'course:create_topic' subject.slug %}" data-toggle="modal" data-target="" class="btn btn-primary btn-lg btn-block btn-raised" name="create_topic">{% trans "Create Topic" %}<div class="ripple-container"></div></a> | |
93 | + </div> | |
94 | + {% endif %} | |
95 | + | |
96 | + {# local onde vai ser colocado todos os HTML's que retornan de uma requisição ajax feitas dentro de subject #} | |
97 | + <div class = 'row' id ="requisicoes_ajax"> | |
98 | + {# Não mudar o id #} | |
99 | + </div> | |
100 | + | |
101 | + <div class="modal fade" id="createForum" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> | |
102 | + <div class="modal-dialog" role="document"> | |
103 | + <div class="modal-content"> | |
104 | + <div class="modal-header"> | |
105 | + <h4 class="modal-title" id="myModalLabel">{% trans 'Forum' %}</h4> | |
106 | + </div> | |
107 | + <div class="modal-body"> | |
108 | + <section> | |
109 | + <div class="forum_form"></div> | |
110 | + </section> | |
111 | + </div> | |
112 | + <div class="modal-footer"> | |
113 | + <button type="button" class="btn btn-default btn-raised" data-dismiss="modal">{% trans 'Close' %}</button> | |
114 | + <button type="button" onclick="$('#forum_create').submit();" class="btn btn-primary btn-raised">{% trans 'Create' %}</button> | |
115 | + </div> | |
102 | 116 | </div> |
103 | - {% endif %} | |
117 | + </div> | |
118 | + </div> | |
104 | 119 | {% endblock %} | ... | ... |
courses/templates/subject/poll_item_actions.html
1 | 1 | {% load static i18n permission_tags professor_access %} |
2 | 2 | |
3 | -<script src="{% static 'js/modals_requisitions.js'%}"></script> | |
4 | -<script src="{% static 'js/modal_poll.js'%}"></script> | |
5 | - | |
6 | - | |
7 | -{% for poll in polls %} | |
8 | - {% professor_subject poll.topic.subject request.user as permission%} | |
9 | - {% if permission %} | |
10 | - <li id="poll_{{poll.slug}}"><i class="material-icons">{% trans 'poll' %}</i> <a href="javascript:modal.get('{% url 'course:poll:update_poll' poll.slug %}','#poll','#modal_poll');">{{ poll.name }}</a><a href="javascript:modal.get('{% url 'course:poll:delete_poll' poll.slug %}','#poll','#modal_poll');"><span class="glyphicon glyphicon-remove"></span></a></li> | |
11 | - {% else %} | |
12 | - <li id="poll_{{poll.slug}}"><i class="material-icons">{% trans 'poll' %}</i> <a href="javascript:modal.get('{% url 'course:poll:view_poll' poll.slug %}','#poll','#modal_poll');">{{ poll.name }}</a></li> | |
13 | - {% endif %} | |
3 | +<div id="list-topic-{{ topic.slug }}-poll"> | |
4 | + {% for poll in polls %} | |
5 | + <li id="poll_{{poll.slug}}"><i class="fa fa-bar-chart"></i> <a href="javascript:modal.get('{% url 'course:poll:view_poll' poll.slug %}','#poll','#requisicoes_ajax');">{{ poll }}</a></li> | |
14 | 6 | {% endfor %} |
15 | -{# <button class="btn btn-primary btn-raised" onclick="javascript:modal.get('{% url 'course:poll:create_poll' topic.slug%}','#poll','#modal_poll');">{% trans '+ Create Poll' %}</button> #} | |
16 | -<div class="row" id="modal_poll"> | |
17 | - | |
18 | - | |
19 | - | |
20 | 7 | |
21 | 8 | </div> | ... | ... |
courses/templates/subject/poll_item_actions_teacher.html
0 → 100644
... | ... | @@ -0,0 +1,10 @@ |
1 | +{% load static i18n permission_tags professor_access %} | |
2 | + | |
3 | +<div id="list-topic-{{ topic.slug }}-poll-edit"> | |
4 | + {% for poll in polls %} | |
5 | + <div id="poll_{{poll.slug}}_div"> | |
6 | + <li class="icon_edit_remove" ><a href="javascript:modal.get('{% url 'course:poll:update_poll' poll.slug %}','#poll','#requisicoes_ajax');"><i class="fa fa-pencil fa-lg" aria-hidden="true"></i></a> <a href="javascript:modal.get('{% url 'course:poll:delete_poll' poll.slug %}','#poll','#requisicoes_ajax');"><i class="fa fa-trash fa-lg" aria-hidden="true"></i></a></li> | |
7 | + <li><i class="fa fa-bar-chart"></i> <a href="javascript:modal.get('{% url 'course:poll:view_poll' poll.slug %}','#poll','#requisicoes_ajax');">{{poll}}</a></li> | |
8 | + </div> | |
9 | + {% endfor %} | |
10 | +</div> | ... | ... |
courses/templates/subject_category/index.html
1 | -{% extends 'base.html' %} | |
1 | +{% extends 'home.html' %} | |
2 | 2 | |
3 | 3 | {% load static i18n permission_tags professor_access%} |
4 | 4 | |
... | ... | @@ -12,27 +12,7 @@ |
12 | 12 | {% endblock %} |
13 | 13 | |
14 | 14 | {% block sidebar %} |
15 | - | |
16 | - <div class="panel panel-primary"> | |
17 | - | |
18 | - <div class="panel-heading"> | |
19 | - <h3 class="panel-title">{{course}}</h3> | |
20 | - </div> | |
21 | - | |
22 | - <div class="panel-body"> | |
23 | - {% for category in subject_categories %} | |
24 | - <div class="row"> | |
25 | - <div class="col-md-12 col-sm-12"> | |
26 | - <a href="" class="btn btn-default text-left">{{subject}}</a> | |
27 | - </div> | |
28 | - </div> | |
29 | - {% endfor %} | |
30 | - </div> | |
31 | - </div> | |
32 | - | |
33 | - {% if user|has_role:'system_admin' or user|has_role:'professor' %} | |
34 | - <a href="" class="btn btn-primary btn-md btn-block">{% trans "Create Subject Category" %}</a> | |
35 | - {% endif %} | |
15 | +{{block.super}} | |
36 | 16 | {% endblock %} |
37 | 17 | |
38 | 18 | {% block content %} | ... | ... |
... | ... | @@ -0,0 +1,36 @@ |
1 | +{% load static i18n permission_tags %} | |
2 | + | |
3 | +<!-- Modal (remember to change the ids!!!) --> | |
4 | +<div class="modal fade" id="subject" tabindex="-1" role="dialog" aria-labelledby="{{topic.slug}}_delete"> | |
5 | + <div class="modal-dialog" role="document"> | |
6 | + <div class="modal-content"> | |
7 | + <!-- Modal Header --> | |
8 | + <div class="modal-header"> | |
9 | + | |
10 | + <h4 class="modal-title" id="{{topic.slug}}_delete">{% trans "Delete Course" %}</h4> | |
11 | + </div> | |
12 | + <!-- Modal Body --> | |
13 | + <div class="modal-body"> | |
14 | + <!-- Put ONLY your content here!!! --> | |
15 | + <form id="delete_topic_{{topic.slug}}" action="" method="post"> | |
16 | + {% csrf_token %} | |
17 | + <p>{% trans 'Are you sure you want to delete the subject' %} "{{subject.name}}"?</p> | |
18 | + </form> | |
19 | + </div> | |
20 | + <!-- Modal Footer --> | |
21 | + <div class="modal-footer"> | |
22 | + <!-- Don't remove that!!! --> | |
23 | + <button type="button" class="btn btn-danger btn-raised" data-dismiss="modal">{% trans "Close" %}</button> | |
24 | + <button type="submit" id="button" form="delete_topic_{{topic.slug}}" class="btn btn-primary btn-raised">{% trans "Delete" %}</button> | |
25 | + <script> | |
26 | + $("#delete_topic_{{topic.slug}}").submit(function(event) { | |
27 | + RemoveCourse.remove("{% url 'course:delete_subject' subject.slug %}",$(this).serialize(),"#subject_{{subject.slug}}"); | |
28 | + event.preventDefault(); | |
29 | + }); | |
30 | + </script> | |
31 | + </div> | |
32 | + </div> | |
33 | + </div> | |
34 | +</div> | |
35 | +<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> | |
36 | +<script src="{% static 'js/modal_subject.js' %}"></script> | ... | ... |
courses/templates/topic/index.html
1 | -{% extends 'base.html' %} | |
1 | +{% extends 'home.html' %} | |
2 | 2 | |
3 | 3 | {% load static i18n permission_tags professor_access %} |
4 | 4 | |
... | ... | @@ -27,21 +27,7 @@ |
27 | 27 | {% endblock %} |
28 | 28 | |
29 | 29 | {% block sidebar %} |
30 | - | |
31 | - <div class="panel panel-primary"> | |
32 | - <div class="panel-heading"> | |
33 | - <h5>{% trans 'Menu' %}</h5> | |
34 | - </div> | |
35 | - <div class="panel-body"> | |
36 | - <ul class="nav nav-pills nav-stacked"> | |
37 | - <li><a href="{% url 'users:profile' %}">{% trans 'Profile' %}</a></li> | |
38 | - <li><a href="{% url 'course:manage' %}">{% trans 'My Courses' %}</a></li> | |
39 | - </ul> | |
40 | - </div> | |
41 | - </div> | |
42 | - | |
43 | - | |
44 | - | |
30 | +{{block.super}} | |
45 | 31 | {% endblock %} |
46 | 32 | |
47 | 33 | {% block content %} | ... | ... |
courses/templates/topic/link_topic_list.html
1 | 1 | {% load static i18n list_topic_foruns permission_tags %} |
2 | 2 | <div id="list-topic{{ topic.id }}-links"> |
3 | 3 | {% for link in links%} |
4 | - <li id = "link_{{ link.slug }}"><i class="fa fa-link" aria-hidden="true"></i> <a href="javascript:modal.get('{% url 'course:links:view_link' link.slug %}', '#viewLinkModal','#divModalLink')">{{link.name}}</a></li> | |
4 | + <li id = "link_{{ link.slug }}"><i class="fa fa-link" aria-hidden="true"></i> <a href="javascript:modal.get('{% url 'course:links:view_link' link.slug %}', '#viewLinkModal','#requisicoes_ajax')">{{link.name}}</a></li> | |
5 | 5 | {% endfor %} |
6 | 6 | </div> |
7 | -<div class = 'row' id ="divModalLink"> | |
8 | - | |
9 | -</div> | ... | ... |
courses/templates/topic/link_topic_list_edit.html
1 | 1 | {% load static i18n list_topic_foruns permission_tags %} |
2 | 2 | <div id="list-topic{{ topic.id }}-links-edit"> |
3 | -{% for link in links%} | |
4 | - | |
5 | - <li class="icon_edit_remove" id = "link_edit_icon_{{ link.slug }}"> <a href="javascript:modal.get('{% url 'course:links:update_link' link.slug %}', '#linksModalEdit', '#divModalLinkUpdate')"><i class="fa fa-pencil fa-lg" aria-hidden="true"></i></a> <a href="javascript:modal.get('{% url 'course:links:delete_link' link.slug %}', '#linkDeleteModal', '#divModalLinkUpdate')"><i class="fa fa-trash fa-lg" aria-hidden="true"></i></a></li> | |
6 | - <li id = "link_{{ link.slug }}"><i class="fa fa-link" aria-hidden="true"></i> <a href="javascript:modal.get('{% url 'course:links:view_link' link.slug %}', '#viewLinkModal','#divModalLink')">{{link.name}}</a></li> | |
7 | - | |
8 | -{% endfor %} | |
9 | -</div> | |
10 | - | |
11 | -<div class="row" id="divModalLinkUpdate"> | |
12 | - | |
3 | + {% for link in links%} | |
4 | + <li class="icon_edit_remove" id = "link_edit_icon_{{ link.slug }}"> <a href="javascript:modal.get('{% url 'course:links:update_link' link.slug %}', '#linksModalEdit', '#requisicoes_ajax')"><i class="fa fa-pencil fa-lg" aria-hidden="true"></i></a> <a href="javascript:modal.get('{% url 'course:links:delete_link' link.slug %}', '#linkDeleteModal', '#requisicoes_ajax')"><i class="fa fa-trash fa-lg" aria-hidden="true"></i></a></li> | |
5 | + <li id = "link_edit_{{ link.slug }}"><i class="fa fa-link" aria-hidden="true"></i> <a href="javascript:modal.get('{% url 'course:links:view_link' link.slug %}', '#viewLinkModal','#requisicoes_ajax')">{{link.name}}</a></li> | |
6 | + {% endfor %} | |
13 | 7 | </div> | ... | ... |
courses/templates/topic/list_file.html
... | ... | @@ -3,10 +3,10 @@ |
3 | 3 | <div id="list-topic{{ topic.id }}-files"> |
4 | 4 | {% for file in files %} |
5 | 5 | <li id="file_{{ file.slug }}"><i class="material-icons">{{ file.file_type.icon }}</i> <a href="{% url 'course:file_material_view' file.slug %}" target="_blank">{{ file.name }}</a></li> |
6 | - {% endfor %} | |
6 | + {% endfor %} | |
7 | 7 | </div> |
8 | - | |
9 | 8 | |
10 | -<div class="row" id="divModalFile"> | |
11 | 9 | |
12 | -</div> | |
10 | +{# <div class="row" id="divModalFile">#} | |
11 | + | |
12 | +{# </div>#} | ... | ... |
courses/templates/topic/list_file_edit.html
... | ... | @@ -2,11 +2,11 @@ |
2 | 2 | |
3 | 3 | <div id="list-topic{{ topic.id }}-files-edit"> |
4 | 4 | {% for file in files %} |
5 | - <li class="icon_edit_remove" id="file_edit_icon_{{ file.slug }}"> <a href="javascript:modal.get('{% url 'course:file:update_file' file.slug %}', '#fileUpdateModal', '#divModalFileUpdate')" ><i class="fa fa-pencil fa-lg" aria-hidden="true"></i></a> <a href="javascript:modal.get('{% url 'course:file:delete_file' file.slug %}', '#fileDeleteModal', '#divModalFileUpdate')"><i class="fa fa-trash fa-lg" aria-hidden="true"></i></a></li> | |
5 | + <li class="icon_edit_remove" id="file_edit_icon_{{ file.slug }}"> <a href="javascript:modal.get('{% url 'course:file:update_file' file.slug %}', '#fileUpdateModal', '#requisicoes_ajax')" ><i class="fa fa-pencil fa-lg" aria-hidden="true"></i></a> <a href="javascript:modal.get('{% url 'course:file:delete_file' file.slug %}', '#fileDeleteModal', '#requisicoes_ajax')"><i class="fa fa-trash fa-lg" aria-hidden="true"></i></a></li> | |
6 | 6 | <li id="file_edit_{{ file.slug }}"><i class="material-icons">{{ file.file_type.icon }}</i> <a href="{{ file.file_url.url }}" target="_blank">{{ file.name }}</a></li> |
7 | 7 | {% endfor %} |
8 | 8 | </div> |
9 | 9 | |
10 | -<div class="row" id="divModalFileUpdate"> | |
10 | +{# <div class="row" id="divModalFileUpdate">#} | |
11 | 11 | |
12 | -</div> | |
13 | 12 | \ No newline at end of file |
13 | +{# </div>#} | ... | ... |
courses/templatetags/list_topic_foruns.py
... | ... | @@ -32,13 +32,14 @@ def list_topic_poll(request, topic): |
32 | 32 | |
33 | 33 | return context |
34 | 34 | |
35 | -@register.inclusion_tag('subject/exam_item_actions.html') | |
36 | -def list_topic_exam(request, topic): | |
35 | + | |
36 | +@register.inclusion_tag('subject/poll_item_actions_teacher.html') | |
37 | +def list_topic_poll_teacher(request, topic): | |
37 | 38 | context = { |
38 | 39 | 'request': request, |
39 | 40 | } |
40 | 41 | |
41 | - context['exams'] = Exam.objects.filter(topic = topic) | |
42 | + context['polls'] = Poll.objects.filter(topic = topic) | |
42 | 43 | context['topic'] = topic |
43 | 44 | |
44 | 45 | return context | ... | ... |
courses/urls.py
... | ... | @@ -22,6 +22,7 @@ urlpatterns = [ |
22 | 22 | url(r'^subjects/subscribe/(?P<slug>[\w_-]+)/$', views.subscribe_subject, name='subscribe_subject'), |
23 | 23 | url(r'^topics/create/(?P<slug>[\w_-]+)/$', views.CreateTopicView.as_view(), name='create_topic'), |
24 | 24 | url(r'^topics/update/(?P<slug>[\w_-]+)/$', views.UpdateTopicView.as_view(), name='update_topic'), |
25 | + url(r'^topics/update/(?P<slug>[\w_-]+)/$', views.DeleteTopic.as_view(), name='update_topic'), | |
25 | 26 | url(r'^topics/(?P<slug>[\w_-]+)/$', views.TopicsView.as_view(), name='view_topic'), |
26 | 27 | url(r'^subjects/categories$',views.IndexSubjectCategoryView.as_view(), name='subject_category_index'), |
27 | 28 | url(r'^forum/', include('forum.urls', namespace = 'forum')), | ... | ... |
courses/views.py
... | ... | @@ -25,6 +25,11 @@ from courses.models import Material |
25 | 25 | from django.urls import reverse |
26 | 26 | |
27 | 27 | from datetime import date, datetime |
28 | +import time | |
29 | + | |
30 | +#API IMPORTS | |
31 | +from rest_framework import viewsets, permissions | |
32 | +from .serializers import * | |
28 | 33 | |
29 | 34 | class IndexView(LoginRequiredMixin, NotificationMixin, generic.ListView): |
30 | 35 | |
... | ... | @@ -142,7 +147,7 @@ class AllCoursesView(LoginRequiredMixin, NotificationMixin, generic.ListView): |
142 | 147 | context['aparece'] = self.aparece |
143 | 148 | |
144 | 149 | return context |
145 | - | |
150 | + | |
146 | 151 | class CreateCourseView(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMixin, generic.edit.CreateView): |
147 | 152 | log_component = "course" |
148 | 153 | log_resource = "course" |
... | ... | @@ -314,7 +319,7 @@ class DeleteCourseView(LoginRequiredMixin, HasRoleMixin, LogMixin, generic.Delet |
314 | 319 | self.log_context['course_category_name'] = self.object.category.name |
315 | 320 | |
316 | 321 | super(DeleteCourseView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) |
317 | - | |
322 | + | |
318 | 323 | return reverse_lazy('course:manage') |
319 | 324 | |
320 | 325 | |
... | ... | @@ -341,10 +346,10 @@ class CourseView(LogMixin, NotificationMixin, generic.DetailView): |
341 | 346 | self.log_context['course_slug'] = course.slug |
342 | 347 | self.log_context['course_category_id'] = course.category.id |
343 | 348 | self.log_context['course_category_name'] = course.category.name |
349 | + self.log_context['timestamp_start'] = str(int(time.time())) | |
344 | 350 | |
345 | 351 | super(CourseView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) |
346 | 352 | |
347 | - self.request.session['time_spent'] = str(datetime.now()) | |
348 | 353 | self.request.session['log_id'] = Log.objects.latest('id').id |
349 | 354 | |
350 | 355 | category_sub = self.kwargs.get('category', None) |
... | ... | @@ -359,7 +364,7 @@ class CourseView(LogMixin, NotificationMixin, generic.DetailView): |
359 | 364 | if not category_sub is None: |
360 | 365 | cat = get_object_or_404(CategorySubject, slug = category_sub) |
361 | 366 | subjects = subjects.filter(category = cat) |
362 | - | |
367 | + | |
363 | 368 | context['subjects'] = subjects |
364 | 369 | |
365 | 370 | if has_role(self.request.user,'system_admin'): |
... | ... | @@ -389,12 +394,12 @@ class CourseView(LogMixin, NotificationMixin, generic.DetailView): |
389 | 394 | |
390 | 395 | return context |
391 | 396 | |
392 | -class DeleteView(LoginRequiredMixin, HasRoleMixin, NotificationMixin, generic.DeleteView): | |
397 | +class DeleteTopic(LoginRequiredMixin, HasRoleMixin, NotificationMixin, generic.DeleteView): | |
393 | 398 | |
394 | 399 | allowed_roles = ['professor', 'system_admin'] |
395 | 400 | login_url = reverse_lazy("core:home") |
396 | 401 | redirect_field_name = 'next' |
397 | - model = Course | |
402 | + model = Topic | |
398 | 403 | template_name = 'course/delete.html' |
399 | 404 | success_url = reverse_lazy('course:manage') |
400 | 405 | |
... | ... | @@ -412,7 +417,7 @@ def subscribe_course(request, slug): |
412 | 417 | |
413 | 418 | if request.user in course.students.all(): |
414 | 419 | |
415 | - log_context = {} | |
420 | + log_context = {} | |
416 | 421 | log_context['course_id'] = course.id |
417 | 422 | log_context['course_name'] = course.name |
418 | 423 | log_context['course_slug'] = course.slug |
... | ... | @@ -548,10 +553,10 @@ class SubjectsView(LoginRequiredMixin, LogMixin, generic.ListView): |
548 | 553 | self.log_context['course_slug'] = subject.course.slug |
549 | 554 | self.log_context['course_category_id'] = subject.course.category.id |
550 | 555 | self.log_context['course_category_name'] = subject.course.category.name |
556 | + self.log_context['timestamp_start'] = str(int(time.time())) | |
551 | 557 | |
552 | 558 | super(SubjectsView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) |
553 | 559 | |
554 | - self.request.session['time_spent'] = str(datetime.now()) | |
555 | 560 | self.request.session['log_id'] = Log.objects.latest('id').id |
556 | 561 | |
557 | 562 | return super(SubjectsView, self).dispatch(*args, **kwargs) |
... | ... | @@ -653,10 +658,10 @@ class TopicsView(LoginRequiredMixin, LogMixin, generic.ListView): |
653 | 658 | self.log_context['course_slug'] = topic.subject.course.slug |
654 | 659 | self.log_context['course_category_id'] = topic.subject.course.category.id |
655 | 660 | self.log_context['course_category_name'] = topic.subject.course.category.name |
661 | + self.log_context['timestamp_start'] = str(int(time.time())) | |
656 | 662 | |
657 | 663 | super(TopicsView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) |
658 | 664 | |
659 | - self.request.session['time_spent'] = str(datetime.now()) | |
660 | 665 | self.request.session['log_id'] = Log.objects.latest('id').id |
661 | 666 | |
662 | 667 | return super(TopicsView, self).dispatch(*args, **kwargs) |
... | ... | @@ -665,7 +670,7 @@ class TopicsView(LoginRequiredMixin, LogMixin, generic.ListView): |
665 | 670 | topic = get_object_or_404(Topic, slug = self.kwargs.get('slug')) |
666 | 671 | subject = topic.subject |
667 | 672 | topics_q = Topic.objects.filter(subject = subject, visible=True) |
668 | - | |
673 | + | |
669 | 674 | return topics_q |
670 | 675 | |
671 | 676 | def get_context_data(self, **kwargs): |
... | ... | @@ -681,7 +686,7 @@ class TopicsView(LoginRequiredMixin, LogMixin, generic.ListView): |
681 | 686 | context['students_activit'] = students_activit |
682 | 687 | context['materials'] = materials |
683 | 688 | context['form'] = ActivityForm |
684 | - | |
689 | + | |
685 | 690 | return context |
686 | 691 | |
687 | 692 | |
... | ... | @@ -716,7 +721,7 @@ class CreateTopicView(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMi |
716 | 721 | self.object.owner = self.request.user |
717 | 722 | self.object.save() |
718 | 723 | action = super(CreateTopicView, self).createorRetrieveAction("create Topic") |
719 | - super(CreateTopicView, self).createNotification("Topic "+ self.object.name + " was created", | |
724 | + super(CreateTopicView, self).createNotification("Topic "+ self.object.name + " was created", | |
720 | 725 | resource_name=self.object.name, resource_link= reverse('course:view_topic',args=[self.object.slug]), |
721 | 726 | actor=self.request.user, users = self.object.subject.course.students.all() ) |
722 | 727 | |
... | ... | @@ -733,7 +738,7 @@ class CreateTopicView(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMi |
733 | 738 | self.log_context['course_category_name'] = self.object.subject.course.category.name |
734 | 739 | |
735 | 740 | super(CreateTopicView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) |
736 | - | |
741 | + | |
737 | 742 | return super(CreateTopicView, self).form_valid(form) |
738 | 743 | |
739 | 744 | class UpdateTopicView(LoginRequiredMixin, HasRoleMixin, LogMixin, generic.UpdateView): |
... | ... | @@ -939,7 +944,7 @@ def subscribe_subject(request, slug): |
939 | 944 | subject.students.add(request.user) |
940 | 945 | |
941 | 946 | if request.user in subject.students.all(): |
942 | - log_context = {} | |
947 | + log_context = {} | |
943 | 948 | log_context['subject_id'] = subject.id |
944 | 949 | log_context['subject_name'] = subject.name |
945 | 950 | log_context['subject_slug'] = subject.slug |
... | ... | @@ -999,10 +1004,29 @@ class FileMaterialView(LoginRequiredMixin, LogMixin, generic.DetailView): |
999 | 1004 | self.log_context['course_slug'] = file.topic.subject.course.slug |
1000 | 1005 | self.log_context['course_category_id'] = file.topic.subject.course.category.id |
1001 | 1006 | self.log_context['course_category_name'] = file.topic.subject.course.category.name |
1007 | + self.log_context['timestamp_start'] = str(int(time.time())) | |
1002 | 1008 | |
1003 | 1009 | super(FileMaterialView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) |
1004 | 1010 | |
1005 | - self.request.session['time_spent'] = str(datetime.now()) | |
1006 | 1011 | self.request.session['log_id'] = Log.objects.latest('id').id |
1007 | 1012 | |
1008 | 1013 | return super(FileMaterialView, self).dispatch(*args, **kwargs) |
1014 | + | |
1015 | + | |
1016 | +#API VIEWS | |
1017 | +class CourseViewSet(viewsets.ModelViewSet): | |
1018 | + queryset = Course.objects.all() | |
1019 | + serializer_class = CourseSerializer | |
1020 | + permissions_class = (permissions.IsAuthenticatedOrReadOnly) | |
1021 | + | |
1022 | +class SubjectViewSet(viewsets.ModelViewSet): | |
1023 | + queryset = Subject.objects.all() | |
1024 | + serializer_class = SubjectSerializer | |
1025 | + permissions_class = (permissions.IsAuthenticatedOrReadOnly) | |
1026 | + | |
1027 | + | |
1028 | +class TopicViewSet(viewsets.ModelViewSet): | |
1029 | + queryset = Topic.objects.all() | |
1030 | + serializer_class = TopicSerializer | |
1031 | + permissions_class = (permissions.IsAuthenticatedOrReadOnly) | |
1032 | + | ... | ... |
exam/templates/exam/create.html
1 | -{# {% extends "topic/index.html" %} #} | |
1 | +{% extends "home.html" %} | |
2 | 2 | |
3 | 3 | {% load i18n widget_tweaks dict_access static%} |
4 | 4 | |
... | ... | @@ -87,17 +87,15 @@ |
87 | 87 | </div> |
88 | 88 | </div> |
89 | 89 | </div> |
90 | -{% block script_exam %} | |
90 | + | |
91 | 91 | <script type="text/javascript"> |
92 | 92 | |
93 | 93 | var id = 1; |
94 | 94 | $("#add_question").click(function(){ |
95 | 95 | $.get("{% url 'course:exam:true_or_false_question' %}", function(data){ |
96 | - // var teste = String(data); | |
97 | - // teste.replace("#radiosTF", "W3Schools"); | |
98 | - // alert(teste); | |
96 | + | |
99 | 97 | $("#questions").append(data); |
100 | - // $("#radiosTF").attr("id", "true_id_" + id); | |
98 | + | |
101 | 99 | $("#0").attr("id","true_" + id++); |
102 | 100 | }); |
103 | 101 | }); |
... | ... | @@ -133,8 +131,7 @@ $(function() { |
133 | 131 | }); |
134 | 132 | |
135 | 133 | </script> |
136 | -{% endblock script_exam %} | |
137 | -{# <a href="" data-toggle="modal" data-target="#exam">modal</a> #} | |
138 | 134 | |
139 | 135 | |
140 | -{# {% endblock content %} #} | |
136 | + | |
137 | +{% endblock content %} | ... | ... |
exam/templates/exam/questions/multiple_choice_question.html
... | ... | @@ -31,7 +31,7 @@ |
31 | 31 | <!-- new alternative button --> |
32 | 32 | <div class="form-group"> |
33 | 33 | <div class="col-md-12 col-md-offset-2"> |
34 | - <button type="button" class="btn btn-primary" id="newAlternative">{% trans 'New Alternative' %]</button> | |
34 | + <button type="button" class="btn btn-primary" id="newAlternative">{% trans 'New Alternative' %}</button> | |
35 | 35 | </div> |
36 | 36 | </div> |
37 | 37 | <div class="form-group"> | ... | ... |
exam/views.py
... | ... | @@ -9,15 +9,22 @@ from django.utils.translation import ugettext_lazy as _ |
9 | 9 | from rolepermissions.verifications import has_role |
10 | 10 | from rolepermissions.verifications import has_object_permission |
11 | 11 | from django.db.models import Q |
12 | +from datetime import datetime | |
13 | +import time | |
12 | 14 | # from django.views.generic.edit import FormMixin |
13 | 15 | |
14 | 16 | from .forms import ExamForm |
15 | 17 | from .models import Exam, Answer, AnswersStudent |
16 | -from core.mixins import NotificationMixin | |
18 | +from core.mixins import LogMixin, NotificationMixin | |
19 | +from core.models import Log | |
17 | 20 | from users.models import User |
18 | 21 | from courses.models import Course, Topic |
19 | 22 | |
20 | -class ViewExam(LoginRequiredMixin,generic.DetailView): | |
23 | +class ViewExam(LoginRequiredMixin, LogMixin, generic.DetailView): | |
24 | + log_component = 'exam' | |
25 | + log_resource = 'exam' | |
26 | + log_action = 'viewed' | |
27 | + log_context = {} | |
21 | 28 | |
22 | 29 | model = Exam |
23 | 30 | context_object_name = 'exam' |
... | ... | @@ -40,11 +47,34 @@ class ViewExam(LoginRequiredMixin,generic.DetailView): |
40 | 47 | context['status'] = False |
41 | 48 | else: |
42 | 49 | context['status'] = answered[0].status |
50 | + | |
51 | + self.log_context['exam_id'] = exam.id | |
52 | + self.log_context['topic_id'] = exam.topic.id | |
53 | + self.log_context['topic_name'] = exam.topic.name | |
54 | + self.log_context['topic_slug'] = exam.topic.slug | |
55 | + self.log_context['subject_id'] = exam.topic.subject.id | |
56 | + self.log_context['subject_name'] = exam.topic.subject.name | |
57 | + self.log_context['subject_slug'] = exam.topic.subject.slug | |
58 | + self.log_context['course_id'] = exam.topic.subject.course.id | |
59 | + self.log_context['course_name'] = exam.topic.subject.course.name | |
60 | + self.log_context['course_slug'] = exam.topic.subject.course.slug | |
61 | + self.log_context['course_category_id'] = exam.topic.subject.course.category.id | |
62 | + self.log_context['course_category_name'] = exam.topic.subject.course.category.name | |
63 | + self.request.session['time_spent'] = str(int(time.time())) | |
64 | + | |
65 | + super(ViewExam, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | |
66 | + | |
67 | + self.request.session['log_id'] = Log.objects.latest('id').id | |
68 | + | |
43 | 69 | return context |
44 | 70 | |
45 | 71 | |
46 | 72 | |
47 | -class CreateExam(LoginRequiredMixin,HasRoleMixin, NotificationMixin,generic.CreateView): | |
73 | +class CreateExam(LoginRequiredMixin,HasRoleMixin, LogMixin, NotificationMixin, generic.CreateView): | |
74 | + log_component = 'exam' | |
75 | + log_resource = 'exam' | |
76 | + log_action = 'create' | |
77 | + log_context = {} | |
48 | 78 | |
49 | 79 | allowed_roles = ['professor', 'system_admin'] |
50 | 80 | login_url = reverse_lazy("core:home") |
... | ... | @@ -83,6 +113,21 @@ class CreateExam(LoginRequiredMixin,HasRoleMixin, NotificationMixin,generic.Crea |
83 | 113 | answer = Answer(answer=self.request.POST[key],order=key,exam=self.object) |
84 | 114 | answer.save() |
85 | 115 | |
116 | + self.log_context['exam_id'] = self.object.id | |
117 | + self.log_context['topic_id'] = self.object.topic.id | |
118 | + self.log_context['topic_name'] = self.object.topic.name | |
119 | + self.log_context['topic_slug'] = self.object.topic.slug | |
120 | + self.log_context['subject_id'] = self.object.topic.subject.id | |
121 | + self.log_context['subject_name'] = self.object.topic.subject.name | |
122 | + self.log_context['subject_slug'] = self.object.topic.subject.slug | |
123 | + self.log_context['course_id'] = self.object.topic.subject.course.id | |
124 | + self.log_context['course_name'] = self.object.topic.subject.course.name | |
125 | + self.log_context['course_slug'] = self.object.topic.subject.course.slug | |
126 | + self.log_context['course_category_id'] = self.object.topic.subject.course.category.id | |
127 | + self.log_context['course_category_name'] = self.object.topic.subject.course.category.name | |
128 | + | |
129 | + super(CreateExam, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | |
130 | + | |
86 | 131 | return self.render_to_response(self.get_context_data(form = form), status = 200) |
87 | 132 | |
88 | 133 | def get_context_data(self, **kwargs): |
... | ... | @@ -93,7 +138,11 @@ class CreateExam(LoginRequiredMixin,HasRoleMixin, NotificationMixin,generic.Crea |
93 | 138 | context['subjects'] = topic.subject.course.subjects.all() |
94 | 139 | return context |
95 | 140 | |
96 | -class UpdateExam(LoginRequiredMixin,HasRoleMixin,generic.UpdateView): | |
141 | +class UpdateExam(LoginRequiredMixin,HasRoleMixin, LogMixin, generic.UpdateView): | |
142 | + log_component = 'exam' | |
143 | + log_resource = 'exam' | |
144 | + log_action = 'update' | |
145 | + log_context = {} | |
97 | 146 | |
98 | 147 | allowed_roles = ['professor', 'system_admin'] |
99 | 148 | login_url = reverse_lazy("core:home") |
... | ... | @@ -139,6 +188,21 @@ class UpdateExam(LoginRequiredMixin,HasRoleMixin,generic.UpdateView): |
139 | 188 | answer = Answer(answer=self.request.POST[key],order=key,exam=exam) |
140 | 189 | answer.save() |
141 | 190 | |
191 | + self.log_context['exam_id'] = self.object.id | |
192 | + self.log_context['topic_id'] = self.object.topic.id | |
193 | + self.log_context['topic_name'] = self.object.topic.name | |
194 | + self.log_context['topic_slug'] = self.object.topic.slug | |
195 | + self.log_context['subject_id'] = self.object.topic.subject.id | |
196 | + self.log_context['subject_name'] = self.object.topic.subject.name | |
197 | + self.log_context['subject_slug'] = self.object.topic.subject.slug | |
198 | + self.log_context['course_id'] = self.object.topic.subject.course.id | |
199 | + self.log_context['course_name'] = self.object.topic.subject.course.name | |
200 | + self.log_context['course_slug'] = self.object.topic.subject.course.slug | |
201 | + self.log_context['course_category_id'] = self.object.topic.subject.course.category.id | |
202 | + self.log_context['course_category_name'] = self.object.topic.subject.course.category.name | |
203 | + | |
204 | + super(UpdateExam, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | |
205 | + | |
142 | 206 | return super(UpdateExam, self).form_valid(form) |
143 | 207 | |
144 | 208 | def get_context_data(self, **kwargs): |
... | ... | @@ -158,7 +222,11 @@ class UpdateExam(LoginRequiredMixin,HasRoleMixin,generic.UpdateView): |
158 | 222 | |
159 | 223 | return context |
160 | 224 | |
161 | -class DeleteExam(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): | |
225 | +class DeleteExam(LoginRequiredMixin, HasRoleMixin, LogMixin, generic.DeleteView): | |
226 | + log_component = 'exam' | |
227 | + log_resource = 'exam' | |
228 | + log_action = 'delete' | |
229 | + log_context = {} | |
162 | 230 | |
163 | 231 | allowed_roles = ['professor', 'system_admin'] |
164 | 232 | login_url = reverse_lazy("core:home") |
... | ... | @@ -184,12 +252,31 @@ class DeleteExam(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): |
184 | 252 | return context |
185 | 253 | |
186 | 254 | def get_success_url(self): |
255 | + self.log_context['exam_id'] = self.object.id | |
256 | + self.log_context['topic_id'] = self.object.topic.id | |
257 | + self.log_context['topic_name'] = self.object.topic.name | |
258 | + self.log_context['topic_slug'] = self.object.topic.slug | |
259 | + self.log_context['subject_id'] = self.object.topic.subject.id | |
260 | + self.log_context['subject_name'] = self.object.topic.subject.name | |
261 | + self.log_context['subject_slug'] = self.object.topic.subject.slug | |
262 | + self.log_context['course_id'] = self.object.topic.subject.course.id | |
263 | + self.log_context['course_name'] = self.object.topic.subject.course.name | |
264 | + self.log_context['course_slug'] = self.object.topic.subject.course.slug | |
265 | + self.log_context['course_category_id'] = self.object.topic.subject.course.category.id | |
266 | + self.log_context['course_category_name'] = self.object.topic.subject.course.category.name | |
267 | + | |
268 | + super(DeleteExam, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | |
269 | + | |
187 | 270 | return reverse_lazy('course:view_topic', kwargs={'slug' : self.object.topic.slug}) |
188 | 271 | |
189 | 272 | class AnswerExam(generic.TemplateView): |
190 | 273 | template_name = 'exam/answer.html' |
191 | 274 | |
192 | -class AnswerStudentExam(LoginRequiredMixin,generic.CreateView): | |
275 | +class AnswerStudentExam(LoginRequiredMixin, LogMixin, generic.CreateView): | |
276 | + log_component = 'exam' | |
277 | + log_resource = 'exam' | |
278 | + log_action = 'answer' | |
279 | + log_context = {} | |
193 | 280 | |
194 | 281 | model = AnswersStudent |
195 | 282 | fields = ['status'] |
... | ... | @@ -209,6 +296,37 @@ class AnswerStudentExam(LoginRequiredMixin,generic.CreateView): |
209 | 296 | if(key != 'csrfmiddlewaretoken'): |
210 | 297 | answers.answer.add(exam.answers.all().filter(order=key)[0]) |
211 | 298 | |
299 | + self.log_context['exam_id'] = exam.id | |
300 | + self.log_context['topic_id'] = exam.topic.id | |
301 | + self.log_context['topic_name'] = exam.topic.name | |
302 | + self.log_context['topic_slug'] = exam.topic.slug | |
303 | + self.log_context['subject_id'] = exam.topic.subject.id | |
304 | + self.log_context['subject_name'] = exam.topic.subject.name | |
305 | + self.log_context['subject_slug'] = exam.topic.subject.slug | |
306 | + self.log_context['course_id'] = exam.topic.subject.course.id | |
307 | + self.log_context['course_name'] = exam.topic.subject.course.name | |
308 | + self.log_context['course_slug'] = exam.topic.subject.course.slug | |
309 | + self.log_context['course_category_id'] = exam.topic.subject.course.category.id | |
310 | + self.log_context['course_category_name'] = exam.topic.subject.course.category.name | |
311 | + | |
312 | + date_time_click = datetime.strptime(self.request.session.get('time_spent'), "%Y-%m-%d %H:%M:%S.%f") | |
313 | + _now = datetime.now() | |
314 | + | |
315 | + time_spent = _now - date_time_click | |
316 | + | |
317 | + secs = time_spent.total_seconds() | |
318 | + hours = int(secs / 3600) | |
319 | + minutes = int(secs / 60) % 60 | |
320 | + secs = secs % 60 | |
321 | + | |
322 | + self.log_context['timestamp_end'] = str(int(time.time())) | |
323 | + self.log_context['time_spent'] = {} | |
324 | + self.log_context['time_spent']['hours'] = hours | |
325 | + self.log_context['time_spent']['minutes'] = minutes | |
326 | + self.log_context['time_spent']['seconds'] = secs | |
327 | + | |
328 | + super(AnswerStudentExam, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | |
329 | + | |
212 | 330 | return self.render_to_response(self.get_context_data(form = form), status = 200) |
213 | 331 | |
214 | 332 | def get_context_data(self, **kwargs): |
... | ... | @@ -230,6 +348,9 @@ class AnswerStudentExam(LoginRequiredMixin,generic.CreateView): |
230 | 348 | context['answers'] = answers |
231 | 349 | context['keys'] = keys |
232 | 350 | |
351 | + self.log_context['timestamp_start'] = str(int(time.time())) | |
352 | + self.request.session['time_spent'] = str(datetime.now()) | |
353 | + | |
233 | 354 | return context |
234 | 355 | |
235 | 356 | class MultipleChoiceQuestion(generic.TemplateView): | ... | ... |
forum/views.py
... | ... | @@ -8,6 +8,7 @@ from django.core.paginator import Paginator, EmptyPage |
8 | 8 | from django.http import Http404, JsonResponse |
9 | 9 | from django.urls import reverse |
10 | 10 | from django.template.loader import render_to_string |
11 | +import time | |
11 | 12 | |
12 | 13 | from rolepermissions.mixins import HasRoleMixin |
13 | 14 | from rolepermissions.verifications import has_object_permission |
... | ... | @@ -229,10 +230,10 @@ class ForumDetailView(LoginRequiredMixin, LogMixin, generic.DetailView): |
229 | 230 | self.log_context['course_slug'] = forum.topic.subject.course.slug |
230 | 231 | self.log_context['course_category_id'] = forum.topic.subject.course.category.id |
231 | 232 | self.log_context['course_category_name'] = forum.topic.subject.course.category.name |
233 | + self.log_context['timestamp_start'] = str(int(time.time())) | |
232 | 234 | |
233 | 235 | super(ForumDetailView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) |
234 | 236 | |
235 | - self.request.session['time_spent'] = str(datetime.datetime.now()) | |
236 | 237 | self.request.session['log_id'] = Log.objects.latest('id').id |
237 | 238 | |
238 | 239 | return super(ForumDetailView, self).dispatch(*args, **kwargs) | ... | ... |
links/static/js/links.js
links/templates/links/create_link.html
... | ... | @@ -45,6 +45,7 @@ |
45 | 45 | {# // <script src="{% static 'js/links.js' %}"></script> #} |
46 | 46 | <script type="text/javascript"> |
47 | 47 | $("#form-link").submit(function(event) { |
48 | + $("#createLinksModal").modal("hide"); | |
48 | 49 | var data = new FormData($('#form-link').get(0)); |
49 | 50 | $.ajax({ |
50 | 51 | url: "{% url 'course:links:create_link' topic.slug %}", |
... | ... | @@ -54,15 +55,16 @@ |
54 | 55 | processData: false, |
55 | 56 | contentType: false, |
56 | 57 | success: function(data) { |
57 | - $('#createLinksModal').modal('hide'); | |
58 | + $('#requisicoes_ajax').empty(); | |
58 | 59 | $('#list-topic{{ topic.id }}-links').append(data); |
59 | 60 | $('#list-topic{{ topic.id }}-links-edit').append(data); |
60 | 61 | alertify.alert('Link successfully created!') |
61 | 62 | }, |
62 | 63 | error: function(data){ |
63 | - $('.erro').html(data.responseText); | |
64 | - $('.modal-backdrop').remove(); | |
65 | - $('#createLinksModal').modal(); | |
64 | + $("div.modal-backdrop.fade.in").remove(); | |
65 | + $('#requisicoes_ajax').empty(); | |
66 | + $('#requisicoes_ajax').append(data.responseText); | |
67 | + $('#createLinksModal').modal('show'); | |
66 | 68 | alertify.alert('Invalid link, insert a valid one!'); |
67 | 69 | } |
68 | 70 | }); | ... | ... |
links/templates/links/delete_link.html
... | ... | @@ -40,6 +40,7 @@ |
40 | 40 | <script type="text/javascript"> |
41 | 41 | $("#form-delete-link").submit(function(event) { |
42 | 42 | var data = new FormData($('#form-delete-link').get(0)); |
43 | + $('#linkDeleteModal').modal('hide'); | |
43 | 44 | $.ajax({ |
44 | 45 | url: "{% url 'course:links:delete_link' link.slug %}", |
45 | 46 | type: $("#form-delete-link").attr('method'), |
... | ... | @@ -48,16 +49,17 @@ |
48 | 49 | processData: false, |
49 | 50 | contentType: false, |
50 | 51 | success: function(data) { |
51 | - $('#linkDeleteModal').modal('hide'); | |
52 | + $('#requisicoes_ajax').empty(); | |
52 | 53 | $('#link_{{ link.slug }}').remove(); |
53 | 54 | $('#link_edit_icon_{{ link.slug }}').remove(); |
54 | 55 | $('#link_edit_{{ link.slug }}').remove(); |
55 | 56 | alertify.alert('Link successfully deleted!') |
56 | 57 | }, |
57 | 58 | error: function(data){ |
58 | - // $('.erro-update').html(data.responseText); | |
59 | - $('.modal-backdrop').remove(); | |
60 | - $('#linkDeteleModal').modal(); | |
59 | + $("div.modal-backdrop.fade.in").remove(); | |
60 | + $('#requisicoes_ajax').empty(); | |
61 | + $('#requisicoes_ajax').append(data.responseText); | |
62 | + $('#linkDeleteModal').modal('show'); | |
61 | 63 | alertify.alert('Error when trying to delete.'); |
62 | 64 | } |
63 | 65 | }); | ... | ... |
links/templates/links/render_link.html
1 | -<li id="link_{{ link.slug }}"><i class="fa fa-link" aria-hidden="true"></i> <a href="javascript:get_modal_link('{% url 'course:links:view_link' link.slug %}', '#viewLinkModal','#divModalLink')">{{link.name}}</a></li> | |
1 | +<li id="link_{{ link.slug }}"><i class="fa fa-link" aria-hidden="true"></i> <a href="javascript:modal.get('{% url 'course:links:view_link' link.slug %}', '#viewLinkModal','#requisicoes_ajax')">{{link.name}}</a></li> | ... | ... |
links/templates/links/update_link.html
... | ... | @@ -50,6 +50,7 @@ |
50 | 50 | {# // <script src="{% static 'js/links.js' %}"></script> #} |
51 | 51 | <script type="text/javascript"> |
52 | 52 | $("#form-update-link").submit(function(event) { |
53 | + $('#linksModalEdit').modal('hide'); | |
53 | 54 | var data = new FormData($('#form-update-link').get(0)); |
54 | 55 | $.ajax({ |
55 | 56 | url: "{% url 'course:links:update_link' link.slug %}", |
... | ... | @@ -59,14 +60,15 @@ |
59 | 60 | processData: false, |
60 | 61 | contentType: false, |
61 | 62 | success: function(data) { |
62 | - $('#linksModalEdit').modal('hide'); | |
63 | + $('#requisicoes_ajax').empty(); | |
63 | 64 | $('#link_edit_{{ link.slug }}').replaceWith(data); |
64 | 65 | $('#link_{{ link.slug }}').replaceWith(data); |
65 | 66 | alertify.alert("Sucessfully Updated!") |
66 | 67 | }, |
67 | 68 | error: function(data){ |
68 | - $('.erro-update').html(data.responseText); | |
69 | - $('.modal-backdrop').remove(); | |
69 | + $("div.modal-backdrop.fade.in").remove(); | |
70 | + $('#requisicoes_ajax').empty(); | |
71 | + $('#requisicoes_ajax').append(data.responseText); | |
70 | 72 | $('#linksModalEdit').modal(); |
71 | 73 | alertify.alert('Invalid link, insert a valid one!'); |
72 | 74 | } | ... | ... |
links/templates/links/view_link.html
links/views.py
... | ... | @@ -10,6 +10,7 @@ from core.mixins import NotificationMixin |
10 | 10 | from django.urls import reverse |
11 | 11 | from django.core.files.base import ContentFile |
12 | 12 | from rolepermissions.verifications import has_role |
13 | +import time | |
13 | 14 | |
14 | 15 | from core.models import Log |
15 | 16 | from core.mixins import LogMixin |
... | ... | @@ -244,6 +245,7 @@ class ViewLink(LoginRequiredMixin, HasRoleMixin, LogMixin, generic.DetailView): |
244 | 245 | self.log_context['course_slug'] = link.topic.subject.course.slug |
245 | 246 | self.log_context['course_category_id'] = link.topic.subject.course.category.id |
246 | 247 | self.log_context['course_category_name'] = link.topic.subject.course.category.name |
248 | + self.log_context['timestamp_start'] = str(int(time.time())) | |
247 | 249 | |
248 | 250 | super(ViewLink, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) |
249 | 251 | ... | ... |
poll/models.py
... | ... | @@ -12,7 +12,7 @@ class Poll(Activity): |
12 | 12 | verbose_name_plural = _('Polls') |
13 | 13 | |
14 | 14 | def __str__(self): |
15 | - return str(self.name) + str("/") + str(self.topic) | |
15 | + return str(self.name) | |
16 | 16 | |
17 | 17 | class Answer(models.Model): |
18 | 18 | answer = models.CharField(_("Answer"), max_length = 200) | ... | ... |
poll/static/js/modal_poll.js
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 | -}); | |
1 | +// | |
2 | +// //controles do modal | |
3 | +// $(window).ready(function() { // utilizado para abrir o modal quando tiver tido algum erro no preenchimento do formulario | |
4 | +// if($('.not_submited').length){ | |
5 | +// $('#poll').modal('show'); | |
6 | +// } | |
7 | +// }); | |
8 | + | |
7 | 9 | var Answer = { |
8 | 10 | init: function(url) { // utilizado para adicionar um novo campo de resposta |
9 | 11 | $.get(url, function(data){ |
... | ... | @@ -17,24 +19,57 @@ var Answer = { |
17 | 19 | }; |
18 | 20 | |
19 | 21 | var Submite = { |
20 | - post: function(url,dados){ | |
22 | + create: function(url,dados, slug){ | |
21 | 23 | $('#poll').modal('hide'); |
24 | + var poll = null; | |
22 | 25 | $.post(url,dados, function(data){ |
26 | + $.ajax({ | |
27 | + method: "get", | |
28 | + url: data["view"], | |
29 | + success: function(view){ | |
30 | + $('#list-topic-'+ slug +'-poll').append(view); | |
31 | + } | |
32 | + }); | |
33 | + $.ajax({ | |
34 | + method: "get", | |
35 | + url: data["edit"], | |
36 | + success: function(edit){ | |
37 | + $('#list-topic-'+ slug +'-poll-edit').append(edit); | |
38 | + } | |
39 | + }); | |
40 | + $("#requisicoes_ajax").empty(); | |
41 | + alertify.alert('Poll successfully created!'); | |
42 | + $("div.modal-backdrop.fade.in").remove(); | |
23 | 43 | }).fail(function(data){ |
24 | 44 | $("div.modal-backdrop.fade.in").remove(); |
25 | - $("#modal_poll").empty(); | |
26 | - $("#modal_poll").append(data.responseText); | |
45 | + $("#requisicoes_ajax").empty(); | |
46 | + $("#requisicoes_ajax").append(data.responseText); | |
47 | + $('#poll').modal('show'); | |
48 | + }); | |
49 | + }, | |
50 | + update: function(url,dados, slug_poll, slug_topic){ | |
51 | + $('#poll').modal('hide'); | |
52 | + $.post(url,dados, function(data){ | |
53 | + $('#list-topic-'+ slug_topic +'-poll #'+slug_poll).replaceWith(data); | |
54 | + $('#list-topic-'+ slug_topic +'-poll #'+slug_poll).replaceWith(data); | |
55 | + alertify.alert('Poll successfully updated!') | |
56 | + }).fail(function(data){ | |
57 | + $("div.modal-backdrop.fade.in").remove(); | |
58 | + $("#requisicoes_ajax").empty(); | |
59 | + $("#requisicoes_ajax").append(data.responseText); | |
60 | + $('#poll').modal('show'); | |
27 | 61 | }); |
28 | 62 | }, |
29 | 63 | remove: function(url,dados, id_li_link){ |
30 | 64 | $('#poll').modal('hide'); |
31 | 65 | $.post(url,dados, function(data){ |
32 | 66 | $(id_li_link).remove(); |
33 | - $("#modal_poll").empty(); | |
67 | + $(id_li_link+"_div").remove(); | |
68 | + $("#requisicoes_ajax").empty(); | |
34 | 69 | $("div.modal-backdrop.fade.in").remove(); |
35 | 70 | }).fail(function(){ |
36 | - $("#modal_poll").empty(); | |
37 | - $("#modal_poll").append(data); | |
71 | + $("#requisicoes_ajax").empty(); | |
72 | + $("#requisicoes_ajax").append(data); | |
38 | 73 | $('#poll').modal('show'); |
39 | 74 | }); |
40 | 75 | } | ... | ... |
poll/templates/poll/create.html
... | ... | @@ -2,13 +2,6 @@ |
2 | 2 | |
3 | 3 | {% load i18n widget_tweaks dict_access static%} |
4 | 4 | |
5 | -{# {% block style %} #} | |
6 | - <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> | |
7 | - <script src="{% static 'js/modal_poll.js' %}"></script> | |
8 | - | |
9 | -{# {% endblock %} #} | |
10 | - | |
11 | -{# {% block content %} #} | |
12 | 5 | <!-- Modal (remember to change the ids!!!) --> |
13 | 6 | <div class="modal fade" id="poll" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> |
14 | 7 | <div class="modal-dialog" role="document"> |
... | ... | @@ -178,7 +171,7 @@ |
178 | 171 | }); |
179 | 172 | |
180 | 173 | $("#form").submit(function(event) { |
181 | - Submite.post("{% url 'course:poll:create_poll' topic.slug %}",$(this).serialize()); | |
174 | + Submite.create("{% url 'course:poll:create_poll' topic.slug %}",$(this).serialize(), "{{topic.slug}}"); | |
182 | 175 | event.preventDefault(); |
183 | 176 | }); |
184 | 177 | </script> | ... | ... |
... | ... | @@ -0,0 +1,4 @@ |
1 | +<div id="poll_{{poll.slug}}_div"> | |
2 | + <li class="icon_edit_remove" ><a href="javascript:modal.get('{% url 'course:poll:update_poll' poll.slug %}','#poll','#requisicoes_ajax');"><i class="fa fa-pencil fa-lg" aria-hidden="true"></i></a> <a href="javascript:modal.get('{% url 'course:poll:delete_poll' poll.slug %}','#poll','#requisicoes_ajax');"><i class="fa fa-trash fa-lg" aria-hidden="true"></i></a></li> | |
3 | + <li><i class="fa fa-bar-chart"></i> <a href="javascript:modal.get('{% url 'course:poll:view_poll' poll.slug %}','#poll','#requisicoes_ajax');">{{poll}}</a></li> | |
4 | +</div> | ... | ... |
... | ... | @@ -0,0 +1 @@ |
1 | +<li id="poll_{{poll.slug}}"><i class="fa fa-bar-chart"></i> <a href="javascript:modal.get('{% url 'course:poll:view_poll' poll.slug %}','#poll','#requisicoes_ajax');">{{ poll }}</a></li> | ... | ... |
poll/templates/poll/remove.html
... | ... | @@ -10,15 +10,15 @@ |
10 | 10 | {% block content_poll %} |
11 | 11 | <script src="{% static 'js/modal_poll.js' %}"></script> |
12 | 12 | <!-- Put ONLY your content here!!! --> |
13 | -<form id="delete_form" action="" method="post"> | |
13 | +<form id="delete_poll" action="" method="post"> | |
14 | 14 | {% csrf_token %} |
15 | 15 | <p>{% trans 'Are you sure you want to delete the subject' %} "{{poll.name}}"?</p> |
16 | 16 | </form> |
17 | 17 | {% endblock content_poll %} |
18 | 18 | {% block button_save %} |
19 | -<button type="submite" id="button" form="delete_form" class="btn btn-primary btn-raised">{% trans "Delete" %}</button> | |
19 | +<button type="submite" id="button" form="delete_poll" class="btn btn-primary btn-raised">{% trans "Delete" %}</button> | |
20 | 20 | <script> |
21 | - $("#delete_form").submit(function(event) { | |
21 | + $("#delete_poll").submit(function(event) { | |
22 | 22 | Submite.remove("{% url 'course:poll:delete_poll' poll.slug %}",$(this).serialize(),"#poll_{{poll.slug}}"); |
23 | 23 | event.preventDefault(); |
24 | 24 | }); | ... | ... |
poll/templates/poll/update.html
... | ... | @@ -25,7 +25,7 @@ |
25 | 25 | }); |
26 | 26 | |
27 | 27 | $("#form").submit(function(event) { |
28 | - Submite.post("{% url 'course:poll:update_poll' poll.slug %}",$(this).serialize()); | |
28 | + Submite.update("{% url 'course:poll:update_poll' poll.slug %}",$(this).serialize(), "{{poll.slug}}"); | |
29 | 29 | event.preventDefault(); |
30 | 30 | }); |
31 | 31 | </script> | ... | ... |
poll/urls.py
... | ... | @@ -9,4 +9,6 @@ urlpatterns = [ |
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 | 11 | url(r'^answer-poll/(?P<slug>[\w\-_]+)/$', views.AnswerStudentPoll.as_view(), name='answer_student_poll'), # poll slug |
12 | + url(r'^poll-view/(?P<slug>[\w\-_]+)/$', views.render_poll_view, name='render_poll_view'), # poll slug | |
13 | + url(r'^poll-edit/(?P<slug>[\w\-_]+)/$', views.render_poll_edit, name='render_poll_edit'), # poll slug | |
12 | 14 | ] | ... | ... |
poll/views.py
... | ... | @@ -10,6 +10,7 @@ from rolepermissions.verifications import has_role |
10 | 10 | from rolepermissions.verifications import has_object_permission |
11 | 11 | from django.db.models import Q |
12 | 12 | from django.urls import reverse |
13 | +import time | |
13 | 14 | |
14 | 15 | from .forms import PollForm |
15 | 16 | from .models import Poll, Answer, AnswersStudent |
... | ... | @@ -20,6 +21,8 @@ from courses.models import Course, Topic |
20 | 21 | |
21 | 22 | import datetime |
22 | 23 | |
24 | +from django.http import JsonResponse | |
25 | + | |
23 | 26 | class ViewPoll(LoginRequiredMixin, LogMixin, generic.DetailView): |
24 | 27 | log_component = "poll" |
25 | 28 | log_resource = "poll" |
... | ... | @@ -46,10 +49,10 @@ class ViewPoll(LoginRequiredMixin, LogMixin, generic.DetailView): |
46 | 49 | self.log_context['course_slug'] = poll.topic.subject.course.slug |
47 | 50 | self.log_context['course_category_id'] = poll.topic.subject.course.category.id |
48 | 51 | self.log_context['course_category_name'] = poll.topic.subject.course.category.name |
52 | + self.log_context['timestamp_start'] = str(int(time.time())) | |
49 | 53 | |
50 | 54 | super(ViewPoll, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) |
51 | 55 | |
52 | - self.request.session['time_spent'] = str(datetime.datetime.now()) | |
53 | 56 | self.request.session['log_id'] = Log.objects.latest('id').id |
54 | 57 | |
55 | 58 | return poll |
... | ... | @@ -96,7 +99,6 @@ class CreatePoll(LoginRequiredMixin,HasRoleMixin, LogMixin, NotificationMixin,ge |
96 | 99 | context.context_data['keys'] = keys |
97 | 100 | context.context_data['form'] = form |
98 | 101 | context.status_code = 400 |
99 | - s | |
100 | 102 | return context |
101 | 103 | |
102 | 104 | def form_valid(self, form): |
... | ... | @@ -107,7 +109,7 @@ class CreatePoll(LoginRequiredMixin,HasRoleMixin, LogMixin, NotificationMixin,ge |
107 | 109 | self.object.save() |
108 | 110 | |
109 | 111 | super(CreatePoll, self).createNotification(message="created a Poll at "+ self.object.topic.name, actor=self.request.user, |
110 | - resource_name=self.object.name, resource_link= reverse('course:view_topic', args=[self.object.topic.slug]), | |
112 | + resource_name=self.object.name, resource_link= reverse('course:view_topic', args=[self.object.topic.slug]), | |
111 | 113 | users=self.object.topic.subject.students.all()) |
112 | 114 | for key in self.request.POST: |
113 | 115 | if(key != 'csrfmiddlewaretoken' and key != 'name' and key != 'limit_date' and key != 'all_students' and key != 'students'): |
... | ... | @@ -130,7 +132,14 @@ class CreatePoll(LoginRequiredMixin,HasRoleMixin, LogMixin, NotificationMixin,ge |
130 | 132 | |
131 | 133 | super(CreatePoll, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) |
132 | 134 | |
133 | - return self.render_to_response(self.get_context_data(form = form), status = 200) | |
135 | + return JsonResponse({"view":reverse_lazy('course:poll:render_poll_view', kwargs={'slug' : self.object.slug}), | |
136 | + "edit":reverse_lazy('course:poll:render_poll_edit', kwargs={'slug' : self.object.slug}), | |
137 | + }) | |
138 | + | |
139 | + | |
140 | + # def get_success_url(self): | |
141 | + # self.success_url = redirect('course:poll:render_poll', slug = self.object.slug) | |
142 | + # return self.success_url | |
134 | 143 | |
135 | 144 | def get_context_data(self, **kwargs): |
136 | 145 | context = super(CreatePoll, self).get_context_data(**kwargs) |
... | ... | @@ -141,6 +150,20 @@ class CreatePoll(LoginRequiredMixin,HasRoleMixin, LogMixin, NotificationMixin,ge |
141 | 150 | context['subjects'] = topic.subject.course.subjects.all() |
142 | 151 | return context |
143 | 152 | |
153 | +def render_poll_view(request, slug): | |
154 | + template_name = 'poll/poll_view.html' | |
155 | + context = { | |
156 | + 'poll': get_object_or_404(Poll, slug = slug) | |
157 | + } | |
158 | + return render(request, template_name, context) | |
159 | + | |
160 | +def render_poll_edit(request, slug): | |
161 | + template_name = 'poll/poll_edit.html' | |
162 | + context = { | |
163 | + 'poll': get_object_or_404(Poll, slug = slug) | |
164 | + } | |
165 | + return render(request, template_name, context) | |
166 | + | |
144 | 167 | class UpdatePoll(LoginRequiredMixin, HasRoleMixin, LogMixin, generic.UpdateView): |
145 | 168 | log_component = "poll" |
146 | 169 | log_resource = "poll" |
... | ... | @@ -293,6 +316,7 @@ class AnswerStudentPoll(LoginRequiredMixin, LogMixin, generic.CreateView): |
293 | 316 | def dispatch(self, *args, **kwargs): |
294 | 317 | if self.request.method == 'GET': |
295 | 318 | self.request.session['time_spent'] = str(datetime.datetime.now()) |
319 | + self.log_context['timestamp_start'] = str(int(time.time())) | |
296 | 320 | |
297 | 321 | return super(AnswerStudentPoll, self).dispatch(*args, **kwargs) |
298 | 322 | |
... | ... | @@ -322,12 +346,13 @@ class AnswerStudentPoll(LoginRequiredMixin, LogMixin, generic.CreateView): |
322 | 346 | self.log_context['course_slug'] = poll.topic.subject.course.slug |
323 | 347 | self.log_context['course_category_id'] = poll.topic.subject.course.category.id |
324 | 348 | self.log_context['course_category_name'] = poll.topic.subject.course.category.name |
349 | + self.log_context['timestamp_end'] = str(int(time.time())) | |
325 | 350 | |
326 | 351 | date_time_click = datetime.datetime.strptime(self.request.session.get('time_spent'), "%Y-%m-%d %H:%M:%S.%f") |
327 | 352 | _now = datetime.datetime.now() |
328 | - | |
353 | + | |
329 | 354 | time_spent = _now - date_time_click |
330 | - | |
355 | + | |
331 | 356 | secs = time_spent.total_seconds() |
332 | 357 | hours = int(secs / 3600) |
333 | 358 | minutes = int(secs / 60) % 60 | ... | ... |
requirements.txt
... | ... | @@ -6,9 +6,11 @@ dj-database-url==0.4.1 |
6 | 6 | Django==1.10 |
7 | 7 | django-autoslug==1.9.3 |
8 | 8 | django-bootstrap-breadcrumbs==0.8 |
9 | +django-braces==1.10.0 | |
9 | 10 | django-discover-runner==1.0 |
10 | 11 | django-floppyforms==1.7.0 |
11 | 12 | django-modalview==0.1.5 |
13 | +django-oauth-toolkit==0.10.0 | |
12 | 14 | django-role-permissions==1.2.1 |
13 | 15 | django-s3direct==0.4.2 |
14 | 16 | django-summernote==0.8.6 |
... | ... | @@ -19,10 +21,12 @@ gunicorn==19.6.0 |
19 | 21 | Jinja2==2.8 |
20 | 22 | lxml==3.6.4 |
21 | 23 | MarkupSafe==0.23 |
24 | +oauthlib==1.0.3 | |
22 | 25 | Pillow==3.3.1 |
23 | 26 | psycopg2==2.6.2 |
24 | 27 | pycpfcnpj==1.0.2 |
25 | 28 | requests==2.11.1 |
29 | +six==1.10.0 | |
26 | 30 | slugify==0.0.1 |
27 | 31 | validators==0.11.0 |
28 | 32 | Werkzeug==0.11.11 | ... | ... |
... | ... | @@ -0,0 +1,9 @@ |
1 | +from rest_framework import serializers | |
2 | +from .models import User | |
3 | + | |
4 | +class UserSerializer(serializers.ModelSerializer): | |
5 | + class Meta: | |
6 | + model = User | |
7 | + fields = ('username','email','name','city','state','gender','image','birth_date','phone', | |
8 | + 'cpf','type_profile','titration','year_titration','institution','curriculum','date_created', | |
9 | + 'is_staff','is_active') | ... | ... |
users/templates/list_users.html
... | ... | @@ -62,7 +62,7 @@ |
62 | 62 | {% if acc.gender == 'M' %} |
63 | 63 | <img src="{% static 'img/male_avatar.png' %}" alt="Avatar" class="img-circle img-responsive img-list-user"> |
64 | 64 | {% else %} |
65 | - <img src="{% static 'img/female_avatar.png' %}" alt="Avatar" class="img-circle img-responsive img-list-user"> | |
65 | + <img src="{% static 'img/female_avatar.png' %}" alt="Avatar" class="img-circle img-responsive img-list-user"> | |
66 | 66 | {% endif %} |
67 | 67 | {% endif %} |
68 | 68 | </div> |
... | ... | @@ -76,7 +76,7 @@ |
76 | 76 | <a href="javascript:void(0)" class="btn btn-danger btn-raised btn-lg" data-toggle="modal" data-target="#DeleteModal{{ forloop.counter }}">{% trans 'Delete' %}</a> |
77 | 77 | </div> |
78 | 78 | </div> |
79 | - | |
79 | + | |
80 | 80 | |
81 | 81 | <!-- Modal --> |
82 | 82 | <div class="modal fade" id="DeleteModal{{ forloop.counter }}" tabindex="-1" role="dialog" aria-labelledby="DeleteModalLabel"> |
... | ... | @@ -87,10 +87,10 @@ |
87 | 87 | <h4 class="modal-title" id="DeleteModalLabel">{% trans 'Confirm delete' %}</h4> |
88 | 88 | </div> |
89 | 89 | <div class="modal-body"> |
90 | - {% trans 'Are you sure you want to delete the user' %} <b>{{acc.name}}</b>? | |
90 | + {% trans 'Are you sure you want to delete the user' %} <b>{{acc.name}}</b>? | |
91 | 91 | </div> |
92 | 92 | <div class="modal-footer"> |
93 | - <a href="#" class="btn btn-raised btn-danger" data-dismiss="modal">{% trans 'Cancel' %}</a> | |
93 | + <a href="#" class="btn btn-raised btn-danger" data-dismiss="modal">{% trans 'Cancel' %}</a> | |
94 | 94 | <a href="{% url 'users:delete' acc.username %}" class="btn btn-raised btn-success" style="margin-top: 0">{% trans 'Delete' %}</a> |
95 | 95 | </div> |
96 | 96 | </div> | ... | ... |
users/templates/users/profile.html
... | ... | @@ -43,7 +43,7 @@ |
43 | 43 | <div class="col-lg-12"> |
44 | 44 | <div class="well well-lg"> |
45 | 45 | <div class="row"> |
46 | - | |
46 | + | |
47 | 47 | {% if user.image %} |
48 | 48 | <div class="col-md-4" style="width: 200px;overflow:hidden;margin-left: 8em;height: 150px;background-image: url('{{user.image.url}}');background-position: center;background-size: cover;"> |
49 | 49 | {% else %} |
... | ... | @@ -51,7 +51,7 @@ |
51 | 51 | {% if user.gender == 'M' %} |
52 | 52 | <img src="{% static 'img/male_avatar.png' %}" alt="Avatar" class="img-circle img-responsive img-list-user" style="margin-left: 8em;"> |
53 | 53 | {% else %} |
54 | - <img src="{% static 'img/female_avatar.png' %}" alt="Avatar" class="img-circle img-responsive img-list-user" style="margin-left: 8em;"> | |
54 | + <img src="{% static 'img/female_avatar.png' %}" alt="Avatar" class="img-circle img-responsive img-list-user" style="margin-left: 8em;"> | |
55 | 55 | {% endif %} |
56 | 56 | {% endif %} |
57 | 57 | </div> |
... | ... | @@ -65,7 +65,7 @@ |
65 | 65 | {% else %} |
66 | 66 | <td> {% trans "OffLine" %}</td> |
67 | 67 | {% endif %} |
68 | - | |
68 | + | |
69 | 69 | </tr> |
70 | 70 | <tr> |
71 | 71 | <td>{% trans "Name" %}:</td> |
... | ... | @@ -94,7 +94,7 @@ |
94 | 94 | {% else %} |
95 | 95 | <td>{% trans "Student" %}</td> |
96 | 96 | {% endif %} |
97 | - | |
97 | + | |
98 | 98 | </tr> |
99 | 99 | <tr> |
100 | 100 | <td>{% trans "CPF" %}:</td> |
... | ... | @@ -104,7 +104,7 @@ |
104 | 104 | {% else %} |
105 | 105 | <td>{% trans "doesn't possess CPF" %}</td> |
106 | 106 | {% endif %} |
107 | - | |
107 | + | |
108 | 108 | </tr> |
109 | 109 | <tr> |
110 | 110 | <td>{% trans "Phone Number" %}:</td> |
... | ... | @@ -113,7 +113,7 @@ |
113 | 113 | {% else %} |
114 | 114 | <td>{% trans "doesn't possess Phone" %}</td> |
115 | 115 | {% endif %} |
116 | - | |
116 | + | |
117 | 117 | </tr> |
118 | 118 | <tr> |
119 | 119 | <td>{% trans "Gender" %}:</td> | ... | ... |
users/templates/users/remove_account.html
... | ... | @@ -29,7 +29,7 @@ |
29 | 29 | <p>{% trans 'All data will be lost and havent how recover it.' %}</p> |
30 | 30 | <div class="row"> |
31 | 31 | <div class="col-md-3 col-sm-2 col-xs-2"> |
32 | - <a href="#" class="btn btn-raised btn-block btn-success" >{% trans 'Remove' %}</a> | |
32 | + <a href="{% url 'users:remove' user.username %}" class="btn btn-raised btn-block btn-success" >{% trans 'Remove' %}</a> | |
33 | 33 | </div> |
34 | 34 | <div class="col-md-3 col-sm-2 col-xs-2"> |
35 | 35 | <a href="{% url 'users:profile' %}" class="btn btn-raised btn-block btn-danger" >{% trans 'Cancel' %}</a> | ... | ... |
users/templates/users/search.html
1 | -<html> | |
2 | -<h1> Links </h1> | |
3 | -{% for link in link_list %} | |
4 | - {{link.name}} </br> | |
5 | -{% endfor %} | |
6 | - | |
7 | -<h1> Polls </h1> | |
8 | -{% for poll in poll_list %} | |
9 | - {{poll.name}} </br> | |
10 | -{% endfor %} | |
11 | - | |
12 | -<h1> Exams </h1> | |
13 | -{% for exam in exam_list %} | |
14 | - {{exam.name}} </br> | |
15 | -{% endfor %} | |
16 | - | |
17 | -<h1> Forums </h1> | |
18 | -{% for forum in forum_list %} | |
19 | - {{forum.name}} </br> | |
20 | -{% endfor %} | |
21 | - | |
22 | -<h1> Files </h1> | |
23 | -{% for file in file_list %} | |
24 | - {{file.name}} </br> | |
25 | -{% endfor %} | |
26 | -</html> | |
1 | +{% extends 'home.html' %} | |
2 | + | |
3 | +{% load i18n pagination django_bootstrap_breadcrumbs permission_tags static %} | |
4 | +{% block javascript %} | |
5 | + <script type="text/javascript" src="{% static 'js/forum.js' %}"></script> | |
6 | + <script src="{% static 'js/file.js' %}"></script> | |
7 | + <script type="text/javascript" src="{% static 'js/material.js' %}"></script> | |
8 | + <script type = "text/javascript" src="{% static 'js/links.js' %}"></script> | |
9 | + <script src="{% static 'js/modals_requisitions.js'%}"></script> | |
10 | + <script src="{% static 'js/modal_poll.js'%}"></script> | |
11 | +{% endblock %} | |
12 | + | |
13 | +{% block breadcrumbs %} | |
14 | + {{ block.super }} | |
15 | + {% breadcrumb 'Search' 'users:search' %} | |
16 | + | |
17 | +{% endblock %} | |
18 | + | |
19 | + | |
20 | +{% block content %} | |
21 | +<div class="jumbotron"> | |
22 | +<h3>Search Result:</h3> {{qtd}} items found | |
23 | + | |
24 | +{% if link_list %} | |
25 | +<div class="panel-group"> | |
26 | + <div class="panel panel-default"> | |
27 | + <div class="panel-heading"> | |
28 | + <h4 class="panel-title"> | |
29 | + <a data-toggle="collapse" href="#Link" id="bot" style="color: black"> <i class="fa fa-caret-square-o-down" aria-hidden="true" id="down"></i>Links</a> | |
30 | + </h4> | |
31 | + </div> | |
32 | + <div id="Link" class="panel-collapse collapse"> | |
33 | + <div class="panel-body"> | |
34 | + | |
35 | + | |
36 | + {% for link in link_list %} | |
37 | + <li id = "link_{{ link.slug }}"><i class="fa fa-link" aria-hidden="true"></i> <a href="javascript:modal.get('{% url 'course:links:view_link' link.slug %}', '#viewLinkModal','#divModalLink')">{{link.name}}</a></li> | |
38 | + {% endfor %} | |
39 | + <div class = 'row' id ="divModalLink"> | |
40 | + | |
41 | + </div> | |
42 | + | |
43 | + </div> | |
44 | + | |
45 | + </div> | |
46 | + </div> | |
47 | +</div> | |
48 | +{% endif%} | |
49 | + | |
50 | +{% if file_list %} | |
51 | +<div class="panel-group"> | |
52 | + <div class="panel panel-default"> | |
53 | + <div class="panel-heading"> | |
54 | + <h4 class="panel-title"> | |
55 | + <a data-toggle="collapse" href="#File" id="bot1" style="color: black"> <i class="fa fa-caret-square-o-down" aria-hidden="true" id="down1"></i>File</a> | |
56 | + </h4> | |
57 | + </div> | |
58 | + <div id="File" class="panel-collapse collapse"> | |
59 | + <div class="panel-body"> | |
60 | + | |
61 | + {% for file in file_list %} | |
62 | + <li id="file_{{ file.slug }}"><i class="material-icons">{{ file.file_type.icon }}</i> <a href="{% url 'course:file_material_view' file.slug %}" target="_blank">{{ file.name }}</a></li> | |
63 | + {% endfor%} | |
64 | + | |
65 | + | |
66 | + <div class="row" id="divModalFile"> | |
67 | + | |
68 | + </div> | |
69 | + </div> | |
70 | + | |
71 | + | |
72 | + </div> | |
73 | + </div> | |
74 | +</div> | |
75 | +{% endif %} | |
76 | + | |
77 | +{% if forum_list %} | |
78 | +<div class="panel-group"> | |
79 | + <div class="panel panel-default"> | |
80 | + <div class="panel-heading"> | |
81 | + <h4 class="panel-title"> | |
82 | + <a data-toggle="collapse" href="#Forum" id="bot2" style="color: black"> <i class="fa fa-caret-square-o-down" aria-hidden="true" id="down2"></i>Forum</a> | |
83 | + </h4> | |
84 | + </div> | |
85 | + <div id="Forum" class="panel-collapse collapse"> | |
86 | + <div class="panel-body"> | |
87 | + {% for forum in forum_list %} | |
88 | + <li><i class="fa fa-commenting" aria-hidden="true"></i> <a id="forum_{{ forum.id }}" href="{% url 'course:forum:view' forum.slug %}"> {{ forum }}</a></li> | |
89 | + {% endfor %} | |
90 | + | |
91 | + </div> | |
92 | + | |
93 | + </div> | |
94 | + </div> | |
95 | +</div> | |
96 | +{% endif %} | |
97 | + | |
98 | +{% if exam_list %} | |
99 | +<div class="panel-group"> | |
100 | + <div class="panel panel-default"> | |
101 | + <div class="panel-heading"> | |
102 | + <h4 class="panel-title"> | |
103 | + <a data-toggle="collapse" href="#Exam" id="bot3" style="color: black"> <i class="fa fa-caret-square-o-down" aria-hidden="true" id="down3"></i>Exam</a> | |
104 | + </h4> | |
105 | + </div> | |
106 | + <div id="Exam" class="panel-collapse collapse"> | |
107 | + <div class="panel-body"> | |
108 | + {% for exam in exam_list %} | |
109 | + {{exam.name}} | |
110 | + {% endfor %} | |
111 | + | |
112 | + </div> | |
113 | + | |
114 | + </div> | |
115 | + </div> | |
116 | +</div> | |
117 | +{% endif %} | |
118 | + | |
119 | +{% if poll_list %} | |
120 | +<div class="panel-group"> | |
121 | + <div class="panel panel-default"> | |
122 | + <div class="panel-heading"> | |
123 | + <h4 class="panel-title"> | |
124 | + <a data-toggle="collapse" href="#Poll" id="bot4" style="color: black"> <i class="fa fa-caret-square-o-down" aria-hidden="true" id="down4"></i>Poll</a> | |
125 | + </h4> | |
126 | + </div> | |
127 | + <div id="Poll" class="panel-collapse collapse"> | |
128 | + <div class="panel-body"> | |
129 | + | |
130 | + {% for poll in poll_list %} | |
131 | + <li id="poll_{{poll.slug}}"><i class="material-icons">{% trans 'poll' %}</i> <a href="javascript:modal.get('{% url 'course:poll:view_poll' poll.slug %}','#poll','#modal_poll');">{{ poll.name }}</a></li> | |
132 | + {% endfor %} | |
133 | + | |
134 | + <div class="row" id="modal_poll"> | |
135 | + | |
136 | + </div> | |
137 | + </div> | |
138 | + </div> | |
139 | + </div> | |
140 | +</div> | |
141 | +{% endif %} | |
142 | +</div> | |
143 | + | |
144 | + | |
145 | +<script type="text/javascript" src="{% static 'js/amadeus.js' %}"> </script> | |
146 | +<script type="text/javascript" src="{% static 'js/topic_editation_presentation_search.js' %}"></script> | |
147 | +{% endblock %} | ... | ... |
users/urls.py
... | ... | @@ -2,12 +2,14 @@ from django.conf.urls import url |
2 | 2 | |
3 | 3 | from . import views |
4 | 4 | |
5 | + | |
5 | 6 | urlpatterns = [ |
6 | 7 | url(r'^$', views.UsersListView.as_view(), name='manage'), |
7 | 8 | url(r'^create/$', views.Create.as_view(), name='create'), |
8 | 9 | url(r'^edit/(?P<username>[\w_-]+)/$', views.Update.as_view(), name='update'), |
9 | 10 | url(r'^view/(?P<username>[\w_-]+)/$', views.View.as_view(), name='view'), |
10 | - url(r'^delete/(?P<username>[\w_-]+)/$', views.delete, name='delete'), | |
11 | + url(r'^delete/(?P<username>[\w_-]+)/$', views.delete_user, name='delete'), | |
12 | + url(r'^remove/(?P<username>[\w_-]+)/$', views.remove_account, name='remove'), | |
11 | 13 | url(r'^profile/$', views.Profile.as_view(), name='profile'), |
12 | 14 | url(r'^search/$', views.SearchView.as_view(), name='search'), |
13 | 15 | # |
... | ... | @@ -15,5 +17,5 @@ urlpatterns = [ |
15 | 17 | url(r'^profile/change_password/$', views.Change_password.as_view(), name='change_password'), |
16 | 18 | url(r'^profile/remove_account/$', views.Remove_account.as_view(), name='remove_account'), |
17 | 19 | url(r'^profile/delete/$', views.DeleteUser.as_view(), name='delete_profile'), |
18 | - | |
20 | + | |
19 | 21 | ] | ... | ... |
users/views.py
... | ... | @@ -20,6 +20,10 @@ from files.models import * |
20 | 20 | from exam.models import * |
21 | 21 | from courses.models import * |
22 | 22 | |
23 | +#API IMPORTS | |
24 | +from rest_framework import viewsets | |
25 | +from .serializers import UserSerializer | |
26 | +from rest_framework.permissions import IsAuthenticated, IsAuthenticatedOrReadOnly | |
23 | 27 | |
24 | 28 | # ================ ADMIN ======================= |
25 | 29 | class UsersListView(HasRoleMixin, LoginRequiredMixin, generic.ListView): |
... | ... | @@ -106,12 +110,17 @@ class View(LoginRequiredMixin, generic.DetailView): |
106 | 110 | slug_field = 'username' |
107 | 111 | slug_url_kwarg = 'username' |
108 | 112 | |
109 | -def delete(request,username): | |
113 | +def delete_user(request,username): | |
110 | 114 | user = get_object_or_404(User,username = username) |
111 | 115 | user.delete() |
112 | 116 | messages.success(request,_("User deleted Successfully!")) |
113 | 117 | return redirect('users:manage') |
114 | 118 | |
119 | +def remove_account(request,username): | |
120 | + user = get_object_or_404(User,username = username) | |
121 | + user.delete() | |
122 | + messages.success(request,_("User deleted Successfully!")) | |
123 | + return redirect('core:logout') | |
115 | 124 | |
116 | 125 | class Change_password(generic.TemplateView): |
117 | 126 | template_name = 'users/change_password.html' |
... | ... | @@ -226,3 +235,12 @@ class SearchView(LoginRequiredMixin, generic.ListView): |
226 | 235 | context['qtd'] = qtd |
227 | 236 | |
228 | 237 | return context |
238 | + | |
239 | + | |
240 | +# API VIEWS | |
241 | + | |
242 | +class UserViewSet(viewsets.ModelViewSet): | |
243 | + queryset = User.objects.all() | |
244 | + serializer_class = UserSerializer | |
245 | + permissions_classes = (IsAuthenticatedOrReadOnly,) | |
246 | + | ... | ... |