Commit 07193e64de2ee9ab1e2642c6ff8b01ebbc0c5d60

Authored by Zambom
1 parent 85fe3d3f

Adding subject notifications view page

amadeus/static/css/base/amadeus.css
... ... @@ -142,6 +142,10 @@ a:focus {
142 142 font-size: 15px;
143 143 }
144 144  
  145 +.pendencies-content {
  146 + padding: 10px;
  147 +}
  148 +
145 149 .category-panel-content {
146 150 padding:10px;
147 151 }
... ... @@ -834,4 +838,54 @@ li.item .notify_badge {
834 838 font-size: 0.9rem;
835 839 border-radius: 50%;
836 840 padding: 0px;
  841 +}
  842 +
  843 +.pendency {
  844 + border: 1px solid;
  845 + padding-left: 10px;
  846 + padding-top: 7px;
  847 + margin-bottom: 15px;
  848 +}
  849 +
  850 +.pendency .breadcrumb {
  851 + padding-left: 0px;
  852 + margin-bottom: 0px;
  853 +}
  854 +
  855 +.pendency h4 {
  856 + margin: 0px;
  857 + font-size: 22px;
  858 + font-weight: 700;
  859 +}
  860 +
  861 +.pendency p {
  862 + margin-bottom: 3px;
  863 +}
  864 +
  865 +.pendency .alert {
  866 + padding-top: 5px;
  867 + padding-bottom: 5px;
  868 + font-weight: 700;
  869 +}
  870 +
  871 +.pendency .alert span {
  872 + position: relative;
  873 + top: -7px;
  874 + padding-left: 10px;
  875 +}
  876 +
  877 +.pendency .alert i {
  878 + font-size: 35px;
  879 +}
  880 +
  881 +.alert-low {
  882 + opacity: 0.5;
  883 +}
  884 +
  885 +.no_button {
  886 + cursor: initial;
  887 +}
  888 +
  889 +.no_button:focus, .no_button:active:focus, .no_button.active:focus, .no_button.focus, .no_button:active.focus, .no_button.active.focus {
  890 + outline: none;
837 891 }
838 892 \ No newline at end of file
... ...
amadeus/static/css/themes/green.css
... ... @@ -85,6 +85,14 @@ a, a:focus, a:hover {
85 85 color: #F5F5F5;
86 86 }
87 87  
  88 +.pendencies-content {
  89 + background: #FFFFFF;
  90 +}
  91 +
  92 +.pendencies-content .core-subjects-options li {
  93 + background: #F5F5F5;
  94 +}
  95 +
88 96 .category-header i {
89 97 color: white;
90 98 }
... ... @@ -426,6 +434,27 @@ a.add-row {
426 434 color: #F5F5F5 !important;
427 435 }
428 436  
  437 +.pendency {
  438 + border-color: #CCCCCC;
  439 +}
  440 +
  441 +.pendency .breadcrumb {
  442 + background-color: #FFFFFF;
  443 +}
  444 +
  445 +.pendency .meta {
  446 + color: #FF0000;
  447 +}
  448 +
  449 +.alert-low, .alert-medium {
  450 + background-color: #FFA500;
  451 + color: #FFFFFF;
  452 +}
  453 +
  454 +.no_button:hover, .no_button:focus, .no_button:active {
  455 + background-color: initial !important;
  456 +}
  457 +
