@dxos/plugin-kanban 0.8.3 → 0.8.4-main.5acf9ea

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 (104) hide show
  1. package/dist/lib/browser/{artifact-definition-6HNQFL2M.mjs → artifact-definition-NIFSAHUK.mjs} +32 -36
  2. package/dist/lib/browser/artifact-definition-NIFSAHUK.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-6JEDX6HA.mjs → chunk-MUK4JV7A.mjs} +34 -11
  4. package/dist/lib/browser/chunk-MUK4JV7A.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +17 -17
  6. package/dist/lib/browser/index.mjs.map +3 -3
  7. package/dist/lib/browser/intent-resolver-6GPK64NB.mjs +111 -0
  8. package/dist/lib/browser/intent-resolver-6GPK64NB.mjs.map +7 -0
  9. package/dist/lib/browser/meta.json +1 -1
  10. package/dist/lib/browser/{react-surface-HJL2JRJP.mjs → react-surface-Y2GO6B24.mjs} +40 -89
  11. package/dist/lib/browser/react-surface-Y2GO6B24.mjs.map +7 -0
  12. package/dist/lib/browser/{types.mjs → types/index.mjs} +4 -4
  13. package/dist/lib/node-esm/{artifact-definition-FA2IAAUQ.mjs → artifact-definition-NACXLTWB.mjs} +32 -36
  14. package/dist/lib/node-esm/artifact-definition-NACXLTWB.mjs.map +7 -0
  15. package/dist/lib/node-esm/{chunk-7DHZSNGQ.mjs → chunk-2GCFRKS2.mjs} +34 -11
  16. package/dist/lib/node-esm/chunk-2GCFRKS2.mjs.map +7 -0
  17. package/dist/lib/node-esm/index.mjs +17 -17
  18. package/dist/lib/node-esm/index.mjs.map +3 -3
  19. package/dist/lib/node-esm/intent-resolver-CXHLNVEN.mjs +112 -0
  20. package/dist/lib/node-esm/intent-resolver-CXHLNVEN.mjs.map +7 -0
  21. package/dist/lib/node-esm/meta.json +1 -1
  22. package/dist/lib/node-esm/{react-surface-257WTPQZ.mjs → react-surface-UEQNH6S4.mjs} +40 -89
  23. package/dist/lib/node-esm/react-surface-UEQNH6S4.mjs.map +7 -0
  24. package/dist/lib/node-esm/{types.mjs → types/index.mjs} +4 -4
  25. package/dist/types/src/KanbanPlugin.d.ts.map +1 -1
  26. package/dist/types/src/capabilities/artifact-definition.d.ts +1 -1
  27. package/dist/types/src/capabilities/artifact-definition.d.ts.map +1 -1
  28. package/dist/types/src/capabilities/index.d.ts +1 -1
  29. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  30. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  31. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  32. package/dist/types/src/components/KanbanContainer.d.ts +3 -3
  33. package/dist/types/src/components/KanbanContainer.d.ts.map +1 -1
  34. package/dist/types/src/components/KanbanContainer.stories.d.ts +1 -1
  35. package/dist/types/src/components/KanbanContainer.stories.d.ts.map +1 -1
  36. package/dist/types/src/components/KanbanViewEditor.d.ts +3 -3
  37. package/dist/types/src/components/KanbanViewEditor.d.ts.map +1 -1
  38. package/dist/types/src/index.d.ts +1 -1
  39. package/dist/types/src/index.d.ts.map +1 -1
  40. package/dist/types/src/translations.d.ts +24 -53
  41. package/dist/types/src/translations.d.ts.map +1 -1
  42. package/dist/types/src/types/index.d.ts +4 -0
  43. package/dist/types/src/types/index.d.ts.map +1 -0
  44. package/dist/types/src/types/kanban.d.ts +11 -0
  45. package/dist/types/src/types/kanban.d.ts.map +1 -0
  46. package/dist/types/src/types/schema.d.ts +110 -0
  47. package/dist/types/src/types/schema.d.ts.map +1 -0
  48. package/dist/types/src/types/types.d.ts +4 -0
  49. package/dist/types/src/types/types.d.ts.map +1 -0
  50. package/dist/types/tsconfig.tsbuildinfo +1 -1
  51. package/package.json +36 -32
  52. package/src/KanbanPlugin.tsx +5 -4
  53. package/src/capabilities/artifact-definition.ts +25 -17
  54. package/src/capabilities/intent-resolver.ts +13 -14
  55. package/src/capabilities/react-surface.tsx +15 -12
  56. package/src/components/KanbanContainer.stories.tsx +42 -45
  57. package/src/components/KanbanContainer.tsx +11 -11
  58. package/src/components/KanbanViewEditor.tsx +21 -65
  59. package/src/index.ts +2 -1
  60. package/src/translations.ts +7 -7
  61. package/src/types/index.ts +7 -0
  62. package/src/types/kanban.ts +29 -0
  63. package/src/{types.ts → types/schema.ts} +5 -26
  64. package/src/types/types.ts +7 -0
  65. package/dist/lib/browser/artifact-definition-6HNQFL2M.mjs.map +0 -7
  66. package/dist/lib/browser/chunk-6JEDX6HA.mjs.map +0 -7
  67. package/dist/lib/browser/intent-resolver-QQOH5EV2.mjs +0 -297
  68. package/dist/lib/browser/intent-resolver-QQOH5EV2.mjs.map +0 -7
  69. package/dist/lib/browser/react-surface-HJL2JRJP.mjs.map +0 -7
  70. package/dist/lib/node/artifact-definition-GRCAYCVG.cjs +0 -193
  71. package/dist/lib/node/artifact-definition-GRCAYCVG.cjs.map +0 -7
  72. package/dist/lib/node/chunk-ATDUVDIE.cjs +0 -108
  73. package/dist/lib/node/chunk-ATDUVDIE.cjs.map +0 -7
  74. package/dist/lib/node/index.cjs +0 -128
  75. package/dist/lib/node/index.cjs.map +0 -7
  76. package/dist/lib/node/intent-resolver-6ZNOIHKY.cjs +0 -308
  77. package/dist/lib/node/intent-resolver-6ZNOIHKY.cjs.map +0 -7
  78. package/dist/lib/node/meta.json +0 -1
  79. package/dist/lib/node/react-surface-G2J6F7U5.cjs +0 -322
  80. package/dist/lib/node/react-surface-G2J6F7U5.cjs.map +0 -7
  81. package/dist/lib/node/types.cjs +0 -35
  82. package/dist/lib/node/types.cjs.map +0 -7
  83. package/dist/lib/node-esm/artifact-definition-FA2IAAUQ.mjs.map +0 -7
  84. package/dist/lib/node-esm/chunk-7DHZSNGQ.mjs.map +0 -7
  85. package/dist/lib/node-esm/intent-resolver-4TYFDM4E.mjs +0 -298
  86. package/dist/lib/node-esm/intent-resolver-4TYFDM4E.mjs.map +0 -7
  87. package/dist/lib/node-esm/react-surface-257WTPQZ.mjs.map +0 -7
  88. package/dist/types/src/testing/index.d.ts +0 -3
  89. package/dist/types/src/testing/index.d.ts.map +0 -1
  90. package/dist/types/src/testing/initialize-kanban.d.ts +0 -17
  91. package/dist/types/src/testing/initialize-kanban.d.ts.map +0 -1
  92. package/dist/types/src/testing/kanban-manager.d.ts +0 -7
  93. package/dist/types/src/testing/kanban-manager.d.ts.map +0 -1
  94. package/dist/types/src/testing/playwright/smoke.spec.d.ts +0 -2
  95. package/dist/types/src/testing/playwright/smoke.spec.d.ts.map +0 -1
  96. package/dist/types/src/types.d.ts +0 -76
  97. package/dist/types/src/types.d.ts.map +0 -1
  98. package/src/testing/index.ts +0 -6
  99. package/src/testing/initialize-kanban.ts +0 -128
  100. package/src/testing/kanban-manager.ts +0 -13
  101. package/src/testing/playwright/playwright.config.cts +0 -18
  102. package/src/testing/playwright/smoke.spec.ts +0 -7
  103. /package/dist/lib/browser/{types.mjs.map → types/index.mjs.map} +0 -0
  104. /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.5acf9ea",
