[WEB-4117] refactor: work item widgets code split (#7078)

* refactor: work item widget code split

* fix: types
This commit is contained in:
Aaryan Khandelwal
2025-05-19 15:20:40 +05:30
committed by GitHub
parent 2a2feaf88e
commit 2d475491e9
12 changed files with 88 additions and 41 deletions

View File

@@ -119,7 +119,7 @@ export type TBulkOperationsPayload = {
properties: Partial<TBulkIssueProperties>;
};
export type TIssueDetailWidget = "sub-issues" | "relations" | "links" | "attachments";
export type TWorkItemWidgets = "sub-work-items" | "relations" | "links" | "attachments";
export type TIssueServiceType = EIssueServiceType.ISSUES | EIssueServiceType.EPICS | EIssueServiceType.WORK_ITEMS;

View File

@@ -0,0 +1,14 @@
import { FC } from "react";
// plane types
import { TIssueServiceType, TWorkItemWidgets } from "@plane/types";
export type TWorkItemAdditionalWidgetActionButtonsProps = {
disabled: boolean;
hideWidgets: TWorkItemWidgets[];
issueServiceType: TIssueServiceType;
projectId: string;
workItemId: string;
workspaceSlug: string;
};
export const WorkItemAdditionalWidgetActionButtons: FC<TWorkItemAdditionalWidgetActionButtonsProps> = () => null;

View File

@@ -1,10 +0,0 @@
import { FC } from "react";
export type TWorkItemAdditionalWidgets = {
workspaceSlug: string;
projectId: string;
workItemId: string;
disabled: boolean;
};
export const WorkItemAdditionalWidgets: FC<TWorkItemAdditionalWidgets> = (props) => <></>;

View File

@@ -0,0 +1,14 @@
import { FC } from "react";
// plane types
import { TIssueServiceType, TWorkItemWidgets } from "@plane/types";
export type TWorkItemAdditionalWidgetCollapsiblesProps = {
disabled: boolean;
hideWidgets: TWorkItemWidgets[];
issueServiceType: TIssueServiceType;
projectId: string;
workItemId: string;
workspaceSlug: string;
};
export const WorkItemAdditionalWidgetCollapsibles: FC<TWorkItemAdditionalWidgetCollapsiblesProps> = () => null;

View File

@@ -1 +0,0 @@
export * from "./additional-widgets";

View File

@@ -0,0 +1,13 @@
import { FC } from "react";
// plane types
import { TIssueServiceType, TWorkItemWidgets } from "@plane/types";
export type TWorkItemAdditionalWidgetModalsProps = {
hideWidgets: TWorkItemWidgets[];
issueServiceType: TIssueServiceType;
projectId: string;
workItemId: string;
workspaceSlug: string;
};
export const WorkItemAdditionalWidgetModals: FC<TWorkItemAdditionalWidgetModalsProps> = () => null;

View File

@@ -4,7 +4,7 @@ import React, { FC } from "react";
import { Layers, Link, Paperclip, Waypoints } from "lucide-react";
// plane imports
import { useTranslation } from "@plane/i18n";
import { TIssueServiceType } from "@plane/types";
import { TIssueServiceType, TWorkItemWidgets } from "@plane/types";
// components
import {
IssueAttachmentActionButton,
@@ -12,8 +12,9 @@ import {
RelationActionButton,
SubIssuesActionButton,
IssueDetailWidgetButton,
TWorkItemWidgets,
} from "@/components/issues/issue-detail-widgets";
// plane web imports
import { WorkItemAdditionalWidgetActionButtons } from "@/plane-web/components/issues/issue-detail-widgets/action-buttons";
type Props = {
workspaceSlug: string;
@@ -88,6 +89,14 @@ export const IssueDetailWidgetActionButtons: FC<Props> = (props) => {
issueServiceType={issueServiceType}
/>
)}
<WorkItemAdditionalWidgetActionButtons
disabled={disabled}
hideWidgets={hideWidgets ?? []}
issueServiceType={issueServiceType}
projectId={projectId}
workItemId={issueId}
workspaceSlug={workspaceSlug}
/>
</div>
);
};

View File

