= (props) => {
const createdByDetails = getUserDetails(linkDetail.created_by_id);
+ const handleOnClose = () => {
+ toggleIssueLinkModal(false);
+ };
+
return (
diff --git a/web/core/components/issues/issue-detail/links/link-item.tsx b/web/core/components/issues/issue-detail/links/link-item.tsx
index ef2de8ed92..256ccb7255 100644
--- a/web/core/components/issues/issue-detail/links/link-item.tsx
+++ b/web/core/components/issues/issue-detail/links/link-item.tsx
@@ -37,11 +37,14 @@ export const IssueLinkItem: FC = (props) => {
const linkDetail = getLinkById(linkId);
if (!linkDetail) return <>>;
+ const handleOnClose = () => {
+ toggleIssueLinkModal(false);
+ };
return (
<>
diff --git a/web/core/components/issues/issue-detail/links/root.tsx b/web/core/components/issues/issue-detail/links/root.tsx
index 1450bb4ce0..7b1908c35a 100644
--- a/web/core/components/issues/issue-detail/links/root.tsx
+++ b/web/core/components/issues/issue-detail/links/root.tsx
@@ -100,11 +100,15 @@ export const IssueLinkRoot: FC = (props) => {
[workspaceSlug, projectId, issueId, createLink, updateLink, removeLink, toggleIssueLinkModal]
);
+ const handleOnClose = () => {
+ toggleIssueLinkModal(false);
+ };
+
return (
<>
diff --git a/web/core/store/issue/issue-details/root.store.ts b/web/core/store/issue/issue-details/root.store.ts
index 8f6e7fd46b..f6dcdd931c 100644
--- a/web/core/store/issue/issue-details/root.store.ts
+++ b/web/core/store/issue/issue-details/root.store.ts
@@ -8,6 +8,7 @@ import {
TIssueLink,
TIssueReaction,
TIssueRelationTypes,
+ TIssueDetailWidget,
} from "@plane/types";
import { IIssueRootStore } from "../root.store";
import { IIssueActivityStore, IssueActivityStore, IIssueActivityStoreActions, TActivityLoader } from "./activity.store";
@@ -50,6 +51,8 @@ export interface IIssueDetail
IIssueCommentReactionStoreActions {
// observables
peekIssue: TPeekIssue | undefined;
+ activeIssueDetailWidgets: TIssueDetailWidget[];
+ lastWidgetAction: TIssueDetailWidget | null;
isCreateIssueModalOpen: boolean;
isIssueLinkModalOpen: boolean;
isParentIssueModalOpen: string | null;
@@ -72,6 +75,9 @@ export interface IIssueDetail
toggleRelationModal: (issueId: string | null, relationType: TIssueRelationTypes | null) => void;
toggleSubIssuesModal: (value: string | null) => void;
toggleDeleteAttachmentModal: (attachmentId: string | null) => void;
+ setActiveIssueDetailWidgets: (state: TIssueDetailWidget[]) => void;
+ setLastWidgetAction: (action: TIssueDetailWidget) => void;
+ toggleActiveIssueDetailWidget: (state: TIssueDetailWidget) => void;
// store
rootIssueStore: IIssueRootStore;
issue: IIssueStore;
@@ -89,6 +95,8 @@ export interface IIssueDetail
export class IssueDetail implements IIssueDetail {
// observables
peekIssue: TPeekIssue | undefined = undefined;
+ activeIssueDetailWidgets: TIssueDetailWidget[] = ["sub-issues"];
+ lastWidgetAction: TIssueDetailWidget | null = null;
isCreateIssueModalOpen: boolean = false;
isIssueLinkModalOpen: boolean = false;
isParentIssueModalOpen: string | null = null;
@@ -122,6 +130,8 @@ export class IssueDetail implements IIssueDetail {
isRelationModalOpen: observable.ref,
isSubIssuesModalOpen: observable.ref,
attachmentDeleteModalId: observable.ref,
+ activeIssueDetailWidgets: observable.ref,
+ lastWidgetAction: observable.ref,
// computed
isAnyModalOpen: computed,
// action
@@ -134,6 +144,9 @@ export class IssueDetail implements IIssueDetail {
toggleRelationModal: action,
toggleSubIssuesModal: action,
toggleDeleteAttachmentModal: action,
+ setActiveIssueDetailWidgets: action,
+ setLastWidgetAction: action,
+ toggleActiveIssueDetailWidget: action,
});
// store
@@ -178,6 +191,18 @@ export class IssueDetail implements IIssueDetail {
(this.isRelationModalOpen = { issueId, relationType });
toggleSubIssuesModal = (issueId: string | null) => (this.isSubIssuesModalOpen = issueId);
toggleDeleteAttachmentModal = (attachmentId: string | null) => (this.attachmentDeleteModalId = attachmentId);
+ setActiveIssueDetailWidgets = (state: TIssueDetailWidget[]) => {
+ this.activeIssueDetailWidgets = state;
+ if (this.lastWidgetAction) this.lastWidgetAction = null;
+ };
+ setLastWidgetAction = (action: TIssueDetailWidget) => {
+ this.activeIssueDetailWidgets = [action];
+ };
+ toggleActiveIssueDetailWidget = (state: TIssueDetailWidget) => {
+ if (this.activeIssueDetailWidgets && this.activeIssueDetailWidgets.includes(state))
+ this.activeIssueDetailWidgets = this.activeIssueDetailWidgets.filter((s) => s !== state);
+ else this.activeIssueDetailWidgets = [state, ...this.activeIssueDetailWidgets];
+ };
// issue
fetchIssue = async (
From 24973c1386335070462486cc07ec844571901418 Mon Sep 17 00:00:00 2001
From: Bavisetti Narayan <72156168+NarayanBavisetti@users.noreply.github.com>
Date: Thu, 11 Jul 2024 14:43:02 +0530
Subject: [PATCH 8/8] [WEB-1909] chore: removed duplication of assignee and
label activity (#5095)
* chore: removed duplication of assignee and label activity
* chore: removed the print statement
* chore: updated the queryset
---
apiserver/plane/app/views/issue/base.py | 33 ++++++++++++++++++++++++-
1 file changed, 32 insertions(+), 1 deletion(-)
diff --git a/apiserver/plane/app/views/issue/base.py b/apiserver/plane/app/views/issue/base.py
index e7b12a528d..c6bdcafe0d 100644
--- a/apiserver/plane/app/views/issue/base.py
+++ b/apiserver/plane/app/views/issue/base.py
@@ -481,7 +481,38 @@ class IssueViewSet(BaseViewSet):
return Response(serializer.data, status=status.HTTP_200_OK)
def partial_update(self, request, slug, project_id, pk=None):
- issue = self.get_queryset().filter(pk=pk).first()
+ issue = (
+ self.get_queryset()
+ .annotate(
+ label_ids=Coalesce(
+ ArrayAgg(
+ "labels__id",
+ distinct=True,
+ filter=~Q(labels__id__isnull=True),
+ ),
+ Value([], output_field=ArrayField(UUIDField())),
+ ),
+ assignee_ids=Coalesce(
+ ArrayAgg(
+ "assignees__id",
+ distinct=True,
+ filter=~Q(assignees__id__isnull=True)
+ & Q(assignees__member_project__is_active=True),
+ ),
+ Value([], output_field=ArrayField(UUIDField())),
+ ),
+ module_ids=Coalesce(
+ ArrayAgg(
+ "issue_module__module_id",
+ distinct=True,
+ filter=~Q(issue_module__module_id__isnull=True),
+ ),
+ Value([], output_field=ArrayField(UUIDField())),
+ ),
+ )
+ .filter(pk=pk)
+ .first()
+ )
if not issue:
return Response(