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

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 (166) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/neutral/PipelineArticle-6JIVXMYF.mjs +69 -0
  4. package/dist/lib/neutral/PipelineArticle-6JIVXMYF.mjs.map +7 -0
  5. package/dist/lib/neutral/PipelinePlugin.mjs +26 -0
  6. package/dist/lib/neutral/PipelinePlugin.mjs.map +7 -0
  7. package/dist/lib/neutral/PipelinePlugin.node.mjs +21 -0
  8. package/dist/lib/neutral/PipelinePlugin.node.mjs.map +7 -0
  9. package/dist/lib/neutral/PipelinePlugin.workerd.mjs +16 -0
  10. package/dist/lib/neutral/PipelinePlugin.workerd.mjs.map +7 -0
  11. package/dist/lib/{browser/PipelineObjectSettings-D36OYVHW.mjs → neutral/PipelineProperties-NFNEU3NR.mjs} +56 -69
  12. package/dist/lib/neutral/PipelineProperties-NFNEU3NR.mjs.map +7 -0
  13. package/dist/lib/neutral/app-graph-builder-ZLGRWRJU.mjs +44 -0
  14. package/dist/lib/neutral/app-graph-builder-ZLGRWRJU.mjs.map +7 -0
  15. package/dist/lib/neutral/capabilities/index.mjs +11 -0
  16. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  17. package/dist/lib/neutral/chunk-OVZ2ASS7.mjs +33 -0
  18. package/dist/lib/neutral/chunk-OVZ2ASS7.mjs.map +7 -0
  19. package/dist/lib/neutral/components/index.mjs +207 -0
  20. package/dist/lib/neutral/components/index.mjs.map +7 -0
  21. package/dist/lib/neutral/containers/index.mjs +9 -0
  22. package/dist/lib/neutral/containers/index.mjs.map +7 -0
  23. package/dist/lib/neutral/create-object-6Z4MMGX4.mjs +26 -0
  24. package/dist/lib/neutral/create-object-6Z4MMGX4.mjs.map +7 -0
  25. package/dist/lib/neutral/hooks/index.mjs +70 -0
  26. package/dist/lib/neutral/hooks/index.mjs.map +7 -0
  27. package/dist/lib/neutral/index.mjs +7 -0
  28. package/dist/lib/neutral/meta.json +1 -0
  29. package/dist/lib/neutral/meta.mjs +7 -0
  30. package/dist/lib/neutral/meta.mjs.map +7 -0
  31. package/dist/lib/neutral/plugin.mjs +11 -0
  32. package/dist/lib/neutral/plugin.mjs.map +7 -0
  33. package/dist/lib/{browser/react-surface-ZGQVH4VX.mjs → neutral/react-surface-4W5YLCHT.mjs} +15 -26
  34. package/dist/lib/neutral/react-surface-4W5YLCHT.mjs.map +7 -0
  35. package/dist/lib/neutral/translations.mjs +39 -0
  36. package/dist/lib/neutral/translations.mjs.map +7 -0
  37. package/dist/lib/neutral/types/index.mjs +1 -0
  38. package/dist/lib/neutral/types/index.mjs.map +7 -0
  39. package/dist/types/src/PipelinePlugin.d.ts +1 -0
  40. package/dist/types/src/PipelinePlugin.d.ts.map +1 -1
  41. package/dist/types/src/PipelinePlugin.node.d.ts +4 -0
  42. package/dist/types/src/PipelinePlugin.node.d.ts.map +1 -0
  43. package/dist/types/src/PipelinePlugin.test.d.ts +2 -0
  44. package/dist/types/src/PipelinePlugin.test.d.ts.map +1 -0
  45. package/dist/types/src/PipelinePlugin.workerd.d.ts +4 -0
  46. package/dist/types/src/PipelinePlugin.workerd.d.ts.map +1 -0
  47. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
  48. package/dist/types/src/capabilities/create-object.d.ts +11 -0
  49. package/dist/types/src/capabilities/create-object.d.ts.map +1 -0
  50. package/dist/types/src/capabilities/index.d.ts +9 -3
  51. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  52. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  53. package/dist/types/src/components/{PipelineColumn.d.ts → PipelineComponent/PipelineColumn.d.ts} +4 -4
  54. package/dist/types/src/components/PipelineComponent/PipelineColumn.d.ts.map +1 -0
  55. package/dist/types/src/components/PipelineComponent/PipelineComponent.d.ts +53 -0
  56. package/dist/types/src/components/PipelineComponent/PipelineComponent.d.ts.map +1 -0
  57. package/dist/types/src/components/PipelineComponent/PipelineComponent.stories.d.ts +62 -0
  58. package/dist/types/src/components/PipelineComponent/PipelineComponent.stories.d.ts.map +1 -0
  59. package/dist/types/src/components/PipelineComponent/index.d.ts +3 -0
  60. package/dist/types/src/components/PipelineComponent/index.d.ts.map +1 -0
  61. package/dist/types/src/components/index.d.ts +0 -1
  62. package/dist/types/src/components/index.d.ts.map +1 -1
  63. package/dist/types/src/containers/PipelineArticle/PipelineArticle.d.ts +6 -0
  64. package/dist/types/src/containers/PipelineArticle/PipelineArticle.d.ts.map +1 -0
  65. package/dist/types/src/containers/PipelineArticle/PipelineArticle.stories.d.ts +76 -0
  66. package/dist/types/src/containers/PipelineArticle/PipelineArticle.stories.d.ts.map +1 -0
  67. package/dist/types/src/containers/PipelineArticle/index.d.ts +2 -0
  68. package/dist/types/src/containers/PipelineArticle/index.d.ts.map +1 -0
  69. package/dist/types/src/containers/PipelineProperties/PipelineProperties.d.ts +11 -0
  70. package/dist/types/src/containers/PipelineProperties/PipelineProperties.d.ts.map +1 -0
  71. package/dist/types/src/containers/PipelineProperties/index.d.ts +2 -0
  72. package/dist/types/src/containers/PipelineProperties/index.d.ts.map +1 -0
  73. package/dist/types/src/containers/index.d.ts +2 -2
  74. package/dist/types/src/containers/index.d.ts.map +1 -1
  75. package/dist/types/src/hooks/usePipelineBoardModel.d.ts.map +1 -1
  76. package/dist/types/src/index.d.ts +0 -1
  77. package/dist/types/src/index.d.ts.map +1 -1
  78. package/dist/types/src/meta.d.ts.map +1 -1
  79. package/dist/types/src/plugin.d.ts +3 -0
  80. package/dist/types/src/plugin.d.ts.map +1 -0
  81. package/dist/types/src/templates/research.d.ts.map +1 -1
  82. package/dist/types/src/translations.d.ts +44 -25
  83. package/dist/types/src/translations.d.ts.map +1 -1
  84. package/dist/types/src/types/index.d.ts +0 -2
  85. package/dist/types/src/types/index.d.ts.map +1 -1
  86. package/dist/types/tsconfig.tsbuildinfo +1 -1
  87. package/package.json +103 -57
  88. package/src/PipelinePlugin.node.ts +19 -0
  89. package/src/PipelinePlugin.test.ts +27 -0
  90. package/src/PipelinePlugin.tsx +7 -31
  91. package/src/PipelinePlugin.workerd.ts +16 -0
  92. package/src/capabilities/app-graph-builder.ts +40 -0
  93. package/src/capabilities/create-object.ts +30 -0
  94. package/src/capabilities/index.ts +5 -3
  95. package/src/capabilities/{react-surface/react-surface.tsx → react-surface.tsx} +16 -15
  96. package/src/components/PipelineComponent/PipelineColumn.tsx +163 -0
  97. package/src/components/{PipelineComponent.stories.tsx → PipelineComponent/PipelineComponent.stories.tsx} +21 -21
  98. package/src/components/{PipelineComponent.tsx → PipelineComponent/PipelineComponent.tsx} +22 -13
  99. package/src/components/PipelineComponent/index.ts +6 -0
  100. package/src/components/index.ts +0 -1
  101. package/src/containers/{PipelineContainer/PipelineContainer.stories.tsx → PipelineArticle/PipelineArticle.stories.tsx} +44 -45
  102. package/src/containers/{PipelineContainer/PipelineContainer.tsx → PipelineArticle/PipelineArticle.tsx} +14 -17
  103. package/src/containers/PipelineArticle/index.ts +5 -0
  104. package/src/containers/{PipelineObjectSettings/PipelineObjectSettings.tsx → PipelineProperties/PipelineProperties.tsx} +68 -75
  105. package/src/containers/PipelineProperties/index.ts +5 -0
  106. package/src/containers/index.ts +2 -2
  107. package/src/hooks/usePipelineBoardModel.ts +6 -6
  108. package/src/index.ts +0 -1
  109. package/src/meta.ts +15 -3
  110. package/src/plugin.ts +9 -0
  111. package/src/templates/research.ts +8 -7
  112. package/src/translations.ts +24 -22
  113. package/src/types/index.ts +0 -3
  114. package/dist/lib/browser/PipelineContainer-2ZYSZATA.mjs +0 -320
  115. package/dist/lib/browser/PipelineContainer-2ZYSZATA.mjs.map +0 -7
  116. package/dist/lib/browser/PipelineObjectSettings-D36OYVHW.mjs.map +0 -7
  117. package/dist/lib/browser/app-graph-builder-NUJB33F7.mjs +0 -65
  118. package/dist/lib/browser/app-graph-builder-NUJB33F7.mjs.map +0 -7
  119. package/dist/lib/browser/chunk-N6FZHYWT.mjs +0 -42
  120. package/dist/lib/browser/chunk-N6FZHYWT.mjs.map +0 -7
  121. package/dist/lib/browser/chunk-QWNKLHBY.mjs +0 -28
  122. package/dist/lib/browser/chunk-QWNKLHBY.mjs.map +0 -7
  123. package/dist/lib/browser/index.mjs +0 -109
  124. package/dist/lib/browser/index.mjs.map +0 -7
  125. package/dist/lib/browser/meta.json +0 -1
  126. package/dist/lib/browser/react-surface-ZGQVH4VX.mjs.map +0 -7
  127. package/dist/lib/browser/types/index.mjs +0 -10
  128. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +0 -1
  129. package/dist/types/src/capabilities/app-graph-builder/index.d.ts +0 -3
  130. package/dist/types/src/capabilities/app-graph-builder/index.d.ts.map +0 -1
  131. package/dist/types/src/capabilities/operation-resolver/index.d.ts +0 -2
  132. package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +0 -1
  133. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +0 -5
  134. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +0 -1
  135. package/dist/types/src/capabilities/react-surface/index.d.ts +0 -3
  136. package/dist/types/src/capabilities/react-surface/index.d.ts.map +0 -1
  137. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +0 -1
  138. package/dist/types/src/components/PipelineColumn.d.ts.map +0 -1
  139. package/dist/types/src/components/PipelineComponent.d.ts +0 -47
  140. package/dist/types/src/components/PipelineComponent.d.ts.map +0 -1
  141. package/dist/types/src/components/PipelineComponent.stories.d.ts +0 -42
  142. package/dist/types/src/components/PipelineComponent.stories.d.ts.map +0 -1
  143. package/dist/types/src/containers/PipelineContainer/PipelineContainer.d.ts +0 -6
  144. package/dist/types/src/containers/PipelineContainer/PipelineContainer.d.ts.map +0 -1
  145. package/dist/types/src/containers/PipelineContainer/PipelineContainer.stories.d.ts +0 -56
  146. package/dist/types/src/containers/PipelineContainer/PipelineContainer.stories.d.ts.map +0 -1
  147. package/dist/types/src/containers/PipelineContainer/index.d.ts +0 -3
  148. package/dist/types/src/containers/PipelineContainer/index.d.ts.map +0 -1
  149. package/dist/types/src/containers/PipelineObjectSettings/PipelineObjectSettings.d.ts +0 -11
  150. package/dist/types/src/containers/PipelineObjectSettings/PipelineObjectSettings.d.ts.map +0 -1
  151. package/dist/types/src/containers/PipelineObjectSettings/index.d.ts +0 -3
  152. package/dist/types/src/containers/PipelineObjectSettings/index.d.ts.map +0 -1
  153. package/dist/types/src/types/PipelineAction.d.ts +0 -25
  154. package/dist/types/src/types/PipelineAction.d.ts.map +0 -1
  155. package/src/capabilities/app-graph-builder/app-graph-builder.ts +0 -51
  156. package/src/capabilities/app-graph-builder/index.ts +0 -7
  157. package/src/capabilities/operation-resolver/index.ts +0 -5
  158. package/src/capabilities/operation-resolver/operation-resolver.ts +0 -29
  159. package/src/capabilities/react-surface/index.ts +0 -7
  160. package/src/components/PipelineColumn.tsx +0 -133
  161. package/src/containers/PipelineContainer/index.ts +0 -7
  162. package/src/containers/PipelineObjectSettings/index.ts +0 -7
  163. package/src/types/PipelineAction.ts +0 -29
  164. /package/dist/lib/{browser/types → neutral}/index.mjs.map +0 -0
  165. /package/dist/types/src/capabilities/{app-graph-builder/app-graph-builder.d.ts → app-graph-builder.d.ts} +0 -0
  166. /package/dist/types/src/capabilities/{react-surface/react-surface.d.ts → react-surface.d.ts} +0 -0
