@dxos/plugin-kanban 0.8.3 → 0.8.4-main.1da679c

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 (109) hide show
  1. package/dist/lib/browser/blueprint-definition-UYVX622Q.mjs +28 -0
  2. package/dist/lib/browser/blueprint-definition-UYVX622Q.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-6JEDX6HA.mjs → chunk-NCNNL74W.mjs} +9 -12
  4. package/dist/lib/browser/chunk-NCNNL74W.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +21 -20
  6. package/dist/lib/browser/index.mjs.map +3 -3
  7. package/dist/lib/browser/intent-resolver-UWM5C5LZ.mjs +111 -0
  8. package/dist/lib/browser/intent-resolver-UWM5C5LZ.mjs.map +7 -0
  9. package/dist/lib/browser/meta.json +1 -1
  10. package/dist/lib/browser/{react-surface-HJL2JRJP.mjs → react-surface-4JNCLFQB.mjs} +48 -100
  11. package/dist/lib/browser/react-surface-4JNCLFQB.mjs.map +7 -0
  12. package/dist/lib/browser/types/index.mjs +11 -0
  13. package/dist/lib/node-esm/blueprint-definition-42P47FUY.mjs +30 -0
  14. package/dist/lib/node-esm/blueprint-definition-42P47FUY.mjs.map +7 -0
  15. package/dist/lib/node-esm/{chunk-7DHZSNGQ.mjs → chunk-5B3LKGA7.mjs} +9 -12
  16. package/dist/lib/node-esm/chunk-5B3LKGA7.mjs.map +7 -0
  17. package/dist/lib/node-esm/index.mjs +21 -20
  18. package/dist/lib/node-esm/index.mjs.map +3 -3
  19. package/dist/lib/node-esm/intent-resolver-JDQ7I5HR.mjs +112 -0
  20. package/dist/lib/node-esm/intent-resolver-JDQ7I5HR.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-2C7LFFY5.mjs} +48 -100
  23. package/dist/lib/node-esm/react-surface-2C7LFFY5.mjs.map +7 -0
  24. package/dist/lib/node-esm/{types.mjs → types/index.mjs} +4 -6
  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/blueprint-definition.d.ts +5 -0
  29. package/dist/types/src/capabilities/blueprint-definition.d.ts.map +1 -0
  30. package/dist/types/src/capabilities/index.d.ts +3 -3
  31. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  32. package/dist/types/src/capabilities/intent-resolver.d.ts +1 -1
  33. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  34. package/dist/types/src/capabilities/react-surface.d.ts +1 -1
  35. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  36. package/dist/types/src/components/KanbanContainer.d.ts +3 -3
  37. package/dist/types/src/components/KanbanContainer.d.ts.map +1 -1
  38. package/dist/types/src/components/KanbanContainer.stories.d.ts +36 -5
  39. package/dist/types/src/components/KanbanContainer.stories.d.ts.map +1 -1
  40. package/dist/types/src/components/KanbanViewEditor.d.ts +3 -3
  41. package/dist/types/src/components/KanbanViewEditor.d.ts.map +1 -1
  42. package/dist/types/src/index.d.ts +1 -1
  43. package/dist/types/src/index.d.ts.map +1 -1
  44. package/dist/types/src/translations.d.ts +24 -53
  45. package/dist/types/src/translations.d.ts.map +1 -1
  46. package/dist/types/src/types/index.d.ts +3 -0
  47. package/dist/types/src/types/index.d.ts.map +1 -0
  48. package/dist/types/src/{types.d.ts → types/schema.d.ts} +4 -13
  49. package/dist/types/src/types/schema.d.ts.map +1 -0
  50. package/dist/types/src/types/types.d.ts +4 -0
  51. package/dist/types/src/types/types.d.ts.map +1 -0
  52. package/dist/types/tsconfig.tsbuildinfo +1 -1
  53. package/package.json +36 -31
  54. package/src/KanbanPlugin.tsx +10 -8
  55. package/src/capabilities/artifact-definition.ts +32 -21
  56. package/src/capabilities/blueprint-definition.ts +30 -0
  57. package/src/capabilities/index.ts +1 -1
  58. package/src/capabilities/intent-resolver.ts +14 -14
  59. package/src/capabilities/react-surface.tsx +16 -13
  60. package/src/components/KanbanContainer.stories.tsx +53 -55
  61. package/src/components/KanbanContainer.tsx +12 -12
  62. package/src/components/KanbanViewEditor.tsx +26 -68
  63. package/src/index.ts +2 -1
  64. package/src/translations.ts +7 -7
  65. package/src/types/index.ts +6 -0
  66. package/src/{types.ts → types/schema.ts} +6 -27
  67. package/src/types/types.ts +7 -0
  68. package/dist/lib/browser/artifact-definition-6HNQFL2M.mjs +0 -178
  69. package/dist/lib/browser/artifact-definition-6HNQFL2M.mjs.map +0 -7
  70. package/dist/lib/browser/chunk-6JEDX6HA.mjs.map +0 -7
  71. package/dist/lib/browser/intent-resolver-QQOH5EV2.mjs +0 -297
  72. package/dist/lib/browser/intent-resolver-QQOH5EV2.mjs.map +0 -7
  73. package/dist/lib/browser/react-surface-HJL2JRJP.mjs.map +0 -7
  74. package/dist/lib/browser/types.mjs +0 -13
  75. package/dist/lib/node/artifact-definition-GRCAYCVG.cjs +0 -193
  76. package/dist/lib/node/artifact-definition-GRCAYCVG.cjs.map +0 -7
  77. package/dist/lib/node/chunk-ATDUVDIE.cjs +0 -108
  78. package/dist/lib/node/chunk-ATDUVDIE.cjs.map +0 -7
  79. package/dist/lib/node/index.cjs +0 -128
  80. package/dist/lib/node/index.cjs.map +0 -7
  81. package/dist/lib/node/intent-resolver-6ZNOIHKY.cjs +0 -308
  82. package/dist/lib/node/intent-resolver-6ZNOIHKY.cjs.map +0 -7
  83. package/dist/lib/node/meta.json +0 -1
  84. package/dist/lib/node/react-surface-G2J6F7U5.cjs +0 -322
  85. package/dist/lib/node/react-surface-G2J6F7U5.cjs.map +0 -7
  86. package/dist/lib/node/types.cjs +0 -35
  87. package/dist/lib/node/types.cjs.map +0 -7
  88. package/dist/lib/node-esm/artifact-definition-FA2IAAUQ.mjs +0 -179
  89. package/dist/lib/node-esm/artifact-definition-FA2IAAUQ.mjs.map +0 -7
  90. package/dist/lib/node-esm/chunk-7DHZSNGQ.mjs.map +0 -7
  91. package/dist/lib/node-esm/intent-resolver-4TYFDM4E.mjs +0 -298
  92. package/dist/lib/node-esm/intent-resolver-4TYFDM4E.mjs.map +0 -7
  93. package/dist/lib/node-esm/react-surface-257WTPQZ.mjs.map +0 -7
  94. package/dist/types/src/testing/index.d.ts +0 -3
  95. package/dist/types/src/testing/index.d.ts.map +0 -1
  96. package/dist/types/src/testing/initialize-kanban.d.ts +0 -17
  97. package/dist/types/src/testing/initialize-kanban.d.ts.map +0 -1
  98. package/dist/types/src/testing/kanban-manager.d.ts +0 -7
  99. package/dist/types/src/testing/kanban-manager.d.ts.map +0 -1
  100. package/dist/types/src/testing/playwright/smoke.spec.d.ts +0 -2
  101. package/dist/types/src/testing/playwright/smoke.spec.d.ts.map +0 -1
  102. package/dist/types/src/types.d.ts.map +0 -1
  103. package/src/testing/index.ts +0 -6
  104. package/src/testing/initialize-kanban.ts +0 -128
  105. package/src/testing/kanban-manager.ts +0 -13
  106. package/src/testing/playwright/playwright.config.cts +0 -18
  107. package/src/testing/playwright/smoke.spec.ts +0 -7
  108. /package/dist/lib/browser/{types.mjs.map → types/index.mjs.map} +0 -0
  109. /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.1da679c",
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,47 +37,50 @@
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.1da679c",
42
+ "@dxos/app-framework": "0.8.4-main.1da679c",
43
+ "@dxos/assistant": "0.8.4-main.1da679c",
44
+ "@dxos/async": "0.8.4-main.1da679c",
45
+ "@dxos/echo": "0.8.4-main.1da679c",
46
+ "@dxos/blueprints": "0.8.4-main.1da679c",
47
+ "@dxos/echo-schema": "0.8.4-main.1da679c",
48
+ "@dxos/effect": "0.8.4-main.1da679c",
49
+ "@dxos/functions": "0.8.4-main.1da679c",
50
+ "@dxos/invariant": "0.8.4-main.1da679c",
51
+ "@dxos/log": "0.8.4-main.1da679c",
52
+ "@dxos/plugin-space": "0.8.4-main.1da679c",
53
+ "@dxos/plugin-client": "0.8.4-main.1da679c",
54
+ "@dxos/react-client": "0.8.4-main.1da679c",
55
+ "@dxos/random": "0.8.4-main.1da679c",
56
+ "@dxos/plugin-search": "0.8.4-main.1da679c",
57
+ "@dxos/react-ui": "0.8.4-main.1da679c",
58
+ "@dxos/react-ui-form": "0.8.4-main.1da679c",
59
+ "@dxos/react-ui-kanban": "0.8.4-main.1da679c",
60
+ "@dxos/react-ui-stack": "0.8.4-main.1da679c",
61
+ "@dxos/util": "0.8.4-main.1da679c",
62
+ "@dxos/schema": "0.8.4-main.1da679c",
63
+ "@dxos/plugin-graph": "0.8.4-main.1da679c"
59
64
  },
