import type { ComponentType, ReactNode } from "react"; import { GanttPartialTheme } from "./theme-types"; import { GanttLocale } from "./theme-locale"; import { ChildByLevelMap, DateSetup, Distances, RelationMoveTarget, RootMapByLevel, Task, TaskBarMoveAction, RenderTask, ViewMode, TaskId } from "./common-types"; export type GanttDrawerData = { type: "task"; task: Task; } | { type: "arrow"; taskFrom: Task; taskTo: Task; }; export type RenderDrawerContent = (data: GanttDrawerData, goToTask: (taskId: string) => void) => ReactNode; export interface GanttDrawerProps { /** * Enable the drawer panel on task/arrow click */ enableDrawer?: boolean; /** * Width of the drawer panel in pixels. Defaults to 360. */ drawerWidth?: number; /** * Render function for custom drawer content */ renderDrawerContent?: RenderDrawerContent; /** * When set (or changed), the drawer will open and display the details of the * task with this id. Requires `enableDrawer: true`. * Set to `undefined` or change to a new id to control the drawer imperatively. */ openDrawerTaskId?: string; } export type RenderTopHeader = (date: Date, viewMode: ViewMode, dateSetup: DateSetup) => ReactNode; export type RenderCustomLabel = (task: RenderTask, x1: number, width: number, taskHeight: number, arrowIndent: number, taskYOffset: number, movingAction: TaskBarMoveAction | null, viewMode: ViewMode, rtl?: boolean) => ReactNode; export type RenderBottomHeader = (date: Date, viewMode: ViewMode, dateSetup: DateSetup, index: number, isUnknownDates: boolean) => ReactNode; export type OnArrowDoubleClick = (taskFrom: Task, taskFromIndex: number, taskTo: Task, taskToIndex: number) => void; export type OnRelationChange = ( /** * Task, from, index */ from: [Task, RelationMoveTarget, number], /** * Task, to, index */ to: [Task, RelationMoveTarget, number], /** * One of tasks is descendant of other task */ isOneDescendant: boolean) => void; export type OnDateChangeSuggestionType = [ /** * Start date */ Date, /** * End date */ Date, /** * Suggested task */ Task, /** * Index in array of tasks */ number ]; export type OnChangeTasksAction = { type: "add_tasks"; payload: { parent: RenderTask; descendants: readonly RenderTask[]; }; } | { type: "date_change"; payload: { taskId: string; taskIndex: number; start: Date; end: Date; }; } | { type: "delete_relation"; payload: { taskFrom: Task; taskFromIndex: number; taskTo: Task; taskToIndex: number; }; } | { type: "delete_task"; payload: { tasks: readonly RenderTask[]; taskIndexes: readonly number[]; }; } | { type: "edit_task"; } | { type: "move_task_before"; payload: { task: RenderTask; taskForMove: RenderTask; taskIndex: number; taskForMoveIndex: number; }; } | { type: "move_task_after"; payload: { task: RenderTask; taskForMove: RenderTask; taskIndex: number; taskForMoveIndex: number; }; } | { type: "move_task_inside"; payload: { parent: Task; childs: readonly RenderTask[]; dependentTasks: readonly Task[]; parentIndex: number; childIndexes: readonly number[]; }; } | { type: "progress_change"; payload: { task: Task; }; } | { type: "relation_change"; payload: { /** * Task, from, index */ from: [Task, RelationMoveTarget, number]; /** * Task, to, index */ to: [Task, RelationMoveTarget, number]; /** * One of tasks is descendant of other task */ isOneDescendant: boolean; }; } | { type: "expandState_change"; payload: { changedTask: Task; }; }; export type RelationKind = "startToStart" | "startToEnd" | "endToStart" | "endToEnd"; export type OnCommitTasksResult = boolean | undefined | void; export type OnCommitTasks = (nextTasks: readonly RenderTask[], action: OnChangeTasksAction) => Promise | OnCommitTasksResult; export interface GanttTaskListProps { enableTableListContextMenu?: number; contextMenuOptions?: ContextMenuOptionType[]; /** * Allow drag-n-drop of tasks in the table */ allowReorderTask?: AllowReorderTask; /** * Can resize columns */ canResizeColumns?: boolean; /** * Show column visibility toggle button in the header */ canToggleColumns?: boolean; /** * Custom icons */ icons?: Partial; /** * Show numbers of tasks next to tasks */ isShowTaskNumbers?: boolean; /** * Can reorder tasks */ canReorderTasks?: boolean; /** * Can reorder tasks */ onResizeColumn?: OnResizeColumn; /** * Callback when column visibility is toggled */ onColumnVisibilityChange?: OnColumnVisibilityChange; /** * Render bottom table content */ tableBottom?: TableRenderBottomProps; /** * Invokes on single click on a task list row. Receives the task data. */ onClickTaskRow?: (task: RenderTask) => void; /** * Invokes on double click on a task list row. Receives the task data. */ onDoubleClickTaskRow?: (task: RenderTask) => void; /** * Callback when a cell value is committed via inline editing. * Return a promise that resolves to the updated task, or void. */ onTaskInlineEdit?: (task: RenderTask, columnId: string, newValue: unknown) => void | Promise; } export interface TableRenderBottomProps { height?: number; renderContent?: () => ReactNode; } export interface GanttTaskBarProps extends GanttTaskBarActions { /** * Render function of bottom part of header above chart */ renderBottomHeader?: RenderBottomHeader; /** * Render function of top part of header above chart */ renderTopHeader?: RenderTopHeader; /** * Render custom label */ renderCustomLabel?: RenderCustomLabel; /** * Show critical path */ isShowCriticalPath?: boolean; isProgressChangeable?: (task: Task) => boolean; isRelationChangeable?: (task: Task) => boolean; isDateChangeable?: (task: Task) => boolean; isDeleteDependencyOnDoubleClick?: boolean; preStepsCount?: number; TooltipContent?: ComponentType<{ task: Task; }>; /** * Context menu options for right-click on the gantt chart area */ taskGanttContextMenuOption?: ContextMenuOptionType[]; /** * Invokes on double-click on the relation arrow between tasks */ onArrowDoubleClick?: OnArrowDoubleClick; /** * Invokes on click on the relation arrow between tasks */ onArrowClick?: (taskFrom: Task, taskTo: Task) => void; /** * Invokes on bar double click. */ onDoubleClick?: (task: Task) => void; /** * Invokes on bar click. */ onClick?: (task: RenderTask) => void; } export interface GanttRenderIconsProps { renderAddIcon: () => ReactNode; renderDragIndicatorIcon: () => ReactNode; renderClosedIcon: () => ReactNode; renderDeleteIcon: () => ReactNode; renderEditIcon: () => ReactNode; renderOpenedIcon: () => ReactNode; renderNoChildrenIcon: () => ReactNode; } export type InsertTaskPosition = "before" | "inside" | "after"; export type AllowReorderTask = (task: RenderTask, method: InsertTaskPosition) => boolean; export type CheckIsHoliday = (date: Date, minTaskDate: Date, dateSetup: DateSetup) => boolean; export interface GanttProps { /** * Language */ language?: string; /** * Theme */ theme?: GanttPartialTheme; /** * Locale */ locale?: GanttLocale; /** * Check is current date holiday * @param date the date * @param minTaskDate lower date of all tasks * @param dateSetup * @returns */ checkIsHoliday?: CheckIsHoliday; /** * Can be used to compare multiple graphs. This prop is the number of graps being compared */ comparisonLevels?: number; /** * Get new id for task after using copy-paste */ getCopiedTaskId?: GetCopiedTaskId; /** * Tasks */ tasks: readonly RenderTask[]; /** * Columns of the table */ columns?: readonly Column[]; /** * Round end date of task after move or resize * @param date Date after move * @param viewMode current date unit * @returns next date */ roundEndDate?: (date: Date, viewMode: ViewMode) => Date; /** * Round start date of task after move or resize * @param date Date after move * @param viewMode current date unit * @returns next date */ roundStartDate?: (date: Date, viewMode: ViewMode) => Date; /** * View mode */ viewMode?: ViewMode; /** * View date */ viewDate?: Date; /** * Task bar options */ taskBar?: GanttTaskBarProps; /** * Task list options */ taskList?: GanttTaskListProps; /** * Authorized relations between tasks */ authorizedRelations?: RelationKind[]; /** * Time step value for date changes. */ timeStep?: number; /** * Invokes on every commit of the list of tasks */ onCommitTasks?: OnCommitTasks; /** * Callback for getting data of the added task */ onAddTaskAction?: (task: Task | null) => Promise; /** * Callback for getting new data of the edited task */ onEditTaskAction?: (task: RenderTask) => Promise; /** * Callback for select task */ onSelectTaskIds?: (taskIds: TaskId[]) => void; /** * Invokes on wheel event * @param wheelEvent */ onWheel?: (wheelEvent: WheelEvent) => void; /** * Invokes when user right-clicks a row in the task list. Receives the full `task` object of the clicked row. */ onRowContextMenu?: (task: RenderTask) => void; /** * Recount descedents of a group task when moving */ isMoveChildsWithParent?: boolean; /** * Recount parents of tasks in callback `onCommitTasks` */ isUpdateDisabledParentsOnChange?: boolean; /** * Display offsets from start on timeline instead of dates */ isUnknownDates?: boolean; /** * Move dates of tasks to working days during change */ isAdjustToWorkingDates?: boolean; /** * Force row height (in pixels) for each single row. If not provided theme distances.rowHeight is used. */ rowHeight?: number; /** * Show vertical line for current day on the chart */ showTodayLine?: boolean; /** * Show vertical line for a custom 'data date' on the chart */ showDataDateLine?: boolean; /** * Custom date to render as data date line when `showDataDateLine` is true */ dataDate?: Date | null; /** * Color used for the today line, pin and label. If not provided, theme calendarTodayColor is used. */ todayColor?: string; /** * Color used for the data date line, pin and label. If not provided, theme calendarTodayColor is used. */ dataDateColor?: string; /** * Label text for the today marker. Defaults to "Today". */ todayLabel?: string; /** * Label text for the data date marker. Defaults to "Data Date". */ dataDateLabel?: string; /** * Show/hide progress bar on task bars. Defaults to true. */ showProgress?: boolean; /** * Hide the progress bar specifically on project type task bars. Defaults to false. */ hideProjectProgress?: boolean; /** * Custom color for progress bars. If not provided, theme progress colors are used. */ progressColor?: string; /** * When set (or changed), the gantt will scroll to reveal and select this task. * Set to a task id to scroll both horizontally and vertically to that task. */ scrollToTaskId?: TaskId; /** * Drawer panel options for task/arrow click */ drawer?: GanttDrawerProps; } export interface GanttTaskBarActions { allowMoveTaskBar?: (action: TaskBarMoveAction, task: RenderTask) => boolean; } export type ColumnData = { dateSetup: DateSetup; depth: number; dependencies: Task[]; distances: Distances; handleAddTask: (task: Task) => void; handleDeleteTasks: (task: RenderTask[]) => void; handleEditTask: (task: RenderTask) => void; hasChildren: boolean; icons?: Partial; indexStr: string; isClosed: boolean; isShowTaskNumbers: boolean; onExpanderClick: (task: Task) => void; task: RenderTask; /** * Whether this cell is currently in inline-edit mode. */ isEditing?: boolean; /** * Call to enter inline-edit mode for this column/cell. */ onStartEdit?: () => void; /** * Commit the edited value. `value` is the new raw value for the column. */ onCommitEdit?: (value: unknown) => void; /** * Cancel inline editing and revert to display mode. */ onCancelEdit?: () => void; }; export type ColumnProps = { data: ColumnData; }; /** * The type of inline editor to render when no custom `editComponent` is provided. * - `"text"` – a plain text input (default) * - `"date"` – a date input (``) * - `"number"` – a numeric input * - `"select"` – a `