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

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 (177) hide show
  1. package/dist/lib/browser/blueprints/index.mjs +1 -1
  2. package/dist/lib/browser/blueprints/index.mjs.map +3 -3
  3. package/dist/lib/browser/{chunk-A3PBV3S5.mjs → chunk-T32TEM55.mjs} +2 -2
  4. package/dist/lib/browser/chunk-T32TEM55.mjs.map +7 -0
  5. package/dist/lib/browser/{delete-card-VPNVIWOA.mjs → delete-card-7OSCNCW2.mjs} +4 -12
  6. package/dist/lib/browser/delete-card-7OSCNCW2.mjs.map +7 -0
  7. package/dist/lib/browser/{delete-card-field-4HHF2GYX.mjs → delete-card-field-NSB2RE3Z.mjs} +4 -12
  8. package/dist/lib/browser/delete-card-field-NSB2RE3Z.mjs.map +7 -0
  9. package/dist/lib/browser/index.mjs +5 -97
  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 +3 -3
  13. package/dist/lib/browser/operations/index.mjs.map +3 -3
  14. package/dist/lib/browser/{restore-card-4GG2RYKR.mjs → restore-card-FO3WERIE.mjs} +4 -12
  15. package/dist/lib/browser/restore-card-FO3WERIE.mjs.map +7 -0
  16. package/dist/lib/browser/{restore-card-field-3T26ACYX.mjs → restore-card-field-U5XYEEOW.mjs} +4 -12
  17. package/dist/lib/browser/restore-card-field-U5XYEEOW.mjs.map +7 -0
  18. package/dist/lib/browser/translations.mjs +44 -0
  19. package/dist/lib/browser/translations.mjs.map +7 -0
  20. package/dist/lib/browser/types/index.mjs +70 -10
  21. package/dist/lib/browser/types/index.mjs.map +3 -3
  22. package/dist/lib/node-esm/blueprints/index.mjs +1 -1
  23. package/dist/lib/node-esm/blueprints/index.mjs.map +3 -3
  24. package/dist/lib/node-esm/{chunk-6LELYA2G.mjs → chunk-W2RNFBMZ.mjs} +2 -2
  25. package/dist/lib/node-esm/chunk-W2RNFBMZ.mjs.map +7 -0
  26. package/dist/lib/node-esm/{delete-card-5PW5OMFN.mjs → delete-card-ZIREL6HN.mjs} +4 -12
  27. package/dist/lib/node-esm/delete-card-ZIREL6HN.mjs.map +7 -0
  28. package/dist/lib/node-esm/{delete-card-field-KPJU2AQ3.mjs → delete-card-field-IPTEGVPP.mjs} +4 -12
  29. package/dist/lib/node-esm/delete-card-field-IPTEGVPP.mjs.map +7 -0
  30. package/dist/lib/node-esm/index.mjs +5 -97
  31. package/dist/lib/node-esm/index.mjs.map +4 -4
  32. package/dist/lib/node-esm/meta.json +1 -1
  33. package/dist/lib/node-esm/operations/index.mjs +3 -3
  34. package/dist/lib/node-esm/operations/index.mjs.map +3 -3
  35. package/dist/lib/node-esm/{restore-card-X2TKMU5A.mjs → restore-card-WJJ4YB7K.mjs} +4 -12
  36. package/dist/lib/node-esm/restore-card-WJJ4YB7K.mjs.map +7 -0
  37. package/dist/lib/node-esm/{restore-card-field-IUTL4RTR.mjs → restore-card-field-L24WJXAW.mjs} +4 -12
  38. package/dist/lib/node-esm/restore-card-field-L24WJXAW.mjs.map +7 -0
  39. package/dist/lib/node-esm/translations.mjs +45 -0
  40. package/dist/lib/node-esm/translations.mjs.map +7 -0
  41. package/dist/lib/node-esm/types/index.mjs +70 -10
  42. package/dist/lib/node-esm/types/index.mjs.map +3 -3
  43. package/dist/types/src/KanbanPlugin.d.ts +1 -0
  44. package/dist/types/src/KanbanPlugin.d.ts.map +1 -1
  45. package/dist/types/src/KanbanPlugin.node.d.ts +4 -0
  46. package/dist/types/src/KanbanPlugin.node.d.ts.map +1 -0
  47. package/dist/types/src/KanbanPlugin.test.d.ts +2 -0
  48. package/dist/types/src/KanbanPlugin.test.d.ts.map +1 -0
  49. package/dist/types/src/blueprints/kanban-blueprint.d.ts +2 -2
  50. package/dist/types/src/blueprints/kanban-blueprint.d.ts.map +1 -1
  51. package/dist/types/src/capabilities/artifact-definition.d.ts.map +1 -1
  52. package/dist/types/src/capabilities/blueprint-definition.d.ts +2 -2
  53. package/dist/types/src/capabilities/blueprint-definition.d.ts.map +1 -1
  54. package/dist/types/src/capabilities/index.d.ts +3 -2
  55. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  56. package/dist/types/src/capabilities/migrations.d.ts +5 -0
  57. package/dist/types/src/capabilities/migrations.d.ts.map +1 -0
  58. package/dist/types/src/capabilities/operation-handler.d.ts +1 -1
  59. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -1
  60. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  61. package/dist/types/src/capabilities/undo-mappings.d.ts.map +1 -1
  62. package/dist/types/src/components/KanbanBoard/KanbanBoard.d.ts +6 -6
  63. package/dist/types/src/components/KanbanBoard/KanbanBoard.d.ts.map +1 -1
  64. package/dist/types/src/components/KanbanBoard/KanbanBoard.stories.d.ts +24 -24
  65. package/dist/types/src/components/KanbanBoard/KanbanBoard.stories.d.ts.map +1 -1
  66. package/dist/types/src/components/KanbanBoard/KanbanCard.d.ts.map +1 -1
  67. package/dist/types/src/components/KanbanBoard/KanbanColumn.d.ts.map +1 -1
  68. package/dist/types/src/containers/KanbanContainer/KanbanContainer.d.ts +2 -2
  69. package/dist/types/src/containers/KanbanContainer/KanbanContainer.d.ts.map +1 -1
  70. package/dist/types/src/containers/KanbanContainer/KanbanContainer.stories.d.ts +24 -24
  71. package/dist/types/src/containers/KanbanContainer/KanbanContainer.stories.d.ts.map +1 -1
  72. package/dist/types/src/containers/KanbanSettings/KanbanSettings.d.ts +13 -0
  73. package/dist/types/src/containers/KanbanSettings/KanbanSettings.d.ts.map +1 -0
  74. package/dist/types/src/containers/KanbanSettings/index.d.ts +2 -0
  75. package/dist/types/src/containers/KanbanSettings/index.d.ts.map +1 -0
  76. package/dist/types/src/containers/index.d.ts +1 -1
  77. package/dist/types/src/containers/index.d.ts.map +1 -1
  78. package/dist/types/src/hooks/index.d.ts +1 -0
  79. package/dist/types/src/hooks/index.d.ts.map +1 -1
  80. package/dist/types/src/hooks/useEchoChangeCallback.d.ts.map +1 -1
  81. package/dist/types/src/hooks/useItemsProjection.d.ts +10 -0
  82. package/dist/types/src/hooks/useItemsProjection.d.ts.map +1 -0
  83. package/dist/types/src/hooks/useKanbanBoardModel.browser.test.d.ts +2 -0
  84. package/dist/types/src/hooks/useKanbanBoardModel.browser.test.d.ts.map +1 -0
  85. package/dist/types/src/hooks/useKanbanBoardModel.d.ts.map +1 -1
  86. package/dist/types/src/hooks/useKanbanColumnEventHandler.d.ts +1 -1
  87. package/dist/types/src/hooks/useKanbanColumnEventHandler.d.ts.map +1 -1
  88. package/dist/types/src/hooks/useKanbanItemEventHandler.d.ts +1 -1
  89. package/dist/types/src/hooks/useKanbanItemEventHandler.d.ts.map +1 -1
  90. package/dist/types/src/hooks/useProjectionModel.d.ts.map +1 -1
  91. package/dist/types/src/index.d.ts +2 -1
  92. package/dist/types/src/index.d.ts.map +1 -1
  93. package/dist/types/src/operations/definitions.d.ts +2 -2
  94. package/dist/types/src/operations/definitions.d.ts.map +1 -1
  95. package/dist/types/src/operations/delete-card-field.d.ts +1 -1
  96. package/dist/types/src/operations/delete-card-field.d.ts.map +1 -1
  97. package/dist/types/src/operations/delete-card.d.ts +1 -1
  98. package/dist/types/src/operations/delete-card.d.ts.map +1 -1
  99. package/dist/types/src/operations/index.d.ts +1 -1
  100. package/dist/types/src/operations/index.d.ts.map +1 -1
  101. package/dist/types/src/operations/restore-card-field.d.ts +1 -1
  102. package/dist/types/src/operations/restore-card-field.d.ts.map +1 -1
  103. package/dist/types/src/operations/restore-card.d.ts +1 -1
  104. package/dist/types/src/operations/restore-card.d.ts.map +1 -1
  105. package/dist/types/src/playwright/board-manager.d.ts.map +1 -1
  106. package/dist/types/src/playwright/playwright.config.d.ts.map +1 -1
  107. package/dist/types/src/translations.d.ts +24 -24
  108. package/dist/types/src/translations.d.ts.map +1 -1
  109. package/dist/types/src/types/Kanban.d.ts +78 -6
  110. package/dist/types/src/types/Kanban.d.ts.map +1 -1
  111. package/dist/types/src/types/constants.d.ts +3 -3
  112. package/dist/types/src/types/constants.d.ts.map +1 -1
  113. package/dist/types/src/types/migrations.test.d.ts +2 -0
  114. package/dist/types/src/types/migrations.test.d.ts.map +1 -0
  115. package/dist/types/src/types/schema.d.ts +15 -1
  116. package/dist/types/src/types/schema.d.ts.map +1 -1
  117. package/dist/types/src/types/types.d.ts +2 -2
  118. package/dist/types/src/util/arrangement.d.ts +7 -3
  119. package/dist/types/src/util/arrangement.d.ts.map +1 -1
  120. package/dist/types/tsconfig.tsbuildinfo +1 -1
  121. package/package.json +50 -50
  122. package/src/KanbanPlugin.node.ts +55 -0
  123. package/src/KanbanPlugin.test.ts +31 -0
  124. package/src/KanbanPlugin.tsx +11 -5
  125. package/src/blueprints/kanban-blueprint.ts +2 -3
  126. package/src/capabilities/artifact-definition.ts +1 -1
  127. package/src/capabilities/blueprint-definition.ts +2 -0
  128. package/src/capabilities/index.ts +3 -1
  129. package/src/capabilities/migrations.ts +35 -0
  130. package/src/capabilities/operation-handler.ts +1 -1
  131. package/src/capabilities/react-surface.tsx +16 -8
  132. package/src/components/KanbanBoard/KanbanBoard.stories.tsx +7 -3
  133. package/src/components/KanbanBoard/KanbanBoard.tsx +7 -2
  134. package/src/components/KanbanBoard/KanbanCard.tsx +15 -3
  135. package/src/components/KanbanBoard/KanbanColumn.tsx +7 -5
  136. package/src/containers/KanbanContainer/KanbanContainer.stories.tsx +21 -16
  137. package/src/containers/KanbanContainer/KanbanContainer.tsx +89 -7
  138. package/src/containers/KanbanSettings/KanbanSettings.tsx +94 -0
  139. package/src/containers/KanbanSettings/index.ts +5 -0
  140. package/src/containers/index.ts +1 -1
  141. package/src/hooks/index.ts +1 -0
  142. package/src/hooks/useEchoChangeCallback.ts +2 -2
  143. package/src/hooks/useItemsProjection.ts +44 -0
  144. package/src/hooks/{useKanbanBoardModel.test.ts → useKanbanBoardModel.browser.test.ts} +3 -3
  145. package/src/hooks/useKanbanBoardModel.ts +18 -5
  146. package/src/hooks/useProjectionModel.ts +2 -2
  147. package/src/index.ts +6 -2
  148. package/src/operations/definitions.ts +1 -1
  149. package/src/operations/delete-card-field.ts +1 -1
  150. package/src/operations/delete-card.ts +1 -1
  151. package/src/operations/index.ts +1 -1
  152. package/src/operations/restore-card-field.ts +1 -1
  153. package/src/operations/restore-card.ts +1 -1
  154. package/src/types/Kanban.ts +92 -12
  155. package/src/types/migrations.test.ts +83 -0
  156. package/src/types/schema.ts +19 -1
  157. package/src/types/types.ts +2 -2
  158. package/src/util/arrangement.test.ts +10 -0
  159. package/src/util/arrangement.ts +24 -14
  160. package/dist/lib/browser/chunk-A3PBV3S5.mjs.map +0 -7
  161. package/dist/lib/browser/delete-card-VPNVIWOA.mjs.map +0 -7
  162. package/dist/lib/browser/delete-card-field-4HHF2GYX.mjs.map +0 -7
  163. package/dist/lib/browser/restore-card-4GG2RYKR.mjs.map +0 -7
  164. package/dist/lib/browser/restore-card-field-3T26ACYX.mjs.map +0 -7
  165. package/dist/lib/node-esm/chunk-6LELYA2G.mjs.map +0 -7
  166. package/dist/lib/node-esm/delete-card-5PW5OMFN.mjs.map +0 -7
  167. package/dist/lib/node-esm/delete-card-field-KPJU2AQ3.mjs.map +0 -7
  168. package/dist/lib/node-esm/restore-card-X2TKMU5A.mjs.map +0 -7
  169. package/dist/lib/node-esm/restore-card-field-IUTL4RTR.mjs.map +0 -7
  170. package/dist/types/src/containers/KanbanViewEditor/KanbanViewEditor.d.ts +0 -6
  171. package/dist/types/src/containers/KanbanViewEditor/KanbanViewEditor.d.ts.map +0 -1
  172. package/dist/types/src/containers/KanbanViewEditor/index.d.ts +0 -2
  173. package/dist/types/src/containers/KanbanViewEditor/index.d.ts.map +0 -1
  174. package/dist/types/src/hooks/useKanbanBoardModel.test.d.ts +0 -2
  175. package/dist/types/src/hooks/useKanbanBoardModel.test.d.ts.map +0 -1
  176. package/src/containers/KanbanViewEditor/KanbanViewEditor.tsx +0 -63
  177. package/src/containers/KanbanViewEditor/index.ts +0 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-kanban",
3
- "version": "0.8.4-main.9be5663bfe",
3
+ "version": "0.8.4-main.abd8ff62ef",
4
4
  "description": "Kanban DXOS Surface plugin",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -20,7 +20,13 @@
20
20
  "#hooks": "./src/hooks/index.ts",
21
21
  "#meta": "./src/meta.ts",
22
22
  "#operations": "./src/operations/index.ts",
23
+ "#plugin": {
24
+ "browser": "./src/KanbanPlugin.tsx",
25
+ "node": "./src/KanbanPlugin.node.ts",
26
+ "default": "./src/KanbanPlugin.tsx"
27
+ },
23
28
  "#testing": "./src/testing/index.ts",
29
+ "#translations": "./src/translations.ts",
24
30
  "#types": "./src/types/index.ts"
25
31
  },
26
32
  "exports": {
@@ -42,6 +48,12 @@
42
48
  "node": "./dist/lib/node-esm/operations/index.mjs",
43
49
  "types": "./dist/types/src/operations/index.d.ts"
44
50
  },
51
+ "./translations": {
52
+ "source": "./src/translations.ts",
53
+ "types": "./dist/types/src/translations.d.ts",
54
+ "browser": "./dist/lib/browser/translations.mjs",
55
+ "node": "./dist/lib/node-esm/translations.mjs"
56
+ },
45
57
  "./types": {
46
58
  "source": "./src/types/index.ts",
47
59
  "browser": "./dist/lib/browser/types/index.mjs",
@@ -50,16 +62,6 @@
50
62
  }
51
63
  },
52
64
  "types": "dist/types/src/index.d.ts",
53
- "typesVersions": {
54
- "*": {
55
- "blueprints": [
56
- "dist/types/src/blueprints/index.d.ts"
57
- ],
58
- "types": [
59
- "dist/types/src/types/index.d.ts"
60
- ]
61
- }
62
- },
63
65
  "files": [
64
66
  "dist",
65
67
  "src"
@@ -68,56 +70,54 @@
68
70
  "@effect-atom/atom-react": "^0.5.0",
69
71
  "@radix-ui/react-context": "1.1.1",
70
72
  "effect": "3.20.0",
71
- "@dxos/ai": "0.8.4-main.9be5663bfe",
72
- "@dxos/async": "0.8.4-main.9be5663bfe",
73
- "@dxos/blueprints": "0.8.4-main.9be5663bfe",
74
- "@dxos/echo": "0.8.4-main.9be5663bfe",
75
- "@dxos/echo-atom": "0.8.4-main.9be5663bfe",
76
- "@dxos/app-framework": "0.8.4-main.9be5663bfe",
77
- "@dxos/effect": "0.8.4-main.9be5663bfe",
78
- "@dxos/functions": "0.8.4-main.9be5663bfe",
79
- "@dxos/invariant": "0.8.4-main.9be5663bfe",
80
- "@dxos/log": "0.8.4-main.9be5663bfe",
81
- "@dxos/app-toolkit": "0.8.4-main.9be5663bfe",
82
- "@dxos/assistant": "0.8.4-main.9be5663bfe",
83
- "@dxos/operation": "0.8.4-main.9be5663bfe",
84
- "@dxos/plugin-graph": "0.8.4-main.9be5663bfe",
85
- "@dxos/plugin-space": "0.8.4-main.9be5663bfe",
86
- "@dxos/plugin-client": "0.8.4-main.9be5663bfe",
87
- "@dxos/plugin-search": "0.8.4-main.9be5663bfe",
88
- "@dxos/random": "0.8.4-main.9be5663bfe",
89
- "@dxos/react-ui": "0.8.4-main.9be5663bfe",
90
- "@dxos/react-client": "0.8.4-main.9be5663bfe",
91
- "@dxos/react-ui-form": "0.8.4-main.9be5663bfe",
92
- "@dxos/react-ui-menu": "0.8.4-main.9be5663bfe",
93
- "@dxos/react-ui-stack": "0.8.4-main.9be5663bfe",
94
- "@dxos/react-ui-mosaic": "0.8.4-main.9be5663bfe",
95
- "@dxos/schema": "0.8.4-main.9be5663bfe",
96
- "@dxos/types": "0.8.4-main.9be5663bfe",
97
- "@dxos/util": "0.8.4-main.9be5663bfe"
73
+ "@dxos/ai": "0.8.4-main.abd8ff62ef",
74
+ "@dxos/app-framework": "0.8.4-main.abd8ff62ef",
75
+ "@dxos/async": "0.8.4-main.abd8ff62ef",
76
+ "@dxos/compute": "0.8.4-main.abd8ff62ef",
77
+ "@dxos/app-toolkit": "0.8.4-main.abd8ff62ef",
78
+ "@dxos/assistant": "0.8.4-main.abd8ff62ef",
79
+ "@dxos/echo": "0.8.4-main.abd8ff62ef",
80
+ "@dxos/echo-atom": "0.8.4-main.abd8ff62ef",
81
+ "@dxos/effect": "0.8.4-main.abd8ff62ef",
82
+ "@dxos/log": "0.8.4-main.abd8ff62ef",
83
+ "@dxos/invariant": "0.8.4-main.abd8ff62ef",
84
+ "@dxos/plugin-client": "0.8.4-main.abd8ff62ef",
85
+ "@dxos/plugin-search": "0.8.4-main.abd8ff62ef",
86
+ "@dxos/plugin-graph": "0.8.4-main.abd8ff62ef",
87
+ "@dxos/plugin-space": "0.8.4-main.abd8ff62ef",
88
+ "@dxos/react-ui": "0.8.4-main.abd8ff62ef",
89
+ "@dxos/random": "0.8.4-main.abd8ff62ef",
90
+ "@dxos/react-client": "0.8.4-main.abd8ff62ef",
91
+ "@dxos/react-ui-form": "0.8.4-main.abd8ff62ef",
92
+ "@dxos/react-ui-menu": "0.8.4-main.abd8ff62ef",
93
+ "@dxos/react-ui-mosaic": "0.8.4-main.abd8ff62ef",
94
+ "@dxos/react-ui-stack": "0.8.4-main.abd8ff62ef",
95
+ "@dxos/schema": "0.8.4-main.abd8ff62ef",
96
+ "@dxos/types": "0.8.4-main.abd8ff62ef",
97
+ "@dxos/util": "0.8.4-main.abd8ff62ef"
98
98
  },
99
99
  "devDependencies": {
100
100
  "@types/react": "~19.2.7",
101
101
  "@types/react-dom": "~19.2.3",
102
102
  "react": "~19.2.3",
103
103
  "react-dom": "~19.2.3",
104
- "vite": "^7.1.11",
105
- "@dxos/echo-db": "0.8.4-main.9be5663bfe",
106
- "@dxos/keys": "0.8.4-main.9be5663bfe",
107
- "@dxos/plugin-preview": "0.8.4-main.9be5663bfe",
108
- "@dxos/plugin-testing": "0.8.4-main.9be5663bfe",
109
- "@dxos/react-ui-syntax-highlighter": "0.8.4-main.9be5663bfe",
110
- "@dxos/plugin-theme": "0.8.4-main.9be5663bfe",
111
- "@dxos/storybook-utils": "0.8.4-main.9be5663bfe",
112
- "@dxos/test-utils": "0.8.4-main.9be5663bfe",
113
- "@dxos/ui-theme": "0.8.4-main.9be5663bfe"
104
+ "vite": "^8.0.10",
105
+ "@dxos/echo-db": "0.8.4-main.abd8ff62ef",
106
+ "@dxos/plugin-testing": "0.8.4-main.abd8ff62ef",
107
+ "@dxos/plugin-theme": "0.8.4-main.abd8ff62ef",
108
+ "@dxos/plugin-preview": "0.8.4-main.abd8ff62ef",
109
+ "@dxos/storybook-utils": "0.8.4-main.abd8ff62ef",
110
+ "@dxos/keys": "0.8.4-main.abd8ff62ef",
111
+ "@dxos/react-ui-syntax-highlighter": "0.8.4-main.abd8ff62ef",
112
+ "@dxos/test-utils": "0.8.4-main.abd8ff62ef",
113
+ "@dxos/ui-theme": "0.8.4-main.abd8ff62ef"
114
114
  },
115
115
  "peerDependencies": {
116
116
  "effect": "3.20.0",
117
117
  "react": "~19.2.3",
118
118
  "react-dom": "~19.2.3",
119
- "@dxos/react-ui": "0.8.4-main.9be5663bfe",
120
- "@dxos/ui-theme": "0.8.4-main.9be5663bfe"
119
+ "@dxos/ui-theme": "0.8.4-main.abd8ff62ef",
120
+ "@dxos/react-ui": "0.8.4-main.abd8ff62ef"
121
121
  },
122
122
  "publishConfig": {
123
123
  "access": "public"
@@ -0,0 +1,55 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+ import * as Option from 'effect/Option';
7
+
8
+ import { Plugin } from '@dxos/app-framework';
9
+ import { AppPlugin } from '@dxos/app-toolkit';
10
+ import { Operation } from '@dxos/compute';
11
+ import { Annotation, Type } from '@dxos/echo';
12
+ import { SpaceOperation } from '@dxos/plugin-space/operations';
13
+ import { type CreateObject } from '@dxos/plugin-space/types';
14
+ import { ViewModel } from '@dxos/schema';
15
+
16
+ import { BlueprintDefinition, OperationHandler, UndoMappings } from '#capabilities';
17
+ import { meta } from '#meta';
18
+ import { CreateKanbanSchema, Kanban } from '#types';
19
+
20
+ export const KanbanPlugin = Plugin.define(meta).pipe(
21
+ AppPlugin.addBlueprintDefinitionModule({ activate: BlueprintDefinition }),
22
+ AppPlugin.addMetadataModule({
23
+ metadata: {
24
+ id: Type.getTypename(Kanban.Kanban),
25
+ metadata: {
26
+ icon: Annotation.IconAnnotation.get(Kanban.Kanban).pipe(Option.getOrThrow).icon,
27
+ iconHue: Annotation.IconAnnotation.get(Kanban.Kanban).pipe(Option.getOrThrow).hue ?? 'white',
28
+ inputSchema: CreateKanbanSchema,
29
+ createObject: ((props, options) =>
30
+ Effect.gen(function* () {
31
+ const object = yield* Effect.promise(async () => {
32
+ const { view } = await ViewModel.makeFromDatabase({
33
+ db: options.db,
34
+ typename: props.typename,
35
+ pivotFieldName: props.initialPivotColumn,
36
+ });
37
+ return Kanban.make({ name: props.name, view });
38
+ });
39
+ return yield* Operation.invoke(SpaceOperation.AddObject, {
40
+ object,
41
+ target: options.target,
42
+ hidden: true,
43
+ targetNodeId: options.targetNodeId,
44
+ });
45
+ })) satisfies CreateObject,
46
+ },
47
+ },
48
+ }),
49
+ AppPlugin.addOperationHandlerModule({ activate: OperationHandler }),
50
+ AppPlugin.addUndoMappingsModule({ activate: UndoMappings }),
51
+ AppPlugin.addSchemaModule({ schema: [Kanban.Kanban] }),
52
+ Plugin.make,
53
+ );
54
+
55
+ export default KanbanPlugin;
@@ -0,0 +1,31 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { describe, test } from 'vitest';
6
+
7
+ import { AppActivationEvents } from '@dxos/app-toolkit';
8
+ import { createComposerTestApp } from '@dxos/plugin-testing/harness';
9
+
10
+ import { KanbanPlugin } from '#plugin';
11
+
12
+ import { meta } from './meta';
13
+
14
+ const moduleId = (name: string) => `${meta.id}.module.${name}`;
15
+
16
+ describe('KanbanPlugin', () => {
17
+ test('modules activate on the expected events', async ({ expect }) => {
18
+ await using harness = await createComposerTestApp({
19
+ plugins: [KanbanPlugin()],
20
+ });
21
+
22
+ // After autoStart: OperationHandler and UndoMappings auto-cascade from OperationPlugin.
23
+ expect(harness.manager.getActive()).toEqual(
24
+ expect.arrayContaining([moduleId('OperationHandler'), moduleId('UndoMappings')]),
25
+ );
26
+
27
+ // BlueprintDefinition fires when AssistantPlugin loads blueprint definitions.
28
+ await harness.fire(AppActivationEvents.SetupArtifactDefinition);
29
+ expect(harness.manager.getActive()).toContain(moduleId('BlueprintDefinition'));
30
+ });
31
+ });
@@ -7,18 +7,18 @@ import * as Option from 'effect/Option';
7
7
 
8
8
  import { Plugin } from '@dxos/app-framework';
9
9
  import { AppPlugin } from '@dxos/app-toolkit';
10
+ import { Operation } from '@dxos/compute';
10
11
  import { Annotation, Type } from '@dxos/echo';
11
- import { Operation } from '@dxos/operation';
12
+ import { ClientEvents } from '@dxos/plugin-client/types';
12
13
  import { SpaceOperation } from '@dxos/plugin-space/operations';
13
14
  import { type CreateObject } from '@dxos/plugin-space/types';
14
15
  import { ViewModel } from '@dxos/schema';
15
16
 
16
- import { BlueprintDefinition, OperationHandler, UndoMappings, ReactSurface } from '#capabilities';
17
+ import { BlueprintDefinition, Migrations, OperationHandler, UndoMappings, ReactSurface } from '#capabilities';
17
18
  import { meta } from '#meta';
19
+ import { translations } from '#translations';
18
20
  import { CreateKanbanSchema, Kanban } from '#types';
19
21
 
20
- import { translations } from './translations';
21
-
22
22
  export const KanbanPlugin = Plugin.define(meta).pipe(
23
23
  AppPlugin.addBlueprintDefinitionModule({ activate: BlueprintDefinition }),
24
24
  AppPlugin.addMetadataModule({
@@ -49,9 +49,15 @@ export const KanbanPlugin = Plugin.define(meta).pipe(
49
49
  },
50
50
  }),
51
51
  AppPlugin.addOperationHandlerModule({ activate: OperationHandler }),
52
- AppPlugin.addOperationHandlerModule({ id: 'undo-mappings', activate: UndoMappings }),
52
+ AppPlugin.addUndoMappingsModule({ activate: UndoMappings }),
53
53
  AppPlugin.addSchemaModule({ schema: [Kanban.Kanban] }),
54
54
  AppPlugin.addSurfaceModule({ activate: ReactSurface }),
55
55
  AppPlugin.addTranslationsModule({ translations }),
56
+ Plugin.addModule({
57
+ activatesOn: ClientEvents.SetupMigration,
58
+ activate: Migrations,
59
+ }),
56
60
  Plugin.make,
57
61
  );
62
+
63
+ export default KanbanPlugin;
@@ -2,8 +2,7 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { type AppCapabilities } from '@dxos/app-toolkit';
6
- import { Blueprint, Template } from '@dxos/blueprints';
5
+ import { Blueprint, Template } from '@dxos/compute';
7
6
  import { trim } from '@dxos/util';
8
7
 
9
8
  const BLUEPRINT_KEY = 'org.dxos.blueprint.kanban';
@@ -20,7 +19,7 @@ const make = () =>
20
19
  }),
21
20
  });
22
21
 
23
- const blueprint: AppCapabilities.BlueprintDefinition = {
22
+ const blueprint: Blueprint.Definition = {
24
23
  key: BLUEPRINT_KEY,
25
24
  make,
26
25
  };
@@ -11,7 +11,7 @@ import * as Schema from 'effect/Schema';
11
11
  import { ToolResult, createTool } from '@dxos/ai';
12
12
  import { Capabilities, Capability, type PromiseIntentDispatcher } from '@dxos/app-framework';
13
13
  import { createArtifactElement } from '@dxos/assistant';
14
- import { defineArtifact } from '@dxos/blueprints';
14
+ import { defineArtifact } from '@dxos/compute';
15
15
  import { Obj, Query } from '@dxos/echo';
16
16
  import { View } from '@dxos/echo';
17
17
  import { invariant } from '@dxos/invariant';
@@ -6,6 +6,8 @@ import * as Effect from 'effect/Effect';
6
6
 
7
7
  import { Capability } from '@dxos/app-framework';
8
8
  import { AppCapabilities } from '@dxos/app-toolkit';
9
+ // eslint-disable-next-line unused-imports/no-unused-imports
10
+ import type { Blueprint } from '@dxos/compute';
9
11
 
10
12
  import { KanbanBlueprint } from '#blueprints';
11
13
 
@@ -3,9 +3,11 @@
3
3
  //
4
4
 
5
5
  import { Capability } from '@dxos/app-framework';
6
- import { OperationHandlerSet } from '@dxos/operation';
6
+ // eslint-disable-next-line unused-imports/no-unused-imports
7
+ import type { Blueprint, OperationHandlerSet } from '@dxos/compute';
7
8
 
8
9
  export const BlueprintDefinition = Capability.lazy('BlueprintDefinition', () => import('./blueprint-definition'));
10
+ export const Migrations = Capability.lazy('Migrations', () => import('./migrations'));
9
11
  export const OperationHandler = Capability.lazy<OperationHandlerSet.OperationHandlerSet>(
10
12
  'OperationHandler',
11
13
  () => import('./operation-handler'),
@@ -0,0 +1,35 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+
7
+ import { Capability } from '@dxos/app-framework';
8
+ import { defineObjectMigration } from '@dxos/client/echo';
9
+ import { ClientCapabilities } from '@dxos/plugin-client/types';
10
+
11
+ import { Kanban } from '#types';
12
+
13
+ /**
14
+ * v0.1.0 → v0.2.0: nests the existing `view` ref under a `spec: { kind: 'view', view }`
15
+ * discriminated union. v0.2.0 introduced an items-variant for externally-synced kanbans;
16
+ * pre-migration objects were all view-based by construction.
17
+ */
18
+ const migrations = [
19
+ defineObjectMigration({
20
+ from: Kanban.KanbanV1,
21
+ to: Kanban.Kanban,
22
+ transform: async (from) => ({
23
+ name: from.name,
24
+ arrangement: from.arrangement,
25
+ spec: { kind: 'view' as const, view: from.view },
26
+ }),
27
+ onMigration: async () => {},
28
+ }),
29
+ ];
30
+
31
+ export default Capability.makeModule(
32
+ Effect.fnUntraced(function* () {
33
+ return Capability.contributes(ClientCapabilities.Migration, migrations);
34
+ }),
35
+ );
@@ -3,7 +3,7 @@
3
3
  import * as Effect from 'effect/Effect';
4
4
 
5
5
  import { Capabilities, Capability } from '@dxos/app-framework';
6
- import type { OperationHandlerSet } from '@dxos/operation';
6
+ import type { OperationHandlerSet } from '@dxos/compute';
7
7
 
8
8
  import { KanbanOperationHandlerSet } from '#operations';
9
9
 
@@ -4,6 +4,7 @@
4
4
 
5
5
  import * as Effect from 'effect/Effect';
6
6
  import type * as Schema from 'effect/Schema';
7
+ import * as SchemaAST from 'effect/SchemaAST';
7
8
  import React, { useMemo } from 'react';
8
9
 
9
10
  import { Capabilities, Capability } from '@dxos/app-framework';
@@ -14,7 +15,7 @@ import { type Collection } from '@dxos/echo';
14
15
  import { findAnnotation } from '@dxos/effect';
15
16
  import { type FormFieldComponentProps, SelectField, useFormValues } from '@dxos/react-ui-form';
16
17
 
17
- import { KanbanContainer, KanbanViewEditor } from '#containers';
18
+ import { KanbanContainer, KanbanSettings } from '#containers';
18
19
  import { Kanban, PivotColumnAnnotationId } from '#types';
19
20
 
20
21
  export default Capability.makeModule(() =>
@@ -23,16 +24,17 @@ export default Capability.makeModule(() =>
23
24
  Surface.create({
24
25
  id: 'root',
25
26
  // TODO(wittjosiah): Split into multiple surfaces if this filter proves too strict for non-article roles.
26
- role: ['article', 'section'],
27
- filter: AppSurface.objectArticle(Kanban.Kanban),
27
+ filter: AppSurface.oneOf(
28
+ AppSurface.object(AppSurface.Article, Kanban.Kanban),
29
+ AppSurface.object(AppSurface.Section, Kanban.Kanban),
30
+ ),
28
31
  component: ({ data, role }) => <KanbanContainer role={role} subject={data.subject} />,
29
32
  }),
30
33
  Surface.create({
31
34
  id: 'object-properties',
32
- role: 'object-properties',
33
35
  position: 'hoist',
34
- filter: AppSurface.objectProperties(Kanban.Kanban),
35
- component: ({ data }) => <KanbanViewEditor subject={data.subject} />,
36
+ filter: AppSurface.object(AppSurface.ObjectProperties, Kanban.Kanban),
37
+ component: ({ data }) => <KanbanSettings subject={data.subject} />,
36
38
  }),
37
39
  Surface.create({
38
40
  id: 'create-initial-schema-form-[pivot-column]',
@@ -43,12 +45,18 @@ export default Capability.makeModule(() =>
43
45
  prop: string;
44
46
  schema: Schema.Schema<any>;
45
47
  target: Database.Database | Collection.Collection | undefined;
48
+ fieldPropertyAst?: SchemaAST.AST;
46
49
  } => {
47
50
  const annotation = findAnnotation<boolean>((data.schema as Schema.Schema.All).ast, PivotColumnAnnotationId);
48
51
  return !!annotation;
49
52
  },
50
- component: ({ data: { target }, ...inputProps }) => {
51
- const props = inputProps as any as FormFieldComponentProps;
53
+ component: ({ data: { target, fieldPropertyAst }, ...inputProps }) => {
54
+ const ast = fieldPropertyAst;
55
+ if (!ast) {
56
+ return null;
57
+ }
58
+
59
+ const props = { ...inputProps, type: ast } as any as FormFieldComponentProps;
52
60
  const db = Database.isDatabase(target) ? target : target && Obj.getDatabase(target);
53
61
  if (!db) {
54
62
  return null;
@@ -17,9 +17,9 @@ import { Organization } from '@dxos/types';
17
17
 
18
18
  import { createEchoChangeCallback as createKanbanChangeCallback } from '#hooks';
19
19
  import { KanbanCardTileSimple } from '#testing';
20
+ import { translations } from '#translations';
20
21
  import { Kanban } from '#types';
21
22
 
22
- import { translations } from '../../translations';
23
23
  import { KanbanBoard } from './KanbanBoard';
24
24
 
25
25
  random.seed(1);
@@ -79,7 +79,9 @@ const DefaultStory = () => {
79
79
 
80
80
  const handleCardAdd = useCallback(
81
81
  (columnValue: string | undefined) => {
82
- if (!state || !columnFieldPath || !registry) return undefined;
82
+ if (!state || !columnFieldPath || !registry) {
83
+ return undefined;
84
+ }
83
85
  const card = Obj.make(Organization.Organization, {
84
86
  ...createOrg(),
85
87
  ...(columnFieldPath ? { [columnFieldPath]: columnValue } : {}),
@@ -93,7 +95,9 @@ const DefaultStory = () => {
93
95
 
94
96
  const handleCardRemove = useCallback(
95
97
  (card: Obj.Unknown) => {
96
- if (!registry) return;
98
+ if (!registry) {
99
+ return;
100
+ }
97
101
  const current = registry.get(items) ?? [];
98
102
  registry.set(
99
103
  items,
@@ -94,15 +94,20 @@ export const KanbanBoardRoot = ({
94
94
  const { t } = useTranslation(meta.id);
95
95
  const model = useKanbanBoardModel(kanban, projection, items, registry);
96
96
  const columns = model?.getColumns?.() ?? [];
97
- const view = kanban?.view?.target;
97
+ const view = kanban?.spec.kind === 'view' ? kanban.spec.view.target : undefined;
98
98
  const pivotFieldId = view?.projection?.pivotFieldId;
99
99
  const columnFieldPath = useMemo(() => {
100
+ // Items-variant kanbans use the property name itself as the pivot field
101
+ // (no view/projection translation layer).
102
+ if (kanban?.spec.kind === 'items') {
103
+ return kanban.spec.pivotField;
104
+ }
100
105
  if (pivotFieldId === undefined || !projection) {
101
106
  return undefined;
102
107
  }
103
108
 
104
109
  return projection.tryGetFieldProjection(pivotFieldId)?.props.property;
105
- }, [projection, pivotFieldId]);
110
+ }, [kanban?.spec, projection, pivotFieldId]);
106
111
 
107
112
  const getPivotAttributes = useCallback<KanbanBoardContextValue['getPivotAttributes']>(
108
113
  (columnValue) => {
@@ -5,7 +5,7 @@
5
5
  import React, { forwardRef, useCallback, useMemo, useState } from 'react';
6
6
 
7
7
  import { Surface } from '@dxos/app-framework/ui';
8
- import { useObjectMenuItems } from '@dxos/app-toolkit/ui';
8
+ import { AppSurface, useObjectMenuItems } from '@dxos/app-toolkit/ui';
9
9
  import { Obj } from '@dxos/echo';
10
10
  import { Card, Toolbar, useTranslation } from '@dxos/react-ui';
11
11
  import { Menu, createMenuAction } from '@dxos/react-ui-menu';
@@ -26,7 +26,7 @@ export type KanbanCardProps = Pick<MosaicTileProps<Obj.Unknown>, 'location' | 'd
26
26
  export const KanbanCard = forwardRef<HTMLDivElement, KanbanCardProps>(({ data, location, debug }, forwardedRef) => {
27
27
  const { t } = useTranslation(meta.id);
28
28
  const { model } = useBoard(KANBAN_CARD_TILE_NAME);
29
- const { projection, onCardRemove } = useKanbanBoard(KANBAN_CARD_TILE_NAME);
29
+ const { projection, columnFieldPath, onCardRemove } = useKanbanBoard(KANBAN_CARD_TILE_NAME);
30
30
  const [dragHandle, setDragHandle] = useState<HTMLButtonElement | null>(null);
31
31
  const dragHandleRef = useCallback((el: HTMLButtonElement | null) => setDragHandle(el), []);
32
32
 
@@ -74,7 +74,19 @@ export const KanbanCard = forwardRef<HTMLDivElement, KanbanCardProps>(({ data, l
74
74
  <Menu.Content items={menuItems} />
75
75
  </Card.Toolbar>
76
76
  <Card.Content>
77
- {projection && <Surface.Surface role='card--content' limit={1} data={{ subject: data, projection }} />}
77
+ {projection && (
78
+ <Surface.Surface
79
+ type={AppSurface.Card}
80
+ limit={1}
81
+ data={{
82
+ subject: data,
83
+ projection,
84
+ // Hide the pivot field: its value is already conveyed by
85
+ // which column the card sits in.
86
+ ignorePaths: columnFieldPath ? [columnFieldPath] : undefined,
87
+ }}
88
+ />
89
+ )}
78
90
  </Card.Content>
79
91
  </Card.Root>
80
92
  </Focus.Item>
@@ -56,11 +56,13 @@ export const KanbanColumn = forwardRef<HTMLDivElement, KanbanColumnProps>(
56
56
  eventHandler={eventHandler}
57
57
  Tile={itemTile as FC<MosaicTileProps<Obj.Unknown>>}
58
58
  />
59
- {onCardAdd && (
60
- <Board.Column.Footer
61
- onAdd={() => onCardAdd(column.columnValue === UNCATEGORIZED_VALUE ? undefined : column.columnValue)}
62
- />
63
- )}
59
+ <Board.Column.Footer
60
+ onAdd={
61
+ onCardAdd
62
+ ? () => onCardAdd(column.columnValue === UNCATEGORIZED_VALUE ? undefined : column.columnValue)
63
+ : undefined
64
+ }
65
+ />
64
66
  </Board.Column.Root>
65
67
  );
66
68
  },
@@ -10,6 +10,7 @@ import { expect, waitFor, within } from 'storybook/test';
10
10
 
11
11
  import { withPluginManager } from '@dxos/app-framework/testing';
12
12
  import { Surface } from '@dxos/app-framework/ui';
13
+ import { AppSurface } from '@dxos/app-toolkit/ui';
13
14
  import { Obj, type QueryAST, Type } from '@dxos/echo';
14
15
  import { View } from '@dxos/echo';
15
16
  import { type Mutable } from '@dxos/echo/internal';
@@ -22,17 +23,17 @@ import { StorybookPlugin, corePlugins } from '@dxos/plugin-testing';
22
23
  import { random } from '@dxos/random';
23
24
  import { Filter, type Space, useQuery, useSchema, useSpaces } from '@dxos/react-client/echo';
24
25
  import { ViewEditor } from '@dxos/react-ui-form';
25
- import { Json } from '@dxos/react-ui-syntax-highlighter';
26
+ import { Syntax } from '@dxos/react-ui-syntax-highlighter';
26
27
  import { withLayout } from '@dxos/react-ui/testing';
27
28
  import { ViewModel, getTypenameFromQuery } from '@dxos/schema';
28
29
  // TODO(wittjosiah): Replace with echo/testing.
29
30
  import { Organization, Person } from '@dxos/types';
30
31
 
31
32
  import { useProjectionModel } from '#hooks';
33
+ import { translations } from '#translations';
32
34
  import { Kanban } from '#types';
33
35
 
34
36
  import { KanbanPlugin } from '../../KanbanPlugin';
35
- import { translations } from '../../translations';
36
37
 
37
38
  random.seed(0);
38
39
 
@@ -87,24 +88,26 @@ const DefaultComponent = () => {
87
88
  const spaces = useSpaces();
88
89
  const space = spaces[spaces.length - 1];
89
90
  const [kanban] = useQuery(space?.db, Filter.type(Kanban.Kanban));
90
- const typename = kanban?.view.target?.query ? getTypenameFromQuery(kanban.view.target.query.ast) : undefined;
91
+ const viewRef = kanban && kanban.spec.kind === 'view' ? kanban.spec.view : undefined;
92
+ const view = viewRef?.target;
93
+ const typename = view?.query ? getTypenameFromQuery(view.query.ast) : undefined;
91
94
  const schema = useSchema(space?.db, typename);
92
95
  const projection = useProjectionModel(schema, kanban, registry);
93
96
 
94
- const data = useMemo(() => (kanban ? { subject: kanban, attendableId: 'story' } : {}), [kanban]);
97
+ const data = useMemo(() => (kanban ? { subject: kanban, attendableId: 'story' } : undefined), [kanban]);
95
98
 
96
99
  const handleUpdateQuery = useCallback(
97
100
  (newQuery: QueryAST.Query) => {
98
101
  invariant(schema);
99
- invariant(kanban?.view.target);
102
+ invariant(view);
100
103
  if (Type.isMutable(schema)) {
101
104
  schema.updateTypename(getTypenameFromQuery(newQuery));
102
105
  }
103
- Obj.change(kanban.view.target, (view) => {
106
+ Obj.update(view, (view) => {
104
107
  view.query.ast = newQuery as Mutable<QueryAST.Query>;
105
108
  });
106
109
  },
107
- [kanban, schema],
110
+ [view, schema],
108
111
  );
109
112
 
110
113
  const handleDeleteField = useCallback(
@@ -116,27 +119,29 @@ const DefaultComponent = () => {
116
119
  [schema, projection],
117
120
  );
118
121
 
119
- if (!schema || !kanban?.view.target) {
122
+ if (!schema || !view) {
120
123
  return null;
121
124
  }
122
125
 
123
126
  return (
124
127
  <div className='grow grid grid-cols-[1fr_350px] overflow-hidden h-full w-full'>
125
- <Surface.Surface role='article' data={data} limit={1} />
128
+ <Surface.Surface type={AppSurface.Article} data={data} limit={1} />
126
129
  <div className='flex flex-col h-full overflow-hidden border-l border-separator'>
127
130
  <ViewEditor
128
131
  registry={space?.db.schemaRegistry}
129
132
  schema={schema}
130
- view={kanban.view.target}
133
+ view={view}
131
134
  onQueryChanged={handleUpdateQuery}
132
135
  onDelete={schema && Type.isMutable(schema) ? handleDeleteField : undefined}
133
136
  />
134
- <Json.Root data={{ view: kanban.view.target, schema }}>
135
- <Json.Content>
136
- <Json.Filter />
137
- <Json.Data classNames='text-xs' />
138
- </Json.Content>
139
- </Json.Root>
137
+ <Syntax.Root data={{ view, schema }}>
138
+ <Syntax.Content>
139
+ <Syntax.Filter />
140
+ <Syntax.Viewport>
141
+ <Syntax.Code classNames='text-xs' />
142
+ </Syntax.Viewport>
143
+ </Syntax.Content>
144
+ </Syntax.Root>
140
145
  </div>
141
146
  </div>
142
147
  );