@dxos/plugin-kanban 0.8.4-main.67995b8 → 0.8.4-main.72ec0f3
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/dist/lib/browser/blueprint-definition-UYVX622Q.mjs +28 -0
- package/dist/lib/browser/blueprint-definition-UYVX622Q.mjs.map +7 -0
- package/dist/lib/browser/{chunk-MUK4JV7A.mjs → chunk-HO3LQ5T7.mjs} +15 -37
- package/dist/lib/browser/chunk-HO3LQ5T7.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +16 -16
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/{intent-resolver-6GPK64NB.mjs → intent-resolver-OPYUDNSU.mjs} +15 -15
- package/dist/lib/browser/intent-resolver-OPYUDNSU.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-surface-Y2GO6B24.mjs → react-surface-X54TNDDN.mjs} +30 -29
- package/dist/lib/browser/react-surface-X54TNDDN.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +3 -5
- package/dist/lib/node-esm/blueprint-definition-42P47FUY.mjs +30 -0
- package/dist/lib/node-esm/blueprint-definition-42P47FUY.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-2GCFRKS2.mjs → chunk-QZMZU5HM.mjs} +15 -37
- package/dist/lib/node-esm/chunk-QZMZU5HM.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +16 -16
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/{intent-resolver-CXHLNVEN.mjs → intent-resolver-BDKNXV3R.mjs} +15 -15
- package/dist/lib/node-esm/intent-resolver-BDKNXV3R.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{react-surface-UEQNH6S4.mjs → react-surface-CVDMIHSC.mjs} +30 -29
- package/dist/lib/node-esm/react-surface-CVDMIHSC.mjs.map +7 -0
- package/dist/lib/node-esm/types/index.mjs +3 -5
- package/dist/types/src/KanbanPlugin.d.ts +1 -1
- package/dist/types/src/KanbanPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/artifact-definition.d.ts +1 -1
- package/dist/types/src/capabilities/artifact-definition.d.ts.map +1 -1
- package/dist/types/src/capabilities/blueprint-definition.d.ts +5 -0
- package/dist/types/src/capabilities/blueprint-definition.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +3 -3
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts +1 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/components/KanbanContainer.d.ts +2 -2
- package/dist/types/src/components/KanbanContainer.d.ts.map +1 -1
- package/dist/types/src/components/KanbanContainer.stories.d.ts +37 -6
- package/dist/types/src/components/KanbanContainer.stories.d.ts.map +1 -1
- package/dist/types/src/components/KanbanViewEditor.d.ts +2 -2
- package/dist/types/src/components/KanbanViewEditor.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +0 -1
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +2 -2
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/index.d.ts +0 -1
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/src/types/schema.d.ts +11 -54
- package/dist/types/src/types/schema.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +45 -44
- package/src/KanbanPlugin.tsx +51 -50
- package/src/capabilities/artifact-definition.ts +15 -11
- package/src/capabilities/blueprint-definition.ts +30 -0
- package/src/capabilities/index.ts +1 -1
- package/src/capabilities/intent-resolver.ts +10 -9
- package/src/capabilities/react-surface.tsx +15 -10
- package/src/components/KanbanContainer.stories.tsx +40 -35
- package/src/components/KanbanContainer.tsx +9 -8
- package/src/components/KanbanViewEditor.tsx +16 -12
- package/src/meta.ts +7 -5
- package/src/translations.ts +2 -2
- package/src/types/index.ts +0 -1
- package/src/types/schema.ts +8 -7
- package/dist/lib/browser/artifact-definition-NIFSAHUK.mjs +0 -174
- package/dist/lib/browser/artifact-definition-NIFSAHUK.mjs.map +0 -7
- package/dist/lib/browser/chunk-MUK4JV7A.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-6GPK64NB.mjs.map +0 -7
- package/dist/lib/browser/react-surface-Y2GO6B24.mjs.map +0 -7
- package/dist/lib/node-esm/artifact-definition-NACXLTWB.mjs +0 -175
- package/dist/lib/node-esm/artifact-definition-NACXLTWB.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-2GCFRKS2.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-CXHLNVEN.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-UEQNH6S4.mjs.map +0 -7
- package/dist/types/src/types/kanban.d.ts +0 -11
- package/dist/types/src/types/kanban.d.ts.map +0 -1
- package/src/types/kanban.ts +0 -29
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/plugin-kanban",
|
|
3
|
-
"version": "0.8.4-main.
|
|
3
|
+
"version": "0.8.4-main.72ec0f3",
|
|
4
4
|
"description": "Kanban DXOS Surface plugin",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -10,16 +10,16 @@
|
|
|
10
10
|
"type": "module",
|
|
11
11
|
"exports": {
|
|
12
12
|
".": {
|
|
13
|
+
"source": "./src/index.ts",
|
|
13
14
|
"types": "./dist/types/src/index.d.ts",
|
|
14
15
|
"browser": "./dist/lib/browser/index.mjs",
|
|
15
|
-
"node": "./dist/lib/node-esm/index.mjs"
|
|
16
|
-
"source": "./src/index.ts"
|
|
16
|
+
"node": "./dist/lib/node-esm/index.mjs"
|
|
17
17
|
},
|
|
18
18
|
"./types": {
|
|
19
|
+
"source": "./src/types/index.ts",
|
|
19
20
|
"types": "./dist/types/src/types/index.d.ts",
|
|
20
21
|
"browser": "./dist/lib/browser/types/index.mjs",
|
|
21
|
-
"node": "./dist/lib/node-esm/types/index.mjs"
|
|
22
|
-
"source": "./src/types/index.ts"
|
|
22
|
+
"node": "./dist/lib/node-esm/types/index.mjs"
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
25
|
"types": "dist/types/src/index.d.ts",
|
|
@@ -36,50 +36,51 @@
|
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@preact-signals/safe-react": "^0.9.0",
|
|
39
|
-
"@preact/signals-core": "^1.
|
|
40
|
-
"effect": "3.
|
|
41
|
-
"@dxos/ai": "0.8.4-main.
|
|
42
|
-
"@dxos/assistant": "0.8.4-main.
|
|
43
|
-
"@dxos/app-framework": "0.8.4-main.
|
|
44
|
-
"@dxos/
|
|
45
|
-
"@dxos/
|
|
46
|
-
"@dxos/
|
|
47
|
-
"@dxos/
|
|
48
|
-
"@dxos/
|
|
49
|
-
"@dxos/
|
|
50
|
-
"@dxos/
|
|
51
|
-
"@dxos/
|
|
52
|
-
"@dxos/plugin-
|
|
53
|
-
"@dxos/plugin-
|
|
54
|
-
"@dxos/plugin-
|
|
55
|
-
"@dxos/random": "0.8.4-main.
|
|
56
|
-
"@dxos/react-client": "0.8.4-main.
|
|
57
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
58
|
-
"@dxos/react-ui-
|
|
59
|
-
"@dxos/react-ui-
|
|
60
|
-
"@dxos/react-ui-stack": "0.8.4-main.
|
|
61
|
-
"@dxos/schema": "0.8.4-main.
|
|
62
|
-
"@dxos/
|
|
39
|
+
"@preact/signals-core": "^1.12.1",
|
|
40
|
+
"effect": "3.18.3",
|
|
41
|
+
"@dxos/ai": "0.8.4-main.72ec0f3",
|
|
42
|
+
"@dxos/assistant": "0.8.4-main.72ec0f3",
|
|
43
|
+
"@dxos/app-framework": "0.8.4-main.72ec0f3",
|
|
44
|
+
"@dxos/echo": "0.8.4-main.72ec0f3",
|
|
45
|
+
"@dxos/async": "0.8.4-main.72ec0f3",
|
|
46
|
+
"@dxos/effect": "0.8.4-main.72ec0f3",
|
|
47
|
+
"@dxos/functions": "0.8.4-main.72ec0f3",
|
|
48
|
+
"@dxos/blueprints": "0.8.4-main.72ec0f3",
|
|
49
|
+
"@dxos/log": "0.8.4-main.72ec0f3",
|
|
50
|
+
"@dxos/plugin-client": "0.8.4-main.72ec0f3",
|
|
51
|
+
"@dxos/invariant": "0.8.4-main.72ec0f3",
|
|
52
|
+
"@dxos/plugin-space": "0.8.4-main.72ec0f3",
|
|
53
|
+
"@dxos/plugin-graph": "0.8.4-main.72ec0f3",
|
|
54
|
+
"@dxos/plugin-search": "0.8.4-main.72ec0f3",
|
|
55
|
+
"@dxos/random": "0.8.4-main.72ec0f3",
|
|
56
|
+
"@dxos/react-client": "0.8.4-main.72ec0f3",
|
|
57
|
+
"@dxos/react-ui": "0.8.4-main.72ec0f3",
|
|
58
|
+
"@dxos/react-ui-form": "0.8.4-main.72ec0f3",
|
|
59
|
+
"@dxos/react-ui-kanban": "0.8.4-main.72ec0f3",
|
|
60
|
+
"@dxos/react-ui-stack": "0.8.4-main.72ec0f3",
|
|
61
|
+
"@dxos/schema": "0.8.4-main.72ec0f3",
|
|
62
|
+
"@dxos/types": "0.8.4-main.72ec0f3",
|
|
63
|
+
"@dxos/util": "0.8.4-main.72ec0f3"
|
|
63
64
|
},
|
|
64
65
|
"devDependencies": {
|
|
65
|
-
"@types/react": "~
|
|
66
|
-
"@types/react-dom": "~
|
|
67
|
-
"react": "~
|
|
68
|
-
"react-dom": "~
|
|
69
|
-
"vite": "
|
|
70
|
-
"@dxos/plugin-
|
|
71
|
-
"@dxos/plugin-
|
|
72
|
-
"@dxos/react-ui-
|
|
73
|
-
"@dxos/
|
|
74
|
-
"@dxos/
|
|
75
|
-
"@dxos/test-utils": "0.8.4-main.
|
|
66
|
+
"@types/react": "~19.2.2",
|
|
67
|
+
"@types/react-dom": "~19.2.2",
|
|
68
|
+
"react": "~19.2.0",
|
|
69
|
+
"react-dom": "~19.2.0",
|
|
70
|
+
"vite": "7.1.9",
|
|
71
|
+
"@dxos/plugin-theme": "0.8.4-main.72ec0f3",
|
|
72
|
+
"@dxos/plugin-preview": "0.8.4-main.72ec0f3",
|
|
73
|
+
"@dxos/react-ui-theme": "0.8.4-main.72ec0f3",
|
|
74
|
+
"@dxos/react-ui-syntax-highlighter": "0.8.4-main.72ec0f3",
|
|
75
|
+
"@dxos/storybook-utils": "0.8.4-main.72ec0f3",
|
|
76
|
+
"@dxos/test-utils": "0.8.4-main.72ec0f3"
|
|
76
77
|
},
|
|
77
78
|
"peerDependencies": {
|
|
78
79
|
"effect": "^3.13.3",
|
|
79
|
-
"react": "
|
|
80
|
-
"react-dom": "
|
|
81
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
82
|
-
"@dxos/react-ui-theme": "0.8.4-main.
|
|
80
|
+
"react": "^19.0.0",
|
|
81
|
+
"react-dom": "^19.0.0",
|
|
82
|
+
"@dxos/react-ui": "0.8.4-main.72ec0f3",
|
|
83
|
+
"@dxos/react-ui-theme": "0.8.4-main.72ec0f3"
|
|
83
84
|
},
|
|
84
85
|
"publishConfig": {
|
|
85
86
|
"access": "public"
|
package/src/KanbanPlugin.tsx
CHANGED
|
@@ -2,62 +2,63 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { Capabilities, Events, contributes, createIntent, defineModule, definePlugin } from '@dxos/app-framework';
|
|
6
6
|
import { ClientEvents } from '@dxos/plugin-client';
|
|
7
7
|
import { SpaceCapabilities } from '@dxos/plugin-space';
|
|
8
8
|
import { defineObjectForm } from '@dxos/plugin-space/types';
|
|
9
|
-
import {
|
|
9
|
+
import { translations as kanbanTranslations } from '@dxos/react-ui-kanban';
|
|
10
|
+
import { Kanban } from '@dxos/react-ui-kanban/types';
|
|
10
11
|
|
|
11
|
-
import {
|
|
12
|
+
import { BlueprintDefinition, IntentResolver, ReactSurface } from './capabilities';
|
|
12
13
|
import { meta } from './meta';
|
|
13
14
|
import { translations } from './translations';
|
|
14
15
|
import { CreateKanbanSchema, KanbanAction } from './types';
|
|
15
16
|
|
|
16
|
-
export const KanbanPlugin = () =>
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
17
|
+
export const KanbanPlugin = definePlugin(meta, () => [
|
|
18
|
+
defineModule({
|
|
19
|
+
id: `${meta.id}/module/translations`,
|
|
20
|
+
activatesOn: Events.SetupTranslations,
|
|
21
|
+
activate: () => contributes(Capabilities.Translations, [...translations, ...kanbanTranslations]),
|
|
22
|
+
}),
|
|
23
|
+
defineModule({
|
|
24
|
+
id: `${meta.id}/module/metadata`,
|
|
25
|
+
activatesOn: Events.SetupMetadata,
|
|
26
|
+
activate: () =>
|
|
27
|
+
contributes(Capabilities.Metadata, {
|
|
28
|
+
id: Kanban.Kanban.typename,
|
|
29
|
+
metadata: {
|
|
30
|
+
icon: 'ph--kanban--regular',
|
|
31
|
+
iconHue: 'green',
|
|
32
|
+
},
|
|
33
|
+
}),
|
|
34
|
+
}),
|
|
35
|
+
defineModule({
|
|
36
|
+
id: `${meta.id}/module/object-form`,
|
|
37
|
+
activatesOn: ClientEvents.SetupSchema,
|
|
38
|
+
activate: () =>
|
|
39
|
+
contributes(
|
|
40
|
+
SpaceCapabilities.ObjectForm,
|
|
41
|
+
defineObjectForm({
|
|
42
|
+
objectSchema: Kanban.Kanban,
|
|
43
|
+
formSchema: CreateKanbanSchema,
|
|
44
|
+
hidden: true,
|
|
45
|
+
getIntent: (props, options) => createIntent(KanbanAction.Create, { ...props, space: options.space }),
|
|
32
46
|
}),
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
activate: ReactSurface,
|
|
52
|
-
}),
|
|
53
|
-
defineModule({
|
|
54
|
-
id: `${meta.id}/module/intent-resolver`,
|
|
55
|
-
activatesOn: Events.SetupIntentResolver,
|
|
56
|
-
activate: IntentResolver,
|
|
57
|
-
}),
|
|
58
|
-
defineModule({
|
|
59
|
-
id: `${meta.id}/module/artifact-definition`,
|
|
60
|
-
activatesOn: Events.SetupArtifactDefinition,
|
|
61
|
-
activate: ArtifactDefinition,
|
|
62
|
-
}),
|
|
63
|
-
]);
|
|
47
|
+
),
|
|
48
|
+
}),
|
|
49
|
+
defineModule({
|
|
50
|
+
id: `${meta.id}/module/react-surface`,
|
|
51
|
+
activatesOn: Events.SetupReactSurface,
|
|
52
|
+
activate: ReactSurface,
|
|
53
|
+
}),
|
|
54
|
+
defineModule({
|
|
55
|
+
id: `${meta.id}/module/intent-resolver`,
|
|
56
|
+
activatesOn: Events.SetupIntentResolver,
|
|
57
|
+
activate: IntentResolver,
|
|
58
|
+
}),
|
|
59
|
+
defineModule({
|
|
60
|
+
id: `${meta.id}/module/blueprint`,
|
|
61
|
+
activatesOn: Events.SetupArtifactDefinition,
|
|
62
|
+
activate: BlueprintDefinition,
|
|
63
|
+
}),
|
|
64
|
+
]);
|
|
@@ -2,18 +2,22 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// ISSUE(burdon): defineArtifact
|
|
6
|
+
// @ts-nocheck
|
|
6
7
|
|
|
7
|
-
import
|
|
8
|
-
import
|
|
8
|
+
import * as Function from 'effect/Function';
|
|
9
|
+
import * as Schema from 'effect/Schema';
|
|
10
|
+
|
|
11
|
+
import { ToolResult, createTool } from '@dxos/ai';
|
|
12
|
+
import { Capabilities, type PromiseIntentDispatcher, chain, contributes, createIntent } from '@dxos/app-framework';
|
|
9
13
|
import { createArtifactElement } from '@dxos/assistant';
|
|
10
14
|
import { defineArtifact } from '@dxos/blueprints';
|
|
11
15
|
import { Obj, Query } from '@dxos/echo';
|
|
12
16
|
import { invariant } from '@dxos/invariant';
|
|
13
17
|
import { SpaceAction } from '@dxos/plugin-space/types';
|
|
14
|
-
import { Filter,
|
|
18
|
+
import { Filter, type Space } from '@dxos/react-client/echo';
|
|
15
19
|
import { KanbanView } from '@dxos/react-ui-kanban';
|
|
16
|
-
import {
|
|
20
|
+
import { View } from '@dxos/schema';
|
|
17
21
|
import { isNonNullable } from '@dxos/util';
|
|
18
22
|
|
|
19
23
|
import { meta } from '../meta';
|
|
@@ -49,7 +53,7 @@ export default () => {
|
|
|
49
53
|
caption: 'Creating kanban board...',
|
|
50
54
|
schema: Schema.Struct({
|
|
51
55
|
typename: Schema.String.annotations({
|
|
52
|
-
description: 'The fully qualified
|
|
56
|
+
description: 'The fully qualified name of the record type to use for the kanban cards.',
|
|
53
57
|
}),
|
|
54
58
|
pivotColumn: Schema.optional(Schema.String).annotations({
|
|
55
59
|
description: 'Optional field name to use as the column pivot.',
|
|
@@ -65,7 +69,7 @@ export default () => {
|
|
|
65
69
|
return ToolResult.Error(`Schema not found: ${typename}`);
|
|
66
70
|
}
|
|
67
71
|
|
|
68
|
-
const intent = pipe(
|
|
72
|
+
const intent = Function.pipe(
|
|
69
73
|
createIntent(KanbanAction.Create, {
|
|
70
74
|
space: extensions.space,
|
|
71
75
|
typename,
|
|
@@ -90,7 +94,7 @@ export default () => {
|
|
|
90
94
|
execute: async (_input, { extensions }) => {
|
|
91
95
|
invariant(extensions?.space, 'No space');
|
|
92
96
|
const space = extensions.space;
|
|
93
|
-
const { objects } = await space.db.query(Filter.type(
|
|
97
|
+
const { objects } = await space.db.query(Filter.type(View.View)).run();
|
|
94
98
|
|
|
95
99
|
const boardInfo = await Promise.all(
|
|
96
100
|
objects.map(async (view) => {
|
|
@@ -100,7 +104,7 @@ export default () => {
|
|
|
100
104
|
}
|
|
101
105
|
|
|
102
106
|
return {
|
|
103
|
-
id:
|
|
107
|
+
id: Obj.getDXN(view).toString(),
|
|
104
108
|
name: view.name ?? 'Unnamed Kanban',
|
|
105
109
|
typename: view.query.typename,
|
|
106
110
|
};
|
|
@@ -120,8 +124,8 @@ export default () => {
|
|
|
120
124
|
const space = extensions.space;
|
|
121
125
|
const view = (await space.db
|
|
122
126
|
// TODO(wittjosiah): Filter.and should aggregate type
|
|
123
|
-
.query(Query.select(Filter.and(Filter.type(
|
|
124
|
-
.first()) as
|
|
127
|
+
.query(Query.select(Filter.and(Filter.type(View.View), Filter.ids(id))))
|
|
128
|
+
.first()) as View.View;
|
|
125
129
|
|
|
126
130
|
const kanban = await view.presentation.load();
|
|
127
131
|
invariant(Obj.instanceOf(KanbanView, kanban));
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Capabilities, contributes } from '@dxos/app-framework';
|
|
6
|
+
import { Blueprint, Template } from '@dxos/blueprints';
|
|
7
|
+
import { type FunctionDefinition } from '@dxos/functions';
|
|
8
|
+
import { trim } from '@dxos/util';
|
|
9
|
+
|
|
10
|
+
const functions: FunctionDefinition[] = [];
|
|
11
|
+
const tools: string[] = [];
|
|
12
|
+
|
|
13
|
+
export default () => {
|
|
14
|
+
return [
|
|
15
|
+
contributes(Capabilities.Functions, functions),
|
|
16
|
+
contributes(
|
|
17
|
+
Capabilities.BlueprintDefinition,
|
|
18
|
+
Blueprint.make({
|
|
19
|
+
key: 'dxos.org/blueprint/kanban',
|
|
20
|
+
name: 'Kanban',
|
|
21
|
+
tools: Blueprint.toolDefinitions({ functions, tools }),
|
|
22
|
+
instructions: Template.make({
|
|
23
|
+
source: trim`
|
|
24
|
+
You can create and update kanban boards to show data in sorted columns defined by schema.
|
|
25
|
+
`,
|
|
26
|
+
}),
|
|
27
|
+
}),
|
|
28
|
+
),
|
|
29
|
+
];
|
|
30
|
+
};
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
import { lazy } from '@dxos/app-framework';
|
|
6
6
|
|
|
7
|
-
export const
|
|
7
|
+
export const BlueprintDefinition = lazy(() => import('./blueprint-definition'));
|
|
8
8
|
export const IntentResolver = lazy(() => import('./intent-resolver'));
|
|
9
9
|
export const ReactSurface = lazy(() => import('./react-surface'));
|
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { Capabilities, type PluginContext, contributes, createResolver } from '@dxos/app-framework';
|
|
6
6
|
import { invariant } from '@dxos/invariant';
|
|
7
7
|
import { ClientCapabilities } from '@dxos/plugin-client';
|
|
8
8
|
import { getSpace } from '@dxos/react-client/echo';
|
|
9
|
-
import {
|
|
9
|
+
import { Kanban } from '@dxos/react-ui-kanban/types';
|
|
10
|
+
import { ProjectionModel, getTypenameFromQuery } from '@dxos/schema';
|
|
10
11
|
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
12
|
+
import { meta } from '../meta';
|
|
13
|
+
import { KanbanAction } from '../types';
|
|
13
14
|
|
|
14
15
|
export default (context: PluginContext) =>
|
|
15
16
|
contributes(Capabilities.IntentResolver, [
|
|
@@ -17,12 +18,12 @@ export default (context: PluginContext) =>
|
|
|
17
18
|
intent: KanbanAction.Create,
|
|
18
19
|
resolve: async ({ space, name, typename, initialPivotColumn }) => {
|
|
19
20
|
const client = context.getCapability(ClientCapabilities.Client);
|
|
20
|
-
const { view } = await
|
|
21
|
+
const { view } = await Kanban.makeView({
|
|
21
22
|
client,
|
|
22
23
|
space,
|
|
23
24
|
name,
|
|
24
25
|
typename,
|
|
25
|
-
initialPivotColumn,
|
|
26
|
+
pivotFieldName: initialPivotColumn,
|
|
26
27
|
});
|
|
27
28
|
return { data: { object: view } };
|
|
28
29
|
},
|
|
@@ -30,7 +31,7 @@ export default (context: PluginContext) =>
|
|
|
30
31
|
createResolver({
|
|
31
32
|
intent: KanbanAction.DeleteCardField,
|
|
32
33
|
resolve: async ({ view, fieldId, deletionData }, undo) => {
|
|
33
|
-
const schema = getSpace(view)?.db.schemaRegistry.getSchema(view.query.
|
|
34
|
+
const schema = getSpace(view)?.db.schemaRegistry.getSchema(getTypenameFromQuery(view.query.ast)!);
|
|
34
35
|
invariant(schema);
|
|
35
36
|
const projection = new ProjectionModel(schema.jsonSchema, view.projection);
|
|
36
37
|
|
|
@@ -38,7 +39,7 @@ export default (context: PluginContext) =>
|
|
|
38
39
|
const { deleted, index } = projection.deleteFieldProjection(fieldId);
|
|
39
40
|
return {
|
|
40
41
|
undoable: {
|
|
41
|
-
message: ['card field deleted label', { ns:
|
|
42
|
+
message: ['card field deleted label', { ns: meta.id }],
|
|
42
43
|
data: { deletionData: { ...deleted, index } },
|
|
43
44
|
},
|
|
44
45
|
};
|
|
@@ -58,7 +59,7 @@ export default (context: PluginContext) =>
|
|
|
58
59
|
space.db.remove(card);
|
|
59
60
|
return {
|
|
60
61
|
undoable: {
|
|
61
|
-
message: ['card deleted label', { ns:
|
|
62
|
+
message: ['card deleted label', { ns: meta.id }],
|
|
62
63
|
data: { card },
|
|
63
64
|
},
|
|
64
65
|
};
|
|
@@ -2,17 +2,18 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import type * as Schema from 'effect/Schema';
|
|
6
6
|
import React, { useMemo } from 'react';
|
|
7
7
|
|
|
8
|
-
import { Capabilities, contributes, createSurface
|
|
8
|
+
import { Capabilities, contributes, createSurface } from '@dxos/app-framework';
|
|
9
|
+
import { useCapabilities } from '@dxos/app-framework/react';
|
|
9
10
|
import { Obj, Type } from '@dxos/echo';
|
|
10
11
|
import { findAnnotation } from '@dxos/effect';
|
|
11
12
|
import { ClientCapabilities } from '@dxos/plugin-client';
|
|
12
|
-
import { getSpace, isSpace
|
|
13
|
+
import { type Space, getSpace, isSpace } from '@dxos/react-client/echo';
|
|
13
14
|
import { type InputProps, SelectInput, useFormValues } from '@dxos/react-ui-form';
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
15
|
+
import { Kanban } from '@dxos/react-ui-kanban/types';
|
|
16
|
+
import { type Collection, View } from '@dxos/schema';
|
|
16
17
|
|
|
17
18
|
import { KanbanContainer, KanbanViewEditor } from '../components';
|
|
18
19
|
import { meta } from '../meta';
|
|
@@ -23,16 +24,16 @@ export default () =>
|
|
|
23
24
|
createSurface({
|
|
24
25
|
id: meta.id,
|
|
25
26
|
role: ['article', 'section'],
|
|
26
|
-
filter: (data): data is { subject:
|
|
27
|
-
Obj.instanceOf(
|
|
27
|
+
filter: (data): data is { subject: View.View } =>
|
|
28
|
+
Obj.instanceOf(View.View, data.subject) && Obj.instanceOf(Kanban.Kanban, data.subject.presentation.target),
|
|
28
29
|
component: ({ data, role }) => <KanbanContainer view={data.subject} role={role} />,
|
|
29
30
|
}),
|
|
30
31
|
createSurface({
|
|
31
32
|
id: `${meta.id}/object-settings`,
|
|
32
33
|
role: 'object-settings',
|
|
33
34
|
position: 'hoist',
|
|
34
|
-
filter: (data): data is { subject:
|
|
35
|
-
Obj.instanceOf(
|
|
35
|
+
filter: (data): data is { subject: View.View } =>
|
|
36
|
+
Obj.instanceOf(View.View, data.subject) && Obj.instanceOf(Kanban.Kanban, data.subject.presentation.target),
|
|
36
37
|
component: ({ data }) => <KanbanViewEditor view={data.subject} />,
|
|
37
38
|
}),
|
|
38
39
|
createSurface({
|
|
@@ -40,7 +41,11 @@ export default () =>
|
|
|
40
41
|
role: 'form-input',
|
|
41
42
|
filter: (
|
|
42
43
|
data,
|
|
43
|
-
): data is {
|
|
44
|
+
): data is {
|
|
45
|
+
prop: string;
|
|
46
|
+
schema: Schema.Schema<any>;
|
|
47
|
+
target: Space | Collection.Collection | undefined;
|
|
48
|
+
} => {
|
|
44
49
|
const annotation = findAnnotation<boolean>((data.schema as Schema.Schema.All).ast, PivotColumnAnnotationId);
|
|
45
50
|
return !!annotation;
|
|
46
51
|
},
|
|
@@ -2,14 +2,12 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@
|
|
6
|
-
|
|
7
|
-
import { type StoryObj, type Meta } from '@storybook/react-vite';
|
|
5
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
8
6
|
import React, { useCallback, useEffect, useState } from 'react';
|
|
9
7
|
|
|
10
8
|
import { IntentPlugin, SettingsPlugin } from '@dxos/app-framework';
|
|
11
9
|
import { withPluginManager } from '@dxos/app-framework/testing';
|
|
12
|
-
import { Obj, Type } from '@dxos/echo';
|
|
10
|
+
import { Obj, type QueryAST, Type } from '@dxos/echo';
|
|
13
11
|
import { invariant } from '@dxos/invariant';
|
|
14
12
|
import { ClientPlugin } from '@dxos/plugin-client';
|
|
15
13
|
import { PreviewPlugin } from '@dxos/plugin-preview';
|
|
@@ -19,16 +17,17 @@ import { StorybookLayoutPlugin } from '@dxos/plugin-storybook-layout';
|
|
|
19
17
|
import { ThemePlugin } from '@dxos/plugin-theme';
|
|
20
18
|
import { faker } from '@dxos/random';
|
|
21
19
|
import { useClient } from '@dxos/react-client';
|
|
22
|
-
import { Filter,
|
|
20
|
+
import { Filter, useQuery, useSchema, useSpaces } from '@dxos/react-client/echo';
|
|
21
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
23
22
|
import { ViewEditor } from '@dxos/react-ui-form';
|
|
24
|
-
import { Kanban
|
|
23
|
+
import { Kanban as KanbanComponent, useKanbanModel } from '@dxos/react-ui-kanban';
|
|
24
|
+
import { Kanban } from '@dxos/react-ui-kanban/types';
|
|
25
25
|
import { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';
|
|
26
26
|
import { defaultTx } from '@dxos/react-ui-theme';
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
27
|
+
import { ProjectionModel, View, getTypenameFromQuery } from '@dxos/schema';
|
|
28
|
+
import { Organization, Person } from '@dxos/types';
|
|
29
29
|
|
|
30
30
|
import { translations } from '../translations';
|
|
31
|
-
import { createKanban } from '../types';
|
|
32
31
|
|
|
33
32
|
faker.seed(0);
|
|
34
33
|
|
|
@@ -41,17 +40,18 @@ const rollOrg = () => ({
|
|
|
41
40
|
description: faker.lorem.paragraph(),
|
|
42
41
|
image: faker.image.url(),
|
|
43
42
|
website: faker.internet.url(),
|
|
44
|
-
status: faker.helpers.arrayElement(
|
|
43
|
+
status: faker.helpers.arrayElement(Organization.StatusOptions).id as Organization.Organization['status'],
|
|
45
44
|
});
|
|
46
45
|
|
|
47
46
|
const StorybookKanban = () => {
|
|
48
47
|
const client = useClient();
|
|
49
48
|
const spaces = useSpaces();
|
|
50
49
|
const space = spaces[spaces.length - 1];
|
|
51
|
-
const views = useQuery(space, Filter.type(
|
|
52
|
-
const [view, setView] = useState<
|
|
50
|
+
const views = useQuery(space, Filter.type(View.View));
|
|
51
|
+
const [view, setView] = useState<View.View>();
|
|
53
52
|
const [projection, setProjection] = useState<ProjectionModel>();
|
|
54
|
-
const
|
|
53
|
+
const typename = view?.query ? getTypenameFromQuery(view.query.ast) : undefined;
|
|
54
|
+
const schema = useSchema(client, space, typename);
|
|
55
55
|
|
|
56
56
|
useEffect(() => {
|
|
57
57
|
if (views.length && !view) {
|
|
@@ -97,14 +97,14 @@ const StorybookKanban = () => {
|
|
|
97
97
|
|
|
98
98
|
const handleRemoveCard = useCallback((card: { id: string }) => space.db.remove(card), [space]);
|
|
99
99
|
|
|
100
|
-
const
|
|
101
|
-
(
|
|
100
|
+
const handleUpdateQuery = useCallback(
|
|
101
|
+
(newQuery: QueryAST.Query) => {
|
|
102
102
|
invariant(schema);
|
|
103
103
|
invariant(Type.isMutable(schema));
|
|
104
104
|
invariant(view);
|
|
105
105
|
|
|
106
|
-
schema.updateTypename(
|
|
107
|
-
view.query.
|
|
106
|
+
schema.updateTypename(getTypenameFromQuery(newQuery));
|
|
107
|
+
view.query.ast = newQuery;
|
|
108
108
|
},
|
|
109
109
|
[view, schema],
|
|
110
110
|
);
|
|
@@ -115,18 +115,18 @@ const StorybookKanban = () => {
|
|
|
115
115
|
|
|
116
116
|
return (
|
|
117
117
|
<div className='grow grid grid-cols-[1fr_350px]'>
|
|
118
|
-
{model ? <
|
|
118
|
+
{model ? <KanbanComponent model={model} onAddCard={handleAddCard} onRemoveCard={handleRemoveCard} /> : <div />}
|
|
119
119
|
<div className='flex flex-col bs-full border-is border-separator overflow-y-auto'>
|
|
120
120
|
<ViewEditor
|
|
121
121
|
registry={space?.db.schemaRegistry}
|
|
122
122
|
schema={schema}
|
|
123
123
|
view={view}
|
|
124
|
-
|
|
124
|
+
onQueryChanged={handleUpdateQuery}
|
|
125
125
|
onDelete={(fieldId: string) => {
|
|
126
126
|
console.log('[ViewEditor]', 'onDelete', fieldId);
|
|
127
127
|
}}
|
|
128
128
|
/>
|
|
129
|
-
<SyntaxHighlighter language='json' className='
|
|
129
|
+
<SyntaxHighlighter language='json' className='text-xs'>
|
|
130
130
|
{JSON.stringify({ view, schema }, null, 2)}
|
|
131
131
|
</SyntaxHighlighter>
|
|
132
132
|
</div>
|
|
@@ -142,48 +142,53 @@ type StoryProps = {
|
|
|
142
142
|
// Story definitions.
|
|
143
143
|
//
|
|
144
144
|
|
|
145
|
-
const meta
|
|
145
|
+
const meta = {
|
|
146
146
|
title: 'plugins/plugin-kanban/Kanban',
|
|
147
147
|
component: StorybookKanban,
|
|
148
148
|
render: () => <StorybookKanban />,
|
|
149
|
-
parameters: { translations },
|
|
150
149
|
decorators: [
|
|
151
|
-
|
|
150
|
+
withTheme,
|
|
152
151
|
withPluginManager({
|
|
153
152
|
plugins: [
|
|
154
|
-
ThemePlugin({ tx: defaultTx }),
|
|
155
153
|
ClientPlugin({
|
|
156
|
-
types: [
|
|
157
|
-
onClientInitialized: async (
|
|
154
|
+
types: [Organization.Organization, Person.Person, View.View, Kanban.Kanban],
|
|
155
|
+
onClientInitialized: async ({ client }) => {
|
|
158
156
|
await client.halo.createIdentity();
|
|
159
157
|
const space = await client.spaces.create();
|
|
160
158
|
await space.waitUntilReady();
|
|
161
|
-
const { view } = await
|
|
159
|
+
const { view } = await Kanban.makeView({
|
|
162
160
|
client,
|
|
163
161
|
space,
|
|
164
|
-
typename:
|
|
165
|
-
|
|
162
|
+
typename: Organization.Organization.typename,
|
|
163
|
+
pivotFieldName: 'status',
|
|
166
164
|
});
|
|
167
165
|
space.db.add(view);
|
|
168
166
|
|
|
169
167
|
// TODO(burdon): Replace with sdk/schema/testing.
|
|
170
168
|
Array.from({ length: 80 }).map(() => {
|
|
171
|
-
return space.db.add(Obj.make(
|
|
169
|
+
return space.db.add(Obj.make(Organization.Organization, rollOrg()));
|
|
172
170
|
});
|
|
173
171
|
},
|
|
174
172
|
}),
|
|
175
|
-
|
|
176
|
-
PreviewPlugin(),
|
|
177
|
-
SpacePlugin(),
|
|
173
|
+
SpacePlugin({}),
|
|
178
174
|
IntentPlugin(),
|
|
179
175
|
SettingsPlugin(),
|
|
176
|
+
|
|
177
|
+
// UI
|
|
178
|
+
ThemePlugin({ tx: defaultTx }),
|
|
179
|
+
PreviewPlugin(),
|
|
180
|
+
StorybookLayoutPlugin({}),
|
|
180
181
|
],
|
|
181
182
|
}),
|
|
182
183
|
],
|
|
183
|
-
|
|
184
|
+
parameters: {
|
|
185
|
+
layout: 'fullscreen',
|
|
186
|
+
translations,
|
|
187
|
+
},
|
|
188
|
+
} satisfies Meta<typeof StorybookKanban>;
|
|
184
189
|
|
|
185
190
|
export default meta;
|
|
186
191
|
|
|
187
|
-
type Story = StoryObj<
|
|
192
|
+
type Story = StoryObj<typeof meta>;
|
|
188
193
|
|
|
189
194
|
export const Default: Story = {};
|