@dxos/plugin-kanban 0.9.0 → 0.9.1-staging.ee54ba693a
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.
- package/PLUGIN.mdl +3 -3
- package/dist/lib/neutral/{KanbanArticle-T4CPKAZH.mjs → KanbanArticle-JQMQQHRB.mjs} +1 -1
- package/dist/lib/neutral/{KanbanArticle-T4CPKAZH.mjs.map → KanbanArticle-JQMQQHRB.mjs.map} +2 -2
- package/dist/lib/neutral/KanbanPlugin.mjs +6 -6
- package/dist/lib/neutral/KanbanPlugin.mjs.map +4 -4
- package/dist/lib/neutral/KanbanPlugin.node.mjs +3 -3
- package/dist/lib/neutral/KanbanPlugin.node.mjs.map +3 -3
- package/dist/lib/neutral/{KanbanSettings-5WOS4CUE.mjs → KanbanProperties-W7MZNZVJ.mjs} +6 -6
- package/dist/lib/neutral/KanbanProperties-W7MZNZVJ.mjs.map +7 -0
- package/dist/lib/neutral/capabilities/index.mjs +5 -5
- package/dist/lib/neutral/capabilities/index.mjs.map +3 -3
- package/dist/lib/neutral/{chunk-DAKIZO46.mjs → chunk-7TVVF45P.mjs} +7 -6
- package/dist/lib/neutral/chunk-7TVVF45P.mjs.map +7 -0
- package/dist/lib/neutral/chunk-7YLGUKDJ.mjs +8 -0
- package/dist/lib/neutral/chunk-CFPH5R6P.mjs +26 -0
- package/dist/lib/neutral/chunk-CFPH5R6P.mjs.map +7 -0
- package/dist/lib/neutral/chunk-V4AVOJVU.mjs +50 -0
- package/dist/lib/neutral/chunk-V4AVOJVU.mjs.map +7 -0
- package/dist/lib/neutral/components/index.mjs +9 -7
- package/dist/lib/neutral/components/index.mjs.map +3 -3
- package/dist/lib/neutral/containers/index.mjs +3 -3
- package/dist/lib/neutral/containers/index.mjs.map +3 -3
- package/dist/lib/neutral/{create-object-DKBSI46K.mjs → create-object-DIIFRS57.mjs} +14 -9
- package/dist/lib/neutral/create-object-DIIFRS57.mjs.map +7 -0
- package/dist/lib/neutral/{delete-card-VNAV3CZV.mjs → delete-card-TK2G6YHX.mjs} +2 -2
- package/dist/lib/neutral/{delete-card-field-XHOLGS6L.mjs → delete-card-field-LGWPBOUW.mjs} +2 -2
- package/dist/lib/neutral/index.mjs +6 -6
- package/dist/lib/neutral/meta.json +1 -1
- package/dist/lib/neutral/meta.mjs +1 -1
- package/dist/lib/neutral/operations/index.mjs +1 -1
- package/dist/lib/neutral/plugin.mjs +2 -2
- package/dist/lib/neutral/{react-surface-VZEVEJL5.mjs → react-surface-FQGXRR3X.mjs} +11 -13
- package/dist/lib/neutral/react-surface-FQGXRR3X.mjs.map +7 -0
- package/dist/lib/neutral/{restore-card-EKVEPATL.mjs → restore-card-3O6PVN7J.mjs} +2 -2
- package/dist/lib/neutral/{restore-card-field-TQCTGGNO.mjs → restore-card-field-5G4DVYYY.mjs} +2 -2
- package/dist/lib/neutral/skill-definition-YGTCKXGP.mjs +15 -0
- package/dist/lib/neutral/skill-definition-YGTCKXGP.mjs.map +7 -0
- package/dist/lib/neutral/skills/index.mjs +8 -0
- package/dist/lib/neutral/testing/index.mjs +7 -5
- package/dist/lib/neutral/testing/index.mjs.map +3 -3
- package/dist/lib/neutral/translations.mjs +1 -1
- package/dist/lib/neutral/translations.mjs.map +3 -3
- package/dist/lib/neutral/types/index.mjs +1 -1
- package/dist/lib/neutral/{undo-mappings-6CHW6BOF.mjs → undo-mappings-EZTHO4UL.mjs} +3 -3
- package/dist/lib/neutral/{undo-mappings-6CHW6BOF.mjs.map → undo-mappings-EZTHO4UL.mjs.map} +3 -3
- package/dist/types/dx.config.d.ts +28 -0
- package/dist/types/dx.config.d.ts.map +1 -0
- package/dist/types/src/capabilities/artifact-definition.d.ts +1 -1
- package/dist/types/src/capabilities/create-object.d.ts +1 -7
- package/dist/types/src/capabilities/create-object.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts +4 -10
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts +2 -2
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/capabilities/skill-definition.d.ts +5 -0
- package/dist/types/src/capabilities/skill-definition.d.ts.map +1 -0
- package/dist/types/src/capabilities/undo-mappings.d.ts +2 -2
- package/dist/types/src/capabilities/undo-mappings.d.ts.map +1 -1
- package/dist/types/src/components/KanbanBoard/KanbanCard.d.ts.map +1 -1
- package/dist/types/src/containers/KanbanArticle/KanbanArticle.d.ts.map +1 -1
- package/dist/types/src/containers/{KanbanSettings/KanbanSettings.d.ts → KanbanProperties/KanbanProperties.d.ts} +4 -4
- package/dist/types/src/containers/KanbanProperties/KanbanProperties.d.ts.map +1 -0
- package/dist/types/src/containers/KanbanProperties/index.d.ts +2 -0
- package/dist/types/src/containers/KanbanProperties/index.d.ts.map +1 -0
- package/dist/types/src/containers/index.d.ts +1 -1
- package/dist/types/src/containers/index.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +32 -2
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/skills/index.d.ts +2 -0
- package/dist/types/src/skills/index.d.ts.map +1 -0
- package/dist/types/src/skills/kanban-skill.d.ts +4 -0
- package/dist/types/src/skills/kanban-skill.d.ts.map +1 -0
- package/dist/types/src/testing/KanbanCardTileSimple.d.ts.map +1 -1
- package/dist/types/src/types/Kanban.d.ts +3 -6
- package/dist/types/src/types/Kanban.d.ts.map +1 -1
- package/dist/types/src/types/KanbanOperation.d.ts.map +1 -1
- package/dist/types/src/types/schema.d.ts +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/dx.config.ts +36 -0
- package/package.json +48 -47
- package/src/KanbanPlugin.node.ts +2 -2
- package/src/KanbanPlugin.test.ts +3 -3
- package/src/KanbanPlugin.tsx +3 -3
- package/src/capabilities/create-object.ts +9 -7
- package/src/capabilities/index.ts +1 -7
- package/src/capabilities/react-surface.tsx +17 -27
- package/src/capabilities/skill-definition.ts +14 -0
- package/src/capabilities/undo-mappings.ts +2 -2
- package/src/components/KanbanBoard/KanbanBoard.tsx +1 -1
- package/src/components/KanbanBoard/KanbanCard.tsx +14 -12
- package/src/containers/KanbanArticle/KanbanArticle.stories.tsx +1 -1
- package/src/containers/KanbanArticle/KanbanArticle.tsx +1 -1
- package/src/containers/{KanbanSettings/KanbanSettings.tsx → KanbanProperties/KanbanProperties.tsx} +13 -6
- package/src/containers/KanbanProperties/index.ts +5 -0
- package/src/containers/index.ts +1 -1
- package/src/hooks/useKanbanBoardModel.browser.test.ts +20 -18
- package/src/index.ts +1 -1
- package/src/meta.ts +2 -29
- package/src/skills/index.ts +5 -0
- package/src/{blueprints/kanban-blueprint.ts → skills/kanban-skill.ts} +8 -8
- package/src/testing/KanbanCardTileSimple.tsx +13 -11
- package/src/translations.ts +1 -1
- package/src/types/Kanban.ts +13 -17
- package/src/types/KanbanOperation.ts +2 -2
- package/src/types/schema.ts +1 -1
- package/dist/lib/neutral/KanbanSettings-5WOS4CUE.mjs.map +0 -7
- package/dist/lib/neutral/blueprint-definition-6DV3Q5MC.mjs +0 -15
- package/dist/lib/neutral/blueprint-definition-6DV3Q5MC.mjs.map +0 -7
- package/dist/lib/neutral/blueprints/index.mjs +0 -8
- package/dist/lib/neutral/chunk-6ZHHQWO5.mjs +0 -39
- package/dist/lib/neutral/chunk-6ZHHQWO5.mjs.map +0 -7
- package/dist/lib/neutral/chunk-DAKIZO46.mjs.map +0 -7
- package/dist/lib/neutral/chunk-M5ISZWZU.mjs +0 -8
- package/dist/lib/neutral/chunk-ZTQW5KQS.mjs +0 -26
- package/dist/lib/neutral/chunk-ZTQW5KQS.mjs.map +0 -7
- package/dist/lib/neutral/create-object-DKBSI46K.mjs.map +0 -7
- package/dist/lib/neutral/react-surface-VZEVEJL5.mjs.map +0 -7
- package/dist/types/src/blueprints/index.d.ts +0 -2
- package/dist/types/src/blueprints/index.d.ts.map +0 -1
- package/dist/types/src/blueprints/kanban-blueprint.d.ts +0 -4
- package/dist/types/src/blueprints/kanban-blueprint.d.ts.map +0 -1
- package/dist/types/src/capabilities/blueprint-definition.d.ts +0 -6
- package/dist/types/src/capabilities/blueprint-definition.d.ts.map +0 -1
- package/dist/types/src/containers/KanbanSettings/KanbanSettings.d.ts.map +0 -1
- package/dist/types/src/containers/KanbanSettings/index.d.ts +0 -2
- package/dist/types/src/containers/KanbanSettings/index.d.ts.map +0 -1
- package/src/blueprints/index.ts +0 -5
- package/src/capabilities/blueprint-definition.ts +0 -19
- package/src/containers/KanbanSettings/index.ts +0 -5
- /package/dist/lib/neutral/{chunk-M5ISZWZU.mjs.map → chunk-7YLGUKDJ.mjs.map} +0 -0
- /package/dist/lib/neutral/{delete-card-VNAV3CZV.mjs.map → delete-card-TK2G6YHX.mjs.map} +0 -0
- /package/dist/lib/neutral/{delete-card-field-XHOLGS6L.mjs.map → delete-card-field-LGWPBOUW.mjs.map} +0 -0
- /package/dist/lib/neutral/{restore-card-EKVEPATL.mjs.map → restore-card-3O6PVN7J.mjs.map} +0 -0
- /package/dist/lib/neutral/{restore-card-field-TQCTGGNO.mjs.map → restore-card-field-5G4DVYYY.mjs.map} +0 -0
- /package/dist/lib/neutral/{blueprints → skills}/index.mjs.map +0 -0
package/dx.config.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Config2 } from '@dxos/app-framework/config';
|
|
6
|
+
import { trim } from '@dxos/util';
|
|
7
|
+
|
|
8
|
+
export default Config2.make({
|
|
9
|
+
plugin: {
|
|
10
|
+
key: 'org.dxos.plugin.kanban',
|
|
11
|
+
name: 'Kanban',
|
|
12
|
+
author: 'DXOS',
|
|
13
|
+
description: trim`
|
|
14
|
+
Visual project management using customizable kanban boards to track workflow progress.
|
|
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 skill that exposes board creation and card management
|
|
29
|
+
to AI agents, enabling automated project tracking workflows.
|
|
30
|
+
`,
|
|
31
|
+
source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-kanban',
|
|
32
|
+
icon: { key: 'ph--kanban--regular', hue: 'green' },
|
|
33
|
+
spec: 'PLUGIN.mdl',
|
|
34
|
+
screenshots: [{ dark: 'https://dxos.network/plugin-details-kanban-dark.png' }],
|
|
35
|
+
},
|
|
36
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/plugin-kanban",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.1-staging.ee54ba693a",
|
|
4
4
|
"description": "Kanban DXOS Surface plugin",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -13,10 +13,10 @@
|
|
|
13
13
|
"sideEffects": true,
|
|
14
14
|
"type": "module",
|
|
15
15
|
"imports": {
|
|
16
|
-
"#
|
|
17
|
-
"source": "./src/
|
|
18
|
-
"types": "./dist/types/src/
|
|
19
|
-
"default": "./dist/lib/neutral/
|
|
16
|
+
"#skills": {
|
|
17
|
+
"source": "./src/skills/index.ts",
|
|
18
|
+
"types": "./dist/types/src/skills/index.d.ts",
|
|
19
|
+
"default": "./dist/lib/neutral/skills/index.mjs"
|
|
20
20
|
},
|
|
21
21
|
"#capabilities": {
|
|
22
22
|
"source": "./src/capabilities/index.ts",
|
|
@@ -78,10 +78,10 @@
|
|
|
78
78
|
"default": "./dist/lib/neutral/index.mjs"
|
|
79
79
|
},
|
|
80
80
|
"./assets/PLUGIN.mdl": "./PLUGIN.mdl",
|
|
81
|
-
"./
|
|
82
|
-
"source": "./src/
|
|
83
|
-
"types": "./dist/types/src/
|
|
84
|
-
"default": "./dist/lib/neutral/
|
|
81
|
+
"./skills": {
|
|
82
|
+
"source": "./src/skills/index.ts",
|
|
83
|
+
"types": "./dist/types/src/skills/index.d.ts",
|
|
84
|
+
"default": "./dist/lib/neutral/skills/index.mjs"
|
|
85
85
|
},
|
|
86
86
|
"./plugin": {
|
|
87
87
|
"source": "./src/plugin.ts",
|
|
@@ -102,56 +102,57 @@
|
|
|
102
102
|
"types": "dist/types/src/index.d.ts",
|
|
103
103
|
"files": [
|
|
104
104
|
"dist",
|
|
105
|
+
"dx.config.ts",
|
|
105
106
|
"src",
|
|
106
107
|
"PLUGIN.mdl"
|
|
107
108
|
],
|
|
108
109
|
"dependencies": {
|
|
109
110
|
"@effect-atom/atom-react": "^0.5.0",
|
|
110
111
|
"@radix-ui/react-context": "1.1.1",
|
|
111
|
-
"effect": "3.21.
|
|
112
|
-
"@dxos/ai": "0.9.
|
|
113
|
-
"@dxos/app-framework": "0.9.
|
|
114
|
-
"@dxos/
|
|
115
|
-
"@dxos/
|
|
116
|
-
"@dxos/echo": "0.9.
|
|
117
|
-
"@dxos/
|
|
118
|
-
"@dxos/
|
|
119
|
-
"@dxos/
|
|
120
|
-
"@dxos/
|
|
121
|
-
"@dxos/
|
|
122
|
-
"@dxos/
|
|
123
|
-
"@dxos/
|
|
124
|
-
"@dxos/
|
|
125
|
-
"@dxos/react-ui
|
|
126
|
-
"@dxos/react-ui-menu": "0.9.
|
|
127
|
-
"@dxos/
|
|
128
|
-
"@dxos/
|
|
129
|
-
"@dxos/
|
|
130
|
-
"@dxos/
|
|
131
|
-
"@dxos/
|
|
112
|
+
"effect": "3.21.4",
|
|
113
|
+
"@dxos/ai": "0.9.1-staging.ee54ba693a",
|
|
114
|
+
"@dxos/app-framework": "0.9.1-staging.ee54ba693a",
|
|
115
|
+
"@dxos/assistant": "0.9.1-staging.ee54ba693a",
|
|
116
|
+
"@dxos/compute": "0.9.1-staging.ee54ba693a",
|
|
117
|
+
"@dxos/echo": "0.9.1-staging.ee54ba693a",
|
|
118
|
+
"@dxos/effect": "0.9.1-staging.ee54ba693a",
|
|
119
|
+
"@dxos/invariant": "0.9.1-staging.ee54ba693a",
|
|
120
|
+
"@dxos/log": "0.9.1-staging.ee54ba693a",
|
|
121
|
+
"@dxos/random": "0.9.1-staging.ee54ba693a",
|
|
122
|
+
"@dxos/react-client": "0.9.1-staging.ee54ba693a",
|
|
123
|
+
"@dxos/plugin-client": "0.9.1-staging.ee54ba693a",
|
|
124
|
+
"@dxos/react-ui-form": "0.9.1-staging.ee54ba693a",
|
|
125
|
+
"@dxos/plugin-space": "0.9.1-staging.ee54ba693a",
|
|
126
|
+
"@dxos/react-ui": "0.9.1-staging.ee54ba693a",
|
|
127
|
+
"@dxos/react-ui-menu": "0.9.1-staging.ee54ba693a",
|
|
128
|
+
"@dxos/react-ui-mosaic": "0.9.1-staging.ee54ba693a",
|
|
129
|
+
"@dxos/schema": "0.9.1-staging.ee54ba693a",
|
|
130
|
+
"@dxos/app-toolkit": "0.9.1-staging.ee54ba693a",
|
|
131
|
+
"@dxos/types": "0.9.1-staging.ee54ba693a",
|
|
132
|
+
"@dxos/util": "0.9.1-staging.ee54ba693a"
|
|
132
133
|
},
|
|
133
134
|
"devDependencies": {
|
|
134
|
-
"@types/react": "~19.2.
|
|
135
|
+
"@types/react": "~19.2.17",
|
|
135
136
|
"@types/react-dom": "~19.2.3",
|
|
136
|
-
"react": "~19.2.
|
|
137
|
-
"react-dom": "~19.2.
|
|
137
|
+
"react": "~19.2.7",
|
|
138
|
+
"react-dom": "~19.2.7",
|
|
138
139
|
"vite": "^8.0.16",
|
|
139
|
-
"@dxos/keys": "0.9.
|
|
140
|
-
"@dxos/echo-client": "0.9.
|
|
141
|
-
"@dxos/plugin-preview": "0.9.
|
|
142
|
-
"@dxos/plugin-testing": "0.9.
|
|
143
|
-
"@dxos/plugin-theme": "0.9.
|
|
144
|
-
"@dxos/
|
|
145
|
-
"@dxos/
|
|
146
|
-
"@dxos/
|
|
147
|
-
"@dxos/storybook-utils": "0.9.
|
|
140
|
+
"@dxos/keys": "0.9.1-staging.ee54ba693a",
|
|
141
|
+
"@dxos/echo-client": "0.9.1-staging.ee54ba693a",
|
|
142
|
+
"@dxos/plugin-preview": "0.9.1-staging.ee54ba693a",
|
|
143
|
+
"@dxos/plugin-testing": "0.9.1-staging.ee54ba693a",
|
|
144
|
+
"@dxos/plugin-theme": "0.9.1-staging.ee54ba693a",
|
|
145
|
+
"@dxos/react-ui-syntax-highlighter": "0.9.1-staging.ee54ba693a",
|
|
146
|
+
"@dxos/test-utils": "0.9.1-staging.ee54ba693a",
|
|
147
|
+
"@dxos/ui-theme": "0.9.1-staging.ee54ba693a",
|
|
148
|
+
"@dxos/storybook-utils": "0.9.1-staging.ee54ba693a"
|
|
148
149
|
},
|
|
149
150
|
"peerDependencies": {
|
|
150
|
-
"effect": "3.21.
|
|
151
|
-
"react": "~19.2.
|
|
152
|
-
"react-dom": "~19.2.
|
|
153
|
-
"@dxos/
|
|
154
|
-
"@dxos/ui
|
|
151
|
+
"effect": "3.21.4",
|
|
152
|
+
"react": "~19.2.7",
|
|
153
|
+
"react-dom": "~19.2.7",
|
|
154
|
+
"@dxos/ui-theme": "0.9.1-staging.ee54ba693a",
|
|
155
|
+
"@dxos/react-ui": "0.9.1-staging.ee54ba693a"
|
|
155
156
|
},
|
|
156
157
|
"publishConfig": {
|
|
157
158
|
"access": "public"
|
package/src/KanbanPlugin.node.ts
CHANGED
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
import { Plugin } from '@dxos/app-framework';
|
|
6
6
|
import { AppPlugin } from '@dxos/app-toolkit';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { CreateObject, OperationHandler, SkillDefinition, UndoMappings } from '#capabilities';
|
|
9
9
|
import { meta } from '#meta';
|
|
10
10
|
import { Kanban } from '#types';
|
|
11
11
|
|
|
12
12
|
export const KanbanPlugin = Plugin.define(meta).pipe(
|
|
13
|
-
AppPlugin.
|
|
13
|
+
AppPlugin.addSkillDefinitionModule({ activate: SkillDefinition }),
|
|
14
14
|
AppPlugin.addCreateObjectModule({ activate: CreateObject }),
|
|
15
15
|
AppPlugin.addOperationHandlerModule({ activate: OperationHandler }),
|
|
16
16
|
AppPlugin.addUndoMappingsModule({ activate: UndoMappings }),
|
package/src/KanbanPlugin.test.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { KanbanPlugin } from '#plugin';
|
|
|
11
11
|
|
|
12
12
|
import { meta } from './meta';
|
|
13
13
|
|
|
14
|
-
const moduleId = (name: string) => `${meta.
|
|
14
|
+
const moduleId = (name: string) => `${meta.profile.key}.module.${name}`;
|
|
15
15
|
|
|
16
16
|
describe('KanbanPlugin', () => {
|
|
17
17
|
test('modules activate on the expected events', async ({ expect }) => {
|
|
@@ -24,8 +24,8 @@ describe('KanbanPlugin', () => {
|
|
|
24
24
|
expect.arrayContaining([moduleId('OperationHandler'), moduleId('UndoMappings')]),
|
|
25
25
|
);
|
|
26
26
|
|
|
27
|
-
//
|
|
27
|
+
// SkillDefinition fires when AssistantPlugin loads skill definitions.
|
|
28
28
|
await harness.fire(AppActivationEvents.SetupArtifactDefinition);
|
|
29
|
-
expect(harness.manager.getActive()).toContain(moduleId('
|
|
29
|
+
expect(harness.manager.getActive()).toContain(moduleId('SkillDefinition'));
|
|
30
30
|
});
|
|
31
31
|
});
|
package/src/KanbanPlugin.tsx
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { Plugin } from '@dxos/app-framework';
|
|
6
6
|
import { AppPlugin } from '@dxos/app-toolkit';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { CreateObject, OperationHandler, ReactSurface, SkillDefinition, UndoMappings } from '#capabilities';
|
|
9
9
|
import { meta } from '#meta';
|
|
10
10
|
import { translations } from '#translations';
|
|
11
11
|
import { Kanban } from '#types';
|
|
@@ -14,7 +14,7 @@ import { Kanban } from '#types';
|
|
|
14
14
|
import pluginSpec from '../PLUGIN.mdl?raw';
|
|
15
15
|
|
|
16
16
|
export const KanbanPlugin = Plugin.define(meta).pipe(
|
|
17
|
-
AppPlugin.
|
|
17
|
+
AppPlugin.addSkillDefinitionModule({ activate: SkillDefinition }),
|
|
18
18
|
AppPlugin.addCreateObjectModule({ activate: CreateObject }),
|
|
19
19
|
AppPlugin.addOperationHandlerModule({ activate: OperationHandler }),
|
|
20
20
|
AppPlugin.addUndoMappingsModule({ activate: UndoMappings }),
|
|
@@ -22,7 +22,7 @@ export const KanbanPlugin = Plugin.define(meta).pipe(
|
|
|
22
22
|
AppPlugin.addSurfaceModule({ activate: ReactSurface }),
|
|
23
23
|
AppPlugin.addTranslationsModule({ translations }),
|
|
24
24
|
AppPlugin.addPluginAssetModule({
|
|
25
|
-
asset: { pluginId: meta.
|
|
25
|
+
asset: { pluginId: meta.profile.key, path: 'PLUGIN.mdl', content: pluginSpec, mimeType: 'application/x-mdl' },
|
|
26
26
|
}),
|
|
27
27
|
Plugin.make,
|
|
28
28
|
);
|
|
@@ -21,17 +21,19 @@ export default Capability.makeModule(
|
|
|
21
21
|
createObject: (props, options) =>
|
|
22
22
|
Effect.gen(function* () {
|
|
23
23
|
const object = yield* Effect.promise(async () => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
if (props.typename) {
|
|
25
|
+
const { view } = await ViewModel.makeFromDatabase({
|
|
26
|
+
db: options.db,
|
|
27
|
+
typename: props.typename,
|
|
28
|
+
pivotFieldName: props.initialPivotColumn,
|
|
29
|
+
});
|
|
30
|
+
return Kanban.make({ name: props.name, view });
|
|
31
|
+
}
|
|
32
|
+
return Kanban.makeItems({ name: props.name, pivotField: props.initialPivotColumn ?? '' });
|
|
30
33
|
});
|
|
31
34
|
return yield* Operation.invoke(SpaceOperation.AddObject, {
|
|
32
35
|
object,
|
|
33
36
|
target: options.target,
|
|
34
|
-
hidden: true,
|
|
35
37
|
targetNodeId: options.targetNodeId,
|
|
36
38
|
});
|
|
37
39
|
}),
|
|
@@ -3,15 +3,9 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { Capability } from '@dxos/app-framework';
|
|
6
|
-
import { type AppCapabilities } from '@dxos/app-toolkit';
|
|
7
6
|
import type { OperationHandlerSet } from '@dxos/compute';
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
// wrapper needs an explicit annotation to keep the inferred type portable (TS2883).
|
|
11
|
-
export const BlueprintDefinition: Capability.LazyCapability<
|
|
12
|
-
void,
|
|
13
|
-
Capability.Capability<typeof AppCapabilities.BlueprintDefinition>[]
|
|
14
|
-
> = Capability.lazy('BlueprintDefinition', () => import('./blueprint-definition'));
|
|
8
|
+
export const SkillDefinition = Capability.lazy('SkillDefinition', () => import('./skill-definition'));
|
|
15
9
|
export const CreateObject = Capability.lazy('CreateObject', () => import('./create-object'));
|
|
16
10
|
export const OperationHandler = Capability.lazy<OperationHandlerSet.OperationHandlerSet>(
|
|
17
11
|
'OperationHandler',
|
|
@@ -3,18 +3,17 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import * as Effect from 'effect/Effect';
|
|
6
|
-
import type * as Schema from 'effect/Schema';
|
|
7
|
-
import * as SchemaAST from 'effect/SchemaAST';
|
|
8
6
|
import React, { useMemo } from 'react';
|
|
9
7
|
|
|
10
8
|
import { Capabilities, Capability } from '@dxos/app-framework';
|
|
11
9
|
import { Surface } from '@dxos/app-framework/ui';
|
|
12
10
|
import { AppSurface } from '@dxos/app-toolkit/ui';
|
|
13
|
-
import {
|
|
11
|
+
import { Database, Obj, Type } from '@dxos/echo';
|
|
14
12
|
import { SchemaEx } from '@dxos/effect';
|
|
15
|
-
import { type
|
|
13
|
+
import { type FormFieldRendererProps, SelectField, useFormValues } from '@dxos/react-ui-form';
|
|
14
|
+
import { Position } from '@dxos/util';
|
|
16
15
|
|
|
17
|
-
import { KanbanArticle,
|
|
16
|
+
import { KanbanArticle, KanbanProperties } from '#containers';
|
|
18
17
|
import { Kanban, PivotColumnAnnotationId } from '#types';
|
|
19
18
|
|
|
20
19
|
export default Capability.makeModule(() =>
|
|
@@ -31,35 +30,22 @@ export default Capability.makeModule(() =>
|
|
|
31
30
|
}),
|
|
32
31
|
Surface.create({
|
|
33
32
|
id: 'objectProperties',
|
|
34
|
-
position:
|
|
33
|
+
position: Position.first,
|
|
35
34
|
filter: AppSurface.object(AppSurface.ObjectProperties, Kanban.Kanban),
|
|
36
|
-
component: ({ data }) => <
|
|
35
|
+
component: ({ data }) => <KanbanProperties subject={data.subject} />,
|
|
37
36
|
}),
|
|
38
37
|
Surface.create({
|
|
39
38
|
id: 'createInitialSchemaForm',
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
data
|
|
43
|
-
): data is {
|
|
44
|
-
prop: string;
|
|
45
|
-
schema: Schema.Schema<any>;
|
|
46
|
-
target: Database.Database | Collection.Collection | undefined;
|
|
47
|
-
fieldPropertyAst?: SchemaAST.AST;
|
|
48
|
-
} => {
|
|
49
|
-
const annotation = SchemaEx.findAnnotation<boolean>(
|
|
50
|
-
(data.schema as Schema.Schema.All).ast,
|
|
51
|
-
PivotColumnAnnotationId,
|
|
52
|
-
);
|
|
53
|
-
return !!annotation;
|
|
54
|
-
},
|
|
55
|
-
component: ({ data: { target, fieldPropertyAst }, ...inputProps }) => {
|
|
56
|
-
const ast = fieldPropertyAst;
|
|
39
|
+
filter: AppSurface.formInputBySchema((ast) => !!SchemaEx.findAnnotation<boolean>(ast, PivotColumnAnnotationId)),
|
|
40
|
+
component: ({ data, ...inputProps }) => {
|
|
41
|
+
const ast = data.fieldPropertyAst;
|
|
57
42
|
if (!ast) {
|
|
58
43
|
return null;
|
|
59
44
|
}
|
|
60
45
|
|
|
61
|
-
const props = { ...inputProps, type: ast } as any as
|
|
62
|
-
const
|
|
46
|
+
const props = { ...inputProps, type: ast } as any as FormFieldRendererProps;
|
|
47
|
+
const target = data.target;
|
|
48
|
+
const db = Database.isDatabase(target) ? target : Obj.isObject(target) ? Obj.getDatabase(target) : undefined;
|
|
63
49
|
if (!db) {
|
|
64
50
|
return null;
|
|
65
51
|
}
|
|
@@ -84,7 +70,11 @@ export default Capability.makeModule(() =>
|
|
|
84
70
|
}
|
|
85
71
|
|
|
86
72
|
const columns = Object.entries(properties).reduce<string[]>((acc, [key, value]) => {
|
|
87
|
-
if (
|
|
73
|
+
if (
|
|
74
|
+
typeof value === 'object' &&
|
|
75
|
+
value !== null &&
|
|
76
|
+
(value as { format?: string }).format === 'single-select'
|
|
77
|
+
) {
|
|
88
78
|
acc.push(key);
|
|
89
79
|
}
|
|
90
80
|
return acc;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
|
|
7
|
+
import { Capability } from '@dxos/app-framework';
|
|
8
|
+
import { AppCapabilities } from '@dxos/app-toolkit';
|
|
9
|
+
|
|
10
|
+
import { KanbanSkill } from '#skills';
|
|
11
|
+
|
|
12
|
+
const skillDefinition = () => Effect.succeed([Capability.contributes(AppCapabilities.SkillDefinition, KanbanSkill)]);
|
|
13
|
+
|
|
14
|
+
export default skillDefinition;
|
|
@@ -19,7 +19,7 @@ export default Capability.makeModule(() =>
|
|
|
19
19
|
props: output.props,
|
|
20
20
|
index: output.index,
|
|
21
21
|
}),
|
|
22
|
-
message: ['card-field-deleted.label', { ns: meta.
|
|
22
|
+
message: ['card-field-deleted.label', { ns: meta.profile.key }],
|
|
23
23
|
}),
|
|
24
24
|
UndoMapping.make({
|
|
25
25
|
operation: KanbanOperation.DeleteCard,
|
|
@@ -27,7 +27,7 @@ export default Capability.makeModule(() =>
|
|
|
27
27
|
deriveContext: (_input, output) => ({
|
|
28
28
|
card: output.card,
|
|
29
29
|
}),
|
|
30
|
-
message: ['card-deleted.label', { ns: meta.
|
|
30
|
+
message: ['card-deleted.label', { ns: meta.profile.key }],
|
|
31
31
|
}),
|
|
32
32
|
]),
|
|
33
33
|
),
|
|
@@ -57,7 +57,7 @@ export const KanbanBoardRoot = ({
|
|
|
57
57
|
onCardRemove,
|
|
58
58
|
}: KanbanBoardRootProps) => {
|
|
59
59
|
const registry = useContext(RegistryContext);
|
|
60
|
-
const { t } = useTranslation(meta.
|
|
60
|
+
const { t } = useTranslation(meta.profile.key);
|
|
61
61
|
const model = useKanbanBoardModel(kanban, projection, items, registry);
|
|
62
62
|
const columns = model?.getColumns?.() ?? [];
|
|
63
63
|
const view = kanban?.spec.kind === 'view' ? kanban.spec.view.target : undefined;
|
|
@@ -7,7 +7,7 @@ import React, { forwardRef, useCallback, useMemo, useState } from 'react';
|
|
|
7
7
|
import { Surface } from '@dxos/app-framework/ui';
|
|
8
8
|
import { AppSurface, useObjectMenuItems } from '@dxos/app-toolkit/ui';
|
|
9
9
|
import { Obj } from '@dxos/echo';
|
|
10
|
-
import { Card,
|
|
10
|
+
import { Card, IconButton, useTranslation } from '@dxos/react-ui';
|
|
11
11
|
import { Menu, createMenuAction } from '@dxos/react-ui-menu';
|
|
12
12
|
import { Focus, Mosaic, useBoard } from '@dxos/react-ui-mosaic';
|
|
13
13
|
|
|
@@ -25,7 +25,7 @@ const KANBAN_CARD_TILE_NAME = 'KanbanBoard.Card';
|
|
|
25
25
|
*/
|
|
26
26
|
export const KanbanCard = forwardRef<HTMLDivElement, KanbanCardProps>(
|
|
27
27
|
({ data, location, debug, draggable }, forwardedRef) => {
|
|
28
|
-
const { t } = useTranslation(meta.
|
|
28
|
+
const { t } = useTranslation(meta.profile.key);
|
|
29
29
|
const { model } = useBoard(KANBAN_CARD_TILE_NAME);
|
|
30
30
|
const { projection, columnFieldPath, onCardRemove } = useKanbanBoard(KANBAN_CARD_TILE_NAME);
|
|
31
31
|
const [dragHandle, setDragHandle] = useState<HTMLButtonElement | null>(null);
|
|
@@ -65,20 +65,22 @@ export const KanbanCard = forwardRef<HTMLDivElement, KanbanCardProps>(
|
|
|
65
65
|
<Card.DragHandle ref={dragHandleRef} testId='mosaicBoard.cardDragHandle' />
|
|
66
66
|
<Card.Title data-testid='mosaicBoard.cardTitle'>{Obj.getLabel(data)}</Card.Title>
|
|
67
67
|
{/* TODO(wittjosiah): Reconcile with Card.Menu. */}
|
|
68
|
-
<
|
|
69
|
-
<
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
68
|
+
<Card.Block end>
|
|
69
|
+
<Menu.Trigger asChild disabled={!menuItems?.length}>
|
|
70
|
+
<IconButton
|
|
71
|
+
iconOnly
|
|
72
|
+
variant='ghost'
|
|
73
|
+
icon='ph--dots-three-vertical--regular'
|
|
74
|
+
label={t('action-menu.label')}
|
|
75
|
+
/>
|
|
76
|
+
</Menu.Trigger>
|
|
77
|
+
<Menu.Content items={menuItems} />
|
|
78
|
+
</Card.Block>
|
|
77
79
|
</Card.Header>
|
|
78
80
|
<Card.Body>
|
|
79
81
|
{projection && (
|
|
80
82
|
<Surface.Surface
|
|
81
|
-
type={AppSurface.
|
|
83
|
+
type={AppSurface.CardContent}
|
|
82
84
|
limit={1}
|
|
83
85
|
data={{
|
|
84
86
|
subject: data,
|
|
@@ -22,7 +22,7 @@ import { PreviewPlugin } from '@dxos/plugin-preview/testing';
|
|
|
22
22
|
import { SpacePlugin } from '@dxos/plugin-space/testing';
|
|
23
23
|
import { StorybookPlugin, corePlugins } from '@dxos/plugin-testing';
|
|
24
24
|
import { random } from '@dxos/random';
|
|
25
|
-
import { type Space, useQuery,
|
|
25
|
+
import { type Space, useQuery, useSpaces, useType } from '@dxos/react-client/echo';
|
|
26
26
|
import { ViewEditor } from '@dxos/react-ui-form';
|
|
27
27
|
import { Syntax } from '@dxos/react-ui-syntax-highlighter';
|
|
28
28
|
import { withLayout } from '@dxos/react-ui/testing';
|
|
@@ -7,7 +7,7 @@ import React, { useCallback, useContext, useMemo } from 'react';
|
|
|
7
7
|
|
|
8
8
|
import { useCapabilities, useOperationInvoker } from '@dxos/app-framework/ui';
|
|
9
9
|
import { AppCapabilities } from '@dxos/app-toolkit';
|
|
10
|
-
import {
|
|
10
|
+
import { type AppSurface, useSchemaFilter } from '@dxos/app-toolkit/ui';
|
|
11
11
|
import { Filter, Obj, Query, type Ref, Type } from '@dxos/echo';
|
|
12
12
|
import { useObject, useType } from '@dxos/react-client/echo';
|
|
13
13
|
import { Panel, Toolbar } from '@dxos/react-ui';
|
package/src/containers/{KanbanSettings/KanbanSettings.tsx → KanbanProperties/KanbanProperties.tsx}
RENAMED
|
@@ -15,16 +15,16 @@ import { getTypeURIFromQuery } from '@dxos/schema';
|
|
|
15
15
|
import { useProjectionModel } from '#hooks';
|
|
16
16
|
import { type Kanban, KanbanSettingsSchema, KanbanViewSettingsSchema, UNCATEGORIZED_VALUE } from '#types';
|
|
17
17
|
|
|
18
|
-
export type
|
|
18
|
+
export type KanbanPropertiesProps = AppSurface.ObjectPropertiesProps<Kanban.Kanban>;
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
|
-
*
|
|
21
|
+
* Object-properties panel for a Kanban. Renders fields common to every kanban
|
|
22
22
|
* (currently the "Hide uncategorized column" toggle); for view-variant
|
|
23
23
|
* kanbans an additional "Column field" picker drives the View's pivot
|
|
24
24
|
* field. Items-variant kanbans use a hardcoded `spec.pivotField`, so that
|
|
25
25
|
* field is omitted there.
|
|
26
26
|
*/
|
|
27
|
-
export const
|
|
27
|
+
export const KanbanProperties = ({ subject: object }: KanbanPropertiesProps) => {
|
|
28
28
|
const registry = useContext(RegistryContext);
|
|
29
29
|
const db = Obj.getDatabase(object);
|
|
30
30
|
const isView = object.spec.kind === 'view';
|
|
@@ -87,8 +87,15 @@ export const KanbanSettings = ({ subject: object }: KanbanSettingsProps) => {
|
|
|
87
87
|
const settingsSchema = (isView ? KanbanViewSettingsSchema : KanbanSettingsSchema) as any;
|
|
88
88
|
|
|
89
89
|
return (
|
|
90
|
-
<Form.
|
|
91
|
-
<Form.
|
|
92
|
-
|
|
90
|
+
<Form.Section>
|
|
91
|
+
<Form.Root
|
|
92
|
+
schema={settingsSchema}
|
|
93
|
+
values={initialValues}
|
|
94
|
+
fieldMap={fieldMap}
|
|
95
|
+
onValuesChanged={handleValuesChanged}
|
|
96
|
+
>
|
|
97
|
+
<Form.FieldSet />
|
|
98
|
+
</Form.Root>
|
|
99
|
+
</Form.Section>
|
|
93
100
|
);
|
|
94
101
|
};
|
package/src/containers/index.ts
CHANGED
|
@@ -5,4 +5,4 @@
|
|
|
5
5
|
import { type ComponentType, lazy } from 'react';
|
|
6
6
|
|
|
7
7
|
export const KanbanArticle: ComponentType<any> = lazy(() => import('./KanbanArticle'));
|
|
8
|
-
export const
|
|
8
|
+
export const KanbanProperties: ComponentType<any> = lazy(() => import('./KanbanProperties'));
|
|
@@ -18,25 +18,27 @@ import { Kanban } from '#types';
|
|
|
18
18
|
import { useKanbanBoardModel } from './useKanbanBoardModel';
|
|
19
19
|
|
|
20
20
|
// TODO(wittjosiah): Consider adding single-select to TestSchema.Task and using that instead.
|
|
21
|
-
const KanbanTaskSchema =
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
21
|
+
const KanbanTaskSchema = Type.makeObject(DXN.make('com.example.type.kanbanTask', '0.1.0'))(
|
|
22
|
+
Schema.Struct({
|
|
23
|
+
title: Schema.optional(Schema.String),
|
|
24
|
+
status: Schema.Literal('__uncategorized__', 'a', 'b').pipe(
|
|
25
|
+
FormatAnnotation.set(Format.TypeFormat.SingleSelect),
|
|
26
|
+
Schema.annotations({
|
|
27
|
+
title: 'Status',
|
|
28
|
+
[PropertyMetaAnnotationId]: {
|
|
29
|
+
singleSelect: {
|
|
30
|
+
options: [
|
|
31
|
+
{ id: '__uncategorized__', title: 'Uncategorized', color: 'neutral' },
|
|
32
|
+
{ id: 'a', title: 'A', color: 'blue' },
|
|
33
|
+
{ id: 'b', title: 'B', color: 'green' },
|
|
34
|
+
],
|
|
35
|
+
},
|
|
34
36
|
},
|
|
35
|
-
},
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
),
|
|
39
|
-
|
|
37
|
+
}),
|
|
38
|
+
Schema.optional,
|
|
39
|
+
),
|
|
40
|
+
}),
|
|
41
|
+
);
|
|
40
42
|
|
|
41
43
|
type KanbanTask = Type.InstanceType<typeof KanbanTaskSchema>;
|
|
42
44
|
|
package/src/index.ts
CHANGED
package/src/meta.ts
CHANGED
|
@@ -3,34 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { Plugin } from '@dxos/app-framework';
|
|
6
|
-
import { DXN } from '@dxos/echo';
|
|
7
|
-
import { trim } from '@dxos/util';
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
key: DXN.make('org.dxos.plugin.kanban'),
|
|
11
|
-
name: 'Kanban',
|
|
12
|
-
author: 'DXOS',
|
|
13
|
-
description: trim`
|
|
14
|
-
Visual project management using customizable kanban boards to track workflow progress.
|
|
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.
|
|
7
|
+
import config from '../dx.config';
|
|
18
8
|
|
|
19
|
-
|
|
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.
|
|
30
|
-
`,
|
|
31
|
-
icon: 'ph--kanban--regular',
|
|
32
|
-
iconHue: 'green',
|
|
33
|
-
source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-kanban',
|
|
34
|
-
spec: 'PLUGIN.mdl',
|
|
35
|
-
screenshots: ['https://dxos.network/plugin-details-kanban-dark.png'],
|
|
36
|
-
});
|
|
9
|
+
export const meta = Plugin.getMetaFromConfig(config);
|