@dxos/plugin-kanban 0.8.3 → 0.8.4-main.c1de068
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/{artifact-definition-6HNQFL2M.mjs → artifact-definition-WMSZK3RW.mjs} +32 -36
- package/dist/lib/browser/artifact-definition-WMSZK3RW.mjs.map +7 -0
- package/dist/lib/browser/{chunk-6JEDX6HA.mjs → chunk-X44RHBZK.mjs} +33 -10
- package/dist/lib/browser/chunk-X44RHBZK.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +17 -17
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/intent-resolver-E6O3LBAB.mjs +111 -0
- package/dist/lib/browser/intent-resolver-E6O3LBAB.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-surface-HJL2JRJP.mjs → react-surface-MWNNZYMN.mjs} +40 -89
- package/dist/lib/browser/react-surface-MWNNZYMN.mjs.map +7 -0
- package/dist/lib/browser/{types.mjs → types/index.mjs} +4 -4
- package/dist/lib/node-esm/{artifact-definition-FA2IAAUQ.mjs → artifact-definition-QVZXPDXK.mjs} +32 -36
- package/dist/lib/node-esm/artifact-definition-QVZXPDXK.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-7DHZSNGQ.mjs → chunk-6WK5CGYY.mjs} +33 -10
- package/dist/lib/node-esm/chunk-6WK5CGYY.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +17 -17
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/intent-resolver-LPASDELU.mjs +112 -0
- package/dist/lib/node-esm/intent-resolver-LPASDELU.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{react-surface-257WTPQZ.mjs → react-surface-T52BBG45.mjs} +40 -89
- package/dist/lib/node-esm/react-surface-T52BBG45.mjs.map +7 -0
- package/dist/lib/node-esm/{types.mjs → types/index.mjs} +4 -4
- 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/index.d.ts +1 -1
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +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 +1 -1
- 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 +4 -0
- package/dist/types/src/types/index.d.ts.map +1 -0
- package/dist/types/src/types/kanban.d.ts +11 -0
- package/dist/types/src/types/kanban.d.ts.map +1 -0
- package/dist/types/src/types/schema.d.ts +110 -0
- 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 +32 -30
- package/src/KanbanPlugin.tsx +5 -4
- package/src/capabilities/artifact-definition.ts +25 -17
- package/src/capabilities/intent-resolver.ts +13 -14
- package/src/capabilities/react-surface.tsx +15 -12
- package/src/components/KanbanContainer.stories.tsx +42 -45
- package/src/components/KanbanContainer.tsx +11 -11
- package/src/components/KanbanViewEditor.tsx +21 -65
- package/src/index.ts +2 -1
- package/src/translations.ts +7 -7
- package/src/types/index.ts +7 -0
- package/src/types/kanban.ts +29 -0
- package/src/{types.ts → types/schema.ts} +4 -25
- package/src/types/types.ts +7 -0
- 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/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.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 +0 -76
- 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.c1de068",
|
|
4
4
|
"description": "Kanban DXOS Surface plugin",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -35,27 +35,29 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@preact-signals/safe-react": "^0.9.0",
|
|
37
37
|
"@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/echo
|
|
45
|
-
"@dxos/echo": "0.8.
|
|
46
|
-
"@dxos/effect": "0.8.
|
|
47
|
-
"@dxos/invariant": "0.8.
|
|
48
|
-
"@dxos/
|
|
49
|
-
"@dxos/plugin-
|
|
50
|
-
"@dxos/plugin-search": "0.8.
|
|
51
|
-
"@dxos/plugin-
|
|
52
|
-
"@dxos/
|
|
53
|
-
"@dxos/
|
|
54
|
-
"@dxos/react-
|
|
55
|
-
"@dxos/react-ui
|
|
56
|
-
"@dxos/react-ui-
|
|
57
|
-
"@dxos/
|
|
58
|
-
"@dxos/
|
|
38
|
+
"effect": "3.17.0",
|
|
39
|
+
"@dxos/ai": "0.8.4-main.c1de068",
|
|
40
|
+
"@dxos/app-framework": "0.8.4-main.c1de068",
|
|
41
|
+
"@dxos/assistant": "0.8.4-main.c1de068",
|
|
42
|
+
"@dxos/async": "0.8.4-main.c1de068",
|
|
43
|
+
"@dxos/blueprints": "0.8.4-main.c1de068",
|
|
44
|
+
"@dxos/echo": "0.8.4-main.c1de068",
|
|
45
|
+
"@dxos/echo-schema": "0.8.4-main.c1de068",
|
|
46
|
+
"@dxos/effect": "0.8.4-main.c1de068",
|
|
47
|
+
"@dxos/invariant": "0.8.4-main.c1de068",
|
|
48
|
+
"@dxos/log": "0.8.4-main.c1de068",
|
|
49
|
+
"@dxos/plugin-client": "0.8.4-main.c1de068",
|
|
50
|
+
"@dxos/plugin-search": "0.8.4-main.c1de068",
|
|
51
|
+
"@dxos/plugin-graph": "0.8.4-main.c1de068",
|
|
52
|
+
"@dxos/plugin-space": "0.8.4-main.c1de068",
|
|
53
|
+
"@dxos/random": "0.8.4-main.c1de068",
|
|
54
|
+
"@dxos/react-client": "0.8.4-main.c1de068",
|
|
55
|
+
"@dxos/react-ui": "0.8.4-main.c1de068",
|
|
56
|
+
"@dxos/react-ui-form": "0.8.4-main.c1de068",
|
|
57
|
+
"@dxos/react-ui-kanban": "0.8.4-main.c1de068",
|
|
58
|
+
"@dxos/react-ui-stack": "0.8.4-main.c1de068",
|
|
59
|
+
"@dxos/schema": "0.8.4-main.c1de068",
|
|
60
|
+
"@dxos/util": "0.8.4-main.c1de068"
|
|
59
61
|
},
|
|
60
62
|
"devDependencies": {
|
|
61
63
|
"@types/react": "~18.2.0",
|
|
@@ -63,19 +65,19 @@
|
|
|
63
65
|
"react": "~18.2.0",
|
|
64
66
|
"react-dom": "~18.2.0",
|
|
65
67
|
"vite": "5.4.7",
|
|
66
|
-
"@dxos/plugin-preview": "0.8.
|
|
67
|
-
"@dxos/plugin-theme": "0.8.
|
|
68
|
-
"@dxos/react-ui": "0.8.
|
|
69
|
-
"@dxos/
|
|
70
|
-
"@dxos/
|
|
71
|
-
"@dxos/
|
|
68
|
+
"@dxos/plugin-preview": "0.8.4-main.c1de068",
|
|
69
|
+
"@dxos/plugin-theme": "0.8.4-main.c1de068",
|
|
70
|
+
"@dxos/react-ui-syntax-highlighter": "0.8.4-main.c1de068",
|
|
71
|
+
"@dxos/react-ui-theme": "0.8.4-main.c1de068",
|
|
72
|
+
"@dxos/storybook-utils": "0.8.4-main.c1de068",
|
|
73
|
+
"@dxos/test-utils": "0.8.4-main.c1de068"
|
|
72
74
|
},
|
|
73
75
|
"peerDependencies": {
|
|
74
76
|
"effect": "^3.13.3",
|
|
75
77
|
"react": "~18.2.0",
|
|
76
78
|
"react-dom": "~18.2.0",
|
|
77
|
-
"@dxos/react-ui": "0.8.
|
|
78
|
-
"@dxos/react-ui-theme": "0.8.
|
|
79
|
+
"@dxos/react-ui": "0.8.4-main.c1de068",
|
|
80
|
+
"@dxos/react-ui-theme": "0.8.4-main.c1de068"
|
|
79
81
|
},
|
|
80
82
|
"publishConfig": {
|
|
81
83
|
"access": "public"
|
package/src/KanbanPlugin.tsx
CHANGED
|
@@ -6,11 +6,11 @@ import { createIntent, defineModule, contributes, Capabilities, Events, definePl
|
|
|
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 { KanbanView, translations as kanbanTranslations } from '@dxos/react-ui-kanban';
|
|
10
10
|
|
|
11
11
|
import { ArtifactDefinition, IntentResolver, ReactSurface } from './capabilities';
|
|
12
12
|
import { meta } from './meta';
|
|
13
|
-
import translations from './translations';
|
|
13
|
+
import { translations } from './translations';
|
|
14
14
|
import { CreateKanbanSchema, KanbanAction } from './types';
|
|
15
15
|
|
|
16
16
|
export const KanbanPlugin = () =>
|
|
@@ -25,7 +25,7 @@ export const KanbanPlugin = () =>
|
|
|
25
25
|
activatesOn: Events.SetupMetadata,
|
|
26
26
|
activate: () =>
|
|
27
27
|
contributes(Capabilities.Metadata, {
|
|
28
|
-
id:
|
|
28
|
+
id: KanbanView.typename,
|
|
29
29
|
metadata: {
|
|
30
30
|
icon: 'ph--kanban--regular',
|
|
31
31
|
},
|
|
@@ -38,8 +38,9 @@ export const KanbanPlugin = () =>
|
|
|
38
38
|
contributes(
|
|
39
39
|
SpaceCapabilities.ObjectForm,
|
|
40
40
|
defineObjectForm({
|
|
41
|
-
objectSchema:
|
|
41
|
+
objectSchema: KanbanView,
|
|
42
42
|
formSchema: CreateKanbanSchema,
|
|
43
|
+
hidden: true,
|
|
43
44
|
getIntent: (props, options) => createIntent(KanbanAction.Create, { ...props, space: options.space }),
|
|
44
45
|
}),
|
|
45
46
|
),
|
|
@@ -6,13 +6,15 @@ import { Schema, pipe } from 'effect';
|
|
|
6
6
|
|
|
7
7
|
import { createTool, ToolResult } from '@dxos/ai';
|
|
8
8
|
import { Capabilities, chain, contributes, createIntent, type PromiseIntentDispatcher } from '@dxos/app-framework';
|
|
9
|
-
import { defineArtifact } from '@dxos/artifact';
|
|
10
9
|
import { createArtifactElement } from '@dxos/assistant';
|
|
11
|
-
import {
|
|
10
|
+
import { defineArtifact } from '@dxos/blueprints';
|
|
11
|
+
import { Obj, Query } from '@dxos/echo';
|
|
12
12
|
import { invariant } from '@dxos/invariant';
|
|
13
13
|
import { SpaceAction } from '@dxos/plugin-space/types';
|
|
14
14
|
import { Filter, fullyQualifiedId, type Space } from '@dxos/react-client/echo';
|
|
15
|
-
import {
|
|
15
|
+
import { KanbanView } from '@dxos/react-ui-kanban';
|
|
16
|
+
import { DataType } from '@dxos/schema';
|
|
17
|
+
import { isNonNullable } from '@dxos/util';
|
|
16
18
|
|
|
17
19
|
import { meta } from '../meta';
|
|
18
20
|
import { KanbanAction } from '../types';
|
|
@@ -37,7 +39,7 @@ export default () => {
|
|
|
37
39
|
- When adding items, you must not include the 'id' field -- it is automatically generated
|
|
38
40
|
- BEFORE adding items, always make sure the board has been shown to the user!
|
|
39
41
|
`,
|
|
40
|
-
schema:
|
|
42
|
+
schema: KanbanView,
|
|
41
43
|
tools: [
|
|
42
44
|
createTool(meta.id, {
|
|
43
45
|
name: 'create',
|
|
@@ -88,19 +90,24 @@ export default () => {
|
|
|
88
90
|
execute: async (_input, { extensions }) => {
|
|
89
91
|
invariant(extensions?.space, 'No space');
|
|
90
92
|
const space = extensions.space;
|
|
91
|
-
const { objects
|
|
93
|
+
const { objects } = await space.db.query(Filter.type(DataType.View)).run();
|
|
92
94
|
|
|
93
95
|
const boardInfo = await Promise.all(
|
|
94
|
-
|
|
95
|
-
const
|
|
96
|
+
objects.map(async (view) => {
|
|
97
|
+
const kanban = await view.presentation.load();
|
|
98
|
+
if (!Obj.instanceOf(KanbanView, kanban)) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
|
|
96
102
|
return {
|
|
97
|
-
id: fullyQualifiedId(
|
|
98
|
-
|
|
103
|
+
id: fullyQualifiedId(view),
|
|
104
|
+
name: view.name ?? 'Unnamed Kanban',
|
|
105
|
+
typename: view.query.typename,
|
|
99
106
|
};
|
|
100
107
|
}),
|
|
101
108
|
);
|
|
102
109
|
|
|
103
|
-
return ToolResult.Success(boardInfo);
|
|
110
|
+
return ToolResult.Success(boardInfo.filter(isNonNullable));
|
|
104
111
|
},
|
|
105
112
|
}),
|
|
106
113
|
createTool(meta.id, {
|
|
@@ -111,12 +118,13 @@ export default () => {
|
|
|
111
118
|
execute: async ({ id }, { extensions }) => {
|
|
112
119
|
invariant(extensions?.space, 'No space');
|
|
113
120
|
const space = extensions.space;
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
121
|
+
const view = (await space.db
|
|
122
|
+
// TODO(wittjosiah): Filter.and should aggregate type
|
|
123
|
+
.query(Query.select(Filter.and(Filter.type(DataType.View), Filter.ids(id))))
|
|
124
|
+
.first()) as DataType.View;
|
|
117
125
|
|
|
118
|
-
const
|
|
119
|
-
invariant(
|
|
126
|
+
const kanban = await view.presentation.load();
|
|
127
|
+
invariant(Obj.instanceOf(KanbanView, kanban));
|
|
120
128
|
|
|
121
129
|
const typename = view.query.typename;
|
|
122
130
|
const schema = await space.db.schemaRegistry.query({ typename }).firstOrUndefined();
|
|
@@ -124,8 +132,8 @@ export default () => {
|
|
|
124
132
|
|
|
125
133
|
return ToolResult.Success({
|
|
126
134
|
schema,
|
|
127
|
-
columnField:
|
|
128
|
-
viewFields: view.fields,
|
|
135
|
+
columnField: kanban.columnFieldId,
|
|
136
|
+
viewFields: view.projection.fields,
|
|
129
137
|
});
|
|
130
138
|
},
|
|
131
139
|
}),
|
|
@@ -6,11 +6,10 @@ import { contributes, Capabilities, createResolver, type PluginContext } from '@
|
|
|
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 { ProjectionModel } from '@dxos/schema';
|
|
10
10
|
|
|
11
11
|
import { KANBAN_PLUGIN } from '../meta';
|
|
12
|
-
import {
|
|
13
|
-
import { KanbanAction } from '../types';
|
|
12
|
+
import { createKanban, KanbanAction } from '../types';
|
|
14
13
|
|
|
15
14
|
export default (context: PluginContext) =>
|
|
16
15
|
contributes(Capabilities.IntentResolver, [
|
|
@@ -18,22 +17,22 @@ export default (context: PluginContext) =>
|
|
|
18
17
|
intent: KanbanAction.Create,
|
|
19
18
|
resolve: async ({ space, name, typename, initialPivotColumn }) => {
|
|
20
19
|
const client = context.getCapability(ClientCapabilities.Client);
|
|
21
|
-
const {
|
|
22
|
-
|
|
20
|
+
const { view } = await createKanban({
|
|
21
|
+
client,
|
|
22
|
+
space,
|
|
23
|
+
name,
|
|
24
|
+
typename,
|
|
25
|
+
initialPivotColumn,
|
|
26
|
+
});
|
|
27
|
+
return { data: { object: view } };
|
|
23
28
|
},
|
|
24
29
|
}),
|
|
25
30
|
createResolver({
|
|
26
31
|
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);
|
|
32
|
+
resolve: async ({ view, fieldId, deletionData }, undo) => {
|
|
33
|
+
const schema = getSpace(view)?.db.schemaRegistry.getSchema(view.query.typename!);
|
|
34
34
|
invariant(schema);
|
|
35
|
-
|
|
36
|
-
const projection = new ViewProjection(schema.jsonSchema, kanban.cardView.target);
|
|
35
|
+
const projection = new ProjectionModel(schema.jsonSchema, view.projection);
|
|
37
36
|
|
|
38
37
|
if (!undo) {
|
|
39
38
|
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
12
|
import { getSpace, isSpace, type Space } from '@dxos/react-client/echo';
|
|
13
13
|
import { type InputProps, SelectInput, useFormValues } from '@dxos/react-ui-form';
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
14
|
+
import { KanbanView } from '@dxos/react-ui-kanban';
|
|
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(KanbanView, 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(KanbanView, 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,7 +3,8 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import '@dxos-theme';
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
import { type StoryObj, type Meta } from '@storybook/react-vite';
|
|
7
8
|
import React, { useCallback, useEffect, useState } from 'react';
|
|
8
9
|
|
|
9
10
|
import { IntentPlugin, SettingsPlugin } from '@dxos/app-framework';
|
|
@@ -20,14 +21,14 @@ import { faker } from '@dxos/random';
|
|
|
20
21
|
import { useClient } from '@dxos/react-client';
|
|
21
22
|
import { Filter, useSpaces, useQuery, useSchema } from '@dxos/react-client/echo';
|
|
22
23
|
import { ViewEditor } from '@dxos/react-ui-form';
|
|
23
|
-
import { Kanban,
|
|
24
|
+
import { Kanban, KanbanView, useKanbanModel } from '@dxos/react-ui-kanban';
|
|
24
25
|
import { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';
|
|
25
26
|
import { defaultTx } from '@dxos/react-ui-theme';
|
|
26
|
-
import { DataType,
|
|
27
|
+
import { DataType, ProjectionModel } from '@dxos/schema';
|
|
27
28
|
import { withLayout } from '@dxos/storybook-utils';
|
|
28
29
|
|
|
29
|
-
import {
|
|
30
|
-
import
|
|
30
|
+
import { translations } from '../translations';
|
|
31
|
+
import { createKanban } from '../types';
|
|
31
32
|
|
|
32
33
|
faker.seed(0);
|
|
33
34
|
|
|
@@ -40,39 +41,39 @@ 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 schema = useSchema(client, space,
|
|
51
|
+
const views = useQuery(space, Filter.type(DataType.View));
|
|
52
|
+
const [view, setView] = useState<DataType.View>();
|
|
53
|
+
const [projection, setProjection] = useState<ProjectionModel>();
|
|
54
|
+
const schema = useSchema(client, space, view?.query.typename);
|
|
54
55
|
|
|
55
56
|
useEffect(() => {
|
|
56
|
-
if (
|
|
57
|
-
const
|
|
58
|
-
|
|
57
|
+
if (views.length && !view) {
|
|
58
|
+
const view = views[0];
|
|
59
|
+
setView(view);
|
|
59
60
|
}
|
|
60
|
-
}, [
|
|
61
|
+
}, [views]);
|
|
61
62
|
|
|
62
63
|
useEffect(() => {
|
|
63
|
-
if (
|
|
64
|
+
if (view?.projection && schema) {
|
|
64
65
|
const jsonSchema = Type.toJsonSchema(schema);
|
|
65
|
-
setProjection(new
|
|
66
|
+
setProjection(new ProjectionModel(jsonSchema, view.projection));
|
|
66
67
|
}
|
|
67
68
|
// TODO(ZaymonFC): Is there a better way to get notified about deep changes in the json schema?
|
|
68
69
|
// @dmaretskyi? Once resolved, update in multiple places (e.g., storybooks).
|
|
69
|
-
}, [
|
|
70
|
+
}, [view?.projection, schema, JSON.stringify(schema ? Type.toJsonSchema(schema) : {})]);
|
|
70
71
|
|
|
71
72
|
const objects = useQuery(space, schema ? Filter.type(schema) : Filter.nothing());
|
|
72
73
|
const filteredObjects = useGlobalFilteredObjects(objects);
|
|
73
74
|
|
|
74
75
|
const model = useKanbanModel({
|
|
75
|
-
|
|
76
|
+
view,
|
|
76
77
|
schema,
|
|
77
78
|
projection,
|
|
78
79
|
items: filteredObjects,
|
|
@@ -100,15 +101,15 @@ const StorybookKanban = () => {
|
|
|
100
101
|
(typename: string) => {
|
|
101
102
|
invariant(schema);
|
|
102
103
|
invariant(Type.isMutable(schema));
|
|
103
|
-
invariant(
|
|
104
|
+
invariant(view);
|
|
104
105
|
|
|
105
106
|
schema.updateTypename(typename);
|
|
106
|
-
|
|
107
|
+
view.query.typename = typename;
|
|
107
108
|
},
|
|
108
|
-
[
|
|
109
|
+
[view, schema],
|
|
109
110
|
);
|
|
110
111
|
|
|
111
|
-
if (!schema || !
|
|
112
|
+
if (!schema || !view) {
|
|
112
113
|
return null;
|
|
113
114
|
}
|
|
114
115
|
|
|
@@ -116,19 +117,17 @@ const StorybookKanban = () => {
|
|
|
116
117
|
<div className='grow grid grid-cols-[1fr_350px]'>
|
|
117
118
|
{model ? <Kanban model={model} onAddCard={handleAddCard} onRemoveCard={handleRemoveCard} /> : <div />}
|
|
118
119
|
<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
|
-
)}
|
|
120
|
+
<ViewEditor
|
|
121
|
+
registry={space?.db.schemaRegistry}
|
|
122
|
+
schema={schema}
|
|
123
|
+
view={view}
|
|
124
|
+
onTypenameChanged={handleTypenameChanged}
|
|
125
|
+
onDelete={(fieldId: string) => {
|
|
126
|
+
console.log('[ViewEditor]', 'onDelete', fieldId);
|
|
127
|
+
}}
|
|
128
|
+
/>
|
|
130
129
|
<SyntaxHighlighter language='json' className='w-full text-xs'>
|
|
131
|
-
{JSON.stringify({
|
|
130
|
+
{JSON.stringify({ view, schema }, null, 2)}
|
|
132
131
|
</SyntaxHighlighter>
|
|
133
132
|
</div>
|
|
134
133
|
</div>
|
|
@@ -154,25 +153,23 @@ const meta: Meta<StoryProps> = {
|
|
|
154
153
|
plugins: [
|
|
155
154
|
ThemePlugin({ tx: defaultTx }),
|
|
156
155
|
ClientPlugin({
|
|
157
|
-
types: [DataType.Organization, DataType.Person,
|
|
156
|
+
types: [DataType.Organization, DataType.Person, DataType.View, KanbanView],
|
|
158
157
|
onClientInitialized: async (_, client) => {
|
|
159
158
|
await client.halo.createIdentity();
|
|
160
159
|
const space = await client.spaces.create();
|
|
161
160
|
await space.waitUntilReady();
|
|
162
|
-
const {
|
|
163
|
-
space,
|
|
161
|
+
const { view } = await createKanban({
|
|
164
162
|
client,
|
|
163
|
+
space,
|
|
165
164
|
typename: DataType.Organization.typename,
|
|
166
165
|
initialPivotColumn: 'status',
|
|
167
166
|
});
|
|
168
|
-
space.db.add(
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
});
|
|
175
|
-
}
|
|
167
|
+
space.db.add(view);
|
|
168
|
+
|
|
169
|
+
// TODO(burdon): Replace with sdk/schema/testing.
|
|
170
|
+
Array.from({ length: 80 }).map(() => {
|
|
171
|
+
return space.db.add(Obj.make(DataType.Organization, rollOrg()));
|
|
172
|
+
});
|
|
176
173
|
},
|
|
177
174
|
}),
|
|
178
175
|
StorybookLayoutPlugin(),
|
|
@@ -10,17 +10,17 @@ import { EchoSchema, type TypedObject } from '@dxos/echo-schema';
|
|
|
10
10
|
import { useGlobalFilteredObjects } from '@dxos/plugin-search';
|
|
11
11
|
import { useClient } from '@dxos/react-client';
|
|
12
12
|
import { useQuery, getSpace } from '@dxos/react-client/echo';
|
|
13
|
-
import {
|
|
13
|
+
import { useKanbanModel, Kanban } from '@dxos/react-ui-kanban';
|
|
14
14
|
import { StackItem } from '@dxos/react-ui-stack';
|
|
15
|
-
import {
|
|
15
|
+
import { ProjectionModel, type DataType } from '@dxos/schema';
|
|
16
16
|
|
|
17
17
|
import { KanbanAction } from '../types';
|
|
18
18
|
|
|
19
|
-
export const KanbanContainer = ({
|
|
19
|
+
export const KanbanContainer = ({ view }: { view: DataType.View; role: string }) => {
|
|
20
20
|
const client = useClient();
|
|
21
21
|
const [cardSchema, setCardSchema] = useState<TypedObject<any, any>>();
|
|
22
|
-
const [projection, setProjection] = useState<
|
|
23
|
-
const space = getSpace(
|
|
22
|
+
const [projection, setProjection] = useState<ProjectionModel>();
|
|
23
|
+
const space = getSpace(view);
|
|
24
24
|
const { dispatchPromise: dispatch } = useIntentDispatcher();
|
|
25
25
|
|
|
26
26
|
const jsonSchema = useMemo(() => {
|
|
@@ -31,7 +31,7 @@ export const KanbanContainer = ({ kanban }: { kanban: KanbanType; role: string }
|
|
|
31
31
|
}, [cardSchema]);
|
|
32
32
|
|
|
33
33
|
useEffect(() => {
|
|
34
|
-
const typename =
|
|
34
|
+
const typename = view.query.typename;
|
|
35
35
|
const staticSchema = client.graph.schemaRegistry.schemas.find((schema) => Type.getTypename(schema) === typename);
|
|
36
36
|
if (staticSchema) {
|
|
37
37
|
setCardSchema(() => staticSchema as TypedObject<any, any>);
|
|
@@ -49,20 +49,20 @@ export const KanbanContainer = ({ kanban }: { kanban: KanbanType; role: string }
|
|
|
49
49
|
);
|
|
50
50
|
return unsubscribe;
|
|
51
51
|
}
|
|
52
|
-
}, [
|
|
52
|
+
}, [view.query.typename, space]);
|
|
53
53
|
|
|
54
54
|
useEffect(() => {
|
|
55
|
-
if (
|
|
56
|
-
setProjection(new
|
|
55
|
+
if (jsonSchema) {
|
|
56
|
+
setProjection(new ProjectionModel(jsonSchema, view.projection));
|
|
57
57
|
}
|
|
58
58
|
// TODO(ZaymonFC): Is there a better way to get notified about deep changes in the json schema?
|
|
59
|
-
}, [
|
|
59
|
+
}, [view.projection, JSON.stringify(jsonSchema)]);
|
|
60
60
|
|
|
61
61
|
const objects = useQuery(space, cardSchema ? Filter.type(cardSchema) : Filter.nothing());
|
|
62
62
|
const filteredObjects = useGlobalFilteredObjects(objects);
|
|
63
63
|
|
|
64
64
|
const model = useKanbanModel({
|
|
65
|
-
|
|
65
|
+
view,
|
|
66
66
|
schema: cardSchema,
|
|
67
67
|
projection,
|
|
68
68
|
items: filteredObjects,
|
|
@@ -4,59 +4,29 @@
|
|
|
4
4
|
|
|
5
5
|
import React, { useCallback, useMemo } from 'react';
|
|
6
6
|
|
|
7
|
-
import { createIntent, useIntentDispatcher } from '@dxos/app-framework';
|
|
8
7
|
import { Type } from '@dxos/echo';
|
|
9
8
|
import { EchoSchema, FormatEnum } from '@dxos/echo-schema';
|
|
10
|
-
import { invariant } from '@dxos/invariant';
|
|
11
9
|
import { useClient } from '@dxos/react-client';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { type
|
|
15
|
-
import {
|
|
10
|
+
import { getSpace, useSchema } from '@dxos/react-client/echo';
|
|
11
|
+
import { Form, SelectInput, type CustomInputMap } from '@dxos/react-ui-form';
|
|
12
|
+
import { KanbanSettingsSchema, type KanbanView } from '@dxos/react-ui-kanban';
|
|
13
|
+
import { type DataType, ProjectionModel } from '@dxos/schema';
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
type KanbanViewEditorProps = { view: DataType.View };
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
export const KanbanViewEditor = ({ kanban }: KanbanViewEditorProps) => {
|
|
22
|
-
const { dispatchPromise: dispatch } = useIntentDispatcher();
|
|
17
|
+
export const KanbanViewEditor = ({ view }: KanbanViewEditorProps) => {
|
|
23
18
|
const client = useClient();
|
|
24
|
-
const space = getSpace(
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
[kanban?.cardView?.target?.query?.typename],
|
|
28
|
-
);
|
|
19
|
+
const space = getSpace(view);
|
|
20
|
+
const kanban = view.presentation.target as KanbanView;
|
|
21
|
+
const currentTypename = useMemo(() => view.query.typename, [view.query.typename]);
|
|
29
22
|
const schema = useSchema(client, space, currentTypename);
|
|
30
|
-
const views = useQuery(space, Filter.type(ViewType));
|
|
31
|
-
|
|
32
|
-
const handleUpdateTypename = useCallback(
|
|
33
|
-
(newTypename: string) => {
|
|
34
|
-
invariant(schema);
|
|
35
|
-
invariant(Type.isMutable(schema));
|
|
36
|
-
|
|
37
|
-
const matchingViews = views.filter((view) => view.query.typename === currentTypename);
|
|
38
|
-
for (const view of matchingViews) {
|
|
39
|
-
view.query.typename = newTypename;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
schema.updateTypename(newTypename);
|
|
43
|
-
},
|
|
44
|
-
[views, schema],
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
const handleDelete = useCallback(
|
|
48
|
-
(fieldId: string) => {
|
|
49
|
-
void dispatch?.(createIntent(KanbanAction.DeleteCardField, { kanban, fieldId }));
|
|
50
|
-
},
|
|
51
|
-
[dispatch, kanban],
|
|
52
|
-
);
|
|
53
23
|
|
|
54
24
|
const projection = useMemo(() => {
|
|
55
|
-
if (
|
|
25
|
+
if (schema) {
|
|
56
26
|
const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : Type.toJsonSchema(schema);
|
|
57
|
-
return new
|
|
27
|
+
return new ProjectionModel(jsonSchema, view.projection);
|
|
58
28
|
}
|
|
59
|
-
}, [
|
|
29
|
+
}, [view.projection, JSON.stringify(schema)]);
|
|
60
30
|
|
|
61
31
|
const fieldProjections = projection?.getFieldProjections() || [];
|
|
62
32
|
const selectFields = fieldProjections
|
|
@@ -76,29 +46,15 @@ export const KanbanViewEditor = ({ kanban }: KanbanViewEditorProps) => {
|
|
|
76
46
|
[selectFields],
|
|
77
47
|
);
|
|
78
48
|
|
|
79
|
-
if (!space || !schema || !kanban.cardView?.target) {
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
49
|
return (
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
/>
|
|
94
|
-
<ViewEditor
|
|
95
|
-
registry={space.db.schemaRegistry}
|
|
96
|
-
schema={schema}
|
|
97
|
-
view={kanban.cardView.target}
|
|
98
|
-
onTypenameChanged={Type.isMutable(schema) ? handleUpdateTypename : undefined}
|
|
99
|
-
onDelete={Type.isMutable(schema) ? handleDelete : undefined}
|
|
100
|
-
outerSpacing={false}
|
|
101
|
-
/>
|
|
102
|
-
</>
|
|
50
|
+
<Form
|
|
51
|
+
Custom={custom}
|
|
52
|
+
schema={KanbanSettingsSchema}
|
|
53
|
+
values={initialValues}
|
|
54
|
+
onSave={handleSave}
|
|
55
|
+
autoSave
|
|
56
|
+
outerSpacing={false}
|
|
57
|
+
classNames='pbs-inputSpacingBlock'
|
|
58
|
+
/>
|
|
103
59
|
);
|
|
104
60
|
};
|