forked from github/plane
94 lines
3.3 KiB
TypeScript
94 lines
3.3 KiB
TypeScript
import React from "react";
|
|
import { useRouter } from "next/router";
|
|
import { observer } from "mobx-react-lite";
|
|
// hooks
|
|
import { useIssues, useUser } from "hooks/store";
|
|
// components
|
|
import { IssueGanttBlock } from "components/issues";
|
|
import {
|
|
GanttChartRoot,
|
|
IBlockUpdateData,
|
|
renderIssueBlocksStructure,
|
|
IssueGanttSidebar,
|
|
} from "components/gantt-chart";
|
|
// types
|
|
import { TIssue, TUnGroupedIssues } from "@plane/types";
|
|
import { ICycleIssues, ICycleIssuesFilter } from "store/issue/cycle";
|
|
import { IModuleIssues, IModuleIssuesFilter } from "store/issue/module";
|
|
import { IProjectIssues, IProjectIssuesFilter } from "store/issue/project";
|
|
import { IProjectViewIssues, IProjectViewIssuesFilter } from "store/issue/project-views";
|
|
// constants
|
|
import { EUserProjectRoles } from "constants/project";
|
|
import { EIssueActions } from "../types";
|
|
|
|
interface IBaseGanttRoot {
|
|
issueFiltersStore: IProjectIssuesFilter | IModuleIssuesFilter | ICycleIssuesFilter | IProjectViewIssuesFilter;
|
|
issueStore: IProjectIssues | IModuleIssues | ICycleIssues | IProjectViewIssues;
|
|
viewId?: string;
|
|
issueActions: {
|
|
[EIssueActions.DELETE]: (issue: TIssue) => Promise<void>;
|
|
[EIssueActions.UPDATE]?: (issue: TIssue) => Promise<void>;
|
|
[EIssueActions.REMOVE]?: (issue: TIssue) => Promise<void>;
|
|
};
|
|
}
|
|
|
|
export const BaseGanttRoot: React.FC<IBaseGanttRoot> = observer((props: IBaseGanttRoot) => {
|
|
const { issueFiltersStore, issueStore, viewId } = props;
|
|
// router
|
|
const router = useRouter();
|
|
const { workspaceSlug } = router.query;
|
|
// store hooks
|
|
const {
|
|
membership: { currentProjectRole },
|
|
} = useUser();
|
|
const { issueMap } = useIssues();
|
|
const appliedDisplayFilters = issueFiltersStore.issueFilters?.displayFilters;
|
|
|
|
const issueIds = (issueStore.groupedIssueIds ?? []) as TUnGroupedIssues;
|
|
const { enableIssueCreation } = issueStore?.viewFlags || {};
|
|
|
|
const issues = issueIds.map((id) => issueMap?.[id]);
|
|
|
|
const updateIssueBlockStructure = async (issue: TIssue, data: IBlockUpdateData) => {
|
|
if (!workspaceSlug) return;
|
|
|
|
const payload: any = { ...data };
|
|
if (data.sort_order) payload.sort_order = data.sort_order.newSortOrder;
|
|
|
|
await issueStore.updateIssue(workspaceSlug.toString(), issue.project_id, issue.id, payload, viewId);
|
|
};
|
|
|
|
const isAllowed = !!currentProjectRole && currentProjectRole >= EUserProjectRoles.MEMBER;
|
|
|
|
return (
|
|
<>
|
|
<div className="h-full w-full">
|
|
<GanttChartRoot
|
|
border={false}
|
|
title="Issues"
|
|
loaderTitle="Issues"
|
|
blocks={issues ? renderIssueBlocksStructure(issues as TIssue[]) : null}
|
|
blockUpdateHandler={updateIssueBlockStructure}
|
|
blockToRender={(data: TIssue) => <IssueGanttBlock issueId={data.id} />}
|
|
sidebarToRender={(props) => (
|
|
<IssueGanttSidebar
|
|
{...props}
|
|
quickAddCallback={issueStore.quickAddIssue}
|
|
viewId={viewId}
|
|
enableQuickIssueCreate
|
|
disableIssueCreation={!enableIssueCreation || !isAllowed}
|
|
showAllBlocks
|
|
/>
|
|
)}
|
|
enableBlockLeftResize={isAllowed}
|
|
enableBlockRightResize={isAllowed}
|
|
enableBlockMove={isAllowed}
|
|
enableReorder={appliedDisplayFilters?.order_by === "sort_order" && isAllowed}
|
|
enableAddBlock={isAllowed}
|
|
showAllBlocks
|
|
/>
|
|
</div>
|
|
</>
|
|
);
|
|
});
|