@dxos/plugin-kanban 0.8.4-main.5ea62a8 → 0.8.4-main.72ec0f3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/lib/browser/{blueprint-definition-GFG7LX2C.mjs → blueprint-definition-UYVX622Q.mjs} +3 -3
  2. package/dist/lib/browser/{blueprint-definition-GFG7LX2C.mjs.map → blueprint-definition-UYVX622Q.mjs.map} +1 -1
  3. package/dist/lib/browser/{chunk-NCNNL74W.mjs → chunk-HO3LQ5T7.mjs} +14 -10
  4. package/dist/lib/browser/chunk-HO3LQ5T7.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +7 -8
  6. package/dist/lib/browser/index.mjs.map +3 -3
  7. package/dist/lib/browser/{intent-resolver-2IYZ7TZE.mjs → intent-resolver-OPYUDNSU.mjs} +10 -10
  8. package/dist/lib/browser/intent-resolver-OPYUDNSU.mjs.map +7 -0
  9. package/dist/lib/browser/meta.json +1 -1
  10. package/dist/lib/browser/{react-surface-XRHHQ4OI.mjs → react-surface-X54TNDDN.mjs} +21 -19
  11. package/dist/lib/browser/react-surface-X54TNDDN.mjs.map +7 -0
  12. package/dist/lib/browser/types/index.mjs +1 -1
  13. package/dist/lib/node-esm/{blueprint-definition-MIMDXMUM.mjs → blueprint-definition-42P47FUY.mjs} +3 -3
  14. package/dist/lib/node-esm/{blueprint-definition-MIMDXMUM.mjs.map → blueprint-definition-42P47FUY.mjs.map} +1 -1
  15. package/dist/lib/node-esm/{chunk-5B3LKGA7.mjs → chunk-QZMZU5HM.mjs} +14 -10
  16. package/dist/lib/node-esm/chunk-QZMZU5HM.mjs.map +7 -0
  17. package/dist/lib/node-esm/index.mjs +7 -8
  18. package/dist/lib/node-esm/index.mjs.map +3 -3
  19. package/dist/lib/node-esm/{intent-resolver-T7CEL6EN.mjs → intent-resolver-BDKNXV3R.mjs} +10 -10
  20. package/dist/lib/node-esm/intent-resolver-BDKNXV3R.mjs.map +7 -0
  21. package/dist/lib/node-esm/meta.json +1 -1
  22. package/dist/lib/node-esm/{react-surface-BTB5JAKG.mjs → react-surface-CVDMIHSC.mjs} +21 -19
  23. package/dist/lib/node-esm/react-surface-CVDMIHSC.mjs.map +7 -0
  24. package/dist/lib/node-esm/types/index.mjs +1 -1
  25. package/dist/types/src/KanbanPlugin.d.ts +1 -1
  26. package/dist/types/src/KanbanPlugin.d.ts.map +1 -1
  27. package/dist/types/src/capabilities/artifact-definition.d.ts.map +1 -1
  28. package/dist/types/src/capabilities/blueprint-definition.d.ts +1 -1
  29. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  30. package/dist/types/src/components/KanbanContainer.d.ts +2 -2
  31. package/dist/types/src/components/KanbanContainer.d.ts.map +1 -1
  32. package/dist/types/src/components/KanbanContainer.stories.d.ts +2 -2
  33. package/dist/types/src/components/KanbanContainer.stories.d.ts.map +1 -1
  34. package/dist/types/src/components/KanbanViewEditor.d.ts +2 -2
  35. package/dist/types/src/components/KanbanViewEditor.d.ts.map +1 -1
  36. package/dist/types/src/meta.d.ts +0 -1
  37. package/dist/types/src/meta.d.ts.map +1 -1
  38. package/dist/types/src/types/schema.d.ts +10 -43
  39. package/dist/types/src/types/schema.d.ts.map +1 -1
  40. package/dist/types/tsconfig.tsbuildinfo +1 -1
  41. package/package.json +41 -41
  42. package/src/KanbanPlugin.tsx +47 -47
  43. package/src/capabilities/artifact-definition.ts +9 -8
  44. package/src/capabilities/intent-resolver.ts +5 -5
  45. package/src/capabilities/react-surface.tsx +13 -8
  46. package/src/components/KanbanContainer.stories.tsx +29 -24
  47. package/src/components/KanbanContainer.tsx +7 -6
  48. package/src/components/KanbanViewEditor.tsx +7 -5
  49. package/src/meta.ts +7 -5
  50. package/src/types/schema.ts +7 -6
  51. package/dist/lib/browser/chunk-NCNNL74W.mjs.map +0 -7
  52. package/dist/lib/browser/intent-resolver-2IYZ7TZE.mjs.map +0 -7
  53. package/dist/lib/browser/react-surface-XRHHQ4OI.mjs.map +0 -7
  54. package/dist/lib/node-esm/chunk-5B3LKGA7.mjs.map +0 -7
  55. package/dist/lib/node-esm/intent-resolver-T7CEL6EN.mjs.map +0 -7
  56. package/dist/lib/node-esm/react-surface-BTB5JAKG.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.5ea62a8",
