@dxos/plugin-kanban 0.8.4-main.f9ba587 → 0.8.4-main.fd6878d

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 (78) hide show
  1. package/dist/lib/browser/{chunk-76UNDUHS.mjs → chunk-5BR6HNHI.mjs} +33 -13
  2. package/dist/lib/browser/chunk-5BR6HNHI.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +10 -15
  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-WMVUSDVR.mjs → react-surface-KX5U6PJ2.mjs} +34 -83
  9. package/dist/lib/browser/react-surface-KX5U6PJ2.mjs.map +7 -0
  10. package/dist/lib/browser/types/index.mjs +3 -3
  11. package/dist/lib/node-esm/{chunk-B3AVV7SF.mjs → chunk-WLFZKRIJ.mjs} +33 -13
  12. package/dist/lib/node-esm/chunk-WLFZKRIJ.mjs.map +7 -0
  13. package/dist/lib/node-esm/index.mjs +10 -15
  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-JKYB6SAC.mjs → react-surface-BAMERRU5.mjs} +34 -83
  19. package/dist/lib/node-esm/react-surface-BAMERRU5.mjs.map +7 -0
  20. package/dist/lib/node-esm/types/index.mjs +3 -3
  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/translations.d.ts +2 -2
  35. package/dist/types/src/types/index.d.ts +2 -1
  36. package/dist/types/src/types/index.d.ts.map +1 -1
  37. package/dist/types/src/types/kanban.d.ts +11 -0
  38. package/dist/types/src/types/kanban.d.ts.map +1 -0
  39. package/dist/types/src/types/schema.d.ts +47 -5
  40. package/dist/types/src/types/schema.d.ts.map +1 -1
  41. package/dist/types/src/types/types.d.ts +0 -11
  42. package/dist/types/src/types/types.d.ts.map +1 -1
  43. package/dist/types/tsconfig.tsbuildinfo +1 -1
  44. package/package.json +38 -36
  45. package/src/KanbanPlugin.tsx +6 -10
  46. package/src/capabilities/artifact-definition.ts +32 -21
  47. package/src/capabilities/index.ts +0 -1
  48. package/src/capabilities/intent-resolver.ts +14 -15
  49. package/src/capabilities/react-surface.tsx +12 -9
  50. package/src/components/KanbanContainer.stories.tsx +46 -48
  51. package/src/components/KanbanContainer.tsx +12 -12
  52. package/src/components/KanbanViewEditor.tsx +21 -65
  53. package/src/translations.ts +2 -2
  54. package/src/types/index.ts +2 -1
  55. package/src/types/kanban.ts +29 -0
  56. package/src/types/schema.ts +5 -6
  57. package/src/types/types.ts +0 -15
  58. package/dist/lib/browser/artifact-definition-H5MOHOV5.mjs +0 -178
  59. package/dist/lib/browser/artifact-definition-H5MOHOV5.mjs.map +0 -7
  60. package/dist/lib/browser/chunk-76UNDUHS.mjs.map +0 -7
  61. package/dist/lib/browser/intent-resolver-VJSWAUZD.mjs +0 -297
  62. package/dist/lib/browser/intent-resolver-VJSWAUZD.mjs.map +0 -7
  63. package/dist/lib/browser/react-surface-WMVUSDVR.mjs.map +0 -7
  64. package/dist/lib/node-esm/artifact-definition-FDRLWGY5.mjs +0 -179
  65. package/dist/lib/node-esm/artifact-definition-FDRLWGY5.mjs.map +0 -7
  66. package/dist/lib/node-esm/chunk-B3AVV7SF.mjs.map +0 -7
  67. package/dist/lib/node-esm/intent-resolver-3ZSJN2NS.mjs +0 -298
  68. package/dist/lib/node-esm/intent-resolver-3ZSJN2NS.mjs.map +0 -7
  69. package/dist/lib/node-esm/react-surface-JKYB6SAC.mjs.map +0 -7
  70. package/dist/types/src/testing/index.d.ts +0 -3
  71. package/dist/types/src/testing/index.d.ts.map +0 -1
  72. package/dist/types/src/testing/initialize-kanban.d.ts +0 -17
  73. package/dist/types/src/testing/initialize-kanban.d.ts.map +0 -1
  74. package/dist/types/src/testing/kanban-manager.d.ts +0 -7
  75. package/dist/types/src/testing/kanban-manager.d.ts.map +0 -1
  76. package/src/testing/index.ts +0 -6
  77. package/src/testing/initialize-kanban.ts +0 -128
  78. package/src/testing/kanban-manager.ts +0 -13
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-kanban",
3
- "version": "0.8.4-main.f9ba587",
3
+ "version": "0.8.4-main.fd6878d",
4
4
  "description": "Kanban DXOS Surface plugin",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -10,21 +10,23 @@
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": {
18
- "types": "./dist/types/src/types.d.ts",
19
- "browser": "./dist/lib/browser/types.mjs",
20
- "node": "./dist/lib/node-esm/types.mjs"
19
+ "source": "./src/types/index.ts",
20
+ "types": "./dist/types/src/types/index.d.ts",
21
+ "browser": "./dist/lib/browser/types/index.mjs",
22
+ "node": "./dist/lib/node-esm/types/index.mjs"
21
23
  }
