Explorar o código

Module notifications ok

omassot %!s(int64=7) %!d(string=hai) anos
pai
achega
ff69f75a82
Modificáronse 2 ficheiros con 73 adicións e 15 borrados
  1. 2 0
      main/static/css/custom.css
  2. 71 15
      main/views.py

+ 2 - 0
main/static/css/custom.css

@@ -246,6 +246,7 @@ select[multiple] option {
 	display: flex;
 	flex-direction: row;
 	text-align: left;
+	font-size: 11px;
 }
 
 .notif-head a {
@@ -257,6 +258,7 @@ select[multiple] option {
 	display: flex;
 	flex-direction: row;
 	justify-content: space-around;
+	font-size: 12px;
 }
 
 .notif-content a {

+ 71 - 15
main/views.py

@@ -8,12 +8,12 @@ from django.core.paginator import Paginator
 from django.http.response import HttpResponse
 from django.shortcuts import render, get_object_or_404, redirect
 from django.urls.base import reverse
+from notifications.models import Notification
 from notifications.signals import notify
 
 from main.forms import StoryForm, EpicForm, RegisterForm, ProfileForm, \
     CommentForm, SprintForm
 from main.models import Story, Epic, Sprint, Comment, Project
-from notifications.models import Notification
 
 
 def register(request):
@@ -80,6 +80,7 @@ def sprint_end(request):
         current_sprint.retro = request.POST["retro"]
         current_sprint.closed = True
         current_sprint.save()
+        notify_sprint_end(current_sprint, next_sprint, request.user)
         return redirect("index")
     
     form = SprintForm(instance=current_sprint)
@@ -124,6 +125,10 @@ def story_create(request, epic_id=None):
         form = StoryForm(request.POST)
         if form.is_valid():
             story = form.save()
+            
+            for assignee in story.assignees.filter(id != request.user.id):
+                notify_story_assigned(story, request.user, assignee)
+            
             return redirect("story_details", story.id)
         
     else:
@@ -139,9 +144,16 @@ def story_create(request, epic_id=None):
 def story_edit(request, story_id):
     if request.method == 'POST':
         story = get_object_or_404(Story, id=story_id)
+        former_assignees = list(story.assignees.all())
+        
         form = StoryForm(request.POST, instance=story)
         if form.is_valid():
             form.save()
+            
+            for assignee in form.instance.assignees.all():
+                if not assignee in former_assignees and assignee.id != request.user.id:
+                    notify_story_assigned(story, request.user, assignee)
+            
             return redirect("story_details", story.id)
         
     else:
@@ -164,6 +176,7 @@ def story_delete(request, story_id):
 def story_close(request, story_id):
     story = get_object_or_404(Story, id=story_id)
     story.close()
+    notify_story_closed(story, request.user)
     if request.is_ajax():
         return HttpResponse(story.to_json())
     else:
@@ -181,9 +194,10 @@ def story_reaffect(request, story_id):
         return redirect('story_details', story.id)
     
 @login_required
-def story_reopen(_, story_id):
+def story_reopen(request, story_id):
     story = get_object_or_404(Story, id=story_id)
     story.reopen()
+    notify_story_reopened(story, request.user)
     return redirect('story_details', story_id)
 
 @login_required
@@ -244,16 +258,18 @@ def epic_value_update(request, epic_id):
         return redirect("backlog_editor")
     
 @login_required
-def epic_close(_, epic_id):
+def epic_close(request, epic_id):
     epic = get_object_or_404(Epic, id=epic_id)
     epic.close()
     epic.save()
+    notify_epic_closed(epic, request.user)
     return redirect("backlog_editor")
 
 @login_required
-def epic_reopen(_, epic_id):
+def epic_reopen(request, epic_id):
     epic = get_object_or_404(Epic, id=epic_id)
     epic.reopen()
+    notify_epic_reopened(epic, request.user)
     return redirect("backlog_editor")
 
 @login_required
@@ -301,6 +317,9 @@ def report_activity(request):
     
     return render(request, 'reports/report_activity.html', {'projects_activity': projects_activity, 'epics_activity': epics_activity_cleaned})
 
+
+# comments
+
 @login_required
 def comment_post(request):
     form = CommentForm(request.POST)
@@ -309,15 +328,7 @@ def comment_post(request):
         comment.author = request.user
         comment.save()
         
-        obj = comment.content_object
-        notify.send(request.user, 
-                    recipient=obj.contributors(), 
-                    action_object = obj,
-                    verb="{} a commenté <a href='{}#a-comment-{}'>{} #{}</a>".format(request.user.username, 
-                                                                        reverse('{}_details'.format(obj.model_name().lower()), args=(obj.id,)),
-                                                                        comment.id,
-                                                                        obj.model_name(), 
-                                                                        obj.id))
+        notify_comment(comment)
         
         return redirect(request.META['HTTP_REFERER'].split("#")[0] + "#a-comment-{}".format(comment.id))
     else:
@@ -364,8 +375,11 @@ def search(request):
         
         return render(request, 'search_results.html', {'results': results, 'pages': range(1, paginator.num_pages + 1)})
 
+
+# notifications
+
 @login_required
-def notif_seen(request, notif_id):
+def notif_seen(_, notif_id):
     notif = get_object_or_404(Notification, id=notif_id)
     notif.mark_as_read()
     return HttpResponse('{}')
@@ -376,4 +390,46 @@ def notif_all_seen(request):
         notif.mark_as_read()
     return HttpResponse('{}')
 
-    
+def notify_comment(comment):
+    obj = comment.content_object
+    target_url = reverse(f"{obj.model_name().lower()}_details", args=(obj.id,))
+    notif_content= f"{comment.author.username} a commenté <a href='{target_url}#a-comment-{comment.id}' title='{obj.name}'>{obj.model_name()} #{obj.id}</a>"
+    
+    for user in obj.contributors():
+        if user.id != comment.author.id:
+            notify.send(comment.author, recipient=user, action_object = obj, verb=notif_content)
+    
+def notify_story_closed(story, closed_by):
+    target_url = reverse(f"story_details", args=(story.id,))
+    notif_content= f"La <a href='{target_url}' title='{story.name}'>story #{story.id}</a> a été <b>clôturée</b> par {closed_by}"
+    
+    notify.send(closed_by, recipient=story.contributors(), action_object = story, verb=notif_content)
+    
+def notify_story_reopened(story, opened_by):
+    target_url = reverse(f"story_details", args=(story.id,))
+    notif_content= f"La <a href='{target_url}' title='{story.name}'>story #{story.id}</a> a été <b>réouverte</b> par {opened_by}"
+    
+    notify.send(opened_by, recipient=story.contributors(), action_object = story, verb=notif_content)
+    
+def notify_epic_closed(epic, closed_by):
+    target_url = reverse(f"epic_details", args=(epic.id,))
+    notif_content= f"La <a href='{target_url}' title='{epic.name}'>story #{epic.id}</a> a été <b>clôturée</b> par {closed_by}"
+    
+    notify.send(closed_by, recipient=User.objects.all(), action_object = epic, verb=notif_content)
+    
+def notify_epic_reopened(epic, opened_by):
+    target_url = reverse(f"epic_details", args=(epic.id,))
+    notif_content= f"L'<a href='{target_url}' title='{epic.name}'>epic #{epic.id}</a> a été <b>réouverte</b> par {opened_by}"
+    
+    notify.send(opened_by, recipient=User.objects.all(), action_object = epic, verb=notif_content)
+    
+def notify_story_assigned(story, assigned_by, assigned_to):
+    target_url = reverse(f"story_details", args=(story.id,))
+    notif_content= f"La <a href='{target_url}' title='{story.name}'>story #{story.id}</a> vous a été assignée par {assigned_by}"
+    
+    notify.send(assigned_by, recipient=assigned_to, action_object = story, verb=notif_content)
+    
+def notify_sprint_end(sprint, next_sprint, ended_by):
+    target_url = reverse(f"report_sprints")
+    notify.send(ended_by, recipient=User.objects.all(), action_object = sprint, verb=f"Fin du <a href='{target_url}'>{sprint}</a>")
+    notify.send(ended_by, recipient=User.objects.all(), action_object = sprint, verb=f"Démarrage du <a href='{target_url}'>{next_sprint}</a>")