429 458 @media(max-width: 768px) {
430 459 .navbar .navbar-nav .dropdown .dropdown-menu li > a {
431 460 color: #333333 !important;
... ...
amadeus/templates/pagination.html
1 1 {% if paginator.count > 0 %}
2   - <div class="row-fluid">
  2 + <div class="row">
3 3 <div class="col-md-12 col-lg-12 col-sm-12 col-xs-12 text-center">
4 4 <ul class="pagination">
5 5 {% if page_obj.has_previous %}
... ...
amadeus/urls.py
... ... @@ -34,6 +34,7 @@ urlpatterns = [
34 34 url(r'^mailsender/', include('mailsender.urls', namespace = 'mailsender')),
35 35 url(r'^security/', include('security.urls', namespace = 'security')),
36 36 url(r'^themes/', include('themes.urls', namespace = 'themes')),
  37 + url(r'^notifications/', include('notifications.urls', namespace = 'notifications')),
37 38 #API
38 39 url(r'^o/', include('oauth2_provider.urls', namespace='oauth2_provider')),
39 40 #S3Direct
... ...
notifications/models.py
... ... @@ -11,3 +11,6 @@ class Notification(models.Model):
11 11 level = models.IntegerField(_('Type'), choices = ((1, _('Type 1-A')), (2, _('Type 1-B')), (3, _('Type 2')), (4, _('Type 3'))))
12 12 viewed = models.BooleanField(_('Visualized'), default = False)
13 13 creation_date = models.DateField(_('Creation Date'), auto_now_add = True)
  14 +
  15 + def __str__(self):
  16 + return self.task.get_action_display() + " " + str(self.task.resource)
... ...
notifications/templates/notifications/_view.html 0 → 100644
... ... @@ -0,0 +1,65 @@
  1 +{% load i18n notification_filters %}
  2 +
  3 +<div class="row">
  4 + <div class="col-md-12">
  5 + <div class="pendency">
  6 + <ul class="breadcrumb">
  7 + <li>
  8 + <a href="">{% trans 'Home' %}</a>
  9 + </li>
  10 + <li>
  11 + <a href="">{{ notification.task.resource.topic.subject.category }}</a>
  12 + </li>
  13 + <li>
  14 + <a href="">{{ notification.task.resource.topic.subject }}</a>
  15 + </li>
  16 + <li>
  17 + <a href="">{{ notification.task.resource.topic }}</a>
  18 + </li>
  19 + <li>
  20 + <a href="">{{ notification.task.resource }}</a>
  21 + </li>
  22 + </ul>
  23 + <div class="row">
  24 + <div class="col-md-6">
  25 + <h4>{{ notification }}</h4>
  26 + <p>{% trans 'Final Date/Time' %}: {{ notification.task.end_date|default:_('Not Informed') }}</p>
  27 +
  28 + {% if notification.level == 2 %}
  29 + <p class="meta">{% trans 'Your goal was to realize this in' %}: {{ notification.meta }}</p>
  30 + {% elif notification.level == 4 %}
  31 + <p class="meta">{% trans 'Task finished in' %}: {{ notification.task.limit_date }}</p>
  32 + {% endif %}
  33 +
  34 + <b>{{ notification|done_percent }}%</b> {% trans 'of the participants already realized this task.' %}
  35 + </div>
  36 + <div class="col-md-6">
  37 + <div class="alert {{ notification.level|warning_class }}">
  38 + <i class="fa fa-exclamation-triangle"></i>
  39 + <span>{{ notification.level|warning_msg }}</span>
  40 + </div>
  41 + </div>
  42 + </div>
  43 + <div class="row text-center">
  44 + <a href="" class="btn btn-success btn-raised">
  45 + {% if notification.level == 4 %}
  46 + {% trans 'Access the task' %}
  47 + {% else %}
  48 + {% trans 'Realize the task' %}
  49 + {% endif %}
  50 + </a>
  51 +
  52 + {% if notification.level < 3 %}
  53 + <button class="btn btn-default no_button">{% trans 'or' %}</button>
  54 + <a href="" class="btn btn-default btn-raised">
  55 + {% if notification.level == 1 %}
  56 + {% trans 'Define goal to realization' %}
  57 + {% else %}
  58 + {% trans 'Define new goal' %}
  59 + {% endif %}
  60 + </a>
  61 + {% endif %}
  62 + </div>
  63 + </div>
  64 + </div>
  65 +</div>
0 66 \ No newline at end of file
... ...
notifications/templates/notifications/subject.html 0 → 100644
... ... @@ -0,0 +1,50 @@
  1 +{% extends 'subjects/view.html' %}
  2 +
  3 +{% load static i18n pagination permissions_tags subject_counter %}
  4 +{% load django_bootstrap_breadcrumbs %}
  5 +
  6 +{% block breadcrumbs %}
  7 + {{ block.super }}
  8 +
  9 + {% breadcrumb 'Pendencies' 'notifications:view' subject.slug %}
  10 +{% endblock %}
  11 +
  12 +{% block content %}
  13 + {% if subject.visible %}
  14 + <div class="panel panel-info subject-panel">
  15 + <div class="panel-heading">
  16 + {% else %}
  17 + <div class="panel panel-info subject-panel-invisible">
  18 + <div class="panel-heading panel-invisible">
  19 + {% endif %}
  20 + <div class="row">
  21 + <div class="col-md-12 category-header">
  22 + <h4 class="panel-title" style="margin-top: 10px; margin-bottom: 8px">
  23 + <span>{% trans 'Pendencies' %}</span>
  24 + </h4>
  25 + </div>
  26 + </div>
  27 + </div>
  28 + <div id="{{subject.slug}}" class="panel-collapse in collapse pendencies-content">
  29 + <div id="core-subjects-options-div">
  30 + <ul class="core-subjects-options">
  31 + <a href="{% url 'notifications:view' subject.slug %}"><li class="active">{% trans "Actual Pendencies" %} ({{ notifications.count }})</li></a>
  32 + <a href="" ><li>{% trans "Notifications History" %}</li></a>
  33 + </ul>
  34 + </div>
  35 +
  36 + {% if notifications.count > 0 %}
  37 + {% for notification in notifications %}
  38 + {% include 'notifications/_view.html' %}
  39 + {% endfor %}
  40 +
  41 + {% pagination request paginator page_obj %}
  42 + {% else %}
  43 + <div class="text-center no-subjects">
  44 + <i class="fa fa-exclamation-triangle"></i>
  45 + <h4>{% trans 'You do not posses any pendency in this subject' %}</h4>
  46 + </div>
  47 + {% endif %}
  48 + </div>
  49 + </div>
  50 +{% endblock %}
0 51 \ No newline at end of file
... ...
notifications/templatetags/__init__.py 0 → 100644
notifications/templatetags/notification_filters.py 0 → 100644
... ... @@ -0,0 +1,45 @@
  1 +from django import template
  2 +from datetime import datetime
  3 +from django.utils.translation import ugettext_lazy as _
  4 +
  5 +from notifications.utils import get_resource_users
  6 +from notifications.models import Notification
  7 +
  8 +register = template.Library()
  9 +
  10 +@register.filter(name = 'warning_class')
  11 +def warning_class(level):
  12 + if level == 1:
  13 + class_name = "alert-low"
  14 + elif level == 2:
  15 + class_name = "alert-low"
  16 + elif level == 3:
  17 + class_name = "alert-medium"
  18 + else:
  19 + class_name = "alert-danger"
  20 +
  21 + return class_name
  22 +
  23 +@register.filter(name = 'warning_msg')
  24 +def warning_msg(level):
  25 + if level == 1:
  26 + msg = _('You still did not realize this task')
  27 + elif level == 2:
  28 + msg = _('You still did not realize this task')
  29 + elif level == 3:
  30 + msg = _('This task is late')
  31 + else:
  32 + msg = _('You miss this task')
  33 +
  34 + return msg
  35 +
  36 +@register.filter(name = 'done_percent')
  37 +def done_percent(notification):
  38 + users = get_resource_users(notification.task.resource)
  39 + notified = Notification.objects.filter(user__in = users.values_list('id', flat = True), creation_date = datetime.now(), task = notification.task).count()
  40 +
  41 + number_users = users.count()
  42 +
  43 + not_done = (notified * 100) / number_users
  44 +
  45 + return 100 - not_done
0 46 \ No newline at end of file
... ...
notifications/urls.py 0 → 100644
... ... @@ -0,0 +1,6 @@
  1 +from django.conf.urls import url
  2 +from . import views
  3 +
  4 +urlpatterns = [
  5 + url(r'^(?P<slug>[\w_-]+)/$', views.SubjectNotifications.as_view(), name='view'),
  6 +]
0 7 \ No newline at end of file
... ...
notifications/views.py
1   -from django.shortcuts import render
  1 +from django.shortcuts import get_object_or_404, redirect, render
  2 +from django.views import generic
  3 +from django.contrib import messages
  4 +from django.core.urlresolvers import reverse, reverse_lazy
  5 +from django.utils.translation import ugettext_lazy as _
  6 +from django.contrib.auth.mixins import LoginRequiredMixin
2 7  
3   -# Create your views here.
  8 +from datetime import datetime
  9 +
  10 +from amadeus.permissions import has_subject_view_permissions
  11 +
  12 +from subjects.models import Subject
  13 +
  14 +from .models import Notification
  15 +
  16 +class SubjectNotifications(LoginRequiredMixin, generic.ListView):
  17 + login_url = reverse_lazy("users:login")
  18 + redirect_field_name = 'next'
  19 +
  20 + context_object_name = 'notifications'
  21 + template_name = 'notifications/subject.html'
  22 + paginate_by = 10
  23 +
  24 + def dispatch(self, request, *args, **kwargs):
  25 + slug = self.kwargs.get('slug', '')
  26 + subject = get_object_or_404(Subject, slug = slug)
  27 +
  28 + if not has_subject_view_permissions(request.user, subject):
  29 + return redirect(reverse_lazy('subjects:home'))
  30 +
  31 + return super(SubjectNotifications, self).dispatch(request, *args, **kwargs)
  32 +
  33 + def get_queryset(self):
  34 + slug = self.kwargs.get('slug', '')
  35 + subject = get_object_or_404(Subject, slug = slug)
  36 +
  37 + notifications = Notification.objects.filter(user = self.request.user, task__resource__topic__subject = subject, creation_date = datetime.now())
  38 +
  39 + return notifications
  40 +
  41 + def get_context_data(self, **kwargs):
  42 + context = super(SubjectNotifications, self).get_context_data(**kwargs)
  43 +
  44 + slug = self.kwargs.get('slug', '')
  45 + subject = get_object_or_404(Subject, slug = slug)
  46 +
  47 + context['title'] = _('%s - Pendencies')%(subject.name)
  48 + context['subject'] = subject
  49 +
  50 + return context
... ...
subjects/templates/subjects/subject_card.html
... ... @@ -37,7 +37,7 @@
37 37  
38 38  
39 39 <a href="" class="pull-right action_icon"><i class="fa fa-bar-chart" aria-hidden="true"></i></a>
40   - <a href="" class="pull-right action_icon">
  40 + <a href="{% url 'notifications:view' subject.slug %}" class="pull-right action_icon">
41 41 <i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
42 42 {% notifies_number subject request.user %}
43 43 </a>
... ...
subjects/templates/subjects/view.html
... ... @@ -56,7 +56,7 @@
56 56 </ul>
57 57 {% endif %}
58 58 <a href="" class="pull-right action_icon"><i class="fa fa-bar-chart" aria-hidden="true"></i></a>
59   - <a href="" class="pull-right action_icon">
  59 + <a href="{% url 'notifications:view' subject.slug %}" class="pull-right action_icon">
60 60 <i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
61 61 {% notifies_number subject request.user %}
62 62 </a>
... ...
subjects/views.py
... ... @@ -46,7 +46,7 @@ class HomeView(LoginRequiredMixin, ListView):
46 46  
47 47 subjects = Subject.objects.filter(Q(students__pk=pk) | Q(professor__pk=pk) | Q(category__coordinators__pk=pk)).distinct()
48 48  
49   - self.total = len(subjects)
  49 + self.total = subjects.count()
50 50  
51 51 return subjects
52 52  
... ...
topics/templates/topics/list.html
... ... @@ -34,7 +34,7 @@
34 34 </div>
35 35 </div>
36 36 </div>
37   - <div id="{{topic.slug}}" class="panel-collapse collapse category-panel-content topic-panel">
  37 + <div id="{{topic.slug}}" class="panel-collapse collapse category-panel-content">
38 38 <input type="hidden" class="id_inp" name="id" value="{{ topic.id }}" />
39 39 <input type="hidden" class="order_inp" name="order" value="{{ topic.order }}" />
40 40  
... ...