@dxos/plugin-pipeline 0.8.4-main.3eb6e50203 → 0.8.4-main.c85a9c8dae

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 (68) hide show
  1. package/dist/lib/browser/PipelineContainer-2ZYSZATA.mjs +320 -0
  2. package/dist/lib/browser/PipelineContainer-2ZYSZATA.mjs.map +7 -0
  3. package/dist/lib/browser/{PipelineSettings-YSGSJHBT.mjs → PipelineObjectSettings-D36OYVHW.mjs} +66 -54
  4. package/dist/lib/browser/PipelineObjectSettings-D36OYVHW.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-7GVESVYR.mjs → chunk-N6FZHYWT.mjs} +2 -2
  6. package/dist/lib/browser/chunk-N6FZHYWT.mjs.map +7 -0
  7. package/dist/lib/browser/index.mjs +4 -4
  8. package/dist/lib/browser/index.mjs.map +3 -3
  9. package/dist/lib/browser/meta.json +1 -1
  10. package/dist/lib/browser/{react-surface-JMMCTIL3.mjs → react-surface-ZGQVH4VX.mjs} +11 -8
  11. package/dist/lib/browser/react-surface-ZGQVH4VX.mjs.map +7 -0
  12. package/dist/lib/browser/types/index.mjs +1 -1
  13. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts +1 -1
  14. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +1 -1
  15. package/dist/types/src/capabilities/react-surface/react-surface.d.ts +1 -1
  16. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +1 -1
  17. package/dist/types/src/components/PipelineColumn.d.ts +3 -4
  18. package/dist/types/src/components/PipelineColumn.d.ts.map +1 -1
  19. package/dist/types/src/components/PipelineComponent.d.ts +20 -11
  20. package/dist/types/src/components/PipelineComponent.d.ts.map +1 -1
  21. package/dist/types/src/components/PipelineComponent.stories.d.ts.map +1 -1
  22. package/dist/types/src/components/index.d.ts +2 -4
  23. package/dist/types/src/components/index.d.ts.map +1 -1
  24. package/dist/types/src/{components → containers/PipelineContainer}/PipelineContainer.d.ts +2 -3
  25. package/dist/types/src/containers/PipelineContainer/PipelineContainer.d.ts.map +1 -0
  26. package/dist/types/src/containers/PipelineContainer/PipelineContainer.stories.d.ts.map +1 -0
  27. package/dist/types/src/containers/PipelineContainer/index.d.ts +3 -0
  28. package/dist/types/src/containers/PipelineContainer/index.d.ts.map +1 -0
  29. package/dist/types/src/{components/PipelineSettings.d.ts → containers/PipelineObjectSettings/PipelineObjectSettings.d.ts} +1 -2
  30. package/dist/types/src/containers/PipelineObjectSettings/PipelineObjectSettings.d.ts.map +1 -0
  31. package/dist/types/src/containers/PipelineObjectSettings/index.d.ts +3 -0
  32. package/dist/types/src/containers/PipelineObjectSettings/index.d.ts.map +1 -0
  33. package/dist/types/src/containers/index.d.ts +4 -0
  34. package/dist/types/src/containers/index.d.ts.map +1 -0
  35. package/dist/types/src/hooks/index.d.ts +2 -0
  36. package/dist/types/src/hooks/index.d.ts.map +1 -0
  37. package/dist/types/src/hooks/usePipelineBoardModel.d.ts +6 -0
  38. package/dist/types/src/hooks/usePipelineBoardModel.d.ts.map +1 -0
  39. package/dist/types/src/templates/research.d.ts.map +1 -1
  40. package/dist/types/src/types/PipelineAction.d.ts +1 -1
  41. package/dist/types/tsconfig.tsbuildinfo +1 -1
  42. package/package.json +42 -39
  43. package/src/capabilities/operation-resolver/operation-resolver.ts +2 -2
  44. package/src/capabilities/react-surface/react-surface.tsx +7 -5
  45. package/src/components/PipelineColumn.tsx +24 -36
  46. package/src/components/PipelineComponent.stories.tsx +27 -14
  47. package/src/components/PipelineComponent.tsx +55 -27
  48. package/src/components/index.ts +2 -7
  49. package/src/{components → containers/PipelineContainer}/PipelineContainer.stories.tsx +91 -88
  50. package/src/containers/PipelineContainer/PipelineContainer.tsx +87 -0
  51. package/src/containers/PipelineContainer/index.ts +7 -0
  52. package/src/{components/PipelineSettings.tsx → containers/PipelineObjectSettings/PipelineObjectSettings.tsx} +65 -53
  53. package/src/containers/PipelineObjectSettings/index.ts +7 -0
  54. package/src/containers/index.ts +8 -0
  55. package/src/hooks/index.ts +5 -0
  56. package/src/hooks/usePipelineBoardModel.ts +79 -0
  57. package/src/templates/research.ts +14 -16
  58. package/src/types/PipelineAction.ts +1 -1
  59. package/dist/lib/browser/PipelineContainer-I3TPA7ZN.mjs +0 -217
  60. package/dist/lib/browser/PipelineContainer-I3TPA7ZN.mjs.map +0 -7
  61. package/dist/lib/browser/PipelineSettings-YSGSJHBT.mjs.map +0 -7
  62. package/dist/lib/browser/chunk-7GVESVYR.mjs.map +0 -7
  63. package/dist/lib/browser/react-surface-JMMCTIL3.mjs.map +0 -7
  64. package/dist/types/src/components/PipelineContainer.d.ts.map +0 -1
  65. package/dist/types/src/components/PipelineContainer.stories.d.ts.map +0 -1
  66. package/dist/types/src/components/PipelineSettings.d.ts.map +0 -1
  67. package/src/components/PipelineContainer.tsx +0 -57
  68. /package/dist/types/src/{components → containers/PipelineContainer}/PipelineContainer.stories.d.ts +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-pipeline",
