dishui 0.0.97 → 0.0.104
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.release-verified.json +2 -2
- package/dist/ai.js +17 -15
- package/dist/components/Card/Ticket.d.ts +52 -0
- package/dist/components/Card/Ticket2.js +218 -0
- package/dist/components/Card/Ticket2.js.map +1 -0
- package/dist/components/Card/index.d.ts +12 -0
- package/dist/components/Card/index.js +142 -139
- package/dist/components/Card/index.js.map +1 -1
- package/dist/components/ai/AgentRunCard/index.d.ts +38 -0
- package/dist/components/ai/AgentRunCard/index.js +100 -0
- package/dist/components/ai/AgentRunCard/index.js.map +1 -0
- package/dist/components/ai/IssueCard/index.d.ts +39 -0
- package/dist/components/ai/IssueCard/index.js +78 -0
- package/dist/components/ai/IssueCard/index.js.map +1 -0
- package/dist/components/ai/index.d.ts +4 -0
- package/dist/components/pro/Flow/constants.js +3 -3
- package/dist/components/pro/Flow/constants.js.map +1 -1
- package/dist/components/pro/Flow/context/FlowAIContext.d.ts +2 -0
- package/dist/components/pro/Flow/context/FlowAIContext.js +9 -4
- package/dist/components/pro/Flow/context/FlowAIContext.js.map +1 -1
- package/dist/components/pro/Flow/nodes/MediaContent.d.ts +3 -2
- package/dist/components/pro/Flow/nodes/MediaContent.js +16 -16
- package/dist/components/pro/Flow/nodes/MediaContent.js.map +1 -1
- package/dist/components/pro/Flow/nodes/MediaOverlay.js +25 -23
- package/dist/components/pro/Flow/nodes/MediaOverlay.js.map +1 -1
- package/dist/components/pro/Flow/nodes/shapes.js +3 -3
- package/dist/components/pro/Flow/nodes/shapes.js.map +1 -1
- package/dist/components/pro/Flow/panels/InspectorPanel.js +396 -384
- package/dist/components/pro/Flow/panels/InspectorPanel.js.map +1 -1
- package/dist/components/pro/Flow/utils/themeColor.d.ts +2 -2
- package/dist/components/pro/Flow/utils/themeColor.js +2 -2
- package/dist/components/pro/Flow/utils/themeColor.js.map +1 -1
- package/dist/components/pro/Kanban/Kanban.d.ts +3 -0
- package/dist/components/pro/Kanban/Kanban.js +339 -0
- package/dist/components/pro/Kanban/Kanban.js.map +1 -0
- package/dist/components/pro/Kanban/Swimlanes.d.ts +3 -0
- package/dist/components/pro/Kanban/Swimlanes.js +60 -0
- package/dist/components/pro/Kanban/Swimlanes.js.map +1 -0
- package/dist/components/pro/Kanban/index.d.ts +5 -0
- package/dist/components/pro/Kanban/types.d.ts +103 -0
- package/dist/components/pro/Kanban/useKanbanDrag.d.ts +17 -0
- package/dist/components/pro/Kanban/useKanbanDrag.js +69 -0
- package/dist/components/pro/Kanban/useKanbanDrag.js.map +1 -0
- package/dist/components/pro/Kanban/utils.d.ts +13 -0
- package/dist/components/pro/Kanban/utils.js +48 -0
- package/dist/components/pro/Kanban/utils.js.map +1 -0
- package/dist/components/pro/RichTextEditor/AIRewrite.js +158 -127
- package/dist/components/pro/RichTextEditor/AIRewrite.js.map +1 -1
- package/dist/components/pro/RichTextEditor/BlockHandle.d.ts +2 -0
- package/dist/components/pro/RichTextEditor/BlockHandle.js +156 -115
- package/dist/components/pro/RichTextEditor/BlockHandle.js.map +1 -1
- package/dist/components/pro/RichTextEditor/RichTextEditor.js +136 -159
- package/dist/components/pro/RichTextEditor/RichTextEditor.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/ColorPicker.js +44 -41
- package/dist/components/pro/RichTextEditor/Toolbar/ColorPicker.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.js +59 -53
- package/dist/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.js +48 -44
- package/dist/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/TableOpsMenu.js +67 -63
- package/dist/components/pro/RichTextEditor/Toolbar/TableOpsMenu.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.d.ts +1 -0
- package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.js +182 -129
- package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/ToolbarButton.d.ts +1 -0
- package/dist/components/pro/RichTextEditor/Toolbar/ToolbarButton.js +3 -3
- package/dist/components/pro/RichTextEditor/Toolbar/ToolbarButton.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/useAnchoredDropdown.d.ts +3 -0
- package/dist/components/pro/RichTextEditor/Toolbar/useAnchoredDropdown.js +31 -0
- package/dist/components/pro/RichTextEditor/Toolbar/useAnchoredDropdown.js.map +1 -0
- package/dist/components/pro/RichTextEditor/index.d.ts +1 -1
- package/dist/components/pro/RichTextEditor/types.d.ts +78 -11
- package/dist/components/pro/RichTextEditor/types.js +11 -0
- package/dist/components/pro/RichTextEditor/types.js.map +1 -1
- package/dist/dishui.css +1 -1
- package/dist/index-nostyled.d.ts +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +128 -122
- package/dist/kanban.js +5 -0
- package/dist/utils/i18n.js +20 -0
- package/dist/utils/i18n.js.map +1 -1
- package/dist/utils/menu.js +1 -1
- package/dist/utils/menu.js.map +1 -1
- package/package.json +5 -1
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import e from "../../Card/index.js";
|
|
2
|
+
import { cardsAt as t, createCardMove as n, getCardLocation as r, idText as i, idsEqual as a, locationEquals as o } from "./utils.js";
|
|
3
|
+
/* empty css */
|
|
4
|
+
import s from "./Swimlanes.js";
|
|
5
|
+
import { useKanbanDrag as c } from "./useKanbanDrag.js";
|
|
6
|
+
import l, { useCallback as u, useEffect as d, useMemo as ee, useRef as te, useState as f } from "react";
|
|
7
|
+
import { Fragment as p, jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
8
|
+
//#region src/components/pro/Kanban/Kanban.tsx
|
|
9
|
+
var ne = {
|
|
10
|
+
loading: "Loading board",
|
|
11
|
+
empty: "No cards",
|
|
12
|
+
error: "Could not load the board.",
|
|
13
|
+
stale: "Outdated data",
|
|
14
|
+
retry: "Try again",
|
|
15
|
+
unnamedColumn: "Untitled column",
|
|
16
|
+
unnamedLane: "Untitled lane",
|
|
17
|
+
card: "card",
|
|
18
|
+
lift: "Lifted",
|
|
19
|
+
move: "Move with the arrow keys.",
|
|
20
|
+
drop: "Dropped",
|
|
21
|
+
cancel: "Move cancelled"
|
|
22
|
+
}, g = e.Ticket;
|
|
23
|
+
function _(e) {
|
|
24
|
+
return typeof e == "number" ? `${e}px` : e;
|
|
25
|
+
}
|
|
26
|
+
function v(e, t) {
|
|
27
|
+
if (e !== void 0) return t.find((t) => String(t.id) === String(e))?.id ?? e;
|
|
28
|
+
}
|
|
29
|
+
function y(e, t) {
|
|
30
|
+
return typeof e == "string" || typeof e == "number" ? String(e) : t;
|
|
31
|
+
}
|
|
32
|
+
function re(e) {
|
|
33
|
+
return /* @__PURE__ */ m(g, {
|
|
34
|
+
issueKey: e.issueKey ?? e.id,
|
|
35
|
+
title: e.title,
|
|
36
|
+
description: e.description,
|
|
37
|
+
status: e.status,
|
|
38
|
+
issueType: e.issueType,
|
|
39
|
+
assignees: e.assignees,
|
|
40
|
+
priority: e.priority,
|
|
41
|
+
labels: e.labels,
|
|
42
|
+
dueDate: e.dueDate,
|
|
43
|
+
estimate: e.estimate,
|
|
44
|
+
subtaskProgress: e.subtaskProgress,
|
|
45
|
+
disabled: e.disabled
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function b({ columns: e, lanes: g, cards: b, onCardMove: S, renderCard: C, renderColumnHeader: w, renderLaneHeader: T, readOnly: E = !1, loading: D = !1, error: O, stale: ie = !1, empty: k, onRetry: A, labels: j, dragThreshold: M = 5, columnWidth: N = 280, height: P, collapsedLaneIds: F, defaultCollapsedLaneIds: I, onCollapsedLaneIdsChange: L, className: ae = "", style: R, ...oe }) {
|
|
49
|
+
let z = ee(() => ({
|
|
50
|
+
...ne,
|
|
51
|
+
...j
|
|
52
|
+
}), [j]), [B, V] = f(null), [H, U] = f(null), [se, W] = f(""), G = te(null), K = u((t, r) => {
|
|
53
|
+
let i = {
|
|
54
|
+
columnId: v(r.columnId, e),
|
|
55
|
+
laneId: g ? v(r.laneId, g) : void 0,
|
|
56
|
+
index: r.index
|
|
57
|
+
}, a = n(b, t, i);
|
|
58
|
+
a && !o(a.from, a.to) && S?.(a);
|
|
59
|
+
}, [
|
|
60
|
+
b,
|
|
61
|
+
e,
|
|
62
|
+
g,
|
|
63
|
+
S
|
|
64
|
+
]), q = c({
|
|
65
|
+
threshold: M,
|
|
66
|
+
disabled: E || !S,
|
|
67
|
+
onDrop: K
|
|
68
|
+
}), J = q.draggingId ?? B, Y = q.target ?? H, X = u((e = !0) => {
|
|
69
|
+
B !== null && (V(null), U(null), e && W(z.cancel), requestAnimationFrame(() => G.current?.focus()));
|
|
70
|
+
}, [B, z.cancel]);
|
|
71
|
+
d(() => {
|
|
72
|
+
let e = () => X(!1);
|
|
73
|
+
return window.addEventListener("blur", e), () => window.removeEventListener("blur", e);
|
|
74
|
+
}, [X]);
|
|
75
|
+
let Z = u((t) => {
|
|
76
|
+
let n = e.find((e) => a(e.id, t.columnId)), r = g?.find((e) => a(e.id, t.laneId));
|
|
77
|
+
return `${y(n?.title, z.unnamedColumn)}${r ? `, ${y(r.title, z.unnamedLane)}` : ""}, position ${t.index + 1}`;
|
|
78
|
+
}, [
|
|
79
|
+
e,
|
|
80
|
+
g,
|
|
81
|
+
z.unnamedColumn,
|
|
82
|
+
z.unnamedLane
|
|
83
|
+
]), Q = u((n) => {
|
|
84
|
+
if (B === null || !H) return;
|
|
85
|
+
let r = Math.max(0, e.findIndex((e) => a(e.id, H.columnId))), i = g ? Math.max(0, g.findIndex((e) => a(e.id, H.laneId))) : 0, o = r, s = i, c = H.index;
|
|
86
|
+
if (n === "ArrowLeft" && (o = Math.max(0, r - 1)), n === "ArrowRight" && (o = Math.min(e.length - 1, r + 1)), n === "ArrowUp" && (c > 0 ? --c : g && i > 0 && --s), n === "ArrowDown") {
|
|
87
|
+
let e = t(b.filter((e) => !a(e.id, B)), H.columnId, H.laneId).length;
|
|
88
|
+
c < e ? c += 1 : g && i < g.length - 1 && (s += 1);
|
|
89
|
+
}
|
|
90
|
+
let l = e[o]?.id ?? H.columnId, u = g?.[s]?.id;
|
|
91
|
+
if (o !== r || s !== i) {
|
|
92
|
+
let e = t(b.filter((e) => !a(e.id, B)), l, u).length;
|
|
93
|
+
c = Math.min(c, e);
|
|
94
|
+
}
|
|
95
|
+
let d = {
|
|
96
|
+
columnId: l,
|
|
97
|
+
laneId: u,
|
|
98
|
+
index: c
|
|
99
|
+
};
|
|
100
|
+
U(d), W(Z(d));
|
|
101
|
+
}, [
|
|
102
|
+
b,
|
|
103
|
+
e,
|
|
104
|
+
Z,
|
|
105
|
+
B,
|
|
106
|
+
H,
|
|
107
|
+
g
|
|
108
|
+
]), ce = u((e, t) => {
|
|
109
|
+
if (!(e.target !== e.currentTarget || t.disabled || E || !S)) {
|
|
110
|
+
if (e.key === "Escape") {
|
|
111
|
+
e.preventDefault(), X();
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (e.key === " " || e.key === "Enter") {
|
|
115
|
+
if (e.preventDefault(), e.repeat) return;
|
|
116
|
+
if (B === null) {
|
|
117
|
+
let n = r(b, t.id);
|
|
118
|
+
if (!n) return;
|
|
119
|
+
G.current = e.currentTarget, V(t.id), U(n), W(`${z.lift} ${y(t.title, z.card)}. ${z.move}`);
|
|
120
|
+
} else a(B, t.id) && H && (K(t.id, H), V(null), U(null), W(`${z.drop} ${y(t.title, z.card)}. ${Z(H)}.`), requestAnimationFrame(() => G.current?.focus()));
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
B !== null && [
|
|
124
|
+
"ArrowLeft",
|
|
125
|
+
"ArrowRight",
|
|
126
|
+
"ArrowUp",
|
|
127
|
+
"ArrowDown"
|
|
128
|
+
].includes(e.key) && (e.preventDefault(), Q(e.key));
|
|
129
|
+
}
|
|
130
|
+
}, [
|
|
131
|
+
X,
|
|
132
|
+
b,
|
|
133
|
+
K,
|
|
134
|
+
Z,
|
|
135
|
+
B,
|
|
136
|
+
H,
|
|
137
|
+
z,
|
|
138
|
+
Q,
|
|
139
|
+
S,
|
|
140
|
+
E
|
|
141
|
+
]), $ = (e, n) => {
|
|
142
|
+
let r = t(b, e.id, n?.id), s = E || !!e.disabled || !!n?.disabled || !S, c = 0;
|
|
143
|
+
return /* @__PURE__ */ h("div", {
|
|
144
|
+
className: "dishui-kanban__column",
|
|
145
|
+
role: "group",
|
|
146
|
+
"aria-label": y(e.title, z.unnamedColumn),
|
|
147
|
+
"data-column-id": i(e.id),
|
|
148
|
+
"data-lane-id": i(n?.id),
|
|
149
|
+
"data-disabled": s || void 0,
|
|
150
|
+
children: [!g && /* @__PURE__ */ m("div", {
|
|
151
|
+
className: "dishui-kanban__column-header",
|
|
152
|
+
children: w ? w(e, r) : /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m("span", { children: e.title }), /* @__PURE__ */ m("span", {
|
|
153
|
+
className: "dishui-kanban__count",
|
|
154
|
+
children: r.length
|
|
155
|
+
})] })
|
|
156
|
+
}), /* @__PURE__ */ h("div", {
|
|
157
|
+
className: "dishui-kanban__cards",
|
|
158
|
+
children: [
|
|
159
|
+
r.length === 0 && J === null && /* @__PURE__ */ m("span", {
|
|
160
|
+
className: "dishui-kanban__cell-empty",
|
|
161
|
+
children: z.empty
|
|
162
|
+
}),
|
|
163
|
+
/* @__PURE__ */ m(x, {
|
|
164
|
+
columnId: e.id,
|
|
165
|
+
laneId: n?.id,
|
|
166
|
+
index: 0,
|
|
167
|
+
active: o(Y, {
|
|
168
|
+
columnId: e.id,
|
|
169
|
+
laneId: n?.id,
|
|
170
|
+
index: 0
|
|
171
|
+
})
|
|
172
|
+
}),
|
|
173
|
+
r.map((t) => {
|
|
174
|
+
let r = J !== null && a(J, t.id), i = c;
|
|
175
|
+
r || (c += 1);
|
|
176
|
+
let u = s || !!t.disabled;
|
|
177
|
+
return /* @__PURE__ */ h(l.Fragment, { children: [/* @__PURE__ */ m("div", {
|
|
178
|
+
className: "dishui-kanban__card",
|
|
179
|
+
role: "button",
|
|
180
|
+
tabIndex: u ? -1 : 0,
|
|
181
|
+
"aria-disabled": u,
|
|
182
|
+
"aria-describedby": "dishui-kanban-instructions",
|
|
183
|
+
"data-kanban-disabled": u || void 0,
|
|
184
|
+
"data-dragging": r || void 0,
|
|
185
|
+
onPointerDown: (e) => q.onPointerDown(e, t.id),
|
|
186
|
+
onPointerMove: q.onPointerMove,
|
|
187
|
+
onPointerUp: q.onPointerUp,
|
|
188
|
+
onPointerCancel: q.onPointerCancel,
|
|
189
|
+
onLostPointerCapture: q.onLostPointerCapture,
|
|
190
|
+
onKeyDown: (e) => ce(e, t),
|
|
191
|
+
children: C ? C(t, {
|
|
192
|
+
dragging: r,
|
|
193
|
+
keyboardDragging: a(B ?? void 0, t.id),
|
|
194
|
+
disabled: u
|
|
195
|
+
}) : re(t)
|
|
196
|
+
}), !r && /* @__PURE__ */ m(x, {
|
|
197
|
+
columnId: e.id,
|
|
198
|
+
laneId: n?.id,
|
|
199
|
+
index: i + 1,
|
|
200
|
+
active: o(Y, {
|
|
201
|
+
columnId: e.id,
|
|
202
|
+
laneId: n?.id,
|
|
203
|
+
index: i + 1
|
|
204
|
+
})
|
|
205
|
+
})] }, String(t.id));
|
|
206
|
+
})
|
|
207
|
+
]
|
|
208
|
+
})]
|
|
209
|
+
}, `${i(n?.id)}:${i(e.id)}`);
|
|
210
|
+
}, le = {
|
|
211
|
+
...R,
|
|
212
|
+
height: _(P) ?? R?.height,
|
|
213
|
+
"--dishui-kanban-column-width": _(N)
|
|
214
|
+
};
|
|
215
|
+
return /* @__PURE__ */ h("div", {
|
|
216
|
+
...oe,
|
|
217
|
+
className: `dishui-kanban ${ae}`.trim(),
|
|
218
|
+
style: le,
|
|
219
|
+
"aria-busy": D || void 0,
|
|
220
|
+
children: [
|
|
221
|
+
/* @__PURE__ */ m("span", {
|
|
222
|
+
id: "dishui-kanban-instructions",
|
|
223
|
+
className: "dishui-kanban__sr-only",
|
|
224
|
+
children: "Press Space or Enter to lift and drop. Use arrow keys to choose a destination. Press Escape to cancel."
|
|
225
|
+
}),
|
|
226
|
+
/* @__PURE__ */ m("div", {
|
|
227
|
+
className: "dishui-kanban__sr-only",
|
|
228
|
+
role: "status",
|
|
229
|
+
"aria-live": "polite",
|
|
230
|
+
"aria-atomic": "true",
|
|
231
|
+
children: se
|
|
232
|
+
}),
|
|
233
|
+
ie && /* @__PURE__ */ m("div", {
|
|
234
|
+
className: "dishui-kanban__stale",
|
|
235
|
+
role: "status",
|
|
236
|
+
children: z.stale
|
|
237
|
+
}),
|
|
238
|
+
D ? /* @__PURE__ */ h("div", {
|
|
239
|
+
className: "dishui-kanban__state",
|
|
240
|
+
role: "status",
|
|
241
|
+
children: [/* @__PURE__ */ m("span", { children: z.loading }), /* @__PURE__ */ h("div", {
|
|
242
|
+
className: "dishui-kanban__skeletons",
|
|
243
|
+
"aria-hidden": "true",
|
|
244
|
+
children: [
|
|
245
|
+
/* @__PURE__ */ m("i", {}),
|
|
246
|
+
/* @__PURE__ */ m("i", {}),
|
|
247
|
+
/* @__PURE__ */ m("i", {})
|
|
248
|
+
]
|
|
249
|
+
})]
|
|
250
|
+
}) : O ? /* @__PURE__ */ h("div", {
|
|
251
|
+
className: "dishui-kanban__state dishui-kanban__state--error",
|
|
252
|
+
role: "alert",
|
|
253
|
+
children: [
|
|
254
|
+
/* @__PURE__ */ m("strong", { children: z.error }),
|
|
255
|
+
/* @__PURE__ */ m("span", { children: O }),
|
|
256
|
+
A && /* @__PURE__ */ m("button", {
|
|
257
|
+
type: "button",
|
|
258
|
+
onClick: A,
|
|
259
|
+
children: z.retry
|
|
260
|
+
})
|
|
261
|
+
]
|
|
262
|
+
}) : e.length === 0 || b.length === 0 ? /* @__PURE__ */ m("div", {
|
|
263
|
+
className: "dishui-kanban__state dishui-kanban__state--empty",
|
|
264
|
+
children: k ?? z.empty
|
|
265
|
+
}) : /* @__PURE__ */ h("div", {
|
|
266
|
+
className: "dishui-kanban__scroll",
|
|
267
|
+
"data-dragging": J !== null || void 0,
|
|
268
|
+
children: [g && g.length > 0 && /* @__PURE__ */ m("div", {
|
|
269
|
+
className: "dishui-kanban__column-headers",
|
|
270
|
+
style: { gridTemplateColumns: `repeat(${e.length}, minmax(var(--dishui-kanban-column-width), 1fr))` },
|
|
271
|
+
children: e.map((e) => {
|
|
272
|
+
let t = b.filter((t) => a(t.columnId, e.id));
|
|
273
|
+
return /* @__PURE__ */ m("div", {
|
|
274
|
+
className: "dishui-kanban__column-header",
|
|
275
|
+
children: w ? w(e, t) : /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m("span", { children: e.title }), /* @__PURE__ */ m("span", {
|
|
276
|
+
className: "dishui-kanban__count",
|
|
277
|
+
children: t.length
|
|
278
|
+
})] })
|
|
279
|
+
}, String(e.id));
|
|
280
|
+
})
|
|
281
|
+
}), g && g.length > 0 ? /* @__PURE__ */ m(s, {
|
|
282
|
+
lanes: g,
|
|
283
|
+
collapsedLaneIds: F,
|
|
284
|
+
defaultCollapsedLaneIds: I,
|
|
285
|
+
onCollapsedLaneIdsChange: L,
|
|
286
|
+
renderLaneHeader: (e, t) => {
|
|
287
|
+
let n = b.filter((t) => a(t.laneId, e.id));
|
|
288
|
+
return /* @__PURE__ */ h("button", {
|
|
289
|
+
className: "dishui-swimlane__toggle",
|
|
290
|
+
type: "button",
|
|
291
|
+
"aria-expanded": !t.collapsed,
|
|
292
|
+
onClick: t.toggle,
|
|
293
|
+
children: [
|
|
294
|
+
/* @__PURE__ */ m("span", {
|
|
295
|
+
className: "dishui-swimlane__chevron",
|
|
296
|
+
"aria-hidden": "true",
|
|
297
|
+
children: "▾"
|
|
298
|
+
}),
|
|
299
|
+
/* @__PURE__ */ m("span", {
|
|
300
|
+
className: "dishui-swimlane__header-content",
|
|
301
|
+
children: T ? T(e, n) : e.title
|
|
302
|
+
}),
|
|
303
|
+
/* @__PURE__ */ m("span", {
|
|
304
|
+
className: "dishui-kanban__count",
|
|
305
|
+
children: n.length
|
|
306
|
+
})
|
|
307
|
+
]
|
|
308
|
+
});
|
|
309
|
+
},
|
|
310
|
+
children: ({ lane: t }) => /* @__PURE__ */ m("div", {
|
|
311
|
+
className: "dishui-kanban__grid",
|
|
312
|
+
style: { gridTemplateColumns: `repeat(${e.length}, minmax(var(--dishui-kanban-column-width), 1fr))` },
|
|
313
|
+
children: e.map((e) => $(e, t))
|
|
314
|
+
})
|
|
315
|
+
}) : /* @__PURE__ */ m("div", {
|
|
316
|
+
className: "dishui-kanban__grid",
|
|
317
|
+
style: { gridTemplateColumns: `repeat(${e.length}, minmax(var(--dishui-kanban-column-width), 1fr))` },
|
|
318
|
+
children: e.map((e) => $(e))
|
|
319
|
+
})]
|
|
320
|
+
})
|
|
321
|
+
]
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
function x({ columnId: e, laneId: t, index: n, active: r }) {
|
|
325
|
+
return /* @__PURE__ */ m("div", {
|
|
326
|
+
className: "dishui-kanban__drop-zone",
|
|
327
|
+
"data-kanban-drop": "true",
|
|
328
|
+
"data-column-id": String(e),
|
|
329
|
+
"data-lane-id": t === void 0 ? "" : String(t),
|
|
330
|
+
"data-index": n,
|
|
331
|
+
"data-active": r || void 0,
|
|
332
|
+
"aria-hidden": "true",
|
|
333
|
+
children: /* @__PURE__ */ m("span", {})
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
//#endregion
|
|
337
|
+
export { b as default };
|
|
338
|
+
|
|
339
|
+
//# sourceMappingURL=Kanban.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Kanban.js","names":[],"sources":["../../../../src/components/pro/Kanban/Kanban.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport Card from \"../../Card\";\nimport Swimlanes from \"./Swimlanes\";\nimport type {\n KanbanCard,\n KanbanColumn,\n KanbanDragTarget,\n KanbanId,\n KanbanLane,\n KanbanLabels,\n KanbanLocation,\n KanbanProps,\n} from \"./types\";\nimport { useKanbanDrag } from \"./useKanbanDrag\";\nimport { cardsAt, createCardMove, getCardLocation, idText, idsEqual, locationEquals } from \"./utils\";\nimport \"./styles.css\";\n\nconst DEFAULT_LABELS: Required<KanbanLabels> = {\n loading: \"Loading board\",\n empty: \"No cards\",\n error: \"Could not load the board.\",\n stale: \"Outdated data\",\n retry: \"Try again\",\n unnamedColumn: \"Untitled column\",\n unnamedLane: \"Untitled lane\",\n card: \"card\",\n lift: \"Lifted\",\n move: \"Move with the arrow keys.\",\n drop: \"Dropped\",\n cancel: \"Move cancelled\",\n};\n\nconst DefaultTicket = Card.Ticket;\n\nfunction cssSize(value: number | string | undefined): string | undefined {\n return typeof value === \"number\" ? `${value}px` : value;\n}\n\nfunction resolveId(value: KanbanId | undefined, items: readonly { id: KanbanId }[]): KanbanId | undefined {\n if (value === undefined) return undefined;\n return items.find(item => String(item.id) === String(value))?.id ?? value;\n}\n\nfunction displayText(value: React.ReactNode, fallback: string): string {\n return typeof value === \"string\" || typeof value === \"number\" ? String(value) : fallback;\n}\n\nfunction renderDefaultCard(card: KanbanCard) {\n return (\n <DefaultTicket\n issueKey={card.issueKey ?? card.id}\n title={card.title}\n description={card.description}\n status={card.status}\n issueType={card.issueType}\n assignees={card.assignees}\n priority={card.priority}\n labels={card.labels}\n dueDate={card.dueDate}\n estimate={card.estimate}\n subtaskProgress={card.subtaskProgress}\n disabled={card.disabled}\n />\n );\n}\n\nexport default function Kanban({\n columns,\n lanes,\n cards,\n onCardMove,\n renderCard,\n renderColumnHeader,\n renderLaneHeader,\n readOnly = false,\n loading = false,\n error,\n stale = false,\n empty,\n onRetry,\n labels: labelsInput,\n dragThreshold = 5,\n columnWidth = 280,\n height,\n collapsedLaneIds,\n defaultCollapsedLaneIds,\n onCollapsedLaneIdsChange,\n className = \"\",\n style,\n ...rest\n}: KanbanProps) {\n const labels = useMemo(() => ({ ...DEFAULT_LABELS, ...labelsInput }), [labelsInput]);\n const [keyboardCardId, setKeyboardCardId] = useState<KanbanId | null>(null);\n const [keyboardTarget, setKeyboardTarget] = useState<KanbanLocation | null>(null);\n const [announcement, setAnnouncement] = useState(\"\");\n const keyboardCardRef = useRef<HTMLElement | null>(null);\n\n const commitMove = useCallback((cardId: KanbanId, rawTarget: KanbanDragTarget) => {\n const target: KanbanLocation = {\n columnId: resolveId(rawTarget.columnId, columns) as KanbanId,\n laneId: lanes ? resolveId(rawTarget.laneId, lanes) : undefined,\n index: rawTarget.index,\n };\n const move = createCardMove(cards, cardId, target);\n if (!move || locationEquals(move.from, move.to)) return;\n onCardMove?.(move);\n }, [cards, columns, lanes, onCardMove]);\n\n const drag = useKanbanDrag({\n threshold: dragThreshold,\n disabled: readOnly || !onCardMove,\n onDrop: commitMove,\n });\n\n const activeCardId = drag.draggingId ?? keyboardCardId;\n const activeTarget = drag.target ?? keyboardTarget;\n\n const cancelKeyboard = useCallback((announce = true) => {\n if (keyboardCardId === null) return;\n setKeyboardCardId(null);\n setKeyboardTarget(null);\n if (announce) setAnnouncement(labels.cancel);\n requestAnimationFrame(() => keyboardCardRef.current?.focus());\n }, [keyboardCardId, labels.cancel]);\n\n useEffect(() => {\n const onBlur = () => cancelKeyboard(false);\n window.addEventListener(\"blur\", onBlur);\n return () => window.removeEventListener(\"blur\", onBlur);\n }, [cancelKeyboard]);\n\n const describeLocation = useCallback((target: KanbanLocation) => {\n const column = columns.find(item => idsEqual(item.id, target.columnId));\n const lane = lanes?.find(item => idsEqual(item.id, target.laneId));\n const columnName = displayText(column?.title, labels.unnamedColumn);\n const laneName = lane ? `, ${displayText(lane.title, labels.unnamedLane)}` : \"\";\n return `${columnName}${laneName}, position ${target.index + 1}`;\n }, [columns, lanes, labels.unnamedColumn, labels.unnamedLane]);\n\n const moveKeyboardTarget = useCallback((key: string) => {\n if (keyboardCardId === null || !keyboardTarget) return;\n const columnIndex = Math.max(0, columns.findIndex(column => idsEqual(column.id, keyboardTarget.columnId)));\n const laneIndex = lanes ? Math.max(0, lanes.findIndex(lane => idsEqual(lane.id, keyboardTarget.laneId))) : 0;\n let nextColumnIndex = columnIndex;\n let nextLaneIndex = laneIndex;\n let nextIndex = keyboardTarget.index;\n\n if (key === \"ArrowLeft\") nextColumnIndex = Math.max(0, columnIndex - 1);\n if (key === \"ArrowRight\") nextColumnIndex = Math.min(columns.length - 1, columnIndex + 1);\n if (key === \"ArrowUp\") {\n if (nextIndex > 0) nextIndex -= 1;\n else if (lanes && laneIndex > 0) nextLaneIndex -= 1;\n }\n if (key === \"ArrowDown\") {\n const count = cardsAt(cards.filter(card => !idsEqual(card.id, keyboardCardId)), keyboardTarget.columnId, keyboardTarget.laneId).length;\n if (nextIndex < count) nextIndex += 1;\n else if (lanes && laneIndex < lanes.length - 1) nextLaneIndex += 1;\n }\n\n const columnId = columns[nextColumnIndex]?.id ?? keyboardTarget.columnId;\n const laneId = lanes?.[nextLaneIndex]?.id;\n if (nextColumnIndex !== columnIndex || nextLaneIndex !== laneIndex) {\n const targetCount = cardsAt(cards.filter(card => !idsEqual(card.id, keyboardCardId)), columnId, laneId).length;\n nextIndex = Math.min(nextIndex, targetCount);\n }\n const next = { columnId, laneId, index: nextIndex };\n setKeyboardTarget(next);\n setAnnouncement(describeLocation(next));\n }, [cards, columns, describeLocation, keyboardCardId, keyboardTarget, lanes]);\n\n const onCardKeyDown = useCallback((event: React.KeyboardEvent<HTMLElement>, card: KanbanCard) => {\n if (event.target !== event.currentTarget || card.disabled || readOnly || !onCardMove) return;\n if (event.key === \"Escape\") {\n event.preventDefault();\n cancelKeyboard();\n return;\n }\n if (event.key === \" \" || event.key === \"Enter\") {\n event.preventDefault();\n if (event.repeat) return;\n if (keyboardCardId === null) {\n const from = getCardLocation(cards, card.id);\n if (!from) return;\n keyboardCardRef.current = event.currentTarget;\n setKeyboardCardId(card.id);\n setKeyboardTarget(from);\n setAnnouncement(`${labels.lift} ${displayText(card.title, labels.card)}. ${labels.move}`);\n } else if (idsEqual(keyboardCardId, card.id) && keyboardTarget) {\n commitMove(card.id, keyboardTarget);\n setKeyboardCardId(null);\n setKeyboardTarget(null);\n setAnnouncement(`${labels.drop} ${displayText(card.title, labels.card)}. ${describeLocation(keyboardTarget)}.`);\n requestAnimationFrame(() => keyboardCardRef.current?.focus());\n }\n return;\n }\n if (keyboardCardId !== null && [\"ArrowLeft\", \"ArrowRight\", \"ArrowUp\", \"ArrowDown\"].includes(event.key)) {\n event.preventDefault();\n moveKeyboardTarget(event.key);\n }\n }, [cancelKeyboard, cards, commitMove, describeLocation, keyboardCardId, keyboardTarget, labels, moveKeyboardTarget, onCardMove, readOnly]);\n\n\n const renderCell = (column: KanbanColumn, lane?: KanbanLane) => {\n const cellCards = cardsAt(cards, column.id, lane?.id);\n const disabledCell = readOnly || !!column.disabled || !!lane?.disabled || !onCardMove;\n let insertionIndex = 0;\n return (\n <div\n className=\"dishui-kanban__column\"\n key={`${idText(lane?.id)}:${idText(column.id)}`}\n role=\"group\"\n aria-label={displayText(column.title, labels.unnamedColumn)}\n data-column-id={idText(column.id)}\n data-lane-id={idText(lane?.id)}\n data-disabled={disabledCell || undefined}\n >\n {!lanes && (\n <div className=\"dishui-kanban__column-header\">\n {renderColumnHeader ? renderColumnHeader(column, cellCards) : (\n <><span>{column.title}</span><span className=\"dishui-kanban__count\">{cellCards.length}</span></>\n )}\n </div>\n )}\n <div className=\"dishui-kanban__cards\">\n {cellCards.length === 0 && activeCardId === null && <span className=\"dishui-kanban__cell-empty\">{labels.empty}</span>}\n <DropIndicator columnId={column.id} laneId={lane?.id} index={0} active={locationEquals(activeTarget, { columnId: column.id, laneId: lane?.id, index: 0 })} />\n {cellCards.map(card => {\n const isActive = activeCardId !== null && idsEqual(activeCardId, card.id);\n const cardIndex = insertionIndex;\n if (!isActive) insertionIndex += 1;\n const cardDisabled = disabledCell || !!card.disabled;\n return (\n <React.Fragment key={String(card.id)}>\n <div\n className=\"dishui-kanban__card\"\n role=\"button\"\n tabIndex={cardDisabled ? -1 : 0}\n aria-disabled={cardDisabled}\n aria-describedby=\"dishui-kanban-instructions\"\n data-kanban-disabled={cardDisabled || undefined}\n data-dragging={isActive || undefined}\n onPointerDown={event => drag.onPointerDown(event, card.id)}\n onPointerMove={drag.onPointerMove}\n onPointerUp={drag.onPointerUp}\n onPointerCancel={drag.onPointerCancel}\n onLostPointerCapture={drag.onLostPointerCapture}\n onKeyDown={event => onCardKeyDown(event, card)}\n >\n {renderCard ? renderCard(card, { dragging: isActive, keyboardDragging: idsEqual(keyboardCardId ?? undefined, card.id), disabled: cardDisabled }) : renderDefaultCard(card)}\n </div>\n {!isActive && (\n <DropIndicator\n columnId={column.id}\n laneId={lane?.id}\n index={cardIndex + 1}\n active={locationEquals(activeTarget, { columnId: column.id, laneId: lane?.id, index: cardIndex + 1 })}\n />\n )}\n </React.Fragment>\n );\n })}\n </div>\n </div>\n );\n };\n\n const boardStyle = {\n ...style,\n height: cssSize(height) ?? style?.height,\n \"--dishui-kanban-column-width\": cssSize(columnWidth),\n } as React.CSSProperties;\n\n return (\n <div {...rest} className={`dishui-kanban ${className}`.trim()} style={boardStyle} aria-busy={loading || undefined}>\n <span id=\"dishui-kanban-instructions\" className=\"dishui-kanban__sr-only\">\n Press Space or Enter to lift and drop. Use arrow keys to choose a destination. Press Escape to cancel.\n </span>\n <div className=\"dishui-kanban__sr-only\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">{announcement}</div>\n\n {stale && <div className=\"dishui-kanban__stale\" role=\"status\">{labels.stale}</div>}\n {loading ? (\n <div className=\"dishui-kanban__state\" role=\"status\">\n <span>{labels.loading}</span>\n <div className=\"dishui-kanban__skeletons\" aria-hidden=\"true\"><i /><i /><i /></div>\n </div>\n ) : error ? (\n <div className=\"dishui-kanban__state dishui-kanban__state--error\" role=\"alert\">\n <strong>{labels.error}</strong><span>{error}</span>\n {onRetry && <button type=\"button\" onClick={onRetry}>{labels.retry}</button>}\n </div>\n ) : columns.length === 0 || cards.length === 0 ? (\n <div className=\"dishui-kanban__state dishui-kanban__state--empty\">{empty ?? labels.empty}</div>\n ) : (\n <div className=\"dishui-kanban__scroll\" data-dragging={activeCardId !== null || undefined}>\n {lanes && lanes.length > 0 && (\n <div className=\"dishui-kanban__column-headers\" style={{ gridTemplateColumns: `repeat(${columns.length}, minmax(var(--dishui-kanban-column-width), 1fr))` }}>\n {columns.map(column => {\n const columnCards = cards.filter(card => idsEqual(card.columnId, column.id));\n return <div className=\"dishui-kanban__column-header\" key={String(column.id)}>{renderColumnHeader ? renderColumnHeader(column, columnCards) : <><span>{column.title}</span><span className=\"dishui-kanban__count\">{columnCards.length}</span></>}</div>;\n })}\n </div>\n )}\n {lanes && lanes.length > 0 ? (\n <Swimlanes\n lanes={lanes}\n collapsedLaneIds={collapsedLaneIds}\n defaultCollapsedLaneIds={defaultCollapsedLaneIds}\n onCollapsedLaneIdsChange={onCollapsedLaneIdsChange}\n renderLaneHeader={(lane, context) => {\n const laneCards = cards.filter(card => idsEqual(card.laneId, lane.id));\n return (\n <button className=\"dishui-swimlane__toggle\" type=\"button\" aria-expanded={!context.collapsed} onClick={context.toggle}>\n <span className=\"dishui-swimlane__chevron\" aria-hidden=\"true\">▾</span>\n <span className=\"dishui-swimlane__header-content\">{renderLaneHeader ? renderLaneHeader(lane, laneCards) : lane.title}</span>\n <span className=\"dishui-kanban__count\">{laneCards.length}</span>\n </button>\n );\n }}\n >\n {({ lane }) => <div className=\"dishui-kanban__grid\" style={{ gridTemplateColumns: `repeat(${columns.length}, minmax(var(--dishui-kanban-column-width), 1fr))` }}>{columns.map(column => renderCell(column, lane))}</div>}\n </Swimlanes>\n ) : (\n <div className=\"dishui-kanban__grid\" style={{ gridTemplateColumns: `repeat(${columns.length}, minmax(var(--dishui-kanban-column-width), 1fr))` }}>{columns.map(column => renderCell(column))}</div>\n )}\n </div>\n )}\n </div>\n );\n}\n\nfunction DropIndicator({ columnId, laneId, index, active }: KanbanLocation & { active: boolean }) {\n return (\n <div\n className=\"dishui-kanban__drop-zone\"\n data-kanban-drop=\"true\"\n data-column-id={String(columnId)}\n data-lane-id={laneId === undefined ? \"\" : String(laneId)}\n data-index={index}\n data-active={active || undefined}\n aria-hidden=\"true\"\n ><span /></div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { KanbanLane, SwimlanesProps } from "./types";
|
|
3
|
+
export default function Swimlanes<TLane extends KanbanLane = KanbanLane>({ lanes, children, renderLaneHeader, collapsedLaneIds, defaultCollapsedLaneIds, onCollapsedLaneIdsChange, collapsible, empty, className, laneClassName, ...rest }: SwimlanesProps<TLane>): React.JSX.Element;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { idsEqual as e } from "./utils.js";
|
|
2
|
+
/* empty css */
|
|
3
|
+
import { useCallback as t, useState as n } from "react";
|
|
4
|
+
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
5
|
+
//#region src/components/pro/Kanban/Swimlanes.tsx
|
|
6
|
+
var a = [];
|
|
7
|
+
function o({ lanes: o, children: s, renderLaneHeader: c, collapsedLaneIds: l, defaultCollapsedLaneIds: u = a, onCollapsedLaneIdsChange: d, collapsible: f = !0, empty: p = "No lanes", className: m = "", laneClassName: h = "", ...g }) {
|
|
8
|
+
let _ = l !== void 0, [v, y] = n(u), b = (_ ? l : v).filter((t) => o.some((n) => e(n.id, t))), x = t((t) => {
|
|
9
|
+
let n = b.some((n) => e(n, t)) ? b.filter((n) => !e(n, t)) : [...b, t];
|
|
10
|
+
_ || y(n), d?.(n);
|
|
11
|
+
}, [
|
|
12
|
+
b,
|
|
13
|
+
_,
|
|
14
|
+
d
|
|
15
|
+
]);
|
|
16
|
+
return /* @__PURE__ */ r("div", {
|
|
17
|
+
...g,
|
|
18
|
+
className: `dishui-swimlanes ${m}`.trim(),
|
|
19
|
+
children: o.length === 0 ? /* @__PURE__ */ r("div", {
|
|
20
|
+
className: "dishui-swimlanes__empty",
|
|
21
|
+
children: p
|
|
22
|
+
}) : o.map((t) => {
|
|
23
|
+
let n = b.some((n) => e(n, t.id)), a = {
|
|
24
|
+
lane: t,
|
|
25
|
+
collapsed: n,
|
|
26
|
+
toggle: () => x(t.id)
|
|
27
|
+
};
|
|
28
|
+
return /* @__PURE__ */ i("section", {
|
|
29
|
+
className: `dishui-swimlane ${h}`.trim(),
|
|
30
|
+
"data-lane-id": String(t.id),
|
|
31
|
+
"data-collapsed": n || void 0,
|
|
32
|
+
children: [/* @__PURE__ */ r("header", {
|
|
33
|
+
className: "dishui-swimlane__header",
|
|
34
|
+
children: c ? c(t, a) : /* @__PURE__ */ i("button", {
|
|
35
|
+
className: "dishui-swimlane__toggle",
|
|
36
|
+
type: "button",
|
|
37
|
+
disabled: !f,
|
|
38
|
+
"aria-expanded": !n,
|
|
39
|
+
"aria-controls": `dishui-swimlane-${String(t.id)}`,
|
|
40
|
+
onClick: a.toggle,
|
|
41
|
+
children: [/* @__PURE__ */ r("span", {
|
|
42
|
+
className: "dishui-swimlane__chevron",
|
|
43
|
+
"aria-hidden": "true",
|
|
44
|
+
children: "▾"
|
|
45
|
+
}), /* @__PURE__ */ r("span", { children: t.title })]
|
|
46
|
+
})
|
|
47
|
+
}), /* @__PURE__ */ r("div", {
|
|
48
|
+
id: `dishui-swimlane-${String(t.id)}`,
|
|
49
|
+
className: "dishui-swimlane__content",
|
|
50
|
+
hidden: n,
|
|
51
|
+
children: typeof s == "function" ? s(a) : s
|
|
52
|
+
})]
|
|
53
|
+
}, String(t.id));
|
|
54
|
+
})
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
//#endregion
|
|
58
|
+
export { o as default };
|
|
59
|
+
|
|
60
|
+
//# sourceMappingURL=Swimlanes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Swimlanes.js","names":[],"sources":["../../../../src/components/pro/Kanban/Swimlanes.tsx"],"sourcesContent":["import React, { useCallback, useState } from \"react\";\nimport type { KanbanId, KanbanLane, SwimlanesProps } from \"./types\";\nimport { idsEqual } from \"./utils\";\nimport \"./styles.css\";\n\nconst EMPTY_IDS: KanbanId[] = [];\n\nexport default function Swimlanes<TLane extends KanbanLane = KanbanLane>({\n lanes,\n children,\n renderLaneHeader,\n collapsedLaneIds,\n defaultCollapsedLaneIds = EMPTY_IDS,\n onCollapsedLaneIdsChange,\n collapsible = true,\n empty = \"No lanes\",\n className = \"\",\n laneClassName = \"\",\n ...rest\n}: SwimlanesProps<TLane>) {\n const controlled = collapsedLaneIds !== undefined;\n const [internalIds, setInternalIds] = useState<KanbanId[]>(defaultCollapsedLaneIds);\n const sourceIds = controlled ? collapsedLaneIds : internalIds;\n const collapsedIds = sourceIds.filter(id => lanes.some(lane => idsEqual(lane.id, id)));\n\n const toggleLane = useCallback((id: KanbanId) => {\n const next = collapsedIds.some(item => idsEqual(item, id))\n ? collapsedIds.filter(item => !idsEqual(item, id))\n : [...collapsedIds, id];\n if (!controlled) setInternalIds(next);\n onCollapsedLaneIdsChange?.(next);\n }, [collapsedIds, controlled, onCollapsedLaneIdsChange]);\n\n return (\n <div {...rest} className={`dishui-swimlanes ${className}`.trim()}>\n {lanes.length === 0 ? <div className=\"dishui-swimlanes__empty\">{empty}</div> : lanes.map(lane => {\n const collapsed = collapsedIds.some(id => idsEqual(id, lane.id));\n const context = { lane, collapsed, toggle: () => toggleLane(lane.id) };\n return (\n <section\n className={`dishui-swimlane ${laneClassName}`.trim()}\n key={String(lane.id)}\n data-lane-id={String(lane.id)}\n data-collapsed={collapsed || undefined}\n >\n <header className=\"dishui-swimlane__header\">\n {renderLaneHeader ? renderLaneHeader(lane, context) : (\n <button\n className=\"dishui-swimlane__toggle\"\n type=\"button\"\n disabled={!collapsible}\n aria-expanded={!collapsed}\n aria-controls={`dishui-swimlane-${String(lane.id)}`}\n onClick={context.toggle}\n >\n <span className=\"dishui-swimlane__chevron\" aria-hidden=\"true\">▾</span>\n <span>{lane.title}</span>\n </button>\n )}\n </header>\n <div id={`dishui-swimlane-${String(lane.id)}`} className=\"dishui-swimlane__content\" hidden={collapsed}>\n {typeof children === \"function\" ? children(context) : children}\n </div>\n </section>\n );\n })}\n </div>\n );\n}\n"],"mappings":";;;;;AAKA,IAAM,IAAwB,CAAC;AAE/B,SAAwB,EAAiD,EACvE,UACA,aACA,qBACA,qBACA,6BAA0B,GAC1B,6BACA,iBAAc,IACd,WAAQ,YACR,eAAY,IACZ,mBAAgB,IAChB,GAAG,KACqB;CACxB,IAAM,IAAa,MAAqB,KAAA,GAClC,CAAC,GAAa,KAAkB,EAAqB,CAAuB,GAE5E,KADY,IAAa,IAAmB,EAAA,CACnB,QAAO,MAAM,EAAM,MAAK,MAAQ,EAAS,EAAK,IAAI,CAAE,CAAC,CAAC,GAE/E,IAAa,GAAa,MAAiB;EAC/C,IAAM,IAAO,EAAa,MAAK,MAAQ,EAAS,GAAM,CAAE,CAAC,IACrD,EAAa,QAAO,MAAQ,CAAC,EAAS,GAAM,CAAE,CAAC,IAC/C,CAAC,GAAG,GAAc,CAAE;EAExB,AADK,KAAY,EAAe,CAAI,GACpC,IAA2B,CAAI;CACjC,GAAG;EAAC;EAAc;EAAY;CAAwB,CAAC;CAEvD,OACE,kBAAC,OAAD;EAAK,GAAI;EAAM,WAAW,oBAAoB,IAAY,KAAK;EAC5D,UAAA,EAAM,WAAW,IAAI,kBAAC,OAAD;GAAK,WAAU;GAA2B,UAAA;EAAW,CAAA,IAAI,EAAM,KAAI,MAAQ;GAC/F,IAAM,IAAY,EAAa,MAAK,MAAM,EAAS,GAAI,EAAK,EAAE,CAAC,GACzD,IAAU;IAAE;IAAM;IAAW,cAAc,EAAW,EAAK,EAAE;GAAE;GACrE,OACE,kBAAC,WAAD;IACE,WAAW,mBAAmB,IAAgB,KAAK;IAEnD,gBAAc,OAAO,EAAK,EAAE;IAC5B,kBAAgB,KAAa,KAAA;IAJ/B,UAAA,CAME,kBAAC,UAAD;KAAQ,WAAU;KACf,UAAA,IAAmB,EAAiB,GAAM,CAAO,IAChD,kBAAC,UAAD;MACE,WAAU;MACV,MAAK;MACL,UAAU,CAAC;MACX,iBAAe,CAAC;MAChB,iBAAe,mBAAmB,OAAO,EAAK,EAAE;MAChD,SAAS,EAAQ;MANnB,UAAA,CAQE,kBAAC,QAAD;OAAM,WAAU;OAA2B,eAAY;OAAO,UAAA;MAAO,CAAA,GACrE,kBAAC,QAAD,EAAA,UAAO,EAAK,MAAY,CAAA,CAClB;;IAEJ,CAAA,GACR,kBAAC,OAAD;KAAK,IAAI,mBAAmB,OAAO,EAAK,EAAE;KAAK,WAAU;KAA2B,QAAQ;KACzF,UAAA,OAAO,KAAa,aAAa,EAAS,CAAO,IAAI;IACnD,CAAA,CACE;GAtBF,GAAA,OAAO,EAAK,EAAE,CAsBZ;EAEb,CAAC;CACE,CAAA;AAET"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type React from "react";
|
|
2
|
+
import type { CardTicketAssignee, CardTicketIssueType, CardTicketLabel, CardTicketPriority, CardTicketStatus, CardTicketSubtaskProgress } from "../../Card";
|
|
3
|
+
export type KanbanId = string | number;
|
|
4
|
+
export interface KanbanColumn {
|
|
5
|
+
id: KanbanId;
|
|
6
|
+
title: React.ReactNode;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
}
|
|
10
|
+
export interface KanbanLane {
|
|
11
|
+
id: KanbanId;
|
|
12
|
+
title: React.ReactNode;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
}
|
|
16
|
+
export interface KanbanCard {
|
|
17
|
+
id: KanbanId;
|
|
18
|
+
columnId: KanbanId;
|
|
19
|
+
laneId?: KanbanId;
|
|
20
|
+
title: React.ReactNode;
|
|
21
|
+
description?: React.ReactNode;
|
|
22
|
+
issueKey?: React.ReactNode;
|
|
23
|
+
status?: CardTicketStatus | React.ReactNode;
|
|
24
|
+
issueType?: CardTicketIssueType | React.ReactNode;
|
|
25
|
+
assignees?: CardTicketAssignee[];
|
|
26
|
+
priority?: CardTicketPriority;
|
|
27
|
+
labels?: Array<CardTicketLabel | React.ReactNode>;
|
|
28
|
+
dueDate?: React.ReactNode;
|
|
29
|
+
estimate?: React.ReactNode;
|
|
30
|
+
subtaskProgress?: CardTicketSubtaskProgress;
|
|
31
|
+
disabled?: boolean;
|
|
32
|
+
[key: string]: unknown;
|
|
33
|
+
}
|
|
34
|
+
export interface KanbanLocation {
|
|
35
|
+
columnId: KanbanId;
|
|
36
|
+
laneId?: KanbanId;
|
|
37
|
+
index: number;
|
|
38
|
+
}
|
|
39
|
+
export interface KanbanCardMove {
|
|
40
|
+
card: KanbanCard;
|
|
41
|
+
from: KanbanLocation;
|
|
42
|
+
to: KanbanLocation;
|
|
43
|
+
cards: KanbanCard[];
|
|
44
|
+
}
|
|
45
|
+
export interface KanbanRenderContext {
|
|
46
|
+
dragging: boolean;
|
|
47
|
+
keyboardDragging: boolean;
|
|
48
|
+
disabled: boolean;
|
|
49
|
+
}
|
|
50
|
+
export interface KanbanLabels {
|
|
51
|
+
loading?: string;
|
|
52
|
+
empty?: string;
|
|
53
|
+
error?: string;
|
|
54
|
+
stale?: string;
|
|
55
|
+
retry?: string;
|
|
56
|
+
unnamedColumn?: string;
|
|
57
|
+
unnamedLane?: string;
|
|
58
|
+
card?: string;
|
|
59
|
+
lift?: string;
|
|
60
|
+
move?: string;
|
|
61
|
+
drop?: string;
|
|
62
|
+
cancel?: string;
|
|
63
|
+
}
|
|
64
|
+
export interface KanbanProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children" | "onError"> {
|
|
65
|
+
columns: KanbanColumn[];
|
|
66
|
+
lanes?: KanbanLane[];
|
|
67
|
+
cards: KanbanCard[];
|
|
68
|
+
onCardMove?: (move: KanbanCardMove) => void;
|
|
69
|
+
renderCard?: (card: KanbanCard, context: KanbanRenderContext) => React.ReactNode;
|
|
70
|
+
renderColumnHeader?: (column: KanbanColumn, cards: KanbanCard[]) => React.ReactNode;
|
|
71
|
+
renderLaneHeader?: (lane: KanbanLane, cards: KanbanCard[]) => React.ReactNode;
|
|
72
|
+
readOnly?: boolean;
|
|
73
|
+
loading?: boolean;
|
|
74
|
+
error?: React.ReactNode;
|
|
75
|
+
stale?: boolean;
|
|
76
|
+
empty?: React.ReactNode;
|
|
77
|
+
onRetry?: () => void;
|
|
78
|
+
labels?: KanbanLabels;
|
|
79
|
+
dragThreshold?: number;
|
|
80
|
+
columnWidth?: number | string;
|
|
81
|
+
height?: number | string;
|
|
82
|
+
collapsedLaneIds?: KanbanId[];
|
|
83
|
+
defaultCollapsedLaneIds?: KanbanId[];
|
|
84
|
+
onCollapsedLaneIdsChange?: (ids: KanbanId[]) => void;
|
|
85
|
+
}
|
|
86
|
+
export interface SwimlaneRenderContext<TLane> {
|
|
87
|
+
lane: TLane;
|
|
88
|
+
collapsed: boolean;
|
|
89
|
+
toggle: () => void;
|
|
90
|
+
}
|
|
91
|
+
export interface SwimlanesProps<TLane extends KanbanLane = KanbanLane> extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
|
|
92
|
+
lanes: TLane[];
|
|
93
|
+
children?: React.ReactNode | ((context: SwimlaneRenderContext<TLane>) => React.ReactNode);
|
|
94
|
+
renderLaneHeader?: (lane: TLane, context: SwimlaneRenderContext<TLane>) => React.ReactNode;
|
|
95
|
+
collapsedLaneIds?: KanbanId[];
|
|
96
|
+
defaultCollapsedLaneIds?: KanbanId[];
|
|
97
|
+
onCollapsedLaneIdsChange?: (ids: KanbanId[]) => void;
|
|
98
|
+
collapsible?: boolean;
|
|
99
|
+
empty?: React.ReactNode;
|
|
100
|
+
laneClassName?: string;
|
|
101
|
+
}
|
|
102
|
+
export interface KanbanDragTarget extends KanbanLocation {
|
|
103
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type React from "react";
|
|
2
|
+
import type { KanbanDragTarget, KanbanId } from "./types";
|
|
3
|
+
export interface UseKanbanDragOptions {
|
|
4
|
+
threshold?: number;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
onDrop: (cardId: KanbanId, target: KanbanDragTarget) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare function useKanbanDrag({ threshold, disabled, onDrop }: UseKanbanDragOptions): {
|
|
9
|
+
draggingId: KanbanId | null;
|
|
10
|
+
target: KanbanDragTarget | null;
|
|
11
|
+
onPointerDown: (event: React.PointerEvent<HTMLElement>, cardId: KanbanId) => void;
|
|
12
|
+
onPointerMove: (event: React.PointerEvent<HTMLElement>) => void;
|
|
13
|
+
onPointerUp: (event: React.PointerEvent<HTMLElement>) => void;
|
|
14
|
+
onPointerCancel: () => void;
|
|
15
|
+
onLostPointerCapture: () => void;
|
|
16
|
+
cancelDrag: () => void;
|
|
17
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { useCallback as e, useEffect as t, useRef as n, useState as r } from "react";
|
|
2
|
+
//#region src/components/pro/Kanban/useKanbanDrag.ts
|
|
3
|
+
function i(e, t) {
|
|
4
|
+
let n = document.elementFromPoint(e, t), r = n?.closest(".dishui-kanban");
|
|
5
|
+
if (!r) return null;
|
|
6
|
+
let i = n?.closest("[data-kanban-drop]"), a = i?.closest("[data-disabled='true']") ? null : i;
|
|
7
|
+
if (!a) {
|
|
8
|
+
let n = Infinity;
|
|
9
|
+
r.querySelectorAll("[data-kanban-drop]").forEach((r) => {
|
|
10
|
+
if (r.closest("[data-disabled='true']")) return;
|
|
11
|
+
let i = r.getBoundingClientRect(), o = e < i.left ? i.left - e : e > i.right ? e - i.right : 0, s = Math.abs(t - (i.top + i.bottom) / 2), c = o * o + s * s;
|
|
12
|
+
c < n && (n = c, a = r);
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
let o = a?.dataset.columnId, s = a?.dataset.laneId, c = Number(a?.dataset.index);
|
|
16
|
+
return o === void 0 || !Number.isFinite(c) ? null : {
|
|
17
|
+
columnId: o,
|
|
18
|
+
laneId: s || void 0,
|
|
19
|
+
index: c
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function a({ threshold: a = 5, disabled: o = !1, onDrop: s }) {
|
|
23
|
+
let [c, l] = r(null), [u, d] = r(null), f = n(null), p = n(!1), m = n(null), h = e(() => {
|
|
24
|
+
let e = f.current;
|
|
25
|
+
f.current = null, p.current = !1, m.current = null, l(null), d(null), e?.element.hasPointerCapture(e.pointerId) && e.element.releasePointerCapture(e.pointerId);
|
|
26
|
+
}, []), g = e((e, t) => {
|
|
27
|
+
if (o || e.button !== 0 || e.currentTarget.closest("[data-kanban-disabled='true']")) return;
|
|
28
|
+
let n = e.currentTarget;
|
|
29
|
+
f.current = {
|
|
30
|
+
cardId: t,
|
|
31
|
+
pointerId: e.pointerId,
|
|
32
|
+
startX: e.clientX,
|
|
33
|
+
startY: e.clientY,
|
|
34
|
+
element: n
|
|
35
|
+
}, n.setPointerCapture(e.pointerId);
|
|
36
|
+
}, [o]), _ = e((e) => {
|
|
37
|
+
let t = f.current;
|
|
38
|
+
if (!t || t.pointerId !== e.pointerId) return;
|
|
39
|
+
let n = Math.hypot(e.clientX - t.startX, e.clientY - t.startY);
|
|
40
|
+
if (!p.current && n < Math.max(4, Math.min(6, a))) return;
|
|
41
|
+
e.preventDefault(), p.current || (p.current = !0, l(t.cardId));
|
|
42
|
+
let r = i(e.clientX, e.clientY);
|
|
43
|
+
m.current = r, d(r);
|
|
44
|
+
}, [a]), v = e((e) => {
|
|
45
|
+
let t = f.current;
|
|
46
|
+
t && t.pointerId === e.pointerId && (p.current && m.current && s(t.cardId, m.current), h());
|
|
47
|
+
}, [h, s]);
|
|
48
|
+
return t(() => {
|
|
49
|
+
let e = () => h(), t = (e) => {
|
|
50
|
+
e.key === "Escape" && h();
|
|
51
|
+
};
|
|
52
|
+
return window.addEventListener("blur", e), window.addEventListener("keydown", t), () => {
|
|
53
|
+
window.removeEventListener("blur", e), window.removeEventListener("keydown", t), h();
|
|
54
|
+
};
|
|
55
|
+
}, [h]), {
|
|
56
|
+
draggingId: c,
|
|
57
|
+
target: u,
|
|
58
|
+
onPointerDown: g,
|
|
59
|
+
onPointerMove: _,
|
|
60
|
+
onPointerUp: v,
|
|
61
|
+
onPointerCancel: h,
|
|
62
|
+
onLostPointerCapture: h,
|
|
63
|
+
cancelDrag: h
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
export { a as useKanbanDrag };
|
|
68
|
+
|
|
69
|
+
//# sourceMappingURL=useKanbanDrag.js.map
|