@@ -2,19 +2,18 @@
import React, { FC } from "react";
import { observer } from "mobx-react";
// plane imports
import { TIssueServiceType } from "@plane/types";
import { TIssueServiceType, TWorkItemWidgets } from "@plane/types";
// components
import {
AttachmentsCollapsible,
LinksCollapsible,
RelationsCollapsible,
SubIssuesCollapsible,
TWorkItemWidgets,
} from "@/components/issues/issue-detail-widgets";
// hooks
import { useIssueDetail } from "@/hooks/store";
// Plane-web
import { WorkItemAdditionalWidgets } from "@/plane-web/components/issues/issue-detail-widgets";
import { WorkItemAdditionalWidgetCollapsibles } from "@/plane-web/components/issues/issue-detail-widgets/collapsibles";
import { useTimeLineRelationOptions } from "@/plane-web/components/relations";
type Props = {
@@ -87,11 +86,13 @@ export const IssueDetailWidgetCollapsibles: FC<Props> = observer((props) => {
issueServiceType={issueServiceType}
/>
)}
<WorkItemAdditionalWidgets
workspaceSlug={workspaceSlug}
<WorkItemAdditionalWidgetCollapsibles
disabled={disabled}
hideWidgets={hideWidgets ?? []}
issueServiceType={issueServiceType}
projectId={projectId}
workItemId={issueId}
disabled={disabled}
workspaceSlug={workspaceSlug}
/>
</div>
);

View File

