@dxos/plugin-pipeline 0.8.4-main.c85a9c8dae → 0.8.4-main.dfabb4ec29

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 (148) hide show
  1. package/dist/lib/neutral/PipelineContainer-7MK2SS76.mjs +69 -0
  2. package/dist/lib/neutral/PipelineContainer-7MK2SS76.mjs.map +7 -0
  3. package/dist/lib/neutral/PipelinePlugin.mjs +26 -0
  4. package/dist/lib/neutral/PipelinePlugin.mjs.map +7 -0
  5. package/dist/lib/neutral/PipelinePlugin.node.mjs +21 -0
  6. package/dist/lib/neutral/PipelinePlugin.node.mjs.map +7 -0
  7. package/dist/lib/{browser/PipelineObjectSettings-D36OYVHW.mjs → neutral/PipelineProperties-RRPQ3V6I.mjs} +16 -30
  8. package/dist/lib/neutral/PipelineProperties-RRPQ3V6I.mjs.map +7 -0
  9. package/dist/lib/neutral/app-graph-builder-ZLGRWRJU.mjs +44 -0
  10. package/dist/lib/neutral/app-graph-builder-ZLGRWRJU.mjs.map +7 -0
  11. package/dist/lib/neutral/capabilities/index.mjs +11 -0
  12. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  13. package/dist/lib/{browser/chunk-QWNKLHBY.mjs → neutral/chunk-ULB5DKWO.mjs} +2 -9
  14. package/dist/lib/{browser/chunk-QWNKLHBY.mjs.map → neutral/chunk-ULB5DKWO.mjs.map} +3 -3
  15. package/dist/lib/neutral/components/index.mjs +206 -0
  16. package/dist/lib/neutral/components/index.mjs.map +7 -0
  17. package/dist/lib/neutral/containers/index.mjs +9 -0
  18. package/dist/lib/neutral/containers/index.mjs.map +7 -0
  19. package/dist/lib/neutral/create-object-ZJYFACOI.mjs +25 -0
  20. package/dist/lib/neutral/create-object-ZJYFACOI.mjs.map +7 -0
  21. package/dist/lib/neutral/hooks/index.mjs +70 -0
  22. package/dist/lib/neutral/hooks/index.mjs.map +7 -0
  23. package/dist/lib/neutral/index.mjs +7 -0
  24. package/dist/lib/neutral/meta.json +1 -0
  25. package/dist/lib/neutral/meta.mjs +7 -0
  26. package/dist/lib/neutral/meta.mjs.map +7 -0
  27. package/dist/lib/neutral/plugin.mjs +11 -0
  28. package/dist/lib/neutral/plugin.mjs.map +7 -0
  29. package/dist/lib/{browser/react-surface-ZGQVH4VX.mjs → neutral/react-surface-TW6TRMO6.mjs} +14 -25
  30. package/dist/lib/neutral/react-surface-TW6TRMO6.mjs.map +7 -0
  31. package/dist/lib/neutral/translations.mjs +38 -0
  32. package/dist/lib/neutral/translations.mjs.map +7 -0
  33. package/dist/lib/neutral/types/index.mjs +1 -0
  34. package/dist/lib/neutral/types/index.mjs.map +7 -0
  35. package/dist/types/src/PipelinePlugin.d.ts +1 -0
  36. package/dist/types/src/PipelinePlugin.d.ts.map +1 -1
  37. package/dist/types/src/PipelinePlugin.node.d.ts +4 -0
  38. package/dist/types/src/PipelinePlugin.node.d.ts.map +1 -0
  39. package/dist/types/src/PipelinePlugin.test.d.ts +2 -0
  40. package/dist/types/src/PipelinePlugin.test.d.ts.map +1 -0
  41. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
  42. package/dist/types/src/capabilities/create-object.d.ts +11 -0
  43. package/dist/types/src/capabilities/create-object.d.ts.map +1 -0
  44. package/dist/types/src/capabilities/index.d.ts +9 -3
  45. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  46. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  47. package/dist/types/src/components/{PipelineColumn.d.ts → PipelineComponent/PipelineColumn.d.ts} +4 -4
  48. package/dist/types/src/components/PipelineComponent/PipelineColumn.d.ts.map +1 -0
  49. package/dist/types/src/components/PipelineComponent/PipelineComponent.d.ts +53 -0
  50. package/dist/types/src/components/PipelineComponent/PipelineComponent.d.ts.map +1 -0
  51. package/dist/types/src/components/PipelineComponent/PipelineComponent.stories.d.ts +62 -0
  52. package/dist/types/src/components/PipelineComponent/PipelineComponent.stories.d.ts.map +1 -0
  53. package/dist/types/src/components/PipelineComponent/index.d.ts +3 -0
  54. package/dist/types/src/components/PipelineComponent/index.d.ts.map +1 -0
  55. package/dist/types/src/components/index.d.ts +0 -1
  56. package/dist/types/src/components/index.d.ts.map +1 -1
  57. package/dist/types/src/containers/PipelineContainer/PipelineContainer.d.ts +3 -3
  58. package/dist/types/src/containers/PipelineContainer/PipelineContainer.d.ts.map +1 -1
  59. package/dist/types/src/containers/PipelineContainer/PipelineContainer.stories.d.ts +52 -32
  60. package/dist/types/src/containers/PipelineContainer/PipelineContainer.stories.d.ts.map +1 -1
  61. package/dist/types/src/containers/PipelineContainer/index.d.ts +1 -2
  62. package/dist/types/src/containers/PipelineContainer/index.d.ts.map +1 -1
  63. package/dist/types/src/containers/PipelineProperties/PipelineProperties.d.ts +11 -0
  64. package/dist/types/src/containers/PipelineProperties/PipelineProperties.d.ts.map +1 -0
  65. package/dist/types/src/containers/PipelineProperties/index.d.ts +2 -0
  66. package/dist/types/src/containers/PipelineProperties/index.d.ts.map +1 -0
  67. package/dist/types/src/containers/index.d.ts +1 -1
  68. package/dist/types/src/containers/index.d.ts.map +1 -1
  69. package/dist/types/src/hooks/usePipelineBoardModel.d.ts.map +1 -1
  70. package/dist/types/src/index.d.ts +0 -1
  71. package/dist/types/src/index.d.ts.map +1 -1
  72. package/dist/types/src/plugin.d.ts +3 -0
  73. package/dist/types/src/plugin.d.ts.map +1 -0
  74. package/dist/types/src/templates/research.d.ts.map +1 -1
  75. package/dist/types/src/translations.d.ts +44 -25
  76. package/dist/types/src/translations.d.ts.map +1 -1
  77. package/dist/types/src/types/index.d.ts +0 -2
  78. package/dist/types/src/types/index.d.ts.map +1 -1
  79. package/dist/types/tsconfig.tsbuildinfo +1 -1
  80. package/package.json +100 -56
  81. package/src/PipelinePlugin.node.ts +19 -0
  82. package/src/PipelinePlugin.test.ts +27 -0
  83. package/src/PipelinePlugin.tsx +7 -31
  84. package/src/capabilities/app-graph-builder.ts +40 -0
  85. package/src/capabilities/create-object.ts +29 -0
  86. package/src/capabilities/index.ts +5 -3
  87. package/src/capabilities/{react-surface/react-surface.tsx → react-surface.tsx} +16 -15
  88. package/src/components/{PipelineColumn.tsx → PipelineComponent/PipelineColumn.tsx} +65 -34
  89. package/src/components/{PipelineComponent.stories.tsx → PipelineComponent/PipelineComponent.stories.tsx} +20 -18
  90. package/src/components/{PipelineComponent.tsx → PipelineComponent/PipelineComponent.tsx} +22 -13
  91. package/src/components/PipelineComponent/index.ts +6 -0
  92. package/src/components/index.ts +0 -1
  93. package/src/containers/PipelineContainer/PipelineContainer.stories.tsx +35 -34
  94. package/src/containers/PipelineContainer/PipelineContainer.tsx +14 -17
  95. package/src/containers/PipelineContainer/index.ts +1 -3
  96. package/src/containers/{PipelineObjectSettings/PipelineObjectSettings.tsx → PipelineProperties/PipelineProperties.tsx} +20 -20
  97. package/src/containers/PipelineProperties/index.ts +5 -0
  98. package/src/containers/index.ts +1 -1
  99. package/src/hooks/usePipelineBoardModel.ts +1 -1
  100. package/src/index.ts +0 -1
  101. package/src/meta.ts +1 -1
  102. package/src/plugin.ts +9 -0
  103. package/src/templates/research.ts +8 -7
  104. package/src/translations.ts +22 -21
  105. package/src/types/index.ts +0 -3
  106. package/dist/lib/browser/PipelineContainer-2ZYSZATA.mjs +0 -320
  107. package/dist/lib/browser/PipelineContainer-2ZYSZATA.mjs.map +0 -7
  108. package/dist/lib/browser/PipelineObjectSettings-D36OYVHW.mjs.map +0 -7
  109. package/dist/lib/browser/app-graph-builder-NUJB33F7.mjs +0 -65
  110. package/dist/lib/browser/app-graph-builder-NUJB33F7.mjs.map +0 -7
  111. package/dist/lib/browser/chunk-N6FZHYWT.mjs +0 -42
  112. package/dist/lib/browser/chunk-N6FZHYWT.mjs.map +0 -7
  113. package/dist/lib/browser/index.mjs +0 -109
  114. package/dist/lib/browser/index.mjs.map +0 -7
  115. package/dist/lib/browser/meta.json +0 -1
  116. package/dist/lib/browser/react-surface-ZGQVH4VX.mjs.map +0 -7
  117. package/dist/lib/browser/types/index.mjs +0 -10
  118. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +0 -1
  119. package/dist/types/src/capabilities/app-graph-builder/index.d.ts +0 -3
  120. package/dist/types/src/capabilities/app-graph-builder/index.d.ts.map +0 -1
  121. package/dist/types/src/capabilities/operation-resolver/index.d.ts +0 -2
  122. package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +0 -1
  123. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +0 -5
  124. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +0 -1
  125. package/dist/types/src/capabilities/react-surface/index.d.ts +0 -3
  126. package/dist/types/src/capabilities/react-surface/index.d.ts.map +0 -1
  127. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +0 -1
  128. package/dist/types/src/components/PipelineColumn.d.ts.map +0 -1
  129. package/dist/types/src/components/PipelineComponent.d.ts +0 -47
  130. package/dist/types/src/components/PipelineComponent.d.ts.map +0 -1
  131. package/dist/types/src/components/PipelineComponent.stories.d.ts +0 -42
  132. package/dist/types/src/components/PipelineComponent.stories.d.ts.map +0 -1
  133. package/dist/types/src/containers/PipelineObjectSettings/PipelineObjectSettings.d.ts +0 -11
  134. package/dist/types/src/containers/PipelineObjectSettings/PipelineObjectSettings.d.ts.map +0 -1
  135. package/dist/types/src/containers/PipelineObjectSettings/index.d.ts +0 -3
  136. package/dist/types/src/containers/PipelineObjectSettings/index.d.ts.map +0 -1
  137. package/dist/types/src/types/PipelineAction.d.ts +0 -25
  138. package/dist/types/src/types/PipelineAction.d.ts.map +0 -1
  139. package/src/capabilities/app-graph-builder/app-graph-builder.ts +0 -51
  140. package/src/capabilities/app-graph-builder/index.ts +0 -7
  141. package/src/capabilities/operation-resolver/index.ts +0 -5
  142. package/src/capabilities/operation-resolver/operation-resolver.ts +0 -29
  143. package/src/capabilities/react-surface/index.ts +0 -7
  144. package/src/containers/PipelineObjectSettings/index.ts +0 -7
  145. package/src/types/PipelineAction.ts +0 -29
  146. /package/dist/lib/{browser/types → neutral}/index.mjs.map +0 -0
  147. /package/dist/types/src/capabilities/{app-graph-builder/app-graph-builder.d.ts → app-graph-builder.d.ts} +0 -0
  148. /package/dist/types/src/capabilities/{react-surface/react-surface.d.ts → react-surface.d.ts} +0 -0