22
24
  },
23
25
  "types": "dist/types/src/index.d.ts",
24
26
  "typesVersions": {
25
27
  "*": {
26
28
  "types": [
27
- "dist/types/src/types.d.ts"
29
+ "dist/types/src/types/index.d.ts"
28
30
  ]
29
31
  }
30
32
  },
@@ -35,29 +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.16.13",
39
- "@dxos/ai": "0.8.4-main.f9ba587",
40
- "@dxos/app-framework": "0.8.4-main.f9ba587",
41
- "@dxos/assistant": "0.8.4-main.f9ba587",
42
- "@dxos/async": "0.8.4-main.f9ba587",
43
- "@dxos/artifact": "0.8.4-main.f9ba587",
44
- "@dxos/echo": "0.8.4-main.f9ba587",
45
- "@dxos/echo-schema": "0.8.4-main.f9ba587",
46
- "@dxos/effect": "0.8.4-main.f9ba587",
47
- "@dxos/invariant": "0.8.4-main.f9ba587",
48
- "@dxos/plugin-client": "0.8.4-main.f9ba587",
49
- "@dxos/log": "0.8.4-main.f9ba587",
50
- "@dxos/plugin-graph": "0.8.4-main.f9ba587",
51
- "@dxos/plugin-search": "0.8.4-main.f9ba587",
52
- "@dxos/plugin-space": "0.8.4-main.f9ba587",
53
- "@dxos/random": "0.8.4-main.f9ba587",
54
- "@dxos/react-client": "0.8.4-main.f9ba587",
55
- "@dxos/react-ui": "0.8.4-main.f9ba587",
56
- "@dxos/react-ui-form": "0.8.4-main.f9ba587",
57
- "@dxos/react-ui-kanban": "0.8.4-main.f9ba587",
58
- "@dxos/react-ui-stack": "0.8.4-main.f9ba587",
59
- "@dxos/schema": "0.8.4-main.f9ba587",
60
- "@dxos/util": "0.8.4-main.f9ba587"
40
+ "effect": "3.17.7",
41
+ "@dxos/app-framework": "0.8.4-main.fd6878d",
42
+ "@dxos/async": "0.8.4-main.fd6878d",
43
+ "@dxos/blueprints": "0.8.4-main.fd6878d",
44
+ "@dxos/assistant": "0.8.4-main.fd6878d",
45
+ "@dxos/echo": "0.8.4-main.fd6878d",
46
+ "@dxos/echo-schema": "0.8.4-main.fd6878d",
47
+ "@dxos/effect": "0.8.4-main.fd6878d",
48
+ "@dxos/invariant": "0.8.4-main.fd6878d",
49
+ "@dxos/plugin-graph": "0.8.4-main.fd6878d",
50
+ "@dxos/log": "0.8.4-main.fd6878d",
51
+ "@dxos/plugin-search": "0.8.4-main.fd6878d",
52
+ "@dxos/plugin-client": "0.8.4-main.fd6878d",
53
+ "@dxos/plugin-space": "0.8.4-main.fd6878d",
54
+ "@dxos/random": "0.8.4-main.fd6878d",
55
+ "@dxos/react-ui": "0.8.4-main.fd6878d",
56
+ "@dxos/react-client": "0.8.4-main.fd6878d",
57
+ "@dxos/react-ui-kanban": "0.8.4-main.fd6878d",
58
+ "@dxos/react-ui-form": "0.8.4-main.fd6878d",
59
+ "@dxos/react-ui-stack": "0.8.4-main.fd6878d",
60
+ "@dxos/schema": "0.8.4-main.fd6878d",
61
+ "@dxos/util": "0.8.4-main.fd6878d",
62
+ "@dxos/ai": "0.8.4-main.fd6878d"
61
63
  },
