[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
16 changed files with 43 additions and 23 deletions
@@ -3,10 +3,10 @@ import { FC } from "react";
import type { IBlockUpdateData, IGanttBlock } from "@plane/types";
import RenderIfVisible from "@/components/core/render-if-visible-HOC";
// 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";
// types
import { BLOCK_HEIGHT } from "../constants";
import { BlockRow } from "./block-row";
export type GanttChartBlocksProps = {
blockIds: string[];
@@ -1,7 +1,7 @@
import { FC } from "react";
//
import type { IBlockUpdateDependencyData } from "@plane/types";
import { GanttChartBlock } from "./block";
import { GanttChartBlock } from "@/components/gantt-chart/blocks/block";
export type GanttChartBlocksProps = {
blockIds: string[];
@@ -3,7 +3,13 @@ import set from "lodash/set";
import { action, makeObservable, observable, runInAction } from "mobx";
import { computedFn } from "mobx-utils";
// 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 { currentViewDataWithView } from "@/components/gantt-chart/data";
import {
@@ -177,7 +183,7 @@ export class BaseTimeLineStore implements IBaseTimelineStore {
* @param getDataById
* @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;
const updatedBlockMaps: { path: string[]; value: any }[] = [];
@@ -195,7 +201,11 @@ export class BaseTimeLineStore implements IBaseTimelineStore {
sort_order: blockData?.sort_order ?? undefined,
start_date: blockData?.start_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)) {
block.position = getItemPositionWidth(this.currentViewData, block);
@@ -285,7 +295,7 @@ export class BaseTimeLineStore implements IBaseTimelineStore {
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 || currBlock.start_date) {
+3
View File
@@ -7,17 +7,20 @@ export interface ITimelineStore {
issuesTimeLineStore: IIssuesTimeLineStore;
modulesTimeLineStore: IModulesTimeLineStore;
projectTimeLineStore: IBaseTimelineStore;
groupedTimeLineStore: IBaseTimelineStore;
}
export class TimeLineStore implements ITimelineStore {
issuesTimeLineStore: IIssuesTimeLineStore;
modulesTimeLineStore: IModulesTimeLineStore;
projectTimeLineStore: IBaseTimelineStore;
groupedTimeLineStore: IBaseTimelineStore;
constructor(rootStore: RootStore) {
this.issuesTimeLineStore = new IssuesTimeLineStore(rootStore);
this.modulesTimeLineStore = new ModulesTimeLineStore(rootStore);
// Dummy store
this.projectTimeLineStore = new BaseTimeLineStore(rootStore);
this.groupedTimeLineStore = new BaseTimeLineStore(rootStore);
}
}
@@ -1 +0,0 @@
export * from "./blocks-list";
@@ -6,23 +6,18 @@ import { ChartDataType, IBlockUpdateData, IBlockUpdateDependencyData, IGanttBloc
import { cn, getDate } from "@plane/utils";
// components
import { MultipleSelectGroup } from "@/components/core";
import {
GanttChartBlocksList,
GanttChartSidebar,
MonthChartView,
QuarterChartView,
WeekChartView,
} from "@/components/gantt-chart";
import { GanttChartSidebar, MonthChartView, QuarterChartView, WeekChartView } from "@/components/gantt-chart";
// helpers
// hooks
import { useTimeLineChartStore } from "@/hooks/use-timeline-chart";
// plane web components
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";
// plane web hooks
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 { getItemPositionWidth } from "../views";
import { TimelineDragHelper } from "./timeline-drag-helper";
@@ -4,6 +4,7 @@ export enum ETimeLineTypeType {
ISSUE = "ISSUE",
MODULE = "MODULE",
PROJECT = "PROJECT",
GROUPED = "GROUPED",
}
export const TimeLineTypeContext = createContext<ETimeLineTypeType | undefined>(undefined);
@@ -48,6 +48,7 @@ export const ChartAddBlock: React.FC<Props> = observer((props) => {
blockUpdateHandler(block.data, {
start_date: renderFormattedPayloadDate(startDate) ?? undefined,
target_date: renderFormattedPayloadDate(endDate) ?? undefined,
meta: block.meta,
});
};
@@ -53,7 +53,7 @@ export const ChartDraggable: React.FC<Props> = observer((props) => {
})}
onMouseDown={(e) => enableBlockMove && handleBlockDrag(e, "move")}
>
{blockToRender(block.data)}
{blockToRender({ ...block.data, meta: block.meta })}
</div>
{/* right resize drag handle */}
<RightResizable
@@ -1,4 +1,3 @@
export * from "./blocks";
export * from "./chart";
export * from "./helpers";
export * from "./root";
@@ -2,7 +2,7 @@ import { RefObject } from "react";
import { observer } from "mobx-react";
import { useTranslation } from "@plane/i18n";
// components
import type { ChartDataType, IBlockUpdateData, IGanttBlock } from "@plane/types";
import type { IBlockUpdateData } from "@plane/types";
import { Row, ERowVariant } from "@plane/ui";
import { cn } from "@plane/utils";
import { MultipleSelectGroupAction } from "@/components/core";
@@ -82,7 +82,7 @@ export const GanttChartSidebar: React.FC<Props> = observer((props) => {
<h6>{t("common.duration")}</h6>
</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({
title,
@@ -17,6 +17,8 @@ export const useTimeLineChart = (timeLineType: ETimeLineTypeType): IBaseTimeline
return context.timelineStore.modulesTimeLineStore as IBaseTimelineStore;
case ETimeLineTypeType.PROJECT:
return context.timelineStore.projectTimeLineStore as IBaseTimelineStore;
case ETimeLineTypeType.GROUPED:
return context.timelineStore.groupedTimeLineStore as IBaseTimelineStore;
}
};
@@ -0,0 +1 @@
export * from "ce/components/gantt-chart/blocks/block-row-list";
@@ -0,0 +1 @@
export * from "ce/components/gantt-chart/blocks/blocks-list";
+8 -2
View File
@@ -1,3 +1,8 @@
export enum EGanttBlockType {
EPIC = "epic",
PROJECT = "project",
ISSUE = "issue",
}
export interface IGanttBlock {
data: any;
id: string;
@@ -9,7 +14,7 @@ export interface IGanttBlock {
sort_order: number | undefined;
start_date: string | undefined;
target_date: string | undefined;
project_id: string | undefined;
meta?: Record<string, any>;
}
export interface IBlockUpdateData {
@@ -20,13 +25,14 @@ export interface IBlockUpdateData {
};
start_date?: string;
target_date?: string;
meta?: Record<string, any>;
}
export interface IBlockUpdateDependencyData {
id: string;
start_date?: string;
target_date?: string;
project_id?: string;
meta?: Record<string, any>;
}
export type TGanttViews = "week" | "month" | "quarter";
+3 -1
View File
@@ -190,7 +190,9 @@ export const getIssueBlocksStructure = (block: TIssue): IGanttBlock => ({
sort_order: block?.sort_order,
start_date: block?.start_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 => {