From 8273314c879730cc1b7c26a6813fb6c8232c4afc Mon Sep 17 00:00:00 2001
From: Parbhat Puri <parbhatpuri17@gmail.com>
Date: Fri, 19 Apr 2019 12:19:34 +0000
Subject: [PATCH] GH-1147: Dashboard view for community reviewers

---
 .../dashboard/community_dashboard.html        | 82 ++++++++++++-------
 opentech/apply/dashboard/views.py             | 69 +++++++++++-----
 opentech/apply/funds/models/submissions.py    |  5 ++
 opentech/apply/funds/tables.py                |  5 --
 4 files changed, 104 insertions(+), 57 deletions(-)

diff --git a/opentech/apply/dashboard/templates/dashboard/community_dashboard.html b/opentech/apply/dashboard/templates/dashboard/community_dashboard.html
index 122386a8b..27d49cb7d 100644
--- a/opentech/apply/dashboard/templates/dashboard/community_dashboard.html
+++ b/opentech/apply/dashboard/templates/dashboard/community_dashboard.html
@@ -1,6 +1,6 @@
 {% extends "base-apply.html" %}
 {% load render_table from django_tables2 %}
-{% load static wagtailcore_tags workflow_tags statusbar_tags %}
+{% load static statusbar_tags workflow_tags wagtailcore_tags %}
 
 {% block title %}Submission Dashboard{% endblock %}
 
@@ -18,40 +18,60 @@
         </div>
     </div>
 </div>
+
 <div class="wrapper wrapper--large wrapper--inner-space-medium">
-    <h3>Your active submissions</h3>
-    {% for submission in my_active_submissions %}
-        <div class="wrapper wrapper--status-bar-outer">
-            <div class="wrapper wrapper--status-bar-inner">
-                <div>
-                    <h5 class="heading heading--no-margin"><a class="link link--underlined" href="{% url 'funds:submissions:detail' submission.id %}">{{ submission.title }}</a></h5>
-                    <h6 class="heading heading--no-margin heading--submission-meta"><span>Submitted:</span> {{ submission.submit_time.date }} by {{ submission.user.get_full_name }}</h6>
+
+    <div class="wrapper wrapper--bottom-space">
+        <h4 class="heading heading--normal">
+            Community review submissions <span class="heading heading--submission-count">{{ my_community_review_count }}</span>
+        </h4>
+
+        {% if my_community_review.data %}
+            {% render_table my_community_review %}
+        {% else %}
+            No submissions
+        {% endif %}
+    </div>
+
+    {% if my_reviewed.data %}
+        <div class="wrapper wrapper--bottom-space">
+            <h4 class="heading heading--normal">Your previous reviews</h4>
+            {% render_table my_reviewed %}
+        </div>
+    {% endif %}
+
+    <div class="wrapper wrapper--bottom-space">
+        <h4 class="heading heading--normal">Your active submissions</h4>
+        {% for submission in my_submissions %}
+            <div class="wrapper wrapper--status-bar-outer">
+                <div class="wrapper wrapper--status-bar-inner">
+                    <div>
+                        <h5 class="heading heading--no-margin"><a class="link link--underlined" href="{% url 'funds:submissions:detail' submission.id %}">{{ submission.title }}</a></h5>
+                        <h6 class="heading heading--no-margin heading--submission-meta"><span>Submitted:</span> {{ submission.submit_time.date }} by {{ submission.user.get_full_name }}</h6>
+                    </div>
+                    {% status_bar submission.workflow submission.phase request.user css_class="status-bar--small" %}
                 </div>
-                {% status_bar submission.workflow submission.phase request.user css_class="status-bar--small" %}
+                {% if request.user|has_edit_perm:submission %}
+                    <a class="button button--primary" href="{% url 'funds:submissions:edit' submission.id %}">
+                        {% if submission.status == 'draft_proposal' %}
+                            Start your {{ submission.stage }} application
+                        {% else %}
+                            Edit
+                        {% endif %}
+                    </a>
+                {% endif %}
             </div>