60
65
  "devDependencies": {
61
66
  "@types/react": "~18.2.0",
62
67
  "@types/react-dom": "~18.2.0",
63
68
  "react": "~18.2.0",
64
69
  "react-dom": "~18.2.0",
65
- "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
+ "vite": "7.1.1",
71
+ "@dxos/plugin-preview": "0.8.4-main.1da679c",
72
+ "@dxos/plugin-theme": "0.8.4-main.1da679c",
73
+ "@dxos/react-ui-theme": "0.8.4-main.1da679c",
74
+ "@dxos/storybook-utils": "0.8.4-main.1da679c",
75
+ "@dxos/react-ui-syntax-highlighter": "0.8.4-main.1da679c",
76
+ "@dxos/test-utils": "0.8.4-main.1da679c"
72
77
  },
73
78
  "peerDependencies": {
74
79
  "effect": "^3.13.3",
75
80
  "react": "~18.2.0",
76
81
  "react-dom": "~18.2.0",
77
- "@dxos/react-ui": "0.8.3",
78
- "@dxos/react-ui-theme": "0.8.3"
82
+ "@dxos/react-ui": "0.8.4-main.1da679c",
83
+ "@dxos/react-ui-theme": "0.8.4-main.1da679c"
79
84
  },
80
85
  "publishConfig": {
81
86
  "access": "public"
@@ -2,15 +2,16 @@
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 { translations as kanbanTranslations } from '@dxos/react-ui-kanban';
10
+ import { Kanban } from '@dxos/react-ui-kanban/types';
10
11
 
11
- import { ArtifactDefinition, IntentResolver, ReactSurface } from './capabilities';
12
+ import { BlueprintDefinition, IntentResolver, ReactSurface } from './capabilities';
12
13
  import { meta } from './meta';
13
- import translations from './translations';
14
+ import { translations } from './translations';
14
15
  import { CreateKanbanSchema, KanbanAction } from './types';
15
16
 
16
17
  export const KanbanPlugin = () =>
@@ -25,7 +26,7 @@ export const KanbanPlugin = () =>
25
26
  activatesOn: Events.SetupMetadata,
26
27
  activate: () =>
27
28
  contributes(Capabilities.Metadata, {
28
- id: KanbanType.typename,
29
+ id: Kanban.Kanban.typename,
29
30
  metadata: {
30
31
  icon: 'ph--kanban--regular',
31
32
  },
@@ -38,8 +39,9 @@ export const KanbanPlugin = () =>
38
39
  contributes(
39
40
  SpaceCapabilities.ObjectForm,
40
41
  defineObjectForm({
41
- objectSchema: KanbanType,
42
+ objectSchema: Kanban.Kanban,
42
43
  formSchema: CreateKanbanSchema,
44
+ hidden: true,
43
45
  getIntent: (props, options) => createIntent(KanbanAction.Create, { ...props, space: options.space }),
44
46
  }),
45
47
  ),
@@ -55,8 +57,8 @@ export const KanbanPlugin = () =>
55
57
  activate: IntentResolver,
56
58
  }),
57
59
  defineModule({
58
- id: `${meta.id}/module/artifact-definition`,
60
+ id: `${meta.id}/module/blueprint`,
59
61
  activatesOn: Events.SetupArtifactDefinition,
60
- activate: ArtifactDefinition,
62
+ activate: BlueprintDefinition,
61
63
  }),
62
64
  ]);