@@ -4,33 +4,35 @@
4
4
 
5
5
  import { RegistryContext } from '@effect-atom/atom-react';
6
6
  import { type Meta, type StoryObj } from '@storybook/react-vite';
7
- import React, { useCallback, useContext, useEffect } from 'react';
7
+ import React, { useCallback, useContext, useEffect, useMemo } from 'react';
8
8
 
9
9
  import { Filter, Ref } from '@dxos/client/echo';
10
10
  import { JsonSchema, Obj, Query } from '@dxos/echo';
11
11
  import { Collection, View } from '@dxos/echo';
12
- import { faker } from '@dxos/random';
12
+ import { random } from '@dxos/random';
13
13
  import { useQuery } from '@dxos/react-client/echo';
14
14
  import { useClientStory, withClientProvider } from '@dxos/react-client/testing';
15
- import { withLayout, withTheme } from '@dxos/react-ui/testing';
16
15
  import { Form, omitId } from '@dxos/react-ui-form';
17
16
  import { withMosaic } from '@dxos/react-ui-mosaic/testing';
17
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
18
18
  import { ViewModel } from '@dxos/schema';
19
19
  import { createObjectFactory } from '@dxos/schema/testing';
20
20
  import { withRegistry } from '@dxos/storybook-utils';
21
21
  import { Person, Pipeline } from '@dxos/types';
