forked from github/plane
chore: add assignee, label and burndown plot in module details (#1313)
* chore: add assignee, label and burndown plot in module details * dev: fix typo and key error * dev: add avatar in module retrieve
This commit is contained in:
parent
ac6fae44e8
commit
7a991720a8
@ -37,7 +37,7 @@ from plane.db.models import (
|
|||||||
from plane.bgtasks.issue_activites_task import issue_activity
|
from plane.bgtasks.issue_activites_task import issue_activity
|
||||||
from plane.utils.grouper import group_results
|
from plane.utils.grouper import group_results
|
||||||
from plane.utils.issue_filters import issue_filters
|
from plane.utils.issue_filters import issue_filters
|
||||||
|
from plane.utils.analytics_plot import burndown_plot
|
||||||
|
|
||||||
class ModuleViewSet(BaseViewSet):
|
class ModuleViewSet(BaseViewSet):
|
||||||
model = Module
|
model = Module
|
||||||
@ -160,6 +160,87 @@ class ModuleViewSet(BaseViewSet):
|
|||||||
status=status.HTTP_400_BAD_REQUEST,
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def retrieve(self, request, slug, project_id, pk):
|
||||||
|
try:
|
||||||
|
queryset = self.get_queryset().get(pk=pk)
|
||||||
|
|
||||||
|
assignee_distribution = (
|
||||||
|
Issue.objects.filter(
|
||||||
|
issue_module__module_id=pk,
|
||||||
|
workspace__slug=slug,
|
||||||
|
project_id=project_id,
|
||||||
|
)
|
||||||
|
.annotate(first_name=F("assignees__first_name"))
|
||||||
|
.annotate(last_name=F("assignees__last_name"))
|
||||||
|
.annotate(assignee_id=F("assignees__id"))
|
||||||
|
.annotate(avatar=F("assignees__avatar"))
|
||||||
|
.values("first_name", "last_name", "assignee_id", "avatar")
|
||||||
|
.annotate(total_issues=Count("assignee_id"))
|
||||||
|
.annotate(
|
||||||
|
completed_issues=Count(
|
||||||
|
"assignee_id",
|
||||||
|
filter=Q(completed_at__isnull=False),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.annotate(
|
||||||
|
pending_issues=Count(
|
||||||
|
"assignee_id",
|
||||||
|
filter=Q(completed_at__isnull=True),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.order_by("first_name", "last_name")
|
||||||
|
)
|
||||||
|
|
||||||
|
label_distribution = (
|
||||||
|
Issue.objects.filter(
|
||||||
|
issue_module__module_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_issues=Count("label_id"))
|
||||||
|
.annotate(
|
||||||
|
completed_issues=Count(
|
||||||
|
"label_id",
|
||||||
|
filter=Q(completed_at__isnull=False),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.annotate(
|
||||||
|
pending_issues=Count(
|
||||||
|
"label_id",
|
||||||
|
filter=Q(completed_at__isnull=True),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.order_by("label_name")
|
||||||
|
)
|
||||||
|
|
||||||
|
data = ModuleSerializer(queryset).data
|
||||||
|
data["distribution"] = {
|
||||||
|
"assignees": assignee_distribution,
|
||||||
|
"labels": label_distribution,
|
||||||
|
"completion_chart": {},
|
||||||
|
}
|
||||||
|
|
||||||
|
if queryset.start_date and queryset.target_date:
|
||||||
|
data["distribution"]["completion_chart"] = burndown_plot(
|
||||||
|
queryset=queryset, slug=slug, project_id=project_id, module_id=pk
|
||||||
|
)
|
||||||
|
|
||||||
|
return Response(
|
||||||
|
data,
|
||||||
|
status=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
capture_exception(e)
|
||||||
|
return Response(
|
||||||
|
{"error": "Something went wrong please try again later"},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ModuleIssueViewSet(BaseViewSet):
|
class ModuleIssueViewSet(BaseViewSet):
|
||||||
serializer_class = ModuleIssueSerializer
|
serializer_class = ModuleIssueSerializer
|
||||||
|
@ -81,30 +81,55 @@ def build_graph_plot(queryset, x_axis, y_axis, segment=None):
|
|||||||
return sorted_data
|
return sorted_data
|
||||||
|
|
||||||
|
|
||||||
def burndown_plot(queryset, slug, project_id, cycle_id):
|
def burndown_plot(queryset, slug, project_id, cycle_id=None, module_id=None):
|
||||||
# Get all dates between the two dates
|
# Total Issues in Cycle or Module
|
||||||
date_range = [
|
|
||||||
queryset.start_date + timedelta(days=x)
|
|
||||||
for x in range((queryset.end_date - queryset.start_date).days + 1)
|
|
||||||
]
|
|
||||||
|
|
||||||
chart_data = {str(date): 0 for date in date_range}
|
|
||||||
|
|
||||||
# Total Issues in Cycle
|
|
||||||
total_issues = queryset.total_issues
|
total_issues = queryset.total_issues
|
||||||
|
|
||||||
completed_issues_distribution = (
|
|
||||||
Issue.objects.filter(
|
if cycle_id:
|
||||||
workspace__slug=slug,
|
# Get all dates between the two dates
|
||||||
project_id=project_id,
|
date_range = [
|
||||||
issue_cycle__cycle_id=cycle_id,
|
queryset.start_date + timedelta(days=x)
|
||||||
|
for x in range((queryset.end_date - queryset.start_date).days + 1)
|
||||||
|
]
|
||||||
|
|
||||||
|
chart_data = {str(date): 0 for date in date_range}
|
||||||
|
|
||||||
|
completed_issues_distribution = (
|
||||||
|
Issue.objects.filter(
|
||||||
|
workspace__slug=slug,
|
||||||
|
project_id=project_id,
|
||||||
|
issue_cycle__cycle_id=cycle_id,
|
||||||
|
)
|
||||||
|
.annotate(date=TruncDate("completed_at"))
|
||||||
|
.values("date")
|
||||||
|
.annotate(total_completed=Count("id"))
|
||||||
|
.values("date", "total_completed")
|
||||||
|
.order_by("date")
|
||||||
)
|
)
|
||||||
.annotate(date=TruncDate("completed_at"))
|
|
||||||
.values("date")
|
if module_id:
|
||||||
.annotate(total_completed=Count("id"))
|
# Get all dates between the two dates
|
||||||
.values("date", "total_completed")
|
date_range = [
|
||||||
.order_by("date")
|
queryset.start_date + timedelta(days=x)
|
||||||
)
|
for x in range((queryset.target_date - queryset.start_date).days + 1)
|
||||||
|
]
|
||||||
|
|
||||||
|
chart_data = {str(date): 0 for date in date_range}
|
||||||
|
|
||||||
|
completed_issues_distribution = (
|
||||||
|
Issue.objects.filter(
|
||||||
|
workspace__slug=slug,
|
||||||
|
project_id=project_id,
|
||||||
|
issue_module__module_id=module_id,
|
||||||
|
)
|
||||||
|
.annotate(date=TruncDate("completed_at"))
|
||||||
|
.values("date")
|
||||||
|
.annotate(total_completed=Count("id"))
|
||||||
|
.values("date", "total_completed")
|
||||||
|
.order_by("date")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
for date in date_range:
|
for date in date_range:
|
||||||
cumulative_pending_issues = total_issues
|
cumulative_pending_issues = total_issues
|
||||||
|
Loading…
Reference in New Issue
Block a user