3
+ "version": "0.8.4-main.72ec0f3",
4
4
  "description": "Kanban DXOS Surface plugin",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -36,51 +36,51 @@
36
36
  ],
37
37
  "dependencies": {
38
38
  "@preact-signals/safe-react": "^0.9.0",
39
- "@preact/signals-core": "^1.9.0",
40
- "effect": "3.17.7",
41
- "@dxos/app-framework": "0.8.4-main.5ea62a8",
42
- "@dxos/ai": "0.8.4-main.5ea62a8",
43
- "@dxos/assistant": "0.8.4-main.5ea62a8",
44
- "@dxos/async": "0.8.4-main.5ea62a8",
45
- "@dxos/echo": "0.8.4-main.5ea62a8",
46
- "@dxos/echo-schema": "0.8.4-main.5ea62a8",
47
- "@dxos/blueprints": "0.8.4-main.5ea62a8",
48
- "@dxos/effect": "0.8.4-main.5ea62a8",
49
- "@dxos/functions": "0.8.4-main.5ea62a8",
50
- "@dxos/invariant": "0.8.4-main.5ea62a8",
51
- "@dxos/log": "0.8.4-main.5ea62a8",
52
- "@dxos/plugin-graph": "0.8.4-main.5ea62a8",
53
- "@dxos/plugin-space": "0.8.4-main.5ea62a8",
54
- "@dxos/plugin-search": "0.8.4-main.5ea62a8",
55
- "@dxos/random": "0.8.4-main.5ea62a8",
56
- "@dxos/react-ui": "0.8.4-main.5ea62a8",
57
- "@dxos/react-ui-form": "0.8.4-main.5ea62a8",
58
- "@dxos/react-ui-kanban": "0.8.4-main.5ea62a8",
59
- "@dxos/react-client": "0.8.4-main.5ea62a8",
60
- "@dxos/react-ui-stack": "0.8.4-main.5ea62a8",
61
- "@dxos/schema": "0.8.4-main.5ea62a8",
62
- "@dxos/plugin-client": "0.8.4-main.5ea62a8",
63
- "@dxos/util": "0.8.4-main.5ea62a8"
39
+ "@preact/signals-core": "^1.12.1",
40
+ "effect": "3.18.3",
41
+ "@dxos/ai": "0.8.4-main.72ec0f3",
42
+ "@dxos/assistant": "0.8.4-main.72ec0f3",
43
+ "@dxos/app-framework": "0.8.4-main.72ec0f3",
44
+ "@dxos/echo": "0.8.4-main.72ec0f3",
45
+ "@dxos/async": "0.8.4-main.72ec0f3",
46
+ "@dxos/effect": "0.8.4-main.72ec0f3",
47
+ "@dxos/functions": "0.8.4-main.72ec0f3",
48
+ "@dxos/blueprints": "0.8.4-main.72ec0f3",
49
+ "@dxos/log": "0.8.4-main.72ec0f3",
50
+ "@dxos/plugin-client": "0.8.4-main.72ec0f3",
51
+ "@dxos/invariant": "0.8.4-main.72ec0f3",
52
+ "@dxos/plugin-space": "0.8.4-main.72ec0f3",
53
+ "@dxos/plugin-graph": "0.8.4-main.72ec0f3",
54
+ "@dxos/plugin-search": "0.8.4-main.72ec0f3",
55
+ "@dxos/random": "0.8.4-main.72ec0f3",
56
+ "@dxos/react-client": "0.8.4-main.72ec0f3",
57
+ "@dxos/react-ui": "0.8.4-main.72ec0f3",
58
+ "@dxos/react-ui-form": "0.8.4-main.72ec0f3",
59
+ "@dxos/react-ui-kanban": "0.8.4-main.72ec0f3",
60
+ "@dxos/react-ui-stack": "0.8.4-main.72ec0f3",
61
+ "@dxos/schema": "0.8.4-main.72ec0f3",
62
+ "@dxos/types": "0.8.4-main.72ec0f3",
63
+ "@dxos/util": "0.8.4-main.72ec0f3"
64
64
  },
