diff --git a/web/core/components/issues/workspace-draft/draft-issue-block.tsx b/web/core/components/issues/workspace-draft/draft-issue-block.tsx index 0e0561353f6..089801447c3 100644 --- a/web/core/components/issues/workspace-draft/draft-issue-block.tsx +++ b/web/core/components/issues/workspace-draft/draft-issue-block.tsx @@ -1,8 +1,14 @@ "use client"; -import React, { FC, useRef } from "react"; +import React, { FC, useRef, useState } from "react"; +import { omit } from "lodash"; import { observer } from "mobx-react"; +import { Copy, Pencil, SquareStackIcon, Trash2 } from "lucide-react"; +// types +import { TWorkspaceDraftIssue } from "@plane/types"; // ui -import { Row, Tooltip } from "@plane/ui"; +import { Row, TContextMenuItem, Tooltip } from "@plane/ui"; +// constants +import { EIssuesStoreType } from "@/constants/issue"; // helper import { cn } from "@/helpers/common.helper"; // hooks @@ -11,6 +17,8 @@ import { useAppTheme, useProject, useWorkspaceDraftIssues } from "@/hooks/store" import { IdentifierText, IssueTypeIdentifier } from "@/plane-web/components/issues"; // local components import { WorkspaceDraftIssueQuickActions } from "../issue-layouts"; +import { CreateUpdateIssueModal } from "../issue-modal"; +import { WorkspaceDraftIssueDeleteIssueModal } from "./delete-modal"; import { DraftIssueProperties } from "./draft-issue-properties"; type Props = { @@ -21,8 +29,13 @@ type Props = { export const DraftIssueBlock: FC = observer((props) => { // props const { workspaceSlug, issueId } = props; + // states + const [moveToIssue, setMoveToIssue] = useState(false); + const [createUpdateIssueModal, setCreateUpdateIssueModal] = useState(false); + const [issueToEdit, setIssueToEdit] = useState(undefined); + const [deleteIssueModal, setDeleteIssueModal] = useState(false); // hooks - const { getIssueById, updateIssue, deleteIssue, moveIssue } = useWorkspaceDraftIssues(); + const { getIssueById, updateIssue, deleteIssue } = useWorkspaceDraftIssues(); const { sidebarCollapsed: isSidebarCollapsed } = useAppTheme(); const { getProjectIdentifierById } = useProject(); // ref @@ -32,97 +45,155 @@ export const DraftIssueBlock: FC = observer((props) => { const projectIdentifier = (issue && issue.project_id && getProjectIdentifierById(issue.project_id)) || undefined; if (!issue || !projectIdentifier) return null; + const duplicateIssuePayload = omit( + { + ...issue, + name: `${issue.name} (copy)`, + is_draft: true, + }, + ["id"] + ); + + const MENU_ITEMS: TContextMenuItem[] = [ + { + key: "edit", + title: "Edit", + icon: Pencil, + action: () => { + setIssueToEdit(issue); + setCreateUpdateIssueModal(true); + }, + }, + { + key: "make-a-copy", + title: "Make a copy", + icon: Copy, + action: () => { + setCreateUpdateIssueModal(true); + }, + }, + { + key: "move-to-issues", + title: "Move to issues", + icon: SquareStackIcon, + action: () => { + setMoveToIssue(true); + setIssueToEdit(issue); + setCreateUpdateIssueModal(true); + }, + }, + { + key: "delete", + title: "Delete", + icon: Trash2, + action: () => { + setDeleteIssueModal(true); + }, + }, + ]; + return ( -
- + setDeleteIssueModal(false)} + onSubmit={async () => deleteIssue(workspaceSlug, issueId)} + /> + { + setCreateUpdateIssueModal(false); + setIssueToEdit(undefined); + setMoveToIssue(false); + }} + data={issueToEdit ?? duplicateIssuePayload} + onSubmit={async (data) => { + if (issueToEdit) await updateIssue(workspaceSlug, issueId, data); + }} + storeType={EIssuesStoreType.WORKSPACE_DRAFT} + fetchIssueDetails={false} + moveToIssue={moveToIssue} + isDraft + /> +
{ + setIssueToEdit(issue); + setCreateUpdateIssueModal(true); + }} > -
-
-
- {/* {displayProperties && (displayProperties.key || displayProperties.issue_type) && ( */} -
- {issue.project_id && ( -
- {issue?.type_id && } - -
- )} + +
+
+
+
+ {issue.project_id && ( +
+ {issue?.type_id && } + +
+ )} +
+ + {/* sub-issues chevron */} +
- {/* )} */} - {/* sub-issues chevron */} -
+ +

{issue.name}

+
- -

{issue.name}

