diff --git a/web/components/cycles/gantt-chart/cycles-list-layout.tsx b/web/components/cycles/gantt-chart/cycles-list-layout.tsx index 49d461d1a..9526de59c 100644 --- a/web/components/cycles/gantt-chart/cycles-list-layout.tsx +++ b/web/components/cycles/gantt-chart/cycles-list-layout.tsx @@ -85,8 +85,8 @@ export const CyclesListGanttChartView: FC = ({ cycles, mutateCycles }) => loaderTitle="Cycles" blocks={cycles ? blockFormat(cycles) : null} blockUpdateHandler={(block, payload) => handleCycleUpdate(block, payload)} - SidebarBlockRender={CycleGanttSidebarBlock} - BlockRender={CycleGanttBlock} + blockToRender={(data: ICycle) => } + sidebarBlockToRender={(data: ICycle) => } enableBlockLeftResize={false} enableBlockRightResize={false} enableBlockMove={false} diff --git a/web/components/gantt-chart/blocks/blocks-display.tsx b/web/components/gantt-chart/blocks/blocks-display.tsx index f0e7279be..586b0d5cc 100644 --- a/web/components/gantt-chart/blocks/blocks-display.tsx +++ b/web/components/gantt-chart/blocks/blocks-display.tsx @@ -11,7 +11,7 @@ import { IBlockUpdateData, IGanttBlock } from "../types"; export const GanttChartBlocks: FC<{ itemsContainerWidth: number; blocks: IGanttBlock[] | null; - BlockRender: React.FC; + blockToRender: (data: any) => React.ReactNode; blockUpdateHandler: (block: any, payload: IBlockUpdateData) => void; enableBlockLeftResize: boolean; enableBlockRightResize: boolean; @@ -19,7 +19,7 @@ export const GanttChartBlocks: FC<{ }> = ({ itemsContainerWidth, blocks, - BlockRender, + blockToRender, blockUpdateHandler, enableBlockLeftResize, enableBlockRightResize, @@ -49,11 +49,9 @@ export const GanttChartBlocks: FC<{ const updatedTargetDate = new Date(originalTargetDate); // update the start date on left resize - if (dragDirection === "left") - updatedStartDate.setDate(originalStartDate.getDate() - totalBlockShifts); + if (dragDirection === "left") updatedStartDate.setDate(originalStartDate.getDate() - totalBlockShifts); // update the target date on right resize - else if (dragDirection === "right") - updatedTargetDate.setDate(originalTargetDate.getDate() + totalBlockShifts); + else if (dragDirection === "right") updatedTargetDate.setDate(originalTargetDate.getDate() + totalBlockShifts); // update both the dates on x-axis move else if (dragDirection === "move") { updatedStartDate.setDate(originalStartDate.getDate() + totalBlockShifts); @@ -86,7 +84,7 @@ export const GanttChartBlocks: FC<{ > handleChartBlockPosition(block, ...args)} enableBlockLeftResize={enableBlockLeftResize} enableBlockRightResize={enableBlockRightResize} diff --git a/web/components/gantt-chart/chart/index.tsx b/web/components/gantt-chart/chart/index.tsx index abd0c5e8a..219f11ebb 100644 --- a/web/components/gantt-chart/chart/index.tsx +++ b/web/components/gantt-chart/chart/index.tsx @@ -39,8 +39,8 @@ type ChartViewRootProps = { loaderTitle: string; blocks: IGanttBlock[] | null; blockUpdateHandler: (block: any, payload: IBlockUpdateData) => void; - SidebarBlockRender: React.FC; - BlockRender: React.FC; + blockToRender: (data: any) => React.ReactNode; + sidebarBlockToRender: (block: any) => React.ReactNode; enableBlockLeftResize: boolean; enableBlockRightResize: boolean; enableBlockMove: boolean; @@ -54,8 +54,8 @@ export const ChartViewRoot: FC = ({ blocks = null, loaderTitle, blockUpdateHandler, - SidebarBlockRender, - BlockRender, + sidebarBlockToRender, + blockToRender, enableBlockLeftResize, enableBlockRightResize, enableBlockMove, @@ -289,7 +289,7 @@ export const ChartViewRoot: FC = ({ title={title} blockUpdateHandler={blockUpdateHandler} blocks={chartBlocks} - SidebarBlockRender={SidebarBlockRender} + sidebarBlockToRender={sidebarBlockToRender} enableReorder={enableReorder} /> @@ -311,7 +311,7 @@ export const ChartViewRoot: FC = ({ ; + blockToRender: (data: any) => React.ReactNode; handleBlock: (totalBlockShifts: number, dragDirection: "left" | "right" | "move") => void; enableBlockLeftResize: boolean; enableBlockRightResize: boolean; @@ -18,7 +18,7 @@ type Props = { export const ChartDraggable: React.FC = ({ block, - BlockRender, + blockToRender, handleBlock, enableBlockLeftResize, enableBlockRightResize, @@ -286,7 +286,7 @@ export const ChartDraggable: React.FC = ({ className={`relative z-[2] rounded h-8 w-full flex items-center ${isMoving ? "pointer-events-none" : ""}`} onMouseDown={handleBlockMove} > - + {blockToRender(block.data)} {/* right resize drag handle */} {enableBlockRightResize && ( diff --git a/web/components/gantt-chart/root.tsx b/web/components/gantt-chart/root.tsx index 5acedd53e..7c1f243d6 100644 --- a/web/components/gantt-chart/root.tsx +++ b/web/components/gantt-chart/root.tsx @@ -12,8 +12,8 @@ type GanttChartRootProps = { loaderTitle: string; blocks: IGanttBlock[] | null; blockUpdateHandler: (block: any, payload: IBlockUpdateData) => void; - SidebarBlockRender: FC; - BlockRender: FC; + blockToRender: (data: any) => React.ReactNode; + sidebarBlockToRender: (block: any) => React.ReactNode; enableBlockLeftResize?: boolean; enableBlockRightResize?: boolean; enableBlockMove?: boolean; @@ -27,8 +27,8 @@ export const GanttChartRoot: FC = ({ blocks, loaderTitle = "blocks", blockUpdateHandler, - SidebarBlockRender, - BlockRender, + sidebarBlockToRender, + blockToRender, enableBlockLeftResize = true, enableBlockRightResize = true, enableBlockMove = true, @@ -42,8 +42,8 @@ export const GanttChartRoot: FC = ({ blocks={blocks} loaderTitle={loaderTitle} blockUpdateHandler={blockUpdateHandler} - SidebarBlockRender={SidebarBlockRender} - BlockRender={BlockRender} + sidebarBlockToRender={sidebarBlockToRender} + blockToRender={blockToRender} enableBlockLeftResize={enableBlockLeftResize} enableBlockRightResize={enableBlockRightResize} enableBlockMove={enableBlockMove} diff --git a/web/components/gantt-chart/sidebar.tsx b/web/components/gantt-chart/sidebar.tsx index 0e7dae048..72da2a4bd 100644 --- a/web/components/gantt-chart/sidebar.tsx +++ b/web/components/gantt-chart/sidebar.tsx @@ -17,14 +17,14 @@ type Props = { title: string; blockUpdateHandler: (block: any, payload: IBlockUpdateData) => void; blocks: IGanttBlock[] | null; - SidebarBlockRender: React.FC; + sidebarBlockToRender: (block: any) => React.ReactNode; enableReorder: boolean; enableQuickIssueCreate?: boolean; }; export const GanttSidebar: React.FC = (props) => { // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { title, blockUpdateHandler, blocks, SidebarBlockRender, enableReorder, enableQuickIssueCreate } = props; + const { title, blockUpdateHandler, blocks, sidebarBlockToRender, enableReorder, enableQuickIssueCreate } = props; const router = useRouter(); const { cycleId } = router.query; @@ -130,9 +130,7 @@ export const GanttSidebar: React.FC = (props) => { )}
-
- -
+
{sidebarBlockToRender(block.data)}
{duration} day{duration > 1 ? "s" : ""}
diff --git a/web/components/issues/issue-layouts/calendar/calendar.tsx b/web/components/issues/issue-layouts/calendar/calendar.tsx index 9b7bfcaf9..bdc0a786e 100644 --- a/web/components/issues/issue-layouts/calendar/calendar.tsx +++ b/web/components/issues/issue-layouts/calendar/calendar.tsx @@ -15,11 +15,12 @@ type Props = { issues: IIssueGroupedStructure | null; layout: "month" | "week" | undefined; showWeekends: boolean; + handleIssues: (date: string, issue: IIssue, action: "update" | "delete") => void; quickActions: (issue: IIssue) => React.ReactNode; }; export const CalendarChart: React.FC = observer((props) => { - const { issues, layout, showWeekends, quickActions } = props; + const { issues, layout, showWeekends, handleIssues, quickActions } = props; const { calendar: calendarStore } = useMobxStore(); @@ -49,6 +50,7 @@ export const CalendarChart: React.FC = observer((props) => { week={week} issues={issues} enableQuickIssueCreate + handleIssues={handleIssues} quickActions={quickActions} /> ))} @@ -59,6 +61,7 @@ export const CalendarChart: React.FC = observer((props) => { week={calendarStore.allDaysOfActiveWeek} issues={issues} enableQuickIssueCreate + handleIssues={handleIssues} quickActions={quickActions} /> )} diff --git a/web/components/issues/issue-layouts/calendar/day-tile.tsx b/web/components/issues/issue-layouts/calendar/day-tile.tsx index 2dacc03ee..87a28a320 100644 --- a/web/components/issues/issue-layouts/calendar/day-tile.tsx +++ b/web/components/issues/issue-layouts/calendar/day-tile.tsx @@ -16,12 +16,13 @@ import { IIssue } from "types"; type Props = { date: ICalendarDate; issues: IIssueGroupedStructure | null; + handleIssues: (date: string, issue: IIssue, action: "update" | "delete") => void; quickActions: (issue: IIssue) => React.ReactNode; enableQuickIssueCreate?: boolean; }; export const CalendarDayTile: React.FC = observer((props) => { - const { date, issues, quickActions, enableQuickIssueCreate } = props; + const { date, issues, handleIssues, quickActions, enableQuickIssueCreate } = props; const { issueFilter: issueFilterStore } = useMobxStore(); @@ -63,7 +64,7 @@ export const CalendarDayTile: React.FC = observer((props) => { {...provided.droppableProps} ref={provided.innerRef} > - + {enableQuickIssueCreate && (
void; quickActions: (issue: IIssue) => React.ReactNode; }; export const CalendarIssueBlocks: React.FC = observer((props) => { - const { issues, quickActions } = props; + const { issues, handleIssues, quickActions } = props; const router = useRouter(); const { workspaceSlug } = router.query; @@ -47,7 +51,19 @@ export const CalendarIssueBlocks: React.FC = observer((props) => {
{issue.project_detail.identifier}-{issue.sequence_id}
-
{issue.name}
+ { + handleIssues(issue.target_date ?? "", { ...issue, ...issueToUpdate }, "update"); + }} + > + + {issue.name} + +
{quickActions(issue)}
diff --git a/web/components/issues/issue-layouts/calendar/roots/cycle-root.tsx b/web/components/issues/issue-layouts/calendar/roots/cycle-root.tsx index ec9e6b94f..a340f534e 100644 --- a/web/components/issues/issue-layouts/calendar/roots/cycle-root.tsx +++ b/web/components/issues/issue-layouts/calendar/roots/cycle-root.tsx @@ -64,6 +64,7 @@ export const CycleCalendarLayout: React.FC = observer(() => { issues={issues as IIssueGroupedStructure | null} layout={issueFilterStore.userDisplayFilters.calendar?.layout} showWeekends={issueFilterStore.userDisplayFilters.calendar?.show_weekends ?? false} + handleIssues={handleIssues} quickActions={(issue) => ( { issues={issues as IIssueGroupedStructure | null} layout={issueFilterStore.userDisplayFilters.calendar?.layout} showWeekends={issueFilterStore.userDisplayFilters.calendar?.show_weekends ?? false} + handleIssues={handleIssues} quickActions={(issue) => ( { issues={issues as IIssueGroupedStructure | null} layout={issueFilterStore.userDisplayFilters.calendar?.layout} showWeekends={issueFilterStore.userDisplayFilters.calendar?.show_weekends ?? false} + handleIssues={handleIssues} quickActions={(issue) => ( { issues={issues as IIssueGroupedStructure | null} layout={issueFilterStore.userDisplayFilters.calendar?.layout} showWeekends={issueFilterStore.userDisplayFilters.calendar?.show_weekends ?? false} + handleIssues={handleIssues} quickActions={(issue) => ( void; quickActions: (issue: IIssue) => React.ReactNode; enableQuickIssueCreate?: boolean; }; export const CalendarWeekDays: React.FC = observer((props) => { - const { issues, week, quickActions, enableQuickIssueCreate } = props; + const { issues, week, handleIssues, quickActions, enableQuickIssueCreate } = props; const { issueFilter: issueFilterStore } = useMobxStore(); @@ -42,6 +43,7 @@ export const CalendarWeekDays: React.FC = observer((props) => { key={renderDateFormat(date.date)} date={date} issues={issues} + handleIssues={handleIssues} quickActions={quickActions} enableQuickIssueCreate={enableQuickIssueCreate} /> diff --git a/web/components/issues/issue-layouts/gantt/blocks.tsx b/web/components/issues/issue-layouts/gantt/blocks.tsx index e29dc81d0..7cf8cc664 100644 --- a/web/components/issues/issue-layouts/gantt/blocks.tsx +++ b/web/components/issues/issue-layouts/gantt/blocks.tsx @@ -1,29 +1,28 @@ -import { useRouter } from "next/router"; - // ui import { Tooltip, StateGroupIcon } from "@plane/ui"; +import { IssuePeekOverview } from "components/issues/issue-peek-overview"; +import { IBlockUpdateData } from "components/gantt-chart"; // helpers import { renderShortDate } from "helpers/date-time.helper"; // types import { IIssue } from "types"; -export const IssueGanttBlock = ({ data }: { data: IIssue }) => { - const router = useRouter(); - - const openPeekOverview = () => { - const { query } = router; - - router.push({ - pathname: router.pathname, - query: { ...query, peekIssue: data.id }, - }); - }; - - return ( +export const IssueGanttBlock = ({ + data, + handleIssue, +}: { + data: IIssue; + handleIssue: (block: IIssue, payload: IBlockUpdateData) => void; +}) => ( + handleIssue({ ...data, ...issueToUpdate }, {})} + >
{ } position="top-left" > -
{data?.name}
+ +
{data?.name}
+
- ); -}; + +); // rendering issues on gantt sidebar -export const IssueGanttSidebarBlock = ({ data }: { data: IIssue }) => { - const router = useRouter(); - - const openPeekOverview = () => { - const { query } = router; - - router.push({ - pathname: router.pathname, - query: { ...query, peekIssue: data.id }, - }); - }; - - return ( -
+export const IssueGanttSidebarBlock = ({ + data, + handleIssue, +}: { + data: IIssue; + handleIssue: (block: IIssue, payload: IBlockUpdateData) => void; +}) => ( + handleIssue({ ...data, ...issueToUpdate }, {})} + > +
{data?.project_detail?.identifier} {data?.sequence_id}
-
{data?.name}
+ + {data?.name} +
- ); -}; +
+); diff --git a/web/components/issues/issue-layouts/gantt/cycle-root.tsx b/web/components/issues/issue-layouts/gantt/cycle-root.tsx index 66b4dc05c..78ba7f2a6 100644 --- a/web/components/issues/issue-layouts/gantt/cycle-root.tsx +++ b/web/components/issues/issue-layouts/gantt/cycle-root.tsx @@ -8,6 +8,7 @@ import { GanttChartRoot, IBlockUpdateData, renderIssueBlocksStructure } from "co import { IssueGanttBlock, IssueGanttSidebarBlock } from "components/issues"; // types import { IIssueUnGroupedStructure } from "store/issue"; +import { IIssue } from "types"; export const CycleGanttLayout: React.FC = observer(() => { const router = useRouter(); @@ -38,8 +39,8 @@ export const CycleGanttLayout: React.FC = observer(() => { loaderTitle="Issues" blocks={issues ? renderIssueBlocksStructure(issues as IIssueUnGroupedStructure) : null} blockUpdateHandler={updateIssue} - BlockRender={IssueGanttBlock} - SidebarBlockRender={IssueGanttSidebarBlock} + blockToRender={(data: IIssue) => } + sidebarBlockToRender={(data: IIssue) => } enableBlockLeftResize={isAllowed} enableBlockRightResize={isAllowed} enableBlockMove={isAllowed} diff --git a/web/components/issues/issue-layouts/gantt/module-root.tsx b/web/components/issues/issue-layouts/gantt/module-root.tsx index 9c9d840b1..7584cc7c6 100644 --- a/web/components/issues/issue-layouts/gantt/module-root.tsx +++ b/web/components/issues/issue-layouts/gantt/module-root.tsx @@ -8,6 +8,7 @@ import { GanttChartRoot, IBlockUpdateData, renderIssueBlocksStructure } from "co import { IssueGanttBlock, IssueGanttSidebarBlock } from "components/issues"; // types import { IIssueUnGroupedStructure } from "store/issue"; +import { IIssue } from "types"; export const ModuleGanttLayout: React.FC = observer(() => { const router = useRouter(); @@ -38,8 +39,8 @@ export const ModuleGanttLayout: React.FC = observer(() => { loaderTitle="Issues" blocks={issues ? renderIssueBlocksStructure(issues as IIssueUnGroupedStructure) : null} blockUpdateHandler={updateIssue} - BlockRender={IssueGanttBlock} - SidebarBlockRender={IssueGanttSidebarBlock} + blockToRender={(data: IIssue) => } + sidebarBlockToRender={(data: IIssue) => } enableBlockLeftResize={isAllowed} enableBlockRightResize={isAllowed} enableBlockMove={isAllowed} diff --git a/web/components/issues/issue-layouts/gantt/project-view-root.tsx b/web/components/issues/issue-layouts/gantt/project-view-root.tsx index ce6ebe0f0..1be9ad0c3 100644 --- a/web/components/issues/issue-layouts/gantt/project-view-root.tsx +++ b/web/components/issues/issue-layouts/gantt/project-view-root.tsx @@ -10,6 +10,7 @@ import { GanttChartRoot, IBlockUpdateData, renderIssueBlocksStructure } from "co import { IssueGanttBlock, IssueGanttSidebarBlock } from "components/issues"; // types import { IIssueUnGroupedStructure } from "store/issue"; +import { IIssue } from "types"; export const ProjectViewGanttLayout: React.FC = observer(() => { const router = useRouter(); @@ -40,8 +41,8 @@ export const ProjectViewGanttLayout: React.FC = observer(() => { loaderTitle="Issues" blocks={issues ? renderIssueBlocksStructure(issues as IIssueUnGroupedStructure) : null} blockUpdateHandler={updateIssue} - BlockRender={IssueGanttBlock} - SidebarBlockRender={IssueGanttSidebarBlock} + blockToRender={(data: IIssue) => } + sidebarBlockToRender={(data: IIssue) => } enableBlockLeftResize={isAllowed} enableBlockRightResize={isAllowed} enableBlockMove={isAllowed} diff --git a/web/components/issues/issue-layouts/gantt/root.tsx b/web/components/issues/issue-layouts/gantt/root.tsx index bf52e29f5..77bbc0710 100644 --- a/web/components/issues/issue-layouts/gantt/root.tsx +++ b/web/components/issues/issue-layouts/gantt/root.tsx @@ -1,3 +1,4 @@ +import React from "react"; import { useRouter } from "next/router"; import { observer } from "mobx-react-lite"; // hooks @@ -8,6 +9,7 @@ import { GanttChartRoot, IBlockUpdateData, renderIssueBlocksStructure } from "co import { IssueGanttBlock, IssueGanttSidebarBlock } from "components/issues"; // types import { IIssueUnGroupedStructure } from "store/issue"; +import { IIssue } from "types"; export const GanttLayout: React.FC = observer(() => { const router = useRouter(); @@ -21,7 +23,7 @@ export const GanttLayout: React.FC = observer(() => { const issues = issueStore.getIssues; - const updateIssue = (block: any, payload: IBlockUpdateData) => { + const updateIssue = (block: IIssue, payload: IBlockUpdateData) => { if (!workspaceSlug) return; issueStore.updateGanttIssueStructure(workspaceSlug.toString(), block, payload); @@ -38,8 +40,8 @@ export const GanttLayout: React.FC = observer(() => { loaderTitle="Issues" blocks={issues ? renderIssueBlocksStructure(issues as IIssueUnGroupedStructure) : null} blockUpdateHandler={updateIssue} - BlockRender={IssueGanttBlock} - SidebarBlockRender={IssueGanttSidebarBlock} + blockToRender={(data: IIssue) => } + sidebarBlockToRender={(data: IIssue) => } enableBlockLeftResize={isAllowed} enableBlockRightResize={isAllowed} enableBlockMove={isAllowed} diff --git a/web/components/issues/issue-layouts/kanban/block.tsx b/web/components/issues/issue-layouts/kanban/block.tsx index bfaa117c6..d72e93a8d 100644 --- a/web/components/issues/issue-layouts/kanban/block.tsx +++ b/web/components/issues/issue-layouts/kanban/block.tsx @@ -1,6 +1,8 @@ import { Draggable } from "@hello-pangea/dnd"; // components import { KanBanProperties } from "./properties"; +import { Tooltip } from "@plane/ui"; +import { IssuePeekOverview } from "components/issues/issue-peek-overview"; // types import { IIssueDisplayProperties, IIssue } from "types"; @@ -57,7 +59,23 @@ export const KanbanIssueBlock: React.FC = (props) => { {issue.project_detail.identifier}-{issue.sequence_id}
)} -
{issue.name}
+ { + handleIssues( + !sub_group_id && sub_group_id === "null" ? null : sub_group_id, + !columnId && columnId === "null" ? null : columnId, + { ...issue, ...issueToUpdate }, + "update" + ); + }} + > + +
{issue.name}
+
+
= (props) => { workspaceSlug={issue?.workspace_detail?.slug} projectId={issue?.project_detail?.id} issueId={issue?.id} - // TODO: add the logic here - handleIssue={() => {}} + handleIssue={(issueToUpdate) => { + handleIssues(!columnId && columnId === "null" ? null : columnId, issueToUpdate as IIssue, "update"); + }} >
{issue.name}
diff --git a/web/components/issues/issue-layouts/spreadsheet/columns/issue/issue-column.tsx b/web/components/issues/issue-layouts/spreadsheet/columns/issue/issue-column.tsx index e26cdb789..18daa039a 100644 --- a/web/components/issues/issue-layouts/spreadsheet/columns/issue/issue-column.tsx +++ b/web/components/issues/issue-layouts/spreadsheet/columns/issue/issue-column.tsx @@ -4,6 +4,9 @@ import { Popover2 } from "@blueprintjs/popover2"; import { MoreHorizontal, Pencil, Trash2, ChevronRight, Link } from "lucide-react"; // hooks import useToast from "hooks/use-toast"; +// components +import { IssuePeekOverview } from "components/issues/issue-peek-overview"; +import { Tooltip } from "@plane/ui"; // helpers import { copyUrlToClipboard } from "helpers/string.helper"; // types @@ -13,6 +16,7 @@ type Props = { issue: IIssue; expanded: boolean; handleToggleExpand: (issueId: string) => void; + handleUpdateIssue: (issue: IIssue, data: Partial) => void; properties: IIssueDisplayProperties; handleEditIssue: (issue: IIssue) => void; handleDeleteIssue: (issue: IIssue) => void; @@ -24,6 +28,7 @@ export const IssueColumn: React.FC = ({ issue, expanded, handleToggleExpand, + handleUpdateIssue, properties, handleEditIssue, handleDeleteIssue, @@ -38,15 +43,6 @@ export const IssueColumn: React.FC = ({ const { setToastAlert } = useToast(); - const openPeekOverview = () => { - const { query } = router; - - router.push({ - pathname: router.pathname, - query: { ...query, peekIssue: issue.id }, - }); - }; - const handleCopyText = () => { copyUrlToClipboard(`${workspaceSlug}/projects/${issue.project}/issues/${issue.id}`).then(() => { setToastAlert({ @@ -142,15 +138,20 @@ export const IssueColumn: React.FC = ({ )}
)} - - - + handleUpdateIssue(issueToUpdate as IIssue, issueToUpdate)} + > + + +
+ {issue.name} +
+
+
+
); }; diff --git a/web/components/issues/issue-layouts/spreadsheet/columns/issue/spreadsheet-issue-column.tsx b/web/components/issues/issue-layouts/spreadsheet/columns/issue/spreadsheet-issue-column.tsx index 22692a396..265925eb0 100644 --- a/web/components/issues/issue-layouts/spreadsheet/columns/issue/spreadsheet-issue-column.tsx +++ b/web/components/issues/issue-layouts/spreadsheet/columns/issue/spreadsheet-issue-column.tsx @@ -11,6 +11,7 @@ type Props = { issue: IIssue; expandedIssues: string[]; setExpandedIssues: React.Dispatch>; + handleUpdateIssue: (issue: IIssue, data: Partial) => void; properties: IIssueDisplayProperties; handleIssueAction: (issue: IIssue, action: "copy" | "delete" | "edit") => void; disableUserActions: boolean; @@ -21,6 +22,7 @@ export const SpreadsheetIssuesColumn: React.FC = ({ issue, expandedIssues, setExpandedIssues, + handleUpdateIssue, properties, handleIssueAction, disableUserActions, @@ -49,6 +51,7 @@ export const SpreadsheetIssuesColumn: React.FC = ({ expanded={isExpanded} handleToggleExpand={handleToggleExpand} properties={properties} + handleUpdateIssue={handleUpdateIssue} handleEditIssue={() => handleIssueAction(issue, "edit")} handleDeleteIssue={() => handleIssueAction(issue, "delete")} disableUserActions={disableUserActions} @@ -64,6 +67,7 @@ export const SpreadsheetIssuesColumn: React.FC = ({ key={subIssue.id} issue={subIssue} expandedIssues={expandedIssues} + handleUpdateIssue={handleUpdateIssue} setExpandedIssues={setExpandedIssues} properties={properties} handleIssueAction={handleIssueAction} diff --git a/web/components/issues/issue-layouts/spreadsheet/spreadsheet-view.tsx b/web/components/issues/issue-layouts/spreadsheet/spreadsheet-view.tsx index be6bbb8e1..3f49670f3 100644 --- a/web/components/issues/issue-layouts/spreadsheet/spreadsheet-view.tsx +++ b/web/components/issues/issue-layouts/spreadsheet/spreadsheet-view.tsx @@ -104,6 +104,7 @@ export const SpreadsheetView: React.FC = observer((props) => { key={`${issue.id}_${index}`} issue={issue} expandedIssues={expandedIssues} + handleUpdateIssue={handleUpdateIssue} setExpandedIssues={setExpandedIssues} properties={displayProperties} handleIssueAction={handleIssueAction} diff --git a/web/components/issues/issue-peek-overview/root.tsx b/web/components/issues/issue-peek-overview/root.tsx index 6af7336d8..142adad92 100644 --- a/web/components/issues/issue-peek-overview/root.tsx +++ b/web/components/issues/issue-peek-overview/root.tsx @@ -22,10 +22,7 @@ export const IssuePeekOverview: FC = observer((props) => { const { issueDetail: issueDetailStore }: RootStore = useMobxStore(); const issueUpdate = (_data: Partial) => { - if (handleIssue) { - handleIssue(_data); - issueDetailStore.updateIssue(workspaceSlug, projectId, issueId, _data); - } + handleIssue(_data); }; const issueReactionCreate = (reaction: string) => diff --git a/web/components/issues/sub-issues/issue.tsx b/web/components/issues/sub-issues/issue.tsx index 1b86221a5..fcf4c5906 100644 --- a/web/components/issues/sub-issues/issue.tsx +++ b/web/components/issues/sub-issues/issue.tsx @@ -1,12 +1,9 @@ import React from "react"; -// next imports -import { useRouter } from "next/router"; -// swr -import { mutate } from "swr"; + // lucide icons import { ChevronDown, ChevronRight, X, Pencil, Trash, Link as LinkIcon, Loader } from "lucide-react"; // components -import { IssuePeekOverview } from "components/issues/peek-overview"; +import { IssuePeekOverview } from "../issue-peek-overview"; import { SubIssuesRootList } from "./issues-list"; import { IssueProperty } from "./properties"; // ui @@ -15,7 +12,6 @@ import { CustomMenu, Tooltip } from "@plane/ui"; import { IUser, IIssue } from "types"; import { ISubIssuesRootLoaders, ISubIssuesRootLoadersHandler } from "./root"; // fetch keys -import { SUB_ISSUES } from "constants/fetch-keys"; export interface ISubIssues { workspaceSlug: string; @@ -34,6 +30,7 @@ export interface ISubIssues { issueId: string, issue?: IIssue | null ) => void; + handleUpdateIssue: (issue: IIssue, data: Partial) => void; } export const SubIssues: React.FC = ({ @@ -49,49 +46,47 @@ export const SubIssues: React.FC = ({ handleIssuesLoader, copyText, handleIssueCrudOperation, -}) => { - const router = useRouter(); - const { query } = router; - const { peekIssue } = query as { peekIssue: string }; + handleUpdateIssue, +}) => ( +
+ {issue && ( +
+
+ {issue?.sub_issues_count > 0 && ( + <> + {issuesLoader.sub_issues.includes(issue?.id) ? ( +
+ +
+ ) : ( +
handleIssuesLoader({ key: "visibility", issueId: issue?.id })} + > + {issuesLoader && issuesLoader.visibility.includes(issue?.id) ? ( + + ) : ( + + )} +
+ )} + + )} +
- const openPeekOverview = (issue_id: string) => { - router.push({ - pathname: router.pathname, - query: { ...query, peekIssue: issue_id }, - }); - }; - - return ( -
- {issue && ( -
{ + console.log("issueToUpdate", issueToUpdate); + handleUpdateIssue(issue, { ...issue, ...issueToUpdate }); + }} > -
- {issue?.sub_issues_count > 0 && ( - <> - {issuesLoader.sub_issues.includes(issue?.id) ? ( -
- -
- ) : ( -
handleIssuesLoader({ key: "visibility", issueId: issue?.id })} - > - {issuesLoader && issuesLoader.visibility.includes(issue?.id) ? ( - - ) : ( - - )} -
- )} - - )} -
- -
openPeekOverview(issue?.id)}> +
= ({
{issue?.name}
+ -
- -
+
+ +
-
- - {editable && ( - handleIssueCrudOperation("edit", parentIssue?.id, issue)}> -
- - Edit issue -
-
- )} - - {editable && ( - handleIssueCrudOperation("delete", parentIssue?.id, issue)}> -
- - Delete issue -
-
- )} - - copyText(`${workspaceSlug}/projects/${issue.project}/issues/${issue.id}`)} - > +
+ + {editable && ( + handleIssueCrudOperation("edit", parentIssue?.id, issue)}>
- - Copy issue link + + Edit issue
-
-
+ )} - {editable && ( - <> - {issuesLoader.delete.includes(issue?.id) ? ( -
- + {editable && ( + handleIssueCrudOperation("delete", parentIssue?.id, issue)}> +
+ + Delete issue
- ) : ( -
{ - handleIssuesLoader({ key: "delete", issueId: issue?.id }); - removeIssueFromSubIssues(parentIssue?.id, issue); - }} - > - -
- )} - - )} +
+ )} + + copyText(`${workspaceSlug}/projects/${issue.project}/issues/${issue.id}`)} + > +
+ + Copy issue link +
+
+
- )} - {issuesLoader.visibility.includes(issue?.id) && issue?.sub_issues_count > 0 && ( - - )} + {editable && ( + <> + {issuesLoader.delete.includes(issue?.id) ? ( +
+ +
+ ) : ( +
{ + handleIssuesLoader({ key: "delete", issueId: issue?.id }); + removeIssueFromSubIssues(parentIssue?.id, issue); + }} + > + +
+ )} + + )} +
+ )} - {peekIssue && peekIssue === issue?.id && ( - parentIssue && parentIssue?.id && mutate(SUB_ISSUES(parentIssue?.id))} - projectId={issue?.project ?? ""} - workspaceSlug={workspaceSlug ?? ""} - readOnly={!editable} - /> - )} -
- ); -}; + {issuesLoader.visibility.includes(issue?.id) && issue?.sub_issues_count > 0 && ( + + )} +
+); diff --git a/web/components/issues/sub-issues/issues-list.tsx b/web/components/issues/sub-issues/issues-list.tsx index 32f6eb315..65f459d95 100644 --- a/web/components/issues/sub-issues/issues-list.tsx +++ b/web/components/issues/sub-issues/issues-list.tsx @@ -27,6 +27,7 @@ export interface ISubIssuesRootList { issueId: string, issue?: IIssue | null ) => void; + handleUpdateIssue: (issue: IIssue, data: Partial) => void; } const issueService = new IssueService(); @@ -43,6 +44,7 @@ export const SubIssuesRootList: React.FC = ({ handleIssuesLoader, copyText, handleIssueCrudOperation, + handleUpdateIssue, }) => { const { data: issues, isLoading } = useSWR( workspaceSlug && projectId && parentIssue && parentIssue?.id ? SUB_ISSUES(parentIssue?.id) : null, @@ -82,6 +84,7 @@ export const SubIssuesRootList: React.FC = ({ handleIssuesLoader={handleIssuesLoader} copyText={copyText} handleIssueCrudOperation={handleIssueCrudOperation} + handleUpdateIssue={handleUpdateIssue} /> ))} diff --git a/web/components/issues/sub-issues/root.tsx b/web/components/issues/sub-issues/root.tsx index abe334f16..88dab132c 100644 --- a/web/components/issues/sub-issues/root.tsx +++ b/web/components/issues/sub-issues/root.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useCallback } from "react"; // next imports import { useRouter } from "next/router"; // swr @@ -13,6 +13,7 @@ import { ProgressBar } from "./progressbar"; // ui import { CustomMenu } from "@plane/ui"; // hooks +import { useMobxStore } from "lib/mobx/store-provider"; import { useProjectMyMembership } from "contexts/project-member.context"; import useToast from "hooks/use-toast"; // helpers @@ -49,6 +50,8 @@ export const SubIssuesRoot: React.FC = ({ parentIssue, user }) = peekIssue: string; }; + const { issue: issueStore, issueDetail: issueDetailStore } = useMobxStore(); + const { memberRole } = useProjectMyMembership(); const { setToastAlert } = useToast(); @@ -158,6 +161,21 @@ export const SubIssuesRoot: React.FC = ({ parentIssue, user }) = }); }; + const handleUpdateIssue = useCallback( + (issue: IIssue, data: Partial) => { + if (!workspaceSlug || !projectId || !user) return; + + const payload = { + ...issue, + ...data, + }; + + issueStore.updateIssueStructure(null, null, payload); + issueDetailStore.updateIssue(workspaceSlug.toString(), projectId.toString(), issue.id, data); + }, + [issueStore, issueDetailStore, projectId, user, workspaceSlug] + ); + const isEditable = memberRole?.isGuest || memberRole?.isViewer ? false : true; const mutateSubIssues = (parentIssueId: string | null) => { @@ -228,6 +246,7 @@ export const SubIssuesRoot: React.FC = ({ parentIssue, user }) = handleIssuesLoader={handleIssuesLoader} copyText={copyText} handleIssueCrudOperation={handleIssueCrudOperation} + handleUpdateIssue={handleUpdateIssue} />
)} diff --git a/web/components/modules/gantt-chart/modules-list-layout.tsx b/web/components/modules/gantt-chart/modules-list-layout.tsx index b1da42fe1..693aec3a5 100644 --- a/web/components/modules/gantt-chart/modules-list-layout.tsx +++ b/web/components/modules/gantt-chart/modules-list-layout.tsx @@ -45,8 +45,8 @@ export const ModulesListGanttChartView: React.FC = observer(() => { loaderTitle="Modules" blocks={modules ? blockFormat(modules) : null} blockUpdateHandler={(block, payload) => handleModuleUpdate(block, payload)} - SidebarBlockRender={ModuleGanttSidebarBlock} - BlockRender={ModuleGanttBlock} + sidebarBlockToRender={ModuleGanttSidebarBlock} + blockToRender={(data: IModule) => } enableBlockLeftResize={isAllowed} enableBlockRightResize={isAllowed} enableBlockMove={isAllowed} diff --git a/web/store/issue/issue.store.ts b/web/store/issue/issue.store.ts index 924c91eb1..b2db11fb9 100644 --- a/web/store/issue/issue.store.ts +++ b/web/store/issue/issue.store.ts @@ -265,9 +265,10 @@ export class IssueStore implements IIssueStore { ...i, ...(i.id === issue.id ? { + ...issue, sort_order: payload.sort_order?.newSortOrder ?? i.sort_order, - start_date: payload.start_date, - target_date: payload.target_date, + start_date: payload.start_date ?? i.start_date, + target_date: payload.target_date ?? i.target_date, } : {}), })); @@ -288,7 +289,7 @@ export class IssueStore implements IIssueStore { }; }); - const newPayload: any = { ...payload }; + const newPayload: any = { ...issue, ...payload }; if (newPayload.sort_order && payload.sort_order) newPayload.sort_order = payload.sort_order.newSortOrder;