@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,85 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ const jsxRuntime = require('react/jsx-runtime');
5
+ const React = require('react');
6
+ const button = require('../../../../../../../ui/src/components/button.cjs');
7
+ const input = require('../../../../../../../ui/src/components/input.cjs');
8
+ const textarea = require('../../../../../../../ui/src/components/textarea.cjs');
9
+ const label = require('../../../../../../../ui/src/components/label.cjs');
10
+ const kanbanHooks = require('../../hooks/kanban-hooks.cjs');
11
+
12
+ function BoardForm({ board, onClose, onSuccess }) {
13
+ const isEditing = !!board;
14
+ const { createBoard, updateBoard, isCreating, isUpdating } = kanbanHooks.useBoardMutations();
15
+ const [name, setName] = React.useState(board?.name || "");
16
+ const [description, setDescription] = React.useState(board?.description || "");
17
+ const [error, setError] = React.useState(null);
18
+ const isPending = isCreating || isUpdating;
19
+ const handleSubmit = async (e) => {
20
+ e.preventDefault();
21
+ setError(null);
22
+ if (!name.trim()) {
23
+ setError("Name is required");
24
+ return;
25
+ }
26
+ try {
27
+ if (isEditing && board) {
28
+ await updateBoard(board.id, { name, description });
29
+ onSuccess(board.id);
30
+ } else {
31
+ const newBoard = await createBoard({ name, description });
32
+ if (newBoard?.id) {
33
+ onSuccess(newBoard.id);
34
+ }
35
+ }
36
+ } catch (err) {
37
+ setError(err instanceof Error ? err.message : "An error occurred");
38
+ }
39
+ };
40
+ return /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
41
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
42
+ /* @__PURE__ */ jsxRuntime.jsx(label.Label, { htmlFor: "name", children: "Name *" }),
43
+ /* @__PURE__ */ jsxRuntime.jsx(
44
+ input.Input,
45
+ {
46
+ id: "name",
47
+ value: name,
48
+ onChange: (e) => setName(e.target.value),
49
+ placeholder: "e.g., Project Alpha",
50
+ disabled: isPending
51
+ }
52
+ )
53
+ ] }),
54
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
55
+ /* @__PURE__ */ jsxRuntime.jsx(label.Label, { htmlFor: "description", children: "Description" }),
56
+ /* @__PURE__ */ jsxRuntime.jsx(
57
+ textarea.Textarea,
58
+ {
59
+ id: "description",
60
+ value: description,
61
+ onChange: (e) => setDescription(e.target.value),
62
+ placeholder: "Describe your board...",
63
+ disabled: isPending,
64
+ rows: 3
65
+ }
66
+ )
67
+ ] }),
68
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-3 text-sm text-red-600 bg-red-50 border border-red-200 rounded-md", children: error }),
69
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2 pt-2", children: [
70
+ /* @__PURE__ */ jsxRuntime.jsx(button.Button, { type: "submit", disabled: isPending, children: isPending ? isEditing ? "Updating..." : "Creating..." : isEditing ? "Update Board" : "Create Board" }),
71
+ /* @__PURE__ */ jsxRuntime.jsx(
72
+ button.Button,
73
+ {
74
+ type: "button",
75
+ variant: "outline",
76
+ onClick: onClose,
77
+ disabled: isPending,
78
+ children: "Cancel"
79
+ }
80
+ )
81
+ ] })
82
+ ] });
83
+ }
84
+
85
+ exports.BoardForm = BoardForm;
@@ -0,0 +1,83 @@
1
+ "use client";
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { useState } from 'react';
4
+ import { Button } from '../../../../../../../ui/src/components/button.mjs';
5
+ import { Input } from '../../../../../../../ui/src/components/input.mjs';
6
+ import { Textarea } from '../../../../../../../ui/src/components/textarea.mjs';
7
+ import { Label } from '../../../../../../../ui/src/components/label.mjs';
8
+ import { useBoardMutations } from '../../hooks/kanban-hooks.mjs';
9
+
10
+ function BoardForm({ board, onClose, onSuccess }) {
11
+ const isEditing = !!board;
12
+ const { createBoard, updateBoard, isCreating, isUpdating } = useBoardMutations();
13
+ const [name, setName] = useState(board?.name || "");
14
+ const [description, setDescription] = useState(board?.description || "");
15
+ const [error, setError] = useState(null);
16
+ const isPending = isCreating || isUpdating;
17
+ const handleSubmit = async (e) => {
18
+ e.preventDefault();
19
+ setError(null);
20
+ if (!name.trim()) {
21
+ setError("Name is required");
22
+ return;
23
+ }
24
+ try {
25
+ if (isEditing && board) {
26
+ await updateBoard(board.id, { name, description });
27
+ onSuccess(board.id);
28
+ } else {
29
+ const newBoard = await createBoard({ name, description });
30
+ if (newBoard?.id) {
31
+ onSuccess(newBoard.id);
32
+ }
33
+ }
34
+ } catch (err) {
35
+ setError(err instanceof Error ? err.message : "An error occurred");
36
+ }
37
+ };
38
+ return /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
39
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
40
+ /* @__PURE__ */ jsx(Label, { htmlFor: "name", children: "Name *" }),
41
+ /* @__PURE__ */ jsx(
42
+ Input,
43
+ {
44
+ id: "name",
45
+ value: name,
46
+ onChange: (e) => setName(e.target.value),
47
+ placeholder: "e.g., Project Alpha",
48
+ disabled: isPending
49
+ }
50
+ )
51
+ ] }),
52
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
53
+ /* @__PURE__ */ jsx(Label, { htmlFor: "description", children: "Description" }),
54
+ /* @__PURE__ */ jsx(
55
+ Textarea,
56
+ {
57
+ id: "description",
58
+ value: description,
59
+ onChange: (e) => setDescription(e.target.value),
60
+ placeholder: "Describe your board...",
61
+ disabled: isPending,
62
+ rows: 3
63
+ }
64
+ )
65
+ ] }),
66
+ error && /* @__PURE__ */ jsx("div", { className: "p-3 text-sm text-red-600 bg-red-50 border border-red-200 rounded-md", children: error }),
67
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2 pt-2", children: [
68
+ /* @__PURE__ */ jsx(Button, { type: "submit", disabled: isPending, children: isPending ? isEditing ? "Updating..." : "Creating..." : isEditing ? "Update Board" : "Create Board" }),
69
+ /* @__PURE__ */ jsx(
70
+ Button,
71
+ {
72
+ type: "button",
73
+ variant: "outline",
74
+ onClick: onClose,
75
+ disabled: isPending,
76
+ children: "Cancel"
77
+ }
78
+ )
79
+ ] })
80
+ ] });
81
+ }
82
+
83
+ export { BoardForm };
@@ -0,0 +1,72 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ const jsxRuntime = require('react/jsx-runtime');
5
+ const React = require('react');
6
+ const button = require('../../../../../../../ui/src/components/button.cjs');
7
+ const input = require('../../../../../../../ui/src/components/input.cjs');
8
+ const label = require('../../../../../../../ui/src/components/label.cjs');
9
+ const kanbanHooks = require('../../hooks/kanban-hooks.cjs');
10
+
11
+ function ColumnForm({
12
+ boardId,
13
+ columnId,
14
+ column,
15
+ onClose,
16
+ onSuccess
17
+ }) {
18
+ const isEditing = !!columnId;
19
+ const { createColumn, updateColumn, isCreating, isUpdating } = kanbanHooks.useColumnMutations();
20
+ const [title, setTitle] = React.useState(column?.title || "");
21
+ const [error, setError] = React.useState(null);
22
+ const isPending = isCreating || isUpdating;
23
+ const handleSubmit = async (e) => {
24
+ e.preventDefault();
25
+ setError(null);
26
+ if (!title.trim()) {
27
+ setError("Title is required");
28
+ return;
29
+ }
30
+ try {
31
+ if (isEditing && columnId) {
32
+ await updateColumn(columnId, { title });
33
+ } else {
34
+ await createColumn({ title, boardId });
35
+ }
36
+ onSuccess();
37
+ } catch (err) {
38
+ setError(err instanceof Error ? err.message : "An error occurred");
39
+ }
40
+ };
41
+ return /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
42
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
43
+ /* @__PURE__ */ jsxRuntime.jsx(label.Label, { htmlFor: "title", children: "Title *" }),
44
+ /* @__PURE__ */ jsxRuntime.jsx(
45
+ input.Input,
46
+ {
47
+ id: "title",
48
+ value: title,
49
+ onChange: (e) => setTitle(e.target.value),
50
+ placeholder: "e.g., To Do",
51
+ disabled: isPending
52
+ }
53
+ )
54
+ ] }),
55
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-3 text-sm text-red-600 bg-red-50 border border-red-200 rounded-md", children: error }),
56
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2 pt-2", children: [
57
+ /* @__PURE__ */ jsxRuntime.jsx(button.Button, { type: "submit", disabled: isPending, children: isPending ? isEditing ? "Updating..." : "Creating..." : isEditing ? "Update Column" : "Create Column" }),
58
+ /* @__PURE__ */ jsxRuntime.jsx(
59
+ button.Button,
60
+ {
61
+ type: "button",
62
+ variant: "outline",
63
+ onClick: onClose,
64
+ disabled: isPending,
65
+ children: "Cancel"
66
+ }
67
+ )
68
+ ] })
69
+ ] });
70
+ }
71
+
72
+ exports.ColumnForm = ColumnForm;
@@ -0,0 +1,70 @@
1
+ "use client";
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { useState } from 'react';
4
+ import { Button } from '../../../../../../../ui/src/components/button.mjs';
5
+ import { Input } from '../../../../../../../ui/src/components/input.mjs';
6
+ import { Label } from '../../../../../../../ui/src/components/label.mjs';
7
+ import { useColumnMutations } from '../../hooks/kanban-hooks.mjs';
8
+
9
+ function ColumnForm({
10
+ boardId,
11
+ columnId,
12
+ column,
13
+ onClose,
14
+ onSuccess
15
+ }) {
16
+ const isEditing = !!columnId;
17
+ const { createColumn, updateColumn, isCreating, isUpdating } = useColumnMutations();
18
+ const [title, setTitle] = useState(column?.title || "");
19
+ const [error, setError] = useState(null);
20
+ const isPending = isCreating || isUpdating;
21
+ const handleSubmit = async (e) => {
22
+ e.preventDefault();
23
+ setError(null);
24
+ if (!title.trim()) {
25
+ setError("Title is required");
26
+ return;
27
+ }
28
+ try {
29
+ if (isEditing && columnId) {
30
+ await updateColumn(columnId, { title });
31
+ } else {
32
+ await createColumn({ title, boardId });
33
+ }
34
+ onSuccess();
35
+ } catch (err) {
36
+ setError(err instanceof Error ? err.message : "An error occurred");
37
+ }
38
+ };
39
+ return /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
40
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
41
+ /* @__PURE__ */ jsx(Label, { htmlFor: "title", children: "Title *" }),
42
+ /* @__PURE__ */ jsx(
43
+ Input,
44
+ {
45
+ id: "title",
46
+ value: title,
47
+ onChange: (e) => setTitle(e.target.value),
48
+ placeholder: "e.g., To Do",
49
+ disabled: isPending
50
+ }
51
+ )
52
+ ] }),
53
+ error && /* @__PURE__ */ jsx("div", { className: "p-3 text-sm text-red-600 bg-red-50 border border-red-200 rounded-md", children: error }),
54
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2 pt-2", children: [
55
+ /* @__PURE__ */ jsx(Button, { type: "submit", disabled: isPending, children: isPending ? isEditing ? "Updating..." : "Creating..." : isEditing ? "Update Column" : "Create Column" }),
56
+ /* @__PURE__ */ jsx(
57
+ Button,
58
+ {
59
+ type: "button",
60
+ variant: "outline",
61
+ onClick: onClose,
62
+ disabled: isPending,
63
+ children: "Cancel"
64
+ }
65
+ )
66
+ ] })
67
+ ] });
68
+ }
69
+
70
+ export { ColumnForm };
@@ -0,0 +1,200 @@
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 input = require('../../../../../../../ui/src/components/input.cjs');
9
+ const label = require('../../../../../../../ui/src/components/label.cjs');
10
+ const select = require('../../../../../../../ui/src/components/select.cjs');
11
+ const minimalTiptap = require('../../../../../../../ui/src/components/minimal-tiptap/minimal-tiptap.cjs');
12
+ const searchSelect = require('../../../../../../../ui/src/components/search-select.cjs');
13
+ const kanbanHooks = require('../../hooks/kanban-hooks.cjs');
14
+ const utils = require('../../../utils.cjs');
15
+
16
+ function TaskForm({
17
+ columnId,
18
+ boardId,
19
+ taskId,
20
+ task,
21
+ columns,
22
+ onClose,
23
+ onSuccess,
24
+ onDelete
25
+ }) {
26
+ const isEditing = !!taskId;
27
+ const {
28
+ createTask,
29
+ updateTask,
30
+ moveTask,
31
+ isCreating,
32
+ isUpdating,
33
+ isDeleting,
34
+ isMoving
35
+ } = kanbanHooks.useTaskMutations();
36
+ const [title, setTitle] = React.useState(task?.title || "");
37
+ const [description, setDescription] = React.useState(task?.description || "");
38
+ const [priority, setPriority] = React.useState(
39
+ task?.priority || "MEDIUM"
40
+ );
41
+ const [selectedColumnId, setSelectedColumnId] = React.useState(
42
+ task?.columnId || columnId
43
+ );
44
+ const [assigneeId, setAssigneeId] = React.useState(task?.assigneeId || "");
45
+ const [error, setError] = React.useState(null);
46
+ const { data: users = [] } = kanbanHooks.useSearchUsers("", boardId);
47
+ const userOptions = [
48
+ { value: "", label: "Unassigned" },
49
+ ...users.map((user) => ({ value: user.id, label: user.name }))
50
+ ];
51
+ const isPending = isCreating || isUpdating || isDeleting || isMoving;
52
+ const handleSubmit = async (e) => {
53
+ e.preventDefault();
54
+ setError(null);
55
+ if (!title.trim()) {
56
+ setError("Title is required");
57
+ return;
58
+ }
59
+ try {
60
+ if (isEditing && taskId) {
61
+ const isColumnChanging = task?.columnId && selectedColumnId !== task.columnId;
62
+ if (isColumnChanging) {
63
+ await updateTask(taskId, {
64
+ title,
65
+ description,
66
+ priority,
67
+ assigneeId: assigneeId || null
68
+ });
69
+ try {
70
+ const targetColumn = columns.find((c) => c.id === selectedColumnId);
71
+ const targetTasks = targetColumn?.tasks || [];
72
+ const targetOrder = targetTasks.length > 0 ? Math.max(...targetTasks.map((t) => t.order)) + 1 : 0;
73
+ await moveTask(taskId, selectedColumnId, targetOrder);
74
+ } catch (moveErr) {
75
+ const moveErrorMsg = moveErr instanceof Error ? moveErr.message : "Unknown error";
76
+ setError(
77
+ `Task properties were saved, but moving to the new column failed: ${moveErrorMsg}. You can try dragging the task to the desired column.`
78
+ );
79
+ return;
80
+ }
81
+ } else {
82
+ await updateTask(taskId, {
83
+ title,
84
+ description,
85
+ priority,
86
+ columnId: selectedColumnId,
87
+ assigneeId: assigneeId || null
88
+ });
89
+ }
90
+ } else {
91
+ await createTask({
92
+ title,
93
+ description,
94
+ priority,
95
+ columnId: selectedColumnId,
96
+ assigneeId: assigneeId || void 0
97
+ });
98
+ }
99
+ onSuccess();
100
+ } catch (err) {
101
+ setError(err instanceof Error ? err.message : "An error occurred");
102
+ }
103
+ };
104
+ return /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
105
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
106
+ /* @__PURE__ */ jsxRuntime.jsx(label.Label, { htmlFor: "title", children: "Title *" }),
107
+ /* @__PURE__ */ jsxRuntime.jsx(
108
+ input.Input,
109
+ {
110
+ id: "title",
111
+ value: title,
112
+ onChange: (e) => setTitle(e.target.value),
113
+ placeholder: "e.g., Fix login bug",
114
+ disabled: isPending
115
+ }
116
+ )
117
+ ] }),
118
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
119
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
120
+ /* @__PURE__ */ jsxRuntime.jsx(label.Label, { htmlFor: "priority", children: "Priority" }),
121
+ /* @__PURE__ */ jsxRuntime.jsxs(
122
+ select.Select,
123
+ {
124
+ value: priority,
125
+ onValueChange: (v) => setPriority(v),
126
+ children: [
127
+ /* @__PURE__ */ jsxRuntime.jsx(select.SelectTrigger, { children: /* @__PURE__ */ jsxRuntime.jsx(select.SelectValue, { placeholder: "Select priority" }) }),
128
+ /* @__PURE__ */ jsxRuntime.jsx(select.SelectContent, { children: utils.PRIORITY_OPTIONS.map((option) => /* @__PURE__ */ jsxRuntime.jsx(select.SelectItem, { value: option.value, children: option.label }, option.value)) })
129
+ ]
130
+ }
131
+ )
132
+ ] }),
133
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
134
+ /* @__PURE__ */ jsxRuntime.jsx(label.Label, { htmlFor: "column", children: "Column" }),
135
+ /* @__PURE__ */ jsxRuntime.jsxs(select.Select, { value: selectedColumnId, onValueChange: setSelectedColumnId, children: [
136
+ /* @__PURE__ */ jsxRuntime.jsx(select.SelectTrigger, { children: /* @__PURE__ */ jsxRuntime.jsx(select.SelectValue, { placeholder: "Select column" }) }),
137
+ /* @__PURE__ */ jsxRuntime.jsx(select.SelectContent, { children: columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx(select.SelectItem, { value: col.id, children: col.title }, col.id)) })
138
+ ] })
139
+ ] })
140
+ ] }),
141
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
142
+ /* @__PURE__ */ jsxRuntime.jsx(label.Label, { htmlFor: "assignee", children: "Assignee" }),
143
+ /* @__PURE__ */ jsxRuntime.jsx(
144
+ searchSelect,
145
+ {
146
+ options: userOptions,
147
+ value: assigneeId,
148
+ onChange: setAssigneeId,
149
+ placeholder: "Select assignee",
150
+ emptyMessage: "No users found"
151
+ }
152
+ )
153
+ ] }),
154
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
155
+ /* @__PURE__ */ jsxRuntime.jsx(label.Label, { children: "Description" }),
156
+ /* @__PURE__ */ jsxRuntime.jsx(
157
+ minimalTiptap.MinimalTiptapEditor,
158
+ {
159
+ value: description,
160
+ onChange: (value) => setDescription(typeof value === "string" ? value : ""),
161
+ output: "markdown",
162
+ placeholder: "Describe the task...",
163
+ editable: !isPending,
164
+ className: "min-h-[150px]"
165
+ }
166
+ )
167
+ ] }),
168
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-3 text-sm text-red-600 bg-red-50 border border-red-200 rounded-md", children: error }),
169
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between pt-2", children: [
170
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
171
+ /* @__PURE__ */ jsxRuntime.jsx(button.Button, { type: "submit", disabled: isPending, children: isPending ? isEditing ? "Updating..." : "Creating..." : isEditing ? "Update Task" : "Create Task" }),
172
+ /* @__PURE__ */ jsxRuntime.jsx(
173
+ button.Button,
174
+ {
175
+ type: "button",
176
+ variant: "outline",
177
+ onClick: onClose,
178
+ disabled: isPending,
179
+ children: "Cancel"
180
+ }
181
+ )
182
+ ] }),
183
+ isEditing && onDelete && /* @__PURE__ */ jsxRuntime.jsxs(
184
+ button.Button,
185
+ {
186
+ type: "button",
187
+ variant: "destructive",
188
+ onClick: onDelete,
189
+ disabled: isPending,
190
+ children: [
191
+ /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Trash2, { className: "mr-2 h-4 w-4" }),
192
+ "Delete"
193
+ ]
194
+ }
195
+ )
196
+ ] })
197
+ ] });
198
+ }
199
+
200
+ exports.TaskForm = TaskForm;