UNPKG

@progress/kendo-react-gantt

Version:

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

249 lines (248 loc) 8.79 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 e from "react"; import { useGanttPropsContext as Ae, useGanttEventsContext as Ne, useGanttRowHeightContext as Xe, useGanttToolbarHeightContext as Ye, useGanttTaskModelFieldsContext as Pe, useGanttDependencyModelFieldsContext as We, useGanttTaskDataContext as _e, useGanttDependencyDataContext as ze } from "../context/GanttContext.mjs"; import { GanttViewContext as Ve } from "../context/GanttViewContext.mjs"; import { GanttTask as ve } from "./GanttTask.mjs"; import { useDictionaryStore as Oe } from "../hooks/useDictionaryStore.mjs"; import { GanttDependency as $e } from "./GanttDependency.mjs"; import { getTimelineHeader as Ke, getTimelineContent as Be, getTimelineWidth as Ue } from "../utils/index.mjs"; import { readColumns as je, mapColumns as qe } from "@progress/kendo-react-data-tools"; import { DEFAULT_COLUMN_WIDTH as Je, DEPENDENCY_DRAG_HANDLE as S, TASK_ID_ATT as A } from "../constants/index.mjs"; import { GanttTreeList as Qe } from "./GanttTreelist.mjs"; import { useId as N, getter as Ze } from "@progress/kendo-react-common"; const et = e.forwardRef((X, Y) => { const { slotLevels: E, slotWidth: P, timelineHeaderCell: W } = X, { columns: k, noRecords: _, resizable: z, reorderable: V, sortable: v, sort: O, filter: $, columnMenuFilter: K, columnMenu: B, navigatable: U, row: j, selectable: q } = Ae(), { onDataStateChange: J, onSortChange: Q, onFilterChange: Z, onColumnMenuFilterChange: ee, onExpandChange: te, onRowClick: ne, onRowDoubleClick: re, onRowContextMenu: oe, onColumnResize: b, onColumnReorder: se, onDependencyCreate: m, onKeyDown: le, onSelectionChange: ce, onHeaderSelectionChange: ae } = Ne(), ie = Xe(), ue = Ye(), i = Pe(), fe = We(), y = _e(), de = ze(), x = e.useRef(null), I = e.useRef(null), u = e.useRef(null), p = e.useRef(null), L = e.useRef(0), F = e.useRef(N()), me = e.useRef(N()), c = e.useRef(null), G = e.useRef(null), pe = e.useCallback((t) => { u.current && u.current.scrollIntoView(t); }, []); e.useImperativeHandle(G, () => ({ scrollIntoView: pe })), e.useImperativeHandle(Y, () => G.current); const C = e.useRef(0), g = e.useRef(0), R = e.useRef(0), h = e.useRef(0), f = e.useRef(null), T = e.useRef(null), [d, w] = e.useState(null), Ce = Ke(E, x, W), ge = Be(E, I), D = Ue(E, P), { extendedColumns: Re, columnsWidth: he, columnsMap: De } = e.useMemo(() => { const t = je( [ ...k, { title: "", sortable: !1, resizable: !1, reorderable: !1, width: D, headerCell: () => Ce, cell: ve, orderIndex: Number.MAX_SAFE_INTEGER, navigatable: !1 } ], { prevId: 0, idPrefix: F.current } ); let r = 0; return t.forEach((n, o, l) => { const s = o + 1 === l.length, a = n.children.length === 0; s ? n.isAccessible = !1 : (n.locked = !0, a && (n.width = n.width || Je)), a && (r += parseFloat(String(n.width))); }), { extendedColumns: t, columnsWidth: r, columnsMap: qe(t) }; }, [k, D]), [Ee, be] = Oe(), H = e.useCallback( () => x.current && x.current.parentElement, [] ), M = () => { const t = H(), r = I.current, n = u.current && u.current.tbodyElement; if (!t || !r || !n) return; const o = n.offsetTop, l = t.offsetLeft, s = D; r.style.top = o + "px", r.style.left = l + "px", r.style.width = s + "px", r.style.height = n.offsetHeight + "px"; }, ye = () => { const t = H(); t && (L.current = t.offsetLeft); }; e.useEffect(M), e.useEffect(ye); const xe = e.useCallback( (t) => { if (!p.current) return; const r = t.columns.slice(0, t.columns.length - 1); if (t.end) p.current.style.left = "0px"; else { const n = H(); if (!n) return; p.current.style.left = n.offsetLeft - L.current + "px", M(); } b({ ...t, columns: r }); }, [b] ), Te = e.useCallback( (t) => { const r = t.columns.slice(0, t.columns.length - 1); se({ ...t, columns: r }); }, [b] ), we = e.useCallback((t) => { const n = (c.current && c.current.ownerDocument ? c.current.ownerDocument : document).elementFromPoint(t.clientX, t.clientY), o = c.current; if (!n || !n.parentElement || !o) return; const l = o.parentElement, s = o.firstElementChild; if (!l || !s) return; const a = n.getAttribute(S); if (a) { const Ie = o.offsetTop, Le = o.offsetLeft, Fe = l.offsetTop, Ge = l.offsetLeft, Me = s.scrollTop, Se = s.scrollLeft; R.current = Le + Ge, h.current = Ie + Fe, C.current = t.clientX - R.current + Se, g.current = t.clientY - h.current + Me, f.current = n.parentElement.getAttribute(A), T.current = a; } }, []), He = e.useCallback((t) => { const r = c.current; if (!r) return; const n = r.firstElementChild; if (!n) return; const o = n.scrollTop, l = n.scrollLeft, s = t.clientX - R.current + l, a = t.clientY - h.current + o; Math.abs(C.current - s) < 10 && Math.abs(g.current - a) < 10 || w({ startX: C.current, startY: g.current, endX: s, endY: a }); }, []), ke = e.useCallback( (t) => { const n = (c.current && c.current.ownerDocument ? c.current.ownerDocument : document).elementFromPoint(t.clientX, t.clientY); if (!n || !n.parentElement) return; const o = n.parentElement.getAttribute(A), l = n.getAttribute(S); if (l && o !== f.current && m) { let s; T.current === "start" ? s = l === "start" ? 3 : 2 : s = l === "start" ? 1 : 0, m({ fromId: f.current, toId: o, type: s }); } C.current = 0, g.current = 0, R.current = 0, h.current = 0, f.current = null, T.current = null, w(null); }, [m, w] ); return /* @__PURE__ */ e.createElement( Ve, { tasksStore: [Ee, be], timelineWidth: D, dependencyDrag: { isEnabled: !!m, draggedId: f.current, onDependencyHandlePress: we, onDependencyHandleDrag: He, onDependencyHandleRelease: ke } }, /* @__PURE__ */ e.createElement("div", { className: "k-gantt-content", ref: c, style: { height: `calc(100% - ${ue}px)` } }, /* @__PURE__ */ e.createElement( Qe, { treelistId: me.current, ref: u, extendedColumns: Re, columnsMap: De, dataItemKey: i.id, data: y, idPrefix: F.current, navigatable: U, expandField: i.isExpanded, subItemsField: i.children, editField: i.isInEdit, selectedField: i.isSelected, onDataStateChange: J, onSortChange: Q, onFilterChange: Z, onExpandChange: te, onRowClick: ne, onRowDoubleClick: re, onRowContextMenu: oe, onColumnResize: xe, onColumnReorder: Te, onColumnMenuFilterChange: ee, onKeyDown: le, onSelectionChange: ce, onHeaderSelectionChange: ae, tableProps: { style: { width: he }, className: "k-table k-table-md k-table-layout-fixed" }, noRecords: _, rowHeight: ie, resizable: z, reorderable: V, sortable: v, sort: O, filter: $, columnMenuFilter: K, columnMenu: B, row: j, selectable: q, afterContent: /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement( "svg", { className: "k-gantt-dependencies-svg", ref: p, style: { left: 0, top: 0 } }, de.map((t) => /* @__PURE__ */ e.createElement( $e, { key: Ze(fe.id)(t), dependency: t } )) ), /* @__PURE__ */ e.createElement("svg", { className: "k-gantt-dependencies-svg", style: { left: 0, top: 0, zIndex: 3 } }, d && /* @__PURE__ */ e.createElement( "polyline", { points: `${d.startX},${d.startY} ${d.endX},${d.endY}` } )), y && y.length ? ge : null) } )) ); }); et.displayName = "KendoReactGanttBaseView"; export { et as BaseView };