From a6a0eb97748438576658377ffcb5178021d99d0e Mon Sep 17 00:00:00 2001 From: Bavisetti Narayan <72156168+NarayanBavisetti@users.noreply.github.com> Date: Tue, 19 Sep 2023 19:46:57 +0530 Subject: [PATCH] chore: added epoch in issue activity (#2187) --- apiserver/plane/api/views/cycle.py | 3 + apiserver/plane/api/views/inbox.py | 4 + apiserver/plane/api/views/issue.py | 32 +++++ apiserver/plane/api/views/module.py | 4 + .../plane/bgtasks/issue_activites_task.py | 121 +++++++++++++----- .../plane/bgtasks/issue_automation_task.py | 2 + ..._alter_analyticview_created_by_and_more.py | 27 ++++ apiserver/plane/db/models/issue.py | 1 + 8 files changed, 164 insertions(+), 30 deletions(-) create mode 100644 apiserver/plane/db/migrations/0045_issueactivity_epoch_alter_analyticview_created_by_and_more.py diff --git a/apiserver/plane/api/views/cycle.py b/apiserver/plane/api/views/cycle.py index 4f9e1db32..4f895aeba 100644 --- a/apiserver/plane/api/views/cycle.py +++ b/apiserver/plane/api/views/cycle.py @@ -80,6 +80,7 @@ class CycleViewSet(BaseViewSet): issue_id=str(self.kwargs.get("pk", None)), project_id=str(self.kwargs.get("project_id", None)), current_instance=None, + epoch = int(timezone.now().timestamp()) ) return super().perform_destroy(instance) @@ -487,6 +488,7 @@ class CycleIssueViewSet(BaseViewSet): issue_id=str(self.kwargs.get("pk", None)), project_id=str(self.kwargs.get("project_id", None)), current_instance=None, + epoch = int(timezone.now().timestamp()) ) return super().perform_destroy(instance) @@ -662,6 +664,7 @@ class CycleIssueViewSet(BaseViewSet): ), } ), + epoch = int(timezone.now().timestamp()) ) # Return all Cycle Issues diff --git a/apiserver/plane/api/views/inbox.py b/apiserver/plane/api/views/inbox.py index 4fbea5f87..1a0284ea4 100644 --- a/apiserver/plane/api/views/inbox.py +++ b/apiserver/plane/api/views/inbox.py @@ -213,6 +213,7 @@ class InboxIssueViewSet(BaseViewSet): issue_id=str(issue.id), project_id=str(project_id), current_instance=None, + epoch = int(timezone.now().timestamp()) ) # create an inbox issue InboxIssue.objects.create( @@ -277,6 +278,7 @@ class InboxIssueViewSet(BaseViewSet): IssueSerializer(current_instance).data, cls=DjangoJSONEncoder, ), + epoch = int(timezone.now().timestamp()) ) issue_serializer.save() else: @@ -518,6 +520,7 @@ class InboxIssuePublicViewSet(BaseViewSet): issue_id=str(issue.id), project_id=str(project_id), current_instance=None, + epoch = int(timezone.now().timestamp()) ) # create an inbox issue InboxIssue.objects.create( @@ -582,6 +585,7 @@ class InboxIssuePublicViewSet(BaseViewSet): IssueSerializer(current_instance).data, cls=DjangoJSONEncoder, ), + epoch = int(timezone.now().timestamp()) ) issue_serializer.save() return Response(issue_serializer.data, status=status.HTTP_200_OK) diff --git a/apiserver/plane/api/views/issue.py b/apiserver/plane/api/views/issue.py index 79141d78d..6ec48babf 100644 --- a/apiserver/plane/api/views/issue.py +++ b/apiserver/plane/api/views/issue.py @@ -4,6 +4,7 @@ import random from itertools import chain # Django imports +from django.utils import timezone from django.db.models import ( Prefetch, OuterRef, @@ -129,6 +130,7 @@ class IssueViewSet(BaseViewSet): current_instance=json.dumps( IssueSerializer(current_instance).data, cls=DjangoJSONEncoder ), + epoch = int(timezone.now().time()) ) return super().perform_update(serializer) @@ -149,6 +151,7 @@ class IssueViewSet(BaseViewSet): current_instance=json.dumps( IssueSerializer(current_instance).data, cls=DjangoJSONEncoder ), + epoch = int(timezone.now().timestamp()) ) return super().perform_destroy(instance) @@ -315,6 +318,7 @@ class IssueViewSet(BaseViewSet): issue_id=str(serializer.data.get("id", None)), project_id=str(project_id), current_instance=None, + epoch = int(timezone.now().timestamp()) ) return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @@ -568,6 +572,7 @@ class IssueCommentViewSet(BaseViewSet): issue_id=str(self.kwargs.get("issue_id")), project_id=str(self.kwargs.get("project_id")), current_instance=None, + epoch = int(timezone.now().timestamp()) ) def perform_update(self, serializer): @@ -586,6 +591,7 @@ class IssueCommentViewSet(BaseViewSet): IssueCommentSerializer(current_instance).data, cls=DjangoJSONEncoder, ), + epoch = int(timezone.now().timestamp()) ) return super().perform_update(serializer) @@ -607,6 +613,7 @@ class IssueCommentViewSet(BaseViewSet): IssueCommentSerializer(current_instance).data, cls=DjangoJSONEncoder, ), + epoch = int(timezone.now().timestamp()) ) return super().perform_destroy(instance) @@ -890,6 +897,7 @@ class IssueLinkViewSet(BaseViewSet): issue_id=str(self.kwargs.get("issue_id")), project_id=str(self.kwargs.get("project_id")), current_instance=None, + epoch = int(timezone.now().timestamp()) ) def perform_update(self, serializer): @@ -908,6 +916,7 @@ class IssueLinkViewSet(BaseViewSet): IssueLinkSerializer(current_instance).data, cls=DjangoJSONEncoder, ), + epoch = int(timezone.now().timestamp()) ) return super().perform_update(serializer) @@ -929,6 +938,7 @@ class IssueLinkViewSet(BaseViewSet): IssueLinkSerializer(current_instance).data, cls=DjangoJSONEncoder, ), + epoch = int(timezone.now().timestamp()) ) return super().perform_destroy(instance) @@ -1007,6 +1017,7 @@ class IssueAttachmentEndpoint(BaseAPIView): serializer.data, cls=DjangoJSONEncoder, ), + epoch = int(timezone.now().timestamp()) ) return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @@ -1029,6 +1040,7 @@ class IssueAttachmentEndpoint(BaseAPIView): issue_id=str(self.kwargs.get("issue_id", None)), project_id=str(self.kwargs.get("project_id", None)), current_instance=None, + epoch = int(timezone.now().timestamp()) ) return Response(status=status.HTTP_204_NO_CONTENT) @@ -1231,6 +1243,7 @@ class IssueArchiveViewSet(BaseViewSet): issue_id=str(issue.id), project_id=str(project_id), current_instance=None, + epoch = int(timezone.now().timestamp()) ) return Response(IssueSerializer(issue).data, status=status.HTTP_200_OK) @@ -1435,6 +1448,7 @@ class IssueReactionViewSet(BaseViewSet): issue_id=str(self.kwargs.get("issue_id", None)), project_id=str(self.kwargs.get("project_id", None)), current_instance=None, + epoch = int(timezone.now().timestamp()) ) def destroy(self, request, slug, project_id, issue_id, reaction_code): @@ -1458,6 +1472,7 @@ class IssueReactionViewSet(BaseViewSet): "identifier": str(issue_reaction.id), } ), + epoch = int(timezone.now().timestamp()) ) issue_reaction.delete() return Response(status=status.HTTP_204_NO_CONTENT) @@ -1506,6 +1521,7 @@ class CommentReactionViewSet(BaseViewSet): issue_id=None, project_id=str(self.kwargs.get("project_id", None)), current_instance=None, + epoch = int(timezone.now().timestamp()) ) def destroy(self, request, slug, project_id, comment_id, reaction_code): @@ -1530,6 +1546,7 @@ class CommentReactionViewSet(BaseViewSet): "comment_id": str(comment_id), } ), + epoch = int(timezone.now().timestamp()) ) comment_reaction.delete() return Response(status=status.HTTP_204_NO_CONTENT) @@ -1626,6 +1643,7 @@ class IssueCommentPublicViewSet(BaseViewSet): issue_id=str(issue_id), project_id=str(project_id), current_instance=None, + epoch = int(timezone.now().timestamp()) ) if not ProjectMember.objects.filter( project_id=project_id, @@ -1675,6 +1693,7 @@ class IssueCommentPublicViewSet(BaseViewSet): IssueCommentSerializer(comment).data, cls=DjangoJSONEncoder, ), + epoch = int(timezone.now().timestamp()) ) return Response(serializer.data, status=status.HTTP_200_OK) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @@ -1708,6 +1727,7 @@ class IssueCommentPublicViewSet(BaseViewSet): IssueCommentSerializer(comment).data, cls=DjangoJSONEncoder, ), + epoch = int(timezone.now().timestamp()) ) comment.delete() return Response(status=status.HTTP_204_NO_CONTENT) @@ -1782,6 +1802,7 @@ class IssueReactionPublicViewSet(BaseViewSet): issue_id=str(self.kwargs.get("issue_id", None)), project_id=str(self.kwargs.get("project_id", None)), current_instance=None, + epoch = int(timezone.now().timestamp()) ) return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @@ -1826,6 +1847,7 @@ class IssueReactionPublicViewSet(BaseViewSet): "identifier": str(issue_reaction.id), } ), + epoch = int(timezone.now().timestamp()) ) issue_reaction.delete() return Response(status=status.HTTP_204_NO_CONTENT) @@ -1899,6 +1921,7 @@ class CommentReactionPublicViewSet(BaseViewSet): issue_id=None, project_id=str(self.kwargs.get("project_id", None)), current_instance=None, + epoch = int(timezone.now().timestamp()) ) return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @@ -1950,6 +1973,7 @@ class CommentReactionPublicViewSet(BaseViewSet): "comment_id": str(comment_id), } ), + epoch = int(timezone.now().timestamp()) ) comment_reaction.delete() return Response(status=status.HTTP_204_NO_CONTENT) @@ -2013,6 +2037,7 @@ class IssueVotePublicViewSet(BaseViewSet): issue_id=str(self.kwargs.get("issue_id", None)), project_id=str(self.kwargs.get("project_id", None)), current_instance=None, + epoch = int(timezone.now().timestamp()) ) serializer = IssueVoteSerializer(issue_vote) return Response(serializer.data, status=status.HTTP_201_CREATED) @@ -2047,6 +2072,7 @@ class IssueVotePublicViewSet(BaseViewSet): "identifier": str(issue_vote.id), } ), + epoch = int(timezone.now().timestamp()) ) issue_vote.delete() return Response(status=status.HTTP_204_NO_CONTENT) @@ -2080,6 +2106,7 @@ class IssueRelationViewSet(BaseViewSet): IssueRelationSerializer(current_instance).data, cls=DjangoJSONEncoder, ), + epoch = int(timezone.now().timestamp()) ) return super().perform_destroy(instance) @@ -2113,6 +2140,7 @@ class IssueRelationViewSet(BaseViewSet): issue_id=str(issue_id), project_id=str(project_id), current_instance=None, + epoch = int(timezone.now().timestamp()) ) if relation == "blocking": @@ -2157,6 +2185,8 @@ class IssueRelationViewSet(BaseViewSet): .select_related("issue") .distinct() ) + + class IssueRetrievePublicEndpoint(BaseAPIView): permission_classes = [ AllowAny, @@ -2382,6 +2412,7 @@ class IssueDraftViewSet(BaseViewSet): current_instance=json.dumps( IssueSerializer(current_instance).data, cls=DjangoJSONEncoder ), + epoch = int(timezone.now().time()) ) return super().perform_update(serializer) @@ -2566,6 +2597,7 @@ class IssueDraftViewSet(BaseViewSet): issue_id=str(serializer.data.get("id", None)), project_id=str(project_id), current_instance=None, + epoch = int(timezone.now().timestamp()) ) return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) diff --git a/apiserver/plane/api/views/module.py b/apiserver/plane/api/views/module.py index 5a472945a..c2a15da1c 100644 --- a/apiserver/plane/api/views/module.py +++ b/apiserver/plane/api/views/module.py @@ -2,6 +2,7 @@ import json # Django Imports +from django.utils import timezone from django.db import IntegrityError from django.db.models import Prefetch, F, OuterRef, Func, Exists, Count, Q from django.core import serializers @@ -129,6 +130,7 @@ class ModuleViewSet(BaseViewSet): issue_id=str(self.kwargs.get("pk", None)), project_id=str(self.kwargs.get("project_id", None)), current_instance=None, + epoch = int(timezone.now().timestamp()) ) return super().perform_destroy(instance) @@ -277,6 +279,7 @@ class ModuleIssueViewSet(BaseViewSet): issue_id=str(self.kwargs.get("pk", None)), project_id=str(self.kwargs.get("project_id", None)), current_instance=None, + epoch = int(timezone.now().timestamp()) ) return super().perform_destroy(instance) @@ -444,6 +447,7 @@ class ModuleIssueViewSet(BaseViewSet): ), } ), + epoch = int(timezone.now().timestamp()) ) return Response( diff --git a/apiserver/plane/bgtasks/issue_activites_task.py b/apiserver/plane/bgtasks/issue_activites_task.py index 9d230dd2c..733defe69 100644 --- a/apiserver/plane/bgtasks/issue_activites_task.py +++ b/apiserver/plane/bgtasks/issue_activites_task.py @@ -39,6 +39,7 @@ def track_name( project, actor, issue_activities, + epoch ): if current_instance.get("name") != requested_data.get("name"): issue_activities.append( @@ -52,6 +53,7 @@ def track_name( project=project, workspace=project.workspace, comment=f"updated the name to {requested_data.get('name')}", + epoch=epoch, ) ) @@ -64,6 +66,7 @@ def track_parent( project, actor, issue_activities, + epoch ): if current_instance.get("parent") != requested_data.get("parent"): if requested_data.get("parent") == None: @@ -81,6 +84,7 @@ def track_parent( comment=f"updated the parent issue to None", old_identifier=old_parent.id, new_identifier=None, + epoch=epoch, ) ) else: @@ -101,6 +105,7 @@ def track_parent( comment=f"updated the parent issue to {new_parent.name}", old_identifier=old_parent.id if old_parent is not None else None, new_identifier=new_parent.id, + epoch=epoch, ) ) @@ -113,6 +118,7 @@ def track_priority( project, actor, issue_activities, + epoch ): if current_instance.get("priority") != requested_data.get("priority"): if requested_data.get("priority") == None: @@ -127,6 +133,7 @@ def track_priority( project=project, workspace=project.workspace, comment=f"updated the priority to None", + epoch=epoch, ) ) else: @@ -141,6 +148,7 @@ def track_priority( project=project, workspace=project.workspace, comment=f"updated the priority to {requested_data.get('priority')}", + epoch=epoch, ) ) @@ -153,6 +161,7 @@ def track_state( project, actor, issue_activities, + epoch ): if current_instance.get("state") != requested_data.get("state"): new_state = State.objects.get(pk=requested_data.get("state", None)) @@ -171,6 +180,7 @@ def track_state( comment=f"updated the state to {new_state.name}", old_identifier=old_state.id, new_identifier=new_state.id, + epoch=epoch, ) ) @@ -183,6 +193,7 @@ def track_description( project, actor, issue_activities, + epoch ): if current_instance.get("description_html") != requested_data.get( "description_html" @@ -203,6 +214,7 @@ def track_description( project=project, workspace=project.workspace, comment=f"updated the description to {requested_data.get('description_html')}", + epoch=epoch, ) ) @@ -215,6 +227,7 @@ def track_target_date( project, actor, issue_activities, + epoch ): if current_instance.get("target_date") != requested_data.get("target_date"): if requested_data.get("target_date") == None: @@ -229,6 +242,7 @@ def track_target_date( project=project, workspace=project.workspace, comment=f"updated the target date to None", + epoch=epoch, ) ) else: @@ -243,6 +257,7 @@ def track_target_date( project=project, workspace=project.workspace, comment=f"updated the target date to {requested_data.get('target_date')}", + epoch=epoch, ) ) @@ -255,6 +270,7 @@ def track_start_date( project, actor, issue_activities, + epoch ): if current_instance.get("start_date") != requested_data.get("start_date"): if requested_data.get("start_date") == None: @@ -269,6 +285,7 @@ def track_start_date( project=project, workspace=project.workspace, comment=f"updated the start date to None", + epoch=epoch, ) ) else: @@ -283,6 +300,7 @@ def track_start_date( project=project, workspace=project.workspace, comment=f"updated the start date to {requested_data.get('start_date')}", + epoch=epoch, ) ) @@ -295,6 +313,7 @@ def track_labels( project, actor, issue_activities, + epoch ): # Label Addition if len(requested_data.get("labels_list")) > len(current_instance.get("labels")): @@ -314,6 +333,7 @@ def track_labels( comment=f"added label {label.name}", new_identifier=label.id, old_identifier=None, + epoch=epoch, ) ) @@ -335,6 +355,7 @@ def track_labels( comment=f"removed label {label.name}", old_identifier=label.id, new_identifier=None, + epoch=epoch, ) ) @@ -347,6 +368,7 @@ def track_assignees( project, actor, issue_activities, + epoch ): # Assignee Addition if len(requested_data.get("assignees_list")) > len( @@ -367,6 +389,7 @@ def track_assignees( workspace=project.workspace, comment=f"added assignee {assignee.display_name}", new_identifier=assignee.id, + epoch=epoch, ) ) @@ -389,12 +412,13 @@ def track_assignees( workspace=project.workspace, comment=f"removed assignee {assignee.display_name}", old_identifier=assignee.id, + epoch=epoch, ) ) def create_issue_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): issue_activities.append( IssueActivity( @@ -404,12 +428,13 @@ def create_issue_activity( comment=f"created the issue", verb="created", actor=actor, + epoch=epoch, ) ) def track_estimate_points( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): if current_instance.get("estimate_point") != requested_data.get("estimate_point"): if requested_data.get("estimate_point") == None: @@ -424,6 +449,7 @@ def track_estimate_points( project=project, workspace=project.workspace, comment=f"updated the estimate point to None", + epoch=epoch, ) ) else: @@ -438,12 +464,13 @@ def track_estimate_points( project=project, workspace=project.workspace, comment=f"updated the estimate point to {requested_data.get('estimate_point')}", + epoch=epoch, ) ) def track_archive_at( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): if requested_data.get("archived_at") is None: issue_activities.append( @@ -457,6 +484,7 @@ def track_archive_at( field="archived_at", old_value="archive", new_value="restore", + epoch=epoch, ) ) else: @@ -471,12 +499,13 @@ def track_archive_at( field="archived_at", old_value=None, new_value="archive", + epoch=epoch, ) ) def track_closed_to( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): if requested_data.get("closed_to") is not None: updated_state = State.objects.get( @@ -496,12 +525,13 @@ def track_closed_to( comment=f"Plane updated the state to {updated_state.name}", old_identifier=None, new_identifier=updated_state.id, + epoch=epoch, ) ) def update_issue_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): ISSUE_ACTIVITY_MAPPER = { "name": track_name, @@ -533,11 +563,12 @@ def update_issue_activity( project, actor, issue_activities, + epoch ) def delete_issue_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): issue_activities.append( IssueActivity( @@ -547,12 +578,13 @@ def delete_issue_activity( verb="deleted", actor=actor, field="issue", + epoch=epoch, ) ) def create_comment_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): requested_data = json.loads(requested_data) if requested_data is not None else None current_instance = ( @@ -571,12 +603,13 @@ def create_comment_activity( new_value=requested_data.get("comment_html", ""), new_identifier=requested_data.get("id", None), issue_comment_id=requested_data.get("id", None), + epoch=epoch, ) ) def update_comment_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): requested_data = json.loads(requested_data) if requested_data is not None else None current_instance = ( @@ -598,12 +631,13 @@ def update_comment_activity( new_value=requested_data.get("comment_html", ""), new_identifier=current_instance.get("id", None), issue_comment_id=current_instance.get("id", None), + epoch=epoch, ) ) def delete_comment_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): issue_activities.append( IssueActivity( @@ -614,12 +648,13 @@ def delete_comment_activity( verb="deleted", actor=actor, field="comment", + epoch=epoch, ) ) def create_cycle_issue_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): requested_data = json.loads(requested_data) if requested_data is not None else None current_instance = ( @@ -651,6 +686,7 @@ def create_cycle_issue_activity( comment=f"updated cycle from {old_cycle.name} to {new_cycle.name}", old_identifier=old_cycle.id, new_identifier=new_cycle.id, + epoch=epoch, ) ) @@ -671,12 +707,13 @@ def create_cycle_issue_activity( workspace=project.workspace, comment=f"added cycle {cycle.name}", new_identifier=cycle.id, + epoch=epoch, ) ) def delete_cycle_issue_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): requested_data = json.loads(requested_data) if requested_data is not None else None current_instance = ( @@ -700,12 +737,13 @@ def delete_cycle_issue_activity( workspace=project.workspace, comment=f"removed this issue from {cycle.name if cycle is not None else None}", old_identifier=cycle.id if cycle is not None else None, + epoch=epoch, ) ) def create_module_issue_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): requested_data = json.loads(requested_data) if requested_data is not None else None current_instance = ( @@ -737,6 +775,7 @@ def create_module_issue_activity( comment=f"updated module from {old_module.name} to {new_module.name}", old_identifier=old_module.id, new_identifier=new_module.id, + epoch=epoch, ) ) @@ -756,12 +795,13 @@ def create_module_issue_activity( workspace=project.workspace, comment=f"added module {module.name}", new_identifier=module.id, + epoch=epoch, ) ) def delete_module_issue_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): requested_data = json.loads(requested_data) if requested_data is not None else None current_instance = ( @@ -785,12 +825,13 @@ def delete_module_issue_activity( workspace=project.workspace, comment=f"removed this issue from {module.name if module is not None else None}", old_identifier=module.id if module is not None else None, + epoch=epoch, ) ) def create_link_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): requested_data = json.loads(requested_data) if requested_data is not None else None current_instance = ( @@ -808,12 +849,13 @@ def create_link_activity( field="link", new_value=requested_data.get("url", ""), new_identifier=requested_data.get("id", None), + epoch=epoch, ) ) def update_link_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): requested_data = json.loads(requested_data) if requested_data is not None else None current_instance = ( @@ -834,12 +876,13 @@ def update_link_activity( old_identifier=current_instance.get("id"), new_value=requested_data.get("url", ""), new_identifier=current_instance.get("id", None), + epoch=epoch, ) ) def delete_link_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): current_instance = ( @@ -856,13 +899,14 @@ def delete_link_activity( actor=actor, field="link", old_value=current_instance.get("url", ""), - new_value="" + new_value="", + epoch=epoch, ) ) def create_attachment_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): requested_data = json.loads(requested_data) if requested_data is not None else None current_instance = ( @@ -880,12 +924,13 @@ def create_attachment_activity( field="attachment", new_value=current_instance.get("asset", ""), new_identifier=current_instance.get("id", None), + epoch=epoch, ) ) def delete_attachment_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): issue_activities.append( IssueActivity( @@ -896,11 +941,12 @@ def delete_attachment_activity( verb="deleted", actor=actor, field="attachment", + epoch=epoch, ) ) def create_issue_reaction_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): requested_data = json.loads(requested_data) if requested_data is not None else None if requested_data and requested_data.get("reaction") is not None: @@ -919,12 +965,13 @@ def create_issue_reaction_activity( comment="added the reaction", old_identifier=None, new_identifier=issue_reaction, + epoch=epoch, ) ) def delete_issue_reaction_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): current_instance = ( json.loads(current_instance) if current_instance is not None else None @@ -943,12 +990,13 @@ def delete_issue_reaction_activity( comment="removed the reaction", old_identifier=current_instance.get("identifier"), new_identifier=None, + epoch=epoch, ) ) def create_comment_reaction_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): requested_data = json.loads(requested_data) if requested_data is not None else None if requested_data and requested_data.get("reaction") is not None: @@ -968,12 +1016,13 @@ def create_comment_reaction_activity( comment="added the reaction", old_identifier=None, new_identifier=comment_reaction_id, + epoch=epoch, ) ) def delete_comment_reaction_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): current_instance = ( json.loads(current_instance) if current_instance is not None else None @@ -994,12 +1043,13 @@ def delete_comment_reaction_activity( comment="removed the reaction", old_identifier=current_instance.get("identifier"), new_identifier=None, + epoch=epoch, ) ) def create_issue_vote_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): requested_data = json.loads(requested_data) if requested_data is not None else None if requested_data and requested_data.get("vote") is not None: @@ -1016,12 +1066,13 @@ def create_issue_vote_activity( comment="added the vote", old_identifier=None, new_identifier=None, + epoch=epoch, ) ) def delete_issue_vote_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): current_instance = ( json.loads(current_instance) if current_instance is not None else None @@ -1040,12 +1091,13 @@ def delete_issue_vote_activity( comment="removed the vote", old_identifier=current_instance.get("identifier"), new_identifier=None, + epoch=epoch, ) ) def create_issue_relation_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): requested_data = json.loads(requested_data) if requested_data is not None else None current_instance = ( @@ -1085,12 +1137,13 @@ def create_issue_relation_activity( workspace=project.workspace, comment=f'added {issue_relation.get("relation_type")} relation', old_identifier=issue_relation.get("related_issue"), + epoch=epoch, ) ) def delete_issue_relation_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): requested_data = json.loads(requested_data) if requested_data is not None else None current_instance = ( @@ -1114,6 +1167,7 @@ def delete_issue_relation_activity( workspace=project.workspace, comment=f'deleted {relation_type} relation', old_identifier=current_instance.get("issue"), + epoch=epoch, ) ) issue = Issue.objects.get(pk=current_instance.get("related_issue")) @@ -1129,12 +1183,13 @@ def delete_issue_relation_activity( workspace=project.workspace, comment=f'deleted {current_instance.get("relation_type")} relation', old_identifier=current_instance.get("related_issue"), + epoch=epoch, ) ) def create_draft_issue_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): issue_activities.append( IssueActivity( @@ -1145,12 +1200,13 @@ def create_draft_issue_activity( field="draft", verb="created", actor=actor, + epoch=epoch, ) ) def update_draft_issue_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): requested_data = json.loads(requested_data) if requested_data is not None else None current_instance = ( @@ -1165,6 +1221,7 @@ def update_draft_issue_activity( comment=f"created the issue", verb="updated", actor=actor, + epoch=epoch, ) ) else: @@ -1177,13 +1234,14 @@ def update_draft_issue_activity( field="draft", verb="updated", actor=actor, + epoch=epoch, ) ) def delete_draft_issue_activity( - requested_data, current_instance, issue_id, project, actor, issue_activities + requested_data, current_instance, issue_id, project, actor, issue_activities, epoch ): issue_activities.append( IssueActivity( @@ -1193,6 +1251,7 @@ def delete_draft_issue_activity( field="draft", verb="deleted", actor=actor, + epoch=epoch, ) ) @@ -1205,6 +1264,7 @@ def issue_activity( issue_id, actor_id, project_id, + epoch, subscriber=True, ): try: @@ -1281,6 +1341,7 @@ def issue_activity( project, actor, issue_activities, + epoch, ) # Save all the values to database diff --git a/apiserver/plane/bgtasks/issue_automation_task.py b/apiserver/plane/bgtasks/issue_automation_task.py index 645772c94..f7b06c625 100644 --- a/apiserver/plane/bgtasks/issue_automation_task.py +++ b/apiserver/plane/bgtasks/issue_automation_task.py @@ -77,6 +77,7 @@ def archive_old_issues(): project_id=project_id, current_instance=None, subscriber=False, + epoch = int(timezone.now().timestamp()) ) for issue in updated_issues ] @@ -148,6 +149,7 @@ def close_old_issues(): project_id=project_id, current_instance=None, subscriber=False, + epoch = int(timezone.now().timestamp()) ) for issue in updated_issues ] diff --git a/apiserver/plane/db/migrations/0045_issueactivity_epoch_alter_analyticview_created_by_and_more.py b/apiserver/plane/db/migrations/0045_issueactivity_epoch_alter_analyticview_created_by_and_more.py new file mode 100644 index 000000000..0d2cca641 --- /dev/null +++ b/apiserver/plane/db/migrations/0045_issueactivity_epoch_alter_analyticview_created_by_and_more.py @@ -0,0 +1,27 @@ +# Generated by Django 4.2.3 on 2023-09-14 06:49 + +from django.db import migrations, models + +def update_epoch(apps, schema_editor): + IssueActivity = apps.get_model('db', 'IssueActivity') + updated_issue_activity = [] + for obj in IssueActivity.objects.all(): + obj.epoch = int(obj.created_at.timestamp()) + updated_issue_activity.append(obj) + IssueActivity.objects.bulk_update(updated_issue_activity, ["epoch"], batch_size=100) + + +class Migration(migrations.Migration): + + dependencies = [ + ('db', '0044_auto_20230913_0709'), + ] + + operations = [ + migrations.AddField( + model_name='issueactivity', + name='epoch', + field=models.FloatField(null=True), + ), + migrations.RunPython(update_epoch), + ] diff --git a/apiserver/plane/db/models/issue.py b/apiserver/plane/db/models/issue.py index 65f1bc965..3ba054d49 100644 --- a/apiserver/plane/db/models/issue.py +++ b/apiserver/plane/db/models/issue.py @@ -309,6 +309,7 @@ class IssueActivity(ProjectBaseModel): ) old_identifier = models.UUIDField(null=True) new_identifier = models.UUIDField(null=True) + epoch = models.FloatField(null=True) class Meta: verbose_name = "Issue Activity"