@@ -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
  }),
@@ -0,0 +1,30 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { Capabilities, contributes } from '@dxos/app-framework';
6
+ import { Blueprint, Template } from '@dxos/blueprints';
7
+ import { type FunctionDefinition } from '@dxos/functions';
8
+ import { trim } from '@dxos/util';
9
+
10
+ const functions: FunctionDefinition[] = [];
11
+ const tools: string[] = [];
12
+
13
+ export default () => {
14
+ return [
15
+ contributes(Capabilities.Functions, functions),
16
+ contributes(
17
+ Capabilities.BlueprintDefinition,
18
+ Blueprint.make({
19
+ key: 'dxos.org/blueprint/kanban',
20
+ name: 'Kanban',
21
+ tools: Blueprint.toolDefinitions({ functions, tools }),
22
+ instructions: Template.make({
23
+ source: trim`
24
+ You can create and update kanban boards to show data in sorted columns defined by schema.
25
+ `,
26
+ }),
27
+ }),
28
+ ),
29
+ ];
30
+ };
@@ -4,6 +4,6 @@
4
4
 
5
5
  import { lazy } from '@dxos/app-framework';
6
6
 
7
- export const ArtifactDefinition = lazy(() => import('./artifact-definition'));
7
+ export const BlueprintDefinition = lazy(() => import('./blueprint-definition'));
8
8
  export const IntentResolver = lazy(() => import('./intent-resolver'));
