@btst/stack 1.11.0 → 1.12.0

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.
Files changed (163) hide show
  1. package/dist/node_modules/.pnpm/@dnd-kit_core@6.3.1_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/@dnd-kit/core/dist/core.esm.cjs +1 -1
  2. package/dist/node_modules/.pnpm/@dnd-kit_core@6.3.1_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/@dnd-kit/core/dist/core.esm.mjs +1 -1
  3. package/dist/node_modules/.pnpm/@dnd-kit_sortable@10.0.0_@dnd-kit_core@6.3.1_react-dom@19.2.0_react@19.2.0__react@19.2.0__react@19.2.0/node_modules/@dnd-kit/sortable/dist/sortable.esm.cjs +77 -0
  4. package/dist/node_modules/.pnpm/@dnd-kit_sortable@10.0.0_@dnd-kit_core@6.3.1_react-dom@19.2.0_react@19.2.0__react@19.2.0__react@19.2.0/node_modules/@dnd-kit/sortable/dist/sortable.esm.mjs +79 -3
  5. package/dist/node_modules/.pnpm/@radix-ui_react-avatar@1.1.11_@types_react-dom@19.2.3_@types_react@19.2.6__@types_react_850cfbef1935a6e49a6ad6c93c7ca70d/node_modules/@radix-ui/react-avatar/dist/index.cjs +140 -0
  6. package/dist/node_modules/.pnpm/@radix-ui_react-avatar@1.1.11_@types_react-dom@19.2.3_@types_react@19.2.6__@types_react_850cfbef1935a6e49a6ad6c93c7ca70d/node_modules/@radix-ui/react-avatar/dist/index.mjs +119 -0
  7. package/dist/node_modules/.pnpm/@radix-ui_react-context@1.1.3_@types_react@19.2.6_react@19.2.0/node_modules/@radix-ui/react-context/dist/index.cjs +80 -0
  8. package/dist/node_modules/.pnpm/@radix-ui_react-context@1.1.3_@types_react@19.2.6_react@19.2.0/node_modules/@radix-ui/react-context/dist/index.mjs +64 -0
  9. package/dist/node_modules/.pnpm/@radix-ui_react-use-is-hydrated@0.1.0_@types_react@19.2.6_react@19.2.0/node_modules/@radix-ui/react-use-is-hydrated/dist/index.cjs +18 -0
  10. package/dist/node_modules/.pnpm/@radix-ui_react-use-is-hydrated@0.1.0_@types_react@19.2.6_react@19.2.0/node_modules/@radix-ui/react-use-is-hydrated/dist/index.mjs +16 -0
  11. package/dist/packages/better-stack/src/plugins/kanban/api/plugin.cjs +846 -0
  12. package/dist/packages/better-stack/src/plugins/kanban/api/plugin.mjs +844 -0
  13. package/dist/packages/better-stack/src/plugins/kanban/client/components/forms/board-form.cjs +85 -0
  14. package/dist/packages/better-stack/src/plugins/kanban/client/components/forms/board-form.mjs +83 -0
  15. package/dist/packages/better-stack/src/plugins/kanban/client/components/forms/column-form.cjs +72 -0
  16. package/dist/packages/better-stack/src/plugins/kanban/client/components/forms/column-form.mjs +70 -0
  17. package/dist/packages/better-stack/src/plugins/kanban/client/components/forms/task-form.cjs +200 -0
  18. package/dist/packages/better-stack/src/plugins/kanban/client/components/forms/task-form.mjs +198 -0
  19. package/dist/packages/better-stack/src/plugins/kanban/client/components/loading/board-skeleton.cjs +47 -0
  20. package/dist/packages/better-stack/src/plugins/kanban/client/components/loading/board-skeleton.mjs +45 -0
  21. package/dist/packages/better-stack/src/plugins/kanban/client/components/loading/boards-list-skeleton.cjs +30 -0
  22. package/dist/packages/better-stack/src/plugins/kanban/client/components/loading/boards-list-skeleton.mjs +28 -0
  23. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/404-page.cjs +27 -0
  24. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/404-page.mjs +25 -0
  25. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/board-page.cjs +31 -0
  26. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/board-page.internal.cjs +458 -0
  27. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/board-page.internal.mjs +456 -0
  28. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/board-page.mjs +29 -0
  29. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/boards-list-page.cjs +30 -0
  30. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/boards-list-page.internal.cjs +72 -0
  31. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/boards-list-page.internal.mjs +70 -0
  32. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/boards-list-page.mjs +28 -0
  33. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/new-board-page.cjs +30 -0
  34. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/new-board-page.internal.cjs +51 -0
  35. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/new-board-page.internal.mjs +49 -0
  36. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/new-board-page.mjs +28 -0
  37. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/column-content.cjs +76 -0
  38. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/column-content.mjs +74 -0
  39. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/default-error.cjs +27 -0
  40. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/default-error.mjs +25 -0
  41. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/empty-state.cjs +32 -0
  42. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/empty-state.mjs +30 -0
  43. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/kanban-board.cjs +78 -0
  44. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/kanban-board.mjs +76 -0
  45. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/page-wrapper.cjs +15 -0
  46. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/page-wrapper.mjs +13 -0
  47. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/task-card.cjs +68 -0
  48. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/task-card.mjs +66 -0
  49. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/user-avatar.cjs +32 -0
  50. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/user-avatar.mjs +30 -0
  51. package/dist/packages/better-stack/src/plugins/kanban/client/hooks/kanban-hooks.cjs +391 -0
  52. package/dist/packages/better-stack/src/plugins/kanban/client/hooks/kanban-hooks.mjs +381 -0
  53. package/dist/packages/better-stack/src/plugins/kanban/client/plugin.cjs +290 -0
  54. package/dist/packages/better-stack/src/plugins/kanban/client/plugin.mjs +288 -0
  55. package/dist/packages/better-stack/src/plugins/kanban/db.cjs +125 -0
  56. package/dist/packages/better-stack/src/plugins/kanban/db.mjs +123 -0
  57. package/dist/packages/better-stack/src/plugins/kanban/schemas.cjs +117 -0
  58. package/dist/packages/better-stack/src/plugins/kanban/schemas.mjs +102 -0
  59. package/dist/packages/better-stack/src/plugins/kanban/utils.cjs +49 -0
  60. package/dist/packages/better-stack/src/plugins/kanban/utils.mjs +45 -0
  61. package/dist/packages/ui/src/components/avatar.cjs +58 -0
  62. package/dist/packages/ui/src/components/avatar.mjs +54 -0
  63. package/dist/packages/ui/src/components/command.cjs +3 -3
  64. package/dist/packages/ui/src/components/command.mjs +3 -3
  65. package/dist/packages/ui/src/components/form-builder/index.mjs +2 -2
  66. package/dist/packages/ui/src/components/kanban.cjs +835 -0
  67. package/dist/packages/ui/src/components/kanban.mjs +805 -0
  68. package/dist/packages/ui/src/components/popover.cjs +8 -3
  69. package/dist/packages/ui/src/components/popover.mjs +9 -4
  70. package/dist/packages/ui/src/components/search-select.cjs +75 -0
  71. package/dist/packages/ui/src/components/search-select.mjs +73 -0
  72. package/dist/packages/ui/src/lib/compose-refs.cjs +56 -0
  73. package/dist/packages/ui/src/lib/compose-refs.mjs +39 -0
  74. package/dist/plugins/blog/api/index.d.cts +1 -1
  75. package/dist/plugins/blog/api/index.d.mts +1 -1
  76. package/dist/plugins/blog/api/index.d.ts +1 -1
  77. package/dist/plugins/blog/client/hooks/index.d.cts +2 -2
  78. package/dist/plugins/blog/client/hooks/index.d.mts +2 -2
  79. package/dist/plugins/blog/client/hooks/index.d.ts +2 -2
  80. package/dist/plugins/blog/client/index.d.cts +1 -1
  81. package/dist/plugins/blog/client/index.d.mts +1 -1
  82. package/dist/plugins/blog/client/index.d.ts +1 -1
  83. package/dist/plugins/blog/query-keys.d.cts +2 -2
  84. package/dist/plugins/blog/query-keys.d.mts +2 -2
  85. package/dist/plugins/blog/query-keys.d.ts +2 -2
  86. package/dist/plugins/kanban/api/index.cjs +7 -0
  87. package/dist/plugins/kanban/api/index.d.cts +403 -0
  88. package/dist/plugins/kanban/api/index.d.mts +403 -0
  89. package/dist/plugins/kanban/api/index.d.ts +403 -0
  90. package/dist/plugins/kanban/api/index.mjs +1 -0
  91. package/dist/plugins/kanban/client/components/index.cjs +35 -0
  92. package/dist/plugins/kanban/client/components/index.d.cts +102 -0
  93. package/dist/plugins/kanban/client/components/index.d.mts +102 -0
  94. package/dist/plugins/kanban/client/components/index.d.ts +102 -0
  95. package/dist/plugins/kanban/client/components/index.mjs +15 -0
  96. package/dist/plugins/kanban/client/hooks/index.cjs +15 -0
  97. package/dist/plugins/kanban/client/hooks/index.d.cts +143 -0
  98. package/dist/plugins/kanban/client/hooks/index.d.mts +143 -0
  99. package/dist/plugins/kanban/client/hooks/index.d.ts +143 -0
  100. package/dist/plugins/kanban/client/hooks/index.mjs +1 -0
  101. package/dist/plugins/kanban/client/index.cjs +7 -0
  102. package/dist/plugins/kanban/client/index.d.cts +196 -0
  103. package/dist/plugins/kanban/client/index.d.mts +196 -0
  104. package/dist/plugins/kanban/client/index.d.ts +196 -0
  105. package/dist/plugins/kanban/client/index.mjs +1 -0
  106. package/dist/plugins/kanban/client.css +68 -0
  107. package/dist/plugins/kanban/query-keys.cjs +105 -0
  108. package/dist/plugins/kanban/query-keys.d.cts +59 -0
  109. package/dist/plugins/kanban/query-keys.d.mts +59 -0
  110. package/dist/plugins/kanban/query-keys.d.ts +59 -0
  111. package/dist/plugins/kanban/query-keys.mjs +103 -0
  112. package/dist/plugins/kanban/style.css +7 -0
  113. package/dist/plugins/ui-builder/style.css +6 -0
  114. package/dist/shared/stack.DKDMI-QO.d.cts +70 -0
  115. package/dist/shared/stack.DKDMI-QO.d.mts +70 -0
  116. package/dist/shared/stack.DKDMI-QO.d.ts +70 -0
  117. package/dist/shared/stack.FeaWkglm.d.cts +190 -0
  118. package/dist/shared/stack.FeaWkglm.d.mts +190 -0
  119. package/dist/shared/stack.FeaWkglm.d.ts +190 -0
  120. package/package.json +56 -2
  121. package/src/plugins/kanban/api/index.ts +6 -0
  122. package/src/plugins/kanban/api/plugin.ts +1245 -0
  123. package/src/plugins/kanban/client/components/forms/board-form.tsx +108 -0
  124. package/src/plugins/kanban/client/components/forms/column-form.tsx +97 -0
  125. package/src/plugins/kanban/client/components/forms/task-form.tsx +274 -0
  126. package/src/plugins/kanban/client/components/index.tsx +21 -0
  127. package/src/plugins/kanban/client/components/loading/board-skeleton.tsx +49 -0
  128. package/src/plugins/kanban/client/components/loading/boards-list-skeleton.tsx +34 -0
  129. package/src/plugins/kanban/client/components/loading/index.tsx +2 -0
  130. package/src/plugins/kanban/client/components/pages/404-page.tsx +28 -0
  131. package/src/plugins/kanban/client/components/pages/board-page.internal.tsx +575 -0
  132. package/src/plugins/kanban/client/components/pages/board-page.tsx +31 -0
  133. package/src/plugins/kanban/client/components/pages/boards-list-page.internal.tsx +101 -0
  134. package/src/plugins/kanban/client/components/pages/boards-list-page.tsx +26 -0
  135. package/src/plugins/kanban/client/components/pages/new-board-page.internal.tsx +65 -0
  136. package/src/plugins/kanban/client/components/pages/new-board-page.tsx +26 -0
  137. package/src/plugins/kanban/client/components/shared/column-content.tsx +108 -0
  138. package/src/plugins/kanban/client/components/shared/default-error.tsx +32 -0
  139. package/src/plugins/kanban/client/components/shared/empty-state.tsx +37 -0
  140. package/src/plugins/kanban/client/components/shared/kanban-board.tsx +87 -0
  141. package/src/plugins/kanban/client/components/shared/page-wrapper.tsx +20 -0
  142. package/src/plugins/kanban/client/components/shared/task-card.tsx +79 -0
  143. package/src/plugins/kanban/client/components/shared/user-avatar.tsx +63 -0
  144. package/src/plugins/kanban/client/hooks/index.tsx +11 -0
  145. package/src/plugins/kanban/client/hooks/kanban-hooks.tsx +560 -0
  146. package/src/plugins/kanban/client/index.ts +8 -0
  147. package/src/plugins/kanban/client/localization/index.ts +28 -0
  148. package/src/plugins/kanban/client/localization/kanban-common.ts +69 -0
  149. package/src/plugins/kanban/client/localization/kanban-forms.ts +70 -0
  150. package/src/plugins/kanban/client/localization/kanban-list.ts +36 -0
  151. package/src/plugins/kanban/client/overrides.ts +145 -0
  152. package/src/plugins/kanban/client/plugin.tsx +463 -0
  153. package/src/plugins/kanban/client.css +68 -0
  154. package/src/plugins/kanban/db.ts +125 -0
  155. package/src/plugins/kanban/query-keys.ts +154 -0
  156. package/src/plugins/kanban/schemas.ts +143 -0
  157. package/src/plugins/kanban/style.css +7 -0
  158. package/src/plugins/kanban/types.ts +106 -0
  159. package/src/plugins/kanban/utils.ts +107 -0
  160. package/src/plugins/ui-builder/style.css +6 -0
  161. package/dist/shared/{stack.DLhzx1-D.d.cts → stack.CcI4sYJP.d.cts} +1 -1
  162. package/dist/shared/{stack.DLhzx1-D.d.mts → stack.CcI4sYJP.d.mts} +1 -1
  163. package/dist/shared/{stack.DLhzx1-D.d.ts → stack.CcI4sYJP.d.ts} +1 -1
