-
Notifications
You must be signed in to change notification settings - Fork 3.6k
[WEB-1989] chore: archived modules and cycles #5212
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
bc8195c
b6c5c1d
53ca1eb
319158d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,21 +14,18 @@ | |
| UUIDField, | ||
| Value, | ||
| When, | ||
| Subquery, | ||
| Sum, | ||
| FloatField, | ||
| ) | ||
| from django.db.models.functions import Coalesce | ||
| from django.db.models.functions import Coalesce, Cast | ||
| from django.utils import timezone | ||
|
|
||
| # Third party imports | ||
| from rest_framework import status | ||
| from rest_framework.response import Response | ||
| from plane.app.permissions import ProjectEntityPermission | ||
| from plane.db.models import ( | ||
| Cycle, | ||
| UserFavorite, | ||
| Issue, | ||
| Label, | ||
| User, | ||
| ) | ||
| from plane.db.models import Cycle, UserFavorite, Issue, Label, User, Project | ||
| from plane.utils.analytics_plot import burndown_plot | ||
|
|
||
| # Module imports | ||
|
|
@@ -49,6 +46,89 @@ def get_queryset(self): | |
| project_id=self.kwargs.get("project_id"), | ||
| workspace__slug=self.kwargs.get("slug"), | ||
| ) | ||
| backlog_estimate_point = ( | ||
| Issue.issue_objects.filter( | ||
| estimate_point__estimate__type="points", | ||
| state__group="backlog", | ||
| issue_cycle__cycle_id=OuterRef("pk"), | ||
| ) | ||
| .values("issue_cycle__cycle_id") | ||
| .annotate( | ||
| backlog_estimate_point=Sum( | ||
| Cast("estimate_point__value", FloatField()) | ||
| ) | ||
| ) | ||
| .values("backlog_estimate_point")[:1] | ||
| ) | ||
| unstarted_estimate_point = ( | ||
| Issue.issue_objects.filter( | ||
| estimate_point__estimate__type="points", | ||
| state__group="unstarted", | ||
| issue_cycle__cycle_id=OuterRef("pk"), | ||
| ) | ||
| .values("issue_cycle__cycle_id") | ||
| .annotate( | ||
| unstarted_estimate_point=Sum( | ||
| Cast("estimate_point__value", FloatField()) | ||
| ) | ||
| ) | ||
| .values("unstarted_estimate_point")[:1] | ||
| ) | ||
|
Comment on lines
+63
to
+76
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Enhance readability by extracting subquery logic into a helper function. The subquery logic for calculating unstarted_estimate_point = get_estimate_point_subquery("unstarted") |
||
| started_estimate_point = ( | ||
| Issue.issue_objects.filter( | ||
| estimate_point__estimate__type="points", | ||
| state__group="started", | ||
| issue_cycle__cycle_id=OuterRef("pk"), | ||
| ) | ||
| .values("issue_cycle__cycle_id") | ||
| .annotate( | ||
| started_estimate_point=Sum( | ||
| Cast("estimate_point__value", FloatField()) | ||
| ) | ||
| ) | ||
| .values("started_estimate_point")[:1] | ||
| ) | ||
|
Comment on lines
+77
to
+90
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Enhance readability by extracting subquery logic into a helper function. The subquery logic for calculating started_estimate_point = get_estimate_point_subquery("started") |
||
| cancelled_estimate_point = ( | ||
| Issue.issue_objects.filter( | ||
| estimate_point__estimate__type="points", | ||
| state__group="cancelled", | ||
| issue_cycle__cycle_id=OuterRef("pk"), | ||
| ) | ||
| .values("issue_cycle__cycle_id") | ||
| .annotate( | ||
| cancelled_estimate_point=Sum( | ||
| Cast("estimate_point__value", FloatField()) | ||
| ) | ||
| ) | ||
| .values("cancelled_estimate_point")[:1] | ||
| ) | ||
|
Comment on lines
+91
to
+104
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Enhance readability by extracting subquery logic into a helper function. The subquery logic for calculating cancelled_estimate_point = get_estimate_point_subquery("cancelled") |
||
| completed_estimate_point = ( | ||
| Issue.issue_objects.filter( | ||
| estimate_point__estimate__type="points", | ||
| state__group="completed", | ||
| issue_cycle__cycle_id=OuterRef("pk"), | ||
| ) | ||
| .values("issue_cycle__cycle_id") | ||
| .annotate( | ||
| completed_estimate_points=Sum( | ||
| Cast("estimate_point__value", FloatField()) | ||
| ) | ||
| ) | ||
| .values("completed_estimate_points")[:1] | ||
| ) | ||
|
Comment on lines
+105
to
+118
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Enhance readability by extracting subquery logic into a helper function. The subquery logic for calculating completed_estimate_point = get_estimate_point_subquery("completed") |
||
| total_estimate_point = ( | ||
| Issue.issue_objects.filter( | ||
| estimate_point__estimate__type="points", | ||
| issue_cycle__cycle_id=OuterRef("pk"), | ||
| ) | ||
| .values("issue_cycle__cycle_id") | ||
| .annotate( | ||
| total_estimate_points=Sum( | ||
| Cast("estimate_point__value", FloatField()) | ||
| ) | ||
| ) | ||
| .values("total_estimate_points")[:1] | ||
|
Comment on lines
+119
to
+130
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Enhance readability by extracting subquery logic into a helper function. The subquery logic for calculating total_estimate_point = get_estimate_point_subquery(None) |
||
| ) | ||
| return ( | ||
| Cycle.objects.filter(workspace__slug=self.kwargs.get("slug")) | ||
| .filter(project_id=self.kwargs.get("project_id")) | ||
|
|
@@ -172,24 +252,50 @@ def get_queryset(self): | |
| Value([], output_field=ArrayField(UUIDField())), | ||
| ) | ||
| ) | ||
| .annotate( | ||
| backlog_estimate_points=Coalesce( | ||
| Subquery(backlog_estimate_point), | ||
| Value(0, output_field=FloatField()), | ||
| ), | ||
| ) | ||
| .annotate( | ||
| unstarted_estimate_points=Coalesce( | ||
| Subquery(unstarted_estimate_point), | ||
| Value(0, output_field=FloatField()), | ||
| ), | ||
| ) | ||
| .annotate( | ||
| started_estimate_points=Coalesce( | ||
| Subquery(started_estimate_point), | ||
| Value(0, output_field=FloatField()), | ||
| ), | ||
| ) | ||
| .annotate( | ||
| cancelled_estimate_points=Coalesce( | ||
| Subquery(cancelled_estimate_point), | ||
| Value(0, output_field=FloatField()), | ||
| ), | ||
| ) | ||
| .annotate( | ||
| completed_estimate_points=Coalesce( | ||
| Subquery(completed_estimate_point), | ||
| Value(0, output_field=FloatField()), | ||
| ), | ||
| ) | ||
| .annotate( | ||
| total_estimate_points=Coalesce( | ||
| Subquery(total_estimate_point), | ||
| Value(0, output_field=FloatField()), | ||
| ), | ||
| ) | ||
| .order_by("-is_favorite", "name") | ||
| .distinct() | ||
| ) | ||
|
|
||
| def get(self, request, slug, project_id, pk=None): | ||
| if pk is None: | ||
| queryset = ( | ||
| self.get_queryset() | ||
| .annotate( | ||
| total_issues=Count( | ||
| "issue_cycle", | ||
| filter=Q( | ||
| issue_cycle__issue__archived_at__isnull=True, | ||
| issue_cycle__issue__is_draft=False, | ||
| ), | ||
| ) | ||
| ) | ||
| .values( | ||
| self.get_queryset().values( | ||
| # necessary fields | ||
| "id", | ||
| "workspace_id", | ||
|
|
@@ -255,7 +361,10 @@ def get(self, request, slug, project_id, pk=None): | |
| "external_id", | ||
| "progress_snapshot", | ||
| "sub_issues", | ||
| "logo_props", | ||
| # meta fields | ||
| "completed_estimate_points", | ||
| "total_estimate_points", | ||
| "is_favorite", | ||
| "total_issues", | ||
| "cancelled_issues", | ||
|
|
@@ -265,17 +374,114 @@ def get(self, request, slug, project_id, pk=None): | |
| "backlog_issues", | ||
| "assignee_ids", | ||
| "status", | ||
| "created_by", | ||
| "archived_at", | ||
| ) | ||
| .first() | ||
| ) | ||
| queryset = queryset.first() | ||
|
|
||
| if data is None: | ||
| return Response( | ||
| {"error": "Cycle does not exist"}, | ||
| status=status.HTTP_400_BAD_REQUEST, | ||
| estimate_type = Project.objects.filter( | ||
| workspace__slug=slug, | ||
| pk=project_id, | ||
| estimate__isnull=False, | ||
| estimate__type="points", | ||
| ).exists() | ||
|
|
||
| data["estimate_distribution"] = {} | ||
| if estimate_type: | ||
| assignee_distribution = ( | ||
| Issue.issue_objects.filter( | ||
| issue_cycle__cycle_id=pk, | ||
| workspace__slug=slug, | ||
| project_id=project_id, | ||
| ) | ||
| .annotate(display_name=F("assignees__display_name")) | ||
| .annotate(assignee_id=F("assignees__id")) | ||
| .annotate(avatar=F("assignees__avatar")) | ||
| .values("display_name", "assignee_id", "avatar") | ||
| .annotate( | ||
| total_estimates=Sum( | ||
| Cast("estimate_point__value", FloatField()) | ||
| ) | ||
| ) | ||
| .annotate( | ||
| completed_estimates=Sum( | ||
| Cast("estimate_point__value", FloatField()), | ||
| filter=Q( | ||
| completed_at__isnull=False, | ||
| archived_at__isnull=True, | ||
| is_draft=False, | ||
| ), | ||
| ) | ||
| ) | ||
| .annotate( | ||
| pending_estimates=Sum( | ||
| Cast("estimate_point__value", FloatField()), | ||
| filter=Q( | ||
| completed_at__isnull=True, | ||
| archived_at__isnull=True, | ||
| is_draft=False, | ||
| ), | ||
| ) | ||
| ) | ||
| .order_by("display_name") | ||
| ) | ||
|
|
||
| label_distribution = ( | ||
| Issue.issue_objects.filter( | ||
| issue_cycle__cycle_id=pk, | ||
| workspace__slug=slug, | ||
| project_id=project_id, | ||
| ) | ||
| .annotate(label_name=F("labels__name")) | ||
| .annotate(color=F("labels__color")) | ||
| .annotate(label_id=F("labels__id")) | ||
| .values("label_name", "color", "label_id") | ||
| .annotate( | ||
| total_estimates=Sum( | ||
| Cast("estimate_point__value", FloatField()) | ||
| ) | ||
| ) | ||
| .annotate( | ||
| completed_estimates=Sum( | ||
| Cast("estimate_point__value", FloatField()), | ||
| filter=Q( | ||
| completed_at__isnull=False, | ||
| archived_at__isnull=True, | ||
| is_draft=False, | ||
| ), | ||
| ) | ||
| ) | ||
| .annotate( | ||
| pending_estimates=Sum( | ||
| Cast("estimate_point__value", FloatField()), | ||
| filter=Q( | ||
| completed_at__isnull=True, | ||
| archived_at__isnull=True, | ||
| is_draft=False, | ||
| ), | ||
| ) | ||
| ) | ||
| .order_by("label_name") | ||
| ) | ||
| data["estimate_distribution"] = { | ||
| "assignees": assignee_distribution, | ||
| "labels": label_distribution, | ||
| "completion_chart": {}, | ||
| } | ||
|
|
||
| if data["start_date"] and data["end_date"]: | ||
| data["estimate_distribution"]["completion_chart"] = ( | ||
| burndown_plot( | ||
| queryset=queryset, | ||
| slug=slug, | ||
| project_id=project_id, | ||
| plot_type="points", | ||
| cycle_id=pk, | ||
| ) | ||
| ) | ||
|
|
||
| # Assignee Distribution | ||
| assignee_distribution = ( | ||
| Issue.issue_objects.filter( | ||
|
|
@@ -298,7 +504,10 @@ def get(self, request, slug, project_id, pk=None): | |
| .annotate( | ||
| total_issues=Count( | ||
| "id", | ||
| filter=Q(archived_at__isnull=True, is_draft=False), | ||
| filter=Q( | ||
| archived_at__isnull=True, | ||
| is_draft=False, | ||
| ), | ||
| ), | ||
| ) | ||
| .annotate( | ||
|
|
@@ -338,7 +547,10 @@ def get(self, request, slug, project_id, pk=None): | |
| .annotate( | ||
| total_issues=Count( | ||
| "id", | ||
| filter=Q(archived_at__isnull=True, is_draft=False), | ||
| filter=Q( | ||
| archived_at__isnull=True, | ||
| is_draft=False, | ||
| ), | ||
| ), | ||
| ) | ||
| .annotate( | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.