9
9
  export const ReactSurface = lazy(() => import('./react-surface'));
@@ -2,14 +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 { Kanban } from '@dxos/react-ui-kanban/types';
10
+ import { ProjectionModel, typenameFromQuery } from '@dxos/schema';
10
11
 
11
12
  import { KANBAN_PLUGIN } from '../meta';
12
- import { initializeKanban } from '../testing';
13
13
  import { KanbanAction } from '../types';
14
14
 
15
15
  export default (context: PluginContext) =>
@@ -18,22 +18,22 @@ export default (context: PluginContext) =>
18
18
  intent: KanbanAction.Create,
19
19
  resolve: async ({ space, name, typename, initialPivotColumn }) => {
20
20
  const client = context.getCapability(ClientCapabilities.Client);
21
- const { kanban } = await initializeKanban({ client, space, name, typename, initialPivotColumn });
22
- return { data: { object: kanban } };
21
+ const { view } = await Kanban.makeView({
22
+ client,
23
+ space,
24
+ name,
25
+ typename,
26
+ pivotFieldName: initialPivotColumn,
27
+ });
28
+ return { data: { object: view } };
23
29
  },
24
30
  }),
25
31
  createResolver({
26
32
  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);
33
+ resolve: async ({ view, fieldId, deletionData }, undo) => {
34
+ const schema = getSpace(view)?.db.schemaRegistry.getSchema(typenameFromQuery(view.query)!);
34
35
  invariant(schema);
35
- invariant(kanban.cardView.target);
36
- const projection = new ViewProjection(schema.jsonSchema, kanban.cardView.target);
36
+ const projection = new ProjectionModel(schema.jsonSchema, view.projection);
37
37
 
38
38
  if (!undo) {
39
39
  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 { Kanban } from '@dxos/react-ui-kanban/types';
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(Kanban.Kanban, 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(Kanban.Kanban, 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,12 +3,13 @@
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';
10
11
  import { withPluginManager } from '@dxos/app-framework/testing';
11
- import { Obj, Type } from '@dxos/echo';
12
+ import { Obj, Query, Type } from '@dxos/echo';
12
13
  import { invariant } from '@dxos/invariant';
13
14
  import { ClientPlugin } from '@dxos/plugin-client';
14
15
  import { PreviewPlugin } from '@dxos/plugin-preview';
@@ -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 as KanbanComponent, useKanbanModel } from '@dxos/react-ui-kanban';
25
+ import { Kanban } from '@dxos/react-ui-kanban/types';
24
26
  import { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';
25
27
  import { defaultTx } from '@dxos/react-ui-theme';
26
- import { DataType, ViewProjection } from '@dxos/schema';
28
+ import { DataType, ProjectionModel, typenameFromQuery } from '@dxos/schema';
27
29
  import { withLayout } from '@dxos/storybook-utils';
28
30
 
29
- import { initializeKanban } from '../testing';
30
- import translations from '../translations';
31
+ import { translations } from '../translations';
31
32
 
32
33
  faker.seed(0);
33
34
 
@@ -40,39 +41,40 @@ 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 typename = view?.query ? typenameFromQuery(view.query) : undefined;
55
+ const schema = useSchema(client, space, typename);
54
56
 
55
57
  useEffect(() => {
56
- if (kanbans.length && !kanban) {
57
- const kanban = kanbans[0];
58
- setKanban(kanban);
58
+ if (views.length && !view) {
59
+ const view = views[0];
60
+ setView(view);
59
61
  }
60
- }, [kanbans]);
62
+ }, [views]);
61
63
 
62
64
  useEffect(() => {
63
- if (kanban?.cardView?.target && schema) {
65
+ if (view?.projection && schema) {
64
66
  const jsonSchema = Type.toJsonSchema(schema);
65
- setProjection(new ViewProjection(jsonSchema, kanban.cardView.target));
67
+ setProjection(new ProjectionModel(jsonSchema, view.projection));
66
68
  }
67
69
  // TODO(ZaymonFC): Is there a better way to get notified about deep changes in the json schema?
68
70
  // @dmaretskyi? Once resolved, update in multiple places (e.g., storybooks).
69
- }, [kanban?.cardView?.target, schema, JSON.stringify(schema ? Type.toJsonSchema(schema) : {})]);
71
+ }, [view?.projection, schema, JSON.stringify(schema ? Type.toJsonSchema(schema) : {})]);
70
72
 
71
73
  const objects = useQuery(space, schema ? Filter.type(schema) : Filter.nothing());
72
74
  const filteredObjects = useGlobalFilteredObjects(objects);
73
75
 
74
76
  const model = useKanbanModel({
75
- kanban,
77
+ view,
76
78
  schema,
77
79
  projection,
78
80
  items: filteredObjects,
@@ -96,39 +98,37 @@ const StorybookKanban = () => {
96
98
 
97
99
  const handleRemoveCard = useCallback((card: { id: string }) => space.db.remove(card), [space]);
98
100
 
99
- const handleTypenameChanged = useCallback(
101
+ const handleUpdateQuery = useCallback(
100
102
  (typename: string) => {
101
103
  invariant(schema);
102
104
  invariant(Type.isMutable(schema));
103
- invariant(kanban?.cardView?.target);
105
+ invariant(view);
104
106
 
105
107
  schema.updateTypename(typename);
106
- kanban.cardView.target.query.typename = typename;
108
+ view.query = Query.select(Filter.typename(typename)).ast;
107
109
  },
108
- [kanban?.cardView?.target, schema],
110
+ [view, schema],
109
111
  );
110
112
 
111
- if (!schema || !kanban) {
113
+ if (!schema || !view) {
112
114
  return null;
113
115
  }
114
116
 
115
117
  return (
116
118
  <div className='grow grid grid-cols-[1fr_350px]'>
117
- {model ? <Kanban model={model} onAddCard={handleAddCard} onRemoveCard={handleRemoveCard} /> : <div />}
119
+ {model ? <KanbanComponent model={model} onAddCard={handleAddCard} onRemoveCard={handleRemoveCard} /> : <div />}
118
120
  <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
- )}
130
- <SyntaxHighlighter language='json' className='w-full text-xs'>
131
- {JSON.stringify({ cardView: kanban.cardView?.target, cardSchema: schema }, null, 2)}
121
+ <ViewEditor
122
+ registry={space?.db.schemaRegistry}
123
+ schema={schema}
124
+ view={view}
125
+ onQueryChanged={handleUpdateQuery}
126
+ onDelete={(fieldId: string) => {
127
+ console.log('[ViewEditor]', 'onDelete', fieldId);
128
+ }}
129
+ />
130
+ <SyntaxHighlighter language='json' className='text-xs'>
131
+ {JSON.stringify({ view, schema }, null, 2)}
132
132
  </SyntaxHighlighter>
133
133
  </div>
134
134
  </div>
@@ -143,7 +143,7 @@ type StoryProps = {
143
143
  // Story definitions.
144
144
  //
145
145
 
146
- const meta: Meta<StoryProps> = {
146
+ const meta = {
147
147
  title: 'plugins/plugin-kanban/Kanban',
148
148
  component: StorybookKanban,
149
149
  render: () => <StorybookKanban />,
@@ -154,25 +154,23 @@ const meta: Meta<StoryProps> = {
154
154
  plugins: [
155
155
  ThemePlugin({ tx: defaultTx }),
156
156
  ClientPlugin({
157
- types: [DataType.Organization, DataType.Person, KanbanType],
158
- onClientInitialized: async (_, client) => {
157
+ types: [DataType.Organization, DataType.Person, DataType.View, Kanban.Kanban],
158
+ onClientInitialized: async ({ client }) => {
159
159
  await client.halo.createIdentity();
160
160
  const space = await client.spaces.create();
161
161
  await space.waitUntilReady();
162
- const { schema, kanban } = await initializeKanban({
163
- space,
162
+ const { view } = await Kanban.makeView({
164
163
  client,
164
+ space,
165
165
  typename: DataType.Organization.typename,
166
- initialPivotColumn: 'status',
166
+ pivotFieldName: 'status',
167
+ });
168
+ space.db.add(view);
169
+
170
+ // TODO(burdon): Replace with sdk/schema/testing.
171
+ Array.from({ length: 80 }).map(() => {
172
+ return space.db.add(Obj.make(DataType.Organization, rollOrg()));
167
173
  });
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
- }
176
174
  },
177
175
  }),
178
176
  StorybookLayoutPlugin(),
@@ -183,10 +181,10 @@ const meta: Meta<StoryProps> = {
183
181
  ],
184
182
  }),
185
183
  ],
186
- };
184
+ } satisfies Meta<typeof StorybookKanban>;
187
185
 
188
186
  export default meta;
189
187
 
190
- type Story = StoryObj<StoryProps>;
188
+ type Story = StoryObj<typeof meta>;
191
189
 
192
190
  export const Default: Story = {};