@progress/kendo-react-taskboard
Version:
KendoReact TaskBoard package
237 lines (236 loc) • 7.82 kB
JavaScript
/**
* @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 t from "react";
import W from "prop-types";
import { packageMetadata as F } from "./package-metadata.mjs";
import { validatePackage as le, getLicenseMessage as de, clone as U, useDraggable as ue, classNames as me, noop as j, WatermarkOverlay as fe } from "@progress/kendo-react-common";
import { TaskBoardColumnBase as G } from "./TaskBoardColumnBase.mjs";
import { TaskBoardCardBase as pe } from "./TaskBoardCardBase.mjs";
import { TASKBOARD_COLUMN as T, TASKBOARD_PLACEHOLDER as ge, TASKBOARD_TASK as B } from "./constants.mjs";
import { closestTaskBoardElement as J, findIndexes as ke } from "./utils.mjs";
import { TaskBoardCard as N } from "./card/Card.mjs";
import { TaskBoardColumn as Q } from "./column/Column.mjs";
const V = t.forwardRef((c, Z) => {
const $ = !le(F, { component: "TaskBoard" }), ee = de(F), { columnData: f = [], className: te, style: ne, id: ae, taskData: l = [], onChange: d } = c, K = t.useRef(null), L = t.useRef(null);
t.useImperativeHandle(K, () => ({ props: c })), t.useImperativeHandle(Z, () => K.current);
const se = t.Children.toArray(c.children).filter(
(e) => e && e.type && e.type.displayName === "KendoReactTaskBoardToolbar"
), M = t.useRef(null), p = t.useRef(null), x = t.useRef(null), [C, w] = t.useState(null), [D, A] = t.useState(null), [I, P] = t.useState({ top: 0, left: 0 }), [oe, X] = t.useState(), O = t.useRef(null), Y = t.useRef(null), b = t.useMemo(() => {
const e = {};
return (C || l).forEach((a) => {
const n = a.status;
e[n] || (e[n] = []), e[n].push(a);
}), e;
}, [l, C]), re = t.useCallback(
(e) => {
const a = e.originalEvent.target;
if (a.closest("button,input,.k-link,.k-taskboard-preview-pane"))
return;
const n = J(a), s = L.current;
if (n && s) {
const r = n.type === T;
if (r && !a.closest(".k-taskboard-column-header"))
return;
const R = n.element.getBoundingClientRect(), y = s.getBoundingClientRect();
x.current = {
x: e.clientX - R.left + y.left,
y: e.clientY - R.top + y.top
};
const u = r ? f : l, S = r ? A : w, m = u.findIndex((v) => String(v.id) === n.id), k = u[m];
if (m === -1 || k.edit)
return;
const i = U(k);
i.isPlaceholder = !0;
const h = [...u];
h[m] = i, p.current = {
...n,
index: m,
item: k,
width: R.width,
height: R.height
}, X(m), P({
top: e.clientY - x.current.y,
left: e.clientX - x.current.x
}), S(h);
}
},
[f, l]
), ie = t.useCallback(
(e) => {
const a = p.current, n = O.current && O.current.element || Y.current;
if (a && n) {
P({
top: e.clientY - x.current.y,
left: e.clientX - x.current.x
}), n.style.visibility = "hidden";
const s = document.elementFromPoint(e.clientX, e.clientY);
if (n.style.visibility = "", s && s.getAttribute(ge))
return;
const r = s && J(s);
if (r) {
let g;
const R = r.type === a.type, y = a.type === T, u = (y ? D : C) || [], S = y ? A : w;
if (y || R) {
if (g = ke(a.id, r.id, u), g) {
const m = u[g.dragIndex], k = u[g.dropIndex], i = U(m);
y || (i.status = k.status);
const h = [...u];
h.splice(g.dragIndex, 1), h.splice(g.dropIndex, 0, i), a.index = g.dropIndex, S(h);
}
} else {
const m = u.findIndex((i) => String(i.id) === a.id), k = f.findIndex((i) => String(i.id) === r.id);
if (m !== -1 && k !== -1) {
const i = u[m], v = f[k].status;
if (b[v])
return;
i.status = v;
const E = [...u];
E.splice(m, 1), E.push(i), a.index = E.length - 1, S(E);
}
}
}
}
},
[D, C, f, b]
), ce = t.useCallback(() => {
const e = p.current;
if (d && e) {
const n = (e.type === T ? D : C) || [], s = n[e.index];
delete s.isPlaceholder;
const r = {
data: n,
type: e.type,
previousItem: { ...e.item, index: oe },
item: { ...s, index: e.index }
};
d.call(void 0, r);
}
p.current = null, x.current = null, w(null), A(null), P({ top: 0, left: 0 }), X(void 0);
}, [D, C, d]);
ue(M, {
onDragStart: re,
onDrag: ie,
onDragEnd: ce
});
const o = p.current, H = t.useCallback(
(e) => {
const n = {
data: [...l, e],
type: B,
previousItem: null,
item: e
};
d.call(void 0, n);
},
[d, l]
), _ = t.useCallback(
(e, a) => {
const n = l.slice(), s = l.indexOf(a);
s !== -1 && n.splice(s, 1, e);
const r = {
data: n,
type: B,
previousItem: a,
item: e
};
d.call(void 0, r);
},
[d, l]
), q = t.useCallback(
(e) => {
const n = {
data: l.filter((s) => s !== e),
type: B,
previousItem: e,
item: null
};
d.call(void 0, n);
},
[d, l]
), z = t.useCallback(
(e, a) => {
const n = f.slice(), s = n.indexOf(a);
s !== -1 && (e ? n.splice(s, 1, e) : n.splice(s, 1));
const r = {
data: n,
type: T,
previousItem: a,
item: e
};
d.call(void 0, r);
},
[d, f]
);
return /* @__PURE__ */ t.createElement("div", { id: ae, style: ne, ref: L, className: me("k-taskboard", te) }, se, /* @__PURE__ */ t.createElement("div", { className: "k-taskboard-content", style: o ? { userSelect: "none" } : void 0 }, /* @__PURE__ */ t.createElement("div", { className: "k-taskboard-columns-container", ref: M }, (D || f).map((e) => /* @__PURE__ */ t.createElement(
G,
{
key: e.id,
tabIndex: c.tabIndex,
column: e,
tasks: b[e.status] || [],
dragTargetRef: p,
onTaskCreate: H,
onTaskEdit: _,
onTaskDelete: q,
onColumnChange: z,
columnComponent: c.column || Q,
cardComponent: c.card || N,
priorities: c.priorities
}
)))), o && o.type === B && /* @__PURE__ */ t.createElement(
pe,
{
elementRef: O,
style: {
position: "absolute",
width: o.width,
height: o.height,
top: I.top,
left: I.left,
zIndex: 10,
borderLeftColor: o.item.priority ? o.item.priority.color : o.item.color
},
task: o.item,
dragTargetRef: p,
cardComponent: c.card || N,
onDeleteTask: j,
showEditPane: j
}
), o && o.type === T && /* @__PURE__ */ t.createElement(
G,
{
elementRef: Y,
style: {
position: "absolute",
width: o.width,
height: o.height,
top: I.top,
left: I.left,
zIndex: 10
},
cardComponent: c.card || N,
columnComponent: c.column || Q,
column: o.item,
tasks: b[o.item.status],
priorities: c.priorities,
dragTargetRef: p,
onTaskDelete: q,
onColumnChange: z,
onTaskEdit: _,
onTaskCreate: H
}
), $ && /* @__PURE__ */ t.createElement(fe, { message: ee }));
});
V.propTypes = {
columnData: W.array.isRequired,
taskData: W.array.isRequired
};
V.displayName = "KendoReactTaskBoard";
export {
V as TaskBoard
};