@dxos/plugin-kanban 0.8.3 → 0.8.4-main.28f8d3d

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 (103) hide show
  1. package/dist/lib/browser/{chunk-6JEDX6HA.mjs → chunk-5BR6HNHI.mjs} +35 -12
  2. package/dist/lib/browser/chunk-5BR6HNHI.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +17 -23
  4. package/dist/lib/browser/index.mjs.map +3 -3
  5. package/dist/lib/browser/intent-resolver-65UVYRI2.mjs +111 -0
  6. package/dist/lib/browser/intent-resolver-65UVYRI2.mjs.map +7 -0
  7. package/dist/lib/browser/meta.json +1 -1
  8. package/dist/lib/browser/{react-surface-HJL2JRJP.mjs → react-surface-KX5U6PJ2.mjs} +42 -91
  9. package/dist/lib/browser/react-surface-KX5U6PJ2.mjs.map +7 -0
  10. package/dist/lib/browser/{types.mjs → types/index.mjs} +4 -4
  11. package/dist/lib/node-esm/{chunk-7DHZSNGQ.mjs → chunk-WLFZKRIJ.mjs} +35 -12
  12. package/dist/lib/node-esm/chunk-WLFZKRIJ.mjs.map +7 -0
  13. package/dist/lib/node-esm/index.mjs +17 -23
  14. package/dist/lib/node-esm/index.mjs.map +3 -3
  15. package/dist/lib/node-esm/intent-resolver-R3MYQATZ.mjs +112 -0
  16. package/dist/lib/node-esm/intent-resolver-R3MYQATZ.mjs.map +7 -0
  17. package/dist/lib/node-esm/meta.json +1 -1
  18. package/dist/lib/node-esm/{react-surface-257WTPQZ.mjs → react-surface-BAMERRU5.mjs} +42 -91
  19. package/dist/lib/node-esm/react-surface-BAMERRU5.mjs.map +7 -0
  20. package/dist/lib/node-esm/{types.mjs → types/index.mjs} +4 -4
  21. package/dist/types/src/KanbanPlugin.d.ts.map +1 -1
  22. package/dist/types/src/capabilities/artifact-definition.d.ts +1 -1
  23. package/dist/types/src/capabilities/artifact-definition.d.ts.map +1 -1
  24. package/dist/types/src/capabilities/index.d.ts +0 -1
  25. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  26. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  27. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  28. package/dist/types/src/components/KanbanContainer.d.ts +3 -3
  29. package/dist/types/src/components/KanbanContainer.d.ts.map +1 -1
  30. package/dist/types/src/components/KanbanContainer.stories.d.ts +1 -1
  31. package/dist/types/src/components/KanbanContainer.stories.d.ts.map +1 -1
  32. package/dist/types/src/components/KanbanViewEditor.d.ts +3 -3
  33. package/dist/types/src/components/KanbanViewEditor.d.ts.map +1 -1
  34. package/dist/types/src/index.d.ts +1 -1
  35. package/dist/types/src/index.d.ts.map +1 -1
  36. package/dist/types/src/translations.d.ts +24 -53
  37. package/dist/types/src/translations.d.ts.map +1 -1
  38. package/dist/types/src/types/index.d.ts +4 -0
  39. package/dist/types/src/types/index.d.ts.map +1 -0
  40. package/dist/types/src/types/kanban.d.ts +11 -0
  41. package/dist/types/src/types/kanban.d.ts.map +1 -0
  42. package/dist/types/src/types/schema.d.ts +110 -0
  43. package/dist/types/src/types/schema.d.ts.map +1 -0
  44. package/dist/types/src/types/types.d.ts +4 -0
  45. package/dist/types/src/types/types.d.ts.map +1 -0
  46. package/dist/types/tsconfig.tsbuildinfo +1 -1
  47. package/package.json +34 -30
  48. package/src/KanbanPlugin.tsx +7 -11
  49. package/src/capabilities/artifact-definition.ts +32 -21
  50. package/src/capabilities/index.ts +0 -1
  51. package/src/capabilities/intent-resolver.ts +14 -15
  52. package/src/capabilities/react-surface.tsx +16 -13
  53. package/src/components/KanbanContainer.stories.tsx +44 -47
  54. package/src/components/KanbanContainer.tsx +12 -12
  55. package/src/components/KanbanViewEditor.tsx +21 -65
  56. package/src/index.ts +2 -1
  57. package/src/translations.ts +7 -7
  58. package/src/types/index.ts +7 -0
  59. package/src/types/kanban.ts +29 -0
  60. package/src/{types.ts → types/schema.ts} +6 -27
  61. package/src/types/types.ts +7 -0
  62. package/dist/lib/browser/artifact-definition-6HNQFL2M.mjs +0 -178
  63. package/dist/lib/browser/artifact-definition-6HNQFL2M.mjs.map +0 -7
  64. package/dist/lib/browser/chunk-6JEDX6HA.mjs.map +0 -7
  65. package/dist/lib/browser/intent-resolver-QQOH5EV2.mjs +0 -297
  66. package/dist/lib/browser/intent-resolver-QQOH5EV2.mjs.map +0 -7
  67. package/dist/lib/browser/react-surface-HJL2JRJP.mjs.map +0 -7
  68. package/dist/lib/node/artifact-definition-GRCAYCVG.cjs +0 -193
  69. package/dist/lib/node/artifact-definition-GRCAYCVG.cjs.map +0 -7
  70. package/dist/lib/node/chunk-ATDUVDIE.cjs +0 -108
  71. package/dist/lib/node/chunk-ATDUVDIE.cjs.map +0 -7
  72. package/dist/lib/node/index.cjs +0 -128
  73. package/dist/lib/node/index.cjs.map +0 -7
  74. package/dist/lib/node/intent-resolver-6ZNOIHKY.cjs +0 -308
  75. package/dist/lib/node/intent-resolver-6ZNOIHKY.cjs.map +0 -7
  76. package/dist/lib/node/meta.json +0 -1
  77. package/dist/lib/node/react-surface-G2J6F7U5.cjs +0 -322
  78. package/dist/lib/node/react-surface-G2J6F7U5.cjs.map +0 -7
  79. package/dist/lib/node/types.cjs +0 -35
  80. package/dist/lib/node/types.cjs.map +0 -7
  81. package/dist/lib/node-esm/artifact-definition-FA2IAAUQ.mjs +0 -179
  82. package/dist/lib/node-esm/artifact-definition-FA2IAAUQ.mjs.map +0 -7
  83. package/dist/lib/node-esm/chunk-7DHZSNGQ.mjs.map +0 -7
  84. package/dist/lib/node-esm/intent-resolver-4TYFDM4E.mjs +0 -298
  85. package/dist/lib/node-esm/intent-resolver-4TYFDM4E.mjs.map +0 -7
  86. package/dist/lib/node-esm/react-surface-257WTPQZ.mjs.map +0 -7
  87. package/dist/types/src/testing/index.d.ts +0 -3
  88. package/dist/types/src/testing/index.d.ts.map +0 -1
  89. package/dist/types/src/testing/initialize-kanban.d.ts +0 -17
  90. package/dist/types/src/testing/initialize-kanban.d.ts.map +0 -1
  91. package/dist/types/src/testing/kanban-manager.d.ts +0 -7
  92. package/dist/types/src/testing/kanban-manager.d.ts.map +0 -1
  93. package/dist/types/src/testing/playwright/smoke.spec.d.ts +0 -2
  94. package/dist/types/src/testing/playwright/smoke.spec.d.ts.map +0 -1
  95. package/dist/types/src/types.d.ts +0 -76
  96. package/dist/types/src/types.d.ts.map +0 -1
  97. package/src/testing/index.ts +0 -6
  98. package/src/testing/initialize-kanban.ts +0 -128
  99. package/src/testing/kanban-manager.ts +0 -13
  100. package/src/testing/playwright/playwright.config.cts +0 -18
  101. package/src/testing/playwright/smoke.spec.ts +0 -7
  102. /package/dist/lib/browser/{types.mjs.map → types/index.mjs.map} +0 -0
  103. /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",
