@dxos/plugin-pipeline 0.8.4-main.fcfe5033a5 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +102 -5
- package/PLUGIN.mdl +345 -0
- package/README.md +1 -1
- package/dist/lib/neutral/PipelineArticle-6JIVXMYF.mjs +69 -0
- package/dist/lib/neutral/PipelineArticle-6JIVXMYF.mjs.map +7 -0
- package/dist/lib/neutral/PipelinePlugin.mjs +38 -0
- package/dist/lib/neutral/PipelinePlugin.mjs.map +7 -0
- package/dist/lib/neutral/PipelinePlugin.node.mjs +21 -0
- package/dist/lib/neutral/PipelinePlugin.node.mjs.map +7 -0
- package/dist/lib/neutral/PipelinePlugin.workerd.mjs +16 -0
- package/dist/lib/neutral/PipelinePlugin.workerd.mjs.map +7 -0
- package/dist/lib/neutral/PipelineProperties-JZQYG2CN.mjs +209 -0
- package/dist/lib/neutral/PipelineProperties-JZQYG2CN.mjs.map +7 -0
- package/dist/lib/neutral/app-graph-builder-ZLGRWRJU.mjs +44 -0
- package/dist/lib/neutral/app-graph-builder-ZLGRWRJU.mjs.map +7 -0
- package/dist/lib/neutral/capabilities/index.mjs +11 -0
- package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
- package/dist/lib/neutral/chunk-CYXDAAKN.mjs +35 -0
- package/dist/lib/neutral/chunk-CYXDAAKN.mjs.map +7 -0
- package/dist/lib/neutral/components/index.mjs +203 -0
- package/dist/lib/neutral/components/index.mjs.map +7 -0
- package/dist/lib/neutral/containers/index.mjs +9 -0
- package/dist/lib/neutral/containers/index.mjs.map +7 -0
- package/dist/lib/neutral/create-object-6Z4MMGX4.mjs +26 -0
- package/dist/lib/neutral/create-object-6Z4MMGX4.mjs.map +7 -0
- package/dist/lib/neutral/hooks/index.mjs +69 -0
- package/dist/lib/neutral/hooks/index.mjs.map +7 -0
- package/dist/lib/neutral/index.mjs +7 -0
- package/dist/lib/neutral/meta.json +1 -0
- package/dist/lib/neutral/meta.mjs +7 -0
- package/dist/lib/neutral/meta.mjs.map +7 -0
- package/dist/lib/neutral/plugin.mjs +11 -0
- package/dist/lib/neutral/plugin.mjs.map +7 -0
- package/dist/lib/neutral/react-surface-QG7QSZSS.mjs +49 -0
- package/dist/lib/neutral/react-surface-QG7QSZSS.mjs.map +7 -0
- package/dist/lib/neutral/translations.mjs +39 -0
- package/dist/lib/neutral/translations.mjs.map +7 -0
- package/dist/lib/neutral/types/index.mjs.map +7 -0
- package/dist/types/src/PipelinePlugin.d.ts +1 -0
- package/dist/types/src/PipelinePlugin.d.ts.map +1 -1
- package/dist/types/src/PipelinePlugin.node.d.ts +4 -0
- package/dist/types/src/PipelinePlugin.node.d.ts.map +1 -0
- package/dist/types/src/PipelinePlugin.test.d.ts +2 -0
- package/dist/types/src/PipelinePlugin.test.d.ts.map +1 -0
- package/dist/types/src/PipelinePlugin.workerd.d.ts +4 -0
- package/dist/types/src/PipelinePlugin.workerd.d.ts.map +1 -0
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/capabilities/create-object.d.ts +11 -0
- package/dist/types/src/capabilities/create-object.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +6 -0
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/components/PipelineComponent/PipelineColumn.d.ts +4 -4
- package/dist/types/src/components/PipelineComponent/PipelineColumn.d.ts.map +1 -1
- package/dist/types/src/components/PipelineComponent/PipelineComponent.d.ts +4 -0
- package/dist/types/src/components/PipelineComponent/PipelineComponent.d.ts.map +1 -1
- package/dist/types/src/components/PipelineComponent/PipelineComponent.stories.d.ts +44 -25
- package/dist/types/src/components/PipelineComponent/PipelineComponent.stories.d.ts.map +1 -1
- package/dist/types/src/containers/PipelineArticle/PipelineArticle.d.ts +6 -0
- package/dist/types/src/containers/PipelineArticle/PipelineArticle.d.ts.map +1 -0
- package/dist/types/src/containers/PipelineArticle/PipelineArticle.stories.d.ts +76 -0
- package/dist/types/src/containers/PipelineArticle/PipelineArticle.stories.d.ts.map +1 -0
- package/dist/types/src/containers/PipelineArticle/index.d.ts +2 -0
- package/dist/types/src/containers/PipelineArticle/index.d.ts.map +1 -0
- package/dist/types/src/containers/PipelineProperties/PipelineProperties.d.ts.map +1 -1
- package/dist/types/src/containers/index.d.ts +1 -1
- package/dist/types/src/containers/index.d.ts.map +1 -1
- package/dist/types/src/hooks/usePipelineBoardModel.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +0 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +1 -1
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/plugin.d.ts +3 -0
- package/dist/types/src/plugin.d.ts.map +1 -0
- package/dist/types/src/templates/research.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +44 -26
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +100 -64
- package/src/PipelinePlugin.node.ts +19 -0
- package/src/PipelinePlugin.test.ts +27 -0
- package/src/PipelinePlugin.tsx +10 -29
- package/src/PipelinePlugin.workerd.ts +16 -0
- package/src/capabilities/create-object.ts +30 -0
- package/src/capabilities/index.ts +1 -0
- package/src/capabilities/react-surface.tsx +3 -3
- package/src/components/PipelineComponent/PipelineColumn.tsx +23 -33
- package/src/components/PipelineComponent/PipelineComponent.stories.tsx +6 -8
- package/src/components/PipelineComponent/PipelineComponent.tsx +2 -2
- package/src/containers/{PipelineContainer/PipelineContainer.stories.tsx → PipelineArticle/PipelineArticle.stories.tsx} +18 -22
- package/src/containers/{PipelineContainer/PipelineContainer.tsx → PipelineArticle/PipelineArticle.tsx} +6 -8
- package/src/containers/PipelineArticle/index.ts +5 -0
- package/src/containers/PipelineProperties/PipelineProperties.tsx +45 -53
- package/src/containers/index.ts +1 -1
- package/src/hooks/usePipelineBoardModel.ts +8 -9
- package/src/index.ts +0 -1
- package/src/meta.ts +19 -6
- package/src/plugin.ts +9 -0
- package/src/templates/research.ts +2 -2
- package/src/translations.ts +2 -1
- package/src/vite-env.d.ts +10 -0
- package/dist/lib/browser/index.mjs +0 -98
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/types/src/containers/PipelineContainer/PipelineContainer.d.ts +0 -6
- package/dist/types/src/containers/PipelineContainer/PipelineContainer.d.ts.map +0 -1
- package/dist/types/src/containers/PipelineContainer/PipelineContainer.stories.d.ts +0 -57
- package/dist/types/src/containers/PipelineContainer/PipelineContainer.stories.d.ts.map +0 -1
- package/dist/types/src/containers/PipelineContainer/index.d.ts +0 -2
- package/dist/types/src/containers/PipelineContainer/index.d.ts.map +0 -1
- package/src/containers/PipelineContainer/index.ts +0 -5
- /package/dist/lib/{browser/types → neutral}/index.mjs.map +0 -0
- /package/dist/lib/{browser → neutral}/types/index.mjs +0 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/PipelinePlugin.node.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { Plugin } from '@dxos/app-framework';\nimport { AppPlugin } from '@dxos/app-toolkit';\nimport { Pipeline } from '@dxos/types';\n\nimport { AppGraphBuilder, CreateObject } from '#capabilities';\nimport { meta } from '#meta';\n\nexport const PipelinePlugin = Plugin.define(meta).pipe(\n AppPlugin.addAppGraphModule({ activate: AppGraphBuilder }),\n AppPlugin.addCreateObjectModule({ activate: CreateObject }),\n AppPlugin.addSchemaModule({ schema: [Pipeline.Pipeline] }),\n Plugin.make,\n);\n\nexport default PipelinePlugin;\n"],
|
|
5
|
+
"mappings": ";AAIA,SAASA,cAAc;AACvB,SAASC,iBAAiB;AAC1B,SAASC,gBAAgB;AAEzB,SAASC,iBAAiBC,oBAAoB;AAC9C,SAASC,YAAY;AAEd,IAAMC,iBAAiBN,OAAOO,OAAOF,IAAAA,EAAMG,KAChDP,UAAUQ,kBAAkB;EAAEC,UAAUP;AAAgB,CAAA,GACxDF,UAAUU,sBAAsB;EAAED,UAAUN;AAAa,CAAA,GACzDH,UAAUW,gBAAgB;EAAEC,QAAQ;IAACX,SAASA;;AAAU,CAAA,GACxDF,OAAOc,IAAI;AAGb,IAAA,8BAAeR;",
|
|
6
|
+
"names": ["Plugin", "AppPlugin", "Pipeline", "AppGraphBuilder", "CreateObject", "meta", "PipelinePlugin", "define", "pipe", "addAppGraphModule", "activate", "addCreateObjectModule", "addSchemaModule", "schema", "make"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// src/PipelinePlugin.workerd.ts
|
|
2
|
+
import { Plugin } from "@dxos/app-framework";
|
|
3
|
+
import { AppPlugin } from "@dxos/app-toolkit";
|
|
4
|
+
import { Pipeline } from "@dxos/types";
|
|
5
|
+
import { meta } from "#meta";
|
|
6
|
+
var PipelinePlugin = Plugin.define(meta).pipe(AppPlugin.addSchemaModule({
|
|
7
|
+
schema: [
|
|
8
|
+
Pipeline.Pipeline
|
|
9
|
+
]
|
|
10
|
+
}), Plugin.make);
|
|
11
|
+
var PipelinePlugin_workerd_default = PipelinePlugin;
|
|
12
|
+
export {
|
|
13
|
+
PipelinePlugin,
|
|
14
|
+
PipelinePlugin_workerd_default as default
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=PipelinePlugin.workerd.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/PipelinePlugin.workerd.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { Plugin } from '@dxos/app-framework';\nimport { AppPlugin } from '@dxos/app-toolkit';\nimport { Pipeline } from '@dxos/types';\n\nimport { meta } from '#meta';\n\nexport const PipelinePlugin = Plugin.define(meta).pipe(\n AppPlugin.addSchemaModule({ schema: [Pipeline.Pipeline] }),\n Plugin.make,\n);\n\nexport default PipelinePlugin;\n"],
|
|
5
|
+
"mappings": ";AAIA,SAASA,cAAc;AACvB,SAASC,iBAAiB;AAC1B,SAASC,gBAAgB;AAEzB,SAASC,YAAY;AAEd,IAAMC,iBAAiBJ,OAAOK,OAAOF,IAAAA,EAAMG,KAChDL,UAAUM,gBAAgB;EAAEC,QAAQ;IAACN,SAASA;;AAAU,CAAA,GACxDF,OAAOS,IAAI;AAGb,IAAA,iCAAeL;",
|
|
6
|
+
"names": ["Plugin", "AppPlugin", "Pipeline", "meta", "PipelinePlugin", "define", "pipe", "addSchemaModule", "schema", "make"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
// src/containers/PipelineProperties/PipelineProperties.tsx
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
import React, { useCallback, useMemo, useRef, useState } from "react";
|
|
4
|
+
import { resolveSchemaWithRegistry } from "@dxos/app-toolkit/query";
|
|
5
|
+
import { useTypeOptions } from "@dxos/app-toolkit/ui";
|
|
6
|
+
import { Filter, JsonSchema, Obj, Query, Ref, Scope, Tag } from "@dxos/echo";
|
|
7
|
+
import { useObject, useQuery } from "@dxos/react-client/echo";
|
|
8
|
+
import { IconButton, useAsyncEffect, useTranslation } from "@dxos/react-ui";
|
|
9
|
+
import { Form, ViewEditor } from "@dxos/react-ui-form";
|
|
10
|
+
import { List } from "@dxos/react-ui-list";
|
|
11
|
+
import { ViewModel } from "@dxos/schema";
|
|
12
|
+
import { Pipeline } from "@dxos/types";
|
|
13
|
+
import { mx, osTranslations } from "@dxos/ui-theme";
|
|
14
|
+
import { arrayMove } from "@dxos/util";
|
|
15
|
+
import { meta } from "#meta";
|
|
16
|
+
var listGrid = "grid grid-cols-[min-content_1fr_min-content_min-content_min-content]";
|
|
17
|
+
var listItemGrid = "grid grid-cols-subgrid col-span-5";
|
|
18
|
+
var ColumnFormSchema = Pipeline.Column.pipe(Schema.mutable, Schema.pick("name"));
|
|
19
|
+
var PipelineProperties = ({ classNames, pipeline }) => {
|
|
20
|
+
const { t } = useTranslation(meta.id);
|
|
21
|
+
const db = Obj.getDatabase(pipeline);
|
|
22
|
+
const [expandedId, setExpandedId] = useState();
|
|
23
|
+
const [columns, updateColumns] = useObject(pipeline, "columns");
|
|
24
|
+
const column = useMemo(() => columns.find((column2) => column2.view.uri === expandedId), [
|
|
25
|
+
columns,
|
|
26
|
+
expandedId
|
|
27
|
+
]);
|
|
28
|
+
const [view, updateView] = useObject(column?.view);
|
|
29
|
+
const [type, setType] = useState();
|
|
30
|
+
const projectionRef = useRef(null);
|
|
31
|
+
const tags = useQuery(db, Filter.type(Tag.Tag));
|
|
32
|
+
const types = useTypeOptions({
|
|
33
|
+
db,
|
|
34
|
+
annotation: {
|
|
35
|
+
location: [
|
|
36
|
+
"database",
|
|
37
|
+
"runtime"
|
|
38
|
+
],
|
|
39
|
+
kind: [
|
|
40
|
+
"user"
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
useAsyncEffect(async () => {
|
|
45
|
+
if (!view?.query || !db) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const foundType = await resolveSchemaWithRegistry(db, view.query.ast);
|
|
49
|
+
if (foundType && foundType !== type) {
|
|
50
|
+
setType(() => foundType);
|
|
51
|
+
}
|
|
52
|
+
}, [
|
|
53
|
+
db,
|
|
54
|
+
view,
|
|
55
|
+
type
|
|
56
|
+
]);
|
|
57
|
+
const handleMove = useCallback((fromIndex, toIndex) => updateColumns((columns2) => {
|
|
58
|
+
arrayMove(columns2, fromIndex, toIndex);
|
|
59
|
+
}), [
|
|
60
|
+
updateColumns
|
|
61
|
+
]);
|
|
62
|
+
const handleQueryChanged = useCallback(async (newQuery, target) => {
|
|
63
|
+
if (!view || !db) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const queue = target;
|
|
67
|
+
const query = queue ? Query.fromAst(newQuery).from([
|
|
68
|
+
Scope.feed(String(queue))
|
|
69
|
+
]) : Query.fromAst(newQuery);
|
|
70
|
+
updateView((view2) => {
|
|
71
|
+
view2.query.ast = query.ast;
|
|
72
|
+
});
|
|
73
|
+
const newType = await resolveSchemaWithRegistry(db, query.ast);
|
|
74
|
+
if (!newType) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const newView = ViewModel.make({
|
|
78
|
+
query,
|
|
79
|
+
jsonSchema: newType.jsonSchema
|
|
80
|
+
});
|
|
81
|
+
updateView((view2) => {
|
|
82
|
+
view2.projection = Obj.getSnapshot(newView).projection;
|
|
83
|
+
});
|
|
84
|
+
setType(() => newType);
|
|
85
|
+
}, [
|
|
86
|
+
db,
|
|
87
|
+
view,
|
|
88
|
+
updateView,
|
|
89
|
+
type
|
|
90
|
+
]);
|
|
91
|
+
const handleColumnValuesChanged = useCallback((column2) => (newValues, { changed }) => {
|
|
92
|
+
if (changed["name"]) {
|
|
93
|
+
const columnIndex = columns.findIndex((c) => c === column2);
|
|
94
|
+
if (columnIndex === -1) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
updateColumns((cols) => {
|
|
98
|
+
cols[columnIndex].name = newValues.name ?? "";
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}, [
|
|
102
|
+
columns,
|
|
103
|
+
updateColumns
|
|
104
|
+
]);
|
|
105
|
+
const handleToggleField = useCallback((column2) => {
|
|
106
|
+
setExpandedId((prevExpandedId) => prevExpandedId === column2.view.uri ? void 0 : column2.view.uri);
|
|
107
|
+
}, []);
|
|
108
|
+
const handleDelete = useCallback(async (column2) => {
|
|
109
|
+
if (column2.view.uri === expandedId) {
|
|
110
|
+
setExpandedId(void 0);
|
|
111
|
+
}
|
|
112
|
+
const index = columns.findIndex((l) => l === column2);
|
|
113
|
+
const viewToRemove = await column2.view.load();
|
|
114
|
+
updateColumns((columns2) => {
|
|
115
|
+
columns2.splice(index, 1);
|
|
116
|
+
});
|
|
117
|
+
db?.remove(viewToRemove);
|
|
118
|
+
}, [
|
|
119
|
+
expandedId,
|
|
120
|
+
columns,
|
|
121
|
+
updateColumns,
|
|
122
|
+
db
|
|
123
|
+
]);
|
|
124
|
+
const handleAdd = useCallback(() => {
|
|
125
|
+
if (!db) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const newView = ViewModel.make({
|
|
129
|
+
query: Query.select(Filter.nothing()),
|
|
130
|
+
jsonSchema: JsonSchema.toJsonSchema(Schema.Struct({}))
|
|
131
|
+
});
|
|
132
|
+
db.add(newView);
|
|
133
|
+
updateColumns((columns2) => {
|
|
134
|
+
columns2.push({
|
|
135
|
+
name: "",
|
|
136
|
+
// Type assertion needed due to QueryAST type variance.
|
|
137
|
+
view: Ref.make(newView),
|
|
138
|
+
order: []
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
setExpandedId(newView.id);
|
|
142
|
+
}, [
|
|
143
|
+
db,
|
|
144
|
+
updateColumns
|
|
145
|
+
]);
|
|
146
|
+
return /* @__PURE__ */ React.createElement("div", {
|
|
147
|
+
className: mx("py-form-padding overflow-y-auto", classNames)
|
|
148
|
+
}, /* @__PURE__ */ React.createElement("h2", {
|
|
149
|
+
className: "text-sm text-description py-1"
|
|
150
|
+
}, t("views.label")), /* @__PURE__ */ React.createElement(List.Root, {
|
|
151
|
+
items: columns,
|
|
152
|
+
isItem: Schema.is(Pipeline.Column),
|
|
153
|
+
getId: (column2) => column2.view.uri,
|
|
154
|
+
onMove: handleMove
|
|
155
|
+
}, ({ items: columns2 }) => /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", {
|
|
156
|
+
role: "list",
|
|
157
|
+
className: mx(listGrid)
|
|
158
|
+
}, columns2.map((column2) => /* @__PURE__ */ React.createElement(List.Item, {
|
|
159
|
+
key: column2.view.uri,
|
|
160
|
+
item: column2,
|
|
161
|
+
classNames: listItemGrid,
|
|
162
|
+
"aria-expanded": expandedId === column2.view.uri
|
|
163
|
+
}, /* @__PURE__ */ React.createElement("div", {
|
|
164
|
+
className: mx(listItemGrid, "dx-hover rounded-xs cursor-pointer min-h-10")
|
|
165
|
+
}, /* @__PURE__ */ React.createElement(List.ItemDragHandle, null), /* @__PURE__ */ React.createElement(List.ItemTitle, {
|
|
166
|
+
onClick: () => handleToggleField(column2)
|
|
167
|
+
}, column2.name || t("untitled-view.title")), /* @__PURE__ */ React.createElement(List.ItemDeleteButton, {
|
|
168
|
+
label: t("delete-view.label"),
|
|
169
|
+
autoHide: false,
|
|
170
|
+
onClick: () => handleDelete(column2),
|
|
171
|
+
"data-testid": "view.delete"
|
|
172
|
+
}), /* @__PURE__ */ React.createElement(IconButton, {
|
|
173
|
+
iconOnly: true,
|
|
174
|
+
variant: "ghost",
|
|
175
|
+
label: t("toggle-expand.label", {
|
|
176
|
+
ns: osTranslations
|
|
177
|
+
}),
|
|
178
|
+
icon: expandedId === column2.view.uri ? "ph--caret-down--regular" : "ph--caret-right--regular",
|
|
179
|
+
onClick: () => handleToggleField(column2)
|
|
180
|
+
})), expandedId === column2.view.uri && column2?.view.target && /* @__PURE__ */ React.createElement("div", {
|
|
181
|
+
className: "col-span-5 my-2 border border-separator rounded-md"
|
|
182
|
+
}, /* @__PURE__ */ React.createElement(Form.Root, {
|
|
183
|
+
schema: ColumnFormSchema,
|
|
184
|
+
values: column2,
|
|
185
|
+
onValuesChanged: handleColumnValuesChanged(column2)
|
|
186
|
+
}, /* @__PURE__ */ React.createElement(Form.Content, null, /* @__PURE__ */ React.createElement(Form.FieldSet, null))), /* @__PURE__ */ React.createElement(ViewEditor, {
|
|
187
|
+
ref: projectionRef,
|
|
188
|
+
mode: "tag",
|
|
189
|
+
readonly: true,
|
|
190
|
+
type,
|
|
191
|
+
view: column2.view.target,
|
|
192
|
+
registry: db?.graph.registry,
|
|
193
|
+
db,
|
|
194
|
+
tags,
|
|
195
|
+
types,
|
|
196
|
+
onQueryChanged: handleQueryChanged
|
|
197
|
+
}))))))), /* @__PURE__ */ React.createElement("div", {
|
|
198
|
+
className: "my-form-padding"
|
|
199
|
+
}, /* @__PURE__ */ React.createElement(IconButton, {
|
|
200
|
+
icon: "ph--plus--regular",
|
|
201
|
+
label: t("add-view.label"),
|
|
202
|
+
onClick: handleAdd,
|
|
203
|
+
classNames: "w-full"
|
|
204
|
+
})));
|
|
205
|
+
};
|
|
206
|
+
export {
|
|
207
|
+
PipelineProperties as default
|
|
208
|
+
};
|
|
209
|
+
//# sourceMappingURL=PipelineProperties-JZQYG2CN.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/containers/PipelineProperties/PipelineProperties.tsx"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Schema from 'effect/Schema';\nimport React, { useCallback, useMemo, useRef, useState } from 'react';\n\nimport { resolveSchemaWithRegistry } from '@dxos/app-toolkit/query';\nimport { useTypeOptions } from '@dxos/app-toolkit/ui';\nimport { EID, Filter, JsonSchema, Obj, Query, type QueryAST, Ref, Scope, Tag, type Type } from '@dxos/echo';\nimport { type Mutable } from '@dxos/echo/Obj';\nimport { SchemaEx } from '@dxos/effect';\nimport { useObject, useQuery } from '@dxos/react-client/echo';\nimport { IconButton, type ThemedClassName, useAsyncEffect, useTranslation } from '@dxos/react-ui';\nimport { Form, ViewEditor } from '@dxos/react-ui-form';\nimport { List } from '@dxos/react-ui-list';\nimport { type ProjectionModel, ViewModel } from '@dxos/schema';\nimport { Pipeline } from '@dxos/types';\nimport { mx, osTranslations } from '@dxos/ui-theme';\nimport { arrayMove } from '@dxos/util';\n\nimport { meta } from '#meta';\n\nconst listGrid = 'grid grid-cols-[min-content_1fr_min-content_min-content_min-content]';\nconst listItemGrid = 'grid grid-cols-subgrid col-span-5';\n\nconst ColumnFormSchema = Pipeline.Column.pipe(Schema.mutable, Schema.pick('name'));\n\nexport type PipelinePropertiesProps = ThemedClassName<{\n pipeline: Pipeline.Pipeline;\n}>;\n\n/**\n * Supports editing the pipeline view.\n */\nexport const PipelineProperties = ({ classNames, pipeline }: PipelinePropertiesProps) => {\n const { t } = useTranslation(meta.id);\n const db = Obj.getDatabase(pipeline);\n const [expandedId, setExpandedId] = useState<string>();\n const [columns, updateColumns] = useObject(pipeline, 'columns');\n const column = useMemo(() => columns.find((column) => column.view.uri === expandedId), [columns, expandedId]);\n const [view, updateView] = useObject(column?.view);\n const [type, setType] = useState<Type.AnyEntity>();\n const projectionRef = useRef<ProjectionModel>(null);\n const tags = useQuery(db, Filter.type(Tag.Tag));\n const types = useTypeOptions({\n db,\n annotation: {\n location: ['database', 'runtime'],\n kind: ['user'],\n },\n });\n\n useAsyncEffect(async () => {\n if (!view?.query || !db) {\n return;\n }\n\n const foundType = await resolveSchemaWithRegistry(db, view.query.ast);\n if (foundType && foundType !== type) {\n setType(() => foundType);\n }\n }, [db, view, type]);\n\n const handleMove = useCallback(\n (fromIndex: number, toIndex: number) =>\n updateColumns((columns) => {\n arrayMove(columns, fromIndex, toIndex);\n }),\n [updateColumns],\n );\n\n const handleQueryChanged = useCallback(\n async (newQuery: QueryAST.Query, target?: EID.EID) => {\n if (!view || !db) {\n return;\n }\n\n const queue = target;\n const query = queue ? Query.fromAst(newQuery).from([Scope.feed(String(queue))]) : Query.fromAst(newQuery);\n updateView((view) => {\n view.query.ast = query.ast as Mutable<typeof query.ast>;\n });\n const newType = await resolveSchemaWithRegistry(db, query.ast);\n if (!newType) {\n return;\n }\n\n const newView = ViewModel.make({\n query,\n jsonSchema: newType.jsonSchema,\n });\n updateView((view) => {\n view.projection = Obj.getSnapshot(newView).projection as Mutable<typeof view.projection>;\n });\n\n setType(() => newType);\n },\n [db, view, updateView, type],\n );\n\n const handleColumnValuesChanged = useCallback(\n (column: Pipeline.Column) =>\n (newValues: { name?: string }, { changed }: { changed: Record<SchemaEx.JsonPath, boolean> }) => {\n if (changed['name' as SchemaEx.JsonPath]) {\n const columnIndex = columns.findIndex((c) => c === column);\n if (columnIndex === -1) {\n return;\n }\n updateColumns((cols) => {\n cols[columnIndex].name = newValues.name ?? '';\n });\n }\n },\n [columns, updateColumns],\n );\n\n const handleToggleField = useCallback((column: Pipeline.Column) => {\n setExpandedId((prevExpandedId) => (prevExpandedId === column.view.uri ? undefined : column.view.uri));\n }, []);\n\n const handleDelete = useCallback(\n async (column: Pipeline.Column) => {\n if (column.view.uri === expandedId) {\n setExpandedId(undefined);\n }\n\n const index = columns.findIndex((l) => l === column);\n const viewToRemove = await column.view.load();\n updateColumns((columns) => {\n columns.splice(index, 1);\n });\n db?.remove(viewToRemove);\n },\n [expandedId, columns, updateColumns, db],\n );\n\n const handleAdd = useCallback(() => {\n if (!db) {\n return;\n }\n const newView = ViewModel.make({\n query: Query.select(Filter.nothing()),\n jsonSchema: JsonSchema.toJsonSchema(Schema.Struct({})),\n });\n db.add(newView);\n updateColumns((columns) => {\n columns.push({\n name: '',\n // Type assertion needed due to QueryAST type variance.\n view: Ref.make(newView) as (typeof columns)[number]['view'],\n order: [],\n });\n });\n setExpandedId(newView.id);\n }, [db, updateColumns]);\n\n return (\n <div className={mx('py-form-padding overflow-y-auto', classNames)}>\n <h2 className='text-sm text-description py-1'>{t('views.label')}</h2>\n\n <List.Root<Pipeline.Column>\n items={columns}\n isItem={Schema.is(Pipeline.Column)}\n getId={(column) => column.view.uri}\n onMove={handleMove}\n >\n {({ items: columns }) => (\n <>\n <div role='list' className={mx(listGrid)}>\n {columns.map((column) => (\n <List.Item<Pipeline.Column>\n key={column.view.uri}\n item={column}\n classNames={listItemGrid}\n aria-expanded={expandedId === column.view.uri}\n >\n <div className={mx(listItemGrid, 'dx-hover rounded-xs cursor-pointer min-h-10')}>\n <List.ItemDragHandle />\n <List.ItemTitle onClick={() => handleToggleField(column)}>\n {column.name || t('untitled-view.title')}\n </List.ItemTitle>\n <List.ItemDeleteButton\n label={t('delete-view.label')}\n autoHide={false}\n onClick={() => handleDelete(column)}\n data-testid='view.delete'\n />\n <IconButton\n iconOnly\n variant='ghost'\n label={t('toggle-expand.label', { ns: osTranslations })}\n icon={expandedId === column.view.uri ? 'ph--caret-down--regular' : 'ph--caret-right--regular'}\n onClick={() => handleToggleField(column)}\n />\n </div>\n {expandedId === column.view.uri && column?.view.target && (\n <div className='col-span-5 my-2 border border-separator rounded-md'>\n <Form.Root\n schema={ColumnFormSchema}\n values={column}\n onValuesChanged={handleColumnValuesChanged(column)}\n >\n <Form.Content>\n <Form.FieldSet />\n </Form.Content>\n </Form.Root>\n <ViewEditor\n ref={projectionRef}\n mode='tag'\n readonly\n type={type}\n view={column.view.target}\n registry={db?.graph.registry}\n db={db}\n tags={tags}\n types={types}\n onQueryChanged={handleQueryChanged}\n />\n </div>\n )}\n </List.Item>\n ))}\n </div>\n </>\n )}\n </List.Root>\n\n <div className='my-form-padding'>\n <IconButton icon='ph--plus--regular' label={t('add-view.label')} onClick={handleAdd} classNames='w-full' />\n </div>\n </div>\n );\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["Schema", "React", "useCallback", "useMemo", "useRef", "useState", "resolveSchemaWithRegistry", "useTypeOptions", "Filter", "JsonSchema", "Obj", "Query", "Ref", "Scope", "Tag", "useObject", "useQuery", "IconButton", "useAsyncEffect", "useTranslation", "Form", "ViewEditor", "List", "ViewModel", "Pipeline", "mx", "osTranslations", "arrayMove", "meta", "listGrid", "listItemGrid", "ColumnFormSchema", "Column", "pipe", "mutable", "pick", "PipelineProperties", "classNames", "pipeline", "t", "id", "db", "getDatabase", "expandedId", "setExpandedId", "columns", "updateColumns", "column", "find", "view", "uri", "updateView", "type", "setType", "projectionRef", "tags", "types", "annotation", "location", "kind", "query", "foundType", "ast", "handleMove", "fromIndex", "toIndex", "handleQueryChanged", "newQuery", "target", "queue", "fromAst", "from", "feed", "String", "newType", "newView", "make", "jsonSchema", "projection", "getSnapshot", "handleColumnValuesChanged", "newValues", "changed", "columnIndex", "findIndex", "c", "cols", "name", "handleToggleField", "prevExpandedId", "undefined", "handleDelete", "index", "l", "viewToRemove", "load", "splice", "remove", "handleAdd", "select", "nothing", "toJsonSchema", "Struct", "add", "push", "order", "div", "className", "h2", "Root", "items", "isItem", "is", "getId", "onMove", "role", "map", "Item", "key", "item", "aria-expanded", "ItemDragHandle", "ItemTitle", "onClick", "ItemDeleteButton", "label", "autoHide", "data-testid", "iconOnly", "variant", "ns", "icon", "schema", "values", "onValuesChanged", "Content", "FieldSet", "ref", "mode", "readonly", "registry", "graph", "onQueryChanged"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// src/capabilities/app-graph-builder.ts
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
import { Capability } from "@dxos/app-framework";
|
|
4
|
+
import { AppCapabilities, AppNode } from "@dxos/app-toolkit";
|
|
5
|
+
import { GraphBuilder } from "@dxos/plugin-graph";
|
|
6
|
+
import { Pipeline } from "@dxos/types";
|
|
7
|
+
import { meta } from "#meta";
|
|
8
|
+
var app_graph_builder_default = Capability.makeModule(Effect.fnUntraced(function* () {
|
|
9
|
+
const extensions = yield* Effect.all([
|
|
10
|
+
GraphBuilder.createTypeExtension({
|
|
11
|
+
id: "triggers",
|
|
12
|
+
type: Pipeline.Pipeline,
|
|
13
|
+
connector: () => Effect.succeed([
|
|
14
|
+
AppNode.makeCompanion({
|
|
15
|
+
id: "invocations",
|
|
16
|
+
label: [
|
|
17
|
+
"pipeline-invocations.label",
|
|
18
|
+
{
|
|
19
|
+
ns: meta.id
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
icon: "ph--clock-countdown--regular",
|
|
23
|
+
data: "invocations"
|
|
24
|
+
}),
|
|
25
|
+
AppNode.makeCompanion({
|
|
26
|
+
id: "automation",
|
|
27
|
+
label: [
|
|
28
|
+
"pipeline-automation.label",
|
|
29
|
+
{
|
|
30
|
+
ns: meta.id
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
icon: "ph--lightning--regular",
|
|
34
|
+
data: "automation"
|
|
35
|
+
})
|
|
36
|
+
])
|
|
37
|
+
})
|
|
38
|
+
]);
|
|
39
|
+
return Capability.contributes(AppCapabilities.AppGraphBuilder, extensions);
|
|
40
|
+
}));
|
|
41
|
+
export {
|
|
42
|
+
app_graph_builder_default as default
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=app-graph-builder-ZLGRWRJU.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/capabilities/app-graph-builder.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Capability } from '@dxos/app-framework';\nimport { AppCapabilities, AppNode } from '@dxos/app-toolkit';\nimport { GraphBuilder } from '@dxos/plugin-graph';\nimport { Pipeline } from '@dxos/types';\n\nimport { meta } from '#meta';\n\nexport default Capability.makeModule(\n Effect.fnUntraced(function* () {\n const extensions = yield* Effect.all([\n GraphBuilder.createTypeExtension({\n id: 'triggers',\n type: Pipeline.Pipeline,\n connector: () =>\n Effect.succeed([\n AppNode.makeCompanion({\n id: 'invocations',\n label: ['pipeline-invocations.label', { ns: meta.id }],\n icon: 'ph--clock-countdown--regular',\n data: 'invocations',\n }),\n AppNode.makeCompanion({\n id: 'automation',\n label: ['pipeline-automation.label', { ns: meta.id }],\n icon: 'ph--lightning--regular',\n data: 'automation',\n }),\n ]),\n }),\n ]);\n\n return Capability.contributes(AppCapabilities.AppGraphBuilder, extensions);\n }),\n);\n"],
|
|
5
|
+
"mappings": ";AAIA,YAAYA,YAAY;AAExB,SAASC,kBAAkB;AAC3B,SAASC,iBAAiBC,eAAe;AACzC,SAASC,oBAAoB;AAC7B,SAASC,gBAAgB;AAEzB,SAASC,YAAY;AAErB,IAAA,4BAAeL,WAAWM,WACjBC,kBAAW,aAAA;AAChB,QAAMC,aAAa,OAAcC,WAAI;IACnCN,aAAaO,oBAAoB;MAC/BC,IAAI;MACJC,MAAMR,SAASA;MACfS,WAAW,MACFC,eAAQ;QACbZ,QAAQa,cAAc;UACpBJ,IAAI;UACJK,OAAO;YAAC;YAA8B;cAAEC,IAAIZ,KAAKM;YAAG;;UACpDO,MAAM;UACNC,MAAM;QACR,CAAA;QACAjB,QAAQa,cAAc;UACpBJ,IAAI;UACJK,OAAO;YAAC;YAA6B;cAAEC,IAAIZ,KAAKM;YAAG;;UACnDO,MAAM;UACNC,MAAM;QACR,CAAA;OACD;IACL,CAAA;GACD;AAED,SAAOnB,WAAWoB,YAAYnB,gBAAgBoB,iBAAiBb,UAAAA;AACjE,CAAA,CAAA;",
|
|
6
|
+
"names": ["Effect", "Capability", "AppCapabilities", "AppNode", "GraphBuilder", "Pipeline", "meta", "makeModule", "fnUntraced", "extensions", "all", "createTypeExtension", "id", "type", "connector", "succeed", "makeCompanion", "label", "ns", "icon", "data", "contributes", "AppGraphBuilder"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// src/capabilities/index.ts
|
|
2
|
+
import { Capability } from "@dxos/app-framework";
|
|
3
|
+
var AppGraphBuilder = Capability.lazy("AppGraphBuilder", () => import("../app-graph-builder-ZLGRWRJU.mjs"));
|
|
4
|
+
var CreateObject = Capability.lazy("CreateObject", () => import("../create-object-6Z4MMGX4.mjs"));
|
|
5
|
+
var ReactSurface = Capability.lazy("ReactSurface", () => import("../react-surface-QG7QSZSS.mjs"));
|
|
6
|
+
export {
|
|
7
|
+
AppGraphBuilder,
|
|
8
|
+
CreateObject,
|
|
9
|
+
ReactSurface
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/capabilities/index.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { Capability } from '@dxos/app-framework';\n\nexport const AppGraphBuilder = Capability.lazy('AppGraphBuilder', () => import('./app-graph-builder'));\nexport const CreateObject = Capability.lazy('CreateObject', () => import('./create-object'));\nexport const ReactSurface = Capability.lazy('ReactSurface', () => import('./react-surface'));\n"],
|
|
5
|
+
"mappings": ";AAIA,SAASA,kBAAkB;AAEpB,IAAMC,kBAAkBD,WAAWE,KAAK,mBAAmB,MAAM,OAAO,mCAAA,CAAA;AACxE,IAAMC,eAAeH,WAAWE,KAAK,gBAAgB,MAAM,OAAO,+BAAA,CAAA;AAClE,IAAME,eAAeJ,WAAWE,KAAK,gBAAgB,MAAM,OAAO,+BAAA,CAAA;",
|
|
6
|
+
"names": ["Capability", "AppGraphBuilder", "lazy", "CreateObject", "ReactSurface"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// src/meta.ts
|
|
2
|
+
import { Plugin } from "@dxos/app-framework";
|
|
3
|
+
import { DXN } from "@dxos/keys";
|
|
4
|
+
import { trim } from "@dxos/util";
|
|
5
|
+
var meta = Plugin.makeMeta({
|
|
6
|
+
key: DXN.make("org.dxos.plugin.pipeline"),
|
|
7
|
+
name: "Pipelines",
|
|
8
|
+
author: "DXOS",
|
|
9
|
+
description: trim`
|
|
10
|
+
A multi-column Kanban-style pipeline plugin for DXOS Composer.
|
|
11
|
+
Each Pipeline holds an ordered set of Columns; each Column is backed by a ViewModel whose query
|
|
12
|
+
can select any ECHO object type — messages, contacts, documents, or custom types — from the active space.
|
|
13
|
+
|
|
14
|
+
Columns are fully configurable through the Settings companion panel, where users can add, rename,
|
|
15
|
+
reorder, and delete columns and edit the underlying query and projection for each column.
|
|
16
|
+
Objects can be dragged between columns and the full pipeline state, including column order and
|
|
17
|
+
per-column item order, persists collaboratively via ECHO.
|
|
18
|
+
|
|
19
|
+
A built-in Research template scaffolds a four-column pipeline wired to the Mailbox, Contacts,
|
|
20
|
+
Organizations, and Notes objects in the space, providing an out-of-the-box CRM-style workflow.
|
|
21
|
+
Pipeline articles also expose Invocations and Automation companion tabs for AI-driven automation.
|
|
22
|
+
`,
|
|
23
|
+
icon: "ph--path--regular",
|
|
24
|
+
iconHue: "purple",
|
|
25
|
+
source: "https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-pipeline",
|
|
26
|
+
spec: "PLUGIN.mdl",
|
|
27
|
+
tags: [
|
|
28
|
+
"labs"
|
|
29
|
+
]
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
export {
|
|
33
|
+
meta
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=chunk-CYXDAAKN.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/meta.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { Plugin } from '@dxos/app-framework';\nimport { DXN } from '@dxos/keys';\nimport { trim } from '@dxos/util';\n\nexport const meta = Plugin.makeMeta({\n key: DXN.make('org.dxos.plugin.pipeline'),\n name: 'Pipelines',\n author: 'DXOS',\n description: trim`\n A multi-column Kanban-style pipeline plugin for DXOS Composer.\n Each Pipeline holds an ordered set of Columns; each Column is backed by a ViewModel whose query\n can select any ECHO object type — messages, contacts, documents, or custom types — from the active space.\n\n Columns are fully configurable through the Settings companion panel, where users can add, rename,\n reorder, and delete columns and edit the underlying query and projection for each column.\n Objects can be dragged between columns and the full pipeline state, including column order and\n per-column item order, persists collaboratively via ECHO.\n\n A built-in Research template scaffolds a four-column pipeline wired to the Mailbox, Contacts,\n Organizations, and Notes objects in the space, providing an out-of-the-box CRM-style workflow.\n Pipeline articles also expose Invocations and Automation companion tabs for AI-driven automation.\n `,\n icon: 'ph--path--regular',\n iconHue: 'purple',\n source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-pipeline',\n spec: 'PLUGIN.mdl',\n tags: ['labs'],\n});\n"],
|
|
5
|
+
"mappings": ";AAIA,SAASA,cAAc;AACvB,SAASC,WAAW;AACpB,SAASC,YAAY;AAEd,IAAMC,OAAOH,OAAOI,SAAS;EAClCC,KAAKJ,IAAIK,KAAK,0BAAA;EACdC,MAAM;EACNC,QAAQ;EACRC,aAAaP;;;;;;;;;;;;;;EAcbQ,MAAM;EACNC,SAAS;EACTC,QAAQ;EACRC,MAAM;EACNC,MAAM;IAAC;;AACT,CAAA;",
|
|
6
|
+
"names": ["Plugin", "DXN", "trim", "meta", "makeMeta", "key", "make", "name", "author", "description", "icon", "iconHue", "source", "spec", "tags"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
// src/components/PipelineComponent/PipelineColumn.tsx
|
|
2
|
+
import { useComposedRefs } from "@radix-ui/react-compose-refs";
|
|
3
|
+
import React2, { forwardRef, useMemo, useRef, useState } from "react";
|
|
4
|
+
import { resolveSchemaWithRegistry } from "@dxos/app-toolkit/query";
|
|
5
|
+
import { Filter, Obj as Obj2, Query, Type } from "@dxos/echo";
|
|
6
|
+
import { useObject } from "@dxos/react-client/echo";
|
|
7
|
+
import { Panel, Toolbar as Toolbar2, useAsyncEffect, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
8
|
+
import { Card } from "@dxos/react-ui";
|
|
9
|
+
import { Menu } from "@dxos/react-ui-menu";
|
|
10
|
+
import { Board as Board2, Focus, Mosaic } from "@dxos/react-ui-mosaic";
|
|
11
|
+
import { ProjectionModel, createEchoChangeCallback } from "@dxos/schema";
|
|
12
|
+
import { meta as meta2 } from "#meta";
|
|
13
|
+
|
|
14
|
+
// src/components/PipelineComponent/PipelineComponent.tsx
|
|
15
|
+
import { useAtomValue } from "@effect-atom/atom-react";
|
|
16
|
+
import { createContext } from "@radix-ui/react-context";
|
|
17
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
18
|
+
import React from "react";
|
|
19
|
+
import { Obj } from "@dxos/echo";
|
|
20
|
+
import { Toolbar, useTranslation } from "@dxos/react-ui";
|
|
21
|
+
import { composable, composableProps, slottable } from "@dxos/react-ui";
|
|
22
|
+
import { Board, useBoard, useEventHandlerAdapter } from "@dxos/react-ui-mosaic";
|
|
23
|
+
import { meta } from "#meta";
|
|
24
|
+
var itemNoOp = ({ item }) => /* @__PURE__ */ React.createElement("span", null, item.id);
|
|
25
|
+
var PIPELINE_ROOT = "Pipeline.Root";
|
|
26
|
+
var [PipelineRootContext, usePipeline] = createContext(PIPELINE_ROOT, {
|
|
27
|
+
Item: itemNoOp
|
|
28
|
+
});
|
|
29
|
+
var PipelineRoot = ({ children, ...contextValue }) => /* @__PURE__ */ React.createElement(PipelineRootContext, contextValue, children);
|
|
30
|
+
PipelineRoot.displayName = PIPELINE_ROOT;
|
|
31
|
+
var PIPELINE_CONTENT_NAME = "Pipeline.Content";
|
|
32
|
+
var PipelineContent = slottable(({ asChild, model, children, ...props }, forwardedRef) => {
|
|
33
|
+
const Comp = asChild ? Slot : "div";
|
|
34
|
+
return /* @__PURE__ */ React.createElement(Board.Root, {
|
|
35
|
+
model
|
|
36
|
+
}, /* @__PURE__ */ React.createElement(Comp, {
|
|
37
|
+
...composableProps(props),
|
|
38
|
+
ref: forwardedRef
|
|
39
|
+
}, children));
|
|
40
|
+
});
|
|
41
|
+
PipelineContent.displayName = PIPELINE_CONTENT_NAME;
|
|
42
|
+
var PIPELINE_COLUMNS_NAME = "Pipeline.Columns";
|
|
43
|
+
var PipelineColumns = composable(({ pipeline, ...props }) => {
|
|
44
|
+
const { model } = useBoard(PIPELINE_COLUMNS_NAME);
|
|
45
|
+
const columns = useAtomValue(model.columns);
|
|
46
|
+
const eventHandler = useEventHandlerAdapter({
|
|
47
|
+
id: pipeline.id,
|
|
48
|
+
// TODO(wittjosiah): Cast because columns array is readonly.
|
|
49
|
+
items: columns,
|
|
50
|
+
getId: model.getColumnId,
|
|
51
|
+
get: (data) => data,
|
|
52
|
+
make: (object) => object,
|
|
53
|
+
canDrop: ({ source }) => model.isColumn(source.data),
|
|
54
|
+
onChange: (mutate) => Obj.update(pipeline, (pipeline2) => mutate(pipeline2.columns))
|
|
55
|
+
});
|
|
56
|
+
return /* @__PURE__ */ React.createElement(Board.Content, {
|
|
57
|
+
...props,
|
|
58
|
+
id: "pipeline",
|
|
59
|
+
eventHandler,
|
|
60
|
+
Tile: PipelineColumn
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
PipelineColumns.displayName = PIPELINE_COLUMNS_NAME;
|
|
64
|
+
var PIPELINE_TOOLBAR_NAME = "Pipeline.Toolbar";
|
|
65
|
+
var PipelineToolbar = composable(({ children, ...props }, forwardedRef) => {
|
|
66
|
+
const { t } = useTranslation(meta.id);
|
|
67
|
+
const { onAddColumn } = usePipeline(PIPELINE_TOOLBAR_NAME);
|
|
68
|
+
return /* @__PURE__ */ React.createElement(Toolbar.Root, {
|
|
69
|
+
...composableProps(props),
|
|
70
|
+
ref: forwardedRef
|
|
71
|
+
}, /* @__PURE__ */ React.createElement(Toolbar.IconButton, {
|
|
72
|
+
icon: "ph--plus--regular",
|
|
73
|
+
iconOnly: true,
|
|
74
|
+
label: t("add-column.label"),
|
|
75
|
+
onClick: onAddColumn
|
|
76
|
+
}));
|
|
77
|
+
});
|
|
78
|
+
PipelineToolbar.displayName = PIPELINE_TOOLBAR_NAME;
|
|
79
|
+
var PipelineComponent = {
|
|
80
|
+
Root: PipelineRoot,
|
|
81
|
+
Content: PipelineContent,
|
|
82
|
+
Columns: PipelineColumns,
|
|
83
|
+
Toolbar: PipelineToolbar
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// src/components/PipelineComponent/PipelineColumn.tsx
|
|
87
|
+
var PIPELINE_COLUMN_NAME = "PipelineColumn";
|
|
88
|
+
var PipelineColumn = ({ data: column, location, classNames, debug }) => {
|
|
89
|
+
const { t } = useTranslation2(meta2.id);
|
|
90
|
+
const [dragHandle, setDragHandle] = useState(null);
|
|
91
|
+
const [viewSnapshot] = useObject(column.view);
|
|
92
|
+
const view = column.view.target;
|
|
93
|
+
const db = view && Obj2.getDatabase(view);
|
|
94
|
+
const { Item } = usePipeline(PIPELINE_COLUMN_NAME);
|
|
95
|
+
const [type, setType] = useState();
|
|
96
|
+
const query = useMemo(() => {
|
|
97
|
+
if (!view) {
|
|
98
|
+
return Query.select(Filter.nothing());
|
|
99
|
+
} else {
|
|
100
|
+
return Query.fromAst(JSON.parse(JSON.stringify(viewSnapshot?.query.ast)));
|
|
101
|
+
}
|
|
102
|
+
}, [
|
|
103
|
+
JSON.stringify(viewSnapshot?.query.ast)
|
|
104
|
+
]);
|
|
105
|
+
useAsyncEffect(async () => {
|
|
106
|
+
if (!query || !db) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const type2 = await resolveSchemaWithRegistry(db, query.ast);
|
|
110
|
+
setType(() => type2);
|
|
111
|
+
}, [
|
|
112
|
+
db,
|
|
113
|
+
query
|
|
114
|
+
]);
|
|
115
|
+
const projectionModel = useMemo(() => {
|
|
116
|
+
if (!type || !view) {
|
|
117
|
+
return void 0;
|
|
118
|
+
}
|
|
119
|
+
const change = createEchoChangeCallback(view, Type.getDatabase(type) != null ? type : void 0);
|
|
120
|
+
return new ProjectionModel({
|
|
121
|
+
view,
|
|
122
|
+
baseSchema: type.jsonSchema,
|
|
123
|
+
change
|
|
124
|
+
});
|
|
125
|
+
}, [
|
|
126
|
+
type,
|
|
127
|
+
view
|
|
128
|
+
]);
|
|
129
|
+
const PipelineTile = useMemo(() => {
|
|
130
|
+
return /* @__PURE__ */ forwardRef((props, ref) => /* @__PURE__ */ React2.createElement(ItemTile, {
|
|
131
|
+
...props,
|
|
132
|
+
itemProps: {
|
|
133
|
+
item: props.data,
|
|
134
|
+
projectionModel
|
|
135
|
+
},
|
|
136
|
+
ref
|
|
137
|
+
}));
|
|
138
|
+
}, [
|
|
139
|
+
projectionModel
|
|
140
|
+
]);
|
|
141
|
+
if (!view) {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
return /* @__PURE__ */ React2.createElement(Panel.Root, {
|
|
145
|
+
asChild: true
|
|
146
|
+
}, /* @__PURE__ */ React2.createElement(Board2.Column.Root, {
|
|
147
|
+
debug,
|
|
148
|
+
data: column,
|
|
149
|
+
location,
|
|
150
|
+
classNames,
|
|
151
|
+
dragHandle
|
|
152
|
+
}, /* @__PURE__ */ React2.createElement(Panel.Toolbar, {
|
|
153
|
+
asChild: true
|
|
154
|
+
}, /* @__PURE__ */ React2.createElement(Board2.Column.Header, {
|
|
155
|
+
classNames: "_opacity-10",
|
|
156
|
+
label: column.name || t("untitled-view.title"),
|
|
157
|
+
dragHandleRef: setDragHandle
|
|
158
|
+
})), /* @__PURE__ */ React2.createElement(Panel.Content, {
|
|
159
|
+
asChild: true
|
|
160
|
+
}, /* @__PURE__ */ React2.createElement(Board2.Column.Body, {
|
|
161
|
+
data: column,
|
|
162
|
+
Tile: PipelineTile
|
|
163
|
+
}))));
|
|
164
|
+
};
|
|
165
|
+
PipelineColumn.displayName = PIPELINE_COLUMN_NAME;
|
|
166
|
+
var ITEM_TILE_NAME = "ItemTile";
|
|
167
|
+
var ItemTile = /* @__PURE__ */ forwardRef(({ classNames, data, location, debug, itemProps }, forwardedRef) => {
|
|
168
|
+
const rootRef = useRef(null);
|
|
169
|
+
const composedRef = useComposedRefs(rootRef, forwardedRef);
|
|
170
|
+
const { Item } = usePipeline(ITEM_TILE_NAME);
|
|
171
|
+
const icon = Obj2.getIcon(data)?.icon ?? "ph--circle-dashed--regular";
|
|
172
|
+
return /* @__PURE__ */ React2.createElement(Menu.Root, null, /* @__PURE__ */ React2.createElement(Mosaic.Tile, {
|
|
173
|
+
asChild: true,
|
|
174
|
+
id: data.id,
|
|
175
|
+
data,
|
|
176
|
+
location,
|
|
177
|
+
debug
|
|
178
|
+
}, /* @__PURE__ */ React2.createElement(Focus.Item, {
|
|
179
|
+
asChild: true
|
|
180
|
+
}, /* @__PURE__ */ React2.createElement(Card.Root, {
|
|
181
|
+
classNames,
|
|
182
|
+
ref: composedRef
|
|
183
|
+
}, /* @__PURE__ */ React2.createElement(Card.Header, null, /* @__PURE__ */ React2.createElement(Card.Icon, {
|
|
184
|
+
icon
|
|
185
|
+
}), /* @__PURE__ */ React2.createElement(Card.Title, null, Obj2.getLabel(data, {
|
|
186
|
+
fallback: "typename"
|
|
187
|
+
})), /* @__PURE__ */ React2.createElement(Card.IconBlock, null, /* @__PURE__ */ React2.createElement(Menu.Trigger, {
|
|
188
|
+
asChild: true
|
|
189
|
+
}, /* @__PURE__ */ React2.createElement(Toolbar2.IconButton, {
|
|
190
|
+
iconOnly: true,
|
|
191
|
+
variant: "ghost",
|
|
192
|
+
icon: "ph--dots-three-vertical--regular",
|
|
193
|
+
label: "Actions"
|
|
194
|
+
})), /* @__PURE__ */ React2.createElement(Menu.Content, null))), /* @__PURE__ */ React2.createElement(Card.Body, null, /* @__PURE__ */ React2.createElement(Item, itemProps))))));
|
|
195
|
+
});
|
|
196
|
+
ItemTile.displayName = ITEM_TILE_NAME;
|
|
197
|
+
export {
|
|
198
|
+
PipelineColumn,
|
|
199
|
+
PipelineComponent,
|
|
200
|
+
PipelineToolbar,
|
|
201
|
+
usePipeline
|
|
202
|
+
};
|
|
203
|
+
//# sourceMappingURL=index.mjs.map
|