3
- "version": "0.8.4-main.3eb6e50203",
3
+ "version": "0.8.4-main.c85a9c8dae",
4
4
  "description": "Pipeline plugin for Composer",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -40,32 +40,34 @@
40
40
  "@radix-ui/react-compose-refs": "1.1.1",
41
41
  "@radix-ui/react-context": "1.1.1",
42
42
  "effect": "3.19.16",
43
- "@dxos/app-framework": "0.8.4-main.3eb6e50203",
44
- "@dxos/async": "0.8.4-main.3eb6e50203",
45
- "@dxos/assistant-toolkit": "0.8.4-main.3eb6e50203",
46
- "@dxos/app-toolkit": "0.8.4-main.3eb6e50203",
47
- "@dxos/devtools": "0.8.4-main.3eb6e50203",
48
- "@dxos/echo": "0.8.4-main.3eb6e50203",
49
- "@dxos/echo-query": "0.8.4-main.3eb6e50203",
50
- "@dxos/log": "0.8.4-main.3eb6e50203",
51
- "@dxos/operation": "0.8.4-main.3eb6e50203",
52
- "@dxos/functions": "0.8.4-main.3eb6e50203",
53
- "@dxos/plugin-deck": "0.8.4-main.3eb6e50203",
54
- "@dxos/plugin-client": "0.8.4-main.3eb6e50203",
55
- "@dxos/plugin-graph": "0.8.4-main.3eb6e50203",
56
- "@dxos/plugin-space": "0.8.4-main.3eb6e50203",
57
- "@dxos/plugin-markdown": "0.8.4-main.3eb6e50203",
58
- "@dxos/react-ui-attention": "0.8.4-main.3eb6e50203",
59
- "@dxos/react-client": "0.8.4-main.3eb6e50203",
60
- "@dxos/plugin-inbox": "0.8.4-main.3eb6e50203",
61
- "@dxos/react-ui-components": "0.8.4-main.3eb6e50203",
62
- "@dxos/react-ui-form": "0.8.4-main.3eb6e50203",
63
- "@dxos/react-ui-list": "0.8.4-main.3eb6e50203",
64
- "@dxos/react-ui-mosaic": "0.8.4-main.3eb6e50203",
65
- "@dxos/react-ui-stack": "0.8.4-main.3eb6e50203",
66
- "@dxos/types": "0.8.4-main.3eb6e50203",
67
- "@dxos/schema": "0.8.4-main.3eb6e50203",
68
- "@dxos/util": "0.8.4-main.3eb6e50203"
43
+ "@dxos/assistant-toolkit": "0.8.4-main.c85a9c8dae",
44
+ "@dxos/app-framework": "0.8.4-main.c85a9c8dae",
45
+ "@dxos/devtools": "0.8.4-main.c85a9c8dae",
46
+ "@dxos/echo": "0.8.4-main.c85a9c8dae",
47
+ "@dxos/echo-atom": "0.8.4-main.c85a9c8dae",
48
+ "@dxos/echo-query": "0.8.4-main.c85a9c8dae",
49
+ "@dxos/async": "0.8.4-main.c85a9c8dae",
50
+ "@dxos/functions": "0.8.4-main.c85a9c8dae",
51
+ "@dxos/log": "0.8.4-main.c85a9c8dae",
52
+ "@dxos/plugin-client": "0.8.4-main.c85a9c8dae",
53
+ "@dxos/operation": "0.8.4-main.c85a9c8dae",
54
+ "@dxos/plugin-deck": "0.8.4-main.c85a9c8dae",
55
+ "@dxos/plugin-graph": "0.8.4-main.c85a9c8dae",
56
+ "@dxos/plugin-inbox": "0.8.4-main.c85a9c8dae",
57
+ "@dxos/plugin-markdown": "0.8.4-main.c85a9c8dae",
58
+ "@dxos/plugin-space": "0.8.4-main.c85a9c8dae",
59
+ "@dxos/react-client": "0.8.4-main.c85a9c8dae",
60
+ "@dxos/react-ui-attention": "0.8.4-main.c85a9c8dae",
61
+ "@dxos/react-ui-components": "0.8.4-main.c85a9c8dae",
62
+ "@dxos/react-ui-form": "0.8.4-main.c85a9c8dae",
63
+ "@dxos/react-ui-menu": "0.8.4-main.c85a9c8dae",
64
+ "@dxos/react-ui-mosaic": "0.8.4-main.c85a9c8dae",
65
+ "@dxos/react-ui-list": "0.8.4-main.c85a9c8dae",
66
+ "@dxos/react-ui-stack": "0.8.4-main.c85a9c8dae",
67
+ "@dxos/app-toolkit": "0.8.4-main.c85a9c8dae",
68
+ "@dxos/schema": "0.8.4-main.c85a9c8dae",
69
+ "@dxos/types": "0.8.4-main.c85a9c8dae",
70
+ "@dxos/util": "0.8.4-main.c85a9c8dae"
69
71
  },