3
+ "version": "0.8.4-main.28f8d3d",
4
4
  "description": "Kanban DXOS Surface plugin",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -10,11 +10,13 @@
10
10
  "type": "module",
11
11
  "exports": {
12
12
  ".": {
13
+ "source": "./src/index.ts",
13
14
  "types": "./dist/types/src/index.d.ts",
14
15
  "browser": "./dist/lib/browser/index.mjs",
15
16
  "node": "./dist/lib/node-esm/index.mjs"
16
17
  },
17
18
  "./types": {
19
+ "source": "./src/types/index.ts",
18
20
  "types": "./dist/types/src/types/index.d.ts",
19
21
  "browser": "./dist/lib/browser/types/index.mjs",
20
22
  "node": "./dist/lib/node-esm/types/index.mjs"
@@ -35,27 +37,29 @@
35
37
  "dependencies": {
36
38
  "@preact-signals/safe-react": "^0.9.0",
37
39
  "@preact/signals-core": "^1.9.0",
38
- "effect": "3.14.21",
39
- "@dxos/ai": "0.8.3",
40
- "@dxos/app-framework": "0.8.3",
41
- "@dxos/assistant": "0.8.3",
42
- "@dxos/artifact": "0.8.3",
43
- "@dxos/async": "0.8.3",
44
- "@dxos/echo-schema": "0.8.3",
45
- "@dxos/echo": "0.8.3",
46
- "@dxos/effect": "0.8.3",
47
- "@dxos/invariant": "0.8.3",
48
- "@dxos/plugin-client": "0.8.3",
49
- "@dxos/plugin-graph": "0.8.3",
50
- "@dxos/plugin-search": "0.8.3",
51
- "@dxos/plugin-space": "0.8.3",
52
- "@dxos/random": "0.8.3",
53
- "@dxos/react-client": "0.8.3",
54
- "@dxos/react-ui-form": "0.8.3",
55
- "@dxos/react-ui-kanban": "0.8.3",
56
- "@dxos/react-ui-stack": "0.8.3",
57
- "@dxos/schema": "0.8.3",
58
- "@dxos/util": "0.8.3"
40
+ "effect": "3.17.7",
41
+ "@dxos/ai": "0.8.4-main.28f8d3d",
42
+ "@dxos/assistant": "0.8.4-main.28f8d3d",
43
+ "@dxos/app-framework": "0.8.4-main.28f8d3d",
44
+ "@dxos/async": "0.8.4-main.28f8d3d",
45
+ "@dxos/blueprints": "0.8.4-main.28f8d3d",
46
+ "@dxos/echo": "0.8.4-main.28f8d3d",
47
+ "@dxos/effect": "0.8.4-main.28f8d3d",
48
+ "@dxos/plugin-client": "0.8.4-main.28f8d3d",
49
+ "@dxos/plugin-graph": "0.8.4-main.28f8d3d",
50
+ "@dxos/invariant": "0.8.4-main.28f8d3d",
51
+ "@dxos/plugin-search": "0.8.4-main.28f8d3d",
52
+ "@dxos/plugin-space": "0.8.4-main.28f8d3d",
53
+ "@dxos/log": "0.8.4-main.28f8d3d",
54
+ "@dxos/random": "0.8.4-main.28f8d3d",
55
+ "@dxos/react-client": "0.8.4-main.28f8d3d",
56
+ "@dxos/react-ui": "0.8.4-main.28f8d3d",
57
+ "@dxos/echo-schema": "0.8.4-main.28f8d3d",
58
+ "@dxos/react-ui-kanban": "0.8.4-main.28f8d3d",
59
+ "@dxos/react-ui-form": "0.8.4-main.28f8d3d",
60
+ "@dxos/react-ui-stack": "0.8.4-main.28f8d3d",
61
+ "@dxos/util": "0.8.4-main.28f8d3d",
62
+ "@dxos/schema": "0.8.4-main.28f8d3d"
59
63
  },
60
64
  "devDependencies": {
61
65
  "@types/react": "~18.2.0",
@@ -63,19 +67,19 @@
63
67
  "react": "~18.2.0",
64
68
  "react-dom": "~18.2.0",
65
69
  "vite": "5.4.7",
66
- "@dxos/plugin-preview": "0.8.3",
67
- "@dxos/plugin-theme": "0.8.3",
68
- "@dxos/react-ui": "0.8.3",
69
- "@dxos/storybook-utils": "0.8.3",
70
- "@dxos/react-ui-theme": "0.8.3",
71
- "@dxos/react-ui-syntax-highlighter": "0.8.3"
70
+ "@dxos/plugin-theme": "0.8.4-main.28f8d3d",
71
+ "@dxos/plugin-preview": "0.8.4-main.28f8d3d",
72
+ "@dxos/react-ui-syntax-highlighter": "0.8.4-main.28f8d3d",
73
+ "@dxos/react-ui-theme": "0.8.4-main.28f8d3d",
74
+ "@dxos/storybook-utils": "0.8.4-main.28f8d3d",
75
+ "@dxos/test-utils": "0.8.4-main.28f8d3d"
72
76
  },
73
77
  "peerDependencies": {
74
78
  "effect": "^3.13.3",
75
79
  "react": "~18.2.0",
76
80
  "react-dom": "~18.2.0",
77
- "@dxos/react-ui": "0.8.3",
78
- "@dxos/react-ui-theme": "0.8.3"
81
+ "@dxos/react-ui": "0.8.4-main.28f8d3d",
82
+ "@dxos/react-ui-theme": "0.8.4-main.28f8d3d"
79
83
  },
80
84
  "publishConfig": {
81
85
  "access": "public"
@@ -2,15 +2,15 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { createIntent, defineModule, contributes, Capabilities, Events, definePlugin } from '@dxos/app-framework';
5
+ import { Capabilities, Events, contributes, createIntent, defineModule, definePlugin } from '@dxos/app-framework';
6
6
  import { ClientEvents } from '@dxos/plugin-client';
7
7
  import { SpaceCapabilities } from '@dxos/plugin-space';
8
8
  import { defineObjectForm } from '@dxos/plugin-space/types';
9
- import { KanbanType, translations as kanbanTranslations } from '@dxos/react-ui-kanban';
9
+ import { KanbanView, translations as kanbanTranslations } from '@dxos/react-ui-kanban';
10
10
 
11
- import { ArtifactDefinition, IntentResolver, ReactSurface } from './capabilities';
11
+ import { 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: KanbanType.typename,
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: KanbanType,
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
  ),
@@ -54,9 +55,4 @@ export const KanbanPlugin = () =>
54
55
  activatesOn: Events.SetupIntentResolver,
55
56
  activate: IntentResolver,
56
57
  }),
57
- defineModule({
58
- id: `${meta.id}/module/artifact-definition`,
59
- activatesOn: Events.SetupArtifactDefinition,
60
- activate: ArtifactDefinition,
61
- }),
62
58
  ]);