4
4
  "description": "Kanban DXOS Surface plugin",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -12,12 +12,14 @@
12
12
  ".": {
13
13
  "types": "./dist/types/src/index.d.ts",
14
14
  "browser": "./dist/lib/browser/index.mjs",
15
- "node": "./dist/lib/node-esm/index.mjs"
15
+ "node": "./dist/lib/node-esm/index.mjs",
16
+ "source": "./src/index.ts"
16
17
  },
17
18
  "./types": {
18
19
  "types": "./dist/types/src/types/index.d.ts",
19
20
  "browser": "./dist/lib/browser/types/index.mjs",
20
- "node": "./dist/lib/node-esm/types/index.mjs"
21
+ "node": "./dist/lib/node-esm/types/index.mjs",
22
+ "source": "./src/types/index.ts"
21
23
  }
22
24
  },
23
25
  "types": "dist/types/src/index.d.ts",
@@ -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.0",
41
+ "@dxos/ai": "0.8.4-main.5acf9ea",
42
+ "@dxos/app-framework": "0.8.4-main.5acf9ea",
43
+ "@dxos/assistant": "0.8.4-main.5acf9ea",
44
+ "@dxos/blueprints": "0.8.4-main.5acf9ea",
45
+ "@dxos/async": "0.8.4-main.5acf9ea",
46
+ "@dxos/echo-schema": "0.8.4-main.5acf9ea",
47
+ "@dxos/effect": "0.8.4-main.5acf9ea",
48
+ "@dxos/echo": "0.8.4-main.5acf9ea",
49
+ "@dxos/log": "0.8.4-main.5acf9ea",
50
+ "@dxos/invariant": "0.8.4-main.5acf9ea",
51
+ "@dxos/plugin-client": "0.8.4-main.5acf9ea",
52
+ "@dxos/plugin-graph": "0.8.4-main.5acf9ea",
53
+ "@dxos/plugin-search": "0.8.4-main.5acf9ea",
54
+ "@dxos/plugin-space": "0.8.4-main.5acf9ea",
55
+ "@dxos/random": "0.8.4-main.5acf9ea",
56
+ "@dxos/react-client": "0.8.4-main.5acf9ea",
57
+ "@dxos/react-ui": "0.8.4-main.5acf9ea",
58
+ "@dxos/react-ui-form": "0.8.4-main.5acf9ea",
59
+ "@dxos/react-ui-kanban": "0.8.4-main.5acf9ea",
60
+ "@dxos/schema": "0.8.4-main.5acf9ea",
61
+ "@dxos/react-ui-stack": "0.8.4-main.5acf9ea",
62
+ "@dxos/util": "0.8.4-main.5acf9ea"
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-preview": "0.8.4-main.5acf9ea",
71
+ "@dxos/plugin-theme": "0.8.4-main.5acf9ea",
72
+ "@dxos/react-ui-syntax-highlighter": "0.8.4-main.5acf9ea",
73
+ "@dxos/react-ui-theme": "0.8.4-main.5acf9ea",
74
+ "@dxos/storybook-utils": "0.8.4-main.5acf9ea",
75
+ "@dxos/test-utils": "0.8.4-main.5acf9ea"
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.5acf9ea",
82
+ "@dxos/react-ui-theme": "0.8.4-main.5acf9ea"
79
83
  },