70
72
  "devDependencies": {
71
73
  "@effect-atom/atom-react": "^0.5.0",
@@ -73,24 +75,25 @@
73
75
  "@types/react-dom": "~19.2.3",
74
76
  "react": "~19.2.3",
75
77
  "react-dom": "~19.2.3",
76
- "vite": "7.1.9",
77
- "@dxos/plugin-inbox": "0.8.4-main.3eb6e50203",
78
- "@dxos/plugin-attention": "0.8.4-main.3eb6e50203",
79
- "@dxos/plugin-preview": "0.8.4-main.3eb6e50203",
80
- "@dxos/plugin-testing": "0.8.4-main.3eb6e50203",
81
- "@dxos/plugin-theme": "0.8.4-main.3eb6e50203",
82
- "@dxos/storybook-utils": "0.8.4-main.3eb6e50203",
83
- "@dxos/random": "0.8.4-main.3eb6e50203",
84
- "@dxos/react-ui": "0.8.4-main.3eb6e50203",
85
- "@dxos/ui-theme": "0.8.4-main.3eb6e50203"
78
+ "vite": "^7.1.11",
79
+ "@dxos/plugin-preview": "0.8.4-main.c85a9c8dae",
80
+ "@dxos/plugin-inbox": "0.8.4-main.c85a9c8dae",
81
+ "@dxos/plugin-testing": "0.8.4-main.c85a9c8dae",
82
+ "@dxos/plugin-theme": "0.8.4-main.c85a9c8dae",
83
+ "@dxos/random": "0.8.4-main.c85a9c8dae",
84
+ "@dxos/react-ui": "0.8.4-main.c85a9c8dae",
85
+ "@dxos/ui-theme": "0.8.4-main.c85a9c8dae",
86
+ "@dxos/echo-db": "0.8.4-main.c85a9c8dae",
87
+ "@dxos/storybook-utils": "0.8.4-main.c85a9c8dae",
88
+ "@dxos/plugin-attention": "0.8.4-main.c85a9c8dae"
86
89
  },
87
90
  "peerDependencies": {
88
91
  "@effect-atom/atom-react": "^0.5.0",
89
92
  "effect": "3.19.16",
90
93
  "react": "~19.2.3",
91
94
  "react-dom": "~19.2.3",
92
- "@dxos/react-ui": "0.8.4-main.3eb6e50203",
93
- "@dxos/ui-theme": "0.8.4-main.3eb6e50203"
95
+ "@dxos/react-ui": "0.8.4-main.c85a9c8dae",
96
+ "@dxos/ui-theme": "0.8.4-main.c85a9c8dae"
94
97
  },