@@ -2,17 +2,22 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
+ // ISSUE(burdon): defineArtifact
6
+ // @ts-nocheck
7
+
5
8
  import { Schema, pipe } from 'effect';
6
9
 
7
- import { createTool, ToolResult } from '@dxos/ai';
8
- import { Capabilities, chain, contributes, createIntent, type PromiseIntentDispatcher } from '@dxos/app-framework';
9
- import { defineArtifact } from '@dxos/artifact';
10
+ import { ToolResult, createTool } from '@dxos/ai';
11
+ import { Capabilities, type PromiseIntentDispatcher, chain, contributes, createIntent } from '@dxos/app-framework';
10
12
  import { createArtifactElement } from '@dxos/assistant';
11
- import { Obj } from '@dxos/echo';
13
+ import { defineArtifact } from '@dxos/blueprints';
14
+ import { Obj, Query } from '@dxos/echo';
12
15
  import { invariant } from '@dxos/invariant';
13
16
  import { SpaceAction } from '@dxos/plugin-space/types';
14
- import { Filter, fullyQualifiedId, type Space } from '@dxos/react-client/echo';
15
- import { KanbanType } from '@dxos/react-ui-kanban';
17
+ import { Filter, type Space, fullyQualifiedId } from '@dxos/react-client/echo';
18
+ import { KanbanView } from '@dxos/react-ui-kanban';
19
+ import { DataType } from '@dxos/schema';
20
+ import { isNonNullable } from '@dxos/util';
16
21
 
