@dxos/plugin-kanban 0.8.4-main.937b3ca → 0.8.4-main.9be5663bfe

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 (233) hide show
  1. package/dist/lib/browser/blueprints/index.mjs +23 -4
  2. package/dist/lib/browser/blueprints/index.mjs.map +4 -4
  3. package/dist/lib/browser/chunk-A3PBV3S5.mjs +105 -0
  4. package/dist/lib/browser/chunk-A3PBV3S5.mjs.map +7 -0
  5. package/dist/lib/browser/delete-card-VPNVIWOA.mjs +32 -0
  6. package/dist/lib/browser/delete-card-VPNVIWOA.mjs.map +7 -0
  7. package/dist/lib/browser/delete-card-field-4HHF2GYX.mjs +50 -0
  8. package/dist/lib/browser/delete-card-field-4HHF2GYX.mjs.map +7 -0
  9. package/dist/lib/browser/index.mjs +84 -61
  10. package/dist/lib/browser/index.mjs.map +4 -4
  11. package/dist/lib/browser/meta.json +1 -1
  12. package/dist/lib/browser/operations/index.mjs +13 -0
  13. package/dist/lib/browser/operations/index.mjs.map +7 -0
  14. package/dist/lib/browser/restore-card-4GG2RYKR.mjs +29 -0
  15. package/dist/lib/browser/restore-card-4GG2RYKR.mjs.map +7 -0
  16. package/dist/lib/browser/restore-card-field-3T26ACYX.mjs +48 -0
  17. package/dist/lib/browser/restore-card-field-3T26ACYX.mjs.map +7 -0
  18. package/dist/lib/browser/types/index.mjs +94 -8
  19. package/dist/lib/browser/types/index.mjs.map +4 -4
  20. package/dist/lib/node-esm/blueprints/index.mjs +23 -4
  21. package/dist/lib/node-esm/blueprints/index.mjs.map +4 -4
  22. package/dist/lib/node-esm/chunk-6LELYA2G.mjs +106 -0
  23. package/dist/lib/node-esm/chunk-6LELYA2G.mjs.map +7 -0
  24. package/dist/lib/node-esm/delete-card-5PW5OMFN.mjs +33 -0
  25. package/dist/lib/node-esm/delete-card-5PW5OMFN.mjs.map +7 -0
  26. package/dist/lib/node-esm/delete-card-field-KPJU2AQ3.mjs +51 -0
  27. package/dist/lib/node-esm/delete-card-field-KPJU2AQ3.mjs.map +7 -0
  28. package/dist/lib/node-esm/index.mjs +84 -61
  29. package/dist/lib/node-esm/index.mjs.map +4 -4
  30. package/dist/lib/node-esm/meta.json +1 -1
  31. package/dist/lib/node-esm/operations/index.mjs +14 -0
  32. package/dist/lib/node-esm/operations/index.mjs.map +7 -0
  33. package/dist/lib/node-esm/restore-card-X2TKMU5A.mjs +30 -0
  34. package/dist/lib/node-esm/restore-card-X2TKMU5A.mjs.map +7 -0
  35. package/dist/lib/node-esm/restore-card-field-IUTL4RTR.mjs +49 -0
  36. package/dist/lib/node-esm/restore-card-field-IUTL4RTR.mjs.map +7 -0
  37. package/dist/lib/node-esm/types/index.mjs +94 -8
  38. package/dist/lib/node-esm/types/index.mjs.map +4 -4
  39. package/dist/types/src/KanbanPlugin.d.ts.map +1 -1
  40. package/dist/types/src/blueprints/index.d.ts +1 -1
  41. package/dist/types/src/blueprints/index.d.ts.map +1 -1
  42. package/dist/types/src/blueprints/kanban-blueprint.d.ts +3 -21
  43. package/dist/types/src/blueprints/kanban-blueprint.d.ts.map +1 -1
  44. package/dist/types/src/capabilities/{artifact-definition/artifact-definition.d.ts → artifact-definition.d.ts} +1 -1
  45. package/dist/types/src/capabilities/artifact-definition.d.ts.map +1 -0
  46. package/dist/types/src/capabilities/blueprint-definition.d.ts +6 -0
  47. package/dist/types/src/capabilities/blueprint-definition.d.ts.map +1 -0
  48. package/dist/types/src/capabilities/index.d.ts +6 -3
  49. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  50. package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
  51. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  52. package/dist/types/src/capabilities/react-surface.d.ts +5 -0
  53. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  54. package/dist/types/src/capabilities/undo-mappings.d.ts +5 -0
  55. package/dist/types/src/capabilities/undo-mappings.d.ts.map +1 -0
  56. package/dist/types/src/components/KanbanBoard/KanbanBoard.d.ts +57 -0
  57. package/dist/types/src/components/KanbanBoard/KanbanBoard.d.ts.map +1 -0
  58. package/dist/types/src/components/KanbanBoard/KanbanBoard.stories.d.ts +72 -0
  59. package/dist/types/src/components/KanbanBoard/KanbanBoard.stories.d.ts.map +1 -0
  60. package/dist/types/src/components/KanbanBoard/KanbanCard.d.ts +10 -0
  61. package/dist/types/src/components/KanbanBoard/KanbanCard.d.ts.map +1 -0
  62. package/dist/types/src/components/KanbanBoard/KanbanColumn.d.ts +9 -0
  63. package/dist/types/src/components/KanbanBoard/KanbanColumn.d.ts.map +1 -0
  64. package/dist/types/src/components/KanbanBoard/index.d.ts +2 -0
  65. package/dist/types/src/components/KanbanBoard/index.d.ts.map +1 -0
  66. package/dist/types/src/components/index.d.ts +1 -2
  67. package/dist/types/src/components/index.d.ts.map +1 -1
  68. package/dist/types/src/containers/KanbanContainer/KanbanContainer.d.ts +6 -0
  69. package/dist/types/src/containers/KanbanContainer/KanbanContainer.d.ts.map +1 -0
  70. package/dist/types/src/containers/KanbanContainer/KanbanContainer.stories.d.ts +79 -0
  71. package/dist/types/src/containers/KanbanContainer/KanbanContainer.stories.d.ts.map +1 -0
  72. package/dist/types/src/containers/KanbanContainer/index.d.ts +2 -0
  73. package/dist/types/src/containers/KanbanContainer/index.d.ts.map +1 -0
  74. package/dist/types/src/containers/KanbanViewEditor/KanbanViewEditor.d.ts +6 -0
  75. package/dist/types/src/containers/KanbanViewEditor/KanbanViewEditor.d.ts.map +1 -0
  76. package/dist/types/src/containers/KanbanViewEditor/index.d.ts +2 -0
  77. package/dist/types/src/containers/KanbanViewEditor/index.d.ts.map +1 -0
  78. package/dist/types/src/containers/index.d.ts +4 -0
  79. package/dist/types/src/containers/index.d.ts.map +1 -0
  80. package/dist/types/src/hooks/index.d.ts +6 -0
  81. package/dist/types/src/hooks/index.d.ts.map +1 -0
  82. package/dist/types/src/hooks/useEchoChangeCallback.d.ts +13 -0
  83. package/dist/types/src/hooks/useEchoChangeCallback.d.ts.map +1 -0
  84. package/dist/types/src/hooks/useKanbanBoardModel.d.ts +16 -0
  85. package/dist/types/src/hooks/useKanbanBoardModel.d.ts.map +1 -0
  86. package/dist/types/src/hooks/useKanbanBoardModel.test.d.ts +2 -0
  87. package/dist/types/src/hooks/useKanbanBoardModel.test.d.ts.map +1 -0
  88. package/dist/types/src/hooks/useKanbanColumnEventHandler.d.ts +22 -0
  89. package/dist/types/src/hooks/useKanbanColumnEventHandler.d.ts.map +1 -0
  90. package/dist/types/src/hooks/useKanbanItemEventHandler.d.ts +19 -0
  91. package/dist/types/src/hooks/useKanbanItemEventHandler.d.ts.map +1 -0
  92. package/dist/types/src/hooks/useProjectionModel.d.ts +15 -0
  93. package/dist/types/src/hooks/useProjectionModel.d.ts.map +1 -0
  94. package/dist/types/src/operations/definitions.d.ts +52 -0
  95. package/dist/types/src/operations/definitions.d.ts.map +1 -0
  96. package/dist/types/src/operations/delete-card-field.d.ts +5 -0
  97. package/dist/types/src/operations/delete-card-field.d.ts.map +1 -0
  98. package/dist/types/src/operations/delete-card.d.ts +5 -0
  99. package/dist/types/src/operations/delete-card.d.ts.map +1 -0
  100. package/dist/types/src/operations/index.d.ts +4 -0
  101. package/dist/types/src/operations/index.d.ts.map +1 -0
  102. package/dist/types/src/operations/restore-card-field.d.ts +5 -0
  103. package/dist/types/src/operations/restore-card-field.d.ts.map +1 -0
  104. package/dist/types/src/operations/restore-card.d.ts +5 -0
  105. package/dist/types/src/operations/restore-card.d.ts.map +1 -0
  106. package/dist/types/src/playwright/board-manager.d.ts +5 -0
  107. package/dist/types/src/playwright/board-manager.d.ts.map +1 -0
  108. package/dist/types/src/playwright/playwright.config.d.ts +3 -0
  109. package/dist/types/src/playwright/playwright.config.d.ts.map +1 -0
  110. package/dist/types/src/playwright/smoke.spec.d.ts +2 -0
  111. package/dist/types/src/playwright/smoke.spec.d.ts.map +1 -0
  112. package/dist/types/src/testing/KanbanCardTileSimple.d.ts +7 -0
  113. package/dist/types/src/testing/KanbanCardTileSimple.d.ts.map +1 -0
  114. package/dist/types/src/testing/index.d.ts +2 -0
  115. package/dist/types/src/testing/index.d.ts.map +1 -0
  116. package/dist/types/src/translations.d.ts +48 -32
  117. package/dist/types/src/translations.d.ts.map +1 -1
  118. package/dist/types/src/types/Kanban.d.ts +37 -0
  119. package/dist/types/src/types/Kanban.d.ts.map +1 -0
  120. package/dist/types/src/types/constants.d.ts +6 -0
  121. package/dist/types/src/types/constants.d.ts.map +1 -0
  122. package/dist/types/src/types/index.d.ts +2 -0
  123. package/dist/types/src/types/index.d.ts.map +1 -1
  124. package/dist/types/src/types/schema.d.ts +0 -103
  125. package/dist/types/src/types/schema.d.ts.map +1 -1
  126. package/dist/types/src/types/types.d.ts +28 -0
  127. package/dist/types/src/types/types.d.ts.map +1 -1
  128. package/dist/types/src/util/arrangement.d.ts +68 -0
  129. package/dist/types/src/util/arrangement.d.ts.map +1 -0
  130. package/dist/types/src/util/arrangement.test.d.ts +2 -0
  131. package/dist/types/src/util/arrangement.test.d.ts.map +1 -0
  132. package/dist/types/src/util/index.d.ts +2 -0
  133. package/dist/types/src/util/index.d.ts.map +1 -0
  134. package/dist/types/tsconfig.tsbuildinfo +1 -1
  135. package/package.json +64 -42
  136. package/src/KanbanPlugin.tsx +35 -23
  137. package/src/blueprints/index.ts +1 -1
  138. package/src/blueprints/kanban-blueprint.ts +12 -8
  139. package/src/capabilities/{artifact-definition/artifact-definition.ts → artifact-definition.ts} +10 -9
  140. package/src/capabilities/blueprint-definition.ts +17 -0
  141. package/src/capabilities/index.ts +10 -3
  142. package/src/capabilities/operation-handler.ts +14 -0
  143. package/src/capabilities/{react-surface/react-surface.tsx → react-surface.tsx} +20 -19
  144. package/src/capabilities/undo-mappings.ts +34 -0
  145. package/src/components/KanbanBoard/KanbanBoard.stories.tsx +142 -0
  146. package/src/components/KanbanBoard/KanbanBoard.tsx +193 -0
  147. package/src/components/KanbanBoard/KanbanCard.tsx +86 -0
  148. package/src/components/KanbanBoard/KanbanColumn.tsx +69 -0
  149. package/src/components/KanbanBoard/index.ts +5 -0
  150. package/src/components/index.ts +1 -2
  151. package/src/containers/KanbanContainer/KanbanContainer.stories.tsx +270 -0
  152. package/src/containers/KanbanContainer/KanbanContainer.tsx +96 -0
  153. package/src/containers/KanbanContainer/index.ts +5 -0
  154. package/src/{components → containers/KanbanViewEditor}/KanbanViewEditor.tsx +23 -19
  155. package/src/containers/KanbanViewEditor/index.ts +5 -0
  156. package/src/containers/index.ts +8 -0
  157. package/src/hooks/index.ts +9 -0
  158. package/src/hooks/useEchoChangeCallback.ts +30 -0
  159. package/src/hooks/useKanbanBoardModel.test.ts +235 -0
  160. package/src/hooks/useKanbanBoardModel.ts +144 -0
  161. package/src/hooks/useKanbanColumnEventHandler.ts +106 -0
  162. package/src/hooks/useKanbanItemEventHandler.ts +133 -0
  163. package/src/hooks/useProjectionModel.ts +58 -0
  164. package/src/meta.ts +1 -1
  165. package/src/operations/definitions.ts +63 -0
  166. package/src/operations/delete-card-field.ts +47 -0
  167. package/src/operations/delete-card.ts +23 -0
  168. package/src/operations/index.ts +12 -0
  169. package/src/operations/restore-card-field.ts +41 -0
  170. package/src/operations/restore-card.ts +21 -0
  171. package/src/playwright/board-manager.ts +13 -0
  172. package/src/playwright/playwright.config.ts +19 -0
  173. package/src/playwright/smoke.spec.ts +107 -0
  174. package/src/testing/KanbanCardTileSimple.tsx +82 -0
  175. package/src/testing/index.ts +5 -0
  176. package/src/translations.ts +26 -18
  177. package/src/types/Kanban.ts +71 -0
  178. package/src/types/constants.ts +9 -0
  179. package/src/types/index.ts +2 -0
  180. package/src/types/schema.ts +0 -76
  181. package/src/types/types.ts +35 -0
  182. package/src/util/arrangement.test.ts +208 -0
  183. package/src/util/arrangement.ts +167 -0
  184. package/src/util/index.ts +5 -0
  185. package/dist/lib/browser/blueprint-definition-T2544VMJ.mjs +0 -17
  186. package/dist/lib/browser/blueprint-definition-T2544VMJ.mjs.map +0 -7
  187. package/dist/lib/browser/chunk-L6N4ZDZ7.mjs +0 -35
  188. package/dist/lib/browser/chunk-L6N4ZDZ7.mjs.map +0 -7
  189. package/dist/lib/browser/chunk-XYQO4VL7.mjs +0 -150
  190. package/dist/lib/browser/chunk-XYQO4VL7.mjs.map +0 -7
  191. package/dist/lib/browser/operation-resolver-UEJHX42A.mjs +0 -162
  192. package/dist/lib/browser/operation-resolver-UEJHX42A.mjs.map +0 -7
  193. package/dist/lib/browser/react-surface-XZSKFDM5.mjs +0 -236
  194. package/dist/lib/browser/react-surface-XZSKFDM5.mjs.map +0 -7
  195. package/dist/lib/node-esm/blueprint-definition-APJQFSHJ.mjs +0 -18
  196. package/dist/lib/node-esm/blueprint-definition-APJQFSHJ.mjs.map +0 -7
  197. package/dist/lib/node-esm/chunk-NN6JMKIT.mjs +0 -152
  198. package/dist/lib/node-esm/chunk-NN6JMKIT.mjs.map +0 -7
  199. package/dist/lib/node-esm/chunk-ZHRMUKTF.mjs +0 -36
  200. package/dist/lib/node-esm/chunk-ZHRMUKTF.mjs.map +0 -7
  201. package/dist/lib/node-esm/operation-resolver-5RPWHZCF.mjs +0 -163
  202. package/dist/lib/node-esm/operation-resolver-5RPWHZCF.mjs.map +0 -7
  203. package/dist/lib/node-esm/react-surface-JWRKX7GS.mjs +0 -237
  204. package/dist/lib/node-esm/react-surface-JWRKX7GS.mjs.map +0 -7
  205. package/dist/types/src/capabilities/artifact-definition/artifact-definition.d.ts.map +0 -1
  206. package/dist/types/src/capabilities/artifact-definition/index.d.ts +0 -3
  207. package/dist/types/src/capabilities/artifact-definition/index.d.ts.map +0 -1
  208. package/dist/types/src/capabilities/blueprint-definition/blueprint-definition.d.ts +0 -9
  209. package/dist/types/src/capabilities/blueprint-definition/blueprint-definition.d.ts.map +0 -1
  210. package/dist/types/src/capabilities/blueprint-definition/index.d.ts +0 -3
  211. package/dist/types/src/capabilities/blueprint-definition/index.d.ts.map +0 -1
  212. package/dist/types/src/capabilities/operation-resolver/index.d.ts +0 -3
  213. package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +0 -1
  214. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +0 -5
  215. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +0 -1
  216. package/dist/types/src/capabilities/react-surface/index.d.ts +0 -3
  217. package/dist/types/src/capabilities/react-surface/index.d.ts.map +0 -1
  218. package/dist/types/src/capabilities/react-surface/react-surface.d.ts +0 -5
  219. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +0 -1
  220. package/dist/types/src/components/KanbanContainer.d.ts +0 -6
  221. package/dist/types/src/components/KanbanContainer.d.ts.map +0 -1
  222. package/dist/types/src/components/KanbanContainer.stories.d.ts +0 -66
  223. package/dist/types/src/components/KanbanContainer.stories.d.ts.map +0 -1
  224. package/dist/types/src/components/KanbanViewEditor.d.ts +0 -8
  225. package/dist/types/src/components/KanbanViewEditor.d.ts.map +0 -1
  226. package/src/capabilities/artifact-definition/index.ts +0 -7
  227. package/src/capabilities/blueprint-definition/blueprint-definition.ts +0 -23
  228. package/src/capabilities/blueprint-definition/index.ts +0 -7
  229. package/src/capabilities/operation-resolver/index.ts +0 -7
  230. package/src/capabilities/operation-resolver/operation-resolver.ts +0 -133
  231. package/src/capabilities/react-surface/index.ts +0 -7
  232. package/src/components/KanbanContainer.stories.tsx +0 -226
  233. package/src/components/KanbanContainer.tsx +0 -84
