forked from github/plane
[WEB-987] fix: inbox issue activity (#4208)
* chore: inbox issue activity * chore: dummy data script * chore: inbox issue activity implementation --------- Co-authored-by: Anmol Singh Bhatia <anmolsinghbhatia@plane.so>
This commit is contained in:
parent
f0cb48006f
commit
bf9049a7a2
@ -272,6 +272,9 @@ class InboxIssueAPIEndpoint(BaseAPIView):
|
||||
serializer = InboxIssueSerializer(
|
||||
inbox_issue, data=request.data, partial=True
|
||||
)
|
||||
current_instance = json.dumps(
|
||||
InboxIssueSerializer(inbox_issue).data, cls=DjangoJSONEncoder
|
||||
)
|
||||
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
@ -311,6 +314,21 @@ class InboxIssueAPIEndpoint(BaseAPIView):
|
||||
issue.state = state
|
||||
issue.save()
|
||||
|
||||
# create a activity for status change
|
||||
issue_activity.delay(
|
||||
type="inbox.activity.created",
|
||||
requested_data=json.dumps(
|
||||
request.data, cls=DjangoJSONEncoder
|
||||
),
|
||||
actor_id=str(request.user.id),
|
||||
issue_id=str(issue_id),
|
||||
project_id=str(project_id),
|
||||
current_instance=current_instance,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=False,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
)
|
||||
|
||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||
return Response(
|
||||
serializer.errors, status=status.HTTP_400_BAD_REQUEST
|
||||
|
@ -391,7 +391,9 @@ class InboxIssueViewSet(BaseViewSet):
|
||||
serializer = InboxIssueSerializer(
|
||||
inbox_issue, data=request.data, partial=True
|
||||
)
|
||||
|
||||
current_instance = json.dumps(
|
||||
InboxIssueSerializer(inbox_issue).data, cls=DjangoJSONEncoder
|
||||
)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
# Update the issue state if the issue is rejected or marked as duplicate
|
||||
@ -429,6 +431,21 @@ class InboxIssueViewSet(BaseViewSet):
|
||||
if state is not None:
|
||||
issue.state = state
|
||||
issue.save()
|
||||
# create a activity for status change
|
||||
issue_activity.delay(
|
||||
type="inbox.activity.created",
|
||||
requested_data=json.dumps(
|
||||
request.data, cls=DjangoJSONEncoder
|
||||
),
|
||||
actor_id=str(request.user.id),
|
||||
issue_id=str(issue_id),
|
||||
project_id=str(project_id),
|
||||
current_instance=current_instance,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=False,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
)
|
||||
|
||||
inbox_issue = (
|
||||
InboxIssue.objects.filter(
|
||||
inbox_id=inbox_id.id,
|
||||
|
@ -1,4 +1,5 @@
|
||||
# Python imports
|
||||
import uuid
|
||||
import random
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
@ -36,9 +37,11 @@ from plane.db.models import (
|
||||
def create_project(workspace, user_id):
|
||||
fake = Faker()
|
||||
name = fake.name()
|
||||
unique_id = str(uuid.uuid4())[:5]
|
||||
|
||||
project = Project.objects.create(
|
||||
workspace=workspace,
|
||||
name=name,
|
||||
name=f"{name}_{unique_id}",
|
||||
identifier=name[
|
||||
: random.randint(2, 12 if len(name) - 1 >= 12 else len(name) - 1)
|
||||
].upper(),
|
||||
|
@ -1553,6 +1553,46 @@ def delete_draft_issue_activity(
|
||||
)
|
||||
|
||||
|
||||
def create_inbox_activity(
|
||||
requested_data,
|
||||
current_instance,
|
||||
issue_id,
|
||||
project_id,
|
||||
workspace_id,
|
||||
actor_id,
|
||||
issue_activities,
|
||||
epoch,
|
||||
):
|
||||
requested_data = (
|
||||
json.loads(requested_data) if requested_data is not None else None
|
||||
)
|
||||
current_instance = (
|
||||
json.loads(current_instance) if current_instance is not None else None
|
||||
)
|
||||
status_dict = {
|
||||
-2: "Pending",
|
||||
-1: "Rejected",
|
||||
0: "Snoozed",
|
||||
1: "Accepted",
|
||||
2: "Duplicate",
|
||||
}
|
||||
if requested_data.get("status") is not None:
|
||||
issue_activities.append(
|
||||
IssueActivity(
|
||||
issue_id=issue_id,
|
||||
project_id=project_id,
|
||||
workspace_id=workspace_id,
|
||||
comment="updated the inbox status",
|
||||
field="inbox",
|
||||
verb=requested_data.get("status"),
|
||||
actor_id=actor_id,
|
||||
epoch=epoch,
|
||||
old_value=status_dict.get(current_instance.get("status")),
|
||||
new_value=status_dict.get(requested_data.get("status")),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
# Receive message from room group
|
||||
@shared_task
|
||||
def issue_activity(
|
||||
@ -1613,6 +1653,7 @@ def issue_activity(
|
||||
"issue_draft.activity.created": create_draft_issue_activity,
|
||||
"issue_draft.activity.updated": update_draft_issue_activity,
|
||||
"issue_draft.activity.deleted": delete_draft_issue_activity,
|
||||
"inbox.activity.created": create_inbox_activity,
|
||||
}
|
||||
|
||||
func = ACTIVITY_MAPPER.get(type)
|
||||
|
@ -0,0 +1,42 @@
|
||||
import { FC } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
// hooks
|
||||
import { Inbox } from "lucide-react";
|
||||
import { useIssueDetail } from "@/hooks/store";
|
||||
// components
|
||||
import { IssueActivityBlockComponent } from "./";
|
||||
// icons
|
||||
|
||||
type TIssueInboxActivity = { activityId: string; ends: "top" | "bottom" | undefined };
|
||||
|
||||
export const IssueInboxActivity: FC<TIssueInboxActivity> = observer((props) => {
|
||||
const { activityId, ends } = props;
|
||||
// hooks
|
||||
const {
|
||||
activity: { getActivityById },
|
||||
} = useIssueDetail();
|
||||
|
||||
const activity = getActivityById(activityId);
|
||||
|
||||
const getInboxActivityMessage = () => {
|
||||
switch (activity?.verb) {
|
||||
case "-1":
|
||||
return "declined this issue from inbox.";
|
||||
case "0":
|
||||
return "snoozed this issue.";
|
||||
case "1":
|
||||
return "accepted this issue from inbox.";
|
||||
case "2":
|
||||
return "declined this issue from inbox by marking a duplicate issue.";
|
||||
default:
|
||||
return "updated inbox issue status.";
|
||||
}
|
||||
};
|
||||
|
||||
if (!activity) return <></>;
|
||||
return (
|
||||
<IssueActivityBlockComponent icon={<Inbox className="h-4 w-4 flex-shrink-0" />} activityId={activityId} ends={ends}>
|
||||
<>{getInboxActivityMessage()}</>
|
||||
</IssueActivityBlockComponent>
|
||||
);
|
||||
});
|
@ -15,6 +15,7 @@ export * from "./label";
|
||||
export * from "./link";
|
||||
export * from "./attachment";
|
||||
export * from "./archived-at";
|
||||
export * from "./inbox";
|
||||
|
||||
// helpers
|
||||
export * from "./helpers/activity-block";
|
||||
|
@ -21,6 +21,7 @@ import {
|
||||
IssueLinkActivity,
|
||||
IssueAttachmentActivity,
|
||||
IssueArchivedAtActivity,
|
||||
IssueInboxActivity,
|
||||
} from "./actions";
|
||||
|
||||
type TIssueActivityList = {
|
||||
@ -74,6 +75,8 @@ export const IssueActivityList: FC<TIssueActivityList> = observer((props) => {
|
||||
return <IssueAttachmentActivity {...componentDefaultProps} showIssue={false} />;
|
||||
case "archived_at":
|
||||
return <IssueArchivedAtActivity {...componentDefaultProps} />;
|
||||
case "inbox":
|
||||
return <IssueInboxActivity {...componentDefaultProps} />;
|
||||
default:
|
||||
return <></>;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user