22
22
 
23
- import { usePipelineBoardModel } from '../hooks';
24
- import { translations } from '../translations';
23
+ import { usePipelineBoardModel } from '#hooks';
24
+ import { translations } from '#translations';
25
25
 
26
26
  import { type ItemProps, PipelineComponent } from './PipelineComponent';
27
27
 
28
28
  const StorybookProjectItem = ({ item, projectionModel }: ItemProps) => {
29
+ const personSchema = useMemo(() => omitId(Person.Person), []);
30
+
29
31
  if (Obj.instanceOf(Person.Person, item)) {
30
32
  const contact = item as Obj.OfShape<Person.Person>;
31
33
 
32
34
  return (
33
- <Form.Root schema={omitId(Person.Person)} projection={projectionModel} values={contact} autoSave>
35
+ <Form.Root schema={personSchema} projection={projectionModel} values={contact} autoSave>
34
36
  <Form.Viewport>
35
37
  <Form.Content>
36
38
  <Form.FieldSet />
@@ -62,10 +64,10 @@ const DefaultStory = () => {
62
64
  fields: ['fullName'],
63
65
  });
64
66
 
65
- Obj.change(pipeline, (p) => {
66
- p.columns.push({
67
+ Obj.update(pipeline, (pipeline) => {
68
+ pipeline.columns.push({
67
69
  name: 'New Contacts',
68
- view: Ref.make(view) as (typeof p.columns)[number]['view'],
70
+ view: Ref.make(view) as (typeof pipeline.columns)[number]['view'],
69
71
  order: [],
70
72
  });
71
73
  });
@@ -106,10 +108,10 @@ const MutationsStory = () => {
106
108
  fields: ['fullName'],
107
109
  });
108
110
 
109
- Obj.change(pipeline, (p) => {
110
- p.columns.push({
111
+ Obj.update(pipeline, (pipeline) => {
112
+ pipeline.columns.push({
111
113
  name: 'New Contacts',
112
- view: Ref.make(view) as (typeof p.columns)[number]['view'],
114
+ view: Ref.make(view) as (typeof pipeline.columns)[number]['view'],
113
115
  order: [],
114
116
  });
115
117
  });
@@ -123,19 +125,19 @@ const MutationsStory = () => {
123
125
  }
124
126
 
125
127
  const interval = setInterval(() => {
126
- const factory = createObjectFactory(space.db, faker as any);
128
+ const factory = createObjectFactory(space.db, random as any);
127
129
  const p = Math.random();
128
130
 
129
131
  if (p < 0.4) {
130
132
  // Append to the name
131
- const contactToAdjust = faker.helpers.arrayElement(contacts);
132
- Obj.change(contactToAdjust, (c) => {
133
- c.fullName = (c.fullName ?? '') + ' X';
133
+ const contactToAdjust = random.helpers.arrayElement(contacts);
134
+ Obj.update(contactToAdjust, (contactToAdjust) => {
135
+ contactToAdjust.fullName = (contactToAdjust.fullName ?? '') + ' X';
134
136
  });
135
137
  return;
136
138
  } else if (p < 0.7 && contacts.length > 1) {
137
139
  // Remove a contact (30% chance, but only if we have more than 1)
138
- const contactToRemove = faker.helpers.arrayElement(contacts);
140
+ const contactToRemove = random.helpers.arrayElement(contacts);
139
141
  space.db.remove(contactToRemove);
140
142
  } else {
141
143
  // Add a new contact (30% chance)
@@ -193,7 +195,7 @@ const meta = {
193
195
  );
194
196
 
195
197
  // Generate random contacts.
196
- const factory = createObjectFactory(space.db, faker as any);
198
+ const factory = createObjectFactory(space.db, random as any);
197
199
  await factory([{ type: Person.Person, count: 12 }]);
198
200
  },
199
201
  }),
@@ -4,6 +4,7 @@
4
4
 
5
5
  import { useAtomValue } from '@effect-atom/atom-react';
6
6
  import { createContext } from '@radix-ui/react-context';
7
+ import { Slot } from '@radix-ui/react-slot';
7
8
  import React, { type FC, type PropsWithChildren } from 'react';
8
9
 
9
10
  import { Obj } from '@dxos/echo';
@@ -11,8 +12,9 @@ import { Toolbar, type ToolbarRootProps, useTranslation } from '@dxos/react-ui';
11
12
  import { Board, type BoardModel, useBoard, useEventHandlerAdapter } from '@dxos/react-ui-mosaic';
12
13
  import { type ProjectionModel } from '@dxos/schema';
13
14
  import { type Pipeline } from '@dxos/types';
15
+ import { composable, composableProps, slottable } from '@dxos/ui-theme';
14
16
 
15
- import { meta } from '../meta';
17
+ import { meta } from '#meta';
16
18
 
17
19
  import { PipelineColumn } from './PipelineColumn';
18
20
 
@@ -59,10 +61,17 @@ type PipelineContentProps = PropsWithChildren<{
59
61
  model: BoardModel<Pipeline.Column, Obj.Unknown>;
60
62
  }>;
61
63
 
62
- const PipelineContent = ({ model, children, ...props }: PipelineContentProps) => (
63
- <Board.Root {...props} model={model}>
64
- {children}
65
- </Board.Root>
64
+ const PipelineContent = slottable<HTMLDivElement, PipelineContentProps>(
65
+ ({ asChild, model, children, ...props }, forwardedRef) => {
66
+ const Comp = asChild ? Slot : 'div';
67
+ return (
68
+ <Board.Root model={model}>
69
+ <Comp {...composableProps(props)} ref={forwardedRef}>
70
+ {children}
71
+ </Comp>
72
+ </Board.Root>
73
+ );
74
+ },
66
75
  );
67
76
 
68
77
  PipelineContent.displayName = PIPELINE_CONTENT_NAME;
@@ -77,7 +86,7 @@ type PipelineColumnsProps = {
77
86
  pipeline: Pipeline.Pipeline;
78
87
  };
79
88
 
80
- const PipelineColumns = ({ pipeline }: PipelineColumnsProps) => {
89
+ const PipelineColumns = composable<HTMLDivElement, PipelineColumnsProps>(({ pipeline, ...props }) => {
81
90
  const { model } = useBoard(PIPELINE_COLUMNS_NAME);
82
91
  const columns = useAtomValue(model.columns);
83
92
  const eventHandler = useEventHandlerAdapter<Pipeline.Column, Obj.Unknown>({
@@ -88,11 +97,11 @@ const PipelineColumns = ({ pipeline }: PipelineColumnsProps) => {
88
97
  get: (data) => data as unknown as Obj.Unknown,
89
98
  make: (object) => object as unknown as Pipeline.Column,
90
99
  canDrop: ({ source }) => model.isColumn(source.data),
91
- onChange: (mutate) => Obj.change(pipeline, (p) => mutate(p.columns)),
100
+ onChange: (mutate) => Obj.update(pipeline, (pipeline) => mutate(pipeline.columns)),
92
101
  });
93
102
 
94
- return <Board.Content id='pipeline' eventHandler={eventHandler} Tile={PipelineColumn} />;
95
- };
103
+ return <Board.Content {...props} id='pipeline' eventHandler={eventHandler} Tile={PipelineColumn} />;
104
+ });
96
105
 
97
106
  PipelineColumns.displayName = PIPELINE_COLUMNS_NAME;
98
107
 
@@ -102,16 +111,16 @@ PipelineColumns.displayName = PIPELINE_COLUMNS_NAME;
102
111
 
103
112
  const PIPELINE_TOOLBAR_NAME = 'Pipeline.Toolbar';
104
113
 
105
- export const PipelineToolbar = (props: ToolbarRootProps) => {
114
+ export const PipelineToolbar = composable<HTMLDivElement, ToolbarRootProps>(({ children, ...props }, forwardedRef) => {
106
115
  const { t } = useTranslation(meta.id);
107
116
  const { onAddColumn } = usePipeline(PIPELINE_TOOLBAR_NAME);
108
117
 
109
118
  return (
110
- <Toolbar.Root {...props}>
111
- <Toolbar.IconButton icon='ph--plus--regular' iconOnly label={t('add column label')} onClick={onAddColumn} />
119
+ <Toolbar.Root {...composableProps(props)} ref={forwardedRef}>
120
+ <Toolbar.IconButton icon='ph--plus--regular' iconOnly label={t('add-column.label')} onClick={onAddColumn} />
112
121
  </Toolbar.Root>
113
122
  );
114
- };
123
+ });
115
124
 
116
125
  PipelineToolbar.displayName = PIPELINE_TOOLBAR_NAME;
117
126
 
@@ -0,0 +1,6 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export * from './PipelineColumn';
6
+ export * from './PipelineComponent';
@@ -2,5 +2,4 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- export * from './PipelineColumn';
6
5
  export * from './PipelineComponent';
@@ -12,24 +12,25 @@ import { Filter, Ref } from '@dxos/client/echo';
12
12
  import { Database, Feed, JsonSchema, Obj, Query, Tag } from '@dxos/echo';
13
13
  import { Collection, View } from '@dxos/echo';
14
14
  import { createFeedServiceLayer } from '@dxos/echo-db';
15
- import { ClientPlugin } from '@dxos/plugin-client';
16
- import { InboxPlugin } from '@dxos/plugin-inbox';
17
- import { PreviewPlugin } from '@dxos/plugin-preview';
15
+ import { ClientPlugin } from '@dxos/plugin-client/plugin';
16
+ import { initializeIdentity } from '@dxos/plugin-client/testing';
17
+ import { InboxPlugin } from '@dxos/plugin-inbox/plugin';
18
+ import { PreviewPlugin } from '@dxos/plugin-preview/testing';
18
19
  import { StorybookPlugin, corePlugins } from '@dxos/plugin-testing';
19
- import { faker } from '@dxos/random';
20
+ import { random } from '@dxos/random';
20
21
  import { useDatabase, useQuery } from '@dxos/react-client/echo';
21
- import { withLayout, withTheme } from '@dxos/react-ui/testing';
22
- import { translations as stackTranslations } from '@dxos/react-ui-stack';
22
+ import { translations as stackTranslations } from '@dxos/react-ui-stack/translations';
23
+ import { withLayout } from '@dxos/react-ui/testing';
23
24
  import { ViewModel } from '@dxos/schema';
24
25
  import { createObjectFactory } from '@dxos/schema/testing';
25
26
  import { Message, Organization, Person, Pipeline, Task } from '@dxos/types';
26
27
 
27
- import { translations } from '../../translations';
28
- import PipelineObjectSettings from '../PipelineObjectSettings';
28
+ import { translations } from '#translations';
29
29
 
30
+ import PipelineProperties from '../PipelineProperties';
30
31
  import { PipelineContainer } from './PipelineContainer';
31
32
 
32
- faker.seed(0);
33
+ random.seed(0);
33
34
 
34
35
  const DefaultStory = () => {
35
36
  const db = useDatabase();
@@ -42,8 +43,8 @@ const DefaultStory = () => {
42
43
 
43
44
  return (
44
45
  <div className='grow grid grid-cols-[1fr_350px] overflow-hidden h-full w-full'>
45
- <PipelineContainer role='article' subject={pipeline} />
46
- <PipelineObjectSettings pipeline={pipeline} classNames='border-s border-separator' />
46
+ <PipelineContainer role='article' subject={pipeline} attendableId='test' />
47
+ <PipelineProperties pipeline={pipeline} classNames='border-s border-separator' />
47
48
  </div>
48
49
  );
49
50
  };
@@ -52,7 +53,6 @@ const meta = {
52
53
  title: 'plugins/plugin-pipeline/containers/PipelineContainer',
53
54
  render: DefaultStory,
54
55
  decorators: [
55
- withTheme(),
56
56
  withLayout({ layout: 'fullscreen' }),
57
57
  withPluginManager({
58
58
  plugins: [
@@ -71,10 +71,7 @@ const meta = {
71
71
  Message.Message,
72
72
  ],
73
73
  onClientInitialized: Effect.fnUntraced(function* ({ client }) {
74
- yield* Effect.promise(() => client.halo.createIdentity());
75
- yield* Effect.promise(() => client.spaces.waitUntilReady());
76
- const space = client.spaces.default;
77
- yield* Effect.promise(() => space.waitUntilReady());
74
+ const { personalSpace } = yield* initializeIdentity(client);
78
75
 
79
76
  yield* Effect.gen(function* () {
80
77
  const tag = yield* Database.add(Tag.make({ label: 'important', hue: 'green' }));
@@ -108,9 +105,9 @@ const meta = {
108
105
  const messageFeed = yield* Database.add(Feed.make({ name: 'Messages' }));
109
106
  const messages = Array.from({ length: 20 }).map(() =>
110
107
  Obj.make(Message.Message, {
111
- created: faker.date.recent().toISOString(),
108
+ created: random.date.recent().toISOString(),
112
109
  sender: { role: 'user' },
113
- blocks: [{ _tag: 'text' as const, text: faker.lorem.sentences(2) }],
110
+ blocks: [{ _tag: 'text' as const, text: random.lorem.sentences(2) }],
114
111
  }),
115
112
  );
116
113
  yield* Feed.append(messageFeed, messages);
@@ -127,9 +124,9 @@ const meta = {
127
124
  const taskFeed = yield* Database.add(Feed.make({ name: 'Tasks' }));
128
125
  const feedTasks = Array.from({ length: 10 }).map(() =>
129
126
  Obj.make(Task.Task, {
130
- title: faker.lorem.sentence(),
131
- status: faker.helpers.arrayElement(['todo', 'in-progress', 'done']) as any,
132
- priority: faker.helpers.arrayElement(['low', 'medium', 'high']) as any,
127
+ title: random.lorem.sentence(),
128
+ status: random.helpers.arrayElement(['todo', 'in-progress', 'done']) as any,
129
+ priority: random.helpers.arrayElement(['low', 'medium', 'high']) as any,
133
130
  }),
134
131
  );
135
132
  yield* Feed.append(taskFeed, feedTasks);
@@ -171,12 +168,12 @@ const meta = {
171
168
  yield* Database.add(
172
169
  Obj.make(Organization.Organization, {
173
170
  [Obj.Meta]: {
174
- tags: faker.datatype.boolean() ? [tagDxn] : [],
171
+ tags: random.datatype.boolean() ? [tagDxn] : [],
175
172
  },
176
- name: faker.company.name(),
177
- website: faker.internet.url(),
178
- description: faker.lorem.paragraph(),
179
- image: faker.image.url(),
173
+ name: random.company.name(),
174
+ website: random.internet.url(),
175
+ description: random.lorem.paragraph(),
176
+ image: random.image.url(),
180
177
  }),
181
178
  );
182
179
  }
@@ -186,29 +183,33 @@ const meta = {
186
183
  yield* Database.add(
187
184
  Obj.make(Task.Task, {
188
185
  [Obj.Meta]: {
189
- tags: faker.datatype.boolean() ? [tagDxn] : [],
186
+ tags: random.datatype.boolean() ? [tagDxn] : [],
190
187
  },
191
- title: faker.lorem.sentence(),
192
- status: faker.helpers.arrayElement(['todo', 'in-progress', 'done']) as any,
193
- priority: faker.helpers.arrayElement(['low', 'medium', 'high']) as any,
188
+ title: random.lorem.sentence(),
189
+ status: random.helpers.arrayElement(['todo', 'in-progress', 'done']) as any,
190
+ priority: random.helpers.arrayElement(['low', 'medium', 'high']) as any,
194
191
  }),
195
192
  );
196
193
  }
197
194
 
198
195
  // Generate sample Contacts.
199
- const factory = createObjectFactory(space.db, faker as any);
196
+ const factory = createObjectFactory(personalSpace.db, random as any);
200
197
  yield* Effect.promise(() => factory([{ type: Person.Person, count: 12 }]));
201
198
 
202
199
  // Generate sample Projects.
203
200
  for (const _ of Array.from({ length: 20 })) {
204
201
  yield* Database.add(
205
202
  Pipeline.make({
206
- name: faker.commerce.productName(),
207
- description: faker.lorem.sentence(),
203
+ name: random.commerce.productName(),
204
+ description: random.lorem.sentence(),
208
205
  }),
209
206
  );
210
207
  }
211
- }).pipe(Effect.provide(Layer.merge(Database.layer(space.db), createFeedServiceLayer(space.queues))));
208
+ }).pipe(
209
+ Effect.provide(
210
+ Layer.merge(Database.layer(personalSpace.db), createFeedServiceLayer(personalSpace.queues)),
211
+ ),
212
+ );
212
213
  }),
213
214
  }),
214
215
  InboxPlugin(),
@@ -5,52 +5,49 @@
5
5
  import React, { useCallback, useEffect } from 'react';
6
6
 
7
7
  import { Capabilities } from '@dxos/app-framework';
8
- import { useCapability } from '@dxos/app-framework/ui';
9
- import { useOperationInvoker } from '@dxos/app-framework/ui';
10
- import { Surface } from '@dxos/app-framework/ui';
8
+ import { Surface, useCapability, useOperationInvoker } from '@dxos/app-framework/ui';
9
+ import { LayoutOperation } from '@dxos/app-toolkit';
11
10
  import {
11
+ AppSurface,
12
12
  OBJECT_ACTIONS_CONTRIBUTION_ID,
13
13
  OBJECT_ACTIONS_CONTRIBUTION_PRIORITY,
14
- type SurfaceComponentProps,
15
14
  useObjectMenuItems,
16
15
  } from '@dxos/app-toolkit/ui';
17
- import { Obj } from '@dxos/echo';
18
- import { ATTENDABLE_PATH_SEPARATOR, DeckOperation } from '@dxos/plugin-deck/types';
19
16
  import { Panel } from '@dxos/react-ui';
17
+ import { linkedSegment } from '@dxos/react-ui-attention';
20
18
  import { useAttention } from '@dxos/react-ui-attention';
21
19
  import { useMenu } from '@dxos/react-ui-menu';
22
20
  import { type Pipeline } from '@dxos/types';
23
21
 
24
- import { type ItemProps, PipelineComponent } from '../../components';
25
- import { usePipelineBoardModel } from '../../hooks';
22
+ import { type ItemProps, PipelineComponent } from '#components';
23
+ import { usePipelineBoardModel } from '#hooks';
26
24
 
27
25
  const PIPELINE_ITEM = 'PipelineItem';
28
26
 
29
- export type PipelineContainerProps = SurfaceComponentProps<Pipeline.Pipeline>;
27
+ export type PipelineContainerProps = AppSurface.ObjectArticleProps<Pipeline.Pipeline>;
30
28
 
31
- export const PipelineContainer = ({ role, subject: pipeline }: PipelineContainerProps) => {
29
+ export const PipelineContainer = ({ role, subject: pipeline, attendableId }: PipelineContainerProps) => {
32
30
  const registry = useCapability(Capabilities.AtomRegistry);
33
31
  const model = usePipelineBoardModel(pipeline, registry);
34
32
  const { invokePromise } = useOperationInvoker();
35
- const attendableId = Obj.getDXN(pipeline).toString();
36
33
  const { hasAttention } = useAttention(attendableId);
37
34
 
38
35
  const handleColumnAdd = useCallback(
39
36
  () =>
40
- invokePromise(DeckOperation.ChangeCompanion, {
41
- companion: `${attendableId}${ATTENDABLE_PATH_SEPARATOR}settings`,
37
+ invokePromise(LayoutOperation.UpdateCompanion, {
38
+ subject: linkedSegment('settings'),
42
39
  }),
43
- [invokePromise, attendableId],
40
+ [invokePromise],
44
41
  );
45
42
 
46
43
  return (
47
44
  <PipelineComponent.Root Item={PipelineItem} onAddColumn={handleColumnAdd}>
48
- <Panel.Root role={role} className='dx-article'>
45
+ <Panel.Root role={role}>
49
46
  <Panel.Toolbar asChild>
50
47
  <PipelineComponent.Toolbar disabled={!hasAttention} />
51
48
  </Panel.Toolbar>
52
49
  <Panel.Content asChild>
53
- <PipelineComponent.Content model={model}>
50
+ <PipelineComponent.Content asChild model={model}>
54
51
  <PipelineComponent.Columns pipeline={pipeline} />
55
52
  </PipelineComponent.Content>
56
53
  </Panel.Content>
@@ -76,7 +73,7 @@ const PipelineItem = ({ item, projectionModel }: ItemProps) => {
76
73
 
77
74
  return (
78
75
  <Surface.Surface
79
- role='card--content'
76
+ type={AppSurface.Card}
80
77
  data={{
81
78
  subject: item,
82
79
  projection: projectionModel,
@@ -2,6 +2,4 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { PipelineContainer } from './PipelineContainer';
6
-
7
- export default PipelineContainer;
5
+ export { PipelineContainer as default } from './PipelineContainer';
@@ -5,35 +5,34 @@
5
5
  import * as Schema from 'effect/Schema';
6
6
  import React, { useCallback, useMemo, useRef, useState } from 'react';
7
7
 
8
+ import { resolveSchemaWithRegistry } from '@dxos/app-toolkit/query';
9
+ import { useTypeOptions } from '@dxos/app-toolkit/ui';
8
10
  import { DXN, Filter, JsonSchema, Obj, Query, type QueryAST, Ref, Tag } from '@dxos/echo';
9
11
  import { type JsonPath, type Mutable } from '@dxos/echo/internal';
10
- import { useTypeOptions } from '@dxos/plugin-space';
11
- import { resolveSchemaWithRegistry } from '@dxos/plugin-space';
12
12
  import { getSpace, useObject, useQuery } from '@dxos/react-client/echo';
13
13
  import { IconButton, type ThemedClassName, useAsyncEffect, useTranslation } from '@dxos/react-ui';
14
14
  import { Form, ViewEditor } from '@dxos/react-ui-form';
15
15
  import { List } from '@dxos/react-ui-list';
16
16
  import { type ProjectionModel, ViewModel } from '@dxos/schema';
17
- import { Pipeline, Task } from '@dxos/types';
17
+ import { Pipeline } from '@dxos/types';
18
18
  import { mx, osTranslations, subtleHover } from '@dxos/ui-theme';
19
19
  import { arrayMove } from '@dxos/util';
20
20
 
21
- import { meta } from '../../meta';
21
+ import { meta } from '#meta';
22
22
 
23
23
  const listGrid = 'grid grid-cols-[min-content_1fr_min-content_min-content_min-content]';
24
24
  const listItemGrid = 'grid grid-cols-subgrid col-span-5';
25
25
 
26
26
  const ColumnFormSchema = Pipeline.Column.pipe(Schema.mutable, Schema.pick('name'));
27
27
 
28
- // TODO(burdon): Standardize Object/Plugin settings.
29
- export type PipelineObjectSettingsProps = ThemedClassName<{
28
+ export type PipelinePropertiesProps = ThemedClassName<{
30
29
  pipeline: Pipeline.Pipeline;
31
30
  }>;
32
31
 
33
32
  /**
34
33
  * Supports editing the pipeline view.
35
34
  */
36
- export const PipelineObjectSettings = ({ classNames, pipeline }: PipelineObjectSettingsProps) => {
35
+ export const PipelineProperties = ({ classNames, pipeline }: PipelinePropertiesProps) => {
37
36
  const { t } = useTranslation(meta.id);
38
37
  const space = getSpace(pipeline);
39
38
  const [expandedId, setExpandedId] = useState<string>();
@@ -51,7 +50,6 @@ export const PipelineObjectSettings = ({ classNames, pipeline }: PipelineObjectS
51
50
  annotation: {
52
51
  location: ['database', 'runtime'],
53
52
  kind: ['user'],
54
- registered: ['registered', 'unregistered'],
55
53
  },
56
54
  });
57
55
 
@@ -146,13 +144,13 @@ export const PipelineObjectSettings = ({ classNames, pipeline }: PipelineObjectS
146
144
  return;
147
145
  }
148
146
  const newView = ViewModel.make({
149
- query: Query.select(Filter.type(Task.Task)),
150
- jsonSchema: JsonSchema.toJsonSchema(Task.Task),
147
+ query: Query.select(Filter.nothing()),
148
+ jsonSchema: JsonSchema.toJsonSchema(Schema.Struct({})),
151
149
  });
152
150
  space.db.add(newView);
153
151
  updateColumns((columns) => {
154
152
  columns.push({
155
- name: 'Tasks',
153
+ name: '',
156
154
  // Type assertion needed due to QueryAST type variance.
157
155
  view: Ref.make(newView) as (typeof columns)[number]['view'],
158
156
  order: [],
@@ -162,8 +160,8 @@ export const PipelineObjectSettings = ({ classNames, pipeline }: PipelineObjectS
162
160
  }, [space, updateColumns]);
163
161
 
164
162
  return (
165
- <div role='none' className={mx('py-form-padding overflow-y-auto', classNames)}>
166
- <h2 className='text-sm text-description py-1'>{t('views label')}</h2>
163
+ <div className={mx('py-form-padding overflow-y-auto', classNames)}>
164
+ <h2 className='text-sm text-description py-1'>{t('views.label')}</h2>
167
165
 
168
166
  <List.Root<Pipeline.Column>
169
167
  items={columns}
@@ -181,11 +179,13 @@ export const PipelineObjectSettings = ({ classNames, pipeline }: PipelineObjectS
181
179
  classNames={listItemGrid}
182
180
  aria-expanded={expandedId === column.view.dxn.toString()}
183
181
  >
184
- <div role='none' className={mx(subtleHover, listItemGrid, 'rounded-xs cursor-pointer min-h-10')}>
182
+ <div className={mx(subtleHover, listItemGrid, 'rounded-xs cursor-pointer min-h-10')}>
185
183
  <List.ItemDragHandle />
186
- <List.ItemTitle onClick={() => handleToggleField(column)}>{column.name}</List.ItemTitle>
184
+ <List.ItemTitle onClick={() => handleToggleField(column)}>
185
+ {column.name || t('untitled-view.title')}
186
+ </List.ItemTitle>
187
187
  <List.ItemDeleteButton
188
- label={t('delete view label')}
188
+ label={t('delete-view.label')}
189
189
  autoHide={false}
190
190
  onClick={() => handleDelete(column)}
191
191
  data-testid='view.delete'
@@ -193,7 +193,7 @@ export const PipelineObjectSettings = ({ classNames, pipeline }: PipelineObjectS
193
193
  <IconButton
194
194
  iconOnly
195
195
  variant='ghost'
196
- label={t('toggle expand label', { ns: osTranslations })}
196
+ label={t('toggle-expand.label', { ns: osTranslations })}
197
197
  icon={
198
198
  expandedId === column.view.dxn.toString()
199
199
  ? 'ph--caret-down--regular'
@@ -203,7 +203,7 @@ export const PipelineObjectSettings = ({ classNames, pipeline }: PipelineObjectS
203
203
  />
204
204
  </div>
205
205
  {expandedId === column.view.dxn.toString() && column?.view.target && (
206
- <div role='none' className='col-span-5 my-2 border border-separator rounded-md'>
206
+ <div className='col-span-5 my-2 border border-separator rounded-md'>
207
207
  <Form.Root
208
208
  schema={ColumnFormSchema}
209
209
  values={column}
@@ -234,8 +234,8 @@ export const PipelineObjectSettings = ({ classNames, pipeline }: PipelineObjectS
234
234
  )}
235
235
  </List.Root>
236
236
 
237
- <div role='none' className='my-form-padding'>
238
- <IconButton icon='ph--plus--regular' label={t('add view label')} onClick={handleAdd} classNames='w-full' />
237
+ <div className='my-form-padding'>
238
+ <IconButton icon='ph--plus--regular' label={t('add-view.label')} onClick={handleAdd} classNames='w-full' />
239
239
  </div>
240
240
  </div>
241
241
  );
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export { PipelineProperties as default } from './PipelineProperties';
@@ -5,4 +5,4 @@
5
5
  import { type ComponentType, lazy } from 'react';
6
6
 
7
7
  export const PipelineContainer: ComponentType<any> = lazy(() => import('./PipelineContainer'));
8
- export const PipelineObjectSettings: ComponentType<any> = lazy(() => import('./PipelineObjectSettings'));
8
+ export const PipelineProperties: ComponentType<any> = lazy(() => import('./PipelineProperties'));
@@ -6,9 +6,9 @@ import { Atom, type Registry } from '@effect-atom/atom-react';
6
6
  import * as Schema from 'effect/Schema';
7
7
  import { useMemo } from 'react';
8
8
 
9
+ import { getQueryTarget } from '@dxos/app-toolkit/query';
9
10
  import { Obj, Query } from '@dxos/echo';
10
11
  import { AtomObj, AtomQuery } from '@dxos/echo-atom';
11
- import { getQueryTarget } from '@dxos/plugin-space';
12
12
  import { getSpace, isSpace } from '@dxos/react-client/echo';
13
13
  import { type BoardModel } from '@dxos/react-ui-mosaic';
14
14
  import { Pipeline } from '@dxos/types';
package/src/index.ts CHANGED
@@ -3,4 +3,3 @@
3
3
  //
4
4
 
5
5
  export * from './meta';
6
- export * from './PipelinePlugin';
package/src/meta.ts CHANGED
@@ -6,7 +6,7 @@ import { type Plugin } from '@dxos/app-framework';
6
6
  import { trim } from '@dxos/util';
7
7
 
8
8
  export const meta: Plugin.Meta = {
9
- id: 'dxos.org/plugin/pipeline',
9
+ id: 'org.dxos.plugin.pipeline',
10
10
  name: 'Pipelines',
11
11
  description: trim`
12
12
  Pipelines for organizing tasks, milestones, and deliverables.
package/src/plugin.ts ADDED
@@ -0,0 +1,9 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { Plugin } from '@dxos/app-framework';
6
+
7
+ import { meta } from './meta';
8
+
9
+ export const PipelinePlugin = Plugin.lazy(meta, () => import('#plugin'));
@@ -2,9 +2,9 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { type Database, Feed, Filter, JsonSchema, Query, Ref } from '@dxos/echo';
6
- import { Mailbox } from '@dxos/plugin-inbox/types';
7
- import { Markdown } from '@dxos/plugin-markdown/types';
5
+ import { type Database, Filter, JsonSchema, Query, Ref } from '@dxos/echo';
6
+ import { Mailbox } from '@dxos/plugin-inbox';
7
+ import { Markdown } from '@dxos/plugin-markdown';
8
8
  import { ViewModel } from '@dxos/schema';
9
9
  import { Message, Organization, Person, Pipeline } from '@dxos/types';
10
10
 
@@ -12,14 +12,15 @@ export const createResearchProject = async (
12
12
  db: Database.Database,
13
13
  name?: string,
14
14
  ): Promise<Pipeline.Pipeline | null> => {
15
- const feeds = await db.query(Filter.type(Feed.Feed)).run();
16
- const mailbox = feeds.find((feed) => feed.kind === Mailbox.kind);
17
- if (!mailbox) {
15
+ const mailboxes = await db.query(Filter.type(Mailbox.Mailbox)).run();
16
+ const mailbox = mailboxes[0];
17
+ const feed = await mailbox?.feed?.tryLoad();
18
+ if (!mailbox || !feed) {
18
19
  return null;
19
20
  }
20
21
 
21
22
  const mailboxView = ViewModel.make({
22
- query: Query.select(Filter.type(Message.Message)).from(mailbox),
23
+ query: Query.select(Filter.type(Message.Message)).from(feed),
23
24
  jsonSchema: JsonSchema.toJsonSchema(Message.Message),
24
25
  });
25
26