62
64
  "devDependencies": {
63
65
  "@types/react": "~18.2.0",
@@ -65,19 +67,19 @@
65
67
  "react": "~18.2.0",
66
68
  "react-dom": "~18.2.0",
67
69
  "vite": "5.4.7",
68
- "@dxos/plugin-preview": "0.8.4-main.f9ba587",
69
- "@dxos/plugin-theme": "0.8.4-main.f9ba587",
70
- "@dxos/react-ui-syntax-highlighter": "0.8.4-main.f9ba587",
71
- "@dxos/react-ui-theme": "0.8.4-main.f9ba587",
72
- "@dxos/storybook-utils": "0.8.4-main.f9ba587",
73
- "@dxos/test-utils": "0.8.4-main.f9ba587"
70
+ "@dxos/plugin-preview": "0.8.4-main.fd6878d",
71
+ "@dxos/react-ui-theme": "0.8.4-main.fd6878d",
72
+ "@dxos/plugin-theme": "0.8.4-main.fd6878d",
73
+ "@dxos/react-ui-syntax-highlighter": "0.8.4-main.fd6878d",
74
+ "@dxos/test-utils": "0.8.4-main.fd6878d",
75
+ "@dxos/storybook-utils": "0.8.4-main.fd6878d"
74
76
  },
75
77
  "peerDependencies": {
76
78
  "effect": "^3.13.3",
77
79
  "react": "~18.2.0",
78
80
  "react-dom": "~18.2.0",
79
- "@dxos/react-ui": "0.8.4-main.f9ba587",
80
- "@dxos/react-ui-theme": "0.8.4-main.f9ba587"
81
+ "@dxos/react-ui": "0.8.4-main.fd6878d",
82
+ "@dxos/react-ui-theme": "0.8.4-main.fd6878d"
81
83
  },