@@ -1,18 +1,19 @@
import React, { FC } from "react";
import { observer } from "mobx-react";
import { ISearchIssueResponse, TIssue, TIssueServiceType } from "@plane/types";
import { ISearchIssueResponse, TIssue, TIssueServiceType, TWorkItemWidgets } from "@plane/types";
import { setToast, TOAST_TYPE } from "@plane/ui";
// components
import { ExistingIssuesListModal } from "@/components/core";
import { CreateUpdateIssueModal } from "@/components/issues/issue-modal";
// hooks
import { useIssueDetail } from "@/hooks/store";
// plane web imports
import { WorkItemAdditionalWidgetModals } from "@/plane-web/components/issues/issue-detail-widgets/modals";
// local imports
import { IssueLinkCreateUpdateModal } from "../issue-detail/links/create-update-link-modal";
// helpers
import { useLinkOperations } from "./links/helper";
import { useSubIssueOperations } from "./sub-issues/helper";
import { TWorkItemWidgets } from ".";
type Props = {
workspaceSlug: string;
@@ -65,7 +66,7 @@ export const IssueDetailWidgetModals: FC<Props> = observer((props) => {
const handleExistingIssuesModalClose = () => {
handleIssueCrudState("existing", null, null);
setLastWidgetAction("sub-issues");
setLastWidgetAction("sub-work-items");
toggleSubIssuesModal(null);
};
@@ -80,7 +81,7 @@ export const IssueDetailWidgetModals: FC<Props> = observer((props) => {
const handleCreateUpdateModalClose = () => {
handleIssueCrudState("create", null, null);
toggleCreateIssueModal(false);
setLastWidgetAction("sub-issues");
setLastWidgetAction("sub-work-items");
};
const handleCreateUpdateModalOnSubmit = async (_issue: TIssue) => {
@@ -190,6 +191,14 @@ export const IssueDetailWidgetModals: FC<Props> = observer((props) => {
workspaceLevelToggle
/>
)}
<WorkItemAdditionalWidgetModals
hideWidgets={hideWidgets ?? []}
issueServiceType={issueServiceType}
projectId={projectId}
workItemId={issueId}
workspaceSlug={workspaceSlug}
/>
</>
);
});

View File

@@ -2,7 +2,7 @@
import React, { FC } from "react";
// plane imports
import { TIssueServiceType } from "@plane/types";
import { TIssueServiceType, TWorkItemWidgets } from "@plane/types";
// components
import {
IssueDetailWidgetActionButtons,
@@ -10,8 +10,6 @@ import {
IssueDetailWidgetModals,
} from "@/components/issues/issue-detail-widgets";
export type TWorkItemWidgets = "sub-work-items" | "relations" | "links" | "attachments";
type Props = {
workspaceSlug: string;
projectId: string;

View File

@@ -22,12 +22,12 @@ export const SubIssuesCollapsible: FC<Props> = observer((props) => {
// store hooks
const { openWidgets, toggleOpenWidget } = useIssueDetail(issueServiceType);
// derived values
const isCollapsibleOpen = openWidgets.includes("sub-issues");
const isCollapsibleOpen = openWidgets.includes("sub-work-items");
return (
<Collapsible
isOpen={isCollapsibleOpen}
onToggle={() => toggleOpenWidget("sub-issues")}
onToggle={() => toggleOpenWidget("sub-work-items")}
title={
<SubIssuesCollapsibleTitle
isOpen={isCollapsibleOpen}

View File

@@ -7,8 +7,8 @@ import {
TIssueCommentReaction,
TIssueLink,
TIssueReaction,
TIssueDetailWidget,
TIssueServiceType,
TWorkItemWidgets,
} from "@plane/types";
// plane web store
import {
@@ -70,8 +70,8 @@ export interface IIssueDetail
relationKey: TIssueRelationTypes | null;
issueLinkData: TIssueLink | null;
issueCrudOperationState: TIssueCrudOperationState;
openWidgets: TIssueDetailWidget[];
lastWidgetAction: TIssueDetailWidget | null;
openWidgets: TWorkItemWidgets[];
lastWidgetAction: TWorkItemWidgets | null;
isCreateIssueModalOpen: boolean;
isIssueLinkModalOpen: boolean;
isParentIssueModalOpen: string | null;
@@ -95,9 +95,9 @@ export interface IIssueDetail
toggleRelationModal: (issueId: string | null, relationType: TIssueRelationTypes | null) => void;
toggleSubIssuesModal: (value: string | null) => void;
toggleDeleteAttachmentModal: (attachmentId: string | null) => void;
setOpenWidgets: (state: TIssueDetailWidget[]) => void;
setLastWidgetAction: (action: TIssueDetailWidget) => void;
toggleOpenWidget: (state: TIssueDetailWidget) => void;
setOpenWidgets: (state: TWorkItemWidgets[]) => void;
setLastWidgetAction: (action: TWorkItemWidgets) => void;
toggleOpenWidget: (state: TWorkItemWidgets) => void;
setRelationKey: (relationKey: TIssueRelationTypes | null) => void;
setIssueCrudOperationState: (state: TIssueCrudOperationState) => void;
// store
@@ -131,8 +131,8 @@ export class IssueDetail implements IIssueDetail {
issue: undefined,
},
};
openWidgets: TIssueDetailWidget[] = ["sub-issues", "links", "attachments"];
lastWidgetAction: TIssueDetailWidget | null = null;
openWidgets: TWorkItemWidgets[] = ["sub-work-items", "links", "attachments"];
lastWidgetAction: TWorkItemWidgets | null = null;
isCreateIssueModalOpen: boolean = false;
isIssueLinkModalOpen: boolean = false;
isParentIssueModalOpen: string | null = null;
@@ -238,14 +238,14 @@ export class IssueDetail implements IIssueDetail {
(this.isRelationModalOpen = { issueId, relationType });
toggleSubIssuesModal = (issueId: string | null) => (this.isSubIssuesModalOpen = issueId);
toggleDeleteAttachmentModal = (attachmentId: string | null) => (this.attachmentDeleteModalId = attachmentId);
setOpenWidgets = (state: TIssueDetailWidget[]) => {
setOpenWidgets = (state: TWorkItemWidgets[]) => {
this.openWidgets = state;
if (this.lastWidgetAction) this.lastWidgetAction = null;
};
setLastWidgetAction = (action: TIssueDetailWidget) => {
setLastWidgetAction = (action: TWorkItemWidgets) => {
this.openWidgets = [action];
};
toggleOpenWidget = (state: TIssueDetailWidget) => {
toggleOpenWidget = (state: TWorkItemWidgets) => {
if (this.openWidgets && this.openWidgets.includes(state))
this.openWidgets = this.openWidgets.filter((s) => s !== state);
else this.openWidgets = [state, ...this.openWidgets];