@@ -1,7 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import { Capability } from '@dxos/app-framework';
6
-
7
- export const ArtifactDefinition = Capability.lazy('ArtifactDefinition', () => import('./artifact-definition'));
@@ -1,23 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import * as Effect from 'effect/Effect';
6
-
7
- import { Capability, Common } from '@dxos/app-framework';
8
-
9
- import { KanbanBlueprint } from '../../blueprints';
10
-
11
- export type BlueprintCapabilities = [
12
- Capability.Capability<typeof Common.Capability.Functions>,
13
- Capability.Capability<typeof Common.Capability.BlueprintDefinition>,
14
- ];
15
-
16
- const blueprintDefinition = Capability.makeModule<[], BlueprintCapabilities>(() =>
17
- Effect.succeed([
18
- Capability.contributes(Common.Capability.Functions, KanbanBlueprint.functions),
19
- Capability.contributes(Common.Capability.BlueprintDefinition, KanbanBlueprint.make()),
20
- ]),
21
- );
22
-
23
- export default blueprintDefinition;
@@ -1,7 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import { Capability } from '@dxos/app-framework';
6
-
7
- export const BlueprintDefinition = Capability.lazy('BlueprintDefinition', () => import('./blueprint-definition'));
@@ -1,7 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import { Capability } from '@dxos/app-framework';
6
-
7
- export const OperationResolver = Capability.lazy('OperationResolver', () => import('./operation-resolver'));
@@ -1,133 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import * as Effect from 'effect/Effect';
6
-
7
- import { Capability, Common, UndoMapping } from '@dxos/app-framework';
8
- import { JsonSchema, Obj } from '@dxos/echo';
9
- import { type EchoSchema } from '@dxos/echo/internal';
10
- import { invariant } from '@dxos/invariant';
11
- import { OperationResolver } from '@dxos/operation';
12
- import { ProjectionModel, createEchoChangeCallback, getTypenameFromQuery } from '@dxos/schema';
13
-
14
- import { meta } from '../../meta';
15
- import { KanbanOperation } from '../../types';
16
-
17
- export default Capability.makeModule(() =>
18
- Effect.succeed([
19
- Capability.contributes(Common.Capability.UndoMapping, [
20
- UndoMapping.make({
21
- operation: KanbanOperation.DeleteCardField,
22
- inverse: KanbanOperation.RestoreCardField,
23
- deriveContext: (input, output) => ({
24
- view: input.view,
25
- field: output.field,
26
- props: output.props,
27
- index: output.index,
28
- }),
29
- message: ['card field deleted label', { ns: meta.id }],
30
- }),
31
- UndoMapping.make({
32
- operation: KanbanOperation.DeleteCard,
33
- inverse: KanbanOperation.RestoreCard,
34
- deriveContext: (_input, output) => ({
35
- card: output.card,
36
- }),
37
- message: ['card deleted label', { ns: meta.id }],
38
- }),
39
- ]),
40
- Capability.contributes(Common.Capability.OperationResolver, [
41
- OperationResolver.make({
42
- operation: KanbanOperation.DeleteCardField,
43
- handler: Effect.fnUntraced(function* ({ view, fieldId }) {
44
- const registry = yield* Capability.get(Common.Capability.AtomRegistry);
45
- const db = Obj.getDatabase(view);
46
- invariant(db, 'Database not found');
47
- const schema = yield* Effect.promise(() =>
48
- db.schemaRegistry
49
- .query({
50
- typename: getTypenameFromQuery(view.query.ast)!,
51
- location: ['database', 'runtime'],
52
- })
53
- .first(),
54
- );
55
-
56
- // Create projection with change callbacks that wrap in Obj.change().
57
- // Schema from registry is an EchoSchema at runtime.
58
- const projection = new ProjectionModel({
59
- registry,
60
- view,
61
- baseSchema: JsonSchema.toJsonSchema(schema),
62
- change: createEchoChangeCallback(view, schema as EchoSchema),
63
- });
64
-
65
- const result = projection.deleteFieldProjection(fieldId);
66
-
67
- // Return data needed for undo.
68
- return {
69
- field: result.deleted.field,
70
- props: result.deleted.props,
71
- index: result.index,
72
- };
73
- }),
74
- }),
75
- OperationResolver.make({
76
- operation: KanbanOperation.DeleteCard,
77
- handler: ({ card }) =>
78
- Effect.sync(() => {
79
- const db = Obj.getDatabase(card);
80
- invariant(db);
81
- db.remove(card);
82
-
83
- // Return data needed for undo.
84
- return { card };
85
- }),
86
- }),
87
-
88
- //
89
- // RestoreCardField (inverse of DeleteCardField)
90
- //
91
- OperationResolver.make({
92
- operation: KanbanOperation.RestoreCardField,
93
- handler: Effect.fnUntraced(function* ({ view, field, props, index }) {
94
- const registry = yield* Capability.get(Common.Capability.AtomRegistry);
95
- const db = Obj.getDatabase(view);
96
- invariant(db, 'Database not found');
97
- const schema = yield* Effect.promise(() =>
98
- db.schemaRegistry
99
- .query({
100
- typename: getTypenameFromQuery(view.query.ast)!,
101
- location: ['database', 'runtime'],
102
- })
103
- .first(),
104
- );
105
-
106
- // Create projection with change callbacks that wrap in Obj.change().
107
- // Schema from registry is an EchoSchema at runtime.
108
- const projection = new ProjectionModel({
109
- registry,
110
- view,
111
- baseSchema: JsonSchema.toJsonSchema(schema),
112
- change: createEchoChangeCallback(view, schema as EchoSchema),
113
- });
114
-
115
- projection.setFieldProjection({ field, props }, index);
116
- }),
117
- }),
118
-
119
- //
120
- // RestoreCard (inverse of DeleteCard)
121
- //
122
- OperationResolver.make({
123
- operation: KanbanOperation.RestoreCard,
124
- handler: ({ card }) =>
125
- Effect.sync(() => {
126
- const db = Obj.getDatabase(card);
127
- invariant(db);
128
- db.add(card);
129
- }),
130
- }),
131
- ]),
132
- ]),
133
- );
@@ -1,7 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import { Capability } from '@dxos/app-framework';
6
-
7
- export const ReactSurface = Capability.lazy('ReactSurface', () => import('./react-surface'));
@@ -1,226 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import { RegistryContext } from '@effect-atom/atom-react';
6
- import { type Meta, type StoryObj } from '@storybook/react-vite';
7
- import * as Effect from 'effect/Effect';
8
- import React, { useCallback, useContext } from 'react';
9
- import { expect, waitFor, within } from 'storybook/test';
10
-
11
- import { withPluginManager } from '@dxos/app-framework/testing';
12
- import { Obj, type QueryAST, Type } from '@dxos/echo';
13
- import { type Mutable } from '@dxos/echo/internal';
14
- import { invariant } from '@dxos/invariant';
15
- import { ClientPlugin } from '@dxos/plugin-client';
16
- import { PreviewPlugin } from '@dxos/plugin-preview';
17
- import { useGlobalFilteredObjects } from '@dxos/plugin-search';
18
- import { SpacePlugin } from '@dxos/plugin-space';
19
- import { StorybookPlugin, corePlugins } from '@dxos/plugin-testing';
20
- import { faker } from '@dxos/random';
21
- import { Filter, useQuery, useSchema, useSpaces } from '@dxos/react-client/echo';
22
- import { withTheme } from '@dxos/react-ui/testing';
23
- import { ViewEditor } from '@dxos/react-ui-form';
24
- import {
25
- Kanban as KanbanComponent,
26
- translations as kanbanTranslations,
27
- useKanbanModel,
28
- useProjectionModel,
29
- } from '@dxos/react-ui-kanban';
30
- import { Kanban } from '@dxos/react-ui-kanban/types';
31
- import { JsonFilter } from '@dxos/react-ui-syntax-highlighter';
32
- import { View, getTypenameFromQuery } from '@dxos/schema';
33
- import { Organization, Person } from '@dxos/types';
34
-
35
- import { translations } from '../translations';
36
-
37
- faker.seed(0);
38
-
39
- const createOrg = () => ({
40
- name: faker.commerce.productName(),
41
- description: faker.lorem.paragraph(),
42
- image: faker.image.url(),
43
- website: faker.internet.url(),
44
- status: faker.helpers.arrayElement(Organization.StatusOptions).id as Organization.Organization['status'],
45
- });
46
-
47
- //
48
- // Story components.
49
- //
50
-
51
- const DefaultComponent = () => {
52
- const registry = useContext(RegistryContext);
53
- const spaces = useSpaces();
54
- const space = spaces[spaces.length - 1];
55
- const [object] = useQuery(space?.db, Filter.type(Kanban.Kanban));
56
- const typename = object?.view.target?.query ? getTypenameFromQuery(object.view.target.query.ast) : undefined;
57
- const schema = useSchema(space?.db, typename);
58
-
59
- const objects = useQuery(space?.db, schema ? Filter.type(schema) : Filter.nothing());
60
- const filteredObjects = useGlobalFilteredObjects(objects);
61
-
62
- const projection = useProjectionModel(schema, object, registry);
63
- const model = useKanbanModel({
64
- object,
65
- projection,
66
- items: filteredObjects,
67
- });
68
-
69
- const handleAddCard = useCallback(
70
- (columnValue: string | undefined) => {
71
- const path = model?.columnFieldPath;
72
- if (space && schema && Type.isObjectSchema(schema) && path) {
73
- const card = Obj.make(schema, {
74
- ...createOrg(),
75
- [path]: columnValue,
76
- });
77
-
78
- space.db.add(card);
79
- return card.id;
80
- }
81
- },
82
- [space, schema, model],
83
- );
84
-
85
- const handleRemoveCard = useCallback((card: { id: string }) => Obj.isObject(card) && space?.db.remove(card), [space]);
86
-
87
- const handleUpdateQuery = useCallback(
88
- (newQuery: QueryAST.Query) => {
89
- invariant(schema);
90
- invariant(Type.isMutable(schema));
91
- invariant(object.view.target);
92
-
93
- schema.updateTypename(getTypenameFromQuery(newQuery));
94
- Obj.change(object.view.target, (v) => {
95
- v.query.ast = newQuery as Mutable<typeof newQuery>;
96
- });
97
- },
98
- [object, schema],
99
- );
100
-
101
- if (!schema || !object.view.target) {
102
- return null;
103
- }
104
-
105
- return (
106
- <div className='grow grid grid-cols-[1fr_350px] overflow-hidden'>
107
- {model ? <KanbanComponent model={model} onAddCard={handleAddCard} onRemoveCard={handleRemoveCard} /> : <div />}
108
- <div className='flex flex-col bs-full overflow-hidden border-l border-separator'>
109
- <ViewEditor
110
- classNames='p-2'
111
- registry={space?.db.schemaRegistry}
112
- schema={schema}
113
- view={object.view.target}
114
- onQueryChanged={handleUpdateQuery}
115
- onDelete={(fieldId: string) => {
116
- console.log('[ViewEditor]', 'onDelete', fieldId);
117
- }}
118
- />
119
- <JsonFilter data={{ view: object.view.target, schema }} classNames='text-xs' />
120
- </div>
121
- </div>
122
- );
123
- };
124
-
125
- //
126
- // Story definitions.
127
- //
128
-
129
- const meta = {
130
- title: 'plugins/plugin-kanban/Kanban',
131
- component: DefaultComponent,
132
- render: () => <DefaultComponent />,
133
- decorators: [
134
- withTheme,
135
- withPluginManager({
136
- plugins: [
137
- ...corePlugins(),
138
- ClientPlugin({
139
- types: [Organization.Organization, Person.Person, View.View, Kanban.Kanban],
140
- onClientInitialized: ({ client }) =>
141
- Effect.gen(function* () {
142
- yield* Effect.promise(() => client.halo.createIdentity());
143
- const space = yield* Effect.promise(() => client.spaces.create());
144
- yield* Effect.promise(() => space.waitUntilReady());
145
-
146
- const { view } = yield* Effect.promise(() =>
147
- View.makeFromDatabase({
148
- db: space.db,
149
- typename: Organization.Organization.typename,
150
- pivotFieldName: 'status',
151
- }),
152
- );
153
- const kanban = Kanban.make({ view });
154
- space.db.add(kanban);
155
-
156
- // TODO(burdon): Replace with sdk/schema/testing.
157
- Array.from({ length: 80 }).map(() => {
158
- return space.db.add(Obj.make(Organization.Organization, createOrg()));
159
- });
160
- }),
161
- }),
162
- PreviewPlugin(),
163
- SpacePlugin({}),
164
- StorybookPlugin({}),
165
- ],
166
- }),
167
- ],
168
- parameters: {
169
- layout: 'fullscreen',
170
- translations: [...translations, ...kanbanTranslations],
171
- },
172
- } satisfies Meta<typeof DefaultComponent>;
173
-
174
- export default meta;
175
-
176
- type Story = StoryObj<typeof meta>;
177
-
178
- export const Default: Story = {
179
- play: async ({ canvasElement }) => {
180
- const canvas = within(canvasElement);
181
-
182
- // Wait for the kanban columns to render by finding the status tags.
183
- // Organization.StatusOptions: prospect, qualified, active, commit, reject.
184
- const activeTag = await canvas.findByText('Active', undefined, { timeout: 30_000 });
185
- const prospectTag = await canvas.findByText('Prospect', undefined, { timeout: 10_000 });
186
- const commitTag = await canvas.findByText('Commit', undefined, { timeout: 10_000 });
187
-
188
- // Verify all expected columns are rendered.
189
- await expect(activeTag).toBeTruthy();
190
- await expect(prospectTag).toBeTruthy();
191
- await expect(commitTag).toBeTruthy();
192
-
193
- // Find the column containers.
194
- const activeColumn = activeTag.closest('[data-dx-stack-item]') as HTMLElement;
195
- const prospectColumn = prospectTag.closest('[data-dx-stack-item]') as HTMLElement;
196
- await expect(activeColumn).toBeTruthy();
197
- await expect(prospectColumn).toBeTruthy();
198
-
199
- // Wait for cards to render in the columns.
200
- // Cards have data-dx-item-id attribute from StackItem.Root.
201
- const getColumnCards = (column: HTMLElement) =>
202
- Array.from(column.querySelectorAll('[data-dx-item-id]')) as HTMLElement[];
203
-
204
- await waitFor(() => expect(getColumnCards(activeColumn).length).toBeGreaterThan(0));
205
-
206
- // Verify cards are distributed across columns.
207
- const activeCards = getColumnCards(activeColumn);
208
- const prospectCards = getColumnCards(prospectColumn);
209
- await expect(activeCards.length).toBeGreaterThan(0);
210
- await expect(prospectCards.length).toBeGreaterThan(0);
211
-
212
- // Verify cards have drag handles (first button in toolbar).
213
- const firstActiveCard = activeCards[0];
214
- const buttons = firstActiveCard.querySelectorAll('button');
215
- await expect(buttons.length).toBeGreaterThan(0);
216
-
217
- // Verify the drop zone exists in each column.
218
- const activeDropZone = activeColumn.querySelector('.kanban-drop');
219
- const prospectDropZone = prospectColumn.querySelector('.kanban-drop');
220
- await expect(activeDropZone).toBeTruthy();
221
- await expect(prospectDropZone).toBeTruthy();
222
-
223
- // TODO(wittjosiah): Get drag & drop tests working.
224
- // See packages/apps/composer-app/src/playwright/stack.spec.ts for reference.
225
- },
226
- };
@@ -1,84 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import { RegistryContext } from '@effect-atom/atom-react';
6
- import React, { useCallback, useContext, useEffect, useState } from 'react';
7
-
8
- import { Common } from '@dxos/app-framework';
9
- import { type SurfaceComponentProps, useCapabilities, useOperationInvoker } from '@dxos/app-framework/react';
10
- import { Filter, Obj, Type } from '@dxos/echo';
11
- import { useGlobalFilteredObjects } from '@dxos/plugin-search';
12
- import { useQuery } from '@dxos/react-client/echo';
13
- import { Kanban as KanbanComponent, useKanbanModel, useProjectionModel } from '@dxos/react-ui-kanban';
14
- import { type Kanban } from '@dxos/react-ui-kanban/types';
15
- import { Layout } from '@dxos/react-ui-mosaic';
16
- import { getTypenameFromQuery } from '@dxos/schema';
17
-
18
- import { KanbanOperation } from '../types';
19
-
20
- export type KanbanContainerProps = SurfaceComponentProps<Kanban.Kanban>;
21
-
22
- export const KanbanContainer = ({ role, subject: object }: KanbanContainerProps) => {
23
- const registry = useContext(RegistryContext);
24
- const schemas = useCapabilities(Common.Capability.Schema);
25
- const [cardSchema, setCardSchema] = useState<Type.Obj.Any>();
26
- const db = Obj.getDatabase(object);
27
- const { invokePromise } = useOperationInvoker();
28
- const typename = object.view.target?.query ? getTypenameFromQuery(object.view.target.query.ast) : undefined;
29
-
30
- useEffect(() => {
31
- const staticSchema = schemas.flat().find((schema) => Type.getTypename(schema) === typename);
32
- if (staticSchema) {
33
- setCardSchema(staticSchema);
34
- }
35
- if (!staticSchema && typename && db) {
36
- const query = db.schemaRegistry.query({ typename });
37
- const unsubscribe = query.subscribe(
38
- () => {
39
- const [schema] = query.results;
40
- if (schema) {
41
- setCardSchema(schema);
42
- }
43
- },
44
- { fire: true },
45
- );
46
- return unsubscribe;
47
- }
48
- }, [schemas, db, typename]);
49
-
50
- const objects = useQuery(db, cardSchema ? Filter.type(cardSchema) : Filter.nothing());
51
- const filteredObjects = useGlobalFilteredObjects(objects);
52
-
53
- const projection = useProjectionModel(cardSchema, object, registry);
54
- const model = useKanbanModel({
55
- object,
56
- projection,
57
- items: filteredObjects,
58
- });
59
-
60
- const handleAddCard = useCallback(
61
- (columnValue: string | undefined) => {
62
- const path = model?.columnFieldPath;
63
- if (db && cardSchema && path) {
64
- const card = Obj.make(cardSchema, { [path]: columnValue });
65
- db.add(card);
66
- return card.id;
67
- }
68
- },
69
- [db, cardSchema, model],
70
- );
71
-
72
- const handleRemoveCard = useCallback(
73
- (card: { id: string }) => {
74
- void invokePromise(KanbanOperation.DeleteCard, { card });
75
- },
76
- [invokePromise],
77
- );
78
-
79
- return (
80
- <Layout.Main role={role}>
81
- {model && <KanbanComponent model={model} onAddCard={handleAddCard} onRemoveCard={handleRemoveCard} />}
82
- </Layout.Main>
83
- );
84
- };