@dxos/plugin-pipeline 0.8.3-main.ef1bc66f44 → 0.8.4-main.2244d791bb
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.
- package/dist/lib/browser/{PipelineContainer-TRO66W6L.mjs → PipelineContainer-2BRZPECS.mjs} +126 -53
- package/dist/lib/browser/PipelineContainer-2BRZPECS.mjs.map +7 -0
- package/dist/lib/browser/{PipelineSettings-EBR3UU5C.mjs → PipelineSettings-R54RTVWZ.mjs} +41 -32
- package/dist/lib/browser/PipelineSettings-R54RTVWZ.mjs.map +7 -0
- package/dist/lib/browser/{app-graph-builder-NKUZQ6A7.mjs → app-graph-builder-NUJB33F7.mjs} +8 -7
- package/dist/lib/browser/app-graph-builder-NUJB33F7.mjs.map +7 -0
- package/dist/lib/browser/{chunk-XDHJKK7D.mjs → chunk-7GVESVYR.mjs} +2 -2
- package/dist/lib/browser/{chunk-J5YNPKHT.mjs → chunk-QWNKLHBY.mjs} +3 -3
- package/dist/lib/browser/{chunk-J5YNPKHT.mjs.map → chunk-QWNKLHBY.mjs.map} +1 -1
- package/dist/lib/browser/index.mjs +30 -29
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-surface-CH2SUJTQ.mjs → react-surface-CMTEEE6F.mjs} +11 -10
- package/dist/lib/browser/react-surface-CMTEEE6F.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +2 -2
- package/dist/types/src/PipelinePlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +2 -2
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface/index.d.ts +1 -1
- package/dist/types/src/capabilities/react-surface/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts +2 -2
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +1 -1
- package/dist/types/src/components/PipelineColumn.d.ts +3 -4
- package/dist/types/src/components/PipelineColumn.d.ts.map +1 -1
- package/dist/types/src/components/PipelineComponent.d.ts +13 -7
- package/dist/types/src/components/PipelineComponent.d.ts.map +1 -1
- package/dist/types/src/components/PipelineComponent.stories.d.ts +11 -11
- package/dist/types/src/components/PipelineComponent.stories.d.ts.map +1 -1
- package/dist/types/src/components/PipelineContainer.d.ts +1 -1
- package/dist/types/src/components/PipelineContainer.d.ts.map +1 -1
- package/dist/types/src/components/PipelineContainer.stories.d.ts +11 -11
- package/dist/types/src/components/PipelineContainer.stories.d.ts.map +1 -1
- package/dist/types/src/components/PipelineSettings.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +11 -11
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +39 -38
- package/src/components/PipelineColumn.tsx +32 -32
- package/src/components/PipelineComponent.stories.tsx +11 -4
- package/src/components/PipelineComponent.tsx +100 -17
- package/src/components/PipelineContainer.stories.tsx +5 -5
- package/src/components/PipelineContainer.tsx +6 -2
- package/src/components/PipelineSettings.tsx +35 -30
- package/dist/lib/browser/PipelineContainer-TRO66W6L.mjs.map +0 -7
- package/dist/lib/browser/PipelineSettings-EBR3UU5C.mjs.map +0 -7
- package/dist/lib/browser/app-graph-builder-NKUZQ6A7.mjs.map +0 -7
- package/dist/lib/browser/react-surface-CH2SUJTQ.mjs.map +0 -7
- /package/dist/lib/browser/{chunk-XDHJKK7D.mjs.map → chunk-7GVESVYR.mjs.map} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/plugin-pipeline",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.4-main.2244d791bb",
|
|
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,33 @@
|
|
|
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-toolkit": "0.8.
|
|
44
|
-
"@dxos/
|
|
45
|
-
"@dxos/
|
|
46
|
-
"@dxos/
|
|
47
|
-
"@dxos/echo": "0.8.
|
|
48
|
-
"@dxos/
|
|
49
|
-
"@dxos/
|
|
50
|
-
"@dxos/
|
|
51
|
-
"@dxos/
|
|
52
|
-
"@dxos/
|
|
53
|
-
"@dxos/plugin-
|
|
54
|
-
"@dxos/plugin-
|
|
55
|
-
"@dxos/plugin-
|
|
56
|
-
"@dxos/
|
|
57
|
-
"@dxos/
|
|
58
|
-
"@dxos/
|
|
59
|
-
"@dxos/react-ui-
|
|
60
|
-
"@dxos/react-
|
|
61
|
-
"@dxos/react-ui-
|
|
62
|
-
"@dxos/
|
|
63
|
-
"@dxos/
|
|
64
|
-
"@dxos/
|
|
65
|
-
"@dxos/react-ui-
|
|
66
|
-
"@dxos/
|
|
67
|
-
"@dxos/
|
|
68
|
-
"@dxos/types": "0.8.
|
|
43
|
+
"@dxos/app-toolkit": "0.8.4-main.2244d791bb",
|
|
44
|
+
"@dxos/app-framework": "0.8.4-main.2244d791bb",
|
|
45
|
+
"@dxos/assistant-toolkit": "0.8.4-main.2244d791bb",
|
|
46
|
+
"@dxos/async": "0.8.4-main.2244d791bb",
|
|
47
|
+
"@dxos/echo-atom": "0.8.4-main.2244d791bb",
|
|
48
|
+
"@dxos/echo": "0.8.4-main.2244d791bb",
|
|
49
|
+
"@dxos/echo-query": "0.8.4-main.2244d791bb",
|
|
50
|
+
"@dxos/devtools": "0.8.4-main.2244d791bb",
|
|
51
|
+
"@dxos/log": "0.8.4-main.2244d791bb",
|
|
52
|
+
"@dxos/operation": "0.8.4-main.2244d791bb",
|
|
53
|
+
"@dxos/plugin-client": "0.8.4-main.2244d791bb",
|
|
54
|
+
"@dxos/plugin-deck": "0.8.4-main.2244d791bb",
|
|
55
|
+
"@dxos/plugin-graph": "0.8.4-main.2244d791bb",
|
|
56
|
+
"@dxos/plugin-inbox": "0.8.4-main.2244d791bb",
|
|
57
|
+
"@dxos/plugin-markdown": "0.8.4-main.2244d791bb",
|
|
58
|
+
"@dxos/functions": "0.8.4-main.2244d791bb",
|
|
59
|
+
"@dxos/react-ui-attention": "0.8.4-main.2244d791bb",
|
|
60
|
+
"@dxos/react-client": "0.8.4-main.2244d791bb",
|
|
61
|
+
"@dxos/react-ui-components": "0.8.4-main.2244d791bb",
|
|
62
|
+
"@dxos/plugin-space": "0.8.4-main.2244d791bb",
|
|
63
|
+
"@dxos/react-ui-form": "0.8.4-main.2244d791bb",
|
|
64
|
+
"@dxos/react-ui-list": "0.8.4-main.2244d791bb",
|
|
65
|
+
"@dxos/react-ui-stack": "0.8.4-main.2244d791bb",
|
|
66
|
+
"@dxos/react-ui-mosaic": "0.8.4-main.2244d791bb",
|
|
67
|
+
"@dxos/schema": "0.8.4-main.2244d791bb",
|
|
68
|
+
"@dxos/types": "0.8.4-main.2244d791bb",
|
|
69
|
+
"@dxos/util": "0.8.4-main.2244d791bb"
|
|
69
70
|
},
|
|
70
71
|
"devDependencies": {
|
|
71
72
|
"@effect-atom/atom-react": "^0.5.0",
|
|
@@ -74,23 +75,23 @@
|
|
|
74
75
|
"react": "~19.2.3",
|
|
75
76
|
"react-dom": "~19.2.3",
|
|
76
77
|
"vite": "7.1.9",
|
|
77
|
-
"@dxos/plugin-
|
|
78
|
-
"@dxos/plugin-
|
|
79
|
-
"@dxos/plugin-
|
|
80
|
-
"@dxos/plugin-testing": "0.8.
|
|
81
|
-
"@dxos/
|
|
82
|
-
"@dxos/
|
|
83
|
-
"@dxos/
|
|
84
|
-
"@dxos/ui
|
|
85
|
-
"@dxos/
|
|
78
|
+
"@dxos/plugin-attention": "0.8.4-main.2244d791bb",
|
|
79
|
+
"@dxos/plugin-preview": "0.8.4-main.2244d791bb",
|
|
80
|
+
"@dxos/plugin-inbox": "0.8.4-main.2244d791bb",
|
|
81
|
+
"@dxos/plugin-testing": "0.8.4-main.2244d791bb",
|
|
82
|
+
"@dxos/plugin-theme": "0.8.4-main.2244d791bb",
|
|
83
|
+
"@dxos/storybook-utils": "0.8.4-main.2244d791bb",
|
|
84
|
+
"@dxos/random": "0.8.4-main.2244d791bb",
|
|
85
|
+
"@dxos/react-ui": "0.8.4-main.2244d791bb",
|
|
86
|
+
"@dxos/ui-theme": "0.8.4-main.2244d791bb"
|
|
86
87
|
},
|
|
87
88
|
"peerDependencies": {
|
|
88
89
|
"@effect-atom/atom-react": "^0.5.0",
|
|
89
90
|
"effect": "3.19.16",
|
|
90
91
|
"react": "~19.2.3",
|
|
91
92
|
"react-dom": "~19.2.3",
|
|
92
|
-
"@dxos/react-ui": "0.8.
|
|
93
|
-
"@dxos/ui-theme": "0.8.
|
|
93
|
+
"@dxos/react-ui": "0.8.4-main.2244d791bb",
|
|
94
|
+
"@dxos/ui-theme": "0.8.4-main.2244d791bb"
|
|
94
95
|
},
|
|
95
96
|
"publishConfig": {
|
|
96
97
|
"access": "public"
|
|
@@ -2,17 +2,19 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { useAtomValue } from '@effect-atom/atom-react';
|
|
5
6
|
import { useComposedRefs } from '@radix-ui/react-compose-refs';
|
|
6
7
|
import type * as Schema from 'effect/Schema';
|
|
7
8
|
import React, { forwardRef, useMemo, useRef, useState } from 'react';
|
|
8
9
|
|
|
9
10
|
import { Obj, Query, Type } from '@dxos/echo';
|
|
10
|
-
import {
|
|
11
|
-
import { Filter, getSpace,
|
|
12
|
-
import {
|
|
13
|
-
import { Card, Focus, Mosaic, type MosaicTileProps } from '@dxos/react-ui-mosaic';
|
|
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 { Board, Card, Focus, Mosaic, type MosaicTileProps, useBoard } from '@dxos/react-ui-mosaic';
|
|
14
15
|
import { ProjectionModel, createEchoChangeCallback } from '@dxos/schema';
|
|
15
16
|
import { type Pipeline } from '@dxos/types';
|
|
17
|
+
import { mx } from '@dxos/ui-theme';
|
|
16
18
|
|
|
17
19
|
import { meta } from '../meta';
|
|
18
20
|
|
|
@@ -24,15 +26,13 @@ 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 { model } = useBoard<Pipeline.Column, Obj.Unknown>(PIPELINE_COLUMN_NAME);
|
|
35
|
+
const items = useAtomValue(model.items(column));
|
|
36
36
|
// Subscribe to the view target for reactivity.
|
|
37
37
|
const [viewSnapshot] = useObject(column.view);
|
|
38
38
|
const view = column.view.target;
|
|
@@ -50,7 +50,7 @@ export const PipelineColumn = ({ column }: PipelineColumnProps) => {
|
|
|
50
50
|
}, [JSON.stringify(viewSnapshot?.query.ast)]);
|
|
51
51
|
|
|
52
52
|
useAsyncEffect(async () => {
|
|
53
|
-
if (!query || !space) {
|
|
53
|
+
if (!query || !space?.db) {
|
|
54
54
|
return;
|
|
55
55
|
}
|
|
56
56
|
|
|
@@ -58,12 +58,6 @@ export const PipelineColumn = ({ column }: PipelineColumnProps) => {
|
|
|
58
58
|
setSchema(() => schema);
|
|
59
59
|
}, [space, query]);
|
|
60
60
|
|
|
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
61
|
const projectionModel = useMemo(() => {
|
|
68
62
|
if (!schema || !view) {
|
|
69
63
|
return undefined;
|
|
@@ -85,23 +79,29 @@ export const PipelineColumn = ({ column }: PipelineColumnProps) => {
|
|
|
85
79
|
return null;
|
|
86
80
|
}
|
|
87
81
|
|
|
82
|
+
const dragHandleRef = useRef<HTMLButtonElement>(null);
|
|
83
|
+
|
|
88
84
|
return (
|
|
89
|
-
<
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
85
|
+
<Board.Column.Root
|
|
86
|
+
data={column}
|
|
87
|
+
location={location}
|
|
88
|
+
classNames={classNames}
|
|
89
|
+
debug={debug}
|
|
90
|
+
dragHandleRef={dragHandleRef}
|
|
91
|
+
>
|
|
92
|
+
<div
|
|
93
|
+
role='none'
|
|
94
|
+
data-testid='board-column'
|
|
95
|
+
className={mx('group/column grid bs-full overflow-hidden grid-rows-[var(--rail-action)_1fr]', classNames)}
|
|
96
|
+
>
|
|
97
|
+
<Board.Column.Header
|
|
98
|
+
classNames='border-be border-separator'
|
|
99
|
+
label={column.name ?? t('untitled view title')}
|
|
100
|
+
dragHandleRef={dragHandleRef}
|
|
101
|
+
/>
|
|
102
|
+
<Board.Column.Body data={column} Tile={Tile} />
|
|
103
103
|
</div>
|
|
104
|
-
</
|
|
104
|
+
</Board.Column.Root>
|
|
105
105
|
);
|
|
106
106
|
};
|
|
107
107
|
|
|
@@ -2,8 +2,9 @@
|
|
|
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
10
|
import { Obj, Query, Type } from '@dxos/echo';
|
|
@@ -15,11 +16,12 @@ import { Form, omitId } from '@dxos/react-ui-form';
|
|
|
15
16
|
import { withMosaic } from '@dxos/react-ui-mosaic/testing';
|
|
16
17
|
import { Collection, View } from '@dxos/schema';
|
|
17
18
|
import { createObjectFactory } from '@dxos/schema/testing';
|
|
19
|
+
import { withRegistry } from '@dxos/storybook-utils';
|
|
18
20
|
import { Person, Pipeline } from '@dxos/types';
|
|
19
21
|
|
|
20
22
|
import { translations } from '../translations';
|
|
21
23
|
|
|
22
|
-
import { type ItemProps, PipelineComponent
|
|
24
|
+
import { type ItemProps, PipelineComponent, usePipelineBoardModel } from './PipelineComponent';
|
|
23
25
|
|
|
24
26
|
const StorybookProjectItem = ({ item, projectionModel }: ItemProps) => {
|
|
25
27
|
if (Obj.instanceOf(Person.Person, item)) {
|
|
@@ -40,9 +42,11 @@ const StorybookProjectItem = ({ item, projectionModel }: ItemProps) => {
|
|
|
40
42
|
};
|
|
41
43
|
|
|
42
44
|
const DefaultStory = () => {
|
|
45
|
+
const registry = useContext(RegistryContext);
|
|
43
46
|
const { space } = useClientStory();
|
|
44
47
|
const pipelines = useQuery(space?.db, Filter.type(Pipeline.Pipeline));
|
|
45
48
|
const pipeline = pipelines[0];
|
|
49
|
+
const model = usePipelineBoardModel(pipeline, registry);
|
|
46
50
|
|
|
47
51
|
const handleAddColumn = useCallback(() => {
|
|
48
52
|
if (!space || !pipeline) {
|
|
@@ -72,17 +76,19 @@ const DefaultStory = () => {
|
|
|
72
76
|
}
|
|
73
77
|
|
|
74
78
|
return (
|
|
75
|
-
<PipelineComponent.Root Item={StorybookProjectItem} onAddColumn={handleAddColumn}>
|
|
79
|
+
<PipelineComponent.Root Item={StorybookProjectItem} model={model} onAddColumn={handleAddColumn}>
|
|
76
80
|
<PipelineComponent.Content pipeline={pipeline} />
|
|
77
81
|
</PipelineComponent.Root>
|
|
78
82
|
);
|
|
79
83
|
};
|
|
80
84
|
|
|
81
85
|
const MutationsStory = () => {
|
|
86
|
+
const registry = useContext(RegistryContext);
|
|
82
87
|
const { space } = useClientStory();
|
|
83
88
|
const pipelines = useQuery(space?.db, Filter.type(Pipeline.Pipeline));
|
|
84
89
|
const contacts = useQuery(space?.db, Filter.type(Person.Person));
|
|
85
90
|
const pipeline = pipelines[0];
|
|
91
|
+
const model = usePipelineBoardModel(pipeline, registry);
|
|
86
92
|
|
|
87
93
|
const handleAddColumn = useCallback(() => {
|
|
88
94
|
if (!space || !pipeline) {
|
|
@@ -141,7 +147,7 @@ const MutationsStory = () => {
|
|
|
141
147
|
}
|
|
142
148
|
|
|
143
149
|
return (
|
|
144
|
-
<PipelineComponent.Root Item={StorybookProjectItem} onAddColumn={handleAddColumn}>
|
|
150
|
+
<PipelineComponent.Root Item={StorybookProjectItem} model={model} onAddColumn={handleAddColumn}>
|
|
145
151
|
<PipelineComponent.Content pipeline={pipeline} />
|
|
146
152
|
</PipelineComponent.Root>
|
|
147
153
|
);
|
|
@@ -152,6 +158,7 @@ const meta = {
|
|
|
152
158
|
decorators: [
|
|
153
159
|
withTheme(),
|
|
154
160
|
withLayout({ layout: 'column' }),
|
|
161
|
+
withRegistry,
|
|
155
162
|
withMosaic(),
|
|
156
163
|
withClientProvider({
|
|
157
164
|
types: [Pipeline.Pipeline, View.View, Collection.Collection, Person.Person],
|
|
@@ -2,15 +2,19 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { Atom, type Registry, useAtomValue } from '@effect-atom/atom-react';
|
|
5
6
|
import { createContext } from '@radix-ui/react-context';
|
|
6
|
-
import
|
|
7
|
+
import * as Schema from 'effect/Schema';
|
|
8
|
+
import React, { type FC, type PropsWithChildren, useMemo } from 'react';
|
|
7
9
|
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
+
import { Obj, Query } from '@dxos/echo';
|
|
11
|
+
import { AtomObj, AtomQuery } from '@dxos/echo-atom';
|
|
12
|
+
import { getQueryTarget } from '@dxos/plugin-space';
|
|
13
|
+
import { getSpace, isSpace } from '@dxos/react-client/echo';
|
|
10
14
|
import { Toolbar, type ToolbarRootProps, useTranslation } from '@dxos/react-ui';
|
|
11
|
-
import {
|
|
15
|
+
import { Board, type BoardModel, useBoard, useEventHandlerAdapter } from '@dxos/react-ui-mosaic';
|
|
12
16
|
import { type ProjectionModel } from '@dxos/schema';
|
|
13
|
-
import { type Pipeline as PipelineType } from '@dxos/types';
|
|
17
|
+
import { Pipeline, type Pipeline as PipelineType } from '@dxos/types';
|
|
14
18
|
|
|
15
19
|
import { meta } from '../meta';
|
|
16
20
|
|
|
@@ -35,16 +39,90 @@ type PipelineContextValue = {
|
|
|
35
39
|
// Root
|
|
36
40
|
//
|
|
37
41
|
|
|
38
|
-
type PipelineRootProps =
|
|
42
|
+
type PipelineRootProps = PropsWithChildren<
|
|
43
|
+
PipelineContextValue & {
|
|
44
|
+
model: BoardModel<PipelineType.Column, Obj.Unknown>;
|
|
45
|
+
}
|
|
46
|
+
>;
|
|
39
47
|
|
|
40
48
|
const PIPELINE_ROOT = 'Pipeline.Root';
|
|
41
49
|
|
|
42
|
-
const [
|
|
50
|
+
const [PipelineRootContext, usePipeline] = createContext<PipelineContextValue>(PIPELINE_ROOT, {
|
|
43
51
|
Item: itemNoOp,
|
|
44
52
|
});
|
|
45
53
|
|
|
54
|
+
const PipelineRoot = ({ model, children, ...contextValue }: PipelineRootProps) => (
|
|
55
|
+
<PipelineRootContext {...contextValue}>
|
|
56
|
+
<Board.Root model={model}>{children}</Board.Root>
|
|
57
|
+
</PipelineRootContext>
|
|
58
|
+
);
|
|
59
|
+
|
|
46
60
|
PipelineRoot.displayName = PIPELINE_ROOT;
|
|
47
61
|
|
|
62
|
+
//
|
|
63
|
+
// usePipelineBoardModel
|
|
64
|
+
//
|
|
65
|
+
|
|
66
|
+
const emptyColumnsAtom = Atom.make(() => [] as PipelineType.Column[]);
|
|
67
|
+
const emptyItemsAtom = Atom.make(() => [] as Obj.Unknown[]);
|
|
68
|
+
const emptyPipelineModel: BoardModel<PipelineType.Column, Obj.Unknown> = {
|
|
69
|
+
getColumnId: (data) => (data as PipelineType.Column).view.dxn.toString(),
|
|
70
|
+
getItemId: (data) => (data as Obj.Unknown).id,
|
|
71
|
+
isColumn: (obj: unknown): obj is PipelineType.Column => Schema.is(Pipeline.Column)(obj),
|
|
72
|
+
isItem: (obj): obj is Obj.Unknown => Obj.isObject(obj),
|
|
73
|
+
columns: emptyColumnsAtom,
|
|
74
|
+
items: () => emptyItemsAtom,
|
|
75
|
+
getColumns: () => [],
|
|
76
|
+
getItems: () => [],
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const usePipelineBoardModel = (
|
|
80
|
+
pipeline: PipelineType.Pipeline | undefined,
|
|
81
|
+
registry: Registry.Registry,
|
|
82
|
+
): BoardModel<PipelineType.Column, Obj.Unknown> =>
|
|
83
|
+
useMemo<BoardModel<PipelineType.Column, Obj.Unknown>>(() => {
|
|
84
|
+
if (pipeline == null) {
|
|
85
|
+
return emptyPipelineModel;
|
|
86
|
+
}
|
|
87
|
+
const space = getSpace(pipeline);
|
|
88
|
+
const columnsAtom = AtomObj.makeProperty(pipeline, 'columns');
|
|
89
|
+
const columnAtomFamily = Atom.family<string, Atom.Atom<PipelineType.Column | undefined>>((viewKey: string) =>
|
|
90
|
+
Atom.make((get) => {
|
|
91
|
+
const columns = get(columnsAtom);
|
|
92
|
+
return columns.find((c) => c.view.dxn.toString() === viewKey);
|
|
93
|
+
}),
|
|
94
|
+
);
|
|
95
|
+
const itemsAtomFamily = Atom.family<string, Atom.Atom<Obj.Unknown[]>>((viewKey: string) =>
|
|
96
|
+
Atom.make((get) => {
|
|
97
|
+
const column = get(columnAtomFamily(viewKey));
|
|
98
|
+
if (column == null) {
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
const viewSnapshot = get(AtomObj.make(column.view));
|
|
102
|
+
if (!viewSnapshot?.query?.ast) {
|
|
103
|
+
return [];
|
|
104
|
+
}
|
|
105
|
+
const query = Query.fromAst(JSON.parse(JSON.stringify(viewSnapshot.query.ast)));
|
|
106
|
+
const queryTarget = space ? getQueryTarget(query.ast, space) : undefined;
|
|
107
|
+
if (!queryTarget) {
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
const raw = get(AtomQuery.make(queryTarget, query));
|
|
111
|
+
return isSpace(queryTarget) ? raw : [...raw].reverse();
|
|
112
|
+
}),
|
|
113
|
+
);
|
|
114
|
+
return {
|
|
115
|
+
getColumnId: (data) => (data as PipelineType.Column).view.dxn.toString(),
|
|
116
|
+
getItemId: (data) => (data as Obj.Unknown).id,
|
|
117
|
+
isColumn: (obj: unknown): obj is PipelineType.Column => Schema.is(Pipeline.Column)(obj),
|
|
118
|
+
isItem: (obj: unknown): obj is Obj.Unknown => Obj.isObject(obj),
|
|
119
|
+
columns: columnsAtom,
|
|
120
|
+
items: (column) => itemsAtomFamily(column.view.dxn.toString()),
|
|
121
|
+
getColumns: () => [...registry.get(columnsAtom)],
|
|
122
|
+
getItems: (column) => registry.get(itemsAtomFamily(column.view.dxn.toString())) ?? [],
|
|
123
|
+
};
|
|
124
|
+
}, [pipeline, registry]);
|
|
125
|
+
|
|
48
126
|
//
|
|
49
127
|
// Content
|
|
50
128
|
//
|
|
@@ -56,15 +134,20 @@ type PipelineContentProps = {
|
|
|
56
134
|
};
|
|
57
135
|
|
|
58
136
|
const PipelineContent = ({ pipeline }: PipelineContentProps) => {
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
137
|
+
const { model } = useBoard(PIPELINE_CONTENT_NAME);
|
|
138
|
+
const columns = useAtomValue(model.columns);
|
|
139
|
+
const eventHandler = useEventHandlerAdapter<PipelineType.Column, Obj.Unknown>({
|
|
140
|
+
id: pipeline.id,
|
|
141
|
+
// TODO(wittjosiah): Cast because columns array is readonly.
|
|
142
|
+
items: columns as any,
|
|
143
|
+
getId: model.getColumnId,
|
|
144
|
+
get: (data) => data as unknown as Obj.Unknown,
|
|
145
|
+
make: (object) => object as unknown as PipelineType.Column,
|
|
146
|
+
canDrop: ({ source }) => model.isColumn(source.data),
|
|
147
|
+
onChange: (mutate) => Obj.change(pipeline, (p) => mutate(p.columns)),
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
return <Board.Content id='pipeline' eventHandler={eventHandler} Tile={PipelineColumn} />;
|
|
68
151
|
};
|
|
69
152
|
|
|
70
153
|
PipelineContent.displayName = PIPELINE_CONTENT_NAME;
|
|
@@ -98,6 +181,6 @@ export const PipelineComponent = {
|
|
|
98
181
|
Toolbar: PipelineToolbar,
|
|
99
182
|
};
|
|
100
183
|
|
|
101
|
-
export { usePipeline };
|
|
184
|
+
export { usePipeline, usePipelineBoardModel };
|
|
102
185
|
|
|
103
186
|
export type { ItemProps, PipelineContextValue, PipelineRootProps };
|
|
@@ -39,7 +39,7 @@ const DefaultStory = () => {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
return (
|
|
42
|
-
<Stack orientation='horizontal' size='split' rail={false} classNames='pli-0'>
|
|
42
|
+
<Stack orientation='horizontal' size='split' rail={false} classNames='pli-0 bs-full'>
|
|
43
43
|
<PipelineContainer role='article' subject={pipeline} />
|
|
44
44
|
<PipelineObjectSettings pipeline={pipeline} classNames='border-is border-separator' />
|
|
45
45
|
</Stack>
|
|
@@ -144,7 +144,7 @@ const meta = {
|
|
|
144
144
|
space.db.add(pipeline);
|
|
145
145
|
|
|
146
146
|
// Generate sample Organizations
|
|
147
|
-
Array.from({ length:
|
|
147
|
+
Array.from({ length: 20 }).forEach(() => {
|
|
148
148
|
const org = Obj.make(
|
|
149
149
|
Organization.Organization,
|
|
150
150
|
{
|
|
@@ -161,7 +161,7 @@ const meta = {
|
|
|
161
161
|
});
|
|
162
162
|
|
|
163
163
|
// Generate sample Tasks
|
|
164
|
-
Array.from({ length:
|
|
164
|
+
Array.from({ length: 20 }).forEach(() => {
|
|
165
165
|
const task = Obj.make(
|
|
166
166
|
Task.Task,
|
|
167
167
|
{
|
|
@@ -181,7 +181,7 @@ const meta = {
|
|
|
181
181
|
yield* Effect.promise(() => factory([{ type: Person.Person, count: 12 }]));
|
|
182
182
|
|
|
183
183
|
// Generate sample Projects
|
|
184
|
-
Array.from({ length:
|
|
184
|
+
Array.from({ length: 20 }).forEach(() => {
|
|
185
185
|
const nestedProject = Pipeline.make({
|
|
186
186
|
name: faker.commerce.productName(),
|
|
187
187
|
description: faker.lorem.sentence(),
|
|
@@ -190,7 +190,7 @@ const meta = {
|
|
|
190
190
|
});
|
|
191
191
|
|
|
192
192
|
// Generate sample Messages
|
|
193
|
-
const messages = Array.from({ length:
|
|
193
|
+
const messages = Array.from({ length: 20 }).map(() => {
|
|
194
194
|
const message = Obj.make(Message.Message, {
|
|
195
195
|
created: faker.date.recent().toISOString(),
|
|
196
196
|
sender: { role: 'user' },
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
import React, { useCallback } from 'react';
|
|
6
6
|
|
|
7
|
+
import { Capabilities } from '@dxos/app-framework';
|
|
8
|
+
import { useCapability } from '@dxos/app-framework/ui';
|
|
7
9
|
import { useOperationInvoker } from '@dxos/app-framework/ui';
|
|
8
10
|
import { Surface } from '@dxos/app-framework/ui';
|
|
9
11
|
import { type SurfaceComponentProps } from '@dxos/app-toolkit/ui';
|
|
@@ -13,11 +15,13 @@ import { Layout } from '@dxos/react-ui';
|
|
|
13
15
|
import { useAttention } from '@dxos/react-ui-attention';
|
|
14
16
|
import { type Pipeline as PipelineType } from '@dxos/types';
|
|
15
17
|
|
|
16
|
-
import { type ItemProps, PipelineComponent } from './PipelineComponent';
|
|
18
|
+
import { type ItemProps, PipelineComponent, usePipelineBoardModel } from './PipelineComponent';
|
|
17
19
|
|
|
18
20
|
export type PipelineContainerProps = SurfaceComponentProps<PipelineType.Pipeline>;
|
|
19
21
|
|
|
20
22
|
export const PipelineContainer = ({ role, subject: pipeline }: PipelineContainerProps) => {
|
|
23
|
+
const registry = useCapability(Capabilities.AtomRegistry);
|
|
24
|
+
const model = usePipelineBoardModel(pipeline, registry);
|
|
21
25
|
const { invokePromise } = useOperationInvoker();
|
|
22
26
|
const attendableId = Obj.getDXN(pipeline).toString();
|
|
23
27
|
const { hasAttention } = useAttention(attendableId);
|
|
@@ -33,7 +37,7 @@ export const PipelineContainer = ({ role, subject: pipeline }: PipelineContainer
|
|
|
33
37
|
|
|
34
38
|
return (
|
|
35
39
|
<Layout.Main role={role} toolbar>
|
|
36
|
-
<PipelineComponent.Root Item={PipelineItem} onAddColumn={handleColumnAdd}>
|
|
40
|
+
<PipelineComponent.Root Item={PipelineItem} model={model} onAddColumn={handleColumnAdd}>
|
|
37
41
|
<PipelineComponent.Toolbar disabled={!hasAttention} />
|
|
38
42
|
<PipelineComponent.Content pipeline={pipeline} />
|
|
39
43
|
</PipelineComponent.Root>
|