diff --git a/apiserver/plane/api/serializers/issue.py b/apiserver/plane/api/serializers/issue.py index ecbb1ca46b7..770880ef035 100644 --- a/apiserver/plane/api/serializers/issue.py +++ b/apiserver/plane/api/serializers/issue.py @@ -291,7 +291,8 @@ def update(self, instance, validated_data): class IssueActivitySerializer(BaseSerializer): actor_detail = UserLiteSerializer(read_only=True, source="actor") - workspace_detail = WorkspaceLiteSerializer(read_only=True, source="workspace") + issue_detail = IssueFlatSerializer(read_only=True, source="issue") + project_detail = ProjectLiteSerializer(read_only=True, source="project") class Meta: model = IssueActivity diff --git a/apiserver/plane/api/views/issue.py b/apiserver/plane/api/views/issue.py index 38d90ecf9fa..9369ccf2b35 100644 --- a/apiserver/plane/api/views/issue.py +++ b/apiserver/plane/api/views/issue.py @@ -477,7 +477,7 @@ def get(self, request, slug, project_id, issue_id): ~Q(field="comment"), project__project_projectmember__member=self.request.user, ) - .select_related("actor", "workspace") + .select_related("actor", "workspace", "issue", "project") ).order_by("created_at") issue_comments = ( IssueComment.objects.filter(issue_id=issue_id) diff --git a/apiserver/plane/api/views/people.py b/apiserver/plane/api/views/people.py index 705f5c96e00..84ee47e4258 100644 --- a/apiserver/plane/api/views/people.py +++ b/apiserver/plane/api/views/people.py @@ -140,7 +140,7 @@ class UserActivityEndpoint(BaseAPIView, BasePaginator): def get(self, request): try: queryset = IssueActivity.objects.filter(actor=request.user).select_related( - "actor", "workspace" + "actor", "workspace", "issue", "project" ) return self.paginate( diff --git a/apiserver/plane/api/views/project.py b/apiserver/plane/api/views/project.py index dfeab07cc0a..0589f4a6180 100644 --- a/apiserver/plane/api/views/project.py +++ b/apiserver/plane/api/views/project.py @@ -267,7 +267,7 @@ def create(self, request, slug): status=status.HTTP_410_GONE, ) except Exception as e: - pr(e) + capture_exception(e) return Response( {"error": "Something went wrong please try again later"}, status=status.HTTP_400_BAD_REQUEST, diff --git a/apiserver/plane/api/views/workspace.py b/apiserver/plane/api/views/workspace.py index 51db47c3dde..b195cedb1ef 100644 --- a/apiserver/plane/api/views/workspace.py +++ b/apiserver/plane/api/views/workspace.py @@ -1190,7 +1190,7 @@ def get(self, request, slug, user_id): workspace__slug=slug, project__project_projectmember__member=request.user, actor=user_id, - ).select_related("actor", "workspace") + ).select_related("actor", "workspace", "issue", "project") if projects: queryset = queryset.filter(project__in=projects) diff --git a/apiserver/plane/db/migrations/0040_projectmember_preferences_user_cover_image_and_more.py b/apiserver/plane/db/migrations/0040_projectmember_preferences_user_cover_image_and_more.py index b7ca6550078..5662ef666af 100644 --- a/apiserver/plane/db/migrations/0040_projectmember_preferences_user_cover_image_and_more.py +++ b/apiserver/plane/db/migrations/0040_projectmember_preferences_user_cover_image_and_more.py @@ -67,5 +67,15 @@ class Migration(migrations.Migration): 'ordering': ('-created_at',), 'unique_together': {('comment', 'actor', 'reaction')}, }, + ), + migrations.AlterField( + model_name='project', + name='identifier', + field=models.CharField(max_length=12, verbose_name='Project Identifier'), + ), + migrations.AlterField( + model_name='projectidentifier', + name='name', + field=models.CharField(max_length=12), ), ] diff --git a/apps/app/helpers/activity.helper.tsx b/apps/app/components/core/activity.tsx similarity index 62% rename from apps/app/helpers/activity.helper.tsx rename to apps/app/components/core/activity.tsx index af5d9bf1267..f7622baa6d2 100644 --- a/apps/app/helpers/activity.helper.tsx +++ b/apps/app/components/core/activity.tsx @@ -1,5 +1,7 @@ +import { useRouter } from "next/router"; + // icons -import { Icon } from "components/ui"; +import { Icon, Tooltip } from "components/ui"; import { Squares2X2Icon } from "@heroicons/react/24/outline"; import { BlockedIcon, BlockerIcon } from "components/icons"; // helpers @@ -8,26 +10,65 @@ import { capitalizeFirstLetter } from "helpers/string.helper"; // types import { IIssueActivity } from "types"; -export const activityDetails: { +const IssueLink = ({ activity }: { activity: IIssueActivity }) => { + const router = useRouter(); + const { workspaceSlug } = router.query; + + return ( + + + {activity.issue_detail + ? `${activity.project_detail.identifier}-${activity.issue_detail.sequence_id}` + : "Issue"} + + + + ); +}; + +const activityDetails: { [key: string]: { - message: (activity: IIssueActivity) => React.ReactNode; + message: (activity: IIssueActivity, showIssue: boolean) => React.ReactNode; icon: React.ReactNode; }; } = { assignees: { - message: (activity) => { + message: (activity, showIssue) => { if (activity.old_value === "") return ( <> added a new assignee{" "} - {activity.new_value}. + {activity.new_value} + {showIssue && ( + <> + {" "} + to + + )} + . ); else return ( <> removed the assignee{" "} - {activity.old_value}. + {activity.old_value} + {showIssue && ( + <> + {" "} + from + + )} + . ); }, @@ -41,7 +82,7 @@ export const activityDetails: { icon: