@dxos/plugin-kanban 0.8.4-main.c85a9c8dae → 0.8.4-main.d9fc60f731

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 (285) hide show
  1. package/LICENSE +102 -5
  2. package/PLUGIN.mdl +398 -0
  3. package/README.md +1 -1
  4. package/dist/lib/neutral/KanbanArticle-V3UCZQB6.mjs +133 -0
  5. package/dist/lib/neutral/KanbanArticle-V3UCZQB6.mjs.map +7 -0
  6. package/dist/lib/neutral/KanbanPlugin.mjs +44 -0
  7. package/dist/lib/neutral/KanbanPlugin.mjs.map +7 -0
  8. package/dist/lib/neutral/KanbanPlugin.node.mjs +27 -0
  9. package/dist/lib/neutral/KanbanPlugin.node.mjs.map +7 -0
  10. package/dist/lib/neutral/KanbanPlugin.workerd.mjs +21 -0
  11. package/dist/lib/neutral/KanbanPlugin.workerd.mjs.map +7 -0
  12. package/dist/lib/{browser/KanbanViewEditor-IH5CJ6BW.mjs → neutral/KanbanSettings-Q2RJW4U4.mjs} +38 -21
  13. package/dist/lib/neutral/KanbanSettings-Q2RJW4U4.mjs.map +7 -0
  14. package/dist/lib/{browser/blueprint-definition-HFEKGFJK.mjs → neutral/blueprint-definition-FHVIEKTQ.mjs} +4 -6
  15. package/dist/lib/neutral/blueprint-definition-FHVIEKTQ.mjs.map +7 -0
  16. package/dist/lib/{browser → neutral}/blueprints/index.mjs +1 -1
  17. package/dist/lib/neutral/capabilities/index.mjs +17 -0
  18. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  19. package/dist/lib/neutral/chunk-6ZHHQWO5.mjs +39 -0
  20. package/dist/lib/neutral/chunk-6ZHHQWO5.mjs.map +7 -0
  21. package/dist/lib/neutral/chunk-PNGVV67W.mjs +246 -0
  22. package/dist/lib/neutral/chunk-PNGVV67W.mjs.map +7 -0
  23. package/dist/lib/neutral/chunk-UWUD7L3O.mjs +8 -0
  24. package/dist/lib/neutral/chunk-UWUD7L3O.mjs.map +7 -0
  25. package/dist/lib/{browser/chunk-TLYZSC7O.mjs → neutral/chunk-ZTQW5KQS.mjs} +3 -6
  26. package/dist/lib/neutral/chunk-ZTQW5KQS.mjs.map +7 -0
  27. package/dist/lib/{browser/KanbanContainer-BCXSJ6KS.mjs → neutral/components/index.mjs} +81 -142
  28. package/dist/lib/neutral/components/index.mjs.map +7 -0
  29. package/dist/lib/neutral/containers/index.mjs +11 -0
  30. package/dist/lib/neutral/containers/index.mjs.map +7 -0
  31. package/dist/lib/neutral/create-object-DKBSI46K.mjs +40 -0
  32. package/dist/lib/neutral/create-object-DKBSI46K.mjs.map +7 -0
  33. package/dist/lib/neutral/delete-card-4QF3TKXO.mjs +24 -0
  34. package/dist/lib/neutral/delete-card-4QF3TKXO.mjs.map +7 -0
  35. package/dist/lib/neutral/delete-card-field-5M4ZHKLO.mjs +39 -0
  36. package/dist/lib/neutral/delete-card-field-5M4ZHKLO.mjs.map +7 -0
  37. package/dist/lib/{node-esm/chunk-CSL3HF2X.mjs → neutral/hooks/index.mjs} +128 -82
  38. package/dist/lib/neutral/hooks/index.mjs.map +7 -0
  39. package/dist/lib/neutral/index.mjs +34 -0
  40. package/dist/lib/neutral/meta.json +1 -0
  41. package/dist/lib/neutral/meta.mjs +8 -0
  42. package/dist/lib/neutral/operation-handler-B7IW6MXU.mjs +13 -0
  43. package/dist/lib/neutral/operation-handler-B7IW6MXU.mjs.map +7 -0
  44. package/dist/lib/neutral/operations/index.mjs +8 -0
  45. package/dist/lib/neutral/plugin.mjs +16 -0
  46. package/dist/lib/neutral/plugin.mjs.map +7 -0
  47. package/dist/lib/{browser/react-surface-FOMOGFVW.mjs → neutral/react-surface-MROAQQQ6.mjs} +30 -38
  48. package/dist/lib/neutral/react-surface-MROAQQQ6.mjs.map +7 -0
  49. package/dist/lib/neutral/restore-card-5NI7HMIJ.mjs +21 -0
  50. package/dist/lib/neutral/restore-card-5NI7HMIJ.mjs.map +7 -0
  51. package/dist/lib/neutral/restore-card-field-QM2R67J5.mjs +37 -0
  52. package/dist/lib/neutral/restore-card-field-QM2R67J5.mjs.map +7 -0
  53. package/dist/lib/neutral/testing/index.mjs +62 -0
  54. package/dist/lib/neutral/testing/index.mjs.map +7 -0
  55. package/dist/lib/neutral/translations.mjs +44 -0
  56. package/dist/lib/neutral/translations.mjs.map +7 -0
  57. package/dist/lib/{browser → neutral}/types/index.mjs +7 -5
  58. package/dist/lib/neutral/undo-mappings-6CHW6BOF.mjs +42 -0
  59. package/dist/lib/neutral/undo-mappings-6CHW6BOF.mjs.map +7 -0
  60. package/dist/types/src/KanbanPlugin.d.ts +1 -0
  61. package/dist/types/src/KanbanPlugin.d.ts.map +1 -1
  62. package/dist/types/src/KanbanPlugin.node.d.ts +4 -0
  63. package/dist/types/src/KanbanPlugin.node.d.ts.map +1 -0
  64. package/dist/types/src/KanbanPlugin.test.d.ts +2 -0
  65. package/dist/types/src/KanbanPlugin.test.d.ts.map +1 -0
  66. package/dist/types/src/KanbanPlugin.workerd.d.ts +4 -0
  67. package/dist/types/src/KanbanPlugin.workerd.d.ts.map +1 -0
  68. package/dist/types/src/blueprints/kanban-blueprint.d.ts +2 -2
  69. package/dist/types/src/blueprints/kanban-blueprint.d.ts.map +1 -1
  70. package/dist/types/src/capabilities/artifact-definition.d.ts.map +1 -0
  71. package/dist/types/src/capabilities/blueprint-definition.d.ts +6 -0
  72. package/dist/types/src/capabilities/blueprint-definition.d.ts.map +1 -0
  73. package/dist/types/src/capabilities/create-object.d.ts +11 -0
  74. package/dist/types/src/capabilities/create-object.d.ts.map +1 -0
  75. package/dist/types/src/capabilities/index.d.ts +12 -3
  76. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  77. package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
  78. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  79. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  80. package/dist/types/src/capabilities/undo-mappings.d.ts +5 -0
  81. package/dist/types/src/capabilities/undo-mappings.d.ts.map +1 -0
  82. package/dist/types/src/components/KanbanBoard/KanbanBoard.d.ts +17 -38
  83. package/dist/types/src/components/KanbanBoard/KanbanBoard.d.ts.map +1 -1
  84. package/dist/types/src/components/KanbanBoard/KanbanBoard.stories.d.ts +48 -46
  85. package/dist/types/src/components/KanbanBoard/KanbanBoard.stories.d.ts.map +1 -1
  86. package/dist/types/src/components/KanbanBoard/KanbanCard.d.ts +2 -3
  87. package/dist/types/src/components/KanbanBoard/KanbanCard.d.ts.map +1 -1
  88. package/dist/types/src/components/KanbanBoard/KanbanColumn.d.ts +2 -3
  89. package/dist/types/src/components/KanbanBoard/KanbanColumn.d.ts.map +1 -1
  90. package/dist/types/src/components/KanbanBoard/context.d.ts +38 -0
  91. package/dist/types/src/components/KanbanBoard/context.d.ts.map +1 -0
  92. package/dist/types/src/containers/KanbanArticle/KanbanArticle.d.ts +6 -0
  93. package/dist/types/src/containers/KanbanArticle/KanbanArticle.d.ts.map +1 -0
  94. package/dist/types/src/containers/KanbanArticle/KanbanArticle.stories.d.ts +79 -0
  95. package/dist/types/src/containers/KanbanArticle/KanbanArticle.stories.d.ts.map +1 -0
  96. package/dist/types/src/containers/KanbanArticle/index.d.ts +2 -0
  97. package/dist/types/src/containers/KanbanArticle/index.d.ts.map +1 -0
  98. package/dist/types/src/containers/KanbanSettings/KanbanSettings.d.ts +13 -0
  99. package/dist/types/src/containers/KanbanSettings/KanbanSettings.d.ts.map +1 -0
  100. package/dist/types/src/containers/KanbanSettings/index.d.ts +2 -0
  101. package/dist/types/src/containers/KanbanSettings/index.d.ts.map +1 -0
  102. package/dist/types/src/containers/index.d.ts +2 -2
  103. package/dist/types/src/containers/index.d.ts.map +1 -1
  104. package/dist/types/src/hooks/index.d.ts +1 -0
  105. package/dist/types/src/hooks/index.d.ts.map +1 -1
  106. package/dist/types/src/hooks/useEchoChangeCallback.d.ts +1 -1
  107. package/dist/types/src/hooks/useEchoChangeCallback.d.ts.map +1 -1
  108. package/dist/types/src/hooks/useItemsProjection.d.ts +10 -0
  109. package/dist/types/src/hooks/useItemsProjection.d.ts.map +1 -0
  110. package/dist/types/src/hooks/useKanbanBoardModel.browser.test.d.ts +2 -0
  111. package/dist/types/src/hooks/useKanbanBoardModel.browser.test.d.ts.map +1 -0
  112. package/dist/types/src/hooks/useKanbanBoardModel.d.ts +1 -1
  113. package/dist/types/src/hooks/useKanbanBoardModel.d.ts.map +1 -1
  114. package/dist/types/src/hooks/useKanbanColumnEventHandler.d.ts +2 -2
  115. package/dist/types/src/hooks/useKanbanColumnEventHandler.d.ts.map +1 -1
  116. package/dist/types/src/hooks/useKanbanItemEventHandler.d.ts +2 -2
  117. package/dist/types/src/hooks/useKanbanItemEventHandler.d.ts.map +1 -1
  118. package/dist/types/src/hooks/useProjectionModel.d.ts +1 -1
  119. package/dist/types/src/hooks/useProjectionModel.d.ts.map +1 -1
  120. package/dist/types/src/index.d.ts +3 -1
  121. package/dist/types/src/index.d.ts.map +1 -1
  122. package/dist/types/src/meta.d.ts +1 -1
  123. package/dist/types/src/meta.d.ts.map +1 -1
  124. package/dist/types/src/operations/delete-card-field.d.ts +5 -0
  125. package/dist/types/src/operations/delete-card-field.d.ts.map +1 -0
  126. package/dist/types/src/operations/delete-card.d.ts +5 -0
  127. package/dist/types/src/operations/delete-card.d.ts.map +1 -0
  128. package/dist/types/src/operations/index.d.ts +3 -0
  129. package/dist/types/src/operations/index.d.ts.map +1 -0
  130. package/dist/types/src/operations/restore-card-field.d.ts +5 -0
  131. package/dist/types/src/operations/restore-card-field.d.ts.map +1 -0
  132. package/dist/types/src/operations/restore-card.d.ts +5 -0
  133. package/dist/types/src/operations/restore-card.d.ts.map +1 -0
  134. package/dist/types/src/playwright/board-manager.d.ts.map +1 -1
  135. package/dist/types/src/playwright/playwright.config.d.ts.map +1 -1
  136. package/dist/types/src/plugin.d.ts +4 -0
  137. package/dist/types/src/plugin.d.ts.map +1 -0
  138. package/dist/types/src/testing/KanbanCardTileSimple.d.ts +4 -2
  139. package/dist/types/src/testing/KanbanCardTileSimple.d.ts.map +1 -1
  140. package/dist/types/src/translations.d.ts +48 -46
  141. package/dist/types/src/translations.d.ts.map +1 -1
  142. package/dist/types/src/types/Kanban.d.ts +66 -9
  143. package/dist/types/src/types/Kanban.d.ts.map +1 -1
  144. package/dist/types/src/types/KanbanOperation.d.ts +52 -0
  145. package/dist/types/src/types/KanbanOperation.d.ts.map +1 -0
  146. package/dist/types/src/types/constants.d.ts +3 -3
  147. package/dist/types/src/types/constants.d.ts.map +1 -1
  148. package/dist/types/src/types/index.d.ts +2 -1
  149. package/dist/types/src/types/index.d.ts.map +1 -1
  150. package/dist/types/src/types/schema.d.ts +15 -104
  151. package/dist/types/src/types/schema.d.ts.map +1 -1
  152. package/dist/types/src/types/types.d.ts +2 -2
  153. package/dist/types/src/util/arrangement.d.ts +8 -4
  154. package/dist/types/src/util/arrangement.d.ts.map +1 -1
  155. package/dist/types/tsconfig.tsbuildinfo +1 -1
  156. package/package.json +115 -63
  157. package/src/KanbanPlugin.node.ts +21 -0
  158. package/src/KanbanPlugin.test.ts +31 -0
  159. package/src/KanbanPlugin.tsx +15 -29
  160. package/src/KanbanPlugin.workerd.ts +18 -0
  161. package/src/blueprints/kanban-blueprint.ts +4 -8
  162. package/src/capabilities/{artifact-definition/artifact-definition.ts → artifact-definition.ts} +12 -11
  163. package/src/capabilities/{blueprint-definition/blueprint-definition.ts → blueprint-definition.ts} +3 -1
  164. package/src/capabilities/create-object.ts +40 -0
  165. package/src/capabilities/index.ts +12 -3
  166. package/src/capabilities/operation-handler.ts +14 -0
  167. package/src/capabilities/{react-surface/react-surface.tsx → react-surface.tsx} +35 -19
  168. package/src/capabilities/undo-mappings.ts +34 -0
  169. package/src/components/KanbanBoard/KanbanBoard.stories.tsx +22 -19
  170. package/src/components/KanbanBoard/KanbanBoard.tsx +43 -63
  171. package/src/components/KanbanBoard/KanbanCard.tsx +77 -63
  172. package/src/components/KanbanBoard/KanbanColumn.tsx +19 -16
  173. package/src/components/KanbanBoard/context.ts +54 -0
  174. package/src/containers/{KanbanContainer/KanbanContainer.stories.tsx → KanbanArticle/KanbanArticle.stories.tsx} +67 -53
  175. package/src/containers/KanbanArticle/KanbanArticle.tsx +180 -0
  176. package/src/containers/KanbanArticle/index.ts +5 -0
  177. package/src/containers/KanbanSettings/KanbanSettings.tsx +94 -0
  178. package/src/containers/KanbanSettings/index.ts +5 -0
  179. package/src/containers/index.ts +2 -2
  180. package/src/hooks/index.ts +1 -0
  181. package/src/hooks/useEchoChangeCallback.ts +3 -3
  182. package/src/hooks/useItemsProjection.ts +44 -0
  183. package/src/hooks/{useKanbanBoardModel.test.ts → useKanbanBoardModel.browser.test.ts} +13 -19
  184. package/src/hooks/useKanbanBoardModel.ts +20 -6
  185. package/src/hooks/useKanbanColumnEventHandler.ts +1 -1
  186. package/src/hooks/useKanbanItemEventHandler.ts +1 -1
  187. package/src/hooks/useProjectionModel.ts +5 -5
  188. package/src/index.ts +3 -2
  189. package/src/meta.ts +22 -5
  190. package/src/operations/delete-card-field.ts +42 -0
  191. package/src/operations/delete-card.ts +23 -0
  192. package/src/operations/index.ts +10 -0
  193. package/src/operations/restore-card-field.ts +36 -0
  194. package/src/operations/restore-card.ts +21 -0
  195. package/src/playwright/smoke.spec.ts +3 -3
  196. package/src/plugin.ts +11 -0
  197. package/src/testing/KanbanCardTileSimple.tsx +29 -23
  198. package/src/translations.ts +26 -25
  199. package/src/types/Kanban.ts +85 -18
  200. package/src/types/KanbanOperation.ts +79 -0
  201. package/src/types/index.ts +3 -1
  202. package/src/types/schema.ts +20 -78
  203. package/src/types/types.ts +2 -2
  204. package/src/util/arrangement.test.ts +23 -14
  205. package/src/util/arrangement.ts +25 -15
  206. package/src/vite-env.d.ts +10 -0
  207. package/dist/lib/browser/KanbanContainer-BCXSJ6KS.mjs.map +0 -7
  208. package/dist/lib/browser/KanbanViewEditor-IH5CJ6BW.mjs.map +0 -7
  209. package/dist/lib/browser/blueprint-definition-HFEKGFJK.mjs.map +0 -7
  210. package/dist/lib/browser/chunk-QSWCFMEB.mjs +0 -385
  211. package/dist/lib/browser/chunk-QSWCFMEB.mjs.map +0 -7
  212. package/dist/lib/browser/chunk-RNFIFE2P.mjs +0 -213
  213. package/dist/lib/browser/chunk-RNFIFE2P.mjs.map +0 -7
  214. package/dist/lib/browser/chunk-TLYZSC7O.mjs.map +0 -7
  215. package/dist/lib/browser/index.mjs +0 -101
  216. package/dist/lib/browser/index.mjs.map +0 -7
  217. package/dist/lib/browser/meta.json +0 -1
  218. package/dist/lib/browser/operation-resolver-BRA2OHUE.mjs +0 -162
  219. package/dist/lib/browser/operation-resolver-BRA2OHUE.mjs.map +0 -7
  220. package/dist/lib/browser/react-surface-FOMOGFVW.mjs.map +0 -7
  221. package/dist/lib/node-esm/KanbanContainer-EHRTLE7M.mjs +0 -305
  222. package/dist/lib/node-esm/KanbanContainer-EHRTLE7M.mjs.map +0 -7
  223. package/dist/lib/node-esm/KanbanViewEditor-WDACFC35.mjs +0 -67
  224. package/dist/lib/node-esm/KanbanViewEditor-WDACFC35.mjs.map +0 -7
  225. package/dist/lib/node-esm/blueprint-definition-NARBX32U.mjs +0 -18
  226. package/dist/lib/node-esm/blueprint-definition-NARBX32U.mjs.map +0 -7
  227. package/dist/lib/node-esm/blueprints/index.mjs +0 -9
  228. package/dist/lib/node-esm/chunk-4AWDHQVY.mjs +0 -214
  229. package/dist/lib/node-esm/chunk-4AWDHQVY.mjs.map +0 -7
  230. package/dist/lib/node-esm/chunk-CSL3HF2X.mjs.map +0 -7
  231. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +0 -11
  232. package/dist/lib/node-esm/chunk-X3UJUQIV.mjs +0 -31
  233. package/dist/lib/node-esm/chunk-X3UJUQIV.mjs.map +0 -7
  234. package/dist/lib/node-esm/index.mjs +0 -102
  235. package/dist/lib/node-esm/index.mjs.map +0 -7
  236. package/dist/lib/node-esm/meta.json +0 -1
  237. package/dist/lib/node-esm/operation-resolver-UEQ64LCN.mjs +0 -163
  238. package/dist/lib/node-esm/operation-resolver-UEQ64LCN.mjs.map +0 -7
  239. package/dist/lib/node-esm/react-surface-AITKFRBE.mjs +0 -100
  240. package/dist/lib/node-esm/react-surface-AITKFRBE.mjs.map +0 -7
  241. package/dist/lib/node-esm/types/index.mjs +0 -21
  242. package/dist/types/src/capabilities/artifact-definition/artifact-definition.d.ts.map +0 -1
  243. package/dist/types/src/capabilities/artifact-definition/index.d.ts +0 -3
  244. package/dist/types/src/capabilities/artifact-definition/index.d.ts.map +0 -1
  245. package/dist/types/src/capabilities/blueprint-definition/blueprint-definition.d.ts +0 -6
  246. package/dist/types/src/capabilities/blueprint-definition/blueprint-definition.d.ts.map +0 -1
  247. package/dist/types/src/capabilities/blueprint-definition/index.d.ts +0 -3
  248. package/dist/types/src/capabilities/blueprint-definition/index.d.ts.map +0 -1
  249. package/dist/types/src/capabilities/operation-resolver/index.d.ts +0 -3
  250. package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +0 -1
  251. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +0 -5
  252. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +0 -1
  253. package/dist/types/src/capabilities/react-surface/index.d.ts +0 -3
  254. package/dist/types/src/capabilities/react-surface/index.d.ts.map +0 -1
  255. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +0 -1
  256. package/dist/types/src/containers/KanbanContainer/KanbanContainer.d.ts +0 -6
  257. package/dist/types/src/containers/KanbanContainer/KanbanContainer.d.ts.map +0 -1
  258. package/dist/types/src/containers/KanbanContainer/KanbanContainer.stories.d.ts +0 -77
  259. package/dist/types/src/containers/KanbanContainer/KanbanContainer.stories.d.ts.map +0 -1
  260. package/dist/types/src/containers/KanbanContainer/index.d.ts +0 -3
  261. package/dist/types/src/containers/KanbanContainer/index.d.ts.map +0 -1
  262. package/dist/types/src/containers/KanbanViewEditor/KanbanViewEditor.d.ts +0 -6
  263. package/dist/types/src/containers/KanbanViewEditor/KanbanViewEditor.d.ts.map +0 -1
  264. package/dist/types/src/containers/KanbanViewEditor/index.d.ts +0 -3
  265. package/dist/types/src/containers/KanbanViewEditor/index.d.ts.map +0 -1
  266. package/dist/types/src/hooks/useKanbanBoardModel.test.d.ts +0 -2
  267. package/dist/types/src/hooks/useKanbanBoardModel.test.d.ts.map +0 -1
  268. package/src/capabilities/artifact-definition/index.ts +0 -7
  269. package/src/capabilities/blueprint-definition/index.ts +0 -7
  270. package/src/capabilities/operation-resolver/index.ts +0 -7
  271. package/src/capabilities/operation-resolver/operation-resolver.ts +0 -133
  272. package/src/capabilities/react-surface/index.ts +0 -7
  273. package/src/containers/KanbanContainer/KanbanContainer.tsx +0 -87
  274. package/src/containers/KanbanContainer/index.ts +0 -7
  275. package/src/containers/KanbanViewEditor/KanbanViewEditor.tsx +0 -63
  276. package/src/containers/KanbanViewEditor/index.ts +0 -7
  277. /package/dist/lib/{browser → neutral}/blueprints/index.mjs.map +0 -0
  278. /package/dist/lib/{browser → neutral}/chunk-J5LGTIGS.mjs +0 -0
  279. /package/dist/lib/{browser → neutral}/chunk-J5LGTIGS.mjs.map +0 -0
  280. /package/dist/lib/{browser/types → neutral}/index.mjs.map +0 -0
  281. /package/dist/lib/{node-esm/blueprints/index.mjs.map → neutral/meta.mjs.map} +0 -0
  282. /package/dist/lib/{node-esm/types → neutral/operations}/index.mjs.map +0 -0
  283. /package/dist/lib/{node-esm/chunk-HSLMI22Q.mjs.map → neutral/types/index.mjs.map} +0 -0
  284. /package/dist/types/src/capabilities/{artifact-definition/artifact-definition.d.ts → artifact-definition.d.ts} +0 -0
  285. /package/dist/types/src/capabilities/{react-surface/react-surface.d.ts → react-surface.d.ts} +0 -0
@@ -7,13 +7,12 @@ import { act, renderHook } from '@testing-library/react';
7
7
  import * as Schema from 'effect/Schema';
8
8
  import { beforeEach, describe, test } from 'vitest';
9
9
 
10
- import { Filter, JsonSchema, Obj, Query, Type } from '@dxos/echo';
11
- import { type View } from '@dxos/echo';
10
+ import { DXN, Filter, JsonSchema, Obj, Query, Type, type View } from '@dxos/echo';
12
11
  import { Format, FormatAnnotation, PropertyMetaAnnotationId } from '@dxos/echo/internal';
13
- import { ObjectId } from '@dxos/keys';
12
+ import { EntityId } from '@dxos/keys';
14
13
  import { ProjectionModel, ViewModel, createDirectChangeCallback } from '@dxos/schema';
15
14
 
16
- import { Kanban } from '../types';
15
+ import { Kanban } from '#types';
17
16
 
18
17
  import { useKanbanBoardModel } from './useKanbanBoardModel';
19
18
 
@@ -36,14 +35,9 @@ const KanbanTaskSchema = Schema.Struct({
36
35
  }),
37
36
  Schema.optional,
38
37
  ),
39
- }).pipe(
40
- Type.object({
41
- typename: 'example.com/type/KanbanTask',
42
- version: '0.1.0',
43
- }),
44
- );
38
+ }).pipe(Type.makeObject(DXN.make('com.example.type.kanbanTask', '0.1.0')));
45
39
 
46
- type KanbanTask = Schema.Schema.Type<typeof KanbanTaskSchema>;
40
+ type KanbanTask = Type.InstanceType<typeof KanbanTaskSchema>;
47
41
 
48
42
  describe('useKanbanBoardModel', () => {
49
43
  let registry: Registry.Registry;
@@ -146,7 +140,7 @@ describe('useKanbanBoardModel', () => {
146
140
  expect(orderBefore).toEqual(['__uncategorized__', 'a', 'b']);
147
141
 
148
142
  act(() => {
149
- Obj.change(kanban, (kanban) => {
143
+ Obj.update(kanban, (kanban) => {
150
144
  kanban.arrangement.order = ['b', 'a'];
151
145
  });
152
146
  });
@@ -160,15 +154,15 @@ describe('useKanbanBoardModel', () => {
160
154
 
161
155
  test('getItems returns items in column ordered by arrangement ids', ({ expect }) => {
162
156
  const item1 = Obj.make(KanbanTaskSchema, {
163
- id: ObjectId.random(),
157
+ id: EntityId.random(),
164
158
  status: 'a',
165
159
  });
166
160
  const item2 = Obj.make(KanbanTaskSchema, {
167
- id: ObjectId.random(),
161
+ id: EntityId.random(),
168
162
  status: 'a',
169
163
  });
170
164
  const item3 = Obj.make(KanbanTaskSchema, {
171
- id: ObjectId.random(),
165
+ id: EntityId.random(),
172
166
  status: 'a',
173
167
  });
174
168
  const items: KanbanTask[] = [item1, item2, item3];
@@ -187,7 +181,7 @@ describe('useKanbanBoardModel', () => {
187
181
  });
188
182
 
189
183
  act(() => {
190
- Obj.change(kanban, (kanban) => {
184
+ Obj.update(kanban, (kanban) => {
191
185
  kanban.arrangement.columns['a'] = {
192
186
  ids: [item3.id, item1.id, item2.id],
193
187
  };
@@ -201,11 +195,11 @@ describe('useKanbanBoardModel', () => {
201
195
 
202
196
  test('subscribing to one column items atom does not fire when another column changes', ({ expect }) => {
203
197
  const itemA = Obj.make(KanbanTaskSchema, {
204
- id: ObjectId.random(),
198
+ id: EntityId.random(),
205
199
  status: 'a',
206
200
  });
207
201
  const itemB = Obj.make(KanbanTaskSchema, {
208
- id: ObjectId.random(),
202
+ id: EntityId.random(),
209
203
  status: 'b',
210
204
  });
211
205
  const items: KanbanTask[] = [itemA, itemB];
@@ -225,7 +219,7 @@ describe('useKanbanBoardModel', () => {
225
219
  });
226
220
 
227
221
  act(() => {
228
- Obj.change(kanban, (kanban) => {
222
+ Obj.update(kanban, (kanban) => {
229
223
  kanban.arrangement.columns['b'] = { ids: [itemB.id] };
230
224
  });
231
225
  });
@@ -10,7 +10,8 @@ import { AtomObj } from '@dxos/echo-atom';
10
10
  import type { BoardModel } from '@dxos/react-ui-mosaic';
11
11
  import type { ProjectionModel } from '@dxos/schema';
12
12
 
13
- import { type BaseKanbanItem, type ColumnStructure, type Kanban } from '../types';
13
+ import { type BaseKanbanItem, type ColumnStructure, type Kanban } from '#types';
14
+
14
15
  import {
15
16
  computeColumnStructure,
16
17
  getOrderByColumnFromArrangement,
@@ -37,14 +38,27 @@ export function useKanbanBoardModel<T extends BaseKanbanItem = BaseKanbanItem>(
37
38
  // Source atoms: reactive reads from the kanban object; items come from the passed-in atom (e.g. AtomQuery or in-memory).
38
39
  const arrangementAtom = useMemo(() => AtomObj.makeProperty(kanban, 'arrangement'), [kanban]);
39
40
  const viewSnapshotAtom = useMemo(
40
- () => (kanban?.view ? AtomObj.make(kanban.view) : Atom.make<undefined>(() => undefined)),
41
- [kanban?.view],
41
+ () =>
42
+ kanban?.spec?.kind === 'view' && kanban.spec.view
43
+ ? AtomObj.make(kanban.spec.view)
44
+ : Atom.make<undefined>(() => undefined),
45
+ [kanban?.spec],
42
46
  );
43
47
 
44
- /** Only changes when view.projection.pivotFieldId changes; keeps columns from firing on other view updates. */
48
+ /**
49
+ * Only changes when the discriminator-relevant pivot input changes.
50
+ * View-variant: derived from `view.projection.pivotFieldId`.
51
+ * Items-variant: the kanban's `spec.pivotField` (the property name itself acts as the field id).
52
+ */
45
53
  const pivotFieldIdAtom = useMemo(
46
- () => Atom.make((get) => get(viewSnapshotAtom)?.projection?.pivotFieldId as string | undefined),
47
- [viewSnapshotAtom],
54
+ () =>
55
+ Atom.make((get) => {
56
+ if (kanban?.spec.kind === 'items') {
57
+ return kanban.spec.pivotField;
58
+ }
59
+ return get(viewSnapshotAtom)?.projection?.pivotFieldId as string | undefined;
60
+ }),
61
+ [kanban?.spec, viewSnapshotAtom],
48
62
  );
49
63
 
50
64
  // Effective per-column ids: from kanban.arrangement.columns; empty when arrangement has no columns.
@@ -8,7 +8,7 @@ import type { BoardModel, MosaicEventHandler, MosaicTileData } from '@dxos/react
8
8
  import type { ProjectionModel } from '@dxos/schema';
9
9
  import { arrayMove } from '@dxos/util';
10
10
 
11
- import { type BaseKanbanItem, type ColumnStructure, type KanbanChangeCallback, UNCATEGORIZED_VALUE } from '../types';
11
+ import { type BaseKanbanItem, type ColumnStructure, type KanbanChangeCallback, UNCATEGORIZED_VALUE } from '#types';
12
12
 
13
13
  /**
14
14
  * Builds the column drag-and-drop handler for the kanban board (reorder columns).
@@ -12,7 +12,7 @@ import {
12
12
  type ColumnStructure,
13
13
  type KanbanChangeCallback,
14
14
  UNCATEGORIZED_VALUE,
15
- } from '../types';
15
+ } from '#types';
16
16
 
17
17
  function findColumn<T extends BaseKanbanItem>(
18
18
  id: string,
@@ -10,7 +10,7 @@ import { log } from '@dxos/log';
10
10
  import { useAsyncEffect } from '@dxos/react-ui';
11
11
  import { ProjectionModel, createEchoChangeCallback } from '@dxos/schema';
12
12
 
13
- import { type Kanban } from '../types';
13
+ import { type Kanban } from '#types';
14
14
 
15
15
  /**
16
16
  * Loads the kanban view and builds a ProjectionModel for field projections and pivot.
@@ -30,17 +30,17 @@ export const useProjectionModel = <S extends Type.AnyEntity>(
30
30
 
31
31
  useAsyncEffect(
32
32
  async (controller) => {
33
- if (!schema || !kanban) {
33
+ if (!schema || !kanban || kanban.spec.kind !== 'view') {
34
34
  return;
35
35
  }
36
36
  try {
37
- const view = await kanban.view.load();
37
+ const view = await kanban.spec.view.load();
38
38
  if (controller.signal.aborted) {
39
39
  return;
40
40
  }
41
41
 
42
- const jsonSchema = Type.isMutable(schema) ? schema.jsonSchema : JsonSchema.toJsonSchema(schema);
43
- const change = createEchoChangeCallback(view, Type.isMutable(schema) ? schema : undefined);
42
+ const jsonSchema = Type.getDatabase(schema) != null ? schema.jsonSchema : JsonSchema.toJsonSchema(schema);
43
+ const change = createEchoChangeCallback(view, Type.getDatabase(schema) != null ? schema : undefined);
44
44
 
45
45
  const projection = new ProjectionModel({ registry, view, baseSchema: jsonSchema, change });
46
46
  projection.normalizeView();
package/src/index.ts CHANGED
@@ -2,6 +2,7 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
+ export * from './blueprints';
5
6
  export * from './meta';
6
-
7
- export * from './KanbanPlugin';
7
+ export * from './operations';
8
+ export * from './types';
package/src/meta.ts CHANGED
@@ -2,18 +2,35 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { type Plugin } from '@dxos/app-framework';
5
+ import { Plugin } from '@dxos/app-framework';
6
+ import { DXN } from '@dxos/echo';
6
7
  import { trim } from '@dxos/util';
7
8
 
8
- export const meta: Plugin.Meta = {
9
- id: 'dxos.org/plugin/kanban',
9
+ export const meta = Plugin.makeMeta({
10
+ key: DXN.make('org.dxos.plugin.kanban'),
10
11
  name: 'Kanban',
12
+ author: 'DXOS',
11
13
  description: trim`
12
14
  Visual project management using customizable kanban boards to track workflow progress.
13
- Organize table data into columns, drag and drop items between stages, and trigger automations based on status changes.
15
+ Organize any ECHO type into drag-and-drop columns defined by a single-select field, move cards
16
+ between stages, and reorder both columns and cards — all changes are persisted to ECHO and
17
+ replicated to collaborators in real time.
18
+
19
+ Kanban boards come in two variants: view-variant boards source their cards through a linked
20
+ View query (any ECHO type can be pivoted on a single-select field), while items-variant boards
21
+ own their cards explicitly and are used by external sync integrations such as Linear or GitHub.
22
+ Both variants share the same arrangement storage and drag-and-drop mechanics.
23
+
24
+ Board settings let users choose which single-select field drives the column layout and
25
+ optionally hide the uncategorized column for items that have no pivot value.
26
+ Field-level undo support allows deleted card fields to be restored without data loss.
27
+
28
+ The plugin contributes a Kanban blueprint that exposes board creation and card management
29
+ to AI agents, enabling automated project tracking workflows.
14
30
  `,
15
31
  icon: 'ph--kanban--regular',
16
32
  iconHue: 'green',
17
33
  source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-kanban',
34
+ spec: 'PLUGIN.mdl',
18
35
  screenshots: ['https://dxos.network/plugin-details-kanban-dark.png'],
19
- };
36
+ });
@@ -0,0 +1,42 @@
1
+ // Copyright 2025 DXOS.org
2
+
3
+ import * as Effect from 'effect/Effect';
4
+
5
+ import { Capabilities, Capability } from '@dxos/app-framework';
6
+ import { Operation } from '@dxos/compute';
7
+ import { Obj, Type } from '@dxos/echo';
8
+ import { invariant } from '@dxos/invariant';
9
+ import { ProjectionModel, createEchoChangeCallback, getTypenameFromQuery } from '@dxos/schema';
10
+
11
+ import { KanbanOperation } from '../types';
12
+
13
+ const handler: Operation.WithHandler<typeof KanbanOperation.DeleteCardField> = KanbanOperation.DeleteCardField.pipe(
14
+ Operation.withHandler(
15
+ Effect.fnUntraced(function* ({ view, fieldId }) {
16
+ const registry = yield* Capability.get(Capabilities.AtomRegistry);
17
+ const db = Obj.getDatabase(view);
18
+ invariant(db, 'Database not found');
19
+ const types = yield* Effect.sync(() => db.graph.registry.list().filter(Type.isType));
20
+ const schema = types.find((t) => Type.getTypename(t) === getTypenameFromQuery(view.query.ast));
21
+ invariant(schema, 'Schema not found');
22
+
23
+ invariant(Type.isType(schema), 'expected stored Type.Type for card schema');
24
+ const projection = new ProjectionModel({
25
+ registry,
26
+ view,
27
+ baseSchema: schema.jsonSchema,
28
+ change: createEchoChangeCallback(view, schema),
29
+ });
30
+
31
+ const result = projection.deleteFieldProjection(fieldId);
32
+
33
+ return {
34
+ field: result.deleted.field,
35
+ props: result.deleted.props,
36
+ index: result.index,
37
+ };
38
+ }),
39
+ ),
40
+ );
41
+
42
+ export default handler;
@@ -0,0 +1,23 @@
1
+ // Copyright 2025 DXOS.org
2
+
3
+ import * as Effect from 'effect/Effect';
4
+
5
+ import { Operation } from '@dxos/compute';
6
+ import { Obj } from '@dxos/echo';
7
+ import { invariant } from '@dxos/invariant';
8
+
9
+ import { KanbanOperation } from '../types';
10
+
11
+ const handler: Operation.WithHandler<typeof KanbanOperation.DeleteCard> = KanbanOperation.DeleteCard.pipe(
12
+ Operation.withHandler(({ card }) =>
13
+ Effect.sync(() => {
14
+ const db = Obj.getDatabase(card);
15
+ invariant(db);
16
+ db.remove(card);
17
+
18
+ return { card };
19
+ }),
20
+ ),
21
+ );
22
+
23
+ export default handler;
@@ -0,0 +1,10 @@
1
+ // Copyright 2025 DXOS.org
2
+
3
+ import { OperationHandlerSet } from '@dxos/compute';
4
+
5
+ export const KanbanOperationHandlerSet = OperationHandlerSet.lazy(
6
+ () => import('./delete-card'),
7
+ () => import('./delete-card-field'),
8
+ () => import('./restore-card'),
9
+ () => import('./restore-card-field'),
10
+ );
@@ -0,0 +1,36 @@
1
+ // Copyright 2025 DXOS.org
2
+
3
+ import * as Effect from 'effect/Effect';
4
+
5
+ import { Capabilities, Capability } from '@dxos/app-framework';
6
+ import { Operation } from '@dxos/compute';
7
+ import { Obj, Type } from '@dxos/echo';
8
+ import { invariant } from '@dxos/invariant';
9
+ import { ProjectionModel, createEchoChangeCallback, getTypenameFromQuery } from '@dxos/schema';
10
+
11
+ import { KanbanOperation } from '../types';
12
+
13
+ const handler: Operation.WithHandler<typeof KanbanOperation.RestoreCardField> = KanbanOperation.RestoreCardField.pipe(
14
+ Operation.withHandler(
15
+ Effect.fnUntraced(function* ({ view, field, props, index }) {
16
+ const registry = yield* Capability.get(Capabilities.AtomRegistry);
17
+ const db = Obj.getDatabase(view);
18
+ invariant(db, 'Database not found');
19
+ const types = db.graph.registry.list().filter(Type.isType);
20
+ const type = types.find((t) => Type.getTypename(t) === getTypenameFromQuery(view.query.ast));
21
+ invariant(type, 'Schema not found');
22
+
23
+ invariant(Type.isType(type), 'expected stored Type.Type for card schema');
24
+ const projection = new ProjectionModel({
25
+ registry,
26
+ view,
27
+ baseSchema: type.jsonSchema,
28
+ change: createEchoChangeCallback(view, type),
29
+ });
30
+
31
+ projection.setFieldProjection({ field, props }, index);
32
+ }),
33
+ ),
34
+ );
35
+
36
+ export default handler;
@@ -0,0 +1,21 @@
1
+ // Copyright 2025 DXOS.org
2
+
3
+ import * as Effect from 'effect/Effect';
4
+
5
+ import { Operation } from '@dxos/compute';
6
+ import { Obj } from '@dxos/echo';
7
+ import { invariant } from '@dxos/invariant';
8
+
9
+ import { KanbanOperation } from '../types';
10
+
11
+ const handler: Operation.WithHandler<typeof KanbanOperation.RestoreCard> = KanbanOperation.RestoreCard.pipe(
12
+ Operation.withHandler(({ card }) =>
13
+ Effect.sync(() => {
14
+ const db = Obj.getDatabase(card);
15
+ invariant(db);
16
+ db.add(card);
17
+ }),
18
+ ),
19
+ );
20
+
21
+ export default handler;
@@ -49,7 +49,7 @@ test.describe('Kanban MutableSchema', () => {
49
49
  expect(secondLabel).not.toBeNull();
50
50
 
51
51
  // Drag first item below the second item.
52
- await column.item(0).dragTo(column.item(1).locator, { x: 0, y: 200 });
52
+ await column.item(0).dragTo(column.item(1).locator, { x: 0, y: 200 }, 'bottom');
53
53
 
54
54
  // Item count should stay the same.
55
55
  await expect(column.items()).toHaveCount(countBefore);
@@ -71,8 +71,8 @@ test.describe('Kanban MutableSchema', () => {
71
71
  const draggedLabel = await col1.item(0).title().textContent();
72
72
  expect(draggedLabel).not.toBeNull();
73
73
 
74
- // Drop above first item. Kanban cards are taller; use larger negative y so we land in top half.
75
- await col1.item(0).dragTo(col2.item(0).locator, { x: 0, y: -30 });
74
+ // Drop above first item.
75
+ await col1.item(0).dragTo(col2.item(0).locator, { x: 0, y: -30 }, 'top');
76
76
 
77
77
  await expect(col1.items()).toHaveCount(col1CountBefore - 1);
78
78
  await expect(col2.items()).toHaveCount(col2CountBefore + 1);
package/src/plugin.ts ADDED
@@ -0,0 +1,11 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { Plugin } from '@dxos/app-framework';
6
+
7
+ import { meta } from './meta';
8
+
9
+ export const KanbanPlugin = Plugin.lazy(meta, () => import('#plugin'));
10
+
11
+ export { KanbanOperationHandlerSet } from './operations';
@@ -9,12 +9,14 @@ import { Card, Toolbar, useTranslation } from '@dxos/react-ui';
9
9
  import { Menu, createMenuAction } from '@dxos/react-ui-menu';
10
10
  import { Focus, Mosaic, useBoard } from '@dxos/react-ui-mosaic';
11
11
 
12
- import { type KanbanCardProps, useKanbanBoard } from '../components';
13
- import { meta } from '../meta';
12
+ import { type KanbanCardProps, useKanbanBoard } from '#components';
13
+ import { meta } from '#meta';
14
14
 
15
15
  const KANBAN_CARD_TILE_SIMPLE_NAME = 'KanbanCardTileSimple';
16
16
 
17
- /** Card tile without Surface; for stories and tests when plugin manager is not available. */
17
+ /**
18
+ * Card tile without Surface; for stories and tests when plugin manager is not available.
19
+ */
18
20
  export const KanbanCardTileSimple = forwardRef<HTMLDivElement, KanbanCardProps>(
19
21
  ({ data, location, debug }, forwardedRef) => {
20
22
  const { t } = useTranslation(meta.id);
@@ -28,7 +30,7 @@ export const KanbanCardTileSimple = forwardRef<HTMLDivElement, KanbanCardProps>(
28
30
  onCardRemove
29
31
  ? [
30
32
  createMenuAction('remove', () => onCardRemove(data), {
31
- label: t('remove card label'),
33
+ label: t('remove-card.label'),
32
34
  icon: 'ph--trash--regular',
33
35
  }),
34
36
  ]
@@ -37,18 +39,18 @@ export const KanbanCardTileSimple = forwardRef<HTMLDivElement, KanbanCardProps>(
37
39
  );
38
40
 
39
41
  return (
40
- <Mosaic.Tile
41
- asChild
42
- id={model.getItemId(data)}
43
- data={data}
44
- location={location}
45
- debug={debug}
46
- dragHandle={dragHandle}
47
- >
48
- <Focus.Group asChild>
49
- <Menu.Root>
42
+ <Menu.Root>
43
+ <Mosaic.Tile
44
+ asChild
45
+ id={model.getItemId(data)}
46
+ data={data}
47
+ location={location}
48
+ debug={debug}
49
+ dragHandle={dragHandle}
50
+ >
51
+ <Focus.Item asChild>
50
52
  <Card.Root ref={forwardedRef} data-testid='board-item'>
51
- <Card.Toolbar>
53
+ <Card.Header>
52
54
  <Card.DragHandle ref={dragHandleRef} />
53
55
  <Card.Title>{Obj.getLabel(data)}</Card.Title>
54
56
  {/* TODO(wittjosiah): Reconcile with Card.Menu. */}
@@ -57,18 +59,22 @@ export const KanbanCardTileSimple = forwardRef<HTMLDivElement, KanbanCardProps>(
57
59
  iconOnly
58
60
  variant='ghost'
59
61
  icon='ph--dots-three-vertical--regular'
60
- label={t('action menu label')}
62
+ label={t('action-menu.label')}
61
63
  />
62
64
  </Menu.Trigger>
63
65
  <Menu.Content items={menuItems} />
64
- </Card.Toolbar>
65
- <Card.Content>
66
- <div className='p-2 text-sm text-fg'>{Obj.getLabel(data)}</div>
67
- </Card.Content>
66
+ </Card.Header>
67
+ <Card.Body>
68
+ <Card.Row fullWidth>
69
+ <pre className='p-2 text-xs text-description whitespace-pre-wrap'>
70
+ {JSON.stringify(data, null, 2)}
71
+ </pre>
72
+ </Card.Row>
73
+ </Card.Body>
68
74
  </Card.Root>
69
- </Menu.Root>
70
- </Focus.Group>
71
- </Mosaic.Tile>
75
+ </Focus.Item>
76
+ </Mosaic.Tile>
77
+ </Menu.Root>
72
78
  );
73
79
  },
74
80
  );
@@ -5,38 +5,39 @@
5
5
  import { Type } from '@dxos/echo';
6
6
  import { type Resource } from '@dxos/react-ui';
7
7
 
8
- import { meta } from './meta';
9
- import { Kanban } from './types';
8
+ import { meta } from '#meta';
9
+ import { Kanban } from '#types';
10
10
 
11
11
  export const translations = [
12
12
  {
13
13
  'en-US': {
14
14
  [Type.getTypename(Kanban.Kanban)]: {
15
- 'typename label': 'Kanban',
16
- 'typename label_zero': 'Kanbans',
17
- 'typename label_one': 'Kanban',
18
- 'typename label_other': 'Kanbans',
19
- 'object name placeholder': 'New kanban',
20
- 'rename object label': 'Rename kanban',
21
- 'delete object label': 'Delete kanban',
22
- 'object deleted label': 'Kanban deleted',
15
+ 'typename.label': 'Kanban',
16
+ 'typename.label_zero': 'Kanbans',
17
+ 'typename.label_one': 'Kanban',
18
+ 'typename.label_other': 'Kanbans',
19
+ 'object-name.placeholder': 'New kanban',
20
+ 'add-object.label': 'Add kanban',
21
+ 'rename-object.label': 'Rename kanban',
22
+ 'delete-object.label': 'Delete kanban',
23
+ 'object-deleted.label': 'Kanban deleted',
23
24
  },
24
25
  [meta.id]: {
25
- 'action menu label': 'Actions',
26
- 'plugin name': 'Kanban',
27
- 'kanban title label': 'Title',
28
- 'column title label': 'Column title',
29
- 'column title placeholder': 'New column',
30
- 'add column label': 'Add column',
31
- 'add card label': 'Add card',
32
- 'new column name label': 'New column name',
33
- 'remove card label': 'Remove card',
34
- 'remove empty column label': 'Remove empty column',
35
- 'column drag handle label': 'Drag to rearrange',
36
- 'delete column label': 'Delete column',
37
- 'card field deleted label': 'Card field deleted',
38
- 'card deleted label': 'Card deleted',
39
- 'select pivot placeholder': 'Select a pivot column in board settings to display columns.',
26
+ 'action-menu.label': 'Actions',
27
+ 'plugin.name': 'Kanban',
28
+ 'kanban-title.label': 'Title',
29
+ 'column-title.label': 'Column title',
30
+ 'column-title.placeholder': 'New column',
31
+ 'add-column.label': 'Add column',
32
+ 'add-card.label': 'Add card',
33
+ 'new-column-name.label': 'New column name',
34
+ 'remove-card.label': 'Remove card',
35
+ 'remove-empty-column.label': 'Remove empty column',
36
+ 'column-drag-handle.label': 'Drag to rearrange',
37
+ 'delete-column.label': 'Delete column',
38
+ 'card-field-deleted.label': 'Card field deleted',
39
+ 'card-deleted.label': 'Card deleted',
40
+ 'select-pivot.placeholder': 'Select a pivot column in board settings to display columns.',
40
41
  },
41
42
  },
42
43
  },