UNPKG

@progress/kendo-react-gantt

Version:

React Gantt enables the display of self-referencing tabular data with many features. KendoReact Gantt package

374 lines (373 loc) 11.6 kB
/** * @license *------------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the package root for more information *------------------------------------------------------------------------------------------- */ import * as a from "react"; import n from "prop-types"; import { getTaskModelFields as xe, getDependencyModelFields as Fe, expandedChildren as Ve } from "./utils/index.mjs"; import { useInternationalization as Ie } from "@progress/kendo-react-intl"; import { GanttContext as He } from "./context/GanttContext.mjs"; import { GanttWeekView as M, ganttWeekViewDefaultProps as ze } from "./views/GanttWeekView.mjs"; import { GanttDayView as Ae, ganttDayViewDefaultProps as Ge } from "./views/GanttDayView.mjs"; import { GanttMonthView as Ne, ganttMonthViewDefaultProps as Pe } from "./views/GanttMonthView.mjs"; import { GanttYearView as Ke, ganttYearViewDefaultProps as Le } from "./views/GanttYearView.mjs"; import { flatData as We } from "@progress/kendo-react-treelist"; import { validatePackage as Be, getLicenseMessage as Oe, getter as h, useIsomorphicLayoutEffect as Ye, classNames as je, WatermarkOverlay as Ue } from "@progress/kendo-react-common"; import { useControlledState as _e } from "./hooks/useControlledState.mjs"; import { ViewSelectorList as qe } from "./components/toolbar/view-selector/ViewSelectorList.mjs"; import { ViewSelector as Je } from "./components/toolbar/view-selector/ViewSelector.mjs"; import { Toolbar as Qe } from "./components/toolbar/Toolbar.mjs"; import { ToolbarSpacer as Xe } from "@progress/kendo-react-buttons"; import { DEFAULT_DATE as I } from "./constants/index.mjs"; import { packageMetadata as H } from "./package-metadata.mjs"; import { AddButton as Ze } from "./components/toolbar/AddButton.mjs"; const z = a.forwardRef((e, A) => { const G = !Be(H, { component: "Gantt" }), N = Oe(H), { columns: P = R.columns, taskData: v = R.taskData, dependencyData: K = R.dependencyData, style: L, className: W, noRecords: B, timezone: S, rowHeight: O = R.rowHeight, resizable: Y, reorderable: j, sortable: U, sort: _, filter: q, columnMenuFilter: J, columnMenu: Q, navigatable: X, toolbar: T, row: Z, selectable: $ } = e, d = /* @__PURE__ */ new Map(); d.set(Ae, Ge), d.set(Ne, Pe), d.set(M, ze), d.set(Ke, Le); const p = Ie(), { fields: o } = a.useMemo( () => xe(e.taskModelFields), [e.taskModelFields] ), { fields: ee } = a.useMemo( () => Fe(e.dependencyModelFields), [e.dependencyModelFields] ), E = a.useCallback( Ve(o.isExpanded, o.children), [o.isExpanded, o.children] ), w = a.useRef(null), c = a.useRef(null), i = a.useRef(null), g = a.useRef(null), C = a.useRef(null), ne = a.useCallback( (t) => { const r = h(o.start)(t), u = h(o.end)(t), D = h(o.isSelected)(t); (!c.current || r < c.current) && (c.current = r), (!i.current || u > i.current) && (i.current = u), D && (g.current = t); }, [o.start, o.end] ), m = a.useMemo(() => (c.current = null, i.current = null, g.current = null, We(v, E, ne)), [v, E]); (!c.current || !i.current) && (c.current = new Date(I), i.current = new Date(I)); const f = a.Children.toArray(e.children || []).map( (t) => { var r; return a.isValidElement(t) ? a.cloneElement(t, { ...d.get(t.type), ...(r = t.props) != null ? r : {} }) : t; } ), te = a.cloneElement(/* @__PURE__ */ a.createElement(M, null), d.get(M)), x = f.length ? f[0] : te, [F, ae] = _e( e.defaultView || x.props.name, e.view, e.onViewChange ), s = f.find((t) => t.props.name === F) || x, le = typeof s.props.dateRange == "function" ? s.props.dateRange.call(void 0, { intl: p, tasksStart: c.current, tasksEnd: i.current, timezone: S }) : s.props.dateRange, b = a.useRef(null), [oe, re] = a.useState(0); Ye(() => { b.current && re(b.current.element.offsetHeight); }, []); const ce = a.useCallback((t) => { w.current && w.current.scrollIntoView(t); }, []), V = a.useRef(null), l = a.useRef(null); a.useImperativeHandle(l, () => ({ props: e, element: V.current, scrollIntoView: ce })), a.useImperativeHandle(A, () => l.current); const ie = a.useCallback( (t) => { e.onDataStateChange && e.onDataStateChange.call(void 0, { ...t, target: l.current }); }, [e.onDataStateChange] ), se = a.useCallback( (t) => { e.onSortChange && e.onSortChange.call(void 0, { ...t, target: l.current }); }, [e.onSortChange] ), de = a.useCallback( (t) => { e.onKeyDown && e.onKeyDown.call(void 0, { ...t, target: l.current }); }, [e.onKeyDown] ), ue = a.useCallback( (t) => { e.onSelectionChange && e.onSelectionChange.call(void 0, { ...t, target: l.current }); }, [e.onSelectionChange] ), Ce = a.useCallback( (t) => { e.onHeaderSelectionChange && e.onHeaderSelectionChange.call(void 0, { ...t, target: l.current }); }, [e.onHeaderSelectionChange] ), ge = a.useCallback( (t) => { e.onFilterChange && e.onFilterChange.call(void 0, { ...t, target: l.current }); }, [e.onFilterChange] ), me = a.useCallback( (t) => { e.onColumnMenuFilterChange && e.onColumnMenuFilterChange.call(void 0, { ...t, target: l.current }); }, [e.onColumnMenuFilterChange] ), fe = a.useCallback( (t) => { e.onExpandChange && e.onExpandChange.call(void 0, { ...t, target: l.current }); }, [e.onExpandChange] ), ke = a.useCallback( (t) => { e.onAddClick && e.onAddClick.call(void 0, { ...t, target: l.current, selectedDataItem: g.current, slotStart: C.current && new Date(C.current.start.getTime()), slotEnd: C.current && new Date(C.current.end.getTime()) }); }, [e.onAddClick] ), he = a.useCallback( (t) => { e.onColumnResize && e.onColumnResize.call(void 0, { ...t, target: l.current }); }, [e.onColumnResize] ), Re = a.useCallback( (t) => { e.onColumnReorder && e.onColumnReorder.call(void 0, { ...t, target: l.current }); }, [e.onColumnReorder] ), we = a.useCallback( (t) => { e.onRowClick && e.onRowClick.call(void 0, { ...t, target: l.current }); }, [e.onRowClick] ), be = a.useCallback( (t) => { e.onRowDoubleClick && e.onRowDoubleClick.call(void 0, { ...t, target: l.current }); }, [e.onRowClick] ), De = a.useCallback( (t) => { e.onRowContextMenu && e.onRowContextMenu.call(void 0, { ...t, target: l.current }); }, [e.onRowClick] ), ye = a.useCallback( (t) => { e.onTaskClick && e.onTaskClick.call(void 0, { ...t, target: l.current }); }, [e.onTaskClick] ), Me = a.useCallback( (t) => { e.onTaskDoubleClick && e.onTaskDoubleClick.call(void 0, { ...t, target: l.current }); }, [e.onTaskDoubleClick] ), ve = a.useCallback( (t) => { e.onTaskContextMenu && e.onTaskContextMenu.call(void 0, { ...t, target: l.current }); }, [e.onTaskContextMenu] ), Se = a.useCallback( (t) => { e.onTaskRemoveClick && e.onTaskRemoveClick.call(void 0, { ...t, target: l.current }); }, [e.onTaskRemoveClick] ), Te = a.useCallback( (t) => { if (e.onDependencyCreate) { let r, u; const D = h(o.id); for (let y = 0; y < m.length; y++) { const Ee = m[y], k = D(Ee.dataItem); if (String(k) === t.fromId && (r = k), String(k) === t.toId && (u = k), r && u) break; } e.onDependencyCreate.call(void 0, { fromId: r, toId: u, target: l.current, type: t.type }); } }, [e.onDependencyCreate, o, m] ); return /* @__PURE__ */ a.createElement( He, { dateRange: le, taskData: m, dependencyData: K, taskModelFields: o, dependencyModelFields: ee, views: f, activeView: [F, ae], rowHeight: O, toolbarHeight: oe, props: { columns: P, noRecords: B, timezone: S, resizable: Y, reorderable: j, sortable: U, sort: _, filter: q, columnMenuFilter: J, columnMenu: Q, navigatable: X, row: Z, selectable: $ }, events: { onDataStateChange: ie, onSortChange: se, onFilterChange: ge, onColumnMenuFilterChange: me, onExpandChange: fe, onRowClick: we, onRowDoubleClick: be, onRowContextMenu: De, onColumnResize: he, onColumnReorder: Re, onDependencyCreate: e.onDependencyCreate && Te, onKeyDown: de, onSelectionChange: ue, onHeaderSelectionChange: Ce }, taskEvents: { onTaskClick: ye, onTaskDoubleClick: Me, onTaskContextMenu: ve, onTaskRemoveClick: e.onTaskRemoveClick && Se } }, /* @__PURE__ */ a.createElement("div", { ref: V, role: "application", style: L, className: je("k-gantt", W) }, /* @__PURE__ */ a.createElement(Qe, { ref: b }, T && T.addTaskButton ? /* @__PURE__ */ a.createElement(Ze, { selectedTask: g.current, onClick: ke }) : null, /* @__PURE__ */ a.createElement(Xe, null), /* @__PURE__ */ a.createElement(Je, null, /* @__PURE__ */ a.createElement(qe, null))), s && /* @__PURE__ */ a.createElement( s.type, { key: s.props.name, ref: w, ...s.props, firstSlotRangeRef: C } ), G && /* @__PURE__ */ a.createElement(Ue, { message: N })) ); }), R = { taskData: [], dependencyData: [], columns: [], rowHeight: 40 }; z.propTypes = { taskData: n.array, taskModelFields: n.shape({ id: n.string, start: n.string, end: n.string, title: n.string, percentComplete: n.string, parentId: n.string, isRollup: n.string, isExpanded: n.string, children: n.string, isInEdit: n.string }), dependencyData: n.array, dependencyModelFields: n.shape({ id: n.string, fromId: n.string, toId: n.string, type: n.string }), columns: n.arrayOf( n.shape({ width: n.number, cell: n.any, editCell: n.any, headerCell: n.any, filter: n.any, children: n.any, field: n.string, title: n.string, sortable: n.any, expandable: n.bool, headerSelectionValue: n.bool, format: n.string, headerClassName: n.string, className: n.string, resizable: n.bool, reorderable: n.bool, minResizableWidth: n.number, orderIndex: n.number, columnMenu: n.any }) ), sort: n.array, filter: n.array, columnMenuFilter: n.array, columnMenu: n.any, style: n.object, className: n.string, children: n.any, timezone: n.string, defaultView: n.string, view: n.string, rowHeight: n.number, navigatable: n.bool, onViewChange: n.func, onDataStateChange: n.func, onSortChange: n.func, onFilterChange: n.func, onExpandChange: n.func, onRowClick: n.func, onColumnResize: n.func, onColumnReorder: n.func }; z.displayName = "KendoReactGantt"; export { z as Gantt, R as ganttDefaultProps };