95
98
  "publishConfig": {
96
99
  "access": "public"
@@ -7,7 +7,7 @@ import * as Effect from 'effect/Effect';
7
7
  import { Capabilities, Capability } from '@dxos/app-framework';
8
8
  import { Obj, Ref, Type } from '@dxos/echo';
9
9
  import { OperationResolver } from '@dxos/operation';
10
- import { Collection } from '@dxos/schema';
10
+ import { ManagedCollection } from '@dxos/schema';
11
11
  import { Pipeline } from '@dxos/types';
12
12
 
13
13
  import { PipelineOperation } from '../../types';
@@ -18,7 +18,7 @@ export default Capability.makeModule(() =>
18
18
  OperationResolver.make({
19
19
  operation: PipelineOperation.OnCreateSpace,
20
20
  handler: Effect.fnUntraced(function* ({ rootCollection }) {
21
- const collection = Collection.makeManaged({ key: Type.getTypename(Pipeline.Pipeline) });
21
+ const collection = ManagedCollection.makeManagedCollection({ key: Type.getTypename(Pipeline.Pipeline) });
22
22
  Obj.change(rootCollection, (c) => {
23
23
  c.objects.push(Ref.make(collection));
24
24
  });
@@ -9,10 +9,10 @@ import { Capabilities, Capability } from '@dxos/app-framework';
9
9
  import { Surface } from '@dxos/app-framework/ui';
10
10
  import { InvocationTraceContainer } from '@dxos/devtools';
11
11
  import { Obj } from '@dxos/echo';
12
- import { Layout } from '@dxos/react-ui';
12
+ import { Panel } from '@dxos/react-ui';
13
13
  import { Pipeline } from '@dxos/types';
14
14
 
15
- import { PipelineContainer, PipelineObjectSettings } from '../../components';
15
+ import { PipelineContainer, PipelineObjectSettings } from '../../containers';
16
16
  import { meta } from '../../meta';
17
17
 
18
18
  export default Capability.makeModule(() =>
@@ -33,9 +33,11 @@ export default Capability.makeModule(() =>
33
33
  const db = Obj.getDatabase(data.companionTo);
34
34
  // TODO(wittjosiah): Filter the invocations to those relevant to the project.
35
35
  return (
36
- <Layout.Main role={role}>
37
- <InvocationTraceContainer db={db} detailAxis='block' />
38
- </Layout.Main>
36
+ <Panel.Root role={role} className='dx-article'>
37
+ <Panel.Content asChild>
38
+ <InvocationTraceContainer db={db} detailAxis='block' />
39
+ </Panel.Content>
40
+ </Panel.Root>
39
41
  );
40
42
  },
41
43
  }),
@@ -6,11 +6,13 @@ import { useComposedRefs } from '@radix-ui/react-compose-refs';
6
6
  import type * as Schema from 'effect/Schema';
7
7
  import React, { forwardRef, useMemo, useRef, useState } from 'react';
8
8
 
9
- import { Obj, Query, Type } from '@dxos/echo';
10
- import { getQueryTarget, resolveSchemaWithRegistry } from '@dxos/plugin-space';
11
- import { Filter, getSpace, isSpace, useObject, useQuery } from '@dxos/react-client/echo';
12
- import { ScrollArea, useAsyncEffect, useTranslation } from '@dxos/react-ui';
13
- import { Card, Focus, Mosaic, type MosaicTileProps } from '@dxos/react-ui-mosaic';
9
+ import { useObjectNavigate } from '@dxos/app-toolkit/ui';
10
+ import { JsonSchema, Obj, Query, Type } from '@dxos/echo';
11
+ import { resolveSchemaWithRegistry } from '@dxos/plugin-space';
12
+ import { Filter, getSpace, useObject } from '@dxos/react-client/echo';
13
+ import { useAsyncEffect, useTranslation } from '@dxos/react-ui';
14
+ import { Card } from '@dxos/react-ui';
15
+ import { Board, Focus, Mosaic, type MosaicTileProps } from '@dxos/react-ui-mosaic';
14
16
  import { ProjectionModel, createEchoChangeCallback } from '@dxos/schema';
15
17
  import { type Pipeline } from '@dxos/types';
16
18
 
@@ -24,15 +26,12 @@ import { type ItemProps, usePipeline } from './PipelineComponent';
24
26
 
25
27
  const PIPELINE_COLUMN_NAME = 'PipelineColumn';
26
28
 
27
- export type PipelineColumnProps = {
28
- column: Pipeline.Column;
29
- };
29
+ export type PipelineColumnProps = Pick<MosaicTileProps<Pipeline.Column>, 'classNames' | 'location' | 'data' | 'debug'>;
30
30
 
31
- // TODO(thure): Duplicates a lot of the same boilerplate as Kanban columns; is there an opportunity to DRY these out?
32
- // TODO(wittjosiah): Support column DnD reordering.
33
31
  // TODO(wittjosiah): Support item DnD reordering (ordering needs to be stored on the view presentation collection).
34
- export const PipelineColumn = ({ column }: PipelineColumnProps) => {
32
+ export const PipelineColumn = ({ data: column, location, classNames, debug }: PipelineColumnProps) => {
35
33
  const { t } = useTranslation(meta.id);
34
+ const dragHandleRef = useRef<HTMLButtonElement>(null);
36
35
  // Subscribe to the view target for reactivity.
37
36
  const [viewSnapshot] = useObject(column.view);
38
37
  const view = column.view.target;
@@ -50,7 +49,7 @@ export const PipelineColumn = ({ column }: PipelineColumnProps) => {
50
49
  }, [JSON.stringify(viewSnapshot?.query.ast)]);
51
50
 
52
51
  useAsyncEffect(async () => {
53
- if (!query || !space) {
52
+ if (!query || !space?.db) {
54
53
  return;
55
54
  }
56
55
 
@@ -58,19 +57,13 @@ export const PipelineColumn = ({ column }: PipelineColumnProps) => {
58
57
  setSchema(() => schema);
59
58
  }, [space, query]);
60
59
 
61
- const queryTarget = getQueryTarget(query.ast, space);
62
- const items = useQuery(queryTarget, query);
63
- const sortedItems = useMemo(() => {
64
- // TODO(burdon): Hack to reverse queue.
65
- return isSpace(queryTarget) ? items : [...items.reverse()];
66
- }, [queryTarget, items]);
67
60
  const projectionModel = useMemo(() => {
68
61
  if (!schema || !view) {
69
62
  return undefined;
70
63
  }
71
64
 
72
65
  // For mutable schemas (EchoSchema), use the live jsonSchema reference for reactivity.
73
- const jsonSchema = Type.isMutable(schema) ? schema.jsonSchema : Type.toJsonSchema(schema);
66
+ const jsonSchema = Type.isMutable(schema) ? schema.jsonSchema : JsonSchema.toJsonSchema(schema);
74
67
  const change = createEchoChangeCallback(view, Type.isMutable(schema) ? schema : undefined);
75
68
  return new ProjectionModel({ view, baseSchema: jsonSchema, change });
76
69
  }, [schema, view]);
@@ -86,22 +79,16 @@ export const PipelineColumn = ({ column }: PipelineColumnProps) => {
86
79
  }
87
80
 
88
81
  return (
89
- <Focus.Group asChild>
90
- <div className='grid bs-full card-default-width overflow-hidden grid-rows-[min-content_1fr] density-fine border border-separator rounded-md bg-deckSurface'>
91
- <Card.Toolbar>
92
- <Card.DragHandle />
93
- <Card.Title>{column.name ?? t('untitled view title')}</Card.Title>
94
- <Card.Menu />
95
- </Card.Toolbar>
96
- <Mosaic.Container asChild orientation='vertical' withFocus>
97
- <ScrollArea.Root orientation='vertical'>
98
- <ScrollArea.Viewport classNames='p-2'>
99
- <Mosaic.Stack orientation='vertical' items={sortedItems} getId={(item) => item.id} Tile={Tile} />
100
- </ScrollArea.Viewport>
101
- </ScrollArea.Root>
102
- </Mosaic.Container>
103
- </div>
104
- </Focus.Group>
82
+ <Board.Column.Root
83
+ data={column}
84
+ location={location}
85
+ classNames={['group/column grid h-full overflow-hidden grid-rows-[var(--dx-rail-action)_1fr]', classNames]}
86
+ debug={debug}
87
+ dragHandleRef={dragHandleRef}
88
+ >
89
+ <Board.Column.Header label={column.name ?? t('untitled view title')} dragHandleRef={dragHandleRef} />
90
+ <Board.Column.Body data={column} Tile={Tile} />
91
+ </Board.Column.Root>
105
92
  );
106
93
  };
107
94
 
@@ -122,6 +109,7 @@ const ItemTile = forwardRef<HTMLDivElement, ItemTileProps>(
122
109
  const rootRef = useRef<HTMLDivElement>(null);
123
110
  const composedRef = useComposedRefs<HTMLDivElement>(rootRef, forwardedRef);
124
111
  const { Item } = usePipeline(ITEM_TILE_NAME);
112
+ const handleNavigate = useObjectNavigate(data);
125
113
 
126
114
  return (
127
115
  <Mosaic.Tile asChild id={data.id} data={data} location={location} debug={debug}>
@@ -129,7 +117,7 @@ const ItemTile = forwardRef<HTMLDivElement, ItemTileProps>(
129
117
  <Card.Root classNames={classNames} ref={composedRef}>
130
118
  <Card.Toolbar>
131
119
  <Card.DragHandle />
132
- <Card.Title>{Obj.getLabel(data)}</Card.Title>
120
+ <Card.Title onClick={handleNavigate}>{Obj.getLabel(data)}</Card.Title>
133
121
  <Card.Menu />
134
122
  </Card.Toolbar>
135
123
  <Card.Content>
@@ -2,28 +2,32 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
+ import { RegistryContext } from '@effect-atom/atom-react';
5
6
  import { type Meta, type StoryObj } from '@storybook/react-vite';
6
- import React, { useCallback, useEffect } from 'react';
7
+ import React, { useCallback, useContext, useEffect } from 'react';
7
8
 
8
9
  import { Filter, Ref } from '@dxos/client/echo';
9
- import { Obj, Query, Type } from '@dxos/echo';
10
+ import { JsonSchema, Obj, Query } from '@dxos/echo';
11
+ import { Collection, View } from '@dxos/echo';
10
12
  import { faker } from '@dxos/random';
11
13
  import { useQuery } from '@dxos/react-client/echo';
12
14
  import { useClientStory, withClientProvider } from '@dxos/react-client/testing';
13
15
  import { withLayout, withTheme } from '@dxos/react-ui/testing';
14
16
  import { Form, omitId } from '@dxos/react-ui-form';
15
17
  import { withMosaic } from '@dxos/react-ui-mosaic/testing';
16
- import { Collection, View } from '@dxos/schema';
18
+ import { ViewModel } from '@dxos/schema';
17
19
  import { createObjectFactory } from '@dxos/schema/testing';
20
+ import { withRegistry } from '@dxos/storybook-utils';
18
21
  import { Person, Pipeline } from '@dxos/types';
19
22
 
23
+ import { usePipelineBoardModel } from '../hooks';
20
24
  import { translations } from '../translations';
21
25
 
22
- import { type ItemProps, PipelineComponent as PipelineComponent } from './PipelineComponent';
26
+ import { type ItemProps, PipelineComponent } from './PipelineComponent';
23
27
 
24
28
  const StorybookProjectItem = ({ item, projectionModel }: ItemProps) => {
25
29
  if (Obj.instanceOf(Person.Person, item)) {
26
- const contact = item as Obj.Obj<Person.Person>;
30
+ const contact = item as Obj.OfShape<Person.Person>;
27
31
 
28
32
  return (
29
33
  <Form.Root schema={omitId(Person.Person)} projection={projectionModel} values={contact} autoSave>
@@ -40,9 +44,11 @@ const StorybookProjectItem = ({ item, projectionModel }: ItemProps) => {
40
44
  };
41
45
 
42
46
  const DefaultStory = () => {
47
+ const registry = useContext(RegistryContext);
43
48
  const { space } = useClientStory();
44
49
  const pipelines = useQuery(space?.db, Filter.type(Pipeline.Pipeline));
45
50
  const pipeline = pipelines[0];
51
+ const model = usePipelineBoardModel(pipeline, registry);
46
52
 
47
53
  const handleAddColumn = useCallback(() => {
48
54
  if (!space || !pipeline) {
@@ -50,9 +56,9 @@ const DefaultStory = () => {
50
56
  }
51
57
 
52
58
  // Create a new view for contacts similar to the initialization.
53
- const view = View.make({
59
+ const view = ViewModel.make({
54
60
  query: Query.select(Filter.type(Person.Person)),
55
- jsonSchema: Type.toJsonSchema(Person.Person),
61
+ jsonSchema: JsonSchema.toJsonSchema(Person.Person),
56
62
  fields: ['fullName'],
57
63
  });
58
64
 
@@ -73,16 +79,20 @@ const DefaultStory = () => {
73
79
 
74
80
  return (
75
81
  <PipelineComponent.Root Item={StorybookProjectItem} onAddColumn={handleAddColumn}>
76
- <PipelineComponent.Content pipeline={pipeline} />
82
+ <PipelineComponent.Content model={model}>
83
+ <PipelineComponent.Columns pipeline={pipeline} />
84
+ </PipelineComponent.Content>
77
85
  </PipelineComponent.Root>
78
86
  );
79
87
  };
80
88
 
81
89
  const MutationsStory = () => {
90
+ const registry = useContext(RegistryContext);
82
91
  const { space } = useClientStory();
83
92
  const pipelines = useQuery(space?.db, Filter.type(Pipeline.Pipeline));
84
93
  const contacts = useQuery(space?.db, Filter.type(Person.Person));
85
94
  const pipeline = pipelines[0];
95
+ const model = usePipelineBoardModel(pipeline, registry);
86
96
 
87
97
  const handleAddColumn = useCallback(() => {
88
98
  if (!space || !pipeline) {
@@ -90,9 +100,9 @@ const MutationsStory = () => {
90
100
  }
91
101
 
92
102
  // Create a new view for contacts similar to the initialization.
93
- const view = View.make({
103
+ const view = ViewModel.make({
94
104
  query: Query.select(Filter.type(Person.Person)),
95
- jsonSchema: Type.toJsonSchema(Person.Person),
105
+ jsonSchema: JsonSchema.toJsonSchema(Person.Person),
96
106
  fields: ['fullName'],
97
107
  });
98
108
 
@@ -142,16 +152,19 @@ const MutationsStory = () => {
142
152
 
143
153
  return (
144
154
  <PipelineComponent.Root Item={StorybookProjectItem} onAddColumn={handleAddColumn}>
145
- <PipelineComponent.Content pipeline={pipeline} />
155
+ <PipelineComponent.Content model={model}>
156
+ <PipelineComponent.Columns pipeline={pipeline} />
157
+ </PipelineComponent.Content>
146
158
  </PipelineComponent.Root>
147
159
  );
148
160
  };
149
161
 
150
162
  const meta = {
151
- title: 'plugins/plugin-pipeline/PipelineComponent',
163
+ title: 'plugins/plugin-pipeline/components/PipelineComponent',
152
164
  decorators: [
153
165
  withTheme(),
154
166
  withLayout({ layout: 'column' }),
167
+ withRegistry,
155
168
  withMosaic(),
156
169
  withClientProvider({
157
170
  types: [Pipeline.Pipeline, View.View, Collection.Collection, Person.Person],
@@ -159,10 +172,10 @@ const meta = {
159
172
  createSpace: true,
160
173
  onCreateSpace: async ({ space }) => {
161
174
  // Create a view for contacts.
162
- const view = View.make({
175
+ const view = ViewModel.make({
163
176
  name: 'Contacts',
164
177
  query: Query.select(Filter.type(Person.Person)),
165
- jsonSchema: Type.toJsonSchema(Person.Person),
178
+ jsonSchema: JsonSchema.toJsonSchema(Person.Person),
166
179
  fields: ['fullName'],
167
180
  });
168
181
 
@@ -2,15 +2,15 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
+ import { useAtomValue } from '@effect-atom/atom-react';
5
6
  import { createContext } from '@radix-ui/react-context';
6
- import React, { type FC } from 'react';
7
+ import React, { type FC, type PropsWithChildren } from 'react';
7
8
 
8
- import { type Obj } from '@dxos/echo';
9
- import { useObject } from '@dxos/react-client/echo';
9
+ import { Obj } from '@dxos/echo';
10
10
  import { Toolbar, type ToolbarRootProps, useTranslation } from '@dxos/react-ui';
11
- import { Stack } from '@dxos/react-ui-stack';
11
+ import { Board, type BoardModel, useBoard, useEventHandlerAdapter } from '@dxos/react-ui-mosaic';
12
12
  import { type ProjectionModel } from '@dxos/schema';
13
- import { type Pipeline as PipelineType } from '@dxos/types';
13
+ import { type Pipeline } from '@dxos/types';
14
14
 
15
15
  import { meta } from '../meta';
16
16
 
@@ -23,26 +23,30 @@ type ItemProps = {
23
23
 
24
24
  const itemNoOp = ({ item }: ItemProps) => <span>{item.id}</span>;
25
25
 
26
+ //
27
+ // Root
28
+ //
29
+
26
30
  type PipelineContextValue = {
27
31
  Item: FC<ItemProps>;
28
32
  // TODO(wittjosiah): Support adding items.
29
- // If the created item doesn't match the current query, it will not be visible.
30
- // onAddItem?: (schema: Schema.Schema.AnyNoContext) => void;
33
+ // If the created item doesn't match the current query, it will not be visible.
34
+ // TODO(wittjosiah): onAddItem?: (schema: Schema.Schema.AnyNoContext) => void;
31
35
  onAddColumn?: () => void;
32
36
  };
33
37
 
34
- //
35
- // Root
36
- //
37
-
38
- type PipelineRootProps = PipelineContextValue;
38
+ type PipelineRootProps = PropsWithChildren<PipelineContextValue>;
39
39
 
40
40
  const PIPELINE_ROOT = 'Pipeline.Root';
41
41
 
42
- const [PipelineRoot, usePipeline] = createContext<PipelineContextValue>(PIPELINE_ROOT, {
42
+ const [PipelineRootContext, usePipeline] = createContext<PipelineContextValue>(PIPELINE_ROOT, {
43
43
  Item: itemNoOp,
44
44
  });
45
45
 
46
+ const PipelineRoot = ({ children, ...contextValue }: PipelineRootProps) => (
47
+ <PipelineRootContext {...contextValue}>{children}</PipelineRootContext>
48
+ );
49
+
46
50
  PipelineRoot.displayName = PIPELINE_ROOT;
47
51
 
48
52
  //
@@ -51,23 +55,46 @@ PipelineRoot.displayName = PIPELINE_ROOT;
51
55
 
52
56
  const PIPELINE_CONTENT_NAME = 'Pipeline.Content';
53
57
 
54
- type PipelineContentProps = {
55
- pipeline: PipelineType.Pipeline;
56
- };
58
+ type PipelineContentProps = PropsWithChildren<{
59
+ model: BoardModel<Pipeline.Column, Obj.Unknown>;
60
+ }>;
57
61
 
58
- const PipelineContent = ({ pipeline }: PipelineContentProps) => {
59
- const [columns] = useObject(pipeline, 'columns');
62
+ const PipelineContent = ({ model, children, ...props }: PipelineContentProps) => (
63
+ <Board.Root {...props} model={model}>
64
+ {children}
65
+ </Board.Root>
66
+ );
60
67
 
61
- return (
62
- <Stack orientation='horizontal' size='contain' rail={false}>
63
- {columns.map((column) => {
64
- return <PipelineColumn key={column.view.dxn.toString()} column={column} />;
65
- })}
66
- </Stack>
67
- );
68
+ PipelineContent.displayName = PIPELINE_CONTENT_NAME;
69
+
70
+ //
71
+ // Columns
72
+ //
73
+
74
+ const PIPELINE_COLUMNS_NAME = 'Pipeline.Columns';
75
+
76
+ type PipelineColumnsProps = {
77
+ pipeline: Pipeline.Pipeline;
68
78
  };
69
79
 
70
- PipelineContent.displayName = PIPELINE_CONTENT_NAME;
80
+ const PipelineColumns = ({ pipeline }: PipelineColumnsProps) => {
81
+ const { model } = useBoard(PIPELINE_COLUMNS_NAME);
82
+ const columns = useAtomValue(model.columns);
83
+ const eventHandler = useEventHandlerAdapter<Pipeline.Column, Obj.Unknown>({
84
+ id: pipeline.id,
85
+ // TODO(wittjosiah): Cast because columns array is readonly.
86
+ items: columns as any,
87
+ getId: model.getColumnId,
88
+ get: (data) => data as unknown as Obj.Unknown,
89
+ make: (object) => object as unknown as Pipeline.Column,
90
+ canDrop: ({ source }) => model.isColumn(source.data),
91
+ onChange: (mutate) => Obj.change(pipeline, (p) => mutate(p.columns)),
92
+ });
93
+
94
+ return <Board.Content id='pipeline' eventHandler={eventHandler} Tile={PipelineColumn} />;
95
+ };
96
+
97
+ PipelineColumns.displayName = PIPELINE_COLUMNS_NAME;
71
98
 
72
99
  //
73
100
  // Toolbar
@@ -95,9 +122,10 @@ PipelineToolbar.displayName = PIPELINE_TOOLBAR_NAME;
95
122
  export const PipelineComponent = {
96
123
  Root: PipelineRoot,
97
124
  Content: PipelineContent,
125
+ Columns: PipelineColumns,
98
126
  Toolbar: PipelineToolbar,
99
127
  };
100
128
 
101
129
  export { usePipeline };
102
130
 
103
- export type { ItemProps, PipelineContextValue, PipelineRootProps };
131
+ export type { ItemProps, PipelineContextValue, PipelineRootProps, PipelineContentProps, PipelineColumnsProps };
@@ -2,10 +2,5 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { lazy } from 'react';
6
-
7
- export type { PipelineContainerProps } from './PipelineContainer';
8
- export type { PipelineObjectSettingsProps } from './PipelineSettings';
9
-
10
- export const PipelineContainer = lazy(() => import('./PipelineContainer'));
11
- export const PipelineObjectSettings = lazy(() => import('./PipelineSettings'));
5
+ export * from './PipelineColumn';
6
+ export * from './PipelineComponent';