-            {% if request.user|has_edit_perm:submission %}
-                <a class="button button--primary" href="{% url 'funds:submissions:edit' submission.id %}">
-                    {% if submission.status == 'draft_proposal' %}
-                        Start your {{ submission.stage }} application
-                    {% else %}
-                        Edit
-                    {% endif %}
-                </a>
-            {% endif %}
+        {% empty %}
+            No active submissions
+        {% endfor %}
     </div>
-    {% empty %}
-        No active submissions
-    {% endfor %}
-</div>
 
-{% if table.data %}
-    <div class="wrapper wrapper--large wrapper--inner-space-medium">
-        <h3>Submission history</h3>
-        {% render_table table %}
-    </div>
-{% endif %}
-{% endblock %}
+    {% if my_inactive_submissions_table.data %}
+        <div class="wrapper wrapper--bottom-space">
+            <h4 class="heading heading--normal">Submission history</h4>
+            {% render_table my_inactive_submissions_table %}
+        </div>
+    {% endif %}
+</div>
 
-{% block extra_js %}
-    <script src="{% static 'js/apply/submission-tooltips.js' %}"></script>
 {% endblock %}
diff --git a/opentech/apply/dashboard/views.py b/opentech/apply/dashboard/views.py
index 84ac2ce23..91a41a7ed 100644
--- a/opentech/apply/dashboard/views.py
+++ b/opentech/apply/dashboard/views.py
@@ -12,8 +12,7 @@ from opentech.apply.funds.tables import (
     SubmissionsTable,
     SummarySubmissionsTable,
     SummarySubmissionsTableWithRole,
-    review_filter_for_user,
-    PartnerSubmissionsTable
+    review_filter_for_user
 )
 from opentech.apply.utils.views import ViewDispatcher
 
@@ -179,13 +178,13 @@ class PartnerDashboardView(TemplateView):
 
     def get_partner_submissions(self, user, qs):
         partner_submissions_qs = qs.partner_for(user).order_by('-submit_time')
-        partner_submissions_table = PartnerSubmissionsTable(partner_submissions_qs, prefix='my-partnered-')
+        partner_submissions_table = ReviewerSubmissionsTable(partner_submissions_qs, prefix='my-partnered-')
 
         return partner_submissions_qs, partner_submissions_table
 
     def get_my_reviewed(self, request, qs):
         my_reviewed_qs = qs.reviewed_by(request.user).order_by('-submit_time')
-        my_reviewed_table = PartnerSubmissionsTable(my_reviewed_qs, prefix='my-reviewed-')
+        my_reviewed_table = ReviewerSubmissionsTable(my_reviewed_qs, prefix='my-reviewed-')
 
         return my_reviewed_qs, my_reviewed_table
 
@@ -198,7 +197,7 @@ class PartnerDashboardView(TemplateView):
         ]
 
         my_inactive_submissions_qs = qs.filter(user=self.request.user).inactive().current()
