@dxos/plugin-kanban 0.8.3 → 0.8.4-main.1da679c
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-6JEDX6HA.mjs → chunk-NCNNL74W.mjs} +9 -12
- package/dist/lib/browser/chunk-NCNNL74W.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +21 -20
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/intent-resolver-UWM5C5LZ.mjs +111 -0
- package/dist/lib/browser/intent-resolver-UWM5C5LZ.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-surface-HJL2JRJP.mjs → react-surface-4JNCLFQB.mjs} +48 -100
- package/dist/lib/browser/react-surface-4JNCLFQB.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +11 -0
- 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-7DHZSNGQ.mjs → chunk-5B3LKGA7.mjs} +9 -12
- package/dist/lib/node-esm/chunk-5B3LKGA7.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +21 -20
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/intent-resolver-JDQ7I5HR.mjs +112 -0
- package/dist/lib/node-esm/intent-resolver-JDQ7I5HR.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{react-surface-257WTPQZ.mjs → react-surface-2C7LFFY5.mjs} +48 -100
- package/dist/lib/node-esm/react-surface-2C7LFFY5.mjs.map +7 -0
- package/dist/lib/node-esm/{types.mjs → types/index.mjs} +4 -6
- 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 +3 -3
- package/dist/types/src/components/KanbanContainer.d.ts.map +1 -1
- package/dist/types/src/components/KanbanContainer.stories.d.ts +36 -5
- package/dist/types/src/components/KanbanContainer.stories.d.ts.map +1 -1
- package/dist/types/src/components/KanbanViewEditor.d.ts +3 -3
- package/dist/types/src/components/KanbanViewEditor.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/translations.d.ts +24 -53
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/index.d.ts +3 -0
- package/dist/types/src/types/index.d.ts.map +1 -0
- package/dist/types/src/{types.d.ts → types/schema.d.ts} +4 -13
- package/dist/types/src/types/schema.d.ts.map +1 -0
- package/dist/types/src/types/types.d.ts +4 -0
- package/dist/types/src/types/types.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +36 -31
- package/src/KanbanPlugin.tsx +10 -8
- package/src/capabilities/artifact-definition.ts +32 -21
- package/src/capabilities/blueprint-definition.ts +30 -0
- package/src/capabilities/index.ts +1 -1
- package/src/capabilities/intent-resolver.ts +14 -14
- package/src/capabilities/react-surface.tsx +16 -13
- package/src/components/KanbanContainer.stories.tsx +53 -55
- package/src/components/KanbanContainer.tsx +12 -12
- package/src/components/KanbanViewEditor.tsx +26 -68
- package/src/index.ts +2 -1
- package/src/translations.ts +7 -7
- package/src/types/index.ts +6 -0
- package/src/{types.ts → types/schema.ts} +6 -27
- package/src/types/types.ts +7 -0
- package/dist/lib/browser/artifact-definition-6HNQFL2M.mjs +0 -178
- package/dist/lib/browser/artifact-definition-6HNQFL2M.mjs.map +0 -7
- package/dist/lib/browser/chunk-6JEDX6HA.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-QQOH5EV2.mjs +0 -297
- package/dist/lib/browser/intent-resolver-QQOH5EV2.mjs.map +0 -7
- package/dist/lib/browser/react-surface-HJL2JRJP.mjs.map +0 -7
- package/dist/lib/browser/types.mjs +0 -13
- package/dist/lib/node/artifact-definition-GRCAYCVG.cjs +0 -193
- package/dist/lib/node/artifact-definition-GRCAYCVG.cjs.map +0 -7
- package/dist/lib/node/chunk-ATDUVDIE.cjs +0 -108
- package/dist/lib/node/chunk-ATDUVDIE.cjs.map +0 -7
- package/dist/lib/node/index.cjs +0 -128
- package/dist/lib/node/index.cjs.map +0 -7
- package/dist/lib/node/intent-resolver-6ZNOIHKY.cjs +0 -308
- package/dist/lib/node/intent-resolver-6ZNOIHKY.cjs.map +0 -7
- package/dist/lib/node/meta.json +0 -1
- package/dist/lib/node/react-surface-G2J6F7U5.cjs +0 -322
- package/dist/lib/node/react-surface-G2J6F7U5.cjs.map +0 -7
- package/dist/lib/node/types.cjs +0 -35
- package/dist/lib/node/types.cjs.map +0 -7
- package/dist/lib/node-esm/artifact-definition-FA2IAAUQ.mjs +0 -179
- package/dist/lib/node-esm/artifact-definition-FA2IAAUQ.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-7DHZSNGQ.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-4TYFDM4E.mjs +0 -298
- package/dist/lib/node-esm/intent-resolver-4TYFDM4E.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-257WTPQZ.mjs.map +0 -7
- package/dist/types/src/testing/index.d.ts +0 -3
- package/dist/types/src/testing/index.d.ts.map +0 -1
- package/dist/types/src/testing/initialize-kanban.d.ts +0 -17
- package/dist/types/src/testing/initialize-kanban.d.ts.map +0 -1
- package/dist/types/src/testing/kanban-manager.d.ts +0 -7
- package/dist/types/src/testing/kanban-manager.d.ts.map +0 -1
- package/dist/types/src/testing/playwright/smoke.spec.d.ts +0 -2
- package/dist/types/src/testing/playwright/smoke.spec.d.ts.map +0 -1
- package/dist/types/src/types.d.ts.map +0 -1
- package/src/testing/index.ts +0 -6
- package/src/testing/initialize-kanban.ts +0 -128
- package/src/testing/kanban-manager.ts +0 -13
- package/src/testing/playwright/playwright.config.cts +0 -18
- package/src/testing/playwright/smoke.spec.ts +0 -7
- /package/dist/lib/browser/{types.mjs.map → types/index.mjs.map} +0 -0
- /package/dist/lib/node-esm/{types.mjs.map → types/index.mjs.map} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/plugin-kanban",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.4-main.1da679c",
|
|
4
4
|
"description": "Kanban DXOS Surface plugin",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -10,11 +10,13 @@
|
|
|
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
16
|
"node": "./dist/lib/node-esm/index.mjs"
|
|
16
17
|
},
|
|
17
18
|
"./types": {
|
|
19
|
+
"source": "./src/types/index.ts",
|
|
18
20
|
"types": "./dist/types/src/types/index.d.ts",
|
|
19
21
|
"browser": "./dist/lib/browser/types/index.mjs",
|
|
20
22
|
"node": "./dist/lib/node-esm/types/index.mjs"
|
|
@@ -35,47 +37,50 @@
|
|
|
35
37
|
"dependencies": {
|
|
36
38
|
"@preact-signals/safe-react": "^0.9.0",
|
|
37
39
|
"@preact/signals-core": "^1.9.0",
|
|
38
|
-
"effect": "3.
|
|
39
|
-
"@dxos/ai": "0.8.
|
|
40
|
-
"@dxos/app-framework": "0.8.
|
|
41
|
-
"@dxos/assistant": "0.8.
|
|
42
|
-
"@dxos/
|
|
43
|
-
"@dxos/
|
|
44
|
-
"@dxos/
|
|
45
|
-
"@dxos/echo": "0.8.
|
|
46
|
-
"@dxos/effect": "0.8.
|
|
47
|
-
"@dxos/
|
|
48
|
-
"@dxos/
|
|
49
|
-
"@dxos/
|
|
50
|
-
"@dxos/plugin-
|
|
51
|
-
"@dxos/plugin-
|
|
52
|
-
"@dxos/
|
|
53
|
-
"@dxos/
|
|
54
|
-
"@dxos/
|
|
55
|
-
"@dxos/react-ui
|
|
56
|
-
"@dxos/react-ui-
|
|
57
|
-
"@dxos/
|
|
58
|
-
"@dxos/
|
|
40
|
+
"effect": "3.17.7",
|
|
41
|
+
"@dxos/ai": "0.8.4-main.1da679c",
|
|
42
|
+
"@dxos/app-framework": "0.8.4-main.1da679c",
|
|
43
|
+
"@dxos/assistant": "0.8.4-main.1da679c",
|
|
44
|
+
"@dxos/async": "0.8.4-main.1da679c",
|
|
45
|
+
"@dxos/echo": "0.8.4-main.1da679c",
|
|
46
|
+
"@dxos/blueprints": "0.8.4-main.1da679c",
|
|
47
|
+
"@dxos/echo-schema": "0.8.4-main.1da679c",
|
|
48
|
+
"@dxos/effect": "0.8.4-main.1da679c",
|
|
49
|
+
"@dxos/functions": "0.8.4-main.1da679c",
|
|
50
|
+
"@dxos/invariant": "0.8.4-main.1da679c",
|
|
51
|
+
"@dxos/log": "0.8.4-main.1da679c",
|
|
52
|
+
"@dxos/plugin-space": "0.8.4-main.1da679c",
|
|
53
|
+
"@dxos/plugin-client": "0.8.4-main.1da679c",
|
|
54
|
+
"@dxos/react-client": "0.8.4-main.1da679c",
|
|
55
|
+
"@dxos/random": "0.8.4-main.1da679c",
|
|
56
|
+
"@dxos/plugin-search": "0.8.4-main.1da679c",
|
|
57
|
+
"@dxos/react-ui": "0.8.4-main.1da679c",
|
|
58
|
+
"@dxos/react-ui-form": "0.8.4-main.1da679c",
|
|
59
|
+
"@dxos/react-ui-kanban": "0.8.4-main.1da679c",
|
|
60
|
+
"@dxos/react-ui-stack": "0.8.4-main.1da679c",
|
|
61
|
+
"@dxos/util": "0.8.4-main.1da679c",
|
|
62
|
+
"@dxos/schema": "0.8.4-main.1da679c",
|
|
63
|
+
"@dxos/plugin-graph": "0.8.4-main.1da679c"
|
|
59
64
|
},
|
|
60
65
|
"devDependencies": {
|
|
61
66
|
"@types/react": "~18.2.0",
|
|
62
67
|
"@types/react-dom": "~18.2.0",
|
|
63
68
|
"react": "~18.2.0",
|
|
64
69
|
"react-dom": "~18.2.0",
|
|
65
|
-
"vite": "
|
|
66
|
-
"@dxos/plugin-preview": "0.8.
|
|
67
|
-
"@dxos/plugin-theme": "0.8.
|
|
68
|
-
"@dxos/react-ui": "0.8.
|
|
69
|
-
"@dxos/storybook-utils": "0.8.
|
|
70
|
-
"@dxos/react-ui-
|
|
71
|
-
"@dxos/
|
|
70
|
+
"vite": "7.1.1",
|
|
71
|
+
"@dxos/plugin-preview": "0.8.4-main.1da679c",
|
|
72
|
+
"@dxos/plugin-theme": "0.8.4-main.1da679c",
|
|
73
|
+
"@dxos/react-ui-theme": "0.8.4-main.1da679c",
|
|
74
|
+
"@dxos/storybook-utils": "0.8.4-main.1da679c",
|
|
75
|
+
"@dxos/react-ui-syntax-highlighter": "0.8.4-main.1da679c",
|
|
76
|
+
"@dxos/test-utils": "0.8.4-main.1da679c"
|
|
72
77
|
},
|
|
73
78
|
"peerDependencies": {
|
|
74
79
|
"effect": "^3.13.3",
|
|
75
80
|
"react": "~18.2.0",
|
|
76
81
|
"react-dom": "~18.2.0",
|
|
77
|
-
"@dxos/react-ui": "0.8.
|
|
78
|
-
"@dxos/react-ui-theme": "0.8.
|
|
82
|
+
"@dxos/react-ui": "0.8.4-main.1da679c",
|
|
83
|
+
"@dxos/react-ui-theme": "0.8.4-main.1da679c"
|
|
79
84
|
},
|
|
80
85
|
"publishConfig": {
|
|
81
86
|
"access": "public"
|
package/src/KanbanPlugin.tsx
CHANGED
|
@@ -2,15 +2,16 @@
|
|
|
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
|
-
import translations from './translations';
|
|
14
|
+
import { translations } from './translations';
|
|
14
15
|
import { CreateKanbanSchema, KanbanAction } from './types';
|
|
15
16
|
|
|
16
17
|
export const KanbanPlugin = () =>
|
|
@@ -25,7 +26,7 @@ export const KanbanPlugin = () =>
|
|
|
25
26
|
activatesOn: Events.SetupMetadata,
|
|
26
27
|
activate: () =>
|
|
27
28
|
contributes(Capabilities.Metadata, {
|
|
28
|
-
id:
|
|
29
|
+
id: Kanban.Kanban.typename,
|
|
29
30
|
metadata: {
|
|
30
31
|
icon: 'ph--kanban--regular',
|
|
31
32
|
},
|
|
@@ -38,8 +39,9 @@ export const KanbanPlugin = () =>
|
|
|
38
39
|
contributes(
|
|
39
40
|
SpaceCapabilities.ObjectForm,
|
|
40
41
|
defineObjectForm({
|
|
41
|
-
objectSchema:
|
|
42
|
+
objectSchema: Kanban.Kanban,
|
|
42
43
|
formSchema: CreateKanbanSchema,
|
|
44
|
+
hidden: true,
|
|
43
45
|
getIntent: (props, options) => createIntent(KanbanAction.Create, { ...props, space: options.space }),
|
|
44
46
|
}),
|
|
45
47
|
),
|
|
@@ -55,8 +57,8 @@ export const KanbanPlugin = () =>
|
|
|
55
57
|
activate: IntentResolver,
|
|
56
58
|
}),
|
|
57
59
|
defineModule({
|
|
58
|
-
id: `${meta.id}/module/
|
|
60
|
+
id: `${meta.id}/module/blueprint`,
|
|
59
61
|
activatesOn: Events.SetupArtifactDefinition,
|
|
60
|
-
activate:
|
|
62
|
+
activate: BlueprintDefinition,
|
|
61
63
|
}),
|
|
62
64
|
]);
|
|
@@ -2,17 +2,22 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
// ISSUE(burdon): defineArtifact
|
|
6
|
+
// @ts-nocheck
|
|
7
|
+
|
|
5
8
|
import { Schema, pipe } from 'effect';
|
|
6
9
|
|
|
7
|
-
import {
|
|
8
|
-
import { Capabilities, chain, contributes, createIntent
|
|
9
|
-
import { defineArtifact } from '@dxos/artifact';
|
|
10
|
+
import { ToolResult, createTool } from '@dxos/ai';
|
|
11
|
+
import { Capabilities, type PromiseIntentDispatcher, chain, contributes, createIntent } from '@dxos/app-framework';
|
|
10
12
|
import { createArtifactElement } from '@dxos/assistant';
|
|
11
|
-
import {
|
|
13
|
+
import { defineArtifact } from '@dxos/blueprints';
|
|
14
|
+
import { Obj, Query } from '@dxos/echo';
|
|
12
15
|
import { invariant } from '@dxos/invariant';
|
|
13
16
|
import { SpaceAction } from '@dxos/plugin-space/types';
|
|
14
|
-
import { Filter,
|
|
15
|
-
import {
|
|
17
|
+
import { Filter, type Space, fullyQualifiedId } from '@dxos/react-client/echo';
|
|
18
|
+
import { KanbanView } from '@dxos/react-ui-kanban';
|
|
19
|
+
import { DataType } from '@dxos/schema';
|
|
20
|
+
import { isNonNullable } from '@dxos/util';
|
|
16
21
|
|
|
17
22
|
import { meta } from '../meta';
|
|
18
23
|
import { KanbanAction } from '../types';
|
|
@@ -37,7 +42,7 @@ export default () => {
|
|
|
37
42
|
- When adding items, you must not include the 'id' field -- it is automatically generated
|
|
38
43
|
- BEFORE adding items, always make sure the board has been shown to the user!
|
|
39
44
|
`,
|
|
40
|
-
schema:
|
|
45
|
+
schema: KanbanView,
|
|
41
46
|
tools: [
|
|
42
47
|
createTool(meta.id, {
|
|
43
48
|
name: 'create',
|
|
@@ -47,7 +52,7 @@ export default () => {
|
|
|
47
52
|
caption: 'Creating kanban board...',
|
|
48
53
|
schema: Schema.Struct({
|
|
49
54
|
typename: Schema.String.annotations({
|
|
50
|
-
description: 'The fully qualified
|
|
55
|
+
description: 'The fully qualified name of the record type to use for the kanban cards.',
|
|
51
56
|
}),
|
|
52
57
|
pivotColumn: Schema.optional(Schema.String).annotations({
|
|
53
58
|
description: 'Optional field name to use as the column pivot.',
|
|
@@ -88,19 +93,24 @@ export default () => {
|
|
|
88
93
|
execute: async (_input, { extensions }) => {
|
|
89
94
|
invariant(extensions?.space, 'No space');
|
|
90
95
|
const space = extensions.space;
|
|
91
|
-
const { objects
|
|
96
|
+
const { objects } = await space.db.query(Filter.type(DataType.View)).run();
|
|
92
97
|
|
|
93
98
|
const boardInfo = await Promise.all(
|
|
94
|
-
|
|
95
|
-
const
|
|
99
|
+
objects.map(async (view) => {
|
|
100
|
+
const kanban = await view.presentation.load();
|
|
101
|
+
if (!Obj.instanceOf(KanbanView, kanban)) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
|
|
96
105
|
return {
|
|
97
|
-
id: fullyQualifiedId(
|
|
98
|
-
|
|
106
|
+
id: fullyQualifiedId(view),
|
|
107
|
+
name: view.name ?? 'Unnamed Kanban',
|
|
108
|
+
typename: view.query.typename,
|
|
99
109
|
};
|
|
100
110
|
}),
|
|
101
111
|
);
|
|
102
112
|
|
|
103
|
-
return ToolResult.Success(boardInfo);
|
|
113
|
+
return ToolResult.Success(boardInfo.filter(isNonNullable));
|
|
104
114
|
},
|
|
105
115
|
}),
|
|
106
116
|
createTool(meta.id, {
|
|
@@ -111,12 +121,13 @@ export default () => {
|
|
|
111
121
|
execute: async ({ id }, { extensions }) => {
|
|
112
122
|
invariant(extensions?.space, 'No space');
|
|
113
123
|
const space = extensions.space;
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
124
|
+
const view = (await space.db
|
|
125
|
+
// TODO(wittjosiah): Filter.and should aggregate type
|
|
126
|
+
.query(Query.select(Filter.and(Filter.type(DataType.View), Filter.ids(id))))
|
|
127
|
+
.first()) as DataType.View;
|
|
117
128
|
|
|
118
|
-
const
|
|
119
|
-
invariant(
|
|
129
|
+
const kanban = await view.presentation.load();
|
|
130
|
+
invariant(Obj.instanceOf(KanbanView, kanban));
|
|
120
131
|
|
|
121
132
|
const typename = view.query.typename;
|
|
122
133
|
const schema = await space.db.schemaRegistry.query({ typename }).firstOrUndefined();
|
|
@@ -124,8 +135,8 @@ export default () => {
|
|
|
124
135
|
|
|
125
136
|
return ToolResult.Success({
|
|
126
137
|
schema,
|
|
127
|
-
columnField:
|
|
128
|
-
viewFields: view.fields,
|
|
138
|
+
columnField: kanban.columnFieldId,
|
|
139
|
+
viewFields: view.projection.fields,
|
|
129
140
|
});
|
|
130
141
|
},
|
|
131
142
|
}),
|
|
@@ -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,14 @@
|
|
|
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, typenameFromQuery } from '@dxos/schema';
|
|
10
11
|
|
|
11
12
|
import { KANBAN_PLUGIN } from '../meta';
|
|
12
|
-
import { initializeKanban } from '../testing';
|
|
13
13
|
import { KanbanAction } from '../types';
|
|
14
14
|
|
|
15
15
|
export default (context: PluginContext) =>
|
|
@@ -18,22 +18,22 @@ export default (context: PluginContext) =>
|
|
|
18
18
|
intent: KanbanAction.Create,
|
|
19
19
|
resolve: async ({ space, name, typename, initialPivotColumn }) => {
|
|
20
20
|
const client = context.getCapability(ClientCapabilities.Client);
|
|
21
|
-
const {
|
|
22
|
-
|
|
21
|
+
const { view } = await Kanban.makeView({
|
|
22
|
+
client,
|
|
23
|
+
space,
|
|
24
|
+
name,
|
|
25
|
+
typename,
|
|
26
|
+
pivotFieldName: initialPivotColumn,
|
|
27
|
+
});
|
|
28
|
+
return { data: { object: view } };
|
|
23
29
|
},
|
|
24
30
|
}),
|
|
25
31
|
createResolver({
|
|
26
32
|
intent: KanbanAction.DeleteCardField,
|
|
27
|
-
resolve: ({
|
|
28
|
-
|
|
29
|
-
invariant(kanban.cardView.target?.query.typename);
|
|
30
|
-
|
|
31
|
-
const schema =
|
|
32
|
-
kanban.cardView.target &&
|
|
33
|
-
getSpace(kanban)?.db.schemaRegistry.getSchema(kanban.cardView.target.query.typename);
|
|
33
|
+
resolve: async ({ view, fieldId, deletionData }, undo) => {
|
|
34
|
+
const schema = getSpace(view)?.db.schemaRegistry.getSchema(typenameFromQuery(view.query)!);
|
|
34
35
|
invariant(schema);
|
|
35
|
-
|
|
36
|
-
const projection = new ViewProjection(schema.jsonSchema, kanban.cardView.target);
|
|
36
|
+
const projection = new ProjectionModel(schema.jsonSchema, view.projection);
|
|
37
37
|
|
|
38
38
|
if (!undo) {
|
|
39
39
|
const { deleted, index } = projection.deleteFieldProjection(fieldId);
|
|
@@ -6,34 +6,37 @@ import { type Schema } from 'effect';
|
|
|
6
6
|
import React, { useMemo } from 'react';
|
|
7
7
|
|
|
8
8
|
import { Capabilities, contributes, createSurface, useCapabilities } from '@dxos/app-framework';
|
|
9
|
-
import { Type } from '@dxos/echo';
|
|
9
|
+
import { Obj, Type } from '@dxos/echo';
|
|
10
10
|
import { findAnnotation } from '@dxos/effect';
|
|
11
11
|
import { ClientCapabilities } from '@dxos/plugin-client';
|
|
12
|
-
import { getSpace, isSpace
|
|
12
|
+
import { type Space, getSpace, isSpace } from '@dxos/react-client/echo';
|
|
13
13
|
import { type InputProps, SelectInput, useFormValues } from '@dxos/react-ui-form';
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
14
|
+
import { Kanban } from '@dxos/react-ui-kanban/types';
|
|
15
|
+
import { DataType } from '@dxos/schema';
|
|
16
16
|
|
|
17
17
|
import { KanbanContainer, KanbanViewEditor } from '../components';
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
18
|
+
import { meta } from '../meta';
|
|
19
|
+
import { PivotColumnAnnotationId } from '../types';
|
|
20
20
|
|
|
21
21
|
export default () =>
|
|
22
22
|
contributes(Capabilities.ReactSurface, [
|
|
23
23
|
createSurface({
|
|
24
|
-
id:
|
|
24
|
+
id: meta.id,
|
|
25
25
|
role: ['article', 'section'],
|
|
26
|
-
filter: (data): data is { subject:
|
|
27
|
-
|
|
26
|
+
filter: (data): data is { subject: DataType.View } =>
|
|
27
|
+
Obj.instanceOf(DataType.View, data.subject) && Obj.instanceOf(Kanban.Kanban, data.subject.presentation.target),
|
|
28
|
+
component: ({ data, role }) => <KanbanContainer view={data.subject} role={role} />,
|
|
28
29
|
}),
|
|
29
30
|
createSurface({
|
|
30
|
-
id: `${
|
|
31
|
+
id: `${meta.id}/object-settings`,
|
|
31
32
|
role: 'object-settings',
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
position: 'hoist',
|
|
34
|
+
filter: (data): data is { subject: DataType.View } =>
|
|
35
|
+
Obj.instanceOf(DataType.View, data.subject) && Obj.instanceOf(Kanban.Kanban, data.subject.presentation.target),
|
|
36
|
+
component: ({ data }) => <KanbanViewEditor view={data.subject} />,
|
|
34
37
|
}),
|
|
35
38
|
createSurface({
|
|
36
|
-
id: `${
|
|
39
|
+
id: `${meta.id}/create-initial-schema-form-[pivot-column]`,
|
|
37
40
|
role: 'form-input',
|
|
38
41
|
filter: (
|
|
39
42
|
data,
|
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import '@dxos-theme';
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
7
8
|
import React, { useCallback, useEffect, useState } from 'react';
|
|
8
9
|
|
|
9
10
|
import { IntentPlugin, SettingsPlugin } from '@dxos/app-framework';
|
|
10
11
|
import { withPluginManager } from '@dxos/app-framework/testing';
|
|
11
|
-
import { Obj, Type } from '@dxos/echo';
|
|
12
|
+
import { Obj, Query, Type } from '@dxos/echo';
|
|
12
13
|
import { invariant } from '@dxos/invariant';
|
|
13
14
|
import { ClientPlugin } from '@dxos/plugin-client';
|
|
14
15
|
import { PreviewPlugin } from '@dxos/plugin-preview';
|
|
@@ -18,16 +19,16 @@ import { StorybookLayoutPlugin } from '@dxos/plugin-storybook-layout';
|
|
|
18
19
|
import { ThemePlugin } from '@dxos/plugin-theme';
|
|
19
20
|
import { faker } from '@dxos/random';
|
|
20
21
|
import { useClient } from '@dxos/react-client';
|
|
21
|
-
import { Filter,
|
|
22
|
+
import { Filter, useQuery, useSchema, useSpaces } from '@dxos/react-client/echo';
|
|
22
23
|
import { ViewEditor } from '@dxos/react-ui-form';
|
|
23
|
-
import { Kanban
|
|
24
|
+
import { Kanban as KanbanComponent, useKanbanModel } from '@dxos/react-ui-kanban';
|
|
25
|
+
import { Kanban } from '@dxos/react-ui-kanban/types';
|
|
24
26
|
import { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';
|
|
25
27
|
import { defaultTx } from '@dxos/react-ui-theme';
|
|
26
|
-
import { DataType,
|
|
28
|
+
import { DataType, ProjectionModel, typenameFromQuery } from '@dxos/schema';
|
|
27
29
|
import { withLayout } from '@dxos/storybook-utils';
|
|
28
30
|
|
|
29
|
-
import {
|
|
30
|
-
import translations from '../translations';
|
|
31
|
+
import { translations } from '../translations';
|
|
31
32
|
|
|
32
33
|
faker.seed(0);
|
|
33
34
|
|
|
@@ -40,39 +41,40 @@ const rollOrg = () => ({
|
|
|
40
41
|
description: faker.lorem.paragraph(),
|
|
41
42
|
image: faker.image.url(),
|
|
42
43
|
website: faker.internet.url(),
|
|
43
|
-
status: faker.helpers.arrayElement(DataType.OrganizationStatusOptions).id,
|
|
44
|
+
status: faker.helpers.arrayElement(DataType.OrganizationStatusOptions).id as DataType.Organization['status'],
|
|
44
45
|
});
|
|
45
46
|
|
|
46
47
|
const StorybookKanban = () => {
|
|
47
48
|
const client = useClient();
|
|
48
49
|
const spaces = useSpaces();
|
|
49
50
|
const space = spaces[spaces.length - 1];
|
|
50
|
-
const
|
|
51
|
-
const [
|
|
52
|
-
const [projection, setProjection] = useState<
|
|
53
|
-
const
|
|
51
|
+
const views = useQuery(space, Filter.type(DataType.View));
|
|
52
|
+
const [view, setView] = useState<DataType.View>();
|
|
53
|
+
const [projection, setProjection] = useState<ProjectionModel>();
|
|
54
|
+
const typename = view?.query ? typenameFromQuery(view.query) : undefined;
|
|
55
|
+
const schema = useSchema(client, space, typename);
|
|
54
56
|
|
|
55
57
|
useEffect(() => {
|
|
56
|
-
if (
|
|
57
|
-
const
|
|
58
|
-
|
|
58
|
+
if (views.length && !view) {
|
|
59
|
+
const view = views[0];
|
|
60
|
+
setView(view);
|
|
59
61
|
}
|
|
60
|
-
}, [
|
|
62
|
+
}, [views]);
|
|
61
63
|
|
|
62
64
|
useEffect(() => {
|
|
63
|
-
if (
|
|
65
|
+
if (view?.projection && schema) {
|
|
64
66
|
const jsonSchema = Type.toJsonSchema(schema);
|
|
65
|
-
setProjection(new
|
|
67
|
+
setProjection(new ProjectionModel(jsonSchema, view.projection));
|
|
66
68
|
}
|
|
67
69
|
// TODO(ZaymonFC): Is there a better way to get notified about deep changes in the json schema?
|
|
68
70
|
// @dmaretskyi? Once resolved, update in multiple places (e.g., storybooks).
|
|
69
|
-
}, [
|
|
71
|
+
}, [view?.projection, schema, JSON.stringify(schema ? Type.toJsonSchema(schema) : {})]);
|
|
70
72
|
|
|
71
73
|
const objects = useQuery(space, schema ? Filter.type(schema) : Filter.nothing());
|
|
72
74
|
const filteredObjects = useGlobalFilteredObjects(objects);
|
|
73
75
|
|
|
74
76
|
const model = useKanbanModel({
|
|
75
|
-
|
|
77
|
+
view,
|
|
76
78
|
schema,
|
|
77
79
|
projection,
|
|
78
80
|
items: filteredObjects,
|
|
@@ -96,39 +98,37 @@ const StorybookKanban = () => {
|
|
|
96
98
|
|
|
97
99
|
const handleRemoveCard = useCallback((card: { id: string }) => space.db.remove(card), [space]);
|
|
98
100
|
|
|
99
|
-
const
|
|
101
|
+
const handleUpdateQuery = useCallback(
|
|
100
102
|
(typename: string) => {
|
|
101
103
|
invariant(schema);
|
|
102
104
|
invariant(Type.isMutable(schema));
|
|
103
|
-
invariant(
|
|
105
|
+
invariant(view);
|
|
104
106
|
|
|
105
107
|
schema.updateTypename(typename);
|
|
106
|
-
|
|
108
|
+
view.query = Query.select(Filter.typename(typename)).ast;
|
|
107
109
|
},
|
|
108
|
-
[
|
|
110
|
+
[view, schema],
|
|
109
111
|
);
|
|
110
112
|
|
|
111
|
-
if (!schema || !
|
|
113
|
+
if (!schema || !view) {
|
|
112
114
|
return null;
|
|
113
115
|
}
|
|
114
116
|
|
|
115
117
|
return (
|
|
116
118
|
<div className='grow grid grid-cols-[1fr_350px]'>
|
|
117
|
-
{model ? <
|
|
119
|
+
{model ? <KanbanComponent model={model} onAddCard={handleAddCard} onRemoveCard={handleRemoveCard} /> : <div />}
|
|
118
120
|
<div className='flex flex-col bs-full border-is border-separator overflow-y-auto'>
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
onDelete
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
<SyntaxHighlighter language='json' className='w-full text-xs'>
|
|
131
|
-
{JSON.stringify({ cardView: kanban.cardView?.target, cardSchema: schema }, null, 2)}
|
|
121
|
+
<ViewEditor
|
|
122
|
+
registry={space?.db.schemaRegistry}
|
|
123
|
+
schema={schema}
|
|
124
|
+
view={view}
|
|
125
|
+
onQueryChanged={handleUpdateQuery}
|
|
126
|
+
onDelete={(fieldId: string) => {
|
|
127
|
+
console.log('[ViewEditor]', 'onDelete', fieldId);
|
|
128
|
+
}}
|
|
129
|
+
/>
|
|
130
|
+
<SyntaxHighlighter language='json' className='text-xs'>
|
|
131
|
+
{JSON.stringify({ view, schema }, null, 2)}
|
|
132
132
|
</SyntaxHighlighter>
|
|
133
133
|
</div>
|
|
134
134
|
</div>
|
|
@@ -143,7 +143,7 @@ type StoryProps = {
|
|
|
143
143
|
// Story definitions.
|
|
144
144
|
//
|
|
145
145
|
|
|
146
|
-
const meta
|
|
146
|
+
const meta = {
|
|
147
147
|
title: 'plugins/plugin-kanban/Kanban',
|
|
148
148
|
component: StorybookKanban,
|
|
149
149
|
render: () => <StorybookKanban />,
|
|
@@ -154,25 +154,23 @@ const meta: Meta<StoryProps> = {
|
|
|
154
154
|
plugins: [
|
|
155
155
|
ThemePlugin({ tx: defaultTx }),
|
|
156
156
|
ClientPlugin({
|
|
157
|
-
types: [DataType.Organization, DataType.Person,
|
|
158
|
-
onClientInitialized: async (
|
|
157
|
+
types: [DataType.Organization, DataType.Person, DataType.View, Kanban.Kanban],
|
|
158
|
+
onClientInitialized: async ({ client }) => {
|
|
159
159
|
await client.halo.createIdentity();
|
|
160
160
|
const space = await client.spaces.create();
|
|
161
161
|
await space.waitUntilReady();
|
|
162
|
-
const {
|
|
163
|
-
space,
|
|
162
|
+
const { view } = await Kanban.makeView({
|
|
164
163
|
client,
|
|
164
|
+
space,
|
|
165
165
|
typename: DataType.Organization.typename,
|
|
166
|
-
|
|
166
|
+
pivotFieldName: 'status',
|
|
167
|
+
});
|
|
168
|
+
space.db.add(view);
|
|
169
|
+
|
|
170
|
+
// TODO(burdon): Replace with sdk/schema/testing.
|
|
171
|
+
Array.from({ length: 80 }).map(() => {
|
|
172
|
+
return space.db.add(Obj.make(DataType.Organization, rollOrg()));
|
|
167
173
|
});
|
|
168
|
-
space.db.add(kanban);
|
|
169
|
-
|
|
170
|
-
if (schema) {
|
|
171
|
-
// TODO(burdon): Replace with sdk/schema/testing.
|
|
172
|
-
Array.from({ length: 80 }).map(() => {
|
|
173
|
-
return space.db.add(Obj.make(schema, rollOrg()));
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
174
|
},
|
|
177
175
|
}),
|
|
178
176
|
StorybookLayoutPlugin(),
|
|
@@ -183,10 +181,10 @@ const meta: Meta<StoryProps> = {
|
|
|
183
181
|
],
|
|
184
182
|
}),
|
|
185
183
|
],
|
|
186
|
-
}
|
|
184
|
+
} satisfies Meta<typeof StorybookKanban>;
|
|
187
185
|
|
|
188
186
|
export default meta;
|
|
189
187
|
|
|
190
|
-
type Story = StoryObj<
|
|
188
|
+
type Story = StoryObj<typeof meta>;
|
|
191
189
|
|
|
192
190
|
export const Default: Story = {};
|