Commit d36bd53fe3a8c3d5c867e837e2c284f0872bad6b
1 parent
9e4a8e34
Exists in
master
and in
3 other branches
Adding mural per category page (unfinished)
Showing
7 changed files
with
176 additions
and
5 deletions
Show diff stats
amadeus/static/css/themes/green.css
@@ -575,6 +575,10 @@ a.add-row { | @@ -575,6 +575,10 @@ a.add-row { | ||
575 | background: #FFFFFF; | 575 | background: #FFFFFF; |
576 | } | 576 | } |
577 | 577 | ||
578 | +.mural-category { | ||
579 | + background: #EEE; | ||
580 | +} | ||
581 | + | ||
578 | .btn:not(.btn-raised):not(.btn-link):focus, .btn:not(.btn-raised):not(.btn-link):hover, .input-group-btn .btn:not(.btn-raised):not(.btn-link):focus, .input-group-btn .btn:not(.btn-raised):not(.btn-link):hover { | 582 | .btn:not(.btn-raised):not(.btn-link):focus, .btn:not(.btn-raised):not(.btn-link):hover, .input-group-btn .btn:not(.btn-raised):not(.btn-link):focus, .input-group-btn .btn:not(.btn-raised):not(.btn-link):hover { |
579 | background-color: initial; | 583 | background-color: initial; |
580 | } | 584 | } |
amadeus/templatetags/permissions_tags.py
@@ -5,6 +5,10 @@ from amadeus import permissions | @@ -5,6 +5,10 @@ from amadeus import permissions | ||
5 | register = template.Library() | 5 | register = template.Library() |
6 | 6 | ||
7 | @register.assignment_tag | 7 | @register.assignment_tag |
8 | +def category_permissions(user, category): | ||
9 | + return permissions.has_category_permissions(user, category) | ||
10 | + | ||
11 | +@register.assignment_tag | ||
8 | def subject_permissions(user, subject): | 12 | def subject_permissions(user, subject): |
9 | return permissions.has_subject_permissions(user, subject) | 13 | return permissions.has_subject_permissions(user, subject) |
10 | 14 |
mural/templates/mural/list.html
@@ -8,14 +8,14 @@ | @@ -8,14 +8,14 @@ | ||
8 | 8 | ||
9 | {% trans 'Mural: General' as general %} | 9 | {% trans 'Mural: General' as general %} |
10 | 10 | ||
11 | - {% breadcrumb general 'mural:manage_general' %} | 11 | + {% breadcrumb general 'mural:manage_general' %} |
12 | {% endblock %} | 12 | {% endblock %} |
13 | 13 | ||
14 | {% block content %} | 14 | {% block content %} |
15 | <div id="core-subjects-options-div"> | 15 | <div id="core-subjects-options-div"> |
16 | <ul class="core-subjects-options"> | 16 | <ul class="core-subjects-options"> |
17 | <a href="{% url 'mural:manage_general' %}"><li class="active">{% trans "General" %} ({{ totals.general }})</li></a> | 17 | <a href="{% url 'mural:manage_general' %}"><li class="active">{% trans "General" %} ({{ totals.general }})</li></a> |
18 | - <a href=""><li>{% trans "Per Category" %} ({{ totals.category }})</li></a> | 18 | + <a href="{% url 'mural:manage_category' %}"><li>{% trans "Per Category" %} ({{ totals.category }})</li></a> |
19 | <a href=""><li>{% trans "Per Subject" %} ({{ totals.subject }})</li></a> | 19 | <a href=""><li>{% trans "Per Subject" %} ({{ totals.subject }})</li></a> |
20 | </ul> | 20 | </ul> |
21 | </div> | 21 | </div> |
@@ -0,0 +1,113 @@ | @@ -0,0 +1,113 @@ | ||
1 | +{% extends 'base.html' %} | ||
2 | + | ||
3 | +{% load static i18n pagination permissions_tags mural_filters %} | ||
4 | +{% load django_bootstrap_breadcrumbs %} | ||
5 | + | ||
6 | +{% block breadcrumbs %} | ||
7 | + {{ block.super }} | ||
8 | + | ||
9 | + {% trans 'Mural: Per Category' as category %} | ||
10 | + | ||
11 | + {% breadcrumb category 'mural:manage_category' %} | ||
12 | +{% endblock %} | ||
13 | + | ||
14 | +{% block content %} | ||
15 | + <div id="core-subjects-options-div"> | ||
16 | + <ul class="core-subjects-options"> | ||
17 | + <a href="{% url 'mural:manage_general' %}"><li>{% trans "General" %} ({{ totals.general }})</li></a> | ||
18 | + <a href="{% url 'mural:manage_category' %}"><li class="active">{% trans "Per Category" %} ({{ totals.category }})</li></a> | ||
19 | + <a href=""><li>{% trans "Per Subject" %} ({{ totals.subject }})</li></a> | ||
20 | + </ul> | ||
21 | + </div> | ||
22 | + | ||
23 | + <div class="col-md-12 cards-content"> | ||
24 | + {% if categories.count > 0 %} | ||
25 | + <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true"> | ||
26 | + {% for category in categories %} | ||
27 | + {% category_permissions request.user category as has_category_permissions %} | ||
28 | + | ||
29 | + {% if category.visible %} | ||
30 | + <div class="panel panel-info category-panel"> | ||
31 | + <div class="panel-heading"> | ||
32 | + {% elif has_category_permissions %} | ||
33 | + <div class="panel special-panel"> | ||
34 | + <div class="panel-heading panel-invisible"> | ||
35 | + {% endif %} | ||
36 | + | ||
37 | + <div class="row"> | ||
38 | + <div class="col-md-12 category-header"> | ||
39 | + <h4 class="panel-title"> | ||
40 | + <a class="category-course-link pull-left" data-parent="#accordion" data-toggle="collapse" href="#{{category.slug}}"> | ||
41 | + <button class="btn btn-default btn-xs text-center cat-selector"><i class="fa fa-angle-right fa-2x" aria-hidden="true"></i></button> {{ category.name }} | ||
42 | + | ||
43 | + ({{ category|unviewed:request.user }}) | ||
44 | + </a> | ||
45 | + </h4> | ||
46 | + | ||
47 | + <div class="col-md-5 pull-right category-card-items"> | ||
48 | + {% if has_category_permissions %} | ||
49 | + <a href="" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | ||
50 | + <i class="fa fa-ellipsis-v" aria-hidden="true"></i> | ||
51 | + </a> | ||
52 | + <ul class="dropdown-menu pull-right" aria-labelledby="moreActions"> | ||
53 | + {% if request.user.is_staff %} | ||
54 | + <li><a href="{% url 'categories:replicate' category.slug %}"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i> {% trans 'Replicate' %}</a></li> | ||
55 | + {% endif %} | ||
56 | + <li><a href="{% url 'categories:update' category.slug %}"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i> {% trans 'Edit' %}</a></li> | ||
57 | + <li> | ||
58 | + <a href="javascript:delete_course.get('{% url 'categories:delete' category.slug %}?view=index','#category','#modal_course')" aria-hidden="true"><i class="fa fa-trash fa-fw" aria-hidden="true"></i> {% trans 'Remove' %}</a></li> | ||
59 | + </ul> | ||
60 | + {% endif %} | ||
61 | + </div> | ||
62 | + </div> | ||
63 | + </div> | ||
64 | + </div> | ||
65 | + <div id="{{category.slug}}" class="panel-collapse panel-body collapse mural-category"> | ||
66 | + <div class="col-md-12 cards-content mural" data-url="{% url 'mural:manage_general' %}"> | ||
67 | + <div class="col-md-9 col-sm-9 col-xs-9 mural-list"> | ||
68 | + <div class="post_make panel panel-default"> | ||
69 | + <div class="panel-body"> | ||
70 | + <div class="col-lg-1 col-md-1 col-sm-1 col-xs-1 user-img text-center"> | ||
71 | + <img src="{{ request.user.image_url }}" class="img-responsive" /> | ||
72 | + </div> | ||
73 | + <div class="col-lg-11 col-md-11 col-sm-11 col-xs-11 post-field"> | ||
74 | + <div> | ||
75 | + <h4 data-url="{% url 'mural:create_general' %}">{% trans 'Wish to make a new post?' %}</h4> | ||
76 | + </div> | ||
77 | + </div> | ||
78 | + </div> | ||
79 | + </div> | ||
80 | + | ||
81 | + <div class="posts"> | ||
82 | + </div> | ||
83 | + </div> | ||
84 | + <div class="col-md-3 col-sm-3 col-xs-3 post-filter"> | ||
85 | + <h4>{% trans 'Filter' %}</h4> | ||
86 | + | ||
87 | + <form id="post-filters" action="" method="GET"> | ||
88 | + <div class="checkbox"> | ||
89 | + <label> | ||
90 | + <input name="favorite" type="checkbox"> {% trans 'Favorite posts' %} <i class="fa fa-thumb-tack"></i> | ||
91 | + </label> | ||
92 | + </div> | ||
93 | + <div class="checkbox"> | ||
94 | + <label> | ||
95 | + <input name="mine" type="checkbox"> {% trans 'Only my posts' %} | ||
96 | + </label> | ||
97 | + </div> | ||
98 | + <button type="submit" class="btn btn-success btn-raised btn-block">{% trans 'Filter' %}</button> | ||
99 | + <button type="button" id="clear_filter" class="btn btn-default btn-raised btn-block">{% trans 'Clean Filters' %}</button> | ||
100 | + </form> | ||
101 | + </div> | ||
102 | + </div> | ||
103 | + </div> | ||
104 | + </div> | ||
105 | + {% endfor %} | ||
106 | + | ||
107 | + {% pagination request paginator page_obj %} | ||
108 | + </div> | ||
109 | + {% endif %} | ||
110 | + </div> | ||
111 | + | ||
112 | + <script type="text/javascript" src="{% static 'js/category.js' %}"></script> | ||
113 | +{% endblock %} | ||
0 | \ No newline at end of file | 114 | \ No newline at end of file |
mural/templatetags/mural_filters.py
1 | from django import template | 1 | from django import template |
2 | from django.utils.translation import ugettext_lazy as _ | 2 | from django.utils.translation import ugettext_lazy as _ |
3 | 3 | ||
4 | -from mural.models import MuralFavorites | 4 | +from mural.models import MuralFavorites, MuralVisualizations |
5 | 5 | ||
6 | register = template.Library() | 6 | register = template.Library() |
7 | 7 | ||
@@ -42,4 +42,10 @@ def fav_class(post, user): | @@ -42,4 +42,10 @@ def fav_class(post, user): | ||
42 | if MuralFavorites.objects.filter(post = post, user = user).exists(): | 42 | if MuralFavorites.objects.filter(post = post, user = user).exists(): |
43 | return "btn_unfav" | 43 | return "btn_unfav" |
44 | 44 | ||
45 | - return "btn_fav" | ||
46 | \ No newline at end of file | 45 | \ No newline at end of file |
46 | + return "btn_fav" | ||
47 | + | ||
48 | +@register.filter(name = 'unviewed') | ||
49 | +def unviewed(category, user): | ||
50 | + count = MuralVisualizations.objects.filter(user = user, viewed = False, post__categorypost__space = category).count() | ||
51 | + | ||
52 | + return count | ||
47 | \ No newline at end of file | 53 | \ No newline at end of file |
mural/urls.py
@@ -3,6 +3,7 @@ from . import views | @@ -3,6 +3,7 @@ from . import views | ||
3 | 3 | ||
4 | urlpatterns = [ | 4 | urlpatterns = [ |
5 | url(r'^$', views.GeneralIndex.as_view(), name='manage_general'), | 5 | url(r'^$', views.GeneralIndex.as_view(), name='manage_general'), |
6 | + url(r'^categories/$', views.CategoryIndex.as_view(), name='manage_category'), | ||
6 | url(r'^create_gen/$', views.GeneralCreate.as_view(), name='create_general'), | 7 | url(r'^create_gen/$', views.GeneralCreate.as_view(), name='create_general'), |
7 | url(r'^update_gen/(?P<pk>[\w_-]+)/$', views.GeneralUpdate.as_view(), name='update_general'), | 8 | url(r'^update_gen/(?P<pk>[\w_-]+)/$', views.GeneralUpdate.as_view(), name='update_general'), |
8 | url(r'^delete_gen/(?P<pk>[\w_-]+)/$', views.GeneralDelete.as_view(), name='delete_general'), | 9 | url(r'^delete_gen/(?P<pk>[\w_-]+)/$', views.GeneralDelete.as_view(), name='delete_general'), |
mural/views.py
@@ -14,11 +14,16 @@ from django.db.models import Q, Count | @@ -14,11 +14,16 @@ from django.db.models import Q, Count | ||
14 | from channels import Group | 14 | from channels import Group |
15 | import json | 15 | import json |
16 | 16 | ||
17 | +from categories.models import Category | ||
18 | +from subjects.models import Subject | ||
17 | from users.models import User | 19 | from users.models import User |
18 | 20 | ||
19 | from .models import Mural, GeneralPost, CategoryPost, SubjectPost, MuralVisualizations, MuralFavorites, Comment | 21 | from .models import Mural, GeneralPost, CategoryPost, SubjectPost, MuralVisualizations, MuralFavorites, Comment |
20 | from .forms import GeneralPostForm, CommentForm | 22 | from .forms import GeneralPostForm, CommentForm |
21 | 23 | ||
24 | +""" | ||
25 | + Section for GeneralPost classes | ||
26 | +""" | ||
22 | class GeneralIndex(LoginRequiredMixin, generic.ListView): | 27 | class GeneralIndex(LoginRequiredMixin, generic.ListView): |
23 | login_url = reverse_lazy("users:login") | 28 | login_url = reverse_lazy("users:login") |
24 | redirect_field_name = 'next' | 29 | redirect_field_name = 'next' |
@@ -201,7 +206,45 @@ class GeneralDelete(LoginRequiredMixin, generic.DeleteView): | @@ -201,7 +206,45 @@ class GeneralDelete(LoginRequiredMixin, generic.DeleteView): | ||
201 | for user in users: | 206 | for user in users: |
202 | Group("user-%s" % user.id).send({'text': json.dumps({"type": notify_type, "subtype": "delete", "pathname": pathname, "post_id": self.object.id})}) | 207 | Group("user-%s" % user.id).send({'text': json.dumps({"type": notify_type, "subtype": "delete", "pathname": pathname, "post_id": self.object.id})}) |
203 | 208 | ||
204 | - return reverse_lazy('mural:deleted_post') | 209 | + return reverse_lazy('mural:deleted_post') |
210 | + | ||
211 | +""" | ||
212 | + Section for CategoryPost classes | ||
213 | +""" | ||
214 | +class CategoryIndex(LoginRequiredMixin, generic.ListView): | ||
215 | + login_url = reverse_lazy("users:login") | ||
216 | + redirect_field_name = 'next' | ||
217 | + | ||
218 | + template_name = 'mural/list_category.html' | ||
219 | + context_object_name = "categories" | ||
220 | + paginate_by = 10 | ||
221 | + | ||
222 | + totals = {} | ||
223 | + | ||
224 | + def get_queryset(self): | ||
225 | + user = self.request.user | ||
226 | + | ||
227 | + if user.is_staff: | ||
228 | + categories = Category.objects.all() | ||
229 | + else: | ||
230 | + categories = Category.objects.filter(Q(coordinators__pk = user.pk) | Q(subject_category__professor__pk = user.pk) | Q(subject_category__students__pk = user.pk, visible = True)).distinct() | ||
231 | + | ||
232 | + self.totals['general'] = MuralVisualizations.objects.filter(Q(user = user) & Q(viewed = False) & (Q(post__generalpost__isnull = False) | Q(comment__post__generalpost__isnull = False))).distinct().count() | ||
233 | + self.totals['category'] = MuralVisualizations.objects.filter(Q(user = user) & Q(viewed = False) & (Q(post__categorypost__space__coordinators = user) | Q(comment__post__categorypost__space__coordinators = user) | Q(post__categorypost__space__subject_category__professor = user) | Q(post__categorypost__space__subject_category__students = user) | Q(comment__post__categorypost__space__subject_category__professor = user) | Q(comment__post__categorypost__space__subject_category__students = user))).distinct().count() | ||
234 | + self.totals['subject'] = MuralVisualizations.objects.filter(Q(user = user) & Q(viewed = False) & (Q(post__subjectpost__space__professor = user) | Q(comment__post__subjectpost__space__professor = user) | Q(post__subjectpost__space__students = user) | Q(comment__post__subjectpost__space__students = user))).distinct().count() | ||
235 | + | ||
236 | + print(categories) | ||
237 | + | ||
238 | + return categories | ||
239 | + | ||
240 | + def get_context_data(self, **kwargs): | ||
241 | + context = super(CategoryIndex, self).get_context_data(**kwargs) | ||
242 | + | ||
243 | + context['title'] = _('Mural - Per Category') | ||
244 | + context['totals'] = self.totals | ||
245 | + context['mural_menu_active'] = 'subjects_menu_active' | ||
246 | + | ||
247 | + return context | ||
205 | 248 | ||
206 | def render_gen_post(request, post, msg): | 249 | def render_gen_post(request, post, msg): |
207 | post = get_object_or_404(GeneralPost, id = post) | 250 | post = get_object_or_404(GeneralPost, id = post) |