@object-ui/plugin-kanban 4.0.4 → 4.0.6
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/CHANGELOG.md +56 -0
- package/dist/index.js +0 -0
- package/dist/index.umd.cjs +0 -0
- package/package.json +6 -6
- package/dist/KanbanEnhanced-t4bTknP9.js +0 -290
- package/dist/KanbanImpl-CBkrj9oG.js +0 -401
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,61 @@
|
|
|
1
1
|
# @object-ui/plugin-kanban
|
|
2
2
|
|
|
3
|
+
## 4.0.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 1b6dc64: fix: complete Tailwind v3→v4 migration cleanup
|
|
8
|
+
- Rename deprecated `flex-shrink-0` → `shrink-0` and `flex-grow-N` →
|
|
9
|
+
`grow-N` (Tailwind v4 dropped the long-form aliases). Affects
|
|
10
|
+
data-table, fields/index, FileField, ChatbotEnhanced,
|
|
11
|
+
FloatingChatbotPanel, ProcessDesigner, HistoryPanel, KanbanEnhanced,
|
|
12
|
+
KanbanImpl, plugin-timeline index, FlowDesigner, LayoutRenderer.
|
|
13
|
+
- Replace `theme(spacing.4)` inside arbitrary-value `[calc(...)]` with
|
|
14
|
+
literal `1rem` in sidebar.tsx — `theme()` is deprecated in v4.
|
|
15
|
+
- Remove obsolete v3-escape CSS overrides from index.css and
|
|
16
|
+
sidebar-fixes.css. The component source now uses native v4 stacked
|
|
17
|
+
data variants (`group-data-[state=collapsed]:group-data-[collapsible=icon]:w-(--sidebar-width-icon)`)
|
|
18
|
+
which Tailwind v4 emits correctly without the manual overrides.
|
|
19
|
+
Only the bespoke `.sidebar-menu-button-icon-mode*` rules are kept.
|
|
20
|
+
|
|
21
|
+
- Updated dependencies [925051d]
|
|
22
|
+
- Updated dependencies [1b6dc64]
|
|
23
|
+
- @object-ui/components@4.0.6
|
|
24
|
+
- @object-ui/types@4.0.6
|
|
25
|
+
- @object-ui/core@4.0.6
|
|
26
|
+
- @object-ui/react@4.0.6
|
|
27
|
+
|
|
28
|
+
## 4.0.5
|
|
29
|
+
|
|
30
|
+
### Patch Changes
|
|
31
|
+
|
|
32
|
+
- 1dc6061: fix(build): inline dynamic imports in library outputs
|
|
33
|
+
|
|
34
|
+
Library `vite build --lib` outputs were emitting separate code-split chunks
|
|
35
|
+
(`rolldown-runtime-*.js`, `LookupField-*.js`, etc.) when source files used
|
|
36
|
+
`React.lazy()` / dynamic `import()`. When consumer apps re-bundled these
|
|
37
|
+
multi-file dists, the library's per-chunk rolldown-runtime collided with the
|
|
38
|
+
consumer's own runtime, causing "TypeError: i is not a function" at runtime
|
|
39
|
+
when lazy components tried to register themselves (e.g. TextField in
|
|
40
|
+
`@object-ui/fields` after 4.0.4).
|
|
41
|
+
|
|
42
|
+
Adding `output.inlineDynamicImports: true` to all `@object-ui/*` library vite
|
|
43
|
+
configs forces a single `dist/index.js` per package, which lets consumer
|
|
44
|
+
bundlers handle the library as an opaque ESM module without identifier
|
|
45
|
+
mismatches across chunks.
|
|
46
|
+
|
|
47
|
+
Affected packages: components, fields, layout, plugin-aggrid, plugin-ai,
|
|
48
|
+
plugin-calendar, plugin-charts, plugin-chatbot, plugin-dashboard,
|
|
49
|
+
plugin-designer, plugin-detail, plugin-editor, plugin-form, plugin-gantt,
|
|
50
|
+
plugin-grid, plugin-kanban, plugin-list, plugin-map, plugin-markdown,
|
|
51
|
+
plugin-report, plugin-timeline, plugin-view, plugin-workflow.
|
|
52
|
+
|
|
53
|
+
- Updated dependencies [1dc6061]
|
|
54
|
+
- @object-ui/components@4.0.5
|
|
55
|
+
- @object-ui/types@4.0.5
|
|
56
|
+
- @object-ui/core@4.0.5
|
|
57
|
+
- @object-ui/react@4.0.5
|
|
58
|
+
|
|
3
59
|
## 4.0.4
|
|
4
60
|
|
|
5
61
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
Binary file
|
package/dist/index.umd.cjs
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@object-ui/plugin-kanban",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Kanban board plugin for Object UI, powered by dnd-kit",
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
"@dnd-kit/utilities": "^3.2.2",
|
|
30
30
|
"@tanstack/react-virtual": "^3.13.24",
|
|
31
31
|
"lucide-react": "^1.14.0",
|
|
32
|
-
"@object-ui/components": "4.0.
|
|
33
|
-
"@object-ui/core": "4.0.
|
|
34
|
-
"@object-ui/react": "4.0.
|
|
35
|
-
"@object-ui/types": "4.0.
|
|
32
|
+
"@object-ui/components": "4.0.6",
|
|
33
|
+
"@object-ui/core": "4.0.6",
|
|
34
|
+
"@object-ui/react": "4.0.6",
|
|
35
|
+
"@object-ui/types": "4.0.6"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"react": "^18.0.0 || ^19.0.0",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"typescript": "^6.0.3",
|
|
46
46
|
"vite": "^8.0.10",
|
|
47
47
|
"vite-plugin-dts": "^5.0.0",
|
|
48
|
-
"@object-ui/data-objectstack": "4.0.
|
|
48
|
+
"@object-ui/data-objectstack": "4.0.6"
|
|
49
49
|
},
|
|
50
50
|
"keywords": [
|
|
51
51
|
"objectui",
|
|
@@ -1,290 +0,0 @@
|
|
|
1
|
-
import * as e from "react";
|
|
2
|
-
import { Badge as t, Button as n, Card as r, CardContent as i, CardDescription as a, CardHeader as o, CardTitle as s, Input as c } from "@object-ui/components";
|
|
3
|
-
import { Fragment as l, jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
4
|
-
import { AlertTriangle as f, ChevronDown as p, ChevronRight as m, Plus as h } from "lucide-react";
|
|
5
|
-
import { useVirtualizer as g } from "@tanstack/react-virtual";
|
|
6
|
-
import { DndContext as _, DragOverlay as v, PointerSensor as y, closestCorners as b, useSensor as x, useSensors as S } from "@dnd-kit/core";
|
|
7
|
-
import { SortableContext as C, arrayMove as w, useSortable as T, verticalListSortingStrategy as E } from "@dnd-kit/sortable";
|
|
8
|
-
import { CSS as D } from "@dnd-kit/utilities";
|
|
9
|
-
//#region src/KanbanEnhanced.tsx
|
|
10
|
-
var O = (...e) => e.filter(Boolean).join(" ");
|
|
11
|
-
function k(e, t) {
|
|
12
|
-
if (!t || t.length === 0) return {};
|
|
13
|
-
for (let n of t) {
|
|
14
|
-
let t = e[n.field];
|
|
15
|
-
if (t == null) continue;
|
|
16
|
-
let r = !1, i = String(t);
|
|
17
|
-
switch (n.operator) {
|
|
18
|
-
case "equals":
|
|
19
|
-
r = i === String(n.value);
|
|
20
|
-
break;
|
|
21
|
-
case "not_equals":
|
|
22
|
-
r = i !== String(n.value);
|
|
23
|
-
break;
|
|
24
|
-
case "contains":
|
|
25
|
-
r = i.toLowerCase().includes(String(n.value).toLowerCase());
|
|
26
|
-
break;
|
|
27
|
-
case "in":
|
|
28
|
-
r = Array.isArray(n.value) && n.value.includes(i);
|
|
29
|
-
break;
|
|
30
|
-
}
|
|
31
|
-
if (r) return {
|
|
32
|
-
...n.backgroundColor ? { backgroundColor: n.backgroundColor } : {},
|
|
33
|
-
...n.borderColor ? { borderColor: n.borderColor } : {}
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
return {};
|
|
37
|
-
}
|
|
38
|
-
function A({ card: e, conditionalFormatting: n }) {
|
|
39
|
-
let { attributes: c, listeners: l, setNodeRef: f, transform: p, transition: m, isDragging: h } = T({ id: e.id }), g = {
|
|
40
|
-
transform: D.Transform.toString(p),
|
|
41
|
-
transition: m,
|
|
42
|
-
opacity: h ? .5 : void 0
|
|
43
|
-
}, _ = k(e, n);
|
|
44
|
-
return /* @__PURE__ */ u("div", {
|
|
45
|
-
ref: f,
|
|
46
|
-
style: g,
|
|
47
|
-
...c,
|
|
48
|
-
...l,
|
|
49
|
-
children: /* @__PURE__ */ d(r, {
|
|
50
|
-
className: "mb-2 cursor-grab active:cursor-grabbing border-border bg-card/60 hover:border-primary/40 hover:shadow-lg hover:shadow-primary/10 transition-all duration-300 group",
|
|
51
|
-
style: _,
|
|
52
|
-
children: [
|
|
53
|
-
e.coverImage && /* @__PURE__ */ u("div", {
|
|
54
|
-
className: "w-full h-32 overflow-hidden rounded-t-lg",
|
|
55
|
-
children: /* @__PURE__ */ u("img", {
|
|
56
|
-
src: e.coverImage,
|
|
57
|
-
alt: "",
|
|
58
|
-
className: "w-full h-full object-cover",
|
|
59
|
-
loading: "lazy"
|
|
60
|
-
})
|
|
61
|
-
}),
|
|
62
|
-
/* @__PURE__ */ d(o, {
|
|
63
|
-
className: "p-4",
|
|
64
|
-
children: [/* @__PURE__ */ u(s, {
|
|
65
|
-
className: "text-sm font-medium tracking-tight text-foreground group-hover:text-primary transition-colors",
|
|
66
|
-
children: e.title
|
|
67
|
-
}), e.description && /* @__PURE__ */ u(a, {
|
|
68
|
-
className: "text-xs text-muted-foreground",
|
|
69
|
-
children: e.description
|
|
70
|
-
})]
|
|
71
|
-
}),
|
|
72
|
-
e.badges && e.badges.length > 0 && /* @__PURE__ */ u(i, {
|
|
73
|
-
className: "p-4 pt-0",
|
|
74
|
-
children: /* @__PURE__ */ u("div", {
|
|
75
|
-
className: "flex flex-wrap gap-1",
|
|
76
|
-
children: e.badges.map((e, n) => /* @__PURE__ */ u(t, {
|
|
77
|
-
variant: e.variant || "default",
|
|
78
|
-
className: "text-xs",
|
|
79
|
-
children: e.label
|
|
80
|
-
}, n))
|
|
81
|
-
})
|
|
82
|
-
})
|
|
83
|
-
]
|
|
84
|
-
})
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
function j({ cards: e, parentRef: t, conditionalFormatting: n }) {
|
|
88
|
-
let r = g({
|
|
89
|
-
count: e.length,
|
|
90
|
-
getScrollElement: () => t.current,
|
|
91
|
-
estimateSize: () => 120,
|
|
92
|
-
overscan: 5
|
|
93
|
-
});
|
|
94
|
-
return /* @__PURE__ */ u("div", {
|
|
95
|
-
style: {
|
|
96
|
-
height: `${r.getTotalSize()}px`,
|
|
97
|
-
width: "100%",
|
|
98
|
-
position: "relative"
|
|
99
|
-
},
|
|
100
|
-
children: r.getVirtualItems().map((t) => {
|
|
101
|
-
let r = e[t.index];
|
|
102
|
-
return /* @__PURE__ */ u("div", {
|
|
103
|
-
style: {
|
|
104
|
-
position: "absolute",
|
|
105
|
-
top: 0,
|
|
106
|
-
left: 0,
|
|
107
|
-
width: "100%",
|
|
108
|
-
transform: `translateY(${t.start}px)`
|
|
109
|
-
},
|
|
110
|
-
children: /* @__PURE__ */ u(A, {
|
|
111
|
-
card: r,
|
|
112
|
-
conditionalFormatting: n
|
|
113
|
-
})
|
|
114
|
-
}, r.id);
|
|
115
|
-
})
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
function M({ columnId: t, onAdd: r }) {
|
|
119
|
-
let [i, a] = e.useState(!1), [o, s] = e.useState(""), l = e.useRef(null), f = () => {
|
|
120
|
-
let e = o.trim();
|
|
121
|
-
e && (r(t, e), s("")), a(!1);
|
|
122
|
-
};
|
|
123
|
-
return i ? /* @__PURE__ */ u("div", {
|
|
124
|
-
className: "mt-2 space-y-2",
|
|
125
|
-
children: /* @__PURE__ */ u(c, {
|
|
126
|
-
ref: l,
|
|
127
|
-
value: o,
|
|
128
|
-
onChange: (e) => s(e.target.value),
|
|
129
|
-
onKeyDown: (e) => {
|
|
130
|
-
e.key === "Enter" ? (e.preventDefault(), f()) : e.key === "Escape" && (s(""), a(!1));
|
|
131
|
-
},
|
|
132
|
-
onBlur: f,
|
|
133
|
-
placeholder: "Enter card title...",
|
|
134
|
-
className: "text-sm",
|
|
135
|
-
autoFocus: !0
|
|
136
|
-
})
|
|
137
|
-
}) : /* @__PURE__ */ d(n, {
|
|
138
|
-
variant: "ghost",
|
|
139
|
-
size: "sm",
|
|
140
|
-
className: "w-full mt-2 text-muted-foreground hover:text-foreground",
|
|
141
|
-
onClick: () => {
|
|
142
|
-
a(!0), setTimeout(() => l.current?.focus(), 0);
|
|
143
|
-
},
|
|
144
|
-
children: [/* @__PURE__ */ u(h, { className: "h-4 w-4 mr-1" }), "Add Card"]
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
function N({ column: r, cards: i, onToggle: a, enableVirtual: o, quickAdd: s, onQuickAdd: c, conditionalFormatting: h }) {
|
|
148
|
-
let g = i || [], _ = e.useRef(null), { setNodeRef: v } = T({
|
|
149
|
-
id: r.id,
|
|
150
|
-
data: { type: "column" }
|
|
151
|
-
}), y = r.limit && g.length >= r.limit, b = r.limit && g.length >= r.limit * .8;
|
|
152
|
-
return /* @__PURE__ */ d("div", {
|
|
153
|
-
ref: v,
|
|
154
|
-
className: O("flex flex-col flex-shrink-0 rounded-lg border border-border bg-card/20 backdrop-blur-sm shadow-xl transition-all", r.collapsed ? "w-16" : "w-80", r.className),
|
|
155
|
-
children: [/* @__PURE__ */ d("div", {
|
|
156
|
-
className: "p-4 border-b border-border/50 bg-muted/20 flex items-center justify-between",
|
|
157
|
-
children: [/* @__PURE__ */ d("div", {
|
|
158
|
-
className: "flex items-center gap-2 flex-1 min-w-0",
|
|
159
|
-
children: [/* @__PURE__ */ u(n, {
|
|
160
|
-
variant: "ghost",
|
|
161
|
-
size: "sm",
|
|
162
|
-
className: "h-6 w-6 p-0",
|
|
163
|
-
onClick: () => a(!r.collapsed),
|
|
164
|
-
children: r.collapsed ? /* @__PURE__ */ u(m, { className: "h-4 w-4" }) : /* @__PURE__ */ u(p, { className: "h-4 w-4" })
|
|
165
|
-
}), !r.collapsed && /* @__PURE__ */ d(l, { children: [/* @__PURE__ */ u("h3", {
|
|
166
|
-
className: " text-sm font-semibold tracking-wider text-primary/90 uppercase truncate",
|
|
167
|
-
children: r.title
|
|
168
|
-
}), /* @__PURE__ */ d("div", {
|
|
169
|
-
className: "flex items-center gap-2",
|
|
170
|
-
children: [
|
|
171
|
-
/* @__PURE__ */ d("span", {
|
|
172
|
-
className: O(" text-xs", y ? "text-destructive" : b ? "text-yellow-500" : "text-muted-foreground"),
|
|
173
|
-
children: [g.length, r.limit && ` / ${r.limit}`]
|
|
174
|
-
}),
|
|
175
|
-
y && /* @__PURE__ */ u(t, {
|
|
176
|
-
variant: "destructive",
|
|
177
|
-
className: "text-xs",
|
|
178
|
-
children: "Full"
|
|
179
|
-
}),
|
|
180
|
-
b && !y && /* @__PURE__ */ u(f, { className: "h-3 w-3 text-yellow-500" })
|
|
181
|
-
]
|
|
182
|
-
})] })]
|
|
183
|
-
}), r.collapsed && /* @__PURE__ */ d("div", {
|
|
184
|
-
className: "flex flex-col items-center gap-1",
|
|
185
|
-
children: [/* @__PURE__ */ u("span", {
|
|
186
|
-
className: " text-xs font-bold text-primary/90 [writing-mode:vertical-rl] rotate-180",
|
|
187
|
-
children: r.title
|
|
188
|
-
}), /* @__PURE__ */ u(t, {
|
|
189
|
-
variant: "secondary",
|
|
190
|
-
className: "text-xs",
|
|
191
|
-
children: g.length
|
|
192
|
-
})]
|
|
193
|
-
})]
|
|
194
|
-
}), !r.collapsed && /* @__PURE__ */ d("div", {
|
|
195
|
-
ref: _,
|
|
196
|
-
className: "flex-1 p-4 overflow-y-auto",
|
|
197
|
-
style: { maxHeight: "600px" },
|
|
198
|
-
children: [/* @__PURE__ */ u(C, {
|
|
199
|
-
items: g.map((e) => e.id),
|
|
200
|
-
strategy: E,
|
|
201
|
-
children: o ? /* @__PURE__ */ u(j, {
|
|
202
|
-
cards: g,
|
|
203
|
-
parentRef: _,
|
|
204
|
-
conditionalFormatting: h
|
|
205
|
-
}) : /* @__PURE__ */ u("div", {
|
|
206
|
-
className: "space-y-2",
|
|
207
|
-
children: g.map((e) => /* @__PURE__ */ u(A, {
|
|
208
|
-
card: e,
|
|
209
|
-
conditionalFormatting: h
|
|
210
|
-
}, e.id))
|
|
211
|
-
})
|
|
212
|
-
}), s && c && /* @__PURE__ */ u(M, {
|
|
213
|
-
columnId: r.id,
|
|
214
|
-
onAdd: c
|
|
215
|
-
})]
|
|
216
|
-
})]
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
function P({ columns: t, onCardMove: n, onColumnToggle: r, enableVirtualScrolling: i = !1, virtualScrollThreshold: a = 50, className: o, quickAdd: s, onQuickAdd: c, conditionalFormatting: l }) {
|
|
220
|
-
let [f, p] = e.useState(null), m = e.useMemo(() => (t || []).map((e) => ({
|
|
221
|
-
...e,
|
|
222
|
-
cards: e.cards || []
|
|
223
|
-
})), [t]), [h, g] = e.useState(m);
|
|
224
|
-
e.useEffect(() => {
|
|
225
|
-
g(m);
|
|
226
|
-
}, [m]);
|
|
227
|
-
let C = S(x(y, { activationConstraint: { distance: 8 } })), T = (e) => {
|
|
228
|
-
let { active: t } = e;
|
|
229
|
-
p(D(t.id));
|
|
230
|
-
}, E = (e) => {
|
|
231
|
-
let { active: t, over: r } = e;
|
|
232
|
-
if (p(null), !r) return;
|
|
233
|
-
let i = t.id, a = r.id;
|
|
234
|
-
if (i === a) return;
|
|
235
|
-
let o = k(i), s = k(a) || j(a);
|
|
236
|
-
if (!(!o || !s)) if (o.id === s.id) {
|
|
237
|
-
let e = [...o.cards], t = w(e, e.findIndex((e) => e.id === i), e.findIndex((e) => e.id === a));
|
|
238
|
-
g((e) => e.map((e) => e.id === o.id ? {
|
|
239
|
-
...e,
|
|
240
|
-
cards: t
|
|
241
|
-
} : e));
|
|
242
|
-
} else {
|
|
243
|
-
let e = [...o.cards], t = [...s.cards], r = e.findIndex((e) => e.id === i), c = a === s.id ? t.length : t.findIndex((e) => e.id === a), [l] = e.splice(r, 1);
|
|
244
|
-
t.splice(c, 0, l), g((n) => n.map((n) => n.id === o.id ? {
|
|
245
|
-
...n,
|
|
246
|
-
cards: e
|
|
247
|
-
} : n.id === s.id ? {
|
|
248
|
-
...n,
|
|
249
|
-
cards: t
|
|
250
|
-
} : n)), n && n(i, o.id, s.id, c);
|
|
251
|
-
}
|
|
252
|
-
}, D = e.useCallback((e) => {
|
|
253
|
-
for (let t of h) {
|
|
254
|
-
let n = t.cards.find((t) => t.id === e);
|
|
255
|
-
if (n) return n;
|
|
256
|
-
}
|
|
257
|
-
return null;
|
|
258
|
-
}, [h]), k = e.useCallback((e) => h.find((t) => t.cards.some((t) => t.id === e)) || null, [h]), j = e.useCallback((e) => h.find((t) => t.id === e) || null, [h]), M = e.useCallback((e, t) => {
|
|
259
|
-
g((n) => n.map((n) => n.id === e ? {
|
|
260
|
-
...n,
|
|
261
|
-
collapsed: t
|
|
262
|
-
} : n)), r?.(e, t);
|
|
263
|
-
}, [r]);
|
|
264
|
-
return /* @__PURE__ */ d(_, {
|
|
265
|
-
sensors: C,
|
|
266
|
-
collisionDetection: b,
|
|
267
|
-
onDragStart: T,
|
|
268
|
-
onDragEnd: E,
|
|
269
|
-
children: [/* @__PURE__ */ u("div", {
|
|
270
|
-
className: O("flex gap-4 overflow-x-auto p-4", o),
|
|
271
|
-
children: h.map((e) => {
|
|
272
|
-
let t = i && e.cards.length > a;
|
|
273
|
-
return /* @__PURE__ */ u(N, {
|
|
274
|
-
column: e,
|
|
275
|
-
cards: e.cards,
|
|
276
|
-
onToggle: (t) => M(e.id, t),
|
|
277
|
-
enableVirtual: t,
|
|
278
|
-
quickAdd: s,
|
|
279
|
-
onQuickAdd: c,
|
|
280
|
-
conditionalFormatting: l
|
|
281
|
-
}, e.id);
|
|
282
|
-
})
|
|
283
|
-
}), /* @__PURE__ */ u(v, { children: f ? /* @__PURE__ */ u(A, {
|
|
284
|
-
card: f,
|
|
285
|
-
conditionalFormatting: l
|
|
286
|
-
}) : null })]
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
//#endregion
|
|
290
|
-
export { P as KanbanEnhanced, P as default };
|
|
@@ -1,401 +0,0 @@
|
|
|
1
|
-
import * as e from "react";
|
|
2
|
-
import { useDnd as t, useHasDndProvider as n } from "@object-ui/react";
|
|
3
|
-
import { Badge as r, Button as i, Card as a, CardContent as o, CardDescription as s, CardHeader as c, CardTitle as l, Input as u, ScrollArea as d, useResizeObserver as f } from "@object-ui/components";
|
|
4
|
-
import { Fragment as p, jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
5
|
-
import { Plus as g } from "lucide-react";
|
|
6
|
-
import { DndContext as _, DragOverlay as v, PointerSensor as y, TouchSensor as b, closestCorners as x, useSensor as S, useSensors as C } from "@dnd-kit/core";
|
|
7
|
-
import { SortableContext as w, arrayMove as T, useSortable as E, verticalListSortingStrategy as D } from "@dnd-kit/sortable";
|
|
8
|
-
import { CSS as O } from "@dnd-kit/utilities";
|
|
9
|
-
//#region src/KanbanImpl.tsx
|
|
10
|
-
var k = (...e) => e.filter(Boolean).join(" "), A = "Uncategorized";
|
|
11
|
-
function j(e, t) {
|
|
12
|
-
if (!t || t.length === 0) return {};
|
|
13
|
-
for (let n of t) {
|
|
14
|
-
let t = e[n.field];
|
|
15
|
-
if (t == null) continue;
|
|
16
|
-
let r = !1, i = String(t);
|
|
17
|
-
switch (n.operator) {
|
|
18
|
-
case "equals":
|
|
19
|
-
r = i === String(n.value);
|
|
20
|
-
break;
|
|
21
|
-
case "not_equals":
|
|
22
|
-
r = i !== String(n.value);
|
|
23
|
-
break;
|
|
24
|
-
case "contains":
|
|
25
|
-
r = i.toLowerCase().includes(String(n.value).toLowerCase());
|
|
26
|
-
break;
|
|
27
|
-
case "in":
|
|
28
|
-
r = Array.isArray(n.value) && n.value.includes(i);
|
|
29
|
-
break;
|
|
30
|
-
}
|
|
31
|
-
if (r) return {
|
|
32
|
-
...n.backgroundColor ? { backgroundColor: n.backgroundColor } : {},
|
|
33
|
-
...n.borderColor ? { borderColor: n.borderColor } : {}
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
return {};
|
|
37
|
-
}
|
|
38
|
-
function M({ card: e, onCardClick: t, conditionalFormatting: n }) {
|
|
39
|
-
let { attributes: i, listeners: u, setNodeRef: d, transform: f, transition: p, isDragging: g } = E({ id: e.id }), _ = {
|
|
40
|
-
transform: O.Transform.toString(f),
|
|
41
|
-
transition: p,
|
|
42
|
-
opacity: g ? .5 : void 0
|
|
43
|
-
}, v = j(e, n);
|
|
44
|
-
return /* @__PURE__ */ m("div", {
|
|
45
|
-
ref: d,
|
|
46
|
-
style: _,
|
|
47
|
-
...i,
|
|
48
|
-
...u,
|
|
49
|
-
role: "listitem",
|
|
50
|
-
"aria-label": e.title,
|
|
51
|
-
onClick: () => t?.(e),
|
|
52
|
-
children: /* @__PURE__ */ h(a, {
|
|
53
|
-
className: "mb-2 cursor-grab active:cursor-grabbing border-border border-l-4 border-l-primary/40 bg-card/60 hover:border-primary/40 hover:shadow-lg hover:shadow-primary/10 transition-all duration-300 group touch-manipulation",
|
|
54
|
-
style: v,
|
|
55
|
-
children: [
|
|
56
|
-
e.coverImage && /* @__PURE__ */ m("div", {
|
|
57
|
-
className: "w-full h-32 overflow-hidden rounded-t-lg",
|
|
58
|
-
children: /* @__PURE__ */ m("img", {
|
|
59
|
-
src: e.coverImage,
|
|
60
|
-
alt: "",
|
|
61
|
-
className: "w-full h-full object-cover",
|
|
62
|
-
loading: "lazy"
|
|
63
|
-
})
|
|
64
|
-
}),
|
|
65
|
-
/* @__PURE__ */ h(c, {
|
|
66
|
-
className: "p-2 sm:p-4",
|
|
67
|
-
children: [/* @__PURE__ */ m(l, {
|
|
68
|
-
className: "text-xs sm:text-sm font-medium tracking-tight text-foreground group-hover:text-primary transition-colors",
|
|
69
|
-
children: e.title
|
|
70
|
-
}), e.description && /* @__PURE__ */ m(s, {
|
|
71
|
-
className: "text-xs text-muted-foreground line-clamp-2 sm:line-clamp-none",
|
|
72
|
-
children: e.description
|
|
73
|
-
})]
|
|
74
|
-
}),
|
|
75
|
-
e.badges && e.badges.length > 0 && /* @__PURE__ */ m(o, {
|
|
76
|
-
className: "p-2 sm:p-4 pt-0",
|
|
77
|
-
children: /* @__PURE__ */ m("div", {
|
|
78
|
-
className: "flex flex-wrap gap-1",
|
|
79
|
-
children: e.badges.map((e, t) => /* @__PURE__ */ m(r, {
|
|
80
|
-
variant: e.variant || "default",
|
|
81
|
-
className: "text-xs",
|
|
82
|
-
children: e.label
|
|
83
|
-
}, t))
|
|
84
|
-
})
|
|
85
|
-
})
|
|
86
|
-
]
|
|
87
|
-
})
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
function N({ columnId: t, onAdd: n }) {
|
|
91
|
-
let [r, a] = e.useState(!1), [o, s] = e.useState(""), c = e.useRef(null), l = () => {
|
|
92
|
-
let e = o.trim();
|
|
93
|
-
e && (n(t, e), s("")), a(!1);
|
|
94
|
-
};
|
|
95
|
-
return r ? /* @__PURE__ */ m("div", {
|
|
96
|
-
className: "mt-2 space-y-2",
|
|
97
|
-
children: /* @__PURE__ */ m(u, {
|
|
98
|
-
ref: c,
|
|
99
|
-
value: o,
|
|
100
|
-
onChange: (e) => s(e.target.value),
|
|
101
|
-
onKeyDown: (e) => {
|
|
102
|
-
e.key === "Enter" ? (e.preventDefault(), l()) : e.key === "Escape" && (s(""), a(!1));
|
|
103
|
-
},
|
|
104
|
-
onBlur: l,
|
|
105
|
-
placeholder: "Enter card title...",
|
|
106
|
-
className: "text-sm",
|
|
107
|
-
autoFocus: !0
|
|
108
|
-
})
|
|
109
|
-
}) : /* @__PURE__ */ h(i, {
|
|
110
|
-
variant: "ghost",
|
|
111
|
-
size: "sm",
|
|
112
|
-
className: "w-full mt-2 text-muted-foreground hover:text-foreground",
|
|
113
|
-
onClick: () => {
|
|
114
|
-
a(!0), setTimeout(() => c.current?.focus(), 0);
|
|
115
|
-
},
|
|
116
|
-
children: [/* @__PURE__ */ m(g, { className: "h-4 w-4 mr-1" }), "Add Card"]
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
function P({ column: e, cards: t, onCardClick: n, quickAdd: i, onQuickAdd: a, conditionalFormatting: o, columnStyle: s }) {
|
|
120
|
-
let c = t || [], { setNodeRef: l } = E({
|
|
121
|
-
id: e.id,
|
|
122
|
-
data: { type: "column" }
|
|
123
|
-
}), u = e.limit && c.length >= e.limit, f = s && s.width != null ? "flex-shrink-0" : "w-[85vw] sm:w-80 flex-shrink-0";
|
|
124
|
-
return /* @__PURE__ */ h("div", {
|
|
125
|
-
ref: l,
|
|
126
|
-
role: "group",
|
|
127
|
-
"aria-label": e.title,
|
|
128
|
-
style: s,
|
|
129
|
-
className: k("flex flex-col rounded-lg border border-border bg-card/20 backdrop-blur-sm shadow-xl snap-start max-h-full min-h-0", f, e.className),
|
|
130
|
-
children: [/* @__PURE__ */ m("div", {
|
|
131
|
-
className: "p-3 sm:p-4 border-b border-border/50 bg-muted/30 rounded-t-lg",
|
|
132
|
-
children: /* @__PURE__ */ h("div", {
|
|
133
|
-
className: "flex items-center justify-between",
|
|
134
|
-
children: [/* @__PURE__ */ m("h3", {
|
|
135
|
-
id: `kanban-col-${e.id}`,
|
|
136
|
-
className: " text-xs sm:text-sm font-semibold tracking-wider text-primary/90 uppercase truncate",
|
|
137
|
-
children: e.title
|
|
138
|
-
}), /* @__PURE__ */ h("div", {
|
|
139
|
-
className: "flex items-center gap-2",
|
|
140
|
-
children: [/* @__PURE__ */ h(r, {
|
|
141
|
-
variant: "secondary",
|
|
142
|
-
className: "text-xs tabular-nums",
|
|
143
|
-
children: [c.length, e.limit && ` / ${e.limit}`]
|
|
144
|
-
}), u && /* @__PURE__ */ m(r, {
|
|
145
|
-
variant: "destructive",
|
|
146
|
-
className: "text-xs",
|
|
147
|
-
children: "Full"
|
|
148
|
-
})]
|
|
149
|
-
})]
|
|
150
|
-
})
|
|
151
|
-
}), /* @__PURE__ */ h(d, {
|
|
152
|
-
className: "flex-1 p-4",
|
|
153
|
-
children: [/* @__PURE__ */ m(w, {
|
|
154
|
-
items: c.map((e) => e.id),
|
|
155
|
-
strategy: D,
|
|
156
|
-
children: /* @__PURE__ */ h("div", {
|
|
157
|
-
className: "space-y-2",
|
|
158
|
-
role: "list",
|
|
159
|
-
"aria-label": `${e.title} cards`,
|
|
160
|
-
children: [c.length === 0 && /* @__PURE__ */ m("div", {
|
|
161
|
-
className: "flex flex-col items-center justify-center py-8 text-muted-foreground/50",
|
|
162
|
-
children: /* @__PURE__ */ m("span", {
|
|
163
|
-
className: "text-xs",
|
|
164
|
-
children: "No cards"
|
|
165
|
-
})
|
|
166
|
-
}), c.map((e) => /* @__PURE__ */ m(M, {
|
|
167
|
-
card: e,
|
|
168
|
-
onCardClick: n,
|
|
169
|
-
conditionalFormatting: o
|
|
170
|
-
}, e.id))]
|
|
171
|
-
})
|
|
172
|
-
}), i && a && /* @__PURE__ */ m(N, {
|
|
173
|
-
columnId: e.id,
|
|
174
|
-
onAdd: a
|
|
175
|
-
})]
|
|
176
|
-
})]
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
function F({ children: e }) {
|
|
180
|
-
return /* @__PURE__ */ m(p, { children: e(t()) });
|
|
181
|
-
}
|
|
182
|
-
function I({ columns: e, onCardMove: t, onCardClick: r, className: i, quickAdd: a, onQuickAdd: o, coverImageField: s, conditionalFormatting: c, swimlaneField: l }) {
|
|
183
|
-
return n() ? /* @__PURE__ */ m(F, { children: (n) => /* @__PURE__ */ m(L, {
|
|
184
|
-
columns: e,
|
|
185
|
-
onCardMove: t,
|
|
186
|
-
onCardClick: r,
|
|
187
|
-
className: i,
|
|
188
|
-
dnd: n,
|
|
189
|
-
quickAdd: a,
|
|
190
|
-
onQuickAdd: o,
|
|
191
|
-
coverImageField: s,
|
|
192
|
-
conditionalFormatting: c,
|
|
193
|
-
swimlaneField: l
|
|
194
|
-
}) }) : /* @__PURE__ */ m(L, {
|
|
195
|
-
columns: e,
|
|
196
|
-
onCardMove: t,
|
|
197
|
-
onCardClick: r,
|
|
198
|
-
className: i,
|
|
199
|
-
dnd: null,
|
|
200
|
-
quickAdd: a,
|
|
201
|
-
onQuickAdd: o,
|
|
202
|
-
coverImageField: s,
|
|
203
|
-
conditionalFormatting: c,
|
|
204
|
-
swimlaneField: l
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
function L({ columns: t, onCardMove: n, onCardClick: r, className: i, dnd: a, quickAdd: o, onQuickAdd: s, coverImageField: c, conditionalFormatting: l, swimlaneField: u }) {
|
|
208
|
-
let [d, p] = e.useState(null), g = e.useRef(null), { width: E } = f(g), O = e.useMemo(() => E ? E < 480 ? { width: Math.max(E - 32, 220) } : E < 720 ? { width: 280 } : { width: 320 } : {}, [E]), j = u ? `objectui:kanban-collapsed:${u}` : null, [N, F] = e.useState(() => {
|
|
209
|
-
if (!j) return /* @__PURE__ */ new Set();
|
|
210
|
-
try {
|
|
211
|
-
let e = localStorage.getItem(j);
|
|
212
|
-
if (e) {
|
|
213
|
-
let t = JSON.parse(e);
|
|
214
|
-
if (Array.isArray(t)) return new Set(t.filter((e) => typeof e == "string"));
|
|
215
|
-
}
|
|
216
|
-
} catch {}
|
|
217
|
-
return /* @__PURE__ */ new Set();
|
|
218
|
-
}), I = e.useMemo(() => (t || []).map((e) => ({
|
|
219
|
-
...e,
|
|
220
|
-
cards: e.cards || []
|
|
221
|
-
})), [t]), [L, R] = e.useState(I);
|
|
222
|
-
e.useEffect(() => {
|
|
223
|
-
R(I);
|
|
224
|
-
}, [I]);
|
|
225
|
-
let z = e.useMemo(() => {
|
|
226
|
-
if (!u) return null;
|
|
227
|
-
let e = L.flatMap((e) => e.cards), t = /* @__PURE__ */ new Set();
|
|
228
|
-
return e.forEach((e) => {
|
|
229
|
-
let n = e[u];
|
|
230
|
-
t.add(n == null ? A : String(n));
|
|
231
|
-
}), Array.from(t).sort();
|
|
232
|
-
}, [L, u]), B = e.useCallback((e) => {
|
|
233
|
-
F((t) => {
|
|
234
|
-
let n = new Set(t);
|
|
235
|
-
if (n.has(e) ? n.delete(e) : n.add(e), j) try {
|
|
236
|
-
localStorage.setItem(j, JSON.stringify([...n]));
|
|
237
|
-
} catch {}
|
|
238
|
-
return n;
|
|
239
|
-
});
|
|
240
|
-
}, [j]), V = C(S(y, { activationConstraint: { distance: 5 } }), S(b, { activationConstraint: {
|
|
241
|
-
delay: 200,
|
|
242
|
-
tolerance: 5
|
|
243
|
-
} })), H = (e) => {
|
|
244
|
-
let { active: t } = e, n = W(t.id);
|
|
245
|
-
if (p(n), a && n) {
|
|
246
|
-
let e = G(n.id);
|
|
247
|
-
e && a.startDrag({
|
|
248
|
-
id: n.id,
|
|
249
|
-
type: "kanban-card",
|
|
250
|
-
data: n,
|
|
251
|
-
sourceId: e.id
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
}, U = (e) => {
|
|
255
|
-
let { active: t, over: r } = e;
|
|
256
|
-
if (p(null), !r) {
|
|
257
|
-
a && a.endDrag();
|
|
258
|
-
return;
|
|
259
|
-
}
|
|
260
|
-
let i = t.id, o = r.id;
|
|
261
|
-
if (i === o) {
|
|
262
|
-
a && a.endDrag();
|
|
263
|
-
return;
|
|
264
|
-
}
|
|
265
|
-
let s = G(i), c = G(o) || K(o);
|
|
266
|
-
if (!s || !c) {
|
|
267
|
-
a && a.endDrag();
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
if (s.id === c.id) {
|
|
271
|
-
let e = [...s.cards], t = T(e, e.findIndex((e) => e.id === i), e.findIndex((e) => e.id === o));
|
|
272
|
-
R((e) => e.map((e) => e.id === s.id ? {
|
|
273
|
-
...e,
|
|
274
|
-
cards: t
|
|
275
|
-
} : e));
|
|
276
|
-
} else {
|
|
277
|
-
let e = [...s.cards], t = [...c.cards], r = e.findIndex((e) => e.id === i), a = o === c.id ? t.length : t.findIndex((e) => e.id === o), [l] = e.splice(r, 1);
|
|
278
|
-
t.splice(a, 0, l), R((n) => n.map((n) => n.id === s.id ? {
|
|
279
|
-
...n,
|
|
280
|
-
cards: e
|
|
281
|
-
} : n.id === c.id ? {
|
|
282
|
-
...n,
|
|
283
|
-
cards: t
|
|
284
|
-
} : n)), n && n(i, s.id, c.id, a);
|
|
285
|
-
}
|
|
286
|
-
a && a.endDrag(c.id);
|
|
287
|
-
}, W = e.useCallback((e) => {
|
|
288
|
-
for (let t of L) {
|
|
289
|
-
let n = t.cards.find((t) => t.id === e);
|
|
290
|
-
if (n) return n;
|
|
291
|
-
}
|
|
292
|
-
return null;
|
|
293
|
-
}, [L]), G = e.useCallback((e) => L.find((t) => t.cards.some((t) => t.id === e)) || null, [L]), K = e.useCallback((e) => L.find((t) => t.id === e) || null, [L]);
|
|
294
|
-
return /* @__PURE__ */ h(_, {
|
|
295
|
-
sensors: V,
|
|
296
|
-
collisionDetection: x,
|
|
297
|
-
onDragStart: H,
|
|
298
|
-
onDragEnd: U,
|
|
299
|
-
children: [/* @__PURE__ */ h("div", {
|
|
300
|
-
ref: g,
|
|
301
|
-
className: "flex flex-col min-w-0 min-h-0 h-full",
|
|
302
|
-
children: [/* @__PURE__ */ h("div", {
|
|
303
|
-
className: "flex sm:hidden items-center justify-between px-3 pb-2 text-xs text-muted-foreground",
|
|
304
|
-
children: [/* @__PURE__ */ h("span", { children: [L.length, " columns"] }), /* @__PURE__ */ m("span", { children: "← Swipe to navigate →" })]
|
|
305
|
-
}), z ? /* @__PURE__ */ h("div", {
|
|
306
|
-
className: k("flex flex-col gap-1 p-2 sm:p-4 min-w-0 overflow-hidden", i),
|
|
307
|
-
role: "region",
|
|
308
|
-
"aria-label": "Kanban board with swimlanes",
|
|
309
|
-
children: [/* @__PURE__ */ m("div", {
|
|
310
|
-
className: "flex gap-3 sm:gap-4 pl-36 sm:pl-44 overflow-x-auto",
|
|
311
|
-
children: L.map((e) => /* @__PURE__ */ h("div", {
|
|
312
|
-
className: "w-[85vw] sm:w-80 flex-shrink-0 text-center",
|
|
313
|
-
children: [/* @__PURE__ */ m("span", {
|
|
314
|
-
className: " text-xs sm:text-sm font-semibold tracking-wider text-primary/90 uppercase",
|
|
315
|
-
children: e.title
|
|
316
|
-
}), /* @__PURE__ */ h("span", {
|
|
317
|
-
className: "ml-2 text-xs text-muted-foreground",
|
|
318
|
-
children: [
|
|
319
|
-
"(",
|
|
320
|
-
e.cards.length,
|
|
321
|
-
")"
|
|
322
|
-
]
|
|
323
|
-
})]
|
|
324
|
-
}, e.id))
|
|
325
|
-
}), z.map((e) => {
|
|
326
|
-
let t = N.has(e), n = L.reduce((t, n) => t + n.cards.filter((t) => (t[u] == null ? A : String(t[u])) === e).length, 0);
|
|
327
|
-
return /* @__PURE__ */ h("div", {
|
|
328
|
-
className: "border rounded-lg bg-muted/10",
|
|
329
|
-
children: [/* @__PURE__ */ h("button", {
|
|
330
|
-
className: "w-full flex items-center gap-2 px-3 py-2 text-left hover:bg-muted/30 transition-colors",
|
|
331
|
-
onClick: () => B(e),
|
|
332
|
-
"aria-expanded": !t,
|
|
333
|
-
children: [
|
|
334
|
-
/* @__PURE__ */ m("span", {
|
|
335
|
-
className: k("transition-transform text-xs", t ? "" : "rotate-90"),
|
|
336
|
-
children: "▶"
|
|
337
|
-
}),
|
|
338
|
-
/* @__PURE__ */ m("span", {
|
|
339
|
-
className: " text-xs font-semibold text-muted-foreground uppercase tracking-wider",
|
|
340
|
-
children: e
|
|
341
|
-
}),
|
|
342
|
-
/* @__PURE__ */ h("span", {
|
|
343
|
-
className: " text-xs text-muted-foreground",
|
|
344
|
-
children: [
|
|
345
|
-
"(",
|
|
346
|
-
n,
|
|
347
|
-
")"
|
|
348
|
-
]
|
|
349
|
-
})
|
|
350
|
-
]
|
|
351
|
-
}), !t && /* @__PURE__ */ m("div", {
|
|
352
|
-
className: "flex gap-3 sm:gap-4 overflow-x-auto px-2 pb-3 pl-36 sm:pl-44",
|
|
353
|
-
children: L.map((t) => {
|
|
354
|
-
let n = t.cards.filter((t) => (t[u] == null ? A : String(t[u])) === e);
|
|
355
|
-
return /* @__PURE__ */ m("div", {
|
|
356
|
-
className: "w-[85vw] sm:w-80 flex-shrink-0 min-h-[60px] rounded-md bg-card/20 p-2",
|
|
357
|
-
children: /* @__PURE__ */ m(w, {
|
|
358
|
-
items: n.map((e) => e.id),
|
|
359
|
-
strategy: D,
|
|
360
|
-
children: /* @__PURE__ */ m("div", {
|
|
361
|
-
className: "space-y-2",
|
|
362
|
-
role: "list",
|
|
363
|
-
"aria-label": `${t.title} - ${e} cards`,
|
|
364
|
-
children: n.map((e) => /* @__PURE__ */ m(M, {
|
|
365
|
-
card: e,
|
|
366
|
-
onCardClick: r,
|
|
367
|
-
conditionalFormatting: l
|
|
368
|
-
}, e.id))
|
|
369
|
-
})
|
|
370
|
-
})
|
|
371
|
-
}, t.id);
|
|
372
|
-
})
|
|
373
|
-
})]
|
|
374
|
-
}, e);
|
|
375
|
-
})]
|
|
376
|
-
}) : /* @__PURE__ */ m("div", {
|
|
377
|
-
className: k("flex gap-3 sm:gap-4 overflow-x-auto snap-x snap-mandatory p-2 sm:p-4 bg-muted/10 rounded-lg [-webkit-overflow-scrolling:touch] min-w-0 min-h-0 h-full", i),
|
|
378
|
-
role: "region",
|
|
379
|
-
"aria-label": "Kanban board",
|
|
380
|
-
children: L.map((e) => /* @__PURE__ */ m(P, {
|
|
381
|
-
column: e,
|
|
382
|
-
cards: e.cards,
|
|
383
|
-
onCardClick: r,
|
|
384
|
-
quickAdd: o,
|
|
385
|
-
onQuickAdd: s,
|
|
386
|
-
conditionalFormatting: l,
|
|
387
|
-
columnStyle: O
|
|
388
|
-
}, e.id))
|
|
389
|
-
})]
|
|
390
|
-
}), /* @__PURE__ */ m(v, { children: /* @__PURE__ */ m("div", {
|
|
391
|
-
"aria-live": "assertive",
|
|
392
|
-
"aria-label": d ? `Dragging ${d.title}` : void 0,
|
|
393
|
-
children: d ? /* @__PURE__ */ m(M, {
|
|
394
|
-
card: d,
|
|
395
|
-
conditionalFormatting: l
|
|
396
|
-
}) : null
|
|
397
|
-
}) })]
|
|
398
|
-
});
|
|
399
|
-
}
|
|
400
|
-
//#endregion
|
|
401
|
-
export { I as default };
|