@dxos/plugin-kanban 0.8.4-main.2c6827d → 0.8.4-main.3c1ae3b
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/{chunk-HO3LQ5T7.mjs → chunk-PEQVHFOX.mjs} +24 -9
- package/dist/lib/browser/chunk-PEQVHFOX.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +22 -24
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/{intent-resolver-OPYUDNSU.mjs → intent-resolver-NHCWHMPW.mjs} +11 -11
- package/dist/lib/browser/intent-resolver-NHCWHMPW.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-surface-X54TNDDN.mjs → react-surface-NSCKM4QW.mjs} +74 -92
- package/dist/lib/browser/react-surface-NSCKM4QW.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +5 -3
- package/dist/lib/node-esm/{chunk-QZMZU5HM.mjs → chunk-LTCOYU73.mjs} +24 -9
- package/dist/lib/node-esm/chunk-LTCOYU73.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +22 -24
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/{intent-resolver-BDKNXV3R.mjs → intent-resolver-L2OEBOJW.mjs} +11 -11
- package/dist/lib/node-esm/intent-resolver-L2OEBOJW.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{react-surface-CVDMIHSC.mjs → react-surface-WXYTWOY2.mjs} +74 -92
- package/dist/lib/node-esm/react-surface-WXYTWOY2.mjs.map +7 -0
- package/dist/lib/node-esm/types/index.mjs +5 -3
- package/dist/types/src/KanbanPlugin.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 +21 -8
- 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/translations.d.ts +21 -9
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/schema.d.ts +5 -1
- package/dist/types/src/types/schema.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +32 -32
- package/src/KanbanPlugin.tsx +9 -15
- package/src/capabilities/artifact-definition.ts +1 -1
- package/src/capabilities/intent-resolver.ts +4 -11
- package/src/capabilities/react-surface.tsx +15 -21
- package/src/components/KanbanContainer.stories.tsx +21 -47
- package/src/components/KanbanContainer.tsx +16 -30
- package/src/components/KanbanViewEditor.tsx +24 -34
- package/src/translations.ts +5 -5
- package/src/types/schema.ts +17 -6
- package/dist/lib/browser/chunk-HO3LQ5T7.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-OPYUDNSU.mjs.map +0 -7
- package/dist/lib/browser/react-surface-X54TNDDN.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-QZMZU5HM.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-BDKNXV3R.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-CVDMIHSC.mjs.map +0 -7
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.3c1ae3b",
|
|
4
4
|
"description": "Kanban DXOS Surface plugin",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -38,29 +38,29 @@
|
|
|
38
38
|
"@preact-signals/safe-react": "^0.9.0",
|
|
39
39
|
"@preact/signals-core": "^1.12.1",
|
|
40
40
|
"effect": "3.18.3",
|
|
41
|
-
"@dxos/ai": "0.8.4-main.
|
|
42
|
-
"@dxos/
|
|
43
|
-
"@dxos/assistant": "0.8.4-main.
|
|
44
|
-
"@dxos/blueprints": "0.8.4-main.
|
|
45
|
-
"@dxos/
|
|
46
|
-
"@dxos/
|
|
47
|
-
"@dxos/
|
|
48
|
-
"@dxos/
|
|
49
|
-
"@dxos/
|
|
50
|
-
"@dxos/plugin-
|
|
51
|
-
"@dxos/
|
|
52
|
-
"@dxos/plugin-
|
|
53
|
-
"@dxos/plugin-
|
|
54
|
-
"@dxos/
|
|
55
|
-
"@dxos/
|
|
56
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
57
|
-
"@dxos/react-
|
|
58
|
-
"@dxos/react-ui-
|
|
59
|
-
"@dxos/
|
|
60
|
-
"@dxos/
|
|
61
|
-
"@dxos/
|
|
62
|
-
"@dxos/util": "0.8.4-main.
|
|
63
|
-
"@dxos/
|
|
41
|
+
"@dxos/ai": "0.8.4-main.3c1ae3b",
|
|
42
|
+
"@dxos/app-framework": "0.8.4-main.3c1ae3b",
|
|
43
|
+
"@dxos/assistant": "0.8.4-main.3c1ae3b",
|
|
44
|
+
"@dxos/blueprints": "0.8.4-main.3c1ae3b",
|
|
45
|
+
"@dxos/effect": "0.8.4-main.3c1ae3b",
|
|
46
|
+
"@dxos/echo": "0.8.4-main.3c1ae3b",
|
|
47
|
+
"@dxos/async": "0.8.4-main.3c1ae3b",
|
|
48
|
+
"@dxos/invariant": "0.8.4-main.3c1ae3b",
|
|
49
|
+
"@dxos/functions": "0.8.4-main.3c1ae3b",
|
|
50
|
+
"@dxos/plugin-client": "0.8.4-main.3c1ae3b",
|
|
51
|
+
"@dxos/log": "0.8.4-main.3c1ae3b",
|
|
52
|
+
"@dxos/plugin-graph": "0.8.4-main.3c1ae3b",
|
|
53
|
+
"@dxos/plugin-search": "0.8.4-main.3c1ae3b",
|
|
54
|
+
"@dxos/plugin-space": "0.8.4-main.3c1ae3b",
|
|
55
|
+
"@dxos/random": "0.8.4-main.3c1ae3b",
|
|
56
|
+
"@dxos/react-ui": "0.8.4-main.3c1ae3b",
|
|
57
|
+
"@dxos/react-client": "0.8.4-main.3c1ae3b",
|
|
58
|
+
"@dxos/react-ui-form": "0.8.4-main.3c1ae3b",
|
|
59
|
+
"@dxos/react-ui-kanban": "0.8.4-main.3c1ae3b",
|
|
60
|
+
"@dxos/schema": "0.8.4-main.3c1ae3b",
|
|
61
|
+
"@dxos/react-ui-stack": "0.8.4-main.3c1ae3b",
|
|
62
|
+
"@dxos/util": "0.8.4-main.3c1ae3b",
|
|
63
|
+
"@dxos/types": "0.8.4-main.3c1ae3b"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"@types/react": "~19.2.2",
|
|
@@ -68,19 +68,19 @@
|
|
|
68
68
|
"react": "~19.2.0",
|
|
69
69
|
"react-dom": "~19.2.0",
|
|
70
70
|
"vite": "7.1.9",
|
|
71
|
-
"@dxos/plugin-preview": "0.8.4-main.
|
|
72
|
-
"@dxos/plugin-theme": "0.8.4-main.
|
|
73
|
-
"@dxos/
|
|
74
|
-
"@dxos/react-ui-syntax-highlighter": "0.8.4-main.
|
|
75
|
-
"@dxos/
|
|
76
|
-
"@dxos/
|
|
71
|
+
"@dxos/plugin-preview": "0.8.4-main.3c1ae3b",
|
|
72
|
+
"@dxos/plugin-theme": "0.8.4-main.3c1ae3b",
|
|
73
|
+
"@dxos/react-ui-theme": "0.8.4-main.3c1ae3b",
|
|
74
|
+
"@dxos/react-ui-syntax-highlighter": "0.8.4-main.3c1ae3b",
|
|
75
|
+
"@dxos/storybook-utils": "0.8.4-main.3c1ae3b",
|
|
76
|
+
"@dxos/test-utils": "0.8.4-main.3c1ae3b"
|
|
77
77
|
},
|
|
78
78
|
"peerDependencies": {
|
|
79
79
|
"effect": "^3.13.3",
|
|
80
80
|
"react": "^19.0.0",
|
|
81
81
|
"react-dom": "^19.0.0",
|
|
82
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
83
|
-
"@dxos/react-ui-theme": "0.8.4-main.
|
|
82
|
+
"@dxos/react-ui": "0.8.4-main.3c1ae3b",
|
|
83
|
+
"@dxos/react-ui-theme": "0.8.4-main.3c1ae3b"
|
|
84
84
|
},
|
|
85
85
|
"publishConfig": {
|
|
86
86
|
"access": "public"
|
package/src/KanbanPlugin.tsx
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { Capabilities, Events, contributes, createIntent, defineModule, definePlugin } from '@dxos/app-framework';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
6
|
+
import { Type } from '@dxos/echo';
|
|
7
|
+
import { ClientCapabilities, ClientEvents } from '@dxos/plugin-client';
|
|
8
|
+
import { type CreateObjectIntent } from '@dxos/plugin-space/types';
|
|
9
9
|
import { translations as kanbanTranslations } from '@dxos/react-ui-kanban';
|
|
10
10
|
import { Kanban } from '@dxos/react-ui-kanban/types';
|
|
11
11
|
|
|
@@ -25,26 +25,20 @@ export const KanbanPlugin = definePlugin(meta, () => [
|
|
|
25
25
|
activatesOn: Events.SetupMetadata,
|
|
26
26
|
activate: () =>
|
|
27
27
|
contributes(Capabilities.Metadata, {
|
|
28
|
-
id: Kanban.Kanban
|
|
28
|
+
id: Type.getTypename(Kanban.Kanban),
|
|
29
29
|
metadata: {
|
|
30
30
|
icon: 'ph--kanban--regular',
|
|
31
31
|
iconHue: 'green',
|
|
32
|
+
inputSchema: CreateKanbanSchema,
|
|
33
|
+
createObjectIntent: ((props, options) =>
|
|
34
|
+
createIntent(KanbanAction.Create, { ...props, space: options.space })) satisfies CreateObjectIntent,
|
|
32
35
|
},
|
|
33
36
|
}),
|
|
34
37
|
}),
|
|
35
38
|
defineModule({
|
|
36
|
-
id: `${meta.id}/module/
|
|
39
|
+
id: `${meta.id}/module/schema`,
|
|
37
40
|
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 }),
|
|
46
|
-
}),
|
|
47
|
-
),
|
|
41
|
+
activate: () => contributes(ClientCapabilities.Schema, [Kanban.Kanban]),
|
|
48
42
|
}),
|
|
49
43
|
defineModule({
|
|
50
44
|
id: `${meta.id}/module/react-surface`,
|
|
@@ -124,7 +124,7 @@ export default () => {
|
|
|
124
124
|
const space = extensions.space;
|
|
125
125
|
const view = (await space.db
|
|
126
126
|
// TODO(wittjosiah): Filter.and should aggregate type
|
|
127
|
-
.query(Query.select(Filter.and(Filter.type(View.View), Filter.
|
|
127
|
+
.query(Query.select(Filter.and(Filter.type(View.View), Filter.id(id))))
|
|
128
128
|
.first()) as View.View;
|
|
129
129
|
|
|
130
130
|
const kanban = await view.presentation.load();
|
|
@@ -4,10 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
import { Capabilities, type PluginContext, contributes, createResolver } from '@dxos/app-framework';
|
|
6
6
|
import { invariant } from '@dxos/invariant';
|
|
7
|
-
import { ClientCapabilities } from '@dxos/plugin-client';
|
|
8
7
|
import { getSpace } from '@dxos/react-client/echo';
|
|
9
8
|
import { Kanban } from '@dxos/react-ui-kanban/types';
|
|
10
|
-
import { ProjectionModel, getTypenameFromQuery } from '@dxos/schema';
|
|
9
|
+
import { ProjectionModel, View, getTypenameFromQuery } from '@dxos/schema';
|
|
11
10
|
|
|
12
11
|
import { meta } from '../meta';
|
|
13
12
|
import { KanbanAction } from '../types';
|
|
@@ -17,15 +16,9 @@ export default (context: PluginContext) =>
|
|
|
17
16
|
createResolver({
|
|
18
17
|
intent: KanbanAction.Create,
|
|
19
18
|
resolve: async ({ space, name, typename, initialPivotColumn }) => {
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
space,
|
|
24
|
-
name,
|
|
25
|
-
typename,
|
|
26
|
-
pivotFieldName: initialPivotColumn,
|
|
27
|
-
});
|
|
28
|
-
return { data: { object: view } };
|
|
19
|
+
const { view } = await View.makeFromSpace({ space, typename, pivotFieldName: initialPivotColumn });
|
|
20
|
+
const kanban = Kanban.make({ name, view });
|
|
21
|
+
return { data: { object: kanban } };
|
|
29
22
|
},
|
|
30
23
|
}),
|
|
31
24
|
createResolver({
|
|
@@ -6,14 +6,12 @@ import type * as Schema from 'effect/Schema';
|
|
|
6
6
|
import React, { useMemo } from 'react';
|
|
7
7
|
|
|
8
8
|
import { Capabilities, contributes, createSurface } from '@dxos/app-framework';
|
|
9
|
-
import { useCapabilities } from '@dxos/app-framework/react';
|
|
10
9
|
import { Obj, Type } from '@dxos/echo';
|
|
11
10
|
import { findAnnotation } from '@dxos/effect';
|
|
12
|
-
import { ClientCapabilities } from '@dxos/plugin-client';
|
|
13
11
|
import { type Space, getSpace, isSpace } from '@dxos/react-client/echo';
|
|
14
|
-
import { type
|
|
12
|
+
import { type FormFieldComponentProps, SelectField, useFormValues } from '@dxos/react-ui-form';
|
|
15
13
|
import { Kanban } from '@dxos/react-ui-kanban/types';
|
|
16
|
-
import { type Collection
|
|
14
|
+
import { type Collection } from '@dxos/schema';
|
|
17
15
|
|
|
18
16
|
import { KanbanContainer, KanbanViewEditor } from '../components';
|
|
19
17
|
import { meta } from '../meta';
|
|
@@ -24,17 +22,15 @@ export default () =>
|
|
|
24
22
|
createSurface({
|
|
25
23
|
id: meta.id,
|
|
26
24
|
role: ['article', 'section'],
|
|
27
|
-
filter: (data): data is { subject:
|
|
28
|
-
|
|
29
|
-
component: ({ data, role }) => <KanbanContainer view={data.subject} role={role} />,
|
|
25
|
+
filter: (data): data is { subject: Kanban.Kanban } => Obj.instanceOf(Kanban.Kanban, data.subject),
|
|
26
|
+
component: ({ data, role }) => <KanbanContainer object={data.subject} role={role} />,
|
|
30
27
|
}),
|
|
31
28
|
createSurface({
|
|
32
29
|
id: `${meta.id}/object-settings`,
|
|
33
30
|
role: 'object-settings',
|
|
34
31
|
position: 'hoist',
|
|
35
|
-
filter: (data): data is { subject:
|
|
36
|
-
|
|
37
|
-
component: ({ data }) => <KanbanViewEditor view={data.subject} />,
|
|
32
|
+
filter: (data): data is { subject: Kanban.Kanban } => Obj.instanceOf(Kanban.Kanban, data.subject),
|
|
33
|
+
component: ({ data }) => <KanbanViewEditor object={data.subject} />,
|
|
38
34
|
}),
|
|
39
35
|
createSurface({
|
|
40
36
|
id: `${meta.id}/create-initial-schema-form-[pivot-column]`,
|
|
@@ -50,21 +46,19 @@ export default () =>
|
|
|
50
46
|
return !!annotation;
|
|
51
47
|
},
|
|
52
48
|
component: ({ data: { target }, ...inputProps }) => {
|
|
53
|
-
const props = inputProps as any as
|
|
49
|
+
const props = inputProps as any as FormFieldComponentProps;
|
|
54
50
|
const space = isSpace(target) ? target : getSpace(target);
|
|
55
51
|
if (!space) {
|
|
56
52
|
return null;
|
|
57
53
|
}
|
|
58
|
-
const { typename } = useFormValues();
|
|
59
|
-
// TODO(wittjosiah): Unify this schema lookup.
|
|
60
|
-
const schemaWhitelists = useCapabilities(ClientCapabilities.SchemaWhiteList);
|
|
61
|
-
const staticSchema = schemaWhitelists.flat().find((schema) => Type.getTypename(schema) === typename);
|
|
62
|
-
const [selectedSchema] = space?.db.schemaRegistry.query({ typename }).runSync();
|
|
63
54
|
|
|
55
|
+
const { typename } = useFormValues('KanbanForm');
|
|
56
|
+
const [selectedSchema] = useMemo(
|
|
57
|
+
() => space?.db.schemaRegistry.query({ location: ['database', 'runtime'], typename }).runSync(),
|
|
58
|
+
[space, typename],
|
|
59
|
+
);
|
|
64
60
|
const singleSelectColumns = useMemo(() => {
|
|
65
|
-
const properties =
|
|
66
|
-
? Type.toJsonSchema(staticSchema).properties
|
|
67
|
-
: selectedSchema?.jsonSchema?.properties;
|
|
61
|
+
const properties = Type.toJsonSchema(selectedSchema).properties;
|
|
68
62
|
if (!properties) {
|
|
69
63
|
return [];
|
|
70
64
|
}
|
|
@@ -77,13 +71,13 @@ export default () =>
|
|
|
77
71
|
}, []);
|
|
78
72
|
|
|
79
73
|
return columns;
|
|
80
|
-
}, [selectedSchema
|
|
74
|
+
}, [selectedSchema]);
|
|
81
75
|
|
|
82
76
|
if (!typename) {
|
|
83
77
|
return null;
|
|
84
78
|
}
|
|
85
79
|
|
|
86
|
-
return <
|
|
80
|
+
return <SelectField {...props} options={singleSelectColumns.map((column) => ({ value: column }))} />;
|
|
87
81
|
},
|
|
88
82
|
}),
|
|
89
83
|
]);
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
|
-
import React, { useCallback
|
|
6
|
+
import React, { useCallback } from 'react';
|
|
7
7
|
|
|
8
8
|
import { IntentPlugin, SettingsPlugin } from '@dxos/app-framework';
|
|
9
9
|
import { withPluginManager } from '@dxos/app-framework/testing';
|
|
@@ -16,15 +16,14 @@ import { SpacePlugin } from '@dxos/plugin-space';
|
|
|
16
16
|
import { StorybookLayoutPlugin } from '@dxos/plugin-storybook-layout';
|
|
17
17
|
import { ThemePlugin } from '@dxos/plugin-theme';
|
|
18
18
|
import { faker } from '@dxos/random';
|
|
19
|
-
import { useClient } from '@dxos/react-client';
|
|
20
19
|
import { Filter, useQuery, useSchema, useSpaces } from '@dxos/react-client/echo';
|
|
21
20
|
import { withTheme } from '@dxos/react-ui/testing';
|
|
22
21
|
import { ViewEditor } from '@dxos/react-ui-form';
|
|
23
|
-
import { Kanban as KanbanComponent, useKanbanModel } from '@dxos/react-ui-kanban';
|
|
22
|
+
import { Kanban as KanbanComponent, useKanbanModel, useProjectionModel } from '@dxos/react-ui-kanban';
|
|
24
23
|
import { Kanban } from '@dxos/react-ui-kanban/types';
|
|
25
|
-
import {
|
|
24
|
+
import { JsonFilter } from '@dxos/react-ui-syntax-highlighter';
|
|
26
25
|
import { defaultTx } from '@dxos/react-ui-theme';
|
|
27
|
-
import {
|
|
26
|
+
import { View, getTypenameFromQuery } from '@dxos/schema';
|
|
28
27
|
import { Organization, Person } from '@dxos/types';
|
|
29
28
|
|
|
30
29
|
import { translations } from '../translations';
|
|
@@ -44,37 +43,18 @@ const rollOrg = () => ({
|
|
|
44
43
|
});
|
|
45
44
|
|
|
46
45
|
const StorybookKanban = () => {
|
|
47
|
-
const client = useClient();
|
|
48
46
|
const spaces = useSpaces();
|
|
49
47
|
const space = spaces[spaces.length - 1];
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
const typename = view?.query ? getTypenameFromQuery(view.query.ast) : undefined;
|
|
54
|
-
const schema = useSchema(client, space, typename);
|
|
55
|
-
|
|
56
|
-
useEffect(() => {
|
|
57
|
-
if (views.length && !view) {
|
|
58
|
-
const view = views[0];
|
|
59
|
-
setView(view);
|
|
60
|
-
}
|
|
61
|
-
}, [views]);
|
|
62
|
-
|
|
63
|
-
useEffect(() => {
|
|
64
|
-
if (view?.projection && schema) {
|
|
65
|
-
const jsonSchema = Type.toJsonSchema(schema);
|
|
66
|
-
setProjection(new ProjectionModel(jsonSchema, view.projection));
|
|
67
|
-
}
|
|
68
|
-
// TODO(ZaymonFC): Is there a better way to get notified about deep changes in the json schema?
|
|
69
|
-
// @dmaretskyi? Once resolved, update in multiple places (e.g., storybooks).
|
|
70
|
-
}, [view?.projection, schema, JSON.stringify(schema ? Type.toJsonSchema(schema) : {})]);
|
|
48
|
+
const [object] = useQuery(space, Filter.type(Kanban.Kanban));
|
|
49
|
+
const typename = object?.view.target?.query ? getTypenameFromQuery(object.view.target.query.ast) : undefined;
|
|
50
|
+
const schema = useSchema(space, typename);
|
|
71
51
|
|
|
72
52
|
const objects = useQuery(space, schema ? Filter.type(schema) : Filter.nothing());
|
|
73
53
|
const filteredObjects = useGlobalFilteredObjects(objects);
|
|
74
54
|
|
|
55
|
+
const projection = useProjectionModel(schema, object);
|
|
75
56
|
const model = useKanbanModel({
|
|
76
|
-
|
|
77
|
-
schema,
|
|
57
|
+
object,
|
|
78
58
|
projection,
|
|
79
59
|
items: filteredObjects,
|
|
80
60
|
});
|
|
@@ -95,49 +75,43 @@ const StorybookKanban = () => {
|
|
|
95
75
|
[space, schema, model],
|
|
96
76
|
);
|
|
97
77
|
|
|
98
|
-
const handleRemoveCard = useCallback((card: { id: string }) => space
|
|
78
|
+
const handleRemoveCard = useCallback((card: { id: string }) => Obj.isObject(card) && space?.db.remove(card), [space]);
|
|
99
79
|
|
|
100
80
|
const handleUpdateQuery = useCallback(
|
|
101
81
|
(newQuery: QueryAST.Query) => {
|
|
102
82
|
invariant(schema);
|
|
103
83
|
invariant(Type.isMutable(schema));
|
|
104
|
-
invariant(view);
|
|
84
|
+
invariant(object.view.target);
|
|
105
85
|
|
|
106
86
|
schema.updateTypename(getTypenameFromQuery(newQuery));
|
|
107
|
-
view.query.ast = newQuery;
|
|
87
|
+
object.view.target.query.ast = newQuery;
|
|
108
88
|
},
|
|
109
|
-
[
|
|
89
|
+
[object, schema],
|
|
110
90
|
);
|
|
111
91
|
|
|
112
|
-
if (!schema || !view) {
|
|
92
|
+
if (!schema || !object.view.target) {
|
|
113
93
|
return null;
|
|
114
94
|
}
|
|
115
95
|
|
|
116
96
|
return (
|
|
117
|
-
<div className='grow grid grid-cols-[1fr_350px]'>
|
|
97
|
+
<div className='grow grid grid-cols-[1fr_350px] overflow-hidden'>
|
|
118
98
|
{model ? <KanbanComponent model={model} onAddCard={handleAddCard} onRemoveCard={handleRemoveCard} /> : <div />}
|
|
119
|
-
<div className='flex flex-col bs-full
|
|
99
|
+
<div className='flex flex-col bs-full overflow-hidden'>
|
|
120
100
|
<ViewEditor
|
|
121
101
|
registry={space?.db.schemaRegistry}
|
|
122
102
|
schema={schema}
|
|
123
|
-
view={view}
|
|
103
|
+
view={object.view.target}
|
|
124
104
|
onQueryChanged={handleUpdateQuery}
|
|
125
105
|
onDelete={(fieldId: string) => {
|
|
126
106
|
console.log('[ViewEditor]', 'onDelete', fieldId);
|
|
127
107
|
}}
|
|
128
108
|
/>
|
|
129
|
-
<
|
|
130
|
-
{JSON.stringify({ view, schema }, null, 2)}
|
|
131
|
-
</SyntaxHighlighter>
|
|
109
|
+
<JsonFilter data={{ view: object.view.target, schema }} classNames='text-xs' />
|
|
132
110
|
</div>
|
|
133
111
|
</div>
|
|
134
112
|
);
|
|
135
113
|
};
|
|
136
114
|
|
|
137
|
-
type StoryProps = {
|
|
138
|
-
rows?: number;
|
|
139
|
-
};
|
|
140
|
-
|
|
141
115
|
//
|
|
142
116
|
// Story definitions.
|
|
143
117
|
//
|
|
@@ -156,13 +130,13 @@ const meta = {
|
|
|
156
130
|
await client.halo.createIdentity();
|
|
157
131
|
const space = await client.spaces.create();
|
|
158
132
|
await space.waitUntilReady();
|
|
159
|
-
const { view } = await
|
|
160
|
-
client,
|
|
133
|
+
const { view } = await View.makeFromSpace({
|
|
161
134
|
space,
|
|
162
135
|
typename: Organization.Organization.typename,
|
|
163
136
|
pivotFieldName: 'status',
|
|
164
137
|
});
|
|
165
|
-
|
|
138
|
+
const kanban = Kanban.make({ view });
|
|
139
|
+
space.db.add(kanban);
|
|
166
140
|
|
|
167
141
|
// TODO(burdon): Replace with sdk/schema/testing.
|
|
168
142
|
Array.from({ length: 80 }).map(() => {
|
|
@@ -2,38 +2,31 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import React, { useCallback, useEffect,
|
|
5
|
+
import React, { useCallback, useEffect, useState } from 'react';
|
|
6
6
|
|
|
7
7
|
import { createIntent } from '@dxos/app-framework';
|
|
8
|
-
import { useIntentDispatcher } from '@dxos/app-framework/react';
|
|
8
|
+
import { useCapabilities, useIntentDispatcher } from '@dxos/app-framework/react';
|
|
9
9
|
import { Filter, Obj, Type } from '@dxos/echo';
|
|
10
|
-
import {
|
|
10
|
+
import { type TypedObject } from '@dxos/echo/internal';
|
|
11
|
+
import { ClientCapabilities } from '@dxos/plugin-client';
|
|
11
12
|
import { useGlobalFilteredObjects } from '@dxos/plugin-search';
|
|
12
|
-
import { useClient } from '@dxos/react-client';
|
|
13
13
|
import { getSpace, useQuery } from '@dxos/react-client/echo';
|
|
14
|
-
import { Kanban, useKanbanModel } from '@dxos/react-ui-kanban';
|
|
14
|
+
import { Kanban as KanbanComponent, useKanbanModel, useProjectionModel } from '@dxos/react-ui-kanban';
|
|
15
|
+
import { type Kanban } from '@dxos/react-ui-kanban/types';
|
|
15
16
|
import { StackItem } from '@dxos/react-ui-stack';
|
|
16
|
-
import {
|
|
17
|
+
import { getTypenameFromQuery } from '@dxos/schema';
|
|
17
18
|
|
|
18
19
|
import { KanbanAction } from '../types';
|
|
19
20
|
|
|
20
|
-
export const KanbanContainer = ({
|
|
21
|
-
const
|
|
21
|
+
export const KanbanContainer = ({ object }: { object: Kanban.Kanban; role: string }) => {
|
|
22
|
+
const schemas = useCapabilities(ClientCapabilities.Schema);
|
|
22
23
|
const [cardSchema, setCardSchema] = useState<TypedObject<any, any>>();
|
|
23
|
-
const
|
|
24
|
-
const space = getSpace(view);
|
|
24
|
+
const space = getSpace(object);
|
|
25
25
|
const { dispatchPromise: dispatch } = useIntentDispatcher();
|
|
26
|
-
const typename = view.query ? getTypenameFromQuery(view.query.ast) : undefined;
|
|
27
|
-
|
|
28
|
-
const jsonSchema = useMemo(() => {
|
|
29
|
-
if (!cardSchema) {
|
|
30
|
-
return undefined;
|
|
31
|
-
}
|
|
32
|
-
return cardSchema instanceof EchoSchema ? cardSchema.jsonSchema : Type.toJsonSchema(cardSchema);
|
|
33
|
-
}, [cardSchema]);
|
|
26
|
+
const typename = object.view.target?.query ? getTypenameFromQuery(object.view.target.query.ast) : undefined;
|
|
34
27
|
|
|
35
28
|
useEffect(() => {
|
|
36
|
-
const staticSchema =
|
|
29
|
+
const staticSchema = schemas.flat().find((schema) => Type.getTypename(schema) === typename);
|
|
37
30
|
if (staticSchema) {
|
|
38
31
|
setCardSchema(() => staticSchema as TypedObject<any, any>);
|
|
39
32
|
}
|
|
@@ -50,21 +43,14 @@ export const KanbanContainer = ({ view }: { view: View.View; role: string }) =>
|
|
|
50
43
|
);
|
|
51
44
|
return unsubscribe;
|
|
52
45
|
}
|
|
53
|
-
}, [
|
|
54
|
-
|
|
55
|
-
useEffect(() => {
|
|
56
|
-
if (jsonSchema) {
|
|
57
|
-
setProjection(new ProjectionModel(jsonSchema, view.projection));
|
|
58
|
-
}
|
|
59
|
-
// TODO(ZaymonFC): Is there a better way to get notified about deep changes in the json schema?
|
|
60
|
-
}, [view.projection, JSON.stringify(jsonSchema)]);
|
|
46
|
+
}, [schemas, space, typename]);
|
|
61
47
|
|
|
62
48
|
const objects = useQuery(space, cardSchema ? Filter.type(cardSchema) : Filter.nothing());
|
|
63
49
|
const filteredObjects = useGlobalFilteredObjects(objects);
|
|
64
50
|
|
|
51
|
+
const projection = useProjectionModel(cardSchema, object);
|
|
65
52
|
const model = useKanbanModel({
|
|
66
|
-
|
|
67
|
-
schema: cardSchema,
|
|
53
|
+
object,
|
|
68
54
|
projection,
|
|
69
55
|
items: filteredObjects,
|
|
70
56
|
});
|
|
@@ -90,7 +76,7 @@ export const KanbanContainer = ({ view }: { view: View.View; role: string }) =>
|
|
|
90
76
|
|
|
91
77
|
return (
|
|
92
78
|
<StackItem.Content>
|
|
93
|
-
{model && <
|
|
79
|
+
{model && <KanbanComponent model={model} onAddCard={handleAddCard} onRemoveCard={handleRemoveCard} />}
|
|
94
80
|
</StackItem.Content>
|
|
95
81
|
);
|
|
96
82
|
};
|
|
@@ -4,61 +4,51 @@
|
|
|
4
4
|
|
|
5
5
|
import React, { useCallback, useMemo } from 'react';
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { useClient } from '@dxos/react-client';
|
|
7
|
+
import { Format } from '@dxos/echo/internal';
|
|
8
|
+
import { invariant } from '@dxos/invariant';
|
|
10
9
|
import { getSpace, useSchema } from '@dxos/react-client/echo';
|
|
11
|
-
import { type
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
10
|
+
import { Form, type FormFieldMap, SelectField } from '@dxos/react-ui-form';
|
|
11
|
+
import { useProjectionModel } from '@dxos/react-ui-kanban';
|
|
12
|
+
import { type Kanban } from '@dxos/react-ui-kanban/types';
|
|
13
|
+
import { getTypenameFromQuery } from '@dxos/schema';
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
import { SettingsSchema } from '../types';
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
const client = useClient();
|
|
19
|
-
const space = getSpace(view);
|
|
20
|
-
const currentTypename = view.query ? getTypenameFromQuery(view.query.ast) : undefined;
|
|
21
|
-
const schema = useSchema(client, space, currentTypename);
|
|
17
|
+
type KanbanViewEditorProps = { object: Kanban.Kanban };
|
|
22
18
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
}, [view.projection, JSON.stringify(schema)]);
|
|
19
|
+
export const KanbanViewEditor = ({ object }: KanbanViewEditorProps) => {
|
|
20
|
+
const space = getSpace(object);
|
|
21
|
+
const view = object.view.target;
|
|
22
|
+
const currentTypename = view?.query ? getTypenameFromQuery(view.query.ast) : undefined;
|
|
23
|
+
const schema = useSchema(space, currentTypename);
|
|
24
|
+
const projection = useProjectionModel(schema, object);
|
|
31
25
|
|
|
32
26
|
const fieldProjections = projection?.getFieldProjections() || [];
|
|
33
27
|
const selectFields = fieldProjections
|
|
34
|
-
.filter((field) => field.props.format ===
|
|
28
|
+
.filter((field) => field.props.format === Format.TypeFormat.SingleSelect)
|
|
35
29
|
.map(({ field }) => ({ value: field.id, label: field.path }));
|
|
36
30
|
|
|
37
31
|
const handleSave = useCallback(
|
|
38
32
|
(values: Partial<{ columnFieldId: string }>) => {
|
|
33
|
+
invariant(view);
|
|
39
34
|
view.projection.pivotFieldId = values.columnFieldId;
|
|
40
35
|
},
|
|
41
36
|
[view],
|
|
42
37
|
);
|
|
43
38
|
|
|
44
39
|
const initialValues = useMemo(
|
|
45
|
-
() => ({ columnFieldId: view
|
|
46
|
-
[view
|
|
40
|
+
() => ({ columnFieldId: view?.projection.pivotFieldId }),
|
|
41
|
+
[view?.projection.pivotFieldId],
|
|
47
42
|
);
|
|
48
|
-
|
|
49
|
-
|
|
43
|
+
|
|
44
|
+
const fieldMap: FormFieldMap = useMemo(
|
|
45
|
+
() => ({ columnFieldId: (props) => <SelectField {...props} options={selectFields} /> }),
|
|
50
46
|
[selectFields],
|
|
51
47
|
);
|
|
52
48
|
|
|
53
49
|
return (
|
|
54
|
-
<Form
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
values={initialValues}
|
|
58
|
-
onSave={handleSave}
|
|
59
|
-
autoSave
|
|
60
|
-
outerSpacing={false}
|
|
61
|
-
classNames='pbs-inputSpacingBlock'
|
|
62
|
-
/>
|
|
50
|
+
<Form.Root schema={SettingsSchema} values={initialValues} fieldMap={fieldMap} autoSave onSave={handleSave}>
|
|
51
|
+
<Form.FieldSet />
|
|
52
|
+
</Form.Root>
|
|
63
53
|
);
|
|
64
54
|
};
|
package/src/translations.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { Type } from '@dxos/echo';
|
|
5
6
|
import { type Resource } from '@dxos/react-ui';
|
|
6
7
|
import { Kanban } from '@dxos/react-ui-kanban/types';
|
|
7
8
|
|
|
@@ -10,24 +11,23 @@ import { meta } from './meta';
|
|
|
10
11
|
export const translations = [
|
|
11
12
|
{
|
|
12
13
|
'en-US': {
|
|
13
|
-
[Kanban.Kanban
|
|
14
|
+
[Type.getTypename(Kanban.Kanban)]: {
|
|
14
15
|
'typename label': 'Kanban',
|
|
15
16
|
'typename label_zero': 'Kanbans',
|
|
16
17
|
'typename label_one': 'Kanban',
|
|
17
18
|
'typename label_other': 'Kanbans',
|
|
18
19
|
'object name placeholder': 'New kanban',
|
|
20
|
+
'rename object label': 'Rename kanban',
|
|
21
|
+
'delete object label': 'Delete kanban',
|
|
22
|
+
'object deleted label': 'Kanban deleted',
|
|
19
23
|
},
|
|
20
24
|
[meta.id]: {
|
|
21
25
|
'plugin name': 'Kanban',
|
|
22
26
|
'kanban title label': 'Title',
|
|
23
27
|
'column title label': 'Column title',
|
|
24
28
|
'column title placeholder': 'New column',
|
|
25
|
-
'item title label': 'Item title',
|
|
26
|
-
'item title placeholder': 'New item',
|
|
27
29
|
'add column label': 'Add column',
|
|
28
|
-
'add item label': 'Add card',
|
|
29
30
|
'delete column label': 'Delete column',
|
|
30
|
-
'delete item label': 'Delete card',
|
|
31
31
|
'card field deleted label': 'Card field deleted',
|
|
32
32
|
'card deleted label': 'Card deleted',
|
|
33
33
|
},
|