17
22
  import { meta } from '../meta';
18
23
  import { KanbanAction } from '../types';
@@ -37,7 +42,7 @@ export default () => {
37
42
  - When adding items, you must not include the 'id' field -- it is automatically generated
38
43
  - BEFORE adding items, always make sure the board has been shown to the user!
39
44
  `,
40
- schema: KanbanType,
45
+ schema: KanbanView,
41
46
  tools: [
42
47
  createTool(meta.id, {
43
48
  name: 'create',
@@ -47,7 +52,7 @@ export default () => {
47
52
  caption: 'Creating kanban board...',
48
53
  schema: Schema.Struct({
49
54
  typename: Schema.String.annotations({
50
- description: 'The fully qualified typename of the schema to use for the kanban cards.',
55
+ description: 'The fully qualified name of the record type to use for the kanban cards.',
51
56
  }),
52
57
  pivotColumn: Schema.optional(Schema.String).annotations({
53
58
  description: 'Optional field name to use as the column pivot.',
@@ -88,19 +93,24 @@ export default () => {
88
93
  execute: async (_input, { extensions }) => {
89
94
  invariant(extensions?.space, 'No space');
90
95
  const space = extensions.space;
91
- const { objects: boards } = await space.db.query(Filter.type(KanbanType)).run();
96
+ const { objects } = await space.db.query(Filter.type(DataType.View)).run();
92
97
 
93
98
  const boardInfo = await Promise.all(
94
- boards.map(async (board: KanbanType) => {
95
- const view = await board.cardView?.load();
99
+ objects.map(async (view) => {
100
+ const kanban = await view.presentation.load();
101
+ if (!Obj.instanceOf(KanbanView, kanban)) {
102
+ return null;
103
+ }
104
+
96
105
  return {
97
- id: fullyQualifiedId(board),
98
- typename: view?.query.typename,
106
+ id: fullyQualifiedId(view),
107
+ name: view.name ?? 'Unnamed Kanban',
108
+ typename: view.query.typename,
99
109
  };
100
110
  }),
101
111
  );
102
112
 
103
- return ToolResult.Success(boardInfo);
113
+ return ToolResult.Success(boardInfo.filter(isNonNullable));
104
114
  },
105
115
  }),
106
116
  createTool(meta.id, {
@@ -111,12 +121,13 @@ export default () => {
111
121
  execute: async ({ id }, { extensions }) => {
112
122
  invariant(extensions?.space, 'No space');
113
123
  const space = extensions.space;
114
- const { objects: boards } = await space.db.query(Filter.type(KanbanType)).run();
115
- const board = boards.find((board: KanbanType) => fullyQualifiedId(board) === id);
116
- invariant(Obj.instanceOf(KanbanType, board));
124
+ const view = (await space.db
125
+ // TODO(wittjosiah): Filter.and should aggregate type
126
+ .query(Query.select(Filter.and(Filter.type(DataType.View), Filter.ids(id))))
127
+ .first()) as DataType.View;
117
128
 
118
- const view = await board.cardView?.load();
119
- invariant(view);
129
+ const kanban = await view.presentation.load();
130
+ invariant(Obj.instanceOf(KanbanView, kanban));
120
131
 
121
132
  const typename = view.query.typename;
122
133
  const schema = await space.db.schemaRegistry.query({ typename }).firstOrUndefined();
@@ -124,8 +135,8 @@ export default () => {
124
135
 
125
136
  return ToolResult.Success({
126
137
  schema,
127
- columnField: board.columnFieldId,
128
- viewFields: view.fields,
138
+ columnField: kanban.columnFieldId,
139
+ viewFields: view.projection.fields,
129
140
  });
130
141
  },
131
142
  }),
@@ -4,6 +4,5 @@
4
4
 
5
5
  import { lazy } from '@dxos/app-framework';
6
6
 
7
- export const ArtifactDefinition = lazy(() => import('./artifact-definition'));
8
7
  export const IntentResolver = lazy(() => import('./intent-resolver'));
9
8
  export const ReactSurface = lazy(() => import('./react-surface'));
@@ -2,15 +2,14 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { contributes, Capabilities, createResolver, type PluginContext } from '@dxos/app-framework';
5
+ import { Capabilities, type PluginContext, contributes, createResolver } from '@dxos/app-framework';
6
6
  import { invariant } from '@dxos/invariant';
7
7
  import { ClientCapabilities } from '@dxos/plugin-client';
8
8
  import { getSpace } from '@dxos/react-client/echo';
9
- import { ViewProjection } from '@dxos/schema';
9
+ import { ProjectionModel } from '@dxos/schema';
10
10
 
11
11
  import { KANBAN_PLUGIN } from '../meta';
12
- import { initializeKanban } from '../testing';
13
- import { KanbanAction } from '../types';
12
+ import { KanbanAction, createKanban } 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 { kanban } = await initializeKanban({ client, space, name, typename, initialPivotColumn });
22
- return { data: { object: kanban } };
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: ({ kanban, fieldId, deletionData }, undo) => {
28
- invariant(kanban.cardView);
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
- invariant(kanban.cardView.target);
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
- import { getSpace, isSpace, type Space } from '@dxos/react-client/echo';
12
+ import { type Space, getSpace, isSpace } from '@dxos/react-client/echo';
13
13
  import { type InputProps, SelectInput, useFormValues } from '@dxos/react-ui-form';
14
- import { type KanbanType } from '@dxos/react-ui-kanban';
15
- import { type DataType } from '@dxos/schema';
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 { KANBAN_PLUGIN } from '../meta';
19
- import { isKanban, PivotColumnAnnotationId } from '../types';
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: `${KANBAN_PLUGIN}/kanban`,
24
+ id: meta.id,
25
25
  role: ['article', 'section'],
26
- filter: (data): data is { subject: KanbanType } => isKanban(data.subject),
27
- component: ({ data, role }) => <KanbanContainer kanban={data.subject} role={role} />,
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: `${KANBAN_PLUGIN}/object-settings`,
31
+ id: `${meta.id}/object-settings`,
31
32
  role: 'object-settings',
32
- filter: (data): data is { subject: KanbanType } => isKanban(data.subject),
33
- component: ({ data }) => <KanbanViewEditor kanban={data.subject} />,
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: `${KANBAN_PLUGIN}/create-initial-schema-form-[pivot-column]`,
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
- import { type StoryObj, type Meta } from '@storybook/react';
6
+
7
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
7
8
  import React, { useCallback, useEffect, useState } from 'react';
8
9
 
9
10
  import { IntentPlugin, SettingsPlugin } from '@dxos/app-framework';
@@ -18,16 +19,16 @@ import { StorybookLayoutPlugin } from '@dxos/plugin-storybook-layout';
18
19
  import { ThemePlugin } from '@dxos/plugin-theme';
19
20
  import { faker } from '@dxos/random';
20
21
  import { useClient } from '@dxos/react-client';
21
- import { Filter, useSpaces, useQuery, useSchema } from '@dxos/react-client/echo';
22
+ import { Filter, useQuery, useSchema, useSpaces } from '@dxos/react-client/echo';
22
23
  import { ViewEditor } from '@dxos/react-ui-form';
23
- import { Kanban, KanbanType, useKanbanModel } from '@dxos/react-ui-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, ViewProjection } from '@dxos/schema';
27
+ import { DataType, ProjectionModel } from '@dxos/schema';
27
28
  import { withLayout } from '@dxos/storybook-utils';
28
29
 
29
- import { initializeKanban } from '../testing';
30
- import translations from '../translations';
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 kanbans = useQuery(space, Filter.type(KanbanType));
51
- const [kanban, setKanban] = useState<KanbanType>();
52
- const [projection, setProjection] = useState<ViewProjection>();
53
- const schema = useSchema(client, space, kanban?.cardView?.target?.query.typename);
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 (kanbans.length && !kanban) {
57
- const kanban = kanbans[0];
58
- setKanban(kanban);
57
+ if (views.length && !view) {
58
+ const view = views[0];
59
+ setView(view);
59
60
  }
60
- }, [kanbans]);
61
+ }, [views]);
61
62
 
62
63
  useEffect(() => {
63
- if (kanban?.cardView?.target && schema) {
64
+ if (view?.projection && schema) {
64
65
  const jsonSchema = Type.toJsonSchema(schema);
65
- setProjection(new ViewProjection(jsonSchema, kanban.cardView.target));
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
- }, [kanban?.cardView?.target, schema, JSON.stringify(schema ? Type.toJsonSchema(schema) : {})]);
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
- kanban,
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(kanban?.cardView?.target);
104
+ invariant(view);
104
105
 
105
106
  schema.updateTypename(typename);
106
- kanban.cardView.target.query.typename = typename;
107
+ view.query.typename = typename;
107
108
  },
108
- [kanban?.cardView?.target, schema],
109
+ [view, schema],
109
110
  );
110
111
 
111
- if (!schema || !kanban) {
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
- {kanban.cardView && (
120
- <ViewEditor
121
- registry={space?.db.schemaRegistry}
122
- schema={schema}
123
- view={kanban.cardView.target!}
124
- onTypenameChanged={handleTypenameChanged}
125
- onDelete={(fieldId: string) => {
126
- console.log('[ViewEditor]', 'onDelete', fieldId);
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({ cardView: kanban.cardView?.target, cardSchema: schema }, null, 2)}
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, KanbanType],
158
- onClientInitialized: async (_, client) => {
156
+ types: [DataType.Organization, DataType.Person, DataType.View, KanbanView],
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 { schema, kanban } = await initializeKanban({
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(kanban);
169
-
170
- if (schema) {
171
- // TODO(burdon): Replace with sdk/schema/testing.
172
- Array.from({ length: 80 }).map(() => {
173
- return space.db.add(Obj.make(schema, rollOrg()));
174
- });
175
- }
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(),
@@ -9,18 +9,18 @@ import { Filter, Obj, Type } from '@dxos/echo';
9
9
  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
- import { useQuery, getSpace } from '@dxos/react-client/echo';
13
- import { type KanbanType, useKanbanModel, Kanban } from '@dxos/react-ui-kanban';
12
+ import { getSpace, useQuery } from '@dxos/react-client/echo';
13
+ import { Kanban, useKanbanModel } from '@dxos/react-ui-kanban';
14
14
  import { StackItem } from '@dxos/react-ui-stack';
15
- import { ViewProjection } from '@dxos/schema';
15
+ import { type DataType, ProjectionModel } from '@dxos/schema';
16
16
 
17
17
  import { KanbanAction } from '../types';
18
18
 
19
- export const KanbanContainer = ({ kanban }: { kanban: KanbanType; role: string }) => {
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<ViewProjection>();
23
- const space = getSpace(kanban);
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 = kanban.cardView?.target?.query?.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
- }, [kanban.cardView?.target?.query, space]);
52
+ }, [view.query.typename, space]);
53
53
 
54
54
  useEffect(() => {
55
- if (kanban.cardView?.target && jsonSchema) {
56
- setProjection(new ViewProjection(jsonSchema, kanban.cardView.target));
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
- }, [kanban.cardView?.target, JSON.stringify(jsonSchema)]);
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
- kanban,
65
+ view,
66
66
  schema: cardSchema,
67
67
  projection,
68
68
  items: filteredObjects,