mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
feat: user activity graph (#437)
* feat: user activity graph * dev: issue completed and activity graph
This commit is contained in:
parent
0082a98d53
commit
ed8f0b8473
@ -38,6 +38,8 @@ from plane.api.views import (
|
|||||||
AddTeamToProjectEndpoint,
|
AddTeamToProjectEndpoint,
|
||||||
UserLastProjectWithWorkspaceEndpoint,
|
UserLastProjectWithWorkspaceEndpoint,
|
||||||
UserWorkspaceInvitationEndpoint,
|
UserWorkspaceInvitationEndpoint,
|
||||||
|
UserActivityGraphEndpoint,
|
||||||
|
UserIssueCompletedGraphEndpoint,
|
||||||
## End Workspaces
|
## End Workspaces
|
||||||
# File Assets
|
# File Assets
|
||||||
FileAssetEndpoint,
|
FileAssetEndpoint,
|
||||||
@ -176,6 +178,18 @@ urlpatterns = [
|
|||||||
name="workspace",
|
name="workspace",
|
||||||
),
|
),
|
||||||
# user join workspace
|
# user join workspace
|
||||||
|
# User Graphs
|
||||||
|
path(
|
||||||
|
"users/me/workspaces/<str:slug>/activity-graph/",
|
||||||
|
UserActivityGraphEndpoint.as_view(),
|
||||||
|
name="user-activity-graph",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"users/me/workspaces/<str:slug>/issues-completed-graph/",
|
||||||
|
UserIssueCompletedGraphEndpoint.as_view(),
|
||||||
|
name="completed-graph",
|
||||||
|
),
|
||||||
|
## User Graph
|
||||||
path(
|
path(
|
||||||
"users/me/invitations/workspaces/<str:slug>/<uuid:pk>/join/",
|
"users/me/invitations/workspaces/<str:slug>/<uuid:pk>/join/",
|
||||||
JoinWorkspaceEndpoint.as_view(),
|
JoinWorkspaceEndpoint.as_view(),
|
||||||
|
@ -36,6 +36,8 @@ from .workspace import (
|
|||||||
UserLastProjectWithWorkspaceEndpoint,
|
UserLastProjectWithWorkspaceEndpoint,
|
||||||
WorkspaceMemberUserEndpoint,
|
WorkspaceMemberUserEndpoint,
|
||||||
WorkspaceMemberUserViewsEndpoint,
|
WorkspaceMemberUserViewsEndpoint,
|
||||||
|
UserActivityGraphEndpoint,
|
||||||
|
UserIssueCompletedGraphEndpoint,
|
||||||
)
|
)
|
||||||
from .state import StateViewSet
|
from .state import StateViewSet
|
||||||
from .shortcut import ShortCutViewSet
|
from .shortcut import ShortCutViewSet
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# Python imports
|
# Python imports
|
||||||
import jwt
|
import jwt
|
||||||
from datetime import datetime
|
from datetime import date
|
||||||
|
from dateutil.relativedelta import relativedelta
|
||||||
|
|
||||||
# Django imports
|
# Django imports
|
||||||
from django.db import IntegrityError
|
from django.db import IntegrityError
|
||||||
@ -10,8 +11,9 @@ from django.utils import timezone
|
|||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.core.validators import validate_email
|
from django.core.validators import validate_email
|
||||||
from django.contrib.sites.shortcuts import get_current_site
|
from django.contrib.sites.shortcuts import get_current_site
|
||||||
from django.db.models import CharField, Count, OuterRef, Func, F
|
from django.db.models import CharField, Count, OuterRef, Func, F, Q
|
||||||
from django.db.models.functions import Cast
|
from django.db.models.functions import Cast, ExtractWeek
|
||||||
|
from django.db.models.fields import DateField
|
||||||
|
|
||||||
# Third party modules
|
# Third party modules
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
@ -37,6 +39,8 @@ from plane.db.models import (
|
|||||||
WorkspaceMemberInvite,
|
WorkspaceMemberInvite,
|
||||||
Team,
|
Team,
|
||||||
ProjectMember,
|
ProjectMember,
|
||||||
|
IssueActivity,
|
||||||
|
Issue,
|
||||||
)
|
)
|
||||||
from plane.api.permissions import WorkSpaceBasePermission, WorkSpaceAdminPermission
|
from plane.api.permissions import WorkSpaceBasePermission, WorkSpaceAdminPermission
|
||||||
from plane.bgtasks.workspace_invitation_task import workspace_invitation
|
from plane.bgtasks.workspace_invitation_task import workspace_invitation
|
||||||
@ -578,3 +582,55 @@ class WorkspaceMemberUserViewsEndpoint(BaseAPIView):
|
|||||||
{"error": "Something went wrong please try again later"},
|
{"error": "Something went wrong please try again later"},
|
||||||
status=status.HTTP_400_BAD_REQUEST,
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class UserActivityGraphEndpoint(BaseAPIView):
|
||||||
|
def get(self, request, slug):
|
||||||
|
try:
|
||||||
|
issue_activities = (
|
||||||
|
IssueActivity.objects.filter(
|
||||||
|
actor=request.user,
|
||||||
|
workspace__slug=slug,
|
||||||
|
created_at__date__gte=date.today() + relativedelta(months=-3),
|
||||||
|
)
|
||||||
|
.annotate(created_date=Cast("created_at", DateField()))
|
||||||
|
.values("created_date")
|
||||||
|
.annotate(activity_count=Count("created_date"))
|
||||||
|
.order_by("created_date")
|
||||||
|
)
|
||||||
|
|
||||||
|
return Response(issue_activities, 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 UserIssueCompletedGraphEndpoint(BaseAPIView):
|
||||||
|
def get(self, request, slug):
|
||||||
|
try:
|
||||||
|
month = request.GET.get("month", 1)
|
||||||
|
|
||||||
|
issues = (
|
||||||
|
Issue.objects.filter(
|
||||||
|
assignees__in=[request.user],
|
||||||
|
workspace__slug=slug,
|
||||||
|
completed_at__month=month,
|
||||||
|
completed_at__isnull=False,
|
||||||
|
)
|
||||||
|
.annotate(completed_week=ExtractWeek("completed_at"))
|
||||||
|
.annotate(week=F("completed_week") % 4)
|
||||||
|
.values("week")
|
||||||
|
.annotate(completed_count=Count("completed_week"))
|
||||||
|
.order_by("week")
|
||||||
|
)
|
||||||
|
|
||||||
|
return Response(issues, status=status.HTTP_200_OK)
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
return Response(
|
||||||
|
{"error": "Something went wrong please try again later"},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user