-
-
- - {/* quick actions */} -
- updateIssue(workspaceSlug, issueId, data)} - handleDelete={async () => deleteIssue(workspaceSlug, issueId)} - handleMoveToIssues={async () => moveIssue(workspaceSlug, issueId, issue)} - /> + +
-
-
- { - await updateIssue(workspaceSlug, issueId, data); - }} - activeLayout="List" - /> -
{ - e.preventDefault(); - e.stopPropagation(); - }} - > - + updateIssue(workspaceSlug, issueId, data)} - handleDelete={async () => deleteIssue(workspaceSlug, issueId)} - handleMoveToIssues={async () => moveIssue(workspaceSlug, issueId, issue)} + updateIssue={async (projectId, issueId, data) => { + await updateIssue(workspaceSlug, issueId, data); + }} + activeLayout="List" /> +
{ + e.preventDefault(); + e.stopPropagation(); + }} + > + +
-
-
-
+ +
+ ); }); diff --git a/web/core/components/issues/workspace-draft/quick-action.tsx b/web/core/components/issues/workspace-draft/quick-action.tsx index 62fea2ea7be..884e81a9127 100644 --- a/web/core/components/issues/workspace-draft/quick-action.tsx +++ b/web/core/components/issues/workspace-draft/quick-action.tsx @@ -1,131 +1,25 @@ "use client"; -import { useState } from "react"; -import { Placement } from "@popperjs/core"; -import omit from "lodash/omit"; import { observer } from "mobx-react"; -// icons -import { Copy, Pencil, SquareStackIcon, Trash2 } from "lucide-react"; -// types -import { TWorkspaceDraftIssue } from "@plane/types"; // ui import { ContextMenu, CustomMenu, TContextMenuItem } from "@plane/ui"; -// components -import { CreateUpdateIssueModal } from "@/components/issues"; -// constant -import { EIssuesStoreType } from "@/constants/issue"; // helpers import { cn } from "@/helpers/common.helper"; -// local components -import { WorkspaceDraftIssueDeleteIssueModal } from "./delete-modal"; -export interface IQuickActionProps { - issue: TWorkspaceDraftIssue; - handleDelete: () => Promise; - handleUpdate: (payload: Partial) => Promise; - handleMoveToIssues?: () => Promise; - customActionButton?: React.ReactElement; - portalElement?: HTMLDivElement | null; - placements?: Placement; +export interface Props { parentRef: React.RefObject; + MENU_ITEMS: TContextMenuItem[]; } -export const WorkspaceDraftIssueQuickActions: React.FC = observer((props) => { - const { - issue, - handleDelete, - handleUpdate, - handleMoveToIssues, - customActionButton, - portalElement, - placements = "bottom-end", - parentRef, - } = props; - // states - const [moveToIssue, setMoveToIssue] = useState(false); - const [createUpdateIssueModal, setCreateUpdateIssueModal] = useState(false); - const [issueToEdit, setIssueToEdit] = useState(undefined); - const [deleteIssueModal, setDeleteIssueModal] = useState(false); - - const duplicateIssuePayload = omit( - { - ...issue, - name: `${issue.name} (copy)`, - is_draft: true, - }, - ["id"] - ); - - const MENU_ITEMS: TContextMenuItem[] = [ - { - key: "edit", - title: "Edit", - icon: Pencil, - action: () => { - setIssueToEdit(issue); - setCreateUpdateIssueModal(true); - }, - }, - { - key: "make-a-copy", - title: "Make a copy", - icon: Copy, - action: () => { - setCreateUpdateIssueModal(true); - }, - }, - { - key: "move-to-issues", - title: "Move to issues", - icon: SquareStackIcon, - action: () => { - if (handleMoveToIssues) { - setMoveToIssue(true); - setIssueToEdit(issue); - setCreateUpdateIssueModal(true); - } - }, - }, - { - key: "delete", - title: "Delete", - icon: Trash2, - action: () => { - setDeleteIssueModal(true); - }, - }, - ]; +export const WorkspaceDraftIssueQuickActions: React.FC = observer((props) => { + const { parentRef, MENU_ITEMS } = props; return ( <> - setDeleteIssueModal(false)} - onSubmit={handleDelete} - /> - { - setCreateUpdateIssueModal(false); - setIssueToEdit(undefined); - setMoveToIssue(false); - }} - data={issueToEdit ?? duplicateIssuePayload} - onSubmit={async (data) => { - if (issueToEdit && handleUpdate) await handleUpdate(data as TWorkspaceDraftIssue); - }} - storeType={EIssuesStoreType.WORKSPACE_DRAFT} - fetchIssueDetails={false} - moveToIssue={moveToIssue} - isDraft - />