80
84
  "publishConfig": {
81
85
  "access": "public"
@@ -6,11 +6,11 @@ import { createIntent, defineModule, contributes, Capabilities, Events, definePl
6
6
  import { ClientEvents } from '@dxos/plugin-client';
7
7
  import { SpaceCapabilities } from '@dxos/plugin-space';
8
8
  import { defineObjectForm } from '@dxos/plugin-space/types';
9
- import { KanbanType, translations as kanbanTranslations } from '@dxos/react-ui-kanban';
9
+ import { KanbanView, translations as kanbanTranslations } from '@dxos/react-ui-kanban';
10
10
 
11
11
  import { ArtifactDefinition, IntentResolver, ReactSurface } from './capabilities';
12
12
  import { meta } from './meta';
13
- import translations from './translations';
13
+ import { translations } from './translations';
14
14
  import { CreateKanbanSchema, KanbanAction } from './types';
15
15
 
16
16
  export const KanbanPlugin = () =>
@@ -25,7 +25,7 @@ export const KanbanPlugin = () =>
25
25
  activatesOn: Events.SetupMetadata,
26
26
  activate: () =>
27
27
  contributes(Capabilities.Metadata, {
28
- id: 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
  ),
@@ -6,13 +6,15 @@ import { Schema, pipe } from 'effect';
6
6
 
7
7
  import { createTool, ToolResult } from '@dxos/ai';
8
8
  import { Capabilities, chain, contributes, createIntent, type PromiseIntentDispatcher } from '@dxos/app-framework';
9
- import { defineArtifact } from '@dxos/artifact';
10
9
  import { createArtifactElement } from '@dxos/assistant';
11
- import { Obj } from '@dxos/echo';
10
+ import { defineArtifact } from '@dxos/blueprints';
11
+ import { Obj, Query } from '@dxos/echo';
12
12
  import { invariant } from '@dxos/invariant';
13
13
  import { SpaceAction } from '@dxos/plugin-space/types';
14
14
  import { Filter, fullyQualifiedId, type Space } from '@dxos/react-client/echo';
15
- import { KanbanType } from '@dxos/react-ui-kanban';
15
+ import { KanbanView } from '@dxos/react-ui-kanban';
16
+ import { DataType } from '@dxos/schema';
17
+ import { isNonNullable } from '@dxos/util';
16
18
 
17
19
  import { meta } from '../meta';
18
20
  import { KanbanAction } from '../types';
@@ -37,7 +39,7 @@ export default () => {
37
39
  - When adding items, you must not include the 'id' field -- it is automatically generated
38
40
  - BEFORE adding items, always make sure the board has been shown to the user!
39
41
  `,
40
- schema: KanbanType,
42
+ schema: KanbanView,
41
43
  tools: [
42
44
  createTool(meta.id, {
43
45
  name: 'create',
@@ -88,19 +90,24 @@ export default () => {
88
90
  execute: async (_input, { extensions }) => {
89
91
  invariant(extensions?.space, 'No space');
90
92
  const space = extensions.space;
91
- const { objects: boards } = await space.db.query(Filter.type(KanbanType)).run();
93
+ const { objects } = await space.db.query(Filter.type(DataType.View)).run();
92
94
 
93
95
  const boardInfo = await Promise.all(
94
- boards.map(async (board: KanbanType) => {
95
- const view = await board.cardView?.load();
96
+ objects.map(async (view) => {
97
+ const kanban = await view.presentation.load();
98
+ if (!Obj.instanceOf(KanbanView, kanban)) {
99
+ return null;
100
+ }
101
+
96
102
  return {
97
- id: fullyQualifiedId(board),
98
- typename: view?.query.typename,
103
+ id: fullyQualifiedId(view),
104
+ name: view.name ?? 'Unnamed Kanban',
105
+ typename: view.query.typename,
99
106
  };
100
107
  }),
101
108
  );
102
109
 
103
- return ToolResult.Success(boardInfo);
110
+ return ToolResult.Success(boardInfo.filter(isNonNullable));
104
111
  },
105
112
  }),
106
113
  createTool(meta.id, {
@@ -111,12 +118,13 @@ export default () => {
111
118
  execute: async ({ id }, { extensions }) => {
112
119
  invariant(extensions?.space, 'No space');
113
120
  const space = extensions.space;
114
- const { 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));
121
+ const view = (await space.db
122
+ // TODO(wittjosiah): Filter.and should aggregate type
123
+ .query(Query.select(Filter.and(Filter.type(DataType.View), Filter.ids(id))))
124
+ .first()) as DataType.View;
117
125
 
118
- const view = await board.cardView?.load();
119
- invariant(view);
126
+ const kanban = await view.presentation.load();
127
+ invariant(Obj.instanceOf(KanbanView, kanban));
120
128
 
121
129
  const typename = view.query.typename;
122
130
  const schema = await space.db.schemaRegistry.query({ typename }).firstOrUndefined();
@@ -124,8 +132,8 @@ export default () => {
124
132
 
125
133
  return ToolResult.Success({
126
134
  schema,
127
- columnField: board.columnFieldId,
128
- viewFields: view.fields,
135
+ columnField: kanban.columnFieldId,
136
+ viewFields: view.projection.fields,
129
137
  });
130
138
  },
131
139
  }),
@@ -6,11 +6,10 @@ import { contributes, Capabilities, createResolver, type PluginContext } from '@
6
6
  import { invariant } from '@dxos/invariant';
7
7
  import { ClientCapabilities } from '@dxos/plugin-client';
8
8
  import { getSpace } from '@dxos/react-client/echo';
9
- import { 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 { createKanban, KanbanAction } from '../types';
14
13
 
15
14
  export default (context: PluginContext) =>
16
15
  contributes(Capabilities.IntentResolver, [
@@ -18,22 +17,22 @@ export default (context: PluginContext) =>
18
17
  intent: KanbanAction.Create,
19
18
  resolve: async ({ space, name, typename, initialPivotColumn }) => {
20
19
  const client = context.getCapability(ClientCapabilities.Client);
21
- const { 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
12
  import { getSpace, isSpace, type Space } from '@dxos/react-client/echo';
13
13
  import { type InputProps, SelectInput, useFormValues } from '@dxos/react-ui-form';
14
- import { 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 StoryObj, type Meta } from '@storybook/react-vite';
7
8
  import React, { useCallback, useEffect, useState } from 'react';
8
9
 
9
10
  import { IntentPlugin, SettingsPlugin } from '@dxos/app-framework';
@@ -20,14 +21,14 @@ import { faker } from '@dxos/random';
20
21
  import { useClient } from '@dxos/react-client';
21
22
  import { Filter, useSpaces, useQuery, useSchema } from '@dxos/react-client/echo';
22
23
  import { ViewEditor } from '@dxos/react-ui-form';
23
- import { Kanban, 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],
156
+ types: [DataType.Organization, DataType.Person, DataType.View, KanbanView],
158
157
  onClientInitialized: async (_, client) => {
159
158
  await client.halo.createIdentity();
160
159
  const space = await client.spaces.create();
161
160
  await space.waitUntilReady();
162
- const { 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(),
@@ -10,17 +10,17 @@ import { EchoSchema, type TypedObject } from '@dxos/echo-schema';
10
10
  import { useGlobalFilteredObjects } from '@dxos/plugin-search';
11
11
  import { useClient } from '@dxos/react-client';
12
12
  import { useQuery, getSpace } from '@dxos/react-client/echo';
13
- import { type KanbanType, useKanbanModel, Kanban } from '@dxos/react-ui-kanban';
13
+ import { useKanbanModel, Kanban } from '@dxos/react-ui-kanban';
14
14
  import { StackItem } from '@dxos/react-ui-stack';
15
- import { ViewProjection } from '@dxos/schema';
15
+ import { ProjectionModel, type DataType } 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,