82
84
  "publishConfig": {
83
85
  "access": "public"
@@ -2,13 +2,13 @@
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
13
  import { translations } from './translations';
14
14
  import { CreateKanbanSchema, KanbanAction } from './types';
@@ -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,31 +6,34 @@ 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
18
  import { meta } from '../meta';
19
- import { isKanban, PivotColumnAnnotationId } from '../types';
19
+ import { PivotColumnAnnotationId } from '../types';
20
20
 
21
21
  export default () =>
22
22
  contributes(Capabilities.ReactSurface, [
23
23
  createSurface({
24
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
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
39
  id: `${meta.id}/create-initial-schema-form-[pivot-column]`,
@@ -4,7 +4,7 @@
4
4
 
5
5
  import '@dxos-theme';
6
6
 
7
- import { type StoryObj, type Meta } from '@storybook/react-vite';
7
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
8
8
  import React, { useCallback, useEffect, useState } from 'react';
9
9
 
10
10
  import { IntentPlugin, SettingsPlugin } from '@dxos/app-framework';
@@ -16,17 +16,19 @@ import { PreviewPlugin } from '@dxos/plugin-preview';
16
16
  import { useGlobalFilteredObjects } from '@dxos/plugin-search';
17
17
  import { SpacePlugin } from '@dxos/plugin-space';
18
18
  import { StorybookLayoutPlugin } from '@dxos/plugin-storybook-layout';
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
- import { DataType, ViewProjection } from '@dxos/schema';
26
- import { withLayout, withTheme } from '@dxos/storybook-utils';
26
+ import { defaultTx } from '@dxos/react-ui-theme';
27
+ import { DataType, ProjectionModel } from '@dxos/schema';
28
+ import { withLayout } from '@dxos/storybook-utils';
27
29
 
28
- import { initializeKanban } from '../testing';
29
30
  import { translations } from '../translations';
31
+ import { createKanban } from '../types';
30
32
 
31
33
  faker.seed(0);
32
34
 
@@ -39,39 +41,39 @@ const rollOrg = () => ({
39
41
  description: faker.lorem.paragraph(),
40
42
  image: faker.image.url(),
41
43
  website: faker.internet.url(),
42
- status: faker.helpers.arrayElement(DataType.OrganizationStatusOptions).id,
44
+ status: faker.helpers.arrayElement(DataType.OrganizationStatusOptions).id as DataType.Organization['status'],
43
45
  });
44
46
 
45
47
  const StorybookKanban = () => {
46
48
  const client = useClient();
47
49
  const spaces = useSpaces();
48
50
  const space = spaces[spaces.length - 1];
49
- const kanbans = useQuery(space, Filter.type(KanbanType));
50
- const [kanban, setKanban] = useState<KanbanType>();
51
- const [projection, setProjection] = useState<ViewProjection>();
52
- 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);
53
55
 
54
56
  useEffect(() => {
55
- if (kanbans.length && !kanban) {
56
- const kanban = kanbans[0];
57
- setKanban(kanban);
57
+ if (views.length && !view) {
58
+ const view = views[0];
59
+ setView(view);
58
60
  }
59
- }, [kanbans]);
61
+ }, [views]);
60
62
 
61
63
  useEffect(() => {
62
- if (kanban?.cardView?.target && schema) {
64
+ if (view?.projection && schema) {
63
65
  const jsonSchema = Type.toJsonSchema(schema);
64
- setProjection(new ViewProjection(jsonSchema, kanban.cardView.target));
66
+ setProjection(new ProjectionModel(jsonSchema, view.projection));
65
67
  }
66
68
  // TODO(ZaymonFC): Is there a better way to get notified about deep changes in the json schema?
67
69
  // @dmaretskyi? Once resolved, update in multiple places (e.g., storybooks).
68
- }, [kanban?.cardView?.target, schema, JSON.stringify(schema ? Type.toJsonSchema(schema) : {})]);
70
+ }, [view?.projection, schema, JSON.stringify(schema ? Type.toJsonSchema(schema) : {})]);
69
71
 
70
72
  const objects = useQuery(space, schema ? Filter.type(schema) : Filter.nothing());
71
73
  const filteredObjects = useGlobalFilteredObjects(objects);
72
74
 
73
75
  const model = useKanbanModel({
74
- kanban,
76
+ view,
75
77
  schema,
76
78
  projection,
77
79
  items: filteredObjects,
@@ -99,15 +101,15 @@ const StorybookKanban = () => {
99
101
  (typename: string) => {
100
102
  invariant(schema);
101
103
  invariant(Type.isMutable(schema));
102
- invariant(kanban?.cardView?.target);
104
+ invariant(view);
103
105
 
104
106
  schema.updateTypename(typename);
105
- kanban.cardView.target.query.typename = typename;
107
+ view.query.typename = typename;
106
108
  },
107
- [kanban?.cardView?.target, schema],
109
+ [view, schema],
108
110
  );
109
111
 
110
- if (!schema || !kanban) {
112
+ if (!schema || !view) {
111
113
  return null;
112
114
  }
113
115
 
@@ -115,19 +117,17 @@ const StorybookKanban = () => {
115
117
  <div className='grow grid grid-cols-[1fr_350px]'>
116
118
  {model ? <Kanban model={model} onAddCard={handleAddCard} onRemoveCard={handleRemoveCard} /> : <div />}
117
119
  <div className='flex flex-col bs-full border-is border-separator overflow-y-auto'>
118
- {kanban.cardView && (
119
- <ViewEditor
120
- registry={space?.db.schemaRegistry}
121
- schema={schema}
122
- view={kanban.cardView.target!}
123
- onTypenameChanged={handleTypenameChanged}
124
- onDelete={(fieldId: string) => {
125
- console.log('[ViewEditor]', 'onDelete', fieldId);
126
- }}
127
- />
128
- )}
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
+ />
129
129
  <SyntaxHighlighter language='json' className='w-full text-xs'>
130
- {JSON.stringify({ cardView: kanban.cardView?.target, cardSchema: schema }, null, 2)}
130
+ {JSON.stringify({ view, schema }, null, 2)}
131
131
  </SyntaxHighlighter>
132
132
  </div>
133
133
  </div>
@@ -148,30 +148,28 @@ const meta: Meta<StoryProps> = {
148
148
  render: () => <StorybookKanban />,
149
149
  parameters: { translations },
150
150
  decorators: [
151
- withTheme,
152
151
  withLayout({ fullscreen: true }),
153
152
  withPluginManager({
154
153
  plugins: [
154
+ ThemePlugin({ tx: defaultTx }),
155
155
  ClientPlugin({
156
- types: [DataType.Organization, DataType.Person, KanbanType],
157
- onClientInitialized: async (_, client) => {
156
+ types: [DataType.Organization, DataType.Person, DataType.View, KanbanView],
157
+ onClientInitialized: async ({ client }) => {
158
158
  await client.halo.createIdentity();
159
159
  const space = await client.spaces.create();
160
160
  await space.waitUntilReady();
161
- const { schema, kanban } = await initializeKanban({
162
- space,
161
+ const { view } = await createKanban({
163
162
  client,
163
+ space,
164
164
  typename: DataType.Organization.typename,
165
165
  initialPivotColumn: 'status',
166
166
  });
167
- space.db.add(kanban);
168
-
169
- if (schema) {
170
- // TODO(burdon): Replace with sdk/schema/testing.
171
- Array.from({ length: 80 }).map(() => {
172
- return space.db.add(Obj.make(schema, rollOrg()));
173
- });
174
- }
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
+ });
175
173
  },
176
174
  }),
177
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,