@@ -5,66 +5,61 @@
5
5
  import * as Schema from 'effect/Schema';
6
6
  import React, { useCallback, useMemo, useRef, useState } from 'react';
7
7
 
8
- import { DXN, Filter, JsonSchema, Obj, Query, type QueryAST, Ref, Tag } from '@dxos/echo';
8
+ import { resolveSchemaWithRegistry } from '@dxos/app-toolkit/query';
9
+ import { useTypeOptions } from '@dxos/app-toolkit/ui';
10
+ import { EchoURI, Filter, JsonSchema, Obj, Query, type QueryAST, Ref, Tag, type Type } 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
- import { getSpace, useObject, useQuery } from '@dxos/react-client/echo';
12
+ import { 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';
18
- import { mx, osTranslations, subtleHover } from '@dxos/ui-theme';
17
+ import { Pipeline } from '@dxos/types';
18
+ import { mx, osTranslations } 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
- const space = getSpace(pipeline);
37
+ const db = Obj.getDatabase(pipeline);
39
38
  const [expandedId, setExpandedId] = useState<string>();
40
39
  const [columns, updateColumns] = useObject(pipeline, 'columns');
41
- const column = useMemo(
42
- () => columns.find((column) => column.view.dxn.toString() === expandedId),
43
- [columns, expandedId],
44
- );
40
+ const column = useMemo(() => columns.find((column) => column.view.uri === expandedId), [columns, expandedId]);
45
41
  const [view, updateView] = useObject(column?.view);
46
- const [schema, setSchema] = useState<Schema.Schema.AnyNoContext>(() => Schema.Struct({}));
42
+ const [type, setType] = useState<Type.AnyEntity>();
47
43
  const projectionRef = useRef<ProjectionModel>(null);
48
- const tags = useQuery(space?.db, Filter.type(Tag.Tag));
44
+ const tags = useQuery(db, Filter.type(Tag.Tag));
49
45
  const types = useTypeOptions({
50
- space,
46
+ db,
51
47
  annotation: {
52
48
  location: ['database', 'runtime'],
53
49
  kind: ['user'],
54
- registered: ['registered', 'unregistered'],
55
50
  },
56
51
  });
57
52
 
58
53
  useAsyncEffect(async () => {
59
- if (!view?.query || !space) {
54
+ if (!view?.query || !db) {
60
55
  return;
61
56
  }
62
57
 
63
- const foundSchema = await resolveSchemaWithRegistry(space.db.schemaRegistry, view.query.ast);
64
- if (foundSchema && foundSchema !== schema) {
65
- setSchema(() => foundSchema);
58
+ const foundType = await resolveSchemaWithRegistry(db.schemaRegistry, view.query.ast);
59
+ if (foundType && foundType !== type) {
60
+ setType(() => foundType);
66
61
  }
67
- }, [space, view, schema]);
62
+ }, [db, view, type]);
68
63
 
69
64
  const handleMove = useCallback(
70
65
  (fromIndex: number, toIndex: number) =>
@@ -75,32 +70,32 @@ export const PipelineObjectSettings = ({ classNames, pipeline }: PipelineObjectS
75
70
  );
76
71
 
77
72
  const handleQueryChanged = useCallback(
78
- async (newQuery: QueryAST.Query, target?: string) => {
79
- if (!view || !space) {
73
+ async (newQuery: QueryAST.Query, target?: EchoURI.EchoURI) => {
74
+ if (!view || !db) {
80
75
  return;
81
76
  }
82
77
 
83
- const queue = target && DXN.tryParse(target) ? target : undefined;
84
- const query = queue ? Query.fromAst(newQuery).from({ queues: [queue] }) : Query.fromAst(newQuery);
78
+ const queue = target;
79
+ const query = queue ? Query.fromAst(newQuery).from({ feeds: [queue] }) : Query.fromAst(newQuery);
85
80
  updateView((view) => {
86
81
  view.query.ast = query.ast as Mutable<typeof query.ast>;
87
82
  });
88
- const newSchema = await resolveSchemaWithRegistry(space.db.schemaRegistry, query.ast);
89
- if (!newSchema) {
83
+ const newType = await resolveSchemaWithRegistry(db.schemaRegistry, query.ast);
84
+ if (!newType) {
90
85
  return;
91
86
  }
92
87
 
93
88
  const newView = ViewModel.make({
94
89
  query,
95
- jsonSchema: JsonSchema.toJsonSchema(newSchema),
90
+ jsonSchema: newType.jsonSchema,
96
91
  });
97
92
  updateView((view) => {
98
93
  view.projection = Obj.getSnapshot(newView).projection as Mutable<typeof view.projection>;
99
94
  });
100
95
 
101
- setSchema(() => newSchema);
96
+ setType(() => newType);
102
97
  },
103
- [view, updateView, schema],
98
+ [db, view, updateView, type],
104
99
  );
105
100
 
106
101
  const handleColumnValuesChanged = useCallback(
@@ -120,14 +115,12 @@ export const PipelineObjectSettings = ({ classNames, pipeline }: PipelineObjectS
120
115
  );
121
116
 
122
117
  const handleToggleField = useCallback((column: Pipeline.Column) => {
123
- setExpandedId((prevExpandedId) =>
124
- prevExpandedId === column.view.dxn.toString() ? undefined : column.view.dxn.toString(),
125
- );
118
+ setExpandedId((prevExpandedId) => (prevExpandedId === column.view.uri ? undefined : column.view.uri));
126
119
  }, []);
127
120
 
128
121
  const handleDelete = useCallback(
129
122
  async (column: Pipeline.Column) => {
130
- if (column.view.dxn.toString() === expandedId) {
123
+ if (column.view.uri === expandedId) {
131
124
  setExpandedId(undefined);
132
125
  }
133
126
 
@@ -136,39 +129,39 @@ export const PipelineObjectSettings = ({ classNames, pipeline }: PipelineObjectS
136
129
  updateColumns((columns) => {
137
130
  columns.splice(index, 1);
138
131
  });
139
- space?.db.remove(viewToRemove);
132
+ db?.remove(viewToRemove);
140
133
  },
141
- [expandedId, columns, updateColumns, space],
134
+ [expandedId, columns, updateColumns, db],
142
135
  );
143
136
 
144
137
  const handleAdd = useCallback(() => {
145
- if (!space) {
138
+ if (!db) {
146
139
  return;
147
140
  }
148
141
  const newView = ViewModel.make({
149
- query: Query.select(Filter.type(Task.Task)),
150
- jsonSchema: JsonSchema.toJsonSchema(Task.Task),
142
+ query: Query.select(Filter.nothing()),
143
+ jsonSchema: JsonSchema.toJsonSchema(Schema.Struct({})),
151
144
  });
152
- space.db.add(newView);
145
+ db.add(newView);
153
146
  updateColumns((columns) => {
154
147
  columns.push({
155
- name: 'Tasks',
148
+ name: '',
156
149
  // Type assertion needed due to QueryAST type variance.
157
150
  view: Ref.make(newView) as (typeof columns)[number]['view'],
158
151
  order: [],
159
152
  });
160
153
  });
161
154
  setExpandedId(newView.id);
162
- }, [space, updateColumns]);
155
+ }, [db, updateColumns]);
163
156
 
164
157
  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>
158
+ <div className={mx('py-form-padding overflow-y-auto', classNames)}>
159
+ <h2 className='text-sm text-description py-1'>{t('views.label')}</h2>
167
160
 
168
161
  <List.Root<Pipeline.Column>
169
162
  items={columns}
170
163
  isItem={Schema.is(Pipeline.Column)}
171
- getId={(column) => column.view.dxn.toString()}
164
+ getId={(column) => column.view.uri}
172
165
  onMove={handleMove}
173
166
  >
174
167
  {({ items: columns }) => (
@@ -176,16 +169,18 @@ export const PipelineObjectSettings = ({ classNames, pipeline }: PipelineObjectS
176
169
  <div role='list' className={mx(listGrid)}>
177
170
  {columns.map((column) => (
178
171
  <List.Item<Pipeline.Column>
179
- key={column.view.dxn.toString()}
172
+ key={column.view.uri}
180
173
  item={column}
181
174
  classNames={listItemGrid}
182
- aria-expanded={expandedId === column.view.dxn.toString()}
175
+ aria-expanded={expandedId === column.view.uri}
183
176
  >
184
- <div role='none' className={mx(subtleHover, listItemGrid, 'rounded-xs cursor-pointer min-h-10')}>
177
+ <div className={mx(listItemGrid, 'dx-hover rounded-xs cursor-pointer min-h-10')}>
185
178
  <List.ItemDragHandle />
186
- <List.ItemTitle onClick={() => handleToggleField(column)}>{column.name}</List.ItemTitle>
179
+ <List.ItemTitle onClick={() => handleToggleField(column)}>
180
+ {column.name || t('untitled-view.title')}
181
+ </List.ItemTitle>
187
182
  <List.ItemDeleteButton
188
- label={t('delete view label')}
183
+ label={t('delete-view.label')}
189
184
  autoHide={false}
190
185
  onClick={() => handleDelete(column)}
191
186
  data-testid='view.delete'
@@ -193,17 +188,13 @@ export const PipelineObjectSettings = ({ classNames, pipeline }: PipelineObjectS
193
188
  <IconButton
194
189
  iconOnly
195
190
  variant='ghost'
196
- label={t('toggle expand label', { ns: osTranslations })}
197
- icon={
198
- expandedId === column.view.dxn.toString()
199
- ? 'ph--caret-down--regular'
200
- : 'ph--caret-right--regular'
201
- }
191
+ label={t('toggle-expand.label', { ns: osTranslations })}
192
+ icon={expandedId === column.view.uri ? 'ph--caret-down--regular' : 'ph--caret-right--regular'}
202
193
  onClick={() => handleToggleField(column)}
203
194
  />
204
195
  </div>
205
- {expandedId === column.view.dxn.toString() && column?.view.target && (
206
- <div role='none' className='col-span-5 my-2 border border-separator rounded-md'>
196
+ {expandedId === column.view.uri && column?.view.target && (
197
+ <div className='col-span-5 my-2 border border-separator rounded-md'>
207
198
  <Form.Root
208
199
  schema={ColumnFormSchema}
209
200
  values={column}
@@ -213,18 +204,20 @@ export const PipelineObjectSettings = ({ classNames, pipeline }: PipelineObjectS
213
204
  <Form.FieldSet />
214
205
  </Form.Content>
215
206
  </Form.Root>
216
- <ViewEditor
217
- ref={projectionRef}
218
- mode='tag'
219
- readonly
220
- schema={schema}
221
- view={column.view.target}
222
- registry={space?.db.schemaRegistry}
223
- db={space?.db}
224
- tags={tags}
225
- types={types}
226
- onQueryChanged={handleQueryChanged}
227
- />
207
+ {type && (
208
+ <ViewEditor
209
+ ref={projectionRef}
210
+ mode='tag'
211
+ readonly
212
+ type={type}
213
+ view={column.view.target}
214
+ registry={db?.schemaRegistry}
215
+ db={db}
216
+ tags={tags}
217
+ types={types}
218
+ onQueryChanged={handleQueryChanged}
219
+ />
220
+ )}
228
221
  </div>
229
222
  )}
230
223
  </List.Item>
@@ -234,8 +227,8 @@ export const PipelineObjectSettings = ({ classNames, pipeline }: PipelineObjectS
234
227
  )}
235
228
  </List.Root>
236
229
 
237
- <div role='none' className='my-form-padding'>
238
- <IconButton icon='ph--plus--regular' label={t('add view label')} onClick={handleAdd} classNames='w-full' />
230
+ <div className='my-form-padding'>
231
+ <IconButton icon='ph--plus--regular' label={t('add-view.label')} onClick={handleAdd} classNames='w-full' />
239
232
  </div>
240
233
  </div>
241
234
  );
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export { PipelineProperties as default } from './PipelineProperties';
@@ -4,5 +4,5 @@
4
4
 
5
5
  import { type ComponentType, lazy } from 'react';
6
6
 
7
- export const PipelineContainer: ComponentType<any> = lazy(() => import('./PipelineContainer'));
8
- export const PipelineObjectSettings: ComponentType<any> = lazy(() => import('./PipelineObjectSettings'));
7
+ export const PipelineArticle: ComponentType<any> = lazy(() => import('./PipelineArticle'));
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';
@@ -27,7 +27,7 @@ export const usePipelineBoardModel = (
27
27
  const columnAtomFamily = Atom.family<string, Atom.Atom<Pipeline.Column | undefined>>((viewKey: string) =>
28
28
  Atom.make((get) => {
29
29
  const columns = get(columnsAtom);
30
- return columns.find((c) => c.view.dxn.toString() === viewKey);
30
+ return columns.find((c) => c.view.uri === viewKey);
31
31
  }),
32
32
  );
33
33
 
@@ -52,14 +52,14 @@ export const usePipelineBoardModel = (
52
52
  );
53
53
 
54
54
  return {
55
- getColumnId: (data) => (data as Pipeline.Column).view.dxn.toString(),
55
+ getColumnId: (data) => (data as Pipeline.Column).view.uri,
56
56
  getItemId: (data) => (data as Obj.Unknown).id,
57
57
  isColumn: (obj: unknown): obj is Pipeline.Column => Schema.is(Pipeline.Column)(obj),
58
58
  isItem: (obj: unknown): obj is Obj.Unknown => Obj.isObject(obj),
59
59
  columns: columnsAtom,
60
- items: (column) => itemsAtomFamily(column.view.dxn.toString()),
60
+ items: (column) => itemsAtomFamily(column.view.uri),
61
61
  getColumns: () => [...registry.get(columnsAtom)],
62
- getItems: (column) => registry.get(itemsAtomFamily(column.view.dxn.toString())) ?? [],
62
+ getItems: (column) => registry.get(itemsAtomFamily(column.view.uri)) ?? [],
63
63
  };
64
64
  }, [pipeline, registry]);
65
65
 
@@ -68,7 +68,7 @@ const emptyColumnsAtom = Atom.make(() => [] as Pipeline.Column[]);
68
68
  const emptyItemsAtom = Atom.make(() => [] as Obj.Unknown[]);
69
69
 
70
70
  const emptyPipelineModel: BoardModel<Pipeline.Column, Obj.Unknown> = {
71
- getColumnId: (data) => (data as Pipeline.Column).view.dxn.toString(),
71
+ getColumnId: (data) => (data as Pipeline.Column).view.uri,
72
72
  getItemId: (data) => (data as Obj.Unknown).id,
73
73
  isColumn: (obj: unknown): obj is Pipeline.Column => Schema.is(Pipeline.Column)(obj),
74
74
  isItem: (obj): obj is Obj.Unknown => Obj.isObject(obj),
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,14 +6,26 @@ 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
+ author: 'DXOS',
11
12
  description: trim`
12
- Pipelines for organizing tasks, milestones, and deliverables.
13
- Track progress across multiple pipelines and coordinate team activities in a structured environment.
13
+ A multi-column Kanban-style pipeline plugin for DXOS Composer.
14
+ Each Pipeline holds an ordered set of Columns; each Column is backed by a ViewModel whose query
15
+ can select any ECHO object type — messages, contacts, documents, or custom types — from the active space.
16
+
17
+ Columns are fully configurable through the Settings companion panel, where users can add, rename,
18
+ reorder, and delete columns and edit the underlying query and projection for each column.
19
+ Objects can be dragged between columns and the full pipeline state, including column order and
20
+ per-column item order, persists collaboratively via ECHO.
21
+
22
+ A built-in Research template scaffolds a four-column pipeline wired to the Mailbox, Contacts,
23
+ Organizations, and Notes objects in the space, providing an out-of-the-box CRM-style workflow.
24
+ Pipeline articles also expose Invocations and Automation companion tabs for AI-driven automation.
14
25
  `,
15
26
  icon: 'ph--path--regular',
16
27
  iconHue: 'purple',
17
28
  source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-pipeline',
29
+ spec: 'PLUGIN.mdl',
18
30
  tags: ['labs'],
19
31
  };
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
 
@@ -1,37 +1,39 @@
1
+ import { Type } from '@dxos/echo';
1
2
  import { type Resource } from '@dxos/react-ui';
2
3
  import { Pipeline } from '@dxos/types';
3
4
  //
4
5
  // Copyright 2023 DXOS.org
5
6
  //
6
7
 
7
- import { meta } from './meta';
8
+ import { meta } from '#meta';
8
9
 
9
10
  export const translations = [
10
11
  {
11
12
  'en-US': {
12
- [Pipeline.Pipeline.typename]: {
13
- 'typename label': 'Pipeline',
14
- 'typename label_zero': 'Pipelines',
15
- 'typename label_one': 'Pipeline',
16
- 'typename label_other': 'Pipelines',
17
- 'object name placeholder': 'New pipeline',
18
- 'rename object label': 'Rename pipeline',
19
- 'delete object label': 'Delete pipeline',
20
- 'object deleted label': 'Pipeline deleted',
13
+ [Type.getTypename(Pipeline.Pipeline)]: {
14
+ 'typename.label': 'Pipeline',
15
+ 'typename.label_zero': 'Pipelines',
16
+ 'typename.label_one': 'Pipeline',
17
+ 'typename.label_other': 'Pipelines',
18
+ 'object-name.placeholder': 'New pipeline',
19
+ 'add-object.label': 'Add pipeline',
20
+ 'rename-object.label': 'Rename pipeline',
21
+ 'delete-object.label': 'Delete pipeline',
22
+ 'object-deleted.label': 'Pipeline deleted',
21
23
  },
22
24
  [meta.id]: {
23
- 'plugin name': 'Pipelines',
24
- 'add column label': 'Add column',
25
- 'add card label': 'Add object',
26
- 'untitled view title': 'New view',
27
- 'enumerating tab label': 'List',
28
- 'editing tab label': 'Edit',
29
- 'views label': 'Views',
30
- 'pipeline invocations label': 'Invocations',
31
- 'pipeline automation label': 'Automations',
32
- 'toggle expand label': 'Toggle expand',
33
- 'delete view label': 'Delete view',
34
- 'add view label': 'Add view',
25
+ 'plugin.name': 'Pipelines',
26
+ 'add-column.label': 'Add column',
27
+ 'add-card.label': 'Add object',
28
+ 'untitled-view.title': 'New view',
29
+ 'enumerating-tab.label': 'List',
30
+ 'editing-tab.label': 'Edit',
31
+ 'views.label': 'Views',
32
+ 'pipeline-invocations.label': 'Invocations',
33
+ 'pipeline-automation.label': 'Automations',
34
+ 'toggle-expand.label': 'Toggle expand',
35
+ 'delete-view.label': 'Delete view',
36
+ 'add-view.label': 'Add view',
35
37
  },
36
38
  },
37
39
  },
@@ -1,6 +1,3 @@
1
1
  //
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
-
5
- export * as PipelineAction from './PipelineAction';
6
- export { PipelineOperation } from './PipelineAction';