@parallelworks/ui 0.57.0 → 0.59.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/README.md +60 -4
- package/dist/access/PrincipalPicker.js +2 -1
- package/dist/ai/agent/diff.d.ts +1 -0
- package/dist/ai/agent/diff.js +50 -3
- package/dist/ai/ai.css +38 -0
- package/dist/ai/components/AttachmentUpload.d.ts +3 -0
- package/dist/ai/components/AttachmentUpload.js +51 -43
- package/dist/ai/components/agent/AgentMessageParts.js +33 -6
- package/dist/ai/strings.d.ts +2 -0
- package/dist/ai/strings.js +2 -1
- package/dist/components/AppLink.js +8 -3
- package/dist/components/Avatar.d.ts +5 -1
- package/dist/components/Avatar.js +13 -5
- package/dist/components/ExternalLink.d.ts +3 -2
- package/dist/components/ExternalLink.js +5 -2
- package/dist/components/Field.d.ts +7 -1
- package/dist/components/Field.js +83 -56
- package/dist/components/HoverCard.js +12 -0
- package/dist/components/Markdown.d.ts +3 -0
- package/dist/components/Markdown.js +2 -1
- package/dist/components/MarkdownImpl.d.ts +1 -1
- package/dist/components/MarkdownImpl.js +5 -3
- package/dist/components/Provider.d.ts +16 -1
- package/dist/components/Provider.js +17 -3
- package/dist/components/StickyBar.d.ts +14 -0
- package/dist/components/StickyBar.js +22 -0
- package/dist/components/Table.d.ts +7 -5
- package/dist/components/Table.js +6 -2
- package/dist/components/Tabs.d.ts +2 -2
- package/dist/components/Tabs.js +5 -2
- package/dist/components/category.d.ts +9 -0
- package/dist/components/category.js +30 -0
- package/dist/components/httpsImages.d.ts +12 -0
- package/dist/components/httpsImages.js +27 -0
- package/dist/components/stickyTop.d.ts +14 -0
- package/dist/components/stickyTop.js +93 -0
- package/dist/file-explorer/FileExplorer.js +21 -15
- package/dist/graph/DependencyGraph.d.ts +14 -1
- package/dist/graph/DependencyGraph.js +169 -77
- package/dist/graph/JobSummary.js +13 -3
- package/dist/graph/StepSummary.d.ts +4 -0
- package/dist/graph/StepSummary.js +31 -0
- package/dist/graph/index.d.ts +1 -0
- package/dist/graph/index.js +2 -1
- package/dist/graph/types.d.ts +3 -0
- package/dist/graph/util.d.ts +1 -1
- package/dist/icons.d.ts +1 -0
- package/dist/icons.js +3 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -1
- package/dist/list/ActionToolbar.d.ts +2 -3
- package/dist/list/ActionToolbar.js +3 -3
- package/dist/list/index.d.ts +1 -1
- package/dist/list/index.js +2 -2
- package/dist/logviewer/LogViewer.js +3 -3
- package/dist/styles/theme.css +27 -0
- package/dist/styles.css +1 -1
- package/dist/theme/derive.d.ts +2 -1
- package/dist/theme/derive.js +45 -1
- package/package.json +1 -1
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { useLayoutEffect } from "react";
|
|
2
|
+
//#region src/components/stickyTop.ts
|
|
3
|
+
/** Pins a bar to the top of its scroller, over what scrolls under it.
|
|
4
|
+
* `useStickyTop` moves it below whatever else is pinned there. */
|
|
5
|
+
var stickyClasses = "sticky top-0 z-(--layer-sticky) bg-(--theme-app-bg)";
|
|
6
|
+
var scrolls = (style) => /auto|scroll|hidden|overlay/.test(`${style.overflow} ${style.overflowX} ${style.overflowY}`);
|
|
7
|
+
/** The box a sticky element sticks to: its nearest ancestor that scrolls, or
|
|
8
|
+
* the document's when none does. */
|
|
9
|
+
function scrollContainer(el) {
|
|
10
|
+
const root = el.ownerDocument.documentElement;
|
|
11
|
+
for (let node = el.parentElement; node && node !== root; node = node.parentElement) if (scrolls(getComputedStyle(node))) return node;
|
|
12
|
+
return root;
|
|
13
|
+
}
|
|
14
|
+
/** Elements laid out as children of `parent`'s box: its children, with those
|
|
15
|
+
* of a `display: contents` child (such as a tab row's root) in its place. */
|
|
16
|
+
function boxChildren(nodes, into) {
|
|
17
|
+
for (const node of nodes) {
|
|
18
|
+
into.push(node);
|
|
19
|
+
if (getComputedStyle(node).display === "contents") boxChildren(node.children, into);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function chromeAbove(el, scroller) {
|
|
23
|
+
const above = {
|
|
24
|
+
chrome: [],
|
|
25
|
+
parents: [],
|
|
26
|
+
siblings: []
|
|
27
|
+
};
|
|
28
|
+
for (let node = el; node !== scroller && node.parentElement;) {
|
|
29
|
+
const parent = node.parentElement;
|
|
30
|
+
const earlier = [];
|
|
31
|
+
for (let sib = node.previousElementSibling; sib; sib = sib.previousElementSibling) earlier.push(sib);
|
|
32
|
+
const laidOut = [];
|
|
33
|
+
boxChildren(earlier, laidOut);
|
|
34
|
+
for (const sib of laidOut) {
|
|
35
|
+
above.siblings.push(sib);
|
|
36
|
+
const style = getComputedStyle(sib);
|
|
37
|
+
if (style.display === "contents") above.parents.push(sib);
|
|
38
|
+
if (style.position === "sticky" && style.top !== "auto" && sib instanceof HTMLElement) above.chrome.push(sib);
|
|
39
|
+
}
|
|
40
|
+
above.parents.push(parent);
|
|
41
|
+
node = parent;
|
|
42
|
+
}
|
|
43
|
+
return above;
|
|
44
|
+
}
|
|
45
|
+
/** Where `chrome`'s bottom edge sits, below the scroller's top, while it's pinned. */
|
|
46
|
+
function pinnedBottom(chrome) {
|
|
47
|
+
const height = chrome.getBoundingClientRect().height;
|
|
48
|
+
return height > 0 ? (Number.parseFloat(getComputedStyle(chrome).top) || 0) + height : 0;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Pins a `sticky` element just below whatever its scroller already pins at
|
|
52
|
+
* the top, such as a page header, a toolbar and a tab row, rather than at
|
|
53
|
+
* `top: 0` behind them. It finds them in the page, so neither they nor the
|
|
54
|
+
* host declare anything, and it follows them as they change height (a toolbar
|
|
55
|
+
* wrapping on a narrow screen), move, or come and go, before the browser
|
|
56
|
+
* paints. Chrome that uses it stacks: each piece pins under the ones before
|
|
57
|
+
* it, and its own `top` moving is a change the pieces after it follow.
|
|
58
|
+
* In a box that scrolls on its own, nothing sits above, so it pins at 0.
|
|
59
|
+
*/
|
|
60
|
+
function useStickyTop(el, enabled) {
|
|
61
|
+
useLayoutEffect(() => {
|
|
62
|
+
if (!enabled || !el) return;
|
|
63
|
+
let chrome = [];
|
|
64
|
+
const place = () => {
|
|
65
|
+
const top = `${Math.max(0, ...chrome.map(pinnedBottom))}px`;
|
|
66
|
+
if (el.style.top !== top) el.style.top = top;
|
|
67
|
+
};
|
|
68
|
+
const resizes = new ResizeObserver(place);
|
|
69
|
+
const changes = new MutationObserver(gather);
|
|
70
|
+
function gather() {
|
|
71
|
+
if (!el) return;
|
|
72
|
+
const above = chromeAbove(el, scrollContainer(el));
|
|
73
|
+
chrome = above.chrome;
|
|
74
|
+
resizes.disconnect();
|
|
75
|
+
changes.disconnect();
|
|
76
|
+
for (const node of chrome) resizes.observe(node);
|
|
77
|
+
for (const parent of above.parents) changes.observe(parent, { childList: true });
|
|
78
|
+
for (const sib of above.siblings) changes.observe(sib, {
|
|
79
|
+
attributes: true,
|
|
80
|
+
attributeFilter: ["class", "style"]
|
|
81
|
+
});
|
|
82
|
+
place();
|
|
83
|
+
}
|
|
84
|
+
gather();
|
|
85
|
+
return () => {
|
|
86
|
+
resizes.disconnect();
|
|
87
|
+
changes.disconnect();
|
|
88
|
+
el.style.top = "";
|
|
89
|
+
};
|
|
90
|
+
}, [el, enabled]);
|
|
91
|
+
}
|
|
92
|
+
//#endregion
|
|
93
|
+
export { stickyClasses, useStickyTop };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cx } from "../cx.js";
|
|
2
2
|
import { buttonClasses } from "../components/buttonClasses.js";
|
|
3
|
-
import { AccessIcon, ChevronDownIcon, ChevronRightIcon, CollapseIcon, DownloadIcon, FileIcon, FileTextIcon, FolderIcon, LinkIcon, PreviewIcon, ShareIcon, TrashIcon, UploadIcon } from "../icons.js";
|
|
3
|
+
import { AccessIcon, ChevronDownIcon, ChevronRightIcon, CollapseIcon, DownloadIcon, FileIcon, FileTextIcon, FolderIcon, FolderTreeIcon, LinkIcon, PreviewIcon, ShareIcon, TrashIcon, UploadIcon } from "../icons.js";
|
|
4
4
|
import { MenuItem, MenuPopup, MenuSeparator } from "../components/Menu.js";
|
|
5
5
|
import { safeUrl } from "../safeUrl.js";
|
|
6
6
|
import { Loader } from "../components/Loader.js";
|
|
@@ -676,24 +676,30 @@ function FileExplorer({ storages, onRefresh, refreshKey, onOpenFile, showUserHie
|
|
|
676
676
|
...open,
|
|
677
677
|
onClick: () => handleSelectTreeItem(node.path, node)
|
|
678
678
|
}];
|
|
679
|
-
const
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
679
|
+
const copy = copySubmenu({
|
|
680
|
+
name: isFile ? node.name : void 0,
|
|
681
|
+
extra: [
|
|
682
|
+
{
|
|
683
|
+
label: t.preview.path,
|
|
684
|
+
value: node.root ? void 0 : getObjectKeyFromNode(node).replace(/\/$/, ""),
|
|
685
|
+
icon: /* @__PURE__ */ jsx(FolderTreeIcon, {})
|
|
686
|
+
},
|
|
687
|
+
{
|
|
688
|
+
label: t.preview.link,
|
|
689
|
+
value: absoluteUrl(href),
|
|
690
|
+
icon: /* @__PURE__ */ jsx(LinkIcon, {})
|
|
691
|
+
},
|
|
692
|
+
...uris.map((value) => ({
|
|
693
|
+
label: `${getUriScheme(value).toUpperCase()} URI`,
|
|
694
|
+
value,
|
|
695
|
+
icon: /* @__PURE__ */ jsx(LinkIcon, {})
|
|
696
|
+
}))
|
|
697
|
+
]
|
|
689
698
|
});
|
|
690
699
|
return assembleRowMenu({
|
|
691
700
|
lead,
|
|
692
701
|
actions,
|
|
693
|
-
copy:
|
|
694
|
-
name: isFile ? node.name : void 0,
|
|
695
|
-
extra: uriExtras
|
|
696
|
-
}) : void 0
|
|
702
|
+
copy: copy.items.length > 0 ? copy : void 0
|
|
697
703
|
});
|
|
698
704
|
};
|
|
699
705
|
const openNodeContextMenu = (e, node) => {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
1
2
|
import type { GraphLayout } from '../editing.js';
|
|
2
3
|
import type { DependencyGraphEditor } from './editorApi.js';
|
|
3
4
|
import { type RunLink, type WorkflowJob } from './types.js';
|
|
@@ -17,7 +18,7 @@ interface GraphRun {
|
|
|
17
18
|
executedJobs?: Record<string, unknown> | undefined;
|
|
18
19
|
links?: Record<string, RunLink> | undefined;
|
|
19
20
|
}
|
|
20
|
-
export default function DependencyGraph({ run, preview, removeBorder, viewMode, setViewMode, layout, editor, yamlJobs, inputs, workflow, fixedHeight, }: {
|
|
21
|
+
export default function DependencyGraph({ run, preview, removeBorder, viewMode, setViewMode, layout, editor, yamlJobs, inputs, workflow, fixedHeight, openStep, onCloseLog, sidebarStickyTop, children, }: {
|
|
21
22
|
run: GraphRun;
|
|
22
23
|
preview?: boolean;
|
|
23
24
|
removeBorder?: boolean | undefined;
|
|
@@ -30,6 +31,18 @@ export default function DependencyGraph({ run, preview, removeBorder, viewMode,
|
|
|
30
31
|
/** The workflow as written, for what the editor's expressions can read. */
|
|
31
32
|
workflow?: Record<string, unknown> | undefined;
|
|
32
33
|
fixedHeight?: string | undefined;
|
|
34
|
+
/** A step to open; `prefix` is its `subworkflows/<job>/step_<n>/` chain when it runs inside a subworkflow. */
|
|
35
|
+
openStep?: {
|
|
36
|
+
job: string;
|
|
37
|
+
step: number;
|
|
38
|
+
prefix?: string | undefined;
|
|
39
|
+
} | undefined;
|
|
40
|
+
/** Called when the log dialog closes, so a host can forget the step it asked to open. */
|
|
41
|
+
onCloseLog?: (() => void) | undefined;
|
|
42
|
+
/** Pins the job list this many pixels below the top of the page's scroll area, under the host's own pinned bars. */
|
|
43
|
+
sidebarStickyTop?: number | undefined;
|
|
44
|
+
/** Shown under the annotations, above the graph. */
|
|
45
|
+
children?: ReactNode;
|
|
33
46
|
}): import("react").JSX.Element | undefined;
|
|
34
47
|
export declare function DependencyGraphPreview(inputs: {
|
|
35
48
|
yml?: Record<string, unknown>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { cx } from "../cx.js";
|
|
2
|
-
import { ArrowLeftIcon, ArrowRightIcon, ChevronLeftIcon, ChevronRightIcon, FileTextIcon, ZoomInIcon, ZoomOutIcon } from "../icons.js";
|
|
2
|
+
import { ArrowLeftIcon, ArrowRightIcon, ChevronLeftIcon, ChevronRightIcon, CloseIcon, FileTextIcon, ZoomInIcon, ZoomOutIcon } from "../icons.js";
|
|
3
3
|
import { Loader } from "../components/Loader.js";
|
|
4
4
|
import { useRunFile, useSlots, useStrings, useWorkflowEngine } from "../components/Provider.js";
|
|
5
5
|
import { Button } from "../components/Button.js";
|
|
@@ -10,6 +10,7 @@ import { DisclosurePanel } from "../components/Disclosure.js";
|
|
|
10
10
|
import { formatDateTime } from "../format.js";
|
|
11
11
|
import { Elapsed } from "../components/relativeTime.js";
|
|
12
12
|
import { RunStatusIcon } from "../components/RunStatusIcon.js";
|
|
13
|
+
import { Tabs } from "../components/Tabs.js";
|
|
13
14
|
import { LogViewer } from "../logviewer/LogViewer.js";
|
|
14
15
|
import { initializeValues } from "../form/lib.js";
|
|
15
16
|
import { AnnotationBanner } from "./AnnotationBanner.js";
|
|
@@ -27,6 +28,7 @@ import { routeConnectors, sameBoxes } from "./connectorGeometry.js";
|
|
|
27
28
|
import { isJobRecord } from "./types.js";
|
|
28
29
|
import { computeGraphLayout, displayJobsOf, hopDistances, positionsOf } from "./graphLayout.js";
|
|
29
30
|
import { MatrixGroupNode, MatrixGroupSummaryItem } from "./MatrixGroup.js";
|
|
31
|
+
import { StepSummary } from "./StepSummary.js";
|
|
30
32
|
import TreeView from "./TreeView.js";
|
|
31
33
|
import { FIT_MAX_SCALE, MIN_SCALE, ZOOM_STEP, fitMargin, fitView, intoView, wheelFactor, zoomAround, zoomLimit } from "./viewport.js";
|
|
32
34
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -35,6 +37,12 @@ import { flushSync } from "react-dom";
|
|
|
35
37
|
import { DateTime } from "luxon";
|
|
36
38
|
import { TransformComponent, TransformWrapper } from "react-zoom-pan-pinch";
|
|
37
39
|
//#region src/graph/DependencyGraph.tsx
|
|
40
|
+
var stepTabFiles = {
|
|
41
|
+
summary: "summary.md",
|
|
42
|
+
logs: "logs.out",
|
|
43
|
+
script: "script-unstable-redacted.sh"
|
|
44
|
+
};
|
|
45
|
+
var fileBeside = (path, file) => path.slice(0, path.lastIndexOf("/") + 1) + file;
|
|
38
46
|
function ViewToggle({ viewMode, setViewMode }) {
|
|
39
47
|
const { dag: t } = useStrings();
|
|
40
48
|
return /* @__PURE__ */ jsxs("div", {
|
|
@@ -193,6 +201,11 @@ function offsetWithin(el, ancestor) {
|
|
|
193
201
|
y
|
|
194
202
|
};
|
|
195
203
|
}
|
|
204
|
+
function unscrolledTop(el) {
|
|
205
|
+
let top = el.getBoundingClientRect().top;
|
|
206
|
+
for (let cur = el.parentElement; cur; cur = cur.parentElement) top += cur.scrollTop;
|
|
207
|
+
return top;
|
|
208
|
+
}
|
|
196
209
|
function parsePrefixToPath(prefix) {
|
|
197
210
|
const parts = prefix.split("/").filter(Boolean);
|
|
198
211
|
const path = [];
|
|
@@ -683,7 +696,7 @@ function graphBounds(content) {
|
|
|
683
696
|
}
|
|
684
697
|
return bounds;
|
|
685
698
|
}
|
|
686
|
-
function DependencyGraph({ run, preview = false, removeBorder, viewMode = "dag", setViewMode, layout, editor, yamlJobs, inputs, workflow, fixedHeight }) {
|
|
699
|
+
function DependencyGraph({ run, preview = false, removeBorder, viewMode = "dag", setViewMode, layout, editor, yamlJobs, inputs, workflow, fixedHeight, openStep, onCloseLog, sidebarStickyTop, children }) {
|
|
687
700
|
const engine = useWorkflowEngine();
|
|
688
701
|
const animT = .125;
|
|
689
702
|
const rootJobs = isJobRecord(run.executedJobs) ? run.executedJobs : {};
|
|
@@ -724,7 +737,7 @@ function DependencyGraph({ run, preview = false, removeBorder, viewMode = "dag",
|
|
|
724
737
|
const cur = containerRef.current;
|
|
725
738
|
if (!cur) return;
|
|
726
739
|
setTopOffset((prev) => {
|
|
727
|
-
const next = cur
|
|
740
|
+
const next = unscrolledTop(cur);
|
|
728
741
|
return prev === next ? prev : next;
|
|
729
742
|
});
|
|
730
743
|
};
|
|
@@ -768,6 +781,7 @@ function DependencyGraph({ run, preview = false, removeBorder, viewMode = "dag",
|
|
|
768
781
|
};
|
|
769
782
|
}, [preview, fixedHeight]);
|
|
770
783
|
const { common, dag: dagStrings } = useStrings();
|
|
784
|
+
const stepHeaderRef = useRef(null);
|
|
771
785
|
const slots = useSlots();
|
|
772
786
|
const [executedJobsPath, setExecutedJobsPath] = useState([[]]);
|
|
773
787
|
const [executedJobsPathIdx, setExecutedJobsPathIdx] = useState(0);
|
|
@@ -827,7 +841,44 @@ function DependencyGraph({ run, preview = false, removeBorder, viewMode = "dag",
|
|
|
827
841
|
setMatrixOpen((prev) => toggled(prev, key));
|
|
828
842
|
requestAnimationFrame(invalidateConnectors);
|
|
829
843
|
}, [invalidateConnectors]);
|
|
830
|
-
const
|
|
844
|
+
const nestingDepth = currentPath.length / 5;
|
|
845
|
+
const levelPrefixes = [];
|
|
846
|
+
for (let i = 0; i < nestingDepth; i++) levelPrefixes.push(`subworkflows/${currentPath[5 * i]}/step_${currentPath[5 * i + 2]}/`);
|
|
847
|
+
const pathAppend = levelPrefixes.join("");
|
|
848
|
+
let generalLogPath = "logs.out";
|
|
849
|
+
if (nestingDepth > 0) {
|
|
850
|
+
const lastJob = String(currentPath[5 * (nestingDepth - 1)] ?? "");
|
|
851
|
+
const lastStep = currentPath[5 * (nestingDepth - 1) + 2] ?? "";
|
|
852
|
+
generalLogPath = engine.stepLogPath(levelPrefixes.slice(0, -1).join(""), lastJob, lastStep);
|
|
853
|
+
}
|
|
854
|
+
const openJob = openStep?.job;
|
|
855
|
+
const openStepIndex = openStep?.step;
|
|
856
|
+
const openPrefix = openStep?.prefix ?? "";
|
|
857
|
+
useEffect(() => {
|
|
858
|
+
if (openJob !== void 0 && openStepIndex !== void 0) setSublogOpen(fileBeside(engine.stepLogPath(openPrefix, openJob, openStepIndex), "summary.md"));
|
|
859
|
+
}, [
|
|
860
|
+
engine,
|
|
861
|
+
openJob,
|
|
862
|
+
openStepIndex,
|
|
863
|
+
openPrefix
|
|
864
|
+
]);
|
|
865
|
+
const [sublogJob = "", sublogStepDir] = sublogOpen.split("/").slice(-3, -1);
|
|
866
|
+
const sublogStep = sublogStepDir === void 0 ? void 0 : sublogStepDir.split("_")[1] ?? "";
|
|
867
|
+
const sublogIsStep = sublogStep !== void 0;
|
|
868
|
+
const sublogJobs = sublogOpen === generalLogPath ? jobs : walkJobPath(rootJobs, parsePrefixToPath(sublogOpen.split("/").slice(0, -4).join("/")));
|
|
869
|
+
const sublogStepData = sublogIsStep ? sublogJobs[sublogJob]?.steps[Number(sublogStep)] : void 0;
|
|
870
|
+
const stepTitle = sublogIsStep ? `${jobLabel(sublogJob, sublogJobs[sublogJob])} › ${engine.stepLabel(sublogStepData ?? {}, Number(sublogStep))}` : "";
|
|
871
|
+
const sublogIsSubworkflow = !!sublogStepData?.subworkflow;
|
|
872
|
+
const sublogDir = sublogOpen.slice(0, sublogOpen.lastIndexOf("/") + 1);
|
|
873
|
+
const sublogFile = sublogOpen.slice(sublogDir.length);
|
|
874
|
+
const sublogHasSummary = !preview && !!sublogStepData?.summary;
|
|
875
|
+
const sublogTab = sublogFile === "summary.md" && sublogHasSummary ? "summary" : sublogFile === "logs.out" || sublogFile === "summary.md" ? "logs" : "script";
|
|
876
|
+
const stepTabs = !sublogIsStep || preview || sublogIsSubworkflow ? [] : sublogHasSummary ? [
|
|
877
|
+
"summary",
|
|
878
|
+
"logs",
|
|
879
|
+
"script"
|
|
880
|
+
] : ["logs", "script"];
|
|
881
|
+
const { data: sublogs, isLoading: sublogsLoading, error: sublogsError } = useRunFile(runSlug, sublogOpen === "" || sublogTab === "summary" ? null : sublogFile === "summary.md" ? `${sublogDir}logs.out` : sublogOpen, preview ? void 0 : { refreshInterval: 2e3 });
|
|
831
882
|
useEffect(() => {
|
|
832
883
|
if (sublogOpen.endsWith("/script-unstable-redacted.sh") && !sublogsLoading && (sublogsError || !sublogs)) setSublogOpen(sublogOpen.replace(/script-unstable-redacted\.sh$/, "script-unstable.sh"));
|
|
833
884
|
}, [
|
|
@@ -836,14 +887,6 @@ function DependencyGraph({ run, preview = false, removeBorder, viewMode = "dag",
|
|
|
836
887
|
sublogsError,
|
|
837
888
|
sublogsLoading
|
|
838
889
|
]);
|
|
839
|
-
const [sublogJob = "", sublogStepDir] = sublogOpen.split("/").slice(-3, -1);
|
|
840
|
-
const sublogStep = sublogStepDir === void 0 ? void 0 : sublogStepDir.split("_")[1] ?? "";
|
|
841
|
-
const sublogIsStep = sublogStep !== void 0;
|
|
842
|
-
const sublogStepData = sublogIsStep ? jobs[sublogJob]?.steps[Number(sublogStep)] : void 0;
|
|
843
|
-
const logName = sublogIsStep ? `Job: ${jobLabel(sublogJob)} \nStep: ${sublogStepData?.name || `Step ${sublogStep}`}` : "";
|
|
844
|
-
const sublogIsSubworkflow = !!sublogStepData?.subworkflow;
|
|
845
|
-
const sublogFileStart = sublogOpen.lastIndexOf("/") + 1;
|
|
846
|
-
const sublogShowsLog = sublogOpen.slice(sublogFileStart) === "logs.out";
|
|
847
890
|
const rootGraph = useMemo(() => computeGraphLayout(engine, jobs, engine.matrixGroups(jobs), placed), [
|
|
848
891
|
engine,
|
|
849
892
|
jobs,
|
|
@@ -1022,16 +1065,6 @@ function DependencyGraph({ run, preview = false, removeBorder, viewMode = "dag",
|
|
|
1022
1065
|
windowSize,
|
|
1023
1066
|
executedJobsPathIdx
|
|
1024
1067
|
]);
|
|
1025
|
-
const nestingDepth = currentPath.length / 5;
|
|
1026
|
-
const levelPrefixes = [];
|
|
1027
|
-
for (let i = 0; i < nestingDepth; i++) levelPrefixes.push(`subworkflows/${currentPath[5 * i]}/step_${currentPath[5 * i + 2]}/`);
|
|
1028
|
-
const pathAppend = levelPrefixes.join("");
|
|
1029
|
-
let generalLogPath = "logs.out";
|
|
1030
|
-
if (nestingDepth > 0) {
|
|
1031
|
-
const lastJob = String(currentPath[5 * (nestingDepth - 1)] ?? "");
|
|
1032
|
-
const lastStep = currentPath[5 * (nestingDepth - 1) + 2] ?? "";
|
|
1033
|
-
generalLogPath = engine.stepLogPath(levelPrefixes.slice(0, -1).join(""), lastJob, lastStep);
|
|
1034
|
-
}
|
|
1035
1068
|
const missingLogText = sublogIsSubworkflow ? "Subworkflows generally have no logs/scripts at this level.\nClick on the \"Open in new graph\" icon on the subworkflow step to open the subworkflow graph." : sublogsError ? dagStrings.logLoadFailed : (sublogOpen === generalLogPath ? dagStrings.statusReason(run.statusReason) : void 0) ?? dagStrings.noLogFound;
|
|
1036
1069
|
const currentSublog = sublogOpen === "" ? "" : preview ? engine.toYaml(sublogStepData) : sublogsError || !sublogs ? missingLogText : sublogs;
|
|
1037
1070
|
const expansionKeys = useMemo(() => engine.expansionKeys(jobs, pathAppend), [
|
|
@@ -1087,6 +1120,8 @@ function DependencyGraph({ run, preview = false, removeBorder, viewMode = "dag",
|
|
|
1087
1120
|
setSublogOpen(`${sublogSplit.slice(0, -3).join("/")}/${job}/step_${step}/${sublogSplit.slice(-1)[0]}`);
|
|
1088
1121
|
}, [jobs, sublogOpen]);
|
|
1089
1122
|
const handleKeyDown = useCallback((e) => {
|
|
1123
|
+
const target = e.target instanceof Element ? e.target : null;
|
|
1124
|
+
if (e.defaultPrevented || e.altKey || e.ctrlKey || e.metaKey || e.shiftKey || target?.closest("input, textarea, select, [contenteditable=\"\"], [contenteditable=\"true\"], [role=\"tablist\"], [role=\"listbox\"], [role=\"menu\"], [role=\"slider\"], [role=\"radiogroup\"]")) return;
|
|
1090
1125
|
if (e.key === "ArrowRight") nextStep(false);
|
|
1091
1126
|
else if (e.key === "ArrowLeft") nextStep(true);
|
|
1092
1127
|
}, [nextStep]);
|
|
@@ -1129,40 +1164,99 @@ function DependencyGraph({ run, preview = false, removeBorder, viewMode = "dag",
|
|
|
1129
1164
|
})
|
|
1130
1165
|
}) : void 0;
|
|
1131
1166
|
const startDt = run.createdAt ? DateTime.fromISO(run.createdAt) : shownAt;
|
|
1132
|
-
const
|
|
1133
|
-
|
|
1134
|
-
|
|
1167
|
+
const jobNames = Object.keys(jobs);
|
|
1168
|
+
const stepCount = jobNames.reduce((n, name) => n + (jobs[name]?.steps.length ?? 0), 0);
|
|
1169
|
+
const stepPosition = jobNames.slice(0, Math.max(0, jobNames.indexOf(sublogJob))).reduce((n, name) => n + (jobs[name]?.steps.length ?? 0), 0) + Number(sublogStep ?? 0) + 1;
|
|
1170
|
+
const stepPager = sublogIsStep ? /* @__PURE__ */ jsxs("div", {
|
|
1171
|
+
className: "flex shrink-0 items-center",
|
|
1172
|
+
children: [/* @__PURE__ */ jsx(IconButton, {
|
|
1135
1173
|
icon: /* @__PURE__ */ jsx(ArrowLeftIcon, {}),
|
|
1136
1174
|
label: dagStrings.previousStep,
|
|
1137
1175
|
onClick: () => nextStep(true)
|
|
1138
|
-
}),
|
|
1139
|
-
/* @__PURE__ */ jsx(IconButton, {
|
|
1140
|
-
variant: "outline",
|
|
1176
|
+
}), /* @__PURE__ */ jsx(IconButton, {
|
|
1141
1177
|
icon: /* @__PURE__ */ jsx(ArrowRightIcon, {}),
|
|
1142
1178
|
label: dagStrings.nextStep,
|
|
1143
1179
|
onClick: () => nextStep(false)
|
|
1144
|
-
})
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1180
|
+
})]
|
|
1181
|
+
}) : void 0;
|
|
1182
|
+
const stepCounter = sublogIsStep && sublogJobs === jobs ? dagStrings.stepOf(stepPosition, stepCount) : void 0;
|
|
1183
|
+
const stepTabLabels = {
|
|
1184
|
+
summary: dagStrings.summaryTab,
|
|
1185
|
+
logs: dagStrings.logsTab,
|
|
1186
|
+
script: dagStrings.scriptTab
|
|
1187
|
+
};
|
|
1188
|
+
const closeLog = () => {
|
|
1189
|
+
setSublogOpen("");
|
|
1190
|
+
onCloseLog?.();
|
|
1191
|
+
};
|
|
1192
|
+
const narrowDialog = windowSize.w < 640;
|
|
1193
|
+
const stepHeader = sublogIsStep ? /* @__PURE__ */ jsxs("div", {
|
|
1194
|
+
ref: stepHeaderRef,
|
|
1195
|
+
className: "grid shrink-0 grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-x-2 gap-y-2 border-b border-(--theme-border) px-2 py-2 sm:flex sm:gap-x-3",
|
|
1196
|
+
children: [
|
|
1197
|
+
stepPager,
|
|
1198
|
+
/* @__PURE__ */ jsxs("div", {
|
|
1199
|
+
className: "flex min-w-0 items-baseline gap-x-2.5 sm:flex-1",
|
|
1200
|
+
children: [/* @__PURE__ */ jsx("h2", {
|
|
1201
|
+
className: "min-w-0 truncate font-semibold",
|
|
1202
|
+
title: stepTitle,
|
|
1203
|
+
children: stepTitle
|
|
1204
|
+
}), stepCounter && /* @__PURE__ */ jsx("span", {
|
|
1205
|
+
className: "hidden shrink-0 text-xs tabular-nums theme-muted-text sm:inline",
|
|
1206
|
+
children: stepCounter
|
|
1207
|
+
})]
|
|
1208
|
+
}),
|
|
1209
|
+
sublogIsSubworkflow && /* @__PURE__ */ jsx(Button, {
|
|
1210
|
+
className: narrowDialog ? "col-span-3 row-start-2 justify-self-start" : void 0,
|
|
1211
|
+
variant: "secondary",
|
|
1212
|
+
size: "sm",
|
|
1213
|
+
onClick: () => {
|
|
1214
|
+
openInNewGraph(pathAppend, sublogJob, parseInt(sublogStep ?? "", 10));
|
|
1215
|
+
setSublogOpen("");
|
|
1216
|
+
},
|
|
1217
|
+
children: dagStrings.openSubworkflow
|
|
1218
|
+
}),
|
|
1219
|
+
stepTabs.length > 0 && /* @__PURE__ */ jsx(Tabs, {
|
|
1220
|
+
className: narrowDialog ? "col-span-3 row-start-2 [&>[role=tablist]]:flex-1" : void 0,
|
|
1221
|
+
label: stepTitle,
|
|
1222
|
+
variant: "segmented",
|
|
1223
|
+
fill: narrowDialog,
|
|
1224
|
+
items: stepTabs.map((tab) => ({
|
|
1225
|
+
value: tab,
|
|
1226
|
+
label: stepTabLabels[tab]
|
|
1227
|
+
})),
|
|
1228
|
+
value: sublogTab,
|
|
1229
|
+
onValueChange: (tab) => setSublogOpen(sublogDir + stepTabFiles[tab])
|
|
1230
|
+
}),
|
|
1231
|
+
/* @__PURE__ */ jsx(IconButton, {
|
|
1232
|
+
className: "col-start-3 row-start-1",
|
|
1233
|
+
icon: /* @__PURE__ */ jsx(CloseIcon, {}),
|
|
1234
|
+
label: common.close,
|
|
1235
|
+
onClick: closeLog
|
|
1236
|
+
})
|
|
1237
|
+
]
|
|
1160
1238
|
}) : void 0;
|
|
1239
|
+
const sublogLoading = sublogsLoading && (!sublogs || !runNumber);
|
|
1240
|
+
const sublogLoader = /* @__PURE__ */ jsx(Loader, {
|
|
1241
|
+
label: dagStrings.loadingLogs,
|
|
1242
|
+
size: 70
|
|
1243
|
+
});
|
|
1244
|
+
const stepLogViewer = /* @__PURE__ */ jsx(LogViewer, {
|
|
1245
|
+
log: currentSublog.slice(-1e5),
|
|
1246
|
+
height: sublogIsStep ? "100%" : windowSize.h / 1.2,
|
|
1247
|
+
width: sublogIsStep ? "100%" : windowSize.w / 1.2,
|
|
1248
|
+
hideExpand: true,
|
|
1249
|
+
enableWorkflowCommands: true
|
|
1250
|
+
});
|
|
1161
1251
|
const graph = /* @__PURE__ */ jsxs("div", {
|
|
1162
1252
|
className: "flex flex-col lg:flex-row w-full",
|
|
1163
1253
|
children: [
|
|
1164
1254
|
!preview && /* @__PURE__ */ jsxs("div", {
|
|
1165
|
-
className: "hidden lg:block lg:w-[280px] flex-shrink-0 lg:mr-1",
|
|
1255
|
+
className: cx("hidden lg:block lg:w-[280px] flex-shrink-0 lg:mr-1", sidebarStickyTop !== void 0 && "lg:sticky lg:self-start lg:overflow-y-auto"),
|
|
1256
|
+
style: sidebarStickyTop !== void 0 ? {
|
|
1257
|
+
top: sidebarStickyTop,
|
|
1258
|
+
maxHeight: `calc(100dvh - ${sidebarStickyTop + 24}px)`
|
|
1259
|
+
} : void 0,
|
|
1166
1260
|
children: [
|
|
1167
1261
|
slots.runSessions && /* @__PURE__ */ jsx("div", {
|
|
1168
1262
|
className: "mb-4 overflow-y-auto",
|
|
@@ -1267,6 +1361,7 @@ function DependencyGraph({ run, preview = false, removeBorder, viewMode = "dag",
|
|
|
1267
1361
|
]
|
|
1268
1362
|
}),
|
|
1269
1363
|
!preview && /* @__PURE__ */ jsx(AnnotationBanner, { executedJobs: jobs }),
|
|
1364
|
+
children,
|
|
1270
1365
|
viewMode === "tree" && !preview ? /* @__PURE__ */ jsx("div", {
|
|
1271
1366
|
className: "panel w-full border",
|
|
1272
1367
|
children: /* @__PURE__ */ jsx(TreeView, {
|
|
@@ -1354,45 +1449,42 @@ function DependencyGraph({ run, preview = false, removeBorder, viewMode = "dag",
|
|
|
1354
1449
|
}),
|
|
1355
1450
|
/* @__PURE__ */ jsx(Modal, {
|
|
1356
1451
|
open: sublogOpen !== "",
|
|
1357
|
-
onClose:
|
|
1358
|
-
"aria-label":
|
|
1452
|
+
onClose: closeLog,
|
|
1453
|
+
"aria-label": stepTitle || sublogFile,
|
|
1454
|
+
initialFocus: () => stepHeaderRef.current?.querySelector("[role=\"tab\"][aria-selected=\"true\"]") ?? true,
|
|
1359
1455
|
align: "center",
|
|
1360
|
-
className: "max-h-full overflow-y-auto p-4 sm:p-6",
|
|
1361
|
-
children: /* @__PURE__ */
|
|
1362
|
-
className: "flex
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
}
|
|
1456
|
+
className: sublogIsStep ? "max-h-full overflow-hidden bg-(--theme-panel-bg) p-0" : "max-h-full overflow-y-auto p-4 sm:p-6",
|
|
1457
|
+
children: sublogIsStep ? /* @__PURE__ */ jsxs("div", {
|
|
1458
|
+
className: "flex flex-col",
|
|
1459
|
+
style: preview ? { width: window.innerWidth / 1.4 } : {
|
|
1460
|
+
width: windowSize.w / 1.2,
|
|
1461
|
+
height: windowSize.h / 1.2
|
|
1462
|
+
},
|
|
1463
|
+
children: [stepHeader, preview ? sublogLoading ? /* @__PURE__ */ jsx("div", {
|
|
1464
|
+
className: "flex justify-center py-16",
|
|
1465
|
+
children: sublogLoader
|
|
1466
|
+
}) : slots.yamlViewer?.({
|
|
1367
1467
|
value: currentSublog,
|
|
1368
1468
|
height: window.innerHeight / 1.4,
|
|
1369
1469
|
width: window.innerWidth / 1.4,
|
|
1370
1470
|
contentKey: `editor_${sublogOpen}`
|
|
1371
1471
|
}) ?? /* @__PURE__ */ jsx("pre", {
|
|
1372
|
-
className: "
|
|
1373
|
-
style: {
|
|
1374
|
-
height: window.innerHeight / 1.4,
|
|
1375
|
-
width: window.innerWidth / 1.4
|
|
1376
|
-
},
|
|
1472
|
+
className: "overflow-auto p-4 text-xs",
|
|
1473
|
+
style: { height: window.innerHeight / 1.4 },
|
|
1377
1474
|
children: currentSublog
|
|
1378
|
-
})
|
|
1379
|
-
className: "flex
|
|
1380
|
-
children:
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
})
|
|
1387
|
-
})]
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
hideExpand: true,
|
|
1392
|
-
additionalBottomLeftBarComponents,
|
|
1393
|
-
additionalBottomRightBarComponents,
|
|
1394
|
-
enableWorkflowCommands: true
|
|
1395
|
-
})
|
|
1475
|
+
}) : /* @__PURE__ */ jsx("div", {
|
|
1476
|
+
className: "flex min-h-0 flex-1 flex-col",
|
|
1477
|
+
children: sublogTab === "summary" ? /* @__PURE__ */ jsx(StepSummary, {
|
|
1478
|
+
runSlug,
|
|
1479
|
+
path: `${sublogDir}summary.md`
|
|
1480
|
+
}) : sublogLoading ? /* @__PURE__ */ jsx("div", {
|
|
1481
|
+
className: "flex flex-1 items-center justify-center",
|
|
1482
|
+
children: sublogLoader
|
|
1483
|
+
}) : stepLogViewer
|
|
1484
|
+
})]
|
|
1485
|
+
}) : /* @__PURE__ */ jsx("div", {
|
|
1486
|
+
className: "flex w-full",
|
|
1487
|
+
children: sublogLoading ? sublogLoader : stepLogViewer
|
|
1396
1488
|
})
|
|
1397
1489
|
})
|
|
1398
1490
|
]
|
package/dist/graph/JobSummary.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { cx } from "../cx.js";
|
|
2
|
-
import { FileTextIcon, OpenInNewGraphIcon } from "../icons.js";
|
|
2
|
+
import { FileTextIcon, OpenInNewGraphIcon, SummaryIcon } from "../icons.js";
|
|
3
3
|
import { Tooltip } from "../components/Tooltip.js";
|
|
4
4
|
import { useNavigation, useSlots, useStrings, useWorkflowEngine } from "../components/Provider.js";
|
|
5
5
|
import { RunStatusIcon } from "../components/RunStatusIcon.js";
|
|
@@ -30,7 +30,7 @@ function UsesIcon({ uses, subworkflow }) {
|
|
|
30
30
|
});
|
|
31
31
|
}
|
|
32
32
|
function Joblist(inputs) {
|
|
33
|
-
const { jobActions } = useStrings();
|
|
33
|
+
const { dag, jobActions } = useStrings();
|
|
34
34
|
const engine = useWorkflowEngine();
|
|
35
35
|
return inputs.jobNames.map((jobName) => {
|
|
36
36
|
if (inputs.jobs[jobName]?._matrixGroup) return null;
|
|
@@ -68,7 +68,17 @@ function Joblist(inputs) {
|
|
|
68
68
|
onClick: () => inputs.onStepClick(jobName, i),
|
|
69
69
|
className: cx(inputs.preview ? "ml-1.5" : "ml-4", "gap-x-1.5 flex items-center text-left"),
|
|
70
70
|
"data-testid": stepLabel,
|
|
71
|
-
children: [
|
|
71
|
+
children: [
|
|
72
|
+
inputs.preview ? "↳" : /* @__PURE__ */ jsx(RunStatusIcon, { status: step.status }),
|
|
73
|
+
/* @__PURE__ */ jsx("div", { children: stepLabel }),
|
|
74
|
+
step.summary && !inputs.preview && /* @__PURE__ */ jsx(Tooltip, {
|
|
75
|
+
content: dag.hasSummary,
|
|
76
|
+
children: /* @__PURE__ */ jsx(SummaryIcon, {
|
|
77
|
+
"aria-label": dag.hasSummary,
|
|
78
|
+
className: "w-[1.1em] h-[1.1em] shrink-0 text-(--theme-muted-text-color)"
|
|
79
|
+
})
|
|
80
|
+
})
|
|
81
|
+
]
|
|
72
82
|
});
|
|
73
83
|
return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("div", {
|
|
74
84
|
className: cx("flex items-center", step.status === "skipped" || step.status === "skipped-failed" ? "cursor-default" : "cursor-pointer"),
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Loader } from "../components/Loader.js";
|
|
2
|
+
import { useRunFile, useStrings } from "../components/Provider.js";
|
|
3
|
+
import Markdown from "../components/Markdown.js";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
//#region src/graph/StepSummary.tsx
|
|
6
|
+
function StepSummary({ runSlug, path }) {
|
|
7
|
+
const { dag } = useStrings();
|
|
8
|
+
const { data, isLoading, error } = useRunFile(runSlug, path);
|
|
9
|
+
return /* @__PURE__ */ jsx("div", {
|
|
10
|
+
className: "min-h-0 flex-1 overflow-y-auto overscroll-contain px-5 py-5 sm:px-8 sm:py-7",
|
|
11
|
+
children: isLoading && data === void 0 ? /* @__PURE__ */ jsx("div", {
|
|
12
|
+
className: "flex h-full items-center justify-center",
|
|
13
|
+
children: /* @__PURE__ */ jsx(Loader, {
|
|
14
|
+
label: dag.loadingSummary,
|
|
15
|
+
size: 70
|
|
16
|
+
})
|
|
17
|
+
}) : error || data === void 0 ? /* @__PURE__ */ jsx("p", {
|
|
18
|
+
className: "text-xs theme-muted-text",
|
|
19
|
+
children: dag.summaryLoadFailed
|
|
20
|
+
}) : /* @__PURE__ */ jsx("div", {
|
|
21
|
+
className: "max-w-[72ch]",
|
|
22
|
+
children: /* @__PURE__ */ jsx(Markdown, {
|
|
23
|
+
httpsImagesOnly: true,
|
|
24
|
+
compact: true,
|
|
25
|
+
children: data
|
|
26
|
+
})
|
|
27
|
+
})
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
export { StepSummary };
|
package/dist/graph/index.d.ts
CHANGED
|
@@ -9,4 +9,5 @@ export { type ListedProblem, ProblemsButton } from './ProblemsButton.js';
|
|
|
9
9
|
export type { SettingsView } from './settingsViews.js';
|
|
10
10
|
export { type WorkflowActions, withFields } from './stepWith.js';
|
|
11
11
|
export type { RunLink } from './types.js';
|
|
12
|
+
export { jobLabel } from './util.js';
|
|
12
13
|
export { INPUT_FORM_FIELDS, LINK_FIELDS, NEEDS_FIELDS, SESSION_FIELDS, WORKFLOW_FIELDS, WorkflowSettingsDialog, } from './WorkflowSettingsDialog.js';
|
package/dist/graph/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { trackDrag } from "./editorPrimitives.js";
|
|
2
|
+
import { jobLabel } from "./util.js";
|
|
2
3
|
import DependencyGraph, { DependencyGraphPreview } from "./DependencyGraph.js";
|
|
3
4
|
import { GRAPH_EDITOR_STRINGS, INPUTS_EDITOR_STRINGS } from "./editorStrings.js";
|
|
4
5
|
import { inputTypes, offeredInputKeys } from "./InputDialog.js";
|
|
@@ -7,4 +8,4 @@ import { JOB_FIELDS, RETRY_FIELDS, RUNS_ON_FIELDS, SSH_KEYS, STEP_FIELDS, STRATE
|
|
|
7
8
|
import { ProblemsButton } from "./ProblemsButton.js";
|
|
8
9
|
import { InputsFormEditor } from "./InputsEditor.js";
|
|
9
10
|
import { INPUT_FORM_FIELDS, LINK_FIELDS, NEEDS_FIELDS, SESSION_FIELDS, WORKFLOW_FIELDS, WorkflowSettingsDialog } from "./WorkflowSettingsDialog.js";
|
|
10
|
-
export { DependencyGraph, DependencyGraphPreview, GRAPH_EDITOR_STRINGS, INPUTS_EDITOR_STRINGS, INPUT_FORM_FIELDS, InputsFormEditor, JOB_FIELDS, LINK_FIELDS, NEEDS_FIELDS, ProblemsButton, RETRY_FIELDS, RUNS_ON_FIELDS, SESSION_FIELDS, SSH_KEYS, STEP_FIELDS, STRATEGY_FIELDS, WORKFLOW_FIELDS, WorkflowSettingsDialog, inputTypes, offeredInputKeys, trackDrag, withFields };
|
|
11
|
+
export { DependencyGraph, DependencyGraphPreview, GRAPH_EDITOR_STRINGS, INPUTS_EDITOR_STRINGS, INPUT_FORM_FIELDS, InputsFormEditor, JOB_FIELDS, LINK_FIELDS, NEEDS_FIELDS, ProblemsButton, RETRY_FIELDS, RUNS_ON_FIELDS, SESSION_FIELDS, SSH_KEYS, STEP_FIELDS, STRATEGY_FIELDS, WORKFLOW_FIELDS, WorkflowSettingsDialog, inputTypes, jobLabel, offeredInputKeys, trackDrag, withFields };
|
package/dist/graph/types.d.ts
CHANGED