65
65
  "devDependencies": {
66
- "@types/react": "~18.2.0",
67
- "@types/react-dom": "~18.2.0",
68
- "react": "~18.2.0",
69
- "react-dom": "~18.2.0",
70
- "vite": "7.1.1",
71
- "@dxos/plugin-theme": "0.8.4-main.5ea62a8",
72
- "@dxos/plugin-preview": "0.8.4-main.5ea62a8",
73
- "@dxos/react-ui-syntax-highlighter": "0.8.4-main.5ea62a8",
74
- "@dxos/react-ui-theme": "0.8.4-main.5ea62a8",
75
- "@dxos/storybook-utils": "0.8.4-main.5ea62a8",
76
- "@dxos/test-utils": "0.8.4-main.5ea62a8"
66
+ "@types/react": "~19.2.2",
67
+ "@types/react-dom": "~19.2.2",
68
+ "react": "~19.2.0",
69
+ "react-dom": "~19.2.0",
70
+ "vite": "7.1.9",
71
+ "@dxos/plugin-theme": "0.8.4-main.72ec0f3",
72
+ "@dxos/plugin-preview": "0.8.4-main.72ec0f3",
73
+ "@dxos/react-ui-theme": "0.8.4-main.72ec0f3",
74
+ "@dxos/react-ui-syntax-highlighter": "0.8.4-main.72ec0f3",
75
+ "@dxos/storybook-utils": "0.8.4-main.72ec0f3",
76
+ "@dxos/test-utils": "0.8.4-main.72ec0f3"
77
77
  },
78
78
  "peerDependencies": {
79
79
  "effect": "^3.13.3",
80
- "react": "~18.2.0",
81
- "react-dom": "~18.2.0",
82
- "@dxos/react-ui": "0.8.4-main.5ea62a8",
83
- "@dxos/react-ui-theme": "0.8.4-main.5ea62a8"
80
+ "react": "^19.0.0",
81
+ "react-dom": "^19.0.0",
82
+ "@dxos/react-ui": "0.8.4-main.72ec0f3",
83
+ "@dxos/react-ui-theme": "0.8.4-main.72ec0f3"
84
84
  },