-        my_inactive_submissions_table = PartnerSubmissionsTable(
+        my_inactive_submissions_table = ReviewerSubmissionsTable(
             my_inactive_submissions_qs, prefix='my-submissions-'
         )
         return my_submissions, my_inactive_submissions_table
@@ -227,29 +226,57 @@ class PartnerDashboardView(TemplateView):
         return context
 
 
-class CommunityDashboardView(SingleTableView):
+class CommunityDashboardView(TemplateView):
     template_name = 'dashboard/community_dashboard.html'
-    model = ApplicationSubmission
-    table_class = SubmissionsTable
 
-    def get_queryset(self):
-        return self.model.objects.filter(
-            user=self.request.user
-        ).inactive().current().for_table(self.request.user)
+    def get_my_community_review(self, user, qs):
+        my_community_review_qs = qs.in_community_review(user).order_by('-submit_time')
+        my_community_review_table = ReviewerSubmissionsTable(my_community_review_qs, prefix='my-community-review-')
 
-    def get_context_data(self, **kwargs):
-        my_active_submissions = self.model.objects.filter(
-            user=self.request.user
-        ).active().current().select_related('draft_revision')
+        return my_community_review_qs, my_community_review_table
 
-        my_active_submissions = [
-            submission.from_draft() for submission in my_active_submissions
+    def get_my_reviewed(self, request, qs):
+        my_reviewed_qs = qs.reviewed_by(request.user).order_by('-submit_time')
+        my_reviewed_table = ReviewerSubmissionsTable(my_reviewed_qs, prefix='my-reviewed-')
+
+        return my_reviewed_qs, my_reviewed_table
+
+    def get_my_submissions(self, request, qs):
+        my_submissions = qs.filter(
+            user=request.user
+        ).active().current().select_related('draft_revision')
+        my_submissions = [
+            submission.from_draft() for submission in my_submissions
         ]
 
-        return super().get_context_data(
-            my_active_submissions=my_active_submissions,
-            **kwargs,
+        my_inactive_submissions_qs = qs.filter(user=self.request.user).inactive().current()
+        my_inactive_submissions_table = ReviewerSubmissionsTable(
+            my_inactive_submissions_qs, prefix='my-submissions-'
         )
+        return my_submissions, my_inactive_submissions_table
+
+    def get_context_data(self, **kwargs):
+        context = super().get_context_data(**kwargs)
+        qs = ApplicationSubmission.objects.all().for_table(self.request.user)
+
+        # Submissions in community review phase
+        my_community_review_qs, my_community_review = self.get_my_community_review(self.request.user, qs)
+
+        # Partner's reviewed submissions
+        my_reviewed_qs, my_reviewed = self.get_my_reviewed(self.request, qs)
+
+        # Applications by partner
+        my_submissions, my_inactive_submissions_table = self.get_my_submissions(self.request, qs)
+
+        context.update({
+            'my_community_review': my_community_review,
+            'my_community_review_count': my_community_review_qs.count(),
+            'my_reviewed': my_reviewed,
+            'my_submissions': my_submissions,
+            'my_inactive_submissions_table': my_inactive_submissions_table,
+        })
+
+        return context
 
 
 class ApplicantDashboardView(SingleTableView):
diff --git a/opentech/apply/funds/models/submissions.py b/opentech/apply/funds/models/submissions.py
index cd0505443..9744ff26c 100644
--- a/opentech/apply/funds/models/submissions.py
+++ b/opentech/apply/funds/models/submissions.py
@@ -81,6 +81,11 @@ class ApplicationSubmissionQueryset(JSONOrderable):
     def inactive(self):
         return self.exclude(status__in=active_statuses)
 
+    def in_community_review(self, user):
+        qs = self.filter(Q(status__in=COMMUNITY_REVIEW_PHASES), ~Q(reviews__author=user) | Q(reviews__is_draft=True))
+        qs = qs.exclude(reviews__opinions__opinion=AGREE, reviews__opinions__author=user)
+        return qs.distinct()
+
     def in_review(self):
         return self.filter(status__in=review_statuses)
 
diff --git a/opentech/apply/funds/tables.py b/opentech/apply/funds/tables.py
index 23c3ba801..a08dc0512 100644
--- a/opentech/apply/funds/tables.py
+++ b/opentech/apply/funds/tables.py
@@ -93,11 +93,6 @@ class ReviewerSubmissionsTable(SubmissionsTable):
         orderable = False
 
 
-class PartnerSubmissionsTable(SubmissionsTable):
-    class Meta(SubmissionsTable.Meta):
-        orderable = False
-
-
 class LabeledCheckboxColumn(tables.CheckBoxColumn):
     def wrap_with_label(self, checkbox, for_value):
         return format_html(
-- 
GitLab