Commit 18f30f2f3c37b9ced2b574099feb0377a8db4f3c

Authored by Jailson Dias
2 parents 74a677d8 6d1a1af1

Merge branch 'refactoring' of https://github.com/amadeusproject/amadeuslms into refactoring

amadeus/static/js/chat.js
@@ -437,7 +437,7 @@ $('.chat-collapse').on('shown.bs.collapse', function(e) { @@ -437,7 +437,7 @@ $('.chat-collapse').on('shown.bs.collapse', function(e) {
437 if($(this).is(e.target)){ 437 if($(this).is(e.target)){
438 var li = $(".breadcrumb").find('li:last-child'); 438 var li = $(".breadcrumb").find('li:last-child');
439 var li_text = $(li).html(); 439 var li_text = $(li).html();
440 - var url = $(".cat_url").val(); 440 + var url = $(".item_url").val();
441 var new_li = $(li).clone(); 441 var new_li = $(li).clone();
442 442
443 new_li.html($(this).parent().find('.panel-title .item_name').text()); 443 new_li.html($(this).parent().find('.panel-title .item_name').text());
amadeus/static/js/socket.js
@@ -283,13 +283,30 @@ function messageReceived(content) { @@ -283,13 +283,30 @@ function messageReceived(content) {
283 var item = $("#" + content.space); 283 var item = $("#" + content.space);
284 284
285 if (typeof(item) != "undefined") { 285 if (typeof(item) != "undefined") {
286 - var span = item.parent().find('span:not(.item_name)'),  
287 - actual = span.text(); 286 + var span = item.parent().find('span.item_badge'),
  287 + actual = span.text();
288 288
289 actual = parseInt(actual, 10) + 1; 289 actual = parseInt(actual, 10) + 1;
290 290
291 span.text(actual); 291 span.text(actual);
292 } 292 }
  293 +
  294 + if (content.subtype == "subject") {
  295 + var subject_cbadge = $("#subject_" + content.space).find('.chat_notify'),
  296 + actual = subject_cbadge.text();
  297 +
  298 + if (actual != "+99") {
  299 + actual = parseInt(actual, 10) + 1;
  300 +
  301 + if (actual > 99) {
  302 + actual = "+99";
  303 + }
  304 +
  305 + subject_cbadge.text(actual);
  306 + }
  307 +
  308 + subject_cbadge.show();
  309 + }
293 } 310 }
294 311
295 if (("Notification" in window)) { 312 if (("Notification" in window)) {
chat/templates/chat/list.html
@@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
16 <ul class="core-subjects-options chat-tabs"> 16 <ul class="core-subjects-options chat-tabs">
17 <a href="{% url 'chat:manage_general' %}"><li data-chat="general" class="active">{% trans "General" %} (<span>{{ totals.general }}</span>)</li></a> 17 <a href="{% url 'chat:manage_general' %}"><li data-chat="general" class="active">{% trans "General" %} (<span>{{ totals.general }}</span>)</li></a>
18 <a href="{% url 'chat:manage_category' %}"><li data-chat="category">{% trans "Per Category" %} (<span>{{ totals.category }}</span>)</li></a> 18 <a href="{% url 'chat:manage_category' %}"><li data-chat="category">{% trans "Per Category" %} (<span>{{ totals.category }}</span>)</li></a>
19 - <a href=""><li data-chat="subject">{% trans "Per Subject" %} (<span>{{ totals.subject }}</span>)</li></a> 19 + <a href="{% url 'chat:manage_subject' %}"><li data-chat="subject">{% trans "Per Subject" %} (<span>{{ totals.subject }}</span>)</li></a>
20 </ul> 20 </ul>
21 </div> 21 </div>
22 22
@@ -54,6 +54,9 @@ @@ -54,6 +54,9 @@
54 {% include 'chat/_view.html' with space="0" space_type='general' %} 54 {% include 'chat/_view.html' with space="0" space_type='general' %}
55 {% endfor %} 55 {% endfor %}
56 </div> 56 </div>
  57 +
  58 + {% pagination request paginator page_obj %}
  59 +
57 </div> 60 </div>
58 {% else %} 61 {% else %}
59 <div class="text-center no-subjects"> 62 <div class="text-center no-subjects">
chat/templates/chat/list_category.html
@@ -12,13 +12,13 @@ @@ -12,13 +12,13 @@
12 {% endblock %} 12 {% endblock %}
13 13
14 {% block content %} 14 {% block content %}
15 - <input type="hidden" value="{% url 'chat:manage_category' %}" class="cat_url"> 15 + <input type="hidden" value="{% url 'chat:manage_category' %}" class="item_url">
16 16
17 <div id="core-subjects-options-div"> 17 <div id="core-subjects-options-div">
18 <ul class="core-subjects-options chat-tabs"> 18 <ul class="core-subjects-options chat-tabs">
19 <a href="{% url 'chat:manage_general' %}"><li data-chat="general">{% trans "General" %} (<span>{{ totals.general }}</span>)</li></a> 19 <a href="{% url 'chat:manage_general' %}"><li data-chat="general">{% trans "General" %} (<span>{{ totals.general }}</span>)</li></a>
20 <a href="{% url 'chat:manage_category' %}"><li data-chat="category" class="active">{% trans "Per Category" %} (<span>{{ totals.category }}</span>)</li></a> 20 <a href="{% url 'chat:manage_category' %}"><li data-chat="category" class="active">{% trans "Per Category" %} (<span>{{ totals.category }}</span>)</li></a>
21 - <a href=""><li data-chat="subject">{% trans "Per Subject" %} (<span>{{ totals.subject }}</span>)</li></a> 21 + <a href="{% url 'chat:manage_subject' %}"><li data-chat="subject">{% trans "Per Subject" %} (<span>{{ totals.subject }}</span>)</li></a>
22 </ul> 22 </ul>
23 </div> 23 </div>
24 24
@@ -41,7 +41,7 @@ @@ -41,7 +41,7 @@
41 <div class="col-md-12 category-header"> 41 <div class="col-md-12 category-header">
42 <h4 class="panel-title"> 42 <h4 class="panel-title">
43 <a class="category-course-link pull-left" data-parent="#accordion" data-toggle="collapse" href="#{{category.slug}}"> 43 <a class="category-course-link pull-left" data-parent="#accordion" data-toggle="collapse" href="#{{category.slug}}">
44 - <button class="btn btn-default btn-xs text-center cat-selector"><i class="fa fa-angle-right fa-2x" aria-hidden="true"></i></button> <span class="item_name">{{ category.name }}</span> (<span style="margin-left:0px">{{ category|notifies_category:request.user }}</span>) 44 + <button class="btn btn-default btn-xs text-center cat-selector"><i class="fa fa-angle-right fa-2x" aria-hidden="true"></i></button> <span class="item_name">{{ category.name }}</span> (<span class="item_badge" style="margin-left:0px">{{ category|notifies_category:request.user }}</span>)
45 45
46 </a> 46 </a>
47 </h4> 47 </h4>
chat/templates/chat/list_subject.html 0 → 100644
@@ -0,0 +1,111 @@ @@ -0,0 +1,111 @@
  1 +{% extends 'base.html' %}
  2 +
  3 +{% load static i18n pagination permissions_tags chat_tags %}
  4 +{% load django_bootstrap_breadcrumbs %}
  5 +
  6 +{% block breadcrumbs %}
  7 + {{ block.super }}
  8 +
  9 + {% trans 'Messages per Subject' as subject %}
  10 +
  11 + {% breadcrumb subject 'chat:manage_category' %}
  12 +{% endblock %}
  13 +
  14 +{% block content %}
  15 + <input type="hidden" value="{% url 'chat:manage_subject' %}" class="item_url">
  16 +
  17 + <div id="core-subjects-options-div">
  18 + <ul class="core-subjects-options chat-tabs">
  19 + <a href="{% url 'chat:manage_general' %}"><li data-chat="general">{% trans "General" %} (<span>{{ totals.general }}</span>)</li></a>
  20 + <a href="{% url 'chat:manage_category' %}"><li data-chat="category">{% trans "Per Category" %} (<span>{{ totals.category }}</span>)</li></a>
  21 + <a href="{% url 'chat:manage_subject' %}"><li data-chat="subject" class="active">{% trans "Per Subject" %} (<span>{{ totals.subject }}</span>)</li></a>
  22 + </ul>
  23 + </div>
  24 +
  25 + <div class="col-md-12 cards-content">
  26 + {% if subjects.count > 0 %}
  27 + <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
  28 + {% for subject in subjects %}
  29 + {% subject_permissions request.user subject as has_subject_permissions %}
  30 +
  31 + {% if subject.visible or has_subject_permissions %}
  32 + {% if subject.visible %}
  33 + <div class="panel panel-info subject-panel chat-panel">
  34 + <div class="panel-heading">
  35 + {% elif has_subject_permissions %}
  36 + <div class="panel panel-info subject-panel-invisible chat-panel">
  37 + <div class="panel-heading panel-invisible">
  38 + {% endif %}
  39 + <div class="row">
  40 + <div class="col-md-12 category-header">
  41 + <h4 class="panel-title">
  42 + <a class="category-course-link pull-left" data-parent="#accordion" data-toggle="collapse" href="#{{subject.slug}}">
  43 + <button class="btn btn-default btn-xs text-center cat-selector"><i class="fa fa-angle-right fa-2x" aria-hidden="true"></i></button> <span class="item_name">{{ subject }}</span>
  44 +
  45 + (<span class="item_badge" style="margin-left:0px">{{ subject|notifies_subject:request.user }}</span>)
  46 + </a>
  47 + </h4>
  48 +
  49 + <div class="col-md-5 pull-right category-card-items">
  50 + {% if has_subject_permissions %}
  51 + <a href="" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  52 + <i class="fa fa-ellipsis-v" aria-hidden="true"></i>
  53 + </a>
  54 + <ul class="dropdown-menu pull-right" aria-labelledby="moreActions">
  55 + {% if request.user not in subject.professor.all %}
  56 + <li><a href="{% url 'subjects:replicate' subject.slug %}"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i>{% trans 'Replicate' %}</a></li>
  57 + {% endif %}
  58 + <li><a href="{% url 'subjects:update' subject.slug %}"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i>{% trans 'Edit' %}</a></li>
  59 + <li><a href="{% url 'groups:index' subject.slug %}"><i class="fa fa-group fa-fw" aria-hidden="true"></i>{% trans 'Groups' %}</a></li>
  60 + <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>
  61 + </ul>
  62 + {% endif %}
  63 + </div>
  64 + </div>
  65 + </div>
  66 + </div>
  67 + <div id="{{subject.slug}}" class="panel-collapse panel-body collapse chat-collapse"data-url="{% url 'chat:subject_talks' subject.id %}" data-breadurl="{% url 'subjects:view' subject.slug %}" data-breadtext="{% trans 'Participants' %}">
  68 + <div class="panel panel-default">
  69 + <div class="panel-body">
  70 + <div class="col-md-8">
  71 + <form id="search-participants" action="{% url 'chat:participants_subject' subject.id %}" method="GET" class="form-horizontal">
  72 + <div class="form-group">
  73 + <div class="col-md-11 col-sm-11 col-xs-11">
  74 + <input type="text" class="form-control" name="search" value="{{ search }}" placeholder="{% trans 'Search...' %}" />
  75 + </div>
  76 + <div class="col-md-1 col-sm-1 col-xs-1">
  77 + <button type="submit" class="btn btn-fab btn-fab-mini">
  78 + <i class="fa fa-search"></i>
  79 + </button>
  80 + </div>
  81 + </div>
  82 + </form>
  83 + </div>
  84 + <div class="col-md-4">
  85 + <a href="{% url 'chat:participants_subject' subject.id %}" onclick="getParticipants($(this)); return false;" class="pull-right btn btn-default btn-raised btn-md">{% trans 'List all participants' %}</a>
  86 + </div>
  87 + </div>
  88 + </div>
  89 +
  90 + <div class="content">
  91 + </div>
  92 + </div>
  93 + </div>
  94 + {% endif %}
  95 + {% endfor %}
  96 +
  97 + {% pagination request paginator page_obj %}
  98 + </div>
  99 + {% endif %}
  100 + </div>
  101 +
  102 + <div id="modal_subject"></div>
  103 +
  104 + <div class="modal fade" id="chat-modal-info" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"></div>
  105 +
  106 + <div class="modal fade" id="chat-modal-form" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"></div>
  107 +
  108 + <script type="text/javascript" src="{% static 'js/category.js' %}"></script>
  109 + <script type="text/javascript" src="{% static 'js/chat.js' %}"></script>
  110 + <script type="text/javascript" src="{% static 'subjects/js/modal_subject.js' %}"></script>
  111 +{% endblock %}
0 \ No newline at end of file 112 \ No newline at end of file
chat/templates/chat/subject_view.html 0 → 100644
@@ -0,0 +1,97 @@ @@ -0,0 +1,97 @@
  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 + {% trans 'Messages' as bread %}
  10 +
  11 + {% breadcrumb bread 'chat:subject_view' subject.slug %}
  12 +{% endblock %}
  13 +
  14 +{% block content %}
  15 + {% subject_permissions request.user subject as has_subject_permissions %}
  16 +
  17 + {% if subject.visible %}
  18 + <div class="panel panel-info subject-panel chat-panel" id="subject_{{subject.slug}}">
  19 + <div class="panel-heading">
  20 + {% elif has_subject_permissions %}
  21 + <div class="panel panel-info subject-panel-invisible chat-panel" id="subject_{{subject.slug}}">
  22 + <div class="panel-heading panel-invisible">
  23 + {% endif %}
  24 + <div class="row">
  25 + <div class="col-md-12 category-header">
  26 + <h4 class="panel-title" style="margin-top: 10px; margin-bottom: 8px">
  27 + <span>{{subject.name}}</span>
  28 + </h4>
  29 +
  30 + <div class="col-md-5 pull-right category-card-items">
  31 + {% if request.user in subject.professor.all or request.user in subject.category.coordinators.all or request.user.is_staff %}
  32 + <a href="" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  33 + <i class="fa fa-ellipsis-v" aria-hidden="true"></i>
  34 + </a>
  35 + <ul class="dropdown-menu pull-right" aria-labelledby="moreActions">
  36 + {% if request.user not in subject.professor.all %}
  37 + <li><a href="{% url 'subjects:replicate' subject.slug %}"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i>{% trans 'Replicate' %}</a></li>
  38 + {% endif %}
  39 + <li><a href="{% url 'subjects:update' subject.slug %}"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i>{% trans 'Edit' %}</a></li>
  40 + <li><a href="{% url 'groups:index' subject.slug %}"><i class="fa fa-group fa-fw" aria-hidden="true"></i>{% trans 'Groups' %}</a></li>
  41 + <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>
  42 + </ul>
  43 + {% endif %}
  44 +
  45 + </div>
  46 + </div>
  47 + </div>
  48 + </div>
  49 + <div id="{{subject.slug}}" class="panel-collapse panel-body in collapse chat-collapse">
  50 + <div class="panel panel-default">
  51 + <div class="panel-body">
  52 + <div class="col-md-8">
  53 + <form action="" method="GET" class="form-horizontal">
  54 + <div class="form-group">
  55 + <div class="col-md-11 col-sm-11 col-xs-11">
  56 + <input type="text" class="form-control" name="search" value="{{ search }}" placeholder="{% trans 'Search...' %}" />
  57 + </div>
  58 + <div class="col-md-1 col-sm-1 col-xs-1">
  59 + <button type="submit" class="btn btn-fab btn-fab-mini">
  60 + <i class="fa fa-search"></i>
  61 + </button>
  62 + </div>
  63 + </div>
  64 + </form>
  65 + </div>
  66 + <div class="col-md-4">
  67 + <a href="" class="pull-right btn btn-default btn-raised btn-md">{% trans 'List all participants' %}</a>
  68 + </div>
  69 + </div>
  70 + </div>
  71 +
  72 + {% if conversations.count > 0 %}
  73 + <div class="panel category-panel-content panel-body">
  74 + <h2 class="my-subjects-title"><b>{% trans 'Conversations' %}</b></h2>
  75 +
  76 + <div class="talks-group">
  77 + {% for chat in conversations %}
  78 + {% include 'chat/_view.html' with space=subject.id space_type='subject' %}
  79 + {% endfor %}
  80 + </div>
  81 +
  82 + {% pagination request paginator page_obj %}
  83 + </div>
  84 + {% else %}
  85 + <div class="text-center no-subjects">
  86 + <i class="fa fa-envelope-o"></i>
  87 + <h4>{% trans 'You do not posses messages in this space yet.' %}</h4>
  88 + </div>
  89 + {% endif %}
  90 + </div>
  91 +
  92 + <div class="modal fade" id="chat-modal-info" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"></div>
  93 +
  94 + <div class="modal fade" id="chat-modal-form" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"></div>
  95 +
  96 + <script type="text/javascript" src="{% static 'js/chat.js' %}"></script>
  97 +{% endblock %}
0 \ No newline at end of file 98 \ No newline at end of file
chat/templatetags/chat_tags.py
@@ -82,4 +82,10 @@ def fav_class(message, user): @@ -82,4 +82,10 @@ def fav_class(message, user):
82 def notifies_category(category, user): 82 def notifies_category(category, user):
83 total = ChatVisualizations.objects.filter(message__talk__categorytalk__space = category, user = user, viewed = False).count() 83 total = ChatVisualizations.objects.filter(message__talk__categorytalk__space = category, user = user, viewed = False).count()
84 84
  85 + return total
  86 +
  87 +@register.filter(name = 'notifies_subject')
  88 +def notifies_subject(subject, user):
  89 + total = ChatVisualizations.objects.filter(message__talk__subjecttalk__space = subject, user = user, viewed = False).count()
  90 +
85 return total 91 return total
86 \ No newline at end of file 92 \ No newline at end of file
@@ -3,10 +3,14 @@ from . import views @@ -3,10 +3,14 @@ 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'^participants/$', views.GeneralParticipants.as_view(), name='participants_general'),  
7 url(r'^categories/$', views.CategoryIndex.as_view(), name='manage_category'), 6 url(r'^categories/$', views.CategoryIndex.as_view(), name='manage_category'),
  7 + url(r'^subjects/$', views.SubjectIndex.as_view(), name='manage_subject'),
  8 + url(r'^subject/(?P<slug>[\w_-]+)/$', views.SubjectView.as_view(), name='subject_view'),
  9 + url(r'^participants/$', views.GeneralParticipants.as_view(), name='participants_general'),
8 url(r'^category/talks/(?P<category>[\w_-]+)/$', views.CategoryTalks.as_view(), name='category_talks'), 10 url(r'^category/talks/(?P<category>[\w_-]+)/$', views.CategoryTalks.as_view(), name='category_talks'),
9 url(r'^category/participants/(?P<category>[\w_-]+)/$', views.CategoryParticipants.as_view(), name='participants_category'), 11 url(r'^category/participants/(?P<category>[\w_-]+)/$', views.CategoryParticipants.as_view(), name='participants_category'),
  12 + url(r'^subject/talks/(?P<subject>[\w_-]+)/$', views.SubjectTalks.as_view(), name='subject_talks'),
  13 + url(r'^subject/participants/(?P<subject>[\w_-]+)/$', views.SubjectParticipants.as_view(), name='participants_subject'),
10 url(r'^render_message/([\w_-]+)/([\w_-]+)/([\w_-]+)/([\w_-]+)/([\w.%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})/$', views.render_message, name='render_message'), 14 url(r'^render_message/([\w_-]+)/([\w_-]+)/([\w_-]+)/([\w_-]+)/([\w.%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})/$', views.render_message, name='render_message'),
11 url(r'^favorite/([\w_-]+)/$', views.favorite, name='favorite'), 15 url(r'^favorite/([\w_-]+)/$', views.favorite, name='favorite'),
12 url(r'^load_messages/([\w_-]+)/$', views.load_messages, name='load_messages'), 16 url(r'^load_messages/([\w_-]+)/$', views.load_messages, name='load_messages'),
@@ -15,6 +15,8 @@ from django.contrib.auth.mixins import LoginRequiredMixin @@ -15,6 +15,8 @@ from django.contrib.auth.mixins import LoginRequiredMixin
15 from django.contrib.auth.decorators import login_required 15 from django.contrib.auth.decorators import login_required
16 from django.db.models import Q 16 from django.db.models import Q
17 17
  18 +from amadeus.permissions import has_subject_view_permissions
  19 +
18 from channels import Group 20 from channels import Group
19 import json 21 import json
20 22
@@ -37,7 +39,6 @@ class GeneralIndex(LoginRequiredMixin, generic.ListView): @@ -37,7 +39,6 @@ class GeneralIndex(LoginRequiredMixin, generic.ListView):
37 39
38 def get_queryset(self): 40 def get_queryset(self):
39 user = self.request.user 41 user = self.request.user
40 - page = self.request.GET.get('page', False)  
41 42
42 conversations = Conversation.objects.filter((Q(user_one = user) | Q(user_two = user)) & Q(categorytalk__isnull = True) & Q(subjecttalk__isnull = True)) 43 conversations = Conversation.objects.filter((Q(user_one = user) | Q(user_two = user)) & Q(categorytalk__isnull = True) & Q(subjecttalk__isnull = True))
43 44
@@ -135,8 +136,6 @@ class CategoryTalks(LoginRequiredMixin, generic.ListView): @@ -135,8 +136,6 @@ class CategoryTalks(LoginRequiredMixin, generic.ListView):
135 136
136 conversations = CategoryTalk.objects.filter((Q(user_one = user) | Q(user_two = user)) & Q(space__id = cat)) 137 conversations = CategoryTalk.objects.filter((Q(user_one = user) | Q(user_two = user)) & Q(space__id = cat))
137 138
138 - print(cat)  
139 -  
140 return conversations 139 return conversations
141 140
142 def get_context_data(self, **kwargs): 141 def get_context_data(self, **kwargs):
@@ -159,8 +158,6 @@ class CategoryParticipants(LoginRequiredMixin, generic.ListView): @@ -159,8 +158,6 @@ class CategoryParticipants(LoginRequiredMixin, generic.ListView):
159 cat = self.kwargs.get('category', 0) 158 cat = self.kwargs.get('category', 0)
160 search = self.request.GET.get('search', '') 159 search = self.request.GET.get('search', '')
161 160
162 - print(search)  
163 -  
164 users = User.objects.filter((Q(username__icontains = search) | Q(last_name__icontains = search) | Q(social_name__icontains = search) | Q(email__icontains = search)) & (Q(is_staff = True) | Q(subject_student__category__id = cat) | Q(professors__category__id = cat) | Q(coordinators__id = cat))).distinct().order_by('social_name','username').exclude(email = user.email) 161 users = User.objects.filter((Q(username__icontains = search) | Q(last_name__icontains = search) | Q(social_name__icontains = search) | Q(email__icontains = search)) & (Q(is_staff = True) | Q(subject_student__category__id = cat) | Q(professors__category__id = cat) | Q(coordinators__id = cat))).distinct().order_by('social_name','username').exclude(email = user.email)
165 162
166 return users 163 return users
@@ -173,6 +170,123 @@ class CategoryParticipants(LoginRequiredMixin, generic.ListView): @@ -173,6 +170,123 @@ class CategoryParticipants(LoginRequiredMixin, generic.ListView):
173 170
174 return context 171 return context
175 172
  173 +class SubjectIndex(LoginRequiredMixin, generic.ListView):
  174 + login_url = reverse_lazy("users:login")
  175 + redirect_field_name = 'next'
  176 +
  177 + template_name = 'chat/list_subject.html'
  178 + context_object_name = "subjects"
  179 + paginate_by = 10
  180 +
  181 + totals = {}
  182 +
  183 + def get_queryset(self):
  184 + user = self.request.user
  185 + page = self.request.GET.get('page', False)
  186 +
  187 + if user.is_staff:
  188 + subjects = Subject.objects.all()
  189 + else:
  190 + subjects = Subject.objects.filter(Q(professor__pk = user.pk) | Q(students__pk = user.pk, visible = True) | Q(category__coordinators__pk = user.pk)).distinct()
  191 +
  192 + self.totals['general'] = ChatVisualizations.objects.filter(user = user, viewed = False, message__talk__generaltalk__isnull = False).count()
  193 + self.totals['category'] = ChatVisualizations.objects.filter(user = user, viewed = False, message__talk__categorytalk__isnull = False).count()
  194 + self.totals['subject'] = ChatVisualizations.objects.filter(user = user, viewed = False, message__talk__subjecttalk__isnull = False).count()
  195 +
  196 + return subjects
  197 +
  198 + def get_context_data(self, **kwargs):
  199 + context = super(SubjectIndex, self).get_context_data(**kwargs)
  200 +
  201 + context['title'] = _('Messages per Subject')
  202 + context['totals'] = self.totals
  203 + context['chat_menu_active'] = 'subjects_menu_active'
  204 +
  205 + return context
  206 +
  207 +class SubjectTalks(LoginRequiredMixin, generic.ListView):
  208 + login_url = reverse_lazy("users:login")
  209 + redirect_field_name = 'next'
  210 +
  211 + template_name = 'chat/_talks_list.html'
  212 + context_object_name = "conversations"
  213 +
  214 + def get_queryset(self):
  215 + user = self.request.user
  216 + sub = self.kwargs.get('subject', 0)
  217 +
  218 + conversations = SubjectTalk.objects.filter((Q(user_one = user) | Q(user_two = user)) & Q(space__id = sub))
  219 +
  220 + return conversations
  221 +
  222 + def get_context_data(self, **kwargs):
  223 + context = super(SubjectTalks, self).get_context_data(**kwargs)
  224 +
  225 + context['space'] = self.kwargs.get('subject', 0)
  226 + context['space_type'] = 'subject'
  227 +
  228 + return context
  229 +
  230 +class SubjectParticipants(LoginRequiredMixin, generic.ListView):
  231 + login_url = reverse_lazy("users:login")
  232 + redirect_field_name = 'next'
  233 +
  234 + template_name = 'chat/_participants.html'
  235 + context_object_name = "participants"
  236 +
  237 + def get_queryset(self):
  238 + user = self.request.user
  239 + sub = self.kwargs.get('subject', 0)
  240 + search = self.request.GET.get('search', '')
  241 +
  242 + users = User.objects.filter((Q(username__icontains = search) | Q(last_name__icontains = search) | Q(social_name__icontains = search) | Q(email__icontains = search)) & (Q(is_staff = True) | Q(subject_student__id = sub) | Q(professors__id = sub) | Q(coordinators__subject_category__id = sub))).distinct().order_by('social_name','username').exclude(email = user.email)
  243 +
  244 + return users
  245 +
  246 + def get_context_data(self, **kwargs):
  247 + context = super(SubjectParticipants, self).get_context_data(**kwargs)
  248 +
  249 + context['space'] = self.kwargs.get('subject', 0)
  250 + context['space_type'] = 'subject'
  251 +
  252 + return context
  253 +
  254 +class SubjectView(LoginRequiredMixin, generic.ListView):
  255 + login_url = reverse_lazy("users:login")
  256 + redirect_field_name = 'next'
  257 +
  258 + template_name = 'chat/subject_view.html'
  259 + context_object_name = "conversations"
  260 + paginate_by = 10
  261 +
  262 + def dispatch(self, request, *args,**kwargs):
  263 + subject = get_object_or_404(Subject, slug = kwargs.get('slug', ''))
  264 +
  265 + if not has_subject_view_permissions(request.user, subject):
  266 + return redirect(reverse_lazy('subjects:home'))
  267 +
  268 + return super(SubjectView, self).dispatch(request, *args, **kwargs)
  269 +
  270 + def get_queryset(self):
  271 + user = self.request.user
  272 + slug = self.kwargs.get('slug')
  273 + subject = get_object_or_404(Subject, slug = slug)
  274 +
  275 + conversations = SubjectTalk.objects.filter((Q(user_one = user) | Q(user_two = user)) & Q(space = subject))
  276 +
  277 + return conversations
  278 +
  279 + def get_context_data(self, **kwargs):
  280 + context = super(SubjectView, self).get_context_data(**kwargs)
  281 +
  282 + slug = self.kwargs.get('slug', None)
  283 + subject = get_object_or_404(Subject, slug = slug)
  284 +
  285 + context['title'] = _('%s - Messages')%(str(subject))
  286 + context['subject'] = subject
  287 +
  288 + return context
  289 +
176 class ParticipantProfile(LoginRequiredMixin, generic.DetailView): 290 class ParticipantProfile(LoginRequiredMixin, generic.DetailView):
177 login_url = reverse_lazy("users:login") 291 login_url = reverse_lazy("users:login")
178 redirect_field_name = 'next' 292 redirect_field_name = 'next'
subjects/templates/subjects/subject_card.html
@@ -39,7 +39,10 @@ @@ -39,7 +39,10 @@
39 <i class="fa fa-exclamation-triangle" aria-hidden="true"></i> 39 <i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
40 {% notifies_number subject request.user %} 40 {% notifies_number subject request.user %}
41 </a> 41 </a>
42 - <a href="" class="pull-right action_icon" data-toggle="tooltip" data-placement="bottom" title="{% trans 'Messages' %}"><i class="fa fa-envelope-o" aria-hidden="true"></i></a> 42 + <a href="{% url 'chat:subject_view' subject.slug %}" class="pull-right action_icon" data-toggle="tooltip" data-placement="bottom" title="{% trans 'Messages' %}">
  43 + <i class="fa fa-envelope-o" aria-hidden="true"></i>
  44 + {% chat_number subject request.user %}
  45 + </a>
43 <a href="{% url 'mural:subject_view' subject.slug %}" class="pull-right action_icon" data-toggle="tooltip" data-placement="bottom" title="{% trans 'Mural' %}"> 46 <a href="{% url 'mural:subject_view' subject.slug %}" class="pull-right action_icon" data-toggle="tooltip" data-placement="bottom" title="{% trans 'Mural' %}">
44 <i class="fa fa-list" aria-hidden="true"></i> 47 <i class="fa fa-list" aria-hidden="true"></i>
45 {% mural_number subject request.user %} 48 {% mural_number subject request.user %}
subjects/templates/subjects/view.html
@@ -61,7 +61,10 @@ @@ -61,7 +61,10 @@
61 <i class="fa fa-exclamation-triangle" aria-hidden="true"></i> 61 <i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
62 {% notifies_number subject request.user %} 62 {% notifies_number subject request.user %}
63 </a> 63 </a>
64 - <a href="" class="pull-right action_icon" data-toggle="tooltip" data-placement="bottom" title="{% trans 'Messages' %}"><i class="fa fa-envelope-o" aria-hidden="true"></i></a> 64 + <a href="{% url 'chat:subject_view' subject.slug %}" class="pull-right action_icon" data-toggle="tooltip" data-placement="bottom" title="{% trans 'Messages' %}">
  65 + <i class="fa fa-envelope-o" aria-hidden="true"></i>
  66 + {% chat_number subject request.user %}
  67 + </a>
65 <a href="{% url 'mural:subject_view' subject.slug %}" class="pull-right action_icon" data-toggle="tooltip" data-placement="bottom" title="{% trans 'Mural' %}"> 68 <a href="{% url 'mural:subject_view' subject.slug %}" class="pull-right action_icon" data-toggle="tooltip" data-placement="bottom" title="{% trans 'Mural' %}">
66 <i class="fa fa-list" aria-hidden="true"></i> 69 <i class="fa fa-list" aria-hidden="true"></i>
67 {% mural_number subject request.user %} 70 {% mural_number subject request.user %}
subjects/templatetags/subject_counter.py
@@ -2,6 +2,7 @@ import datetime @@ -2,6 +2,7 @@ import datetime
2 from django import template 2 from django import template
3 from django.db.models import Q 3 from django.db.models import Q
4 4
  5 +from chat.models import ChatVisualizations
5 from mural.models import MuralVisualizations 6 from mural.models import MuralVisualizations
6 from notifications.models import Notification 7 from notifications.models import Notification
7 8
@@ -39,6 +40,15 @@ def mural_number(subject, user): @@ -39,6 +40,15 @@ def mural_number(subject, user):
39 return context 40 return context
40 41
41 @register.inclusion_tag('subjects/badge.html') 42 @register.inclusion_tag('subjects/badge.html')
  43 +def chat_number(subject, user):
  44 + context = {}
  45 +
  46 + context['number'] = ChatVisualizations.objects.filter(Q(user = user) & Q(viewed = False) & Q(message__talk__subjecttalk__space = subject)).count()
  47 + context['custom_class'] = 'chat_notify'
  48 +
  49 + return context
  50 +
  51 +@register.inclusion_tag('subjects/badge.html')
42 def resource_mural_number(resource, user): 52 def resource_mural_number(resource, user):
43 context = {} 53 context = {}
44 54