85
85
  "publishConfig": {
86
86
  "access": "public"
@@ -14,51 +14,51 @@ import { meta } from './meta';
14
14
  import { translations } from './translations';
15
15
  import { CreateKanbanSchema, KanbanAction } from './types';
16
16
 
17
- export const KanbanPlugin = () =>
18
- definePlugin(meta, [
19
- defineModule({
20
- id: `${meta.id}/module/translations`,
21
- activatesOn: Events.SetupTranslations,
22
- activate: () => contributes(Capabilities.Translations, [...translations, ...kanbanTranslations]),
23
- }),
24
- defineModule({
25
- id: `${meta.id}/module/metadata`,
26
- activatesOn: Events.SetupMetadata,
27
- activate: () =>
28
- contributes(Capabilities.Metadata, {
29
- id: Kanban.Kanban.typename,
30
- metadata: {
31
- icon: 'ph--kanban--regular',
32
- },
17
+ export const KanbanPlugin = definePlugin(meta, () => [
18
+ defineModule({
19
+ id: `${meta.id}/module/translations`,
20
+ activatesOn: Events.SetupTranslations,
21
+ activate: () => contributes(Capabilities.Translations, [...translations, ...kanbanTranslations]),
22
+ }),
23
+ defineModule({
24
+ id: `${meta.id}/module/metadata`,
25
+ activatesOn: Events.SetupMetadata,
26
+ activate: () =>
27
+ contributes(Capabilities.Metadata, {
28
+ id: Kanban.Kanban.typename,
29
+ metadata: {
30
+ icon: 'ph--kanban--regular',
31
+ iconHue: 'green',
32
+ },
33
+ }),
34
+ }),
35
+ defineModule({
36
+ id: `${meta.id}/module/object-form`,
37
+ activatesOn: ClientEvents.SetupSchema,
38
+ activate: () =>
39
+ contributes(
40
+ SpaceCapabilities.ObjectForm,
41
+ defineObjectForm({
42
+ objectSchema: Kanban.Kanban,
43
+ formSchema: CreateKanbanSchema,
44
+ hidden: true,
45
+ getIntent: (props, options) => createIntent(KanbanAction.Create, { ...props, space: options.space }),
33
46
  }),
34
- }),
35
- defineModule({
36
- id: `${meta.id}/module/object-form`,
37
- activatesOn: ClientEvents.SetupSchema,
38
- activate: () =>
39
- contributes(
40
- SpaceCapabilities.ObjectForm,
41
- defineObjectForm({
42
- objectSchema: Kanban.Kanban,
43
- formSchema: CreateKanbanSchema,
44
- hidden: true,
45
- getIntent: (props, options) => createIntent(KanbanAction.Create, { ...props, space: options.space }),
46
- }),
47
- ),
48
- }),
49
- defineModule({
50
- id: `${meta.id}/module/react-surface`,
51
- activatesOn: Events.SetupReactSurface,
52
- activate: ReactSurface,
53
- }),
54
- defineModule({
55
- id: `${meta.id}/module/intent-resolver`,
56
- activatesOn: Events.SetupIntentResolver,
57
- activate: IntentResolver,
58
- }),
59
- defineModule({
60
- id: `${meta.id}/module/blueprint`,
61
- activatesOn: Events.SetupArtifactDefinition,
62
- activate: BlueprintDefinition,
63
- }),
64
- ]);
47
+ ),
48
+ }),
49
+ defineModule({
50
+ id: `${meta.id}/module/react-surface`,
51
+ activatesOn: Events.SetupReactSurface,
52
+ activate: ReactSurface,
53
+ }),
54
+ defineModule({
55
+ id: `${meta.id}/module/intent-resolver`,
56
+ activatesOn: Events.SetupIntentResolver,
57
+ activate: IntentResolver,
58
+ }),
59
+ defineModule({
60
+ id: `${meta.id}/module/blueprint`,
61
+ activatesOn: Events.SetupArtifactDefinition,
62
+ activate: BlueprintDefinition,
63
+ }),
64
+ ]);
@@ -5,7 +5,8 @@
5
5
  // ISSUE(burdon): defineArtifact
6
6
  // @ts-nocheck
7
7
 
8
- import { Schema, pipe } from 'effect';
8
+ import * as Function from 'effect/Function';
9
+ import * as Schema from 'effect/Schema';
9
10
 
10
11
  import { ToolResult, createTool } from '@dxos/ai';
11
12
  import { Capabilities, type PromiseIntentDispatcher, chain, contributes, createIntent } from '@dxos/app-framework';
@@ -14,9 +15,9 @@ import { defineArtifact } from '@dxos/blueprints';
14
15
  import { Obj, Query } from '@dxos/echo';
15
16
  import { invariant } from '@dxos/invariant';
16
17
  import { SpaceAction } from '@dxos/plugin-space/types';
17
- import { Filter, type Space, fullyQualifiedId } from '@dxos/react-client/echo';
18
+ import { Filter, type Space } from '@dxos/react-client/echo';
18
19
  import { KanbanView } from '@dxos/react-ui-kanban';
19
- import { DataType } from '@dxos/schema';
20
+ import { View } from '@dxos/schema';
20
21
  import { isNonNullable } from '@dxos/util';
21
22
 
22
23
  import { meta } from '../meta';
@@ -68,7 +69,7 @@ export default () => {
68
69
  return ToolResult.Error(`Schema not found: ${typename}`);
69
70
  }
70
71
 
71
- const intent = pipe(
72
+ const intent = Function.pipe(
72
73
  createIntent(KanbanAction.Create, {
73
74
  space: extensions.space,
74
75
  typename,
@@ -93,7 +94,7 @@ export default () => {
93
94
  execute: async (_input, { extensions }) => {
94
95
  invariant(extensions?.space, 'No space');
95
96
  const space = extensions.space;
96
- const { objects } = await space.db.query(Filter.type(DataType.View)).run();
97
+ const { objects } = await space.db.query(Filter.type(View.View)).run();
97
98
 
98
99
  const boardInfo = await Promise.all(
99
100
  objects.map(async (view) => {
@@ -103,7 +104,7 @@ export default () => {
103
104
  }
104
105
 
105
106
  return {
106
- id: fullyQualifiedId(view),
107
+ id: Obj.getDXN(view).toString(),
107
108
  name: view.name ?? 'Unnamed Kanban',
108
109
  typename: view.query.typename,
109
110
  };
@@ -123,8 +124,8 @@ export default () => {
123
124
  const space = extensions.space;
124
125
  const view = (await space.db
125
126
  // 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;
127
+ .query(Query.select(Filter.and(Filter.type(View.View), Filter.ids(id))))
128
+ .first()) as View.View;
128
129
 
129
130
  const kanban = await view.presentation.load();
130
131
  invariant(Obj.instanceOf(KanbanView, kanban));
@@ -7,9 +7,9 @@ import { invariant } from '@dxos/invariant';
7
7
  import { ClientCapabilities } from '@dxos/plugin-client';
8
8
  import { getSpace } from '@dxos/react-client/echo';
9
9
  import { Kanban } from '@dxos/react-ui-kanban/types';
10
- import { ProjectionModel } from '@dxos/schema';
10
+ import { ProjectionModel, getTypenameFromQuery } from '@dxos/schema';
11
11
 
12
- import { KANBAN_PLUGIN } from '../meta';
12
+ import { meta } from '../meta';
13
13
  import { KanbanAction } from '../types';
14
14
 
15
15
  export default (context: PluginContext) =>
@@ -31,7 +31,7 @@ export default (context: PluginContext) =>
31
31
  createResolver({
32
32
  intent: KanbanAction.DeleteCardField,
33
33
  resolve: async ({ view, fieldId, deletionData }, undo) => {
34
- const schema = getSpace(view)?.db.schemaRegistry.getSchema(view.query.typename!);
34
+ const schema = getSpace(view)?.db.schemaRegistry.getSchema(getTypenameFromQuery(view.query.ast)!);
35
35
  invariant(schema);
36
36
  const projection = new ProjectionModel(schema.jsonSchema, view.projection);
37
37
 
@@ -39,7 +39,7 @@ export default (context: PluginContext) =>
39
39
  const { deleted, index } = projection.deleteFieldProjection(fieldId);
40
40
  return {
41
41
  undoable: {
42
- message: ['card field deleted label', { ns: KANBAN_PLUGIN }],
42
+ message: ['card field deleted label', { ns: meta.id }],
43
43
  data: { deletionData: { ...deleted, index } },
44
44
  },
45
45
  };
@@ -59,7 +59,7 @@ export default (context: PluginContext) =>
59
59
  space.db.remove(card);
60
60
  return {
61
61
  undoable: {
62
- message: ['card deleted label', { ns: KANBAN_PLUGIN }],
62
+ message: ['card deleted label', { ns: meta.id }],
63
63
  data: { card },
64
64
  },
65
65
  };
@@ -2,17 +2,18 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { type Schema } from 'effect';
5
+ import type * as Schema from 'effect/Schema';
6
6
  import React, { useMemo } from 'react';
7
7
 
8
- import { Capabilities, contributes, createSurface, useCapabilities } from '@dxos/app-framework';
8
+ import { Capabilities, contributes, createSurface } from '@dxos/app-framework';
9
+ import { useCapabilities } from '@dxos/app-framework/react';
9
10
  import { Obj, Type } from '@dxos/echo';
10
11
  import { findAnnotation } from '@dxos/effect';
11
12
  import { ClientCapabilities } from '@dxos/plugin-client';
12
13
  import { type Space, getSpace, isSpace } from '@dxos/react-client/echo';
13
14
  import { type InputProps, SelectInput, useFormValues } from '@dxos/react-ui-form';
14
15
  import { Kanban } from '@dxos/react-ui-kanban/types';
15
- import { DataType } from '@dxos/schema';
16
+ import { type Collection, View } from '@dxos/schema';
16
17
 
17
18
  import { KanbanContainer, KanbanViewEditor } from '../components';
18
19
  import { meta } from '../meta';
@@ -23,16 +24,16 @@ export default () =>
23
24
  createSurface({
24
25
  id: meta.id,
25
26
  role: ['article', 'section'],
26
- filter: (data): data is { subject: DataType.View } =>
27
- Obj.instanceOf(DataType.View, data.subject) && Obj.instanceOf(Kanban.Kanban, data.subject.presentation.target),
27
+ filter: (data): data is { subject: View.View } =>
28
+ Obj.instanceOf(View.View, data.subject) && Obj.instanceOf(Kanban.Kanban, data.subject.presentation.target),
28
29
  component: ({ data, role }) => <KanbanContainer view={data.subject} role={role} />,
29
30
  }),
30
31
  createSurface({
31
32
  id: `${meta.id}/object-settings`,
32
33
  role: 'object-settings',
33
34
  position: 'hoist',
34
- filter: (data): data is { subject: DataType.View } =>
35
- Obj.instanceOf(DataType.View, data.subject) && Obj.instanceOf(Kanban.Kanban, data.subject.presentation.target),
35
+ filter: (data): data is { subject: View.View } =>
36
+ Obj.instanceOf(View.View, data.subject) && Obj.instanceOf(Kanban.Kanban, data.subject.presentation.target),
36
37
  component: ({ data }) => <KanbanViewEditor view={data.subject} />,
37
38
  }),
38
39
  createSurface({
@@ -40,7 +41,11 @@ export default () =>
40
41
  role: 'form-input',
41
42
  filter: (
42
43
  data,
43
- ): data is { prop: string; schema: Schema.Schema<any>; target: Space | DataType.Collection | undefined } => {
44
+ ): data is {
45
+ prop: string;
46
+ schema: Schema.Schema<any>;
47
+ target: Space | Collection.Collection | undefined;
48
+ } => {
44
49
  const annotation = findAnnotation<boolean>((data.schema as Schema.Schema.All).ast, PivotColumnAnnotationId);
45
50
  return !!annotation;
46
51
  },
@@ -2,14 +2,12 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
8
6
  import React, { useCallback, useEffect, useState } from 'react';
9
7
 
10
8
  import { IntentPlugin, SettingsPlugin } from '@dxos/app-framework';
11
9
  import { withPluginManager } from '@dxos/app-framework/testing';
12
- import { Obj, Type } from '@dxos/echo';
10
+ import { Obj, type QueryAST, Type } from '@dxos/echo';
13
11
  import { invariant } from '@dxos/invariant';
14
12
  import { ClientPlugin } from '@dxos/plugin-client';
15
13
  import { PreviewPlugin } from '@dxos/plugin-preview';
@@ -20,13 +18,14 @@ import { ThemePlugin } from '@dxos/plugin-theme';
20
18
  import { faker } from '@dxos/random';
21
19
  import { useClient } from '@dxos/react-client';
22
20
  import { Filter, useQuery, useSchema, useSpaces } from '@dxos/react-client/echo';
21
+ import { withTheme } from '@dxos/react-ui/testing';
23
22
  import { ViewEditor } from '@dxos/react-ui-form';
24
23
  import { Kanban as KanbanComponent, useKanbanModel } from '@dxos/react-ui-kanban';
25
24
  import { Kanban } from '@dxos/react-ui-kanban/types';
26
25
  import { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';
27
26
  import { defaultTx } from '@dxos/react-ui-theme';
28
- import { DataType, ProjectionModel } from '@dxos/schema';
29
- import { withLayout } from '@dxos/storybook-utils';
27
+ import { ProjectionModel, View, getTypenameFromQuery } from '@dxos/schema';
28
+ import { Organization, Person } from '@dxos/types';
30
29
 
31
30
  import { translations } from '../translations';
32
31
 
@@ -41,17 +40,18 @@ const rollOrg = () => ({
41
40
  description: faker.lorem.paragraph(),
42
41
  image: faker.image.url(),
43
42
  website: faker.internet.url(),
44
- status: faker.helpers.arrayElement(DataType.OrganizationStatusOptions).id as DataType.Organization['status'],
43
+ status: faker.helpers.arrayElement(Organization.StatusOptions).id as Organization.Organization['status'],
45
44
  });
46
45
 
47
46
  const StorybookKanban = () => {
48
47
  const client = useClient();
49
48
  const spaces = useSpaces();
50
49
  const space = spaces[spaces.length - 1];
51
- const views = useQuery(space, Filter.type(DataType.View));
52
- const [view, setView] = useState<DataType.View>();
50
+ const views = useQuery(space, Filter.type(View.View));
51
+ const [view, setView] = useState<View.View>();
53
52
  const [projection, setProjection] = useState<ProjectionModel>();
54
- const schema = useSchema(client, space, view?.query.typename);
53
+ const typename = view?.query ? getTypenameFromQuery(view.query.ast) : undefined;
54
+ const schema = useSchema(client, space, typename);
55
55
 
56
56
  useEffect(() => {
57
57
  if (views.length && !view) {
@@ -97,14 +97,14 @@ const StorybookKanban = () => {
97
97
 
98
98
  const handleRemoveCard = useCallback((card: { id: string }) => space.db.remove(card), [space]);
99
99
 
100
- const handleTypenameChanged = useCallback(
101
- (typename: string) => {
100
+ const handleUpdateQuery = useCallback(
101
+ (newQuery: QueryAST.Query) => {
102
102
  invariant(schema);
103
103
  invariant(Type.isMutable(schema));
104
104
  invariant(view);
105
105
 
106
- schema.updateTypename(typename);
107
- view.query.typename = typename;
106
+ schema.updateTypename(getTypenameFromQuery(newQuery));
107
+ view.query.ast = newQuery;
108
108
  },
109
109
  [view, schema],
110
110
  );
@@ -121,12 +121,12 @@ const StorybookKanban = () => {
121
121
  registry={space?.db.schemaRegistry}
122
122
  schema={schema}
123
123
  view={view}
124
- onTypenameChanged={handleTypenameChanged}
124
+ onQueryChanged={handleUpdateQuery}
125
125
  onDelete={(fieldId: string) => {
126
126
  console.log('[ViewEditor]', 'onDelete', fieldId);
127
127
  }}
128
128
  />
129
- <SyntaxHighlighter language='json' className='w-full text-xs'>
129
+ <SyntaxHighlighter language='json' className='text-xs'>
130
130
  {JSON.stringify({ view, schema }, null, 2)}
131
131
  </SyntaxHighlighter>
132
132
  </div>
@@ -146,14 +146,12 @@ const meta = {
146
146
  title: 'plugins/plugin-kanban/Kanban',
147
147
  component: StorybookKanban,
148
148
  render: () => <StorybookKanban />,
149
- parameters: { translations },
150
149
  decorators: [
151
- withLayout({ fullscreen: true }),
150
+ withTheme,
152
151
  withPluginManager({
153
152
  plugins: [
154
- ThemePlugin({ tx: defaultTx }),
155
153
  ClientPlugin({
156
- types: [DataType.Organization, DataType.Person, DataType.View, Kanban.Kanban],
154
+ types: [Organization.Organization, Person.Person, View.View, Kanban.Kanban],
157
155
  onClientInitialized: async ({ client }) => {
158
156
  await client.halo.createIdentity();
159
157
  const space = await client.spaces.create();
@@ -161,25 +159,32 @@ const meta = {
161
159
  const { view } = await Kanban.makeView({
162
160
  client,
163
161
  space,
164
- typename: DataType.Organization.typename,
162
+ typename: Organization.Organization.typename,
165
163
  pivotFieldName: 'status',
166
164
  });
167
165
  space.db.add(view);
168
166
 
169
167
  // TODO(burdon): Replace with sdk/schema/testing.
170
168
  Array.from({ length: 80 }).map(() => {
171
- return space.db.add(Obj.make(DataType.Organization, rollOrg()));
169
+ return space.db.add(Obj.make(Organization.Organization, rollOrg()));
172
170
  });
173
171
  },
174
172
  }),
175
- StorybookLayoutPlugin(),
176
- PreviewPlugin(),
177
- SpacePlugin(),
173
+ SpacePlugin({}),
178
174
  IntentPlugin(),
179
175
  SettingsPlugin(),
176
+
177
+ // UI
178
+ ThemePlugin({ tx: defaultTx }),
179
+ PreviewPlugin(),
180
+ StorybookLayoutPlugin({}),
180
181
  ],
181
182
  }),
182
183
  ],
184
+ parameters: {
185
+ layout: 'fullscreen',
186
+ translations,
187
+ },
183
188
  } satisfies Meta<typeof StorybookKanban>;
184
189
 
185
190
  export default meta;
@@ -4,24 +4,26 @@
4
4
 
5
5
  import React, { useCallback, useEffect, useMemo, useState } from 'react';
6
6
 
7
- import { createIntent, useIntentDispatcher } from '@dxos/app-framework';
7
+ import { createIntent } from '@dxos/app-framework';
8
+ import { useIntentDispatcher } from '@dxos/app-framework/react';
8
9
  import { Filter, Obj, Type } from '@dxos/echo';
9
- import { EchoSchema, type TypedObject } from '@dxos/echo-schema';
10
+ import { EchoSchema, type TypedObject } from '@dxos/echo/internal';
10
11
  import { useGlobalFilteredObjects } from '@dxos/plugin-search';
11
12
  import { useClient } from '@dxos/react-client';
12
13
  import { getSpace, useQuery } from '@dxos/react-client/echo';
13
14
  import { Kanban, useKanbanModel } from '@dxos/react-ui-kanban';
14
15
  import { StackItem } from '@dxos/react-ui-stack';
15
- import { type DataType, ProjectionModel } from '@dxos/schema';
16
+ import { ProjectionModel, type View, getTypenameFromQuery } from '@dxos/schema';
16
17
 
17
18
  import { KanbanAction } from '../types';
18
19
 
19
- export const KanbanContainer = ({ view }: { view: DataType.View; role: string }) => {
20
+ export const KanbanContainer = ({ view }: { view: View.View; role: string }) => {
20
21
  const client = useClient();
21
22
  const [cardSchema, setCardSchema] = useState<TypedObject<any, any>>();
22
23
  const [projection, setProjection] = useState<ProjectionModel>();
23
24
  const space = getSpace(view);
24
25
  const { dispatchPromise: dispatch } = useIntentDispatcher();
26
+ const typename = view.query ? getTypenameFromQuery(view.query.ast) : undefined;
25
27
 
26
28
  const jsonSchema = useMemo(() => {
27
29
  if (!cardSchema) {
@@ -31,7 +33,6 @@ export const KanbanContainer = ({ view }: { view: DataType.View; role: string })
31
33
  }, [cardSchema]);
32
34
 
33
35
  useEffect(() => {
34
- const typename = view.query.typename;
35
36
  const staticSchema = client.graph.schemaRegistry.schemas.find((schema) => Type.getTypename(schema) === typename);
36
37
  if (staticSchema) {
37
38
  setCardSchema(() => staticSchema as TypedObject<any, any>);
@@ -49,7 +50,7 @@ export const KanbanContainer = ({ view }: { view: DataType.View; role: string })
49
50
  );
50
51
  return unsubscribe;
51
52
  }
52
- }, [view.query.typename, space]);
53
+ }, [typename, space]);
53
54
 
54
55
  useEffect(() => {
55
56
  if (jsonSchema) {
@@ -5,25 +5,27 @@
5
5
  import React, { useCallback, useMemo } from 'react';
6
6
 
7
7
  import { Type } from '@dxos/echo';
8
- import { EchoSchema, FormatEnum } from '@dxos/echo-schema';
8
+ import { EchoSchema, FormatEnum } from '@dxos/echo/internal';
9
9
  import { useClient } from '@dxos/react-client';
10
10
  import { getSpace, useSchema } from '@dxos/react-client/echo';
11
11
  import { type CustomInputMap, Form, SelectInput } from '@dxos/react-ui-form';
12
12
  import { Kanban } from '@dxos/react-ui-kanban/types';
13
- import { type DataType, ProjectionModel } from '@dxos/schema';
13
+ import { ProjectionModel, type View, getTypenameFromQuery } from '@dxos/schema';
14
14
 
15
- type KanbanViewEditorProps = { view: DataType.View };
15
+ type KanbanViewEditorProps = { view: View.View };
16
16
 
17
17
  export const KanbanViewEditor = ({ view }: KanbanViewEditorProps) => {
18
18
  const client = useClient();
19
19
  const space = getSpace(view);
20
- const currentTypename = useMemo(() => view.query.typename, [view.query.typename]);
20
+ const currentTypename = view.query ? getTypenameFromQuery(view.query.ast) : undefined;
21
21
  const schema = useSchema(client, space, currentTypename);
22
22
 
23
23
  const projection = useMemo(() => {
24
24
  if (schema) {
25
25
  const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : Type.toJsonSchema(schema);
26
- return new ProjectionModel(jsonSchema, view.projection);
26
+ const projection = new ProjectionModel(jsonSchema, view.projection);
27
+ projection.normalizeView();
28
+ return projection;
27
29
  }
28
30
  }, [view.projection, JSON.stringify(schema)]);
29
31
 
package/src/meta.ts CHANGED
@@ -3,15 +3,17 @@
3
3
  //
4
4
 
5
5
  import { type PluginMeta } from '@dxos/app-framework';
6
-
7
- export const KANBAN_PLUGIN = 'dxos.org/plugin/kanban';
6
+ import { trim } from '@dxos/util';
8
7
 
9
8
  export const meta: PluginMeta = {
10
- id: KANBAN_PLUGIN,
9
+ id: 'dxos.org/plugin/kanban',
11
10
  name: 'Kanban',
12
- description:
13
- 'Kanban allows you to explore Table data in sorted columns defined by your custom schema. You can use Kanbans to track progress or trigger custom automations when cards are moved from one state to another.',
11
+ description: trim`
12
+ Visual project management using customizable kanban boards to track workflow progress.
13
+ Organize table data into columns, drag and drop items between stages, and trigger automations based on status changes.
14
+ `,
14
15
  icon: 'ph--kanban--regular',
16
+ iconHue: 'green',
15
17
  source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-kanban',
16
18
  screenshots: ['https://dxos.network/plugin-details-kanban-dark.png'],
17
19
  };
@@ -2,12 +2,12 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Schema } from 'effect';
5
+ import * as Schema from 'effect/Schema';
6
6
 
7
7
  import { SpaceSchema } from '@dxos/react-client/echo';
8
- import { DataType, FieldSchema, TypenameAnnotationId } from '@dxos/schema';
8
+ import { FieldSchema, TypenameAnnotationId, View } from '@dxos/schema';
9
9
 
10
- import { KANBAN_PLUGIN } from '../meta';
10
+ import { meta } from '../meta';
11
11
 
12
12
  /**
13
13
  * Kanban data model.
@@ -23,6 +23,7 @@ export const PivotColumnAnnotationId = Symbol.for('@dxos/plugin-kanban/annotatio
23
23
 
24
24
  export const CreateKanbanSchema = Schema.Struct({
25
25
  name: Schema.optional(Schema.String),
26
+ // TODO(wittjosiah): This should be a query input instead.
26
27
  typename: Schema.optional(
27
28
  Schema.String.annotations({
28
29
  [TypenameAnnotationId]: ['used-static', 'dynamic'],
@@ -38,18 +39,18 @@ export const CreateKanbanSchema = Schema.Struct({
38
39
  });
39
40
 
40
41
  export namespace KanbanAction {
41
- const KANBAN_ACTION = `${KANBAN_PLUGIN}/action`;
42
+ const KANBAN_ACTION = `${meta.id}/action`;
42
43
 
43
44
  export class Create extends Schema.TaggedClass<Create>()(`${KANBAN_ACTION}/create`, {
44
45
  input: Schema.extend(Schema.Struct({ space: SpaceSchema }), CreateKanbanSchema),
45
46
  output: Schema.Struct({
46
- object: DataType.View,
47
+ object: View.View,
47
48
  }),
48
49
  }) {}
49
50
 
50
51
  export class DeleteCardField extends Schema.TaggedClass<DeleteCardField>()(`${KANBAN_ACTION}/delete-card-field`, {
51
52
  input: Schema.Struct({
52
- view: DataType.View,
53
+ view: View.View,
53
54
  fieldId: Schema.String,
54
55
  // TODO(wittjosiah): Separate fields for undo data?
55
56
  deletionData: Schema.optional(