@@ -0,0 +1,68 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ const jsxRuntime = require('react/jsx-runtime');
5
+ const React = require('react');
6
+ const LucideIcons = require('lucide-react');
7
+ const button = require('../../../../../../../ui/src/components/button.cjs');
8
+ const badge = require('../../../../../../../ui/src/components/badge.cjs');
9
+ const kanban = require('../../../../../../../ui/src/components/kanban.cjs');
10
+ const dateFns = require('date-fns');
11
+ const utils = require('../../../utils.cjs');
12
+ const kanbanHooks = require('../../hooks/kanban-hooks.cjs');
13
+ const userAvatar = require('./user-avatar.cjs');
14
+
15
+ function TaskCardComponent({ task, onClick }) {
16
+ const priorityConfig = utils.getPriorityConfig(task.priority);
17
+ const { data: assignee } = kanbanHooks.useResolveUser(task.assigneeId);
18
+ return /* @__PURE__ */ jsxRuntime.jsx(kanban.KanbanItem, { value: task.id, asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
19
+ "div",
20
+ {
21
+ className: "rounded-md border bg-card p-3 shadow-xs cursor-pointer hover:shadow-md transition-shadow",
22
+ onClick,
23
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
24
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
25
+ /* @__PURE__ */ jsxRuntime.jsx(kanban.KanbanItemHandle, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
26
+ button.Button,
27
+ {
28
+ variant: "ghost",
29
+ size: "icon",
30
+ className: "h-6 w-6",
31
+ onClick: (e) => e.stopPropagation(),
32
+ children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.GripVertical, { className: "h-3 w-3" })
33
+ }
34
+ ) }),
35
+ /* @__PURE__ */ jsxRuntime.jsx(
36
+ "span",
37
+ {
38
+ className: "line-clamp-1 font-medium text-base flex-1 text-left cursor-pointer hover:text-primary",
39
+ title: task.title,
40
+ children: task.title
41
+ }
42
+ ),
43
+ /* @__PURE__ */ jsxRuntime.jsx(
44
+ badge.Badge,
45
+ {
46
+ variant: priorityConfig.variant,
47
+ className: `pointer-events-none h-5 rounded-sm px-1.5 text-[11px] capitalize ${priorityConfig.className}`,
48
+ children: priorityConfig.label
49
+ }
50
+ )
51
+ ] }),
52
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-muted-foreground text-xs", children: [
53
+ task.assigneeId ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
54
+ /* @__PURE__ */ jsxRuntime.jsx(userAvatar.UserAvatar, { user: assignee ?? null, size: "sm" }),
55
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "line-clamp-1", children: assignee?.name || "Assigned" })
56
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
57
+ /* @__PURE__ */ jsxRuntime.jsx(userAvatar.UserAvatar, { user: null, size: "sm" }),
58
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "line-clamp-1", children: "Unassigned" })
59
+ ] }),
60
+ /* @__PURE__ */ jsxRuntime.jsx("time", { className: "tabular-nums", children: dateFns.format(new Date(task.createdAt), "MMM d") })
61
+ ] })
62
+ ] })
63
+ }
64
+ ) });
65
+ }
66
+ const TaskCard = React.memo(TaskCardComponent);
67
+
68
+ exports.TaskCard = TaskCard;
@@ -0,0 +1,66 @@
1
+ "use client";
2
+ import { jsx, jsxs } from 'react/jsx-runtime';
3
+ import { memo } from 'react';
4
+ import { GripVertical } from 'lucide-react';
5
+ import { Button } from '../../../../../../../ui/src/components/button.mjs';
6
+ import { Badge } from '../../../../../../../ui/src/components/badge.mjs';
7
+ import { KanbanItem, KanbanItemHandle } from '../../../../../../../ui/src/components/kanban.mjs';
8
+ import { format } from 'date-fns';
9
+ import { getPriorityConfig } from '../../../utils.mjs';
10
+ import { useResolveUser } from '../../hooks/kanban-hooks.mjs';
11
+ import { UserAvatar } from './user-avatar.mjs';
12
+
13
+ function TaskCardComponent({ task, onClick }) {
14
+ const priorityConfig = getPriorityConfig(task.priority);
15
+ const { data: assignee } = useResolveUser(task.assigneeId);
16
+ return /* @__PURE__ */ jsx(KanbanItem, { value: task.id, asChild: true, children: /* @__PURE__ */ jsx(
17
+ "div",
18
+ {
19
+ className: "rounded-md border bg-card p-3 shadow-xs cursor-pointer hover:shadow-md transition-shadow",
20
+ onClick,
21
+ children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
22
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
23
+ /* @__PURE__ */ jsx(KanbanItemHandle, { asChild: true, children: /* @__PURE__ */ jsx(
24
+ Button,
25
+ {
26
+ variant: "ghost",
27
+ size: "icon",
28
+ className: "h-6 w-6",
29
+ onClick: (e) => e.stopPropagation(),
30
+ children: /* @__PURE__ */ jsx(GripVertical, { className: "h-3 w-3" })
31
+ }
32
+ ) }),
33
+ /* @__PURE__ */ jsx(
34
+ "span",
35
+ {
36
+ className: "line-clamp-1 font-medium text-base flex-1 text-left cursor-pointer hover:text-primary",
37
+ title: task.title,
38
+ children: task.title
39
+ }
40
+ ),
41
+ /* @__PURE__ */ jsx(
42
+ Badge,
43
+ {
44
+ variant: priorityConfig.variant,
45
+ className: `pointer-events-none h-5 rounded-sm px-1.5 text-[11px] capitalize ${priorityConfig.className}`,
46
+ children: priorityConfig.label
47
+ }
48
+ )
49
+ ] }),
50
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-muted-foreground text-xs", children: [
51
+ task.assigneeId ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
52
+ /* @__PURE__ */ jsx(UserAvatar, { user: assignee ?? null, size: "sm" }),
53
+ /* @__PURE__ */ jsx("span", { className: "line-clamp-1", children: assignee?.name || "Assigned" })
54
+ ] }) : /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
55
+ /* @__PURE__ */ jsx(UserAvatar, { user: null, size: "sm" }),
56
+ /* @__PURE__ */ jsx("span", { className: "line-clamp-1", children: "Unassigned" })
57
+ ] }),
58
+ /* @__PURE__ */ jsx("time", { className: "tabular-nums", children: format(new Date(task.createdAt), "MMM d") })
59
+ ] })
60
+ ] })
61
+ }
62
+ ) });
63
+ }
64
+ const TaskCard = memo(TaskCardComponent);
65
+
66
+ export { TaskCard };
@@ -0,0 +1,32 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ const jsxRuntime = require('react/jsx-runtime');
5
+ const React = require('react');
6
+ const LucideIcons = require('lucide-react');
7
+ const avatar = require('../../../../../../../ui/src/components/avatar.cjs');
8
+
9
+ function getInitials(name) {
10
+ const parts = name.trim().split(/\s+/);
11
+ if (parts.length === 1) {
12
+ return parts[0]?.charAt(0).toUpperCase() || "";
13
+ }
14
+ return ((parts[0]?.charAt(0) || "") + (parts[parts.length - 1]?.charAt(0) || "")).toUpperCase();
15
+ }
16
+ function UserAvatarComponent({
17
+ user,
18
+ size = "sm",
19
+ className
20
+ }) {
21
+ if (!user) {
22
+ return /* @__PURE__ */ jsxRuntime.jsx(avatar.Avatar, { size, className, title: "Unassigned", children: /* @__PURE__ */ jsxRuntime.jsx(avatar.AvatarFallback, { children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.User, { className: "size-3 group-data-[size=default]/avatar:size-4 group-data-[size=lg]/avatar:size-5" }) }) });
23
+ }
24
+ const initials = getInitials(user.name);
25
+ return /* @__PURE__ */ jsxRuntime.jsxs(avatar.Avatar, { size, className, title: user.name, children: [
26
+ user.avatarUrl && /* @__PURE__ */ jsxRuntime.jsx(avatar.AvatarImage, { src: user.avatarUrl, alt: user.name }),
27
+ /* @__PURE__ */ jsxRuntime.jsx(avatar.AvatarFallback, { className: "bg-primary/10 text-primary font-medium", children: initials })
28
+ ] });
29
+ }
30
+ const UserAvatar = React.memo(UserAvatarComponent);
31
+
32
+ exports.UserAvatar = UserAvatar;
@@ -0,0 +1,30 @@
1
+ "use client";
2
+ import { jsx, jsxs } from 'react/jsx-runtime';
3
+ import { memo } from 'react';
4
+ import { User } from 'lucide-react';
5
+ import { Avatar, AvatarFallback, AvatarImage } from '../../../../../../../ui/src/components/avatar.mjs';
6
+
7
+ function getInitials(name) {
8
+ const parts = name.trim().split(/\s+/);
9
+ if (parts.length === 1) {
10
+ return parts[0]?.charAt(0).toUpperCase() || "";
11
+ }
12
+ return ((parts[0]?.charAt(0) || "") + (parts[parts.length - 1]?.charAt(0) || "")).toUpperCase();
13
+ }
14
+ function UserAvatarComponent({
15
+ user,
16
+ size = "sm",
17
+ className
18
+ }) {
19
+ if (!user) {
20
+ return /* @__PURE__ */ jsx(Avatar, { size, className, title: "Unassigned", children: /* @__PURE__ */ jsx(AvatarFallback, { children: /* @__PURE__ */ jsx(User, { className: "size-3 group-data-[size=default]/avatar:size-4 group-data-[size=lg]/avatar:size-5" }) }) });
21
+ }
22
+ const initials = getInitials(user.name);
23
+ return /* @__PURE__ */ jsxs(Avatar, { size, className, title: user.name, children: [
24
+ user.avatarUrl && /* @__PURE__ */ jsx(AvatarImage, { src: user.avatarUrl, alt: user.name }),
25
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "bg-primary/10 text-primary font-medium", children: initials })
26
+ ] });
27
+ }
28
+ const UserAvatar = memo(UserAvatarComponent);
29
+
30
+ export { UserAvatar };
@@ -0,0 +1,391 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ const reactQuery = require('@tanstack/react-query');
5
+ const client = require('@btst/stack/plugins/client');
6
+ const context = require('@btst/stack/context');
7
+ const plugins_kanban_queryKeys = require('../../../../../../../plugins/kanban/query-keys.cjs');
8
+
9
+ function isErrorResponse(response) {
10
+ return typeof response === "object" && response !== null && "error" in response && response.error !== null && response.error !== void 0;
11
+ }
12
+ function toError(error) {
13
+ if (error instanceof Error) {
14
+ return error;
15
+ }
16
+ if (typeof error === "object" && error !== null) {
17
+ const errorObj = error;
18
+ const message = (typeof errorObj.message === "string" ? errorObj.message : null) || (typeof errorObj.error === "string" ? errorObj.error : null) || JSON.stringify(error);
19
+ const err = new Error(message);
20
+ Object.assign(err, error);
21
+ return err;
22
+ }
23
+ return new Error(String(error));
24
+ }
25
+ function useKanbanClient() {
26
+ const { apiBaseURL, apiBasePath, headers } = context.usePluginOverrides("kanban");
27
+ const client$1 = client.createApiClient({
28
+ baseURL: apiBaseURL,
29
+ basePath: apiBasePath
30
+ });
31
+ return { client: client$1, headers };
32
+ }
33
+ function useBoards(params) {
34
+ const { client, headers } = useKanbanClient();
35
+ const queries = plugins_kanban_queryKeys.createKanbanQueryKeys(client, headers);
36
+ return reactQuery.useQuery({
37
+ ...queries.boards.list(params),
38
+ staleTime: 3e4
39
+ });
40
+ }
41
+ function useSuspenseBoards(params) {
42
+ const { client, headers } = useKanbanClient();
43
+ const queries = plugins_kanban_queryKeys.createKanbanQueryKeys(client, headers);
44
+ const result = reactQuery.useSuspenseQuery({
45
+ ...queries.boards.list(params),
46
+ staleTime: 3e4
47
+ });
48
+ if (result.error && !result.isFetching) {
49
+ throw result.error;
50
+ }
51
+ return result;
52
+ }
53
+ function useBoard(boardId) {
54
+ const { client, headers } = useKanbanClient();
55
+ const queries = plugins_kanban_queryKeys.createKanbanQueryKeys(client, headers);
56
+ return reactQuery.useQuery({
57
+ ...queries.boards.detail(boardId),
58
+ staleTime: 3e4,
59
+ enabled: !!boardId
60
+ });
61
+ }
62
+ function useSuspenseBoard(boardId) {
63
+ const { client, headers } = useKanbanClient();
64
+ const queries = plugins_kanban_queryKeys.createKanbanQueryKeys(client, headers);
65
+ const result = reactQuery.useSuspenseQuery({
66
+ ...queries.boards.detail(boardId),
67
+ staleTime: 3e4
68
+ });
69
+ if (result.error && !result.isFetching) {
70
+ throw result.error;
71
+ }
72
+ return result;
73
+ }
74
+ function useBoardMutations() {
75
+ const { client, headers } = useKanbanClient();
76
+ const queryClient = reactQuery.useQueryClient();
77
+ const createMutation = reactQuery.useMutation({
78
+ mutationFn: async (data) => {
79
+ const response = await client("@post/boards", {
80
+ method: "POST",
81
+ body: data,
82
+ headers
83
+ });
84
+ if (isErrorResponse(response)) {
85
+ const errorResponse = response;
86
+ throw toError(errorResponse.error);
87
+ }
88
+ return response.data;
89
+ },
90
+ onSuccess: () => {
91
+ queryClient.invalidateQueries({ queryKey: ["boards"] });
92
+ }
93
+ });
94
+ const updateMutation = reactQuery.useMutation({
95
+ mutationFn: async ({
96
+ id,
97
+ data
98
+ }) => {
99
+ const response = await client("@put/boards/:id", {
100
+ method: "PUT",
101
+ params: { id },
102
+ body: data,
103
+ headers
104
+ });
105
+ if (isErrorResponse(response)) {
106
+ const errorResponse = response;
107
+ throw toError(errorResponse.error);
108
+ }
109
+ return response.data;
110
+ },
111
+ onSuccess: () => {
112
+ queryClient.invalidateQueries({ queryKey: ["boards"] });
113
+ }
114
+ });
115
+ const deleteMutation = reactQuery.useMutation({
116
+ mutationFn: async (id) => {
117
+ const response = await client("@delete/boards/:id", {
118
+ method: "DELETE",
119
+ params: { id },
120
+ headers
121
+ });
122
+ if (isErrorResponse(response)) {
123
+ const errorResponse = response;
124
+ throw toError(errorResponse.error);
125
+ }
126
+ return response.data;
127
+ },
128
+ onSuccess: () => {
129
+ queryClient.invalidateQueries({ queryKey: ["boards"] });
130
+ }
131
+ });
132
+ return {
133
+ createBoard: createMutation.mutateAsync,
134
+ updateBoard: (id, data) => updateMutation.mutateAsync({ id, data }),
135
+ deleteBoard: deleteMutation.mutateAsync,
136
+ isCreating: createMutation.isPending,
137
+ isUpdating: updateMutation.isPending,
138
+ isDeleting: deleteMutation.isPending,
139
+ createError: createMutation.error,
140
+ updateError: updateMutation.error,
141
+ deleteError: deleteMutation.error
142
+ };
143
+ }
144
+ function useColumnMutations() {
145
+ const { client, headers } = useKanbanClient();
146
+ const queryClient = reactQuery.useQueryClient();
147
+ const createMutation = reactQuery.useMutation({
148
+ mutationFn: async (data) => {
149
+ const response = await client("@post/columns", {
150
+ method: "POST",
151
+ body: data,
152
+ headers
153
+ });
154
+ if (isErrorResponse(response)) {
155
+ const errorResponse = response;
156
+ throw toError(errorResponse.error);
157
+ }
158
+ return response.data;
159
+ },
160
+ onSuccess: () => {
161
+ queryClient.invalidateQueries({ queryKey: ["boards"] });
162
+ }
163
+ });
164
+ const updateMutation = reactQuery.useMutation({
165
+ mutationFn: async ({
166
+ id,
167
+ data
168
+ }) => {
169
+ const response = await client("@put/columns/:id", {
170
+ method: "PUT",
171
+ params: { id },
172
+ body: data,
173
+ headers
174
+ });
175
+ if (isErrorResponse(response)) {
176
+ const errorResponse = response;
177
+ throw toError(errorResponse.error);
178
+ }
179
+ return response.data;
180
+ },
181
+ onSuccess: () => {
182
+ queryClient.invalidateQueries({ queryKey: ["boards"] });
183
+ }
184
+ });
185
+ const deleteMutation = reactQuery.useMutation({
186
+ mutationFn: async (id) => {
187
+ const response = await client("@delete/columns/:id", {
188
+ method: "DELETE",
189
+ params: { id },
190
+ headers
191
+ });
192
+ if (isErrorResponse(response)) {
193
+ const errorResponse = response;
194
+ throw toError(errorResponse.error);
195
+ }
196
+ return response.data;
197
+ },
198
+ onSuccess: () => {
199
+ queryClient.invalidateQueries({ queryKey: ["boards"] });
200
+ }
201
+ });
202
+ const reorderMutation = reactQuery.useMutation({
203
+ mutationFn: async ({
204
+ boardId,
205
+ columnIds
206
+ }) => {
207
+ const response = await client("@post/columns/reorder", {
208
+ method: "POST",
209
+ body: { boardId, columnIds },
210
+ headers
211
+ });
212
+ if (isErrorResponse(response)) {
213
+ const errorResponse = response;
214
+ throw toError(errorResponse.error);
215
+ }
216
+ return response.data;
217
+ },
218
+ onSuccess: () => {
219
+ queryClient.invalidateQueries({ queryKey: ["boards"] });
220
+ }
221
+ });
222
+ return {
223
+ createColumn: createMutation.mutateAsync,
224
+ updateColumn: (id, data) => updateMutation.mutateAsync({ id, data }),
225
+ deleteColumn: deleteMutation.mutateAsync,
226
+ reorderColumns: (boardId, columnIds) => reorderMutation.mutateAsync({ boardId, columnIds }),
227
+ isCreating: createMutation.isPending,
228
+ isUpdating: updateMutation.isPending,
229
+ isDeleting: deleteMutation.isPending,
230
+ isReordering: reorderMutation.isPending,
231
+ createError: createMutation.error,
232
+ updateError: updateMutation.error,
233
+ deleteError: deleteMutation.error,
234
+ reorderError: reorderMutation.error
235
+ };
236
+ }
237
+ function useTaskMutations() {
238
+ const { client, headers } = useKanbanClient();
239
+ const queryClient = reactQuery.useQueryClient();
240
+ const createMutation = reactQuery.useMutation({
241
+ mutationFn: async (data) => {
242
+ const response = await client("@post/tasks", {
243
+ method: "POST",
244
+ body: data,
245
+ headers
246
+ });
247
+ if (isErrorResponse(response)) {
248
+ const errorResponse = response;
249
+ throw toError(errorResponse.error);
250
+ }
251
+ return response.data;
252
+ },
253
+ onSuccess: () => {
254
+ queryClient.invalidateQueries({ queryKey: ["boards"] });
255
+ }
256
+ });
257
+ const updateMutation = reactQuery.useMutation({
258
+ mutationFn: async ({
259
+ id,
260
+ data
261
+ }) => {
262
+ const response = await client("@put/tasks/:id", {
263
+ method: "PUT",
264
+ params: { id },
265
+ body: data,
266
+ headers
267
+ });
268
+ if (isErrorResponse(response)) {
269
+ const errorResponse = response;
270
+ throw toError(errorResponse.error);
271
+ }
272
+ return response.data;
273
+ },
274
+ onSuccess: () => {
275
+ queryClient.invalidateQueries({ queryKey: ["boards"] });
276
+ }
277
+ });
278
+ const deleteMutation = reactQuery.useMutation({
279
+ mutationFn: async (id) => {
280
+ const response = await client("@delete/tasks/:id", {
281
+ method: "DELETE",
282
+ params: { id },
283
+ headers
284
+ });
285
+ if (isErrorResponse(response)) {
286
+ const errorResponse = response;
287
+ throw toError(errorResponse.error);
288
+ }
289
+ return response.data;
290
+ },
291
+ onSuccess: () => {
292
+ queryClient.invalidateQueries({ queryKey: ["boards"] });
293
+ }
294
+ });
295
+ const moveMutation = reactQuery.useMutation({
296
+ mutationFn: async ({
297
+ taskId,
298
+ targetColumnId,
299
+ targetOrder
300
+ }) => {
301
+ const response = await client("@post/tasks/move", {
302
+ method: "POST",
303
+ body: { taskId, targetColumnId, targetOrder },
304
+ headers
305
+ });
306
+ if (isErrorResponse(response)) {
307
+ const errorResponse = response;
308
+ throw toError(errorResponse.error);
309
+ }
310
+ return response.data;
311
+ },
312
+ onSuccess: () => {
313
+ queryClient.invalidateQueries({ queryKey: ["boards"] });
314
+ }
315
+ });
316
+ const reorderMutation = reactQuery.useMutation({
317
+ mutationFn: async ({
318
+ columnId,
319
+ taskIds
320
+ }) => {
321
+ const response = await client("@post/tasks/reorder", {
322
+ method: "POST",
323
+ body: { columnId, taskIds },
324
+ headers
325
+ });
326
+ if (isErrorResponse(response)) {
327
+ const errorResponse = response;
328
+ throw toError(errorResponse.error);
329
+ }
330
+ return response.data;
331
+ },
332
+ onSuccess: () => {
333
+ queryClient.invalidateQueries({ queryKey: ["boards"] });
334
+ }
335
+ });
336
+ return {
337
+ createTask: createMutation.mutateAsync,
338
+ updateTask: (id, data) => updateMutation.mutateAsync({ id, data }),
339
+ deleteTask: deleteMutation.mutateAsync,
340
+ moveTask: (taskId, targetColumnId, targetOrder) => moveMutation.mutateAsync({ taskId, targetColumnId, targetOrder }),
341
+ reorderTasks: (columnId, taskIds) => reorderMutation.mutateAsync({ columnId, taskIds }),
342
+ isCreating: createMutation.isPending,
343
+ isUpdating: updateMutation.isPending,
344
+ isDeleting: deleteMutation.isPending,
345
+ isMoving: moveMutation.isPending,
346
+ isReordering: reorderMutation.isPending,
347
+ createError: createMutation.error,
348
+ updateError: updateMutation.error,
349
+ deleteError: deleteMutation.error,
350
+ moveError: moveMutation.error,
351
+ reorderError: reorderMutation.error
352
+ };
353
+ }
354
+ function useResolveUser(userId) {
355
+ const { resolveUser } = context.usePluginOverrides("kanban");
356
+ return reactQuery.useQuery({
357
+ queryKey: ["kanban", "users", userId],
358
+ queryFn: async () => {
359
+ if (!userId) return null;
360
+ const result = await resolveUser(userId);
361
+ return result;
362
+ },
363
+ enabled: !!userId,
364
+ staleTime: 5 * 60 * 1e3,
365
+ // Cache user info for 5 minutes
366
+ gcTime: 10 * 60 * 1e3
367
+ // Keep in cache for 10 minutes
368
+ });
369
+ }
370
+ function useSearchUsers(query, boardId) {
371
+ const { searchUsers } = context.usePluginOverrides("kanban");
372
+ return reactQuery.useQuery({
373
+ queryKey: ["kanban", "users", "search", query, boardId],
374
+ queryFn: async () => {
375
+ const result = await searchUsers(query, boardId);
376
+ return result;
377
+ },
378
+ staleTime: 3e4
379
+ // Cache search results for 30 seconds
380
+ });
381
+ }
382
+
383
+ exports.useBoard = useBoard;
384
+ exports.useBoardMutations = useBoardMutations;
385
+ exports.useBoards = useBoards;
386
+ exports.useColumnMutations = useColumnMutations;
387
+ exports.useResolveUser = useResolveUser;
388
+ exports.useSearchUsers = useSearchUsers;
389
+ exports.useSuspenseBoard = useSuspenseBoard;
390
+ exports.useSuspenseBoards = useSuspenseBoards;
391
+ exports.useTaskMutations = useTaskMutations;