[WEB-4531]chore: refactor for timeline chart (#7440)

This commit is contained in:
Vamsi Krishna 2025-07-21 19:22:58 +05:30 committed by GitHub
parent cc673a17a0
commit 4c3af7f8a1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 43 additions and 23 deletions

View file

@ -3,10 +3,10 @@ import { FC } from "react";
import type { IBlockUpdateData, IGanttBlock } from "@plane/types"; import type { IBlockUpdateData, IGanttBlock } from "@plane/types";
import RenderIfVisible from "@/components/core/render-if-visible-HOC"; import RenderIfVisible from "@/components/core/render-if-visible-HOC";
// hooks // hooks
import { BlockRow } from "@/components/gantt-chart/blocks/block-row";
import { BLOCK_HEIGHT } from "@/components/gantt-chart/constants";
import { TSelectionHelper } from "@/hooks/use-multiple-select"; import { TSelectionHelper } from "@/hooks/use-multiple-select";
// types // types
import { BLOCK_HEIGHT } from "../constants";
import { BlockRow } from "./block-row";
export type GanttChartBlocksProps = { export type GanttChartBlocksProps = {
blockIds: string[]; blockIds: string[];

View file

@ -1,7 +1,7 @@
import { FC } from "react"; import { FC } from "react";
// //
import type { IBlockUpdateDependencyData } from "@plane/types"; import type { IBlockUpdateDependencyData } from "@plane/types";
import { GanttChartBlock } from "./block"; import { GanttChartBlock } from "@/components/gantt-chart/blocks/block";
export type GanttChartBlocksProps = { export type GanttChartBlocksProps = {
blockIds: string[]; blockIds: string[];

View file

@ -3,7 +3,13 @@ import set from "lodash/set";
import { action, makeObservable, observable, runInAction } from "mobx"; import { action, makeObservable, observable, runInAction } from "mobx";
import { computedFn } from "mobx-utils"; import { computedFn } from "mobx-utils";
// components // components
import type { ChartDataType, IBlockUpdateDependencyData, IGanttBlock, TGanttViews } from "@plane/types"; import type {
ChartDataType,
IBlockUpdateDependencyData,
IGanttBlock,
TGanttViews,
EGanttBlockType,
} from "@plane/types";
import { renderFormattedPayloadDate } from "@plane/utils"; import { renderFormattedPayloadDate } from "@plane/utils";
import { currentViewDataWithView } from "@/components/gantt-chart/data"; import { currentViewDataWithView } from "@/components/gantt-chart/data";
import { import {
@ -177,7 +183,7 @@ export class BaseTimeLineStore implements IBaseTimelineStore {
* @param getDataById * @param getDataById
* @returns * @returns
*/ */
updateBlocks(getDataById: (id: string) => BlockData | undefined | null) { updateBlocks(getDataById: (id: string) => BlockData | undefined | null, type?: EGanttBlockType, index?: number) {
if (!this.blockIds || !Array.isArray(this.blockIds) || this.isDragging) return true; if (!this.blockIds || !Array.isArray(this.blockIds) || this.isDragging) return true;
const updatedBlockMaps: { path: string[]; value: any }[] = []; const updatedBlockMaps: { path: string[]; value: any }[] = [];
@ -195,7 +201,11 @@ export class BaseTimeLineStore implements IBaseTimelineStore {
sort_order: blockData?.sort_order ?? undefined, sort_order: blockData?.sort_order ?? undefined,
start_date: blockData?.start_date ?? undefined, start_date: blockData?.start_date ?? undefined,
target_date: blockData?.target_date ?? undefined, target_date: blockData?.target_date ?? undefined,
project_id: blockData?.project_id ?? undefined, meta: {
type,
index,
project_id: blockData?.project_id,
},
}; };
if (this.currentViewData && (this.currentViewData?.data?.startDate || this.currentViewData?.data?.dayWidth)) { if (this.currentViewData && (this.currentViewData?.data?.startDate || this.currentViewData?.data?.dayWidth)) {
block.position = getItemPositionWidth(this.currentViewData, block); block.position = getItemPositionWidth(this.currentViewData, block);
@ -285,7 +295,7 @@ export class BaseTimeLineStore implements IBaseTimelineStore {
if (!currBlock?.position || !this.currentViewData) return []; if (!currBlock?.position || !this.currentViewData) return [];
const updatePayload: IBlockUpdateDependencyData = { id }; const updatePayload: IBlockUpdateDependencyData = { id, meta: currBlock.meta };
// If shouldUpdateHalfBlock or the start date is available then update start date // If shouldUpdateHalfBlock or the start date is available then update start date
if (shouldUpdateHalfBlock || currBlock.start_date) { if (shouldUpdateHalfBlock || currBlock.start_date) {

View file

@ -7,17 +7,20 @@ export interface ITimelineStore {
issuesTimeLineStore: IIssuesTimeLineStore; issuesTimeLineStore: IIssuesTimeLineStore;
modulesTimeLineStore: IModulesTimeLineStore; modulesTimeLineStore: IModulesTimeLineStore;
projectTimeLineStore: IBaseTimelineStore; projectTimeLineStore: IBaseTimelineStore;
groupedTimeLineStore: IBaseTimelineStore;
} }
export class TimeLineStore implements ITimelineStore { export class TimeLineStore implements ITimelineStore {
issuesTimeLineStore: IIssuesTimeLineStore; issuesTimeLineStore: IIssuesTimeLineStore;
modulesTimeLineStore: IModulesTimeLineStore; modulesTimeLineStore: IModulesTimeLineStore;
projectTimeLineStore: IBaseTimelineStore; projectTimeLineStore: IBaseTimelineStore;
groupedTimeLineStore: IBaseTimelineStore;
constructor(rootStore: RootStore) { constructor(rootStore: RootStore) {
this.issuesTimeLineStore = new IssuesTimeLineStore(rootStore); this.issuesTimeLineStore = new IssuesTimeLineStore(rootStore);
this.modulesTimeLineStore = new ModulesTimeLineStore(rootStore); this.modulesTimeLineStore = new ModulesTimeLineStore(rootStore);
// Dummy store // Dummy store
this.projectTimeLineStore = new BaseTimeLineStore(rootStore); this.projectTimeLineStore = new BaseTimeLineStore(rootStore);
this.groupedTimeLineStore = new BaseTimeLineStore(rootStore);
} }
} }

View file

@ -1 +0,0 @@
export * from "./blocks-list";

View file

@ -6,23 +6,18 @@ import { ChartDataType, IBlockUpdateData, IBlockUpdateDependencyData, IGanttBloc
import { cn, getDate } from "@plane/utils"; import { cn, getDate } from "@plane/utils";
// components // components
import { MultipleSelectGroup } from "@/components/core"; import { MultipleSelectGroup } from "@/components/core";
import { import { GanttChartSidebar, MonthChartView, QuarterChartView, WeekChartView } from "@/components/gantt-chart";
GanttChartBlocksList,
GanttChartSidebar,
MonthChartView,
QuarterChartView,
WeekChartView,
} from "@/components/gantt-chart";
// helpers // helpers
// hooks // hooks
import { useTimeLineChartStore } from "@/hooks/use-timeline-chart"; import { useTimeLineChartStore } from "@/hooks/use-timeline-chart";
// plane web components // plane web components
import { TimelineDependencyPaths, TimelineDraggablePath } from "@/plane-web/components/gantt-chart"; import { TimelineDependencyPaths, TimelineDraggablePath } from "@/plane-web/components/gantt-chart";
import { GanttChartRowList } from "@/plane-web/components/gantt-chart/blocks/block-row-list";
import { GanttChartBlocksList } from "@/plane-web/components/gantt-chart/blocks/blocks-list";
import { IssueBulkOperationsRoot } from "@/plane-web/components/issues"; import { IssueBulkOperationsRoot } from "@/plane-web/components/issues";
// plane web hooks // plane web hooks
import { useBulkOperationStatus } from "@/plane-web/hooks/use-bulk-operation-status"; import { useBulkOperationStatus } from "@/plane-web/hooks/use-bulk-operation-status";
// //
import { GanttChartRowList } from "../blocks/block-row-list";
import { DEFAULT_BLOCK_WIDTH, GANTT_SELECT_GROUP, HEADER_HEIGHT } from "../constants"; import { DEFAULT_BLOCK_WIDTH, GANTT_SELECT_GROUP, HEADER_HEIGHT } from "../constants";
import { getItemPositionWidth } from "../views"; import { getItemPositionWidth } from "../views";
import { TimelineDragHelper } from "./timeline-drag-helper"; import { TimelineDragHelper } from "./timeline-drag-helper";

View file

@ -4,6 +4,7 @@ export enum ETimeLineTypeType {
ISSUE = "ISSUE", ISSUE = "ISSUE",
MODULE = "MODULE", MODULE = "MODULE",
PROJECT = "PROJECT", PROJECT = "PROJECT",
GROUPED = "GROUPED",
} }
export const TimeLineTypeContext = createContext<ETimeLineTypeType | undefined>(undefined); export const TimeLineTypeContext = createContext<ETimeLineTypeType | undefined>(undefined);

View file

@ -48,6 +48,7 @@ export const ChartAddBlock: React.FC<Props> = observer((props) => {
blockUpdateHandler(block.data, { blockUpdateHandler(block.data, {
start_date: renderFormattedPayloadDate(startDate) ?? undefined, start_date: renderFormattedPayloadDate(startDate) ?? undefined,
target_date: renderFormattedPayloadDate(endDate) ?? undefined, target_date: renderFormattedPayloadDate(endDate) ?? undefined,
meta: block.meta,
}); });
}; };

View file

@ -53,7 +53,7 @@ export const ChartDraggable: React.FC<Props> = observer((props) => {
})} })}
onMouseDown={(e) => enableBlockMove && handleBlockDrag(e, "move")} onMouseDown={(e) => enableBlockMove && handleBlockDrag(e, "move")}
> >
{blockToRender(block.data)} {blockToRender({ ...block.data, meta: block.meta })}
</div> </div>
{/* right resize drag handle */} {/* right resize drag handle */}
<RightResizable <RightResizable

View file

@ -1,4 +1,3 @@
export * from "./blocks";
export * from "./chart"; export * from "./chart";
export * from "./helpers"; export * from "./helpers";
export * from "./root"; export * from "./root";

View file

@ -2,7 +2,7 @@ import { RefObject } from "react";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import { useTranslation } from "@plane/i18n"; import { useTranslation } from "@plane/i18n";
// components // components
import type { ChartDataType, IBlockUpdateData, IGanttBlock } from "@plane/types"; import type { IBlockUpdateData } from "@plane/types";
import { Row, ERowVariant } from "@plane/ui"; import { Row, ERowVariant } from "@plane/ui";
import { cn } from "@plane/utils"; import { cn } from "@plane/utils";
import { MultipleSelectGroupAction } from "@/components/core"; import { MultipleSelectGroupAction } from "@/components/core";
@ -82,7 +82,7 @@ export const GanttChartSidebar: React.FC<Props> = observer((props) => {
<h6>{t("common.duration")}</h6> <h6>{t("common.duration")}</h6>
</Row> </Row>
<Row variant={ERowVariant.HUGGING} className="min-h-full h-max bg-custom-background-100 overflow-hidden"> <Row variant={ERowVariant.HUGGING} className="min-h-full h-max bg-custom-background-100">
{sidebarToRender && {sidebarToRender &&
sidebarToRender({ sidebarToRender({
title, title,

View file

@ -17,6 +17,8 @@ export const useTimeLineChart = (timeLineType: ETimeLineTypeType): IBaseTimeline
return context.timelineStore.modulesTimeLineStore as IBaseTimelineStore; return context.timelineStore.modulesTimeLineStore as IBaseTimelineStore;
case ETimeLineTypeType.PROJECT: case ETimeLineTypeType.PROJECT:
return context.timelineStore.projectTimeLineStore as IBaseTimelineStore; return context.timelineStore.projectTimeLineStore as IBaseTimelineStore;
case ETimeLineTypeType.GROUPED:
return context.timelineStore.groupedTimeLineStore as IBaseTimelineStore;
} }
}; };

View file

@ -0,0 +1 @@
export * from "ce/components/gantt-chart/blocks/block-row-list";

View file

@ -0,0 +1 @@
export * from "ce/components/gantt-chart/blocks/blocks-list";

View file

@ -1,3 +1,8 @@
export enum EGanttBlockType {
EPIC = "epic",
PROJECT = "project",
ISSUE = "issue",
}
export interface IGanttBlock { export interface IGanttBlock {
data: any; data: any;
id: string; id: string;
@ -9,7 +14,7 @@ export interface IGanttBlock {
sort_order: number | undefined; sort_order: number | undefined;
start_date: string | undefined; start_date: string | undefined;
target_date: string | undefined; target_date: string | undefined;
project_id: string | undefined; meta?: Record<string, any>;
} }
export interface IBlockUpdateData { export interface IBlockUpdateData {
@ -20,13 +25,14 @@ export interface IBlockUpdateData {
}; };
start_date?: string; start_date?: string;
target_date?: string; target_date?: string;
meta?: Record<string, any>;
} }
export interface IBlockUpdateDependencyData { export interface IBlockUpdateDependencyData {
id: string; id: string;
start_date?: string; start_date?: string;
target_date?: string; target_date?: string;
project_id?: string; meta?: Record<string, any>;
} }
export type TGanttViews = "week" | "month" | "quarter"; export type TGanttViews = "week" | "month" | "quarter";

View file

@ -190,7 +190,9 @@ export const getIssueBlocksStructure = (block: TIssue): IGanttBlock => ({
sort_order: block?.sort_order, sort_order: block?.sort_order,
start_date: block?.start_date ?? undefined, start_date: block?.start_date ?? undefined,
target_date: block?.target_date ?? undefined, target_date: block?.target_date ?? undefined,
project_id: block?.project_id ?? undefined, meta: {
project_id: block?.project_id ?? undefined,
},
}); });
export const formatTextList = (TextArray: string[]): string => { export const formatTextList = (TextArray: string[]): string => {