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

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