Commit de22fa0c2dacde2c646fb09abd416aad90588e0a

Authored by Zambom
1 parent 29448ed5

Subject list speed improvement

amadeus/permissions.py
@@ -20,6 +20,15 @@ def has_subject_permissions(user, subject): @@ -20,6 +20,15 @@ def has_subject_permissions(user, subject):
20 20
21 return False 21 return False
22 22
  23 +def has_subject_view_permissions(user, subject):
  24 + if has_subject_permissions(user, subject):
  25 + return True
  26 +
  27 + if subject.students.filter(id = user.id).exists():
  28 + return True
  29 +
  30 + return False
  31 +
23 """ 32 """
24 Function to know if user has permission to: 33 Function to know if user has permission to:
25 - Access Resource 34 - Access Resource
amadeus/static/js/category.js
1 -var locale = navigator.language || navigator.userLanguage;  
2 -  
3 -$('.date-picker').datepicker({  
4 - language: locale,  
5 -});  
6 -  
7 /* 1 /*
8 * 2 *
9 * Function to get a cookie stored on browser 3 * Function to get a cookie stored on browser
@@ -106,49 +100,107 @@ function replicate_course(url, course) { @@ -106,49 +100,107 @@ function replicate_course(url, course) {
106 * Functions to control category marker 100 * Functions to control category marker
107 * 101 *
108 */ 102 */
109 -$('.collapse').on('show.bs.collapse', function (e) {  
110 - if($(this).is(e.target)){  
111 - var btn = $(this).parent().find('.fa-angle-right');  
112 -  
113 - btn = btn[0];  
114 -  
115 - $(btn).switchClass("fa-angle-right", "fa-angle-down", 250, "easeInOutQuad"); 103 +$(function () {
  104 + bindCollapse();
  105 +});
116 106
117 - var url = $(this).parent().find('.log_url').val();  
118 - var log_input = $(this).parent().find('.log_id'); 107 +function bindCollapse() {
  108 + $('.collapse').on('show.bs.collapse', function (e) {
  109 + if($(this).is(e.target)){
  110 + var btn = $(this).parent().find('.fa-angle-right');
  111 +
  112 + btn = btn[0];
  113 +
  114 + $(btn).switchClass("fa-angle-right", "fa-angle-down", 250, "easeInOutQuad");
  115 +
  116 + var url = $(this).parent().find('.log_url').val();
  117 + var log_input = $(this).parent().find('.log_id');
  118 +
  119 + if (typeof(url) != 'undefined') {
  120 + $.ajax({
  121 + url: url,
  122 + data: {'action': 'open'},
  123 + dataType: 'json',
  124 + success: function (data) {
  125 + log_input.val(data.log_id);
  126 + },
  127 + error: function (data) {
  128 + console.log(data);
  129 + }
  130 + });
  131 + }
119 132
120 - if (typeof(url) != 'undefined') {  
121 - $.ajax({  
122 - url: url,  
123 - data: {'action': 'open'},  
124 - dataType: 'json',  
125 - success: function (data) {  
126 - log_input.val(data.log_id);  
127 - },  
128 - error: function (data) {  
129 - console.log(data);  
130 - }  
131 - });  
132 } 133 }
  134 + });
133 135
134 - }  
135 -}); 136 + $('.collapse').on('hide.bs.collapse', function (e) {
  137 + if($(this).is(e.target)){
  138 + var btn = $(this).parent().find('.fa-angle-down');
  139 +
  140 + btn = btn[0];
  141 +
  142 + $(btn).switchClass("fa-angle-down", "fa-angle-right", 250, "easeInOutQuad");
  143 +
  144 + var url = $(this).parent().find('.log_url').val();
  145 + var log_id = $(this).parent().find('.log_id').val();
  146 +
  147 + if (typeof(url) != 'undefined') {
  148 + $.ajax({
  149 + url: url,
  150 + data: {'action': 'close', 'log_id': log_id},
  151 + dataType: 'json',
  152 + success: function (data) {
  153 + console.log(data.message);
  154 + },
  155 + error: function (data) {
  156 + console.log(data);
  157 + }
  158 + });
  159 + }
  160 + }
  161 + });
  162 +}
136 163
137 $('.category-panel-content').on('shown.bs.collapse', function(e) { 164 $('.category-panel-content').on('shown.bs.collapse', function(e) {
138 if($(this).is(e.target)){ 165 if($(this).is(e.target)){
139 var panel_id = $(this).attr('id'); 166 var panel_id = $(this).attr('id');
140 var holder = $(this).find('.holder'); 167 var holder = $(this).find('.holder');
141 168
142 - var items = $('#' + panel_id + '-accordion').children(":visible").length; 169 + if ($('#' + panel_id + '-accordion').children().length == 0) {
  170 + var load_sub_url = $(this).find('.load_sub_url').val();
143 171
144 - if (items > 10) {  
145 - holder.jPages({  
146 - containerID : panel_id + "-accordion",  
147 - perPage: 10,  
148 - previous: "«",  
149 - next: "»",  
150 - midRange: 5 172 + $.ajax({
  173 + url: load_sub_url,
  174 + success: function (data) {
  175 + $('#' + panel_id + '-accordion').html(data);
  176 +
  177 + var items = $('#' + panel_id + '-accordion').children(":visible").length;
  178 +
  179 + if (items > 10) {
  180 + holder.jPages({
  181 + containerID : panel_id + "-accordion",
  182 + perPage: 10,
  183 + previous: "«",
  184 + next: "»",
  185 + midRange: 5
  186 + });
  187 + }
  188 +
  189 + bindCollapse();
  190 + }
151 }); 191 });
  192 + } else {
  193 + var items = $('#' + panel_id + '-accordion').children(":visible").length;
  194 +
  195 + if (items > 10) {
  196 + holder.jPages({
  197 + containerID : panel_id + "-accordion",
  198 + perPage: 10,
  199 + previous: "«",
  200 + next: "»",
  201 + midRange: 5
  202 + });
  203 + }
152 } 204 }
153 } 205 }
154 }); 206 });
@@ -168,32 +220,6 @@ $('.category-panel-content').on('hidden.bs.collapse', function(e) { @@ -168,32 +220,6 @@ $('.category-panel-content').on('hidden.bs.collapse', function(e) {
168 } 220 }
169 }); 221 });
170 222
171 -$('.collapse').on('hide.bs.collapse', function (e) {  
172 - if($(this).is(e.target)){  
173 - var btn = $(this).parent().find('.fa-angle-down');  
174 -  
175 - btn = btn[0];  
176 -  
177 - $(btn).switchClass("fa-angle-down", "fa-angle-right", 250, "easeInOutQuad");  
178 -  
179 - var url = $(this).parent().find('.log_url').val();  
180 - var log_id = $(this).parent().find('.log_id').val();  
181 -  
182 - if (typeof(url) != 'undefined') {  
183 - $.ajax({  
184 - url: url,  
185 - data: {'action': 'close', 'log_id': log_id},  
186 - dataType: 'json',  
187 - success: function (data) {  
188 - console.log(data.message);  
189 - },  
190 - error: function (data) {  
191 - console.log(data);  
192 - }  
193 - });  
194 - }  
195 - }  
196 -});  
197 223
198 function delete_group(url) { 224 function delete_group(url) {
199 $('.modal').remove(); 225 $('.modal').remove();
amadeus/templatetags/permissions_tags.py
@@ -6,4 +6,8 @@ register = template.Library() @@ -6,4 +6,8 @@ register = template.Library()
6 6
7 @register.assignment_tag 7 @register.assignment_tag
8 def subject_permissions(user, subject): 8 def subject_permissions(user, subject):
9 - return permissions.has_subject_permissions(user, subject)  
10 \ No newline at end of file 9 \ No newline at end of file
  10 + return permissions.has_subject_permissions(user, subject)
  11 +
  12 +@register.assignment_tag
  13 +def subject_view_permissions(user, subject):
  14 + return permissions.has_subject_view_permissions(user, subject)
11 \ No newline at end of file 15 \ No newline at end of file
subjects/templates/subjects/_list.html 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +{% load permissions_tags %}
  2 +
  3 +{% for subject in subjects %}
  4 + {% subject_view_permissions request.user subject as has_subject_view_permissions %}
  5 +
  6 + {% if all or has_subject_view_permissions %}
  7 + {% include "subjects/subject_card.html" with subject=subject %}
  8 + {% endif %}
  9 +{% endfor %}
0 \ No newline at end of file 10 \ No newline at end of file
subjects/templates/subjects/list.html
@@ -90,6 +90,8 @@ @@ -90,6 +90,8 @@
90 <div id="{{category.slug}}" class="panel-collapse panel-body collapse category-panel-content"> 90 <div id="{{category.slug}}" class="panel-collapse panel-body collapse category-panel-content">
91 <input type="hidden" class="log_url" value="{% url 'categories:view_log' category.id %}" /> 91 <input type="hidden" class="log_url" value="{% url 'categories:view_log' category.id %}" />
92 <input type="hidden" class="log_id" value="" /> 92 <input type="hidden" class="log_id" value="" />
  93 +
  94 + <input type="hidden" class="load_sub_url" value="{% url 'subjects:load_view' category.slug %}" />
93 95
94 {% if category.coordinators.all|length > 0 %} 96 {% if category.coordinators.all|length > 0 %}
95 <h4><b>{% trans "Coordinator(s) " %}: </b> 97 <h4><b>{% trans "Coordinator(s) " %}: </b>
@@ -106,11 +108,7 @@ @@ -106,11 +108,7 @@
106 {% endif %} 108 {% endif %}
107 109
108 <div class="panel-group subject-group" id="{{ category.slug }}-accordion" role="tablist" aria-multiselectable="true"> 110 <div class="panel-group subject-group" id="{{ category.slug }}-accordion" role="tablist" aria-multiselectable="true">
109 - {% for subject in category.subject_category.all %}  
110 - {% if request.user in subject.students.all or request.user.is_staff or request.user in subject.professor.all or all or request.user in subject.category.coordinators.all %}  
111 - {% include "subjects/subject_card.html" %}  
112 - {% endif %}  
113 - {% endfor %} 111 +
114 </div> 112 </div>
115 <div class="holder text-center"></div> 113 <div class="holder text-center"></div>
116 </div> 114 </div>
@@ -171,9 +169,7 @@ @@ -171,9 +169,7 @@
171 {% endif %} 169 {% endif %}
172 170
173 <div class="panel-group subject-group" id="{{ category.slug }}-accordion" role="tablist" aria-multiselectable="true"> 171 <div class="panel-group subject-group" id="{{ category.slug }}-accordion" role="tablist" aria-multiselectable="true">
174 - {% for subject in category.subject_category.all %}  
175 - {% include "subjects/subject_card.html" %}  
176 - {% endfor %} 172 +
177 </div> 173 </div>
178 </div> 174 </div>
179 </div> 175 </div>
subjects/templates/subjects/subject_card.html
1 -{% load static i18n permission_tags %}  
2 -{% if subject.visible %}  
3 - <div class="panel panel-info subject-panel">  
4 - <div class="panel-heading"> 1 +{% load static i18n permissions_tags %}
  2 +
  3 +{% subject_permissions request.user subject as has_subject_permissions %}
  4 +{% subject_view_permissions request.user subject as has_subject_view_permissions %}
  5 +
  6 +{% if subject.visible or has_subject_permissions %}
  7 + {% if subject.visible %}
  8 + <div class="panel panel-info subject-panel">
  9 + <div class="panel-heading">
  10 + {% elif has_subject_permissions %}
  11 + <div class="panel panel-info subject-panel-invisible">
  12 + <div class="panel-heading panel-invisible">
  13 + {% endif %}
5 <div class="row"> 14 <div class="row">
6 <div class="col-md-12 category-header"> 15 <div class="col-md-12 category-header">
7 <h4 class="panel-title"> 16 <h4 class="panel-title">
8 <a class="category-course-link pull-left" data-parent="#{% if accordion_id %}{{ accordion_id }}{% else %}{{ subject.category.slug }}-accordion{% endif %}" data-toggle="collapse" href="#{{subject.slug}}"> 17 <a class="category-course-link pull-left" data-parent="#{% if accordion_id %}{{ accordion_id }}{% else %}{{ subject.category.slug }}-accordion{% endif %}" data-toggle="collapse" href="#{{subject.slug}}">
9 - <button class="btn btn-default btn-xs text-center cat-selector"><i class="fa fa-angle-right fa-2x" aria-hidden="true"></i></button> {{subject.name}} 18 + <button class="btn btn-default btn-xs text-center cat-selector"><i class="fa fa-angle-right fa-2x" aria-hidden="true"></i></button> {{ subject }}
10 </a> 19 </a>
11 </h4> 20 </h4>
12 21
13 <div class="col-md-5 pull-right category-card-items"> 22 <div class="col-md-5 pull-right category-card-items">
14 - {% if request.user in subject.professor.all or request.user in subject.category.coordinators.all or request.user.is_staff %} 23 + {% if has_subject_permissions %}
15 <a href="" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> 24 <a href="" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
16 <i class="fa fa-ellipsis-v" aria-hidden="true"></i> 25 <i class="fa fa-ellipsis-v" aria-hidden="true"></i>
17 </a> 26 </a>
@@ -56,7 +65,7 @@ @@ -56,7 +65,7 @@
56 65
57 {% if show_buttons %} 66 {% if show_buttons %}
58 67
59 - {% if request.user in subject.students.all or request.user in subject.professor.all or request.user.is_staff or request.user in subject.category.coordinators.all %} 68 + {% if has_subject_view_permissions %}
60 <a href="{% url 'subjects:view' subject.slug %}" class="btn btn-success btn-raised"> {% trans "Access Subject" %}</a> 69 <a href="{% url 'subjects:view' subject.slug %}" class="btn btn-success btn-raised"> {% trans "Access Subject" %}</a>
61 {% else %} 70 {% else %}
62 <a href="javascript:subscribe_subject.get('{% url 'subjects:subscribe' subject.slug %}?view=index','#subject-subscribe','#modal_subject')" class="subscribe-subject btn btn-primary btn-raised"> {% trans "Subscribe to Subject" %}</a> 71 <a href="javascript:subscribe_subject.get('{% url 'subjects:subscribe' subject.slug %}?view=index','#subject-subscribe','#modal_subject')" class="subscribe-subject btn btn-primary btn-raised"> {% trans "Subscribe to Subject" %}</a>
@@ -65,65 +74,4 @@ @@ -65,65 +74,4 @@
65 {% endif %} 74 {% endif %}
66 </div> 75 </div>
67 </div> 76 </div>
68 -{% elif request.user in subject.professor.all or request.user in subject.category.coordinators.all or request.user.is_staff %}  
69 - <div class="panel panel-info subject-panel-invisible">  
70 - <div class="panel-heading panel-invisible">  
71 - <div class="row">  
72 - <div class="col-md-12 category-header">  
73 - <h4 class="panel-title">  
74 - <a class="category-course-link pull-left" data-parent="#{% if accordion_id %}{{ accordion_id }}{% else %}{{ subject.category.slug }}-accordion{% endif %}" data-toggle="collapse" href="#{{subject.slug}}">  
75 - <button class="btn btn-default btn-xs text-center cat-selector"><i class="fa fa-angle-right fa-2x" aria-hidden="true"></i></button> {{subject.name}}  
76 - </a>  
77 - </h4>  
78 -  
79 - <div class="col-md-5 pull-right category-card-items">  
80 - {% if request.user in subject.professor.all or request.user in subject.category.coordinators.all or request.user.is_staff %}  
81 - <a href="" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">  
82 - <i class="fa fa-ellipsis-v" aria-hidden="true"></i>  
83 - </a>  
84 - <ul class="dropdown-menu pull-right" aria-labelledby="moreActions">  
85 - <li><a href="{% url 'subjects:replicate' subject.slug %}"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i>{% trans 'Replicate' %}</a></li>  
86 - <li><a href="{% url 'subjects:update' subject.slug %}"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i>{% trans 'Edit' %}</a></li>  
87 - <li><a href="javascript:delete_subject.get('{% url 'subjects:delete' subject.slug %}?view=index','#subject','#modal_subject')"><i class="fa fa-trash fa-fw" aria-hidden="true"></i>&nbsp;{% trans 'Remove' %}</a></li>  
88 - </ul>  
89 - {% endif %}  
90 - <a href="" ><i class="fa fa-list" aria-hidden="true"></i></a>  
91 - <a href=""><i class="fa fa-envelope-o" aria-hidden="true"></i></a>  
92 - <a href=""><i class="fa fa-exclamation-triangle" aria-hidden="true"></i></a>  
93 - <a href=""><i class="fa fa-bar-chart" aria-hidden="true"></i></a>  
94 - </div>  
95 - </div>  
96 - </div>  
97 - </div>  
98 - <div id="{{subject.slug}}" class="panel-collapse collapse category-panel-content">  
99 - <div class="row">  
100 - <div class="col-md-6">  
101 - {% if subject.professor.all|length > 0 %}  
102 - <h4><b>{% trans "Professor(s) " %}: </b>  
103 - {{ subject.professor.all|join:', ' }}  
104 - </h4>  
105 - {% else %}  
106 - <h4> {% trans "It doesn't possess professors" %} </h4>  
107 - {% endif %}  
108 - </div>  
109 - <div class="col-xs-6 col-md-3">  
110 - <p><b>{% trans "Beginning" %}:</b> {{subject.init_date}}</p>  
111 - </div>  
112 - <div class="col-xs-6 col-md-3">  
113 - <p><b>{% trans "End" %}:</b> {{subject.end_date}}</p>  
114 - </div>  
115 - </div>  
116 -  
117 - <p>{{subject.description_brief|safe}}</p>  
118 - {% if show_buttons %}  
119 -  
120 - {% if request.user in subject.students.all or request.user in subject.professor.all or request.user.is_staff or request.user in subject.category.coordinators.all %}  
121 - <a href="{% url 'subjects:view' subject.slug %}" class="btn btn-success btn-raised"> {% trans "ACESS SUBJECT" %}</a>  
122 - {% else %}  
123 - <a href="{% url 'subjects:subscribe' subject.slug %}?view=index','#subject','#subject')" class="subscribe-subject btn btn-primary btn-raised"> {% trans "SUBSCRIBE TO SUBJECT" %}</a>  
124 - {% endif %}  
125 -  
126 - {% endif %}  
127 - </div>  
128 - </div>  
129 {% endif %} 77 {% endif %}
subjects/urls.py
@@ -13,5 +13,6 @@ urlpatterns = [ @@ -13,5 +13,6 @@ urlpatterns = [
13 url(r'^subscribe/(?P<slug>[\w_-]+)/$', views.SubjectSubscribeView.as_view(), name='subscribe'), 13 url(r'^subscribe/(?P<slug>[\w_-]+)/$', views.SubjectSubscribeView.as_view(), name='subscribe'),
14 url(r'^search/$', views.SubjectSearchView.as_view(), name='search'), 14 url(r'^search/$', views.SubjectSearchView.as_view(), name='search'),
15 url(r'^search/(?P<option>[\w_-]+)/$', views.SubjectSearchView.as_view(), name='search'), 15 url(r'^search/(?P<option>[\w_-]+)/$', views.SubjectSearchView.as_view(), name='search'),
  16 + url(r'^load_subs/(?P<slug>[\w_-]+)/$', views.GetSubjectList.as_view(), name='load_view'),
16 url(r'^(?P<option>[\w_-]+)/$', views.IndexView.as_view(), name='index'), 17 url(r'^(?P<option>[\w_-]+)/$', views.IndexView.as_view(), name='index'),
17 ] 18 ]
18 \ No newline at end of file 19 \ No newline at end of file
subjects/views.py
@@ -73,28 +73,30 @@ class IndexView(LoginRequiredMixin, ListView): @@ -73,28 +73,30 @@ class IndexView(LoginRequiredMixin, ListView):
73 paginate_by = 10 73 paginate_by = 10
74 74
75 def get_queryset(self): 75 def get_queryset(self):
  76 + self.totals['all_subjects'] = count_subjects(self.request.user)
  77 +
  78 + self.totals['my_subjects'] = self.totals['all_subjects']
  79 +
76 if self.request.user.is_staff: 80 if self.request.user.is_staff:
77 categories = Category.objects.all().order_by('name') 81 categories = Category.objects.all().order_by('name')
78 else: 82 else:
79 pk = self.request.user.pk 83 pk = self.request.user.pk
80 84
81 - categories = Category.objects.filter(Q(coordinators__pk = pk) | Q(visible=True) ).distinct().order_by('name') 85 + self.totals['my_subjects'] = count_subjects(self.request.user, False)
82 86
83 - self.totals['all_subjects'] = count_subjects(self.request.user) 87 + if not self.kwargs.get('option'):
  88 + my_categories = Category.objects.filter(Q(coordinators__pk=pk) | Q(subject_category__professor__pk=pk) | Q(subject_category__students__pk = pk, visible = True)).distinct().order_by('name')
  89 +
  90 + categories = my_categories
  91 + else:
  92 + categories = Category.objects.filter(Q(coordinators__pk = pk) | Q(visible=True) ).distinct().order_by('name')
84 93
85 - self.totals['my_subjects'] = self.totals['all_subjects']  
86 -  
87 - if not self.request.user.is_staff:  
88 -  
89 - #my_categories = Category.objects.filter(Q(coordinators__pk=pk) | Q(subject_professor__pk=pk) | Q())  
90 - my_categories = [category for category in categories if self.request.user in category.coordinators.all() \  
91 - or has_professor_profile(self.request.user, category) or has_student_profile(self.request.user, category)] 94 + #if not self.request.user.is_staff:
  95 +
  96 + #my_categories = [category for category in categories if self.request.user in category.coordinators.all() \
  97 + #or has_professor_profile(self.request.user, category) or has_student_profile(self.request.user, category)]
92 #So I remove all categories that doesn't have the possibility for the user to be on 98 #So I remove all categories that doesn't have the possibility for the user to be on
93 99
94 - self.totals['my_subjects'] = count_subjects(self.request.user, False)  
95 -  
96 - if not self.kwargs.get('option'):  
97 - categories = my_categories  
98 100
99 return categories 101 return categories
100 102
@@ -165,6 +167,30 @@ class IndexView(LoginRequiredMixin, ListView): @@ -165,6 +167,30 @@ class IndexView(LoginRequiredMixin, ListView):
165 167
166 return context 168 return context
167 169
  170 +class GetSubjectList(LoginRequiredMixin, ListView):
  171 + login_url = reverse_lazy("users:login")
  172 + redirect_field_name = 'next'
  173 +
  174 + template_name = 'subjects/_list.html'
  175 + model = Subject
  176 + context_object_name = 'subjects'
  177 +
  178 + def get_queryset(self):
  179 + slug = self.kwargs.get('slug')
  180 + category = get_object_or_404(Category, slug = slug)
  181 +
  182 + return category.subject_category.all()
  183 +
  184 + def get_context_data(self, **kwargs):
  185 + context = super(GetSubjectList, self).get_context_data(**kwargs)
  186 +
  187 + context['show_buttons'] = True #So it shows subscribe and access buttons
  188 +
  189 + if 'all' in self.request.META.get('HTTP_REFERER'):
  190 + context['all'] = True
  191 +
  192 + return context
  193 +
168 class SubjectCreateView(LoginRequiredMixin, CreateView): 194 class SubjectCreateView(LoginRequiredMixin, CreateView):
169 model = Subject 195 model = Subject
170 template_name = "subjects/create.html" 196 template_name = "subjects/create.html"