@parallelworks/ui 0.12.1 → 0.14.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/dist/chunks/{BareModal-DBa84JZO.js → BareModal-BqroLbZ5.js} +1 -0
- package/dist/chunks/{CodePreviewEditor-hwjZof0M.js → CodePreviewEditor-67A_SKgE.js} +1 -1
- package/dist/chunks/{CreateModal-DLCC8t_x.js → CreateModal-DoA2WsXf.js} +28 -8
- package/dist/chunks/{Monaco-DCwRDrPm.js → Monaco-H56KyEdb.js} +22 -12
- package/dist/chunks/{PageHeader-dyoL44ue.js → PageHeader-CxxbidPp.js} +44 -10
- package/dist/chunks/{Provider-CfFV-vc5.js → Provider-CbFVFB7O.js} +8 -2
- package/dist/chunks/RequiredMark-DfLdYbYZ.js +11 -0
- package/dist/chunks/{StatusBadge-P6C2tv7Z.js → StatusBadge-RRUI78iS.js} +4 -4
- package/dist/chunks/{SwitchToggle-DcPCXkqL.js → SwitchToggle-DbW0Q__L.js} +49 -32
- package/dist/chunks/{Table-ByziK93x.js → Table-CutP1bRt.js} +22 -6
- package/dist/chunks/{Tooltip-WgbiC_nd.js → Tooltip-n9w7Tkt1.js} +28 -3
- package/dist/chunks/{editor-BH81U5-C.js → editor-BZ9Buwi4.js} +34 -23
- package/dist/chunks/lib-DyJvmbzj.js +256 -0
- package/dist/chunks/{list-CWVR3dfZ.js → list-CBZpAYP7.js} +35 -15
- package/dist/components/Breadcrumbs.d.ts +9 -0
- package/dist/components/CollapsiblePanel.d.ts +4 -4
- package/dist/components/CreateModal.d.ts +8 -8
- package/dist/components/Dropdown.d.ts +5 -3
- package/dist/components/Input.d.ts +1 -1
- package/dist/components/Listbox.d.ts +7 -4
- package/dist/components/Loader.d.ts +1 -1
- package/dist/components/MultiSelect.d.ts +8 -5
- package/dist/components/PageHeader.d.ts +4 -3
- package/dist/components/Pagination.d.ts +2 -2
- package/dist/components/Provider.d.ts +9 -3
- package/dist/components/RequiredMark.d.ts +1 -0
- package/dist/components/SettingRow.d.ts +1 -1
- package/dist/components/SwitchToggle.d.ts +3 -2
- package/dist/components/Table.d.ts +5 -3
- package/dist/components/Tooltip.d.ts +7 -1
- package/dist/components/dropdownUtils.d.ts +6 -6
- package/dist/editor/FormCodePanel.d.ts +3 -3
- package/dist/editor/Monaco.d.ts +2 -2
- package/dist/editor/index.js +1 -1
- package/dist/file-explorer/FileExplorer.d.ts +2 -2
- package/dist/file-explorer/helpers.d.ts +2 -2
- package/dist/file-explorer/index.js +46 -18
- package/dist/file-explorer/lib/fileExplorer.d.ts +1 -1
- package/dist/file-explorer/lib/types.d.ts +21 -21
- package/dist/form/FieldWrapper.d.ts +6 -1
- package/dist/form/Fields/ResourceOptionIcon.d.ts +1 -1
- package/dist/form/Fields/StepField.d.ts +1 -1
- package/dist/form/Form.d.ts +28 -27
- package/dist/form/SpecialTypes/DropdownWrapper.d.ts +16 -3
- package/dist/form/SpecialTypes/FormikCustomDropdown.d.ts +11 -11
- package/dist/form/SpecialTypes/FormikCustomInput.d.ts +12 -10
- package/dist/form/SpecialTypes/FormikMultiSelectDropdown.d.ts +1 -1
- package/dist/form/SpecialTypes/FormikNumericInput.d.ts +2 -2
- package/dist/form/Wizard/WizardContainer.d.ts +1 -1
- package/dist/form/Wizard/WizardStepContent.d.ts +2 -2
- package/dist/form/Wizard/types.d.ts +21 -14
- package/dist/form/Wizard/utils.d.ts +1 -1
- package/dist/form/fieldContext.d.ts +19 -0
- package/dist/form/index.d.ts +2 -1
- package/dist/form/index.js +191 -106
- package/dist/form/lib.d.ts +3 -3
- package/dist/form/types/fieldComponentTypes.d.ts +2 -2
- package/dist/form/useParsedOpts.d.ts +1 -1
- package/dist/form/utils/getParentValue.d.ts +3 -1
- package/dist/form/utils/getValueUsingPath.d.ts +1 -1
- package/dist/form/utils/pwResolver.d.ts +4 -4
- package/dist/icons.d.ts +8 -8
- package/dist/icons.js +4 -4
- package/dist/index.d.ts +4 -3
- package/dist/index.js +51 -21
- package/dist/list/ActionToolbar.d.ts +4 -4
- package/dist/list/HoverCard.d.ts +3 -1
- package/dist/list/ListPage.d.ts +3 -3
- package/dist/list/ListTable.d.ts +1 -1
- package/dist/list/RowContextMenu.d.ts +20 -20
- package/dist/list/index.js +2 -2
- package/dist/logviewer/index.js +24 -7
- package/dist/styles/theme.css +6 -6
- package/dist/styles.css +1 -1
- package/dist/theme/index.js +4 -3
- package/dist/workflow/AnnotationBanner.d.ts +2 -1
- package/dist/workflow/DependencyGraph.d.ts +15 -3
- package/dist/workflow/JobSummary.d.ts +2 -25
- package/dist/workflow/MatrixGroup.d.ts +3 -2
- package/dist/workflow/TreeView.d.ts +1 -32
- package/dist/workflow/index.js +235 -138
- package/dist/workflow/types.d.ts +48 -0
- package/package.json +2 -6
- package/dist/chunks/lib-DTgL8klR.js +0 -191
package/dist/workflow/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { ArrowLeftIcon, ArrowRightIcon, ChevronDownIcon, ChevronRightIcon, DocumentIcon, ErrorIcon, InfoIcon, LoaderIcon, OpenInNewGraphIcon, WarningIcon } from "../icons.js";
|
|
2
|
-
import { c as useStrings, o as useRunFile, r as useNavigation, s as useSlots } from "../chunks/Provider-
|
|
3
|
-
import { n as TOOLTIP_ID, r as TooltipInfo } from "../chunks/Tooltip-
|
|
2
|
+
import { c as useStrings, o as useRunFile, r as useNavigation, s as useSlots } from "../chunks/Provider-CbFVFB7O.js";
|
|
3
|
+
import { n as TOOLTIP_ID, r as TooltipInfo } from "../chunks/Tooltip-n9w7Tkt1.js";
|
|
4
4
|
import { t as Loader } from "../chunks/Loader-BXoXTZGc.js";
|
|
5
|
-
import { n as modalPanelClasses, t as BareModal } from "../chunks/BareModal-
|
|
5
|
+
import { n as modalPanelClasses, t as BareModal } from "../chunks/BareModal-BqroLbZ5.js";
|
|
6
6
|
import { t as Indicator } from "../chunks/Indicator-hBSIxOPK.js";
|
|
7
7
|
import { LogViewer } from "../logviewer/index.js";
|
|
8
8
|
import cx from "classnames";
|
|
9
9
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
-
import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
10
|
+
import React, { useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
11
11
|
import { flushSync } from "react-dom";
|
|
12
12
|
import { DateTime } from "luxon";
|
|
13
13
|
import { buildSubworkflowLogPath, collapseMatrixGroupsInLayout, collectExpansionKeys, computeMatrixAggStatus, detectMatrixGroups, dumpYaml, getAllDeps, getStepLabel, isRunActive, toAbsHumanDuration } from "@parallelworks/workflow-parser";
|
|
@@ -246,13 +246,15 @@ function UsesIcon({ uses, subworkflow }) {
|
|
|
246
246
|
const { jobActions } = useStrings();
|
|
247
247
|
if (!uses || !slots.workflowIcon) return null;
|
|
248
248
|
const open = () => {
|
|
249
|
-
if (uses.startsWith("workflow/")) navigation.toWorkflow(uses.split("/")[1]);
|
|
249
|
+
if (uses.startsWith("workflow/")) navigation.toWorkflow(uses.split("/")[1] ?? "");
|
|
250
250
|
else if (uses.startsWith("github/")) {
|
|
251
251
|
const [ownerRepo, ref] = uses.replace("github/", "").split("@");
|
|
252
252
|
navigation.openExternal("https://github.com/" + ownerRepo + "/tree/" + ref);
|
|
253
|
-
} else navigation.toMarketItem(uses.split("/")[1]);
|
|
253
|
+
} else navigation.toMarketItem(uses.split("/")[1] ?? "");
|
|
254
254
|
};
|
|
255
|
-
return /* @__PURE__ */ jsx("
|
|
255
|
+
return /* @__PURE__ */ jsx("button", {
|
|
256
|
+
type: "button",
|
|
257
|
+
"aria-label": jobActions.openOriginalWorkflow,
|
|
256
258
|
"data-tooltip-id": TOOLTIP_ID,
|
|
257
259
|
"data-tooltip-content": jobActions.openOriginalWorkflow,
|
|
258
260
|
onClick: open,
|
|
@@ -273,9 +275,11 @@ function Joblist(inputs) {
|
|
|
273
275
|
const jobLabel = matrixMeta?.originaljob ? `${matrixMeta.originaljob[0].toUpperCase() + matrixMeta.originaljob.slice(1)} (${(matrixMeta.index ?? 0) + 1}/${matrixMeta.totalingroup ?? "?"})` : (jobName[0].toUpperCase() + jobName.slice(1)).replace(/_/g, " ");
|
|
274
276
|
return /* @__PURE__ */ jsxs("div", {
|
|
275
277
|
className: "py-1 select-none",
|
|
276
|
-
children: [/* @__PURE__ */ jsxs("
|
|
278
|
+
children: [/* @__PURE__ */ jsxs("button", {
|
|
279
|
+
type: "button",
|
|
280
|
+
"aria-expanded": inputs.isStepsOpen(jobName),
|
|
277
281
|
onClick: () => inputs.onJobClick(jobName),
|
|
278
|
-
className: cx("flex items-center gap-x-1.5", jobStatus === "skipped" || jobStatus === "skipped-failed" ? "cursor-default" : "cursor-pointer"),
|
|
282
|
+
className: cx("flex items-center gap-x-1.5 w-full text-left", jobStatus === "skipped" || jobStatus === "skipped-failed" ? "cursor-default" : "cursor-pointer"),
|
|
279
283
|
children: [!inputs.preview && /* @__PURE__ */ jsx(Indicator, { status: inputs.jobs[jobName]?.status }), /* @__PURE__ */ jsx("div", {
|
|
280
284
|
className: "font-medium",
|
|
281
285
|
children: jobLabel
|
|
@@ -291,9 +295,10 @@ function Joblist(inputs) {
|
|
|
291
295
|
const canExpand = !!inputs.renderSubworkflow && !!subJobs && Object.keys(subJobs).length > 0;
|
|
292
296
|
return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("div", {
|
|
293
297
|
className: cx("flex items-center", step.status === "skipped" || step.status === "skipped-failed" ? "cursor-default" : "cursor-pointer"),
|
|
294
|
-
children: [/* @__PURE__ */ jsxs("
|
|
298
|
+
children: [/* @__PURE__ */ jsxs("button", {
|
|
299
|
+
type: "button",
|
|
295
300
|
onClick: () => inputs.onStepClick(jobName, i),
|
|
296
|
-
className: cx(inputs.preview ? "ml-1.5" : "ml-4", "gap-x-1.5 flex items-center"),
|
|
301
|
+
className: cx(inputs.preview ? "ml-1.5" : "ml-4", "gap-x-1.5 flex items-center text-left"),
|
|
297
302
|
"data-testid": stepLabel,
|
|
298
303
|
children: [inputs.preview ? "↳" : /* @__PURE__ */ jsx(Indicator, { status: step.status }), /* @__PURE__ */ jsx("div", { children: stepLabel })]
|
|
299
304
|
}), step.subworkflow && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -373,10 +378,14 @@ function InlineLogViewer({ slug, jobName, stepIndex }) {
|
|
|
373
378
|
function JobRow({ jobName, job, isExpanded, onToggle, dependencies, workflowName, runNumber, slug, expandedJobs, onJobToggle, expandedSteps, onStepToggle }) {
|
|
374
379
|
const hasSteps = job.steps && job.steps.length > 0;
|
|
375
380
|
const duration = getJobDuration(job);
|
|
381
|
+
const panelId = useId();
|
|
376
382
|
return /* @__PURE__ */ jsxs("div", {
|
|
377
383
|
className: "border-b border-[var(--theme-border)] last:border-b-0",
|
|
378
|
-
children: [/* @__PURE__ */ jsxs("
|
|
379
|
-
|
|
384
|
+
children: [/* @__PURE__ */ jsxs("button", {
|
|
385
|
+
type: "button",
|
|
386
|
+
"aria-expanded": isExpanded,
|
|
387
|
+
"aria-controls": hasSteps ? panelId : void 0,
|
|
388
|
+
className: cx("flex items-center gap-3 px-5 py-3 transition-colors w-full text-left", job.status === "skipped" || job.status === "skipped-failed" ? "cursor-default" : "cursor-pointer", isExpanded && "bg-[var(--theme-panel-bg)]"),
|
|
380
389
|
onClick: onToggle,
|
|
381
390
|
children: [
|
|
382
391
|
/* @__PURE__ */ jsx(motion.div, {
|
|
@@ -433,6 +442,7 @@ function JobRow({ jobName, job, isExpanded, onToggle, dependencies, workflowName
|
|
|
433
442
|
]
|
|
434
443
|
},
|
|
435
444
|
className: "overflow-hidden",
|
|
445
|
+
id: panelId,
|
|
436
446
|
children: /* @__PURE__ */ jsx("div", {
|
|
437
447
|
className: "ml-[38px] border-l-2 border-[var(--theme-border)]",
|
|
438
448
|
children: job.steps.map((step, index) => {
|
|
@@ -462,20 +472,24 @@ function StepRow({ step, index, isExpanded, onToggle, workflowName, runNumber, s
|
|
|
462
472
|
const duration = getStepDuration(step);
|
|
463
473
|
const label = getStepLabel(step, index);
|
|
464
474
|
const isSubworkflow = !!step.subworkflow;
|
|
465
|
-
const
|
|
466
|
-
const
|
|
475
|
+
const panelId = useId();
|
|
476
|
+
const subworkflowJobs = step.subworkflow?.jobs ?? null;
|
|
477
|
+
const subworkflowJobNames = subworkflowJobs ? Object.keys(subworkflowJobs).filter((name) => subworkflowJobs[name]?.if !== false) : [];
|
|
467
478
|
const subworkflowDependenciesMap = useMemo(() => {
|
|
468
479
|
if (!subworkflowJobs) return {};
|
|
469
480
|
const map = {};
|
|
470
481
|
for (const subJobName of subworkflowJobNames) {
|
|
471
482
|
const job = subworkflowJobs[subJobName];
|
|
472
|
-
if (job
|
|
483
|
+
if (job?.needs && Array.isArray(job.needs) && job.needs.length > 0) map[subJobName] = job.needs;
|
|
473
484
|
}
|
|
474
485
|
return map;
|
|
475
486
|
}, [subworkflowJobs, subworkflowJobNames]);
|
|
476
487
|
return /* @__PURE__ */ jsxs("div", { children: [
|
|
477
|
-
/* @__PURE__ */ jsxs("
|
|
478
|
-
|
|
488
|
+
/* @__PURE__ */ jsxs("button", {
|
|
489
|
+
type: "button",
|
|
490
|
+
"aria-expanded": isExpanded,
|
|
491
|
+
"aria-controls": panelId,
|
|
492
|
+
className: cx("flex items-center gap-3 px-5 py-2.5 cursor-pointer transition-colors w-full text-left", isExpanded ? "" : "hover:bg-[var(--theme-hover)]"),
|
|
479
493
|
onClick: onToggle,
|
|
480
494
|
children: [
|
|
481
495
|
/* @__PURE__ */ jsx(motion.div, {
|
|
@@ -486,8 +500,8 @@ function StepRow({ step, index, isExpanded, onToggle, workflowName, runNumber, s
|
|
|
486
500
|
}),
|
|
487
501
|
/* @__PURE__ */ jsx(Indicator, { status: step.status }),
|
|
488
502
|
isSubworkflow && slots.workflowIcon?.({
|
|
489
|
-
image: step.subworkflow
|
|
490
|
-
type: step.subworkflow
|
|
503
|
+
image: step.subworkflow?.image,
|
|
504
|
+
type: step.subworkflow?.type,
|
|
491
505
|
className: "h-4 w-4 flex-shrink-0"
|
|
492
506
|
}),
|
|
493
507
|
/* @__PURE__ */ jsxs("span", {
|
|
@@ -528,6 +542,7 @@ function StepRow({ step, index, isExpanded, onToggle, workflowName, runNumber, s
|
|
|
528
542
|
]
|
|
529
543
|
},
|
|
530
544
|
className: "overflow-hidden",
|
|
545
|
+
id: panelId,
|
|
531
546
|
children: /* @__PURE__ */ jsx(InlineLogViewer, {
|
|
532
547
|
slug,
|
|
533
548
|
jobName,
|
|
@@ -560,15 +575,17 @@ function StepRow({ step, index, isExpanded, onToggle, workflowName, runNumber, s
|
|
|
560
575
|
]
|
|
561
576
|
},
|
|
562
577
|
className: "overflow-hidden",
|
|
578
|
+
id: panelId,
|
|
563
579
|
children: /* @__PURE__ */ jsx("div", {
|
|
564
580
|
className: "ml-[38px] border-l-2 border-[var(--theme-border)]",
|
|
565
581
|
children: subworkflowJobNames.map((subJobName) => {
|
|
582
|
+
const subJob = subworkflowJobs?.[subJobName];
|
|
583
|
+
if (!subJob) return null;
|
|
566
584
|
const subJobKey = `${jobName}:${index}:${subJobName}`;
|
|
567
|
-
const isSubJobExpanded = expandedJobs.has(subJobKey);
|
|
568
585
|
return /* @__PURE__ */ jsx(SubworkflowJobRow, {
|
|
569
586
|
jobName: subJobName,
|
|
570
|
-
job:
|
|
571
|
-
isExpanded:
|
|
587
|
+
job: subJob,
|
|
588
|
+
isExpanded: expandedJobs.has(subJobKey),
|
|
572
589
|
onToggle: () => onJobToggle(subJobKey),
|
|
573
590
|
dependencies: subworkflowDependenciesMap[subJobName],
|
|
574
591
|
slug,
|
|
@@ -590,10 +607,14 @@ function SubworkflowJobRow({ jobName, job, isExpanded, onToggle, dependencies, s
|
|
|
590
607
|
const hasSteps = job.steps && job.steps.length > 0;
|
|
591
608
|
const duration = getJobDuration(job);
|
|
592
609
|
const nestedSubworkflowPrefix = `${subworkflowPrefix || ""}subworkflows/${parentJobName}/step_${parentStepIndex}/`;
|
|
610
|
+
const panelId = useId();
|
|
593
611
|
return /* @__PURE__ */ jsxs("div", {
|
|
594
612
|
className: "border-b border-[var(--theme-border)] last:border-b-0",
|
|
595
|
-
children: [/* @__PURE__ */ jsxs("
|
|
596
|
-
|
|
613
|
+
children: [/* @__PURE__ */ jsxs("button", {
|
|
614
|
+
type: "button",
|
|
615
|
+
"aria-expanded": isExpanded,
|
|
616
|
+
"aria-controls": hasSteps ? panelId : void 0,
|
|
617
|
+
className: cx("flex items-center gap-3 px-5 py-3 transition-colors w-full text-left", job.status === "skipped" || job.status === "skipped-failed" ? "cursor-default" : "cursor-pointer", isExpanded && "bg-[var(--theme-panel-bg)]"),
|
|
597
618
|
onClick: onToggle,
|
|
598
619
|
children: [
|
|
599
620
|
/* @__PURE__ */ jsx(motion.div, {
|
|
@@ -650,6 +671,7 @@ function SubworkflowJobRow({ jobName, job, isExpanded, onToggle, dependencies, s
|
|
|
650
671
|
]
|
|
651
672
|
},
|
|
652
673
|
className: "overflow-hidden",
|
|
674
|
+
id: panelId,
|
|
653
675
|
children: /* @__PURE__ */ jsx("div", {
|
|
654
676
|
className: "ml-[38px] border-l-2 border-[var(--theme-border)]",
|
|
655
677
|
children: job.steps.map((step, index) => {
|
|
@@ -679,20 +701,24 @@ function SubworkflowStepRow({ step, index, isExpanded, onToggle, slug, subworkfl
|
|
|
679
701
|
const duration = getStepDuration(step);
|
|
680
702
|
const label = getStepLabel(step, index);
|
|
681
703
|
const isSubworkflow = !!step.subworkflow;
|
|
682
|
-
const
|
|
683
|
-
const
|
|
704
|
+
const panelId = useId();
|
|
705
|
+
const subworkflowJobs = step.subworkflow?.jobs ?? null;
|
|
706
|
+
const subworkflowJobNames = subworkflowJobs ? Object.keys(subworkflowJobs).filter((name) => subworkflowJobs[name]?.if !== false) : [];
|
|
684
707
|
const subworkflowDependenciesMap = useMemo(() => {
|
|
685
708
|
if (!subworkflowJobs) return {};
|
|
686
709
|
const map = {};
|
|
687
710
|
for (const subJobName of subworkflowJobNames) {
|
|
688
711
|
const job = subworkflowJobs[subJobName];
|
|
689
|
-
if (job
|
|
712
|
+
if (job?.needs && Array.isArray(job.needs) && job.needs.length > 0) map[subJobName] = job.needs;
|
|
690
713
|
}
|
|
691
714
|
return map;
|
|
692
715
|
}, [subworkflowJobs, subworkflowJobNames]);
|
|
693
716
|
return /* @__PURE__ */ jsxs("div", { children: [
|
|
694
|
-
/* @__PURE__ */ jsxs("
|
|
695
|
-
|
|
717
|
+
/* @__PURE__ */ jsxs("button", {
|
|
718
|
+
type: "button",
|
|
719
|
+
"aria-expanded": isExpanded,
|
|
720
|
+
"aria-controls": panelId,
|
|
721
|
+
className: cx("flex items-center gap-3 px-5 py-2.5 cursor-pointer transition-colors w-full text-left", isExpanded ? "" : "hover:bg-[var(--theme-hover)]"),
|
|
696
722
|
onClick: onToggle,
|
|
697
723
|
children: [
|
|
698
724
|
/* @__PURE__ */ jsx(motion.div, {
|
|
@@ -703,8 +729,8 @@ function SubworkflowStepRow({ step, index, isExpanded, onToggle, slug, subworkfl
|
|
|
703
729
|
}),
|
|
704
730
|
/* @__PURE__ */ jsx(Indicator, { status: step.status }),
|
|
705
731
|
isSubworkflow && slots.workflowIcon?.({
|
|
706
|
-
image: step.subworkflow
|
|
707
|
-
type: step.subworkflow
|
|
732
|
+
image: step.subworkflow?.image,
|
|
733
|
+
type: step.subworkflow?.type,
|
|
708
734
|
className: "h-4 w-4 flex-shrink-0"
|
|
709
735
|
}),
|
|
710
736
|
/* @__PURE__ */ jsxs("span", {
|
|
@@ -745,6 +771,7 @@ function SubworkflowStepRow({ step, index, isExpanded, onToggle, slug, subworkfl
|
|
|
745
771
|
]
|
|
746
772
|
},
|
|
747
773
|
className: "overflow-hidden",
|
|
774
|
+
id: panelId,
|
|
748
775
|
children: /* @__PURE__ */ jsx(SubworkflowInlineLogViewer, {
|
|
749
776
|
slug,
|
|
750
777
|
subworkflowPrefix,
|
|
@@ -778,15 +805,17 @@ function SubworkflowStepRow({ step, index, isExpanded, onToggle, slug, subworkfl
|
|
|
778
805
|
]
|
|
779
806
|
},
|
|
780
807
|
className: "overflow-hidden",
|
|
808
|
+
id: panelId,
|
|
781
809
|
children: /* @__PURE__ */ jsx("div", {
|
|
782
810
|
className: "ml-[38px] border-l-2 border-[var(--theme-border)]",
|
|
783
811
|
children: subworkflowJobNames.map((subJobName) => {
|
|
812
|
+
const subJob = subworkflowJobs?.[subJobName];
|
|
813
|
+
if (!subJob) return null;
|
|
784
814
|
const subJobKey = `${subworkflowPrefix}${jobName}:${index}:${subJobName}`;
|
|
785
|
-
const isSubJobExpanded = expandedJobs.has(subJobKey);
|
|
786
815
|
return /* @__PURE__ */ jsx(SubworkflowJobRow, {
|
|
787
816
|
jobName: subJobName,
|
|
788
|
-
job:
|
|
789
|
-
isExpanded:
|
|
817
|
+
job: subJob,
|
|
818
|
+
isExpanded: expandedJobs.has(subJobKey),
|
|
790
819
|
onToggle: () => onJobToggle(subJobKey),
|
|
791
820
|
dependencies: subworkflowDependenciesMap[subJobName],
|
|
792
821
|
slug,
|
|
@@ -829,7 +858,7 @@ function SubworkflowInlineLogViewer({ slug, subworkflowPrefix, jobName, stepInde
|
|
|
829
858
|
}
|
|
830
859
|
function TreeView({ jobs, workflowName, runNumber, slug, expandedJobs, setExpandedJobs }) {
|
|
831
860
|
const visibleJobNames = useMemo(() => {
|
|
832
|
-
return Object.keys(jobs).filter((jobName) => jobs[jobName]
|
|
861
|
+
return Object.keys(jobs).filter((jobName) => jobs[jobName]?.if !== false);
|
|
833
862
|
}, [jobs]);
|
|
834
863
|
const [expandedSteps, setExpandedSteps] = useState(/* @__PURE__ */ new Set());
|
|
835
864
|
const [expandedSubworkflowJobs, setExpandedSubworkflowJobs] = useState(/* @__PURE__ */ new Set());
|
|
@@ -876,7 +905,7 @@ function TreeView({ jobs, workflowName, runNumber, slug, expandedJobs, setExpand
|
|
|
876
905
|
const map = {};
|
|
877
906
|
for (const jobName of visibleJobNames) {
|
|
878
907
|
const job = jobs[jobName];
|
|
879
|
-
if (job
|
|
908
|
+
if (job?.needs && Array.isArray(job.needs) && job.needs.length > 0) map[jobName] = job.needs;
|
|
880
909
|
}
|
|
881
910
|
return map;
|
|
882
911
|
}, [jobs, visibleJobNames]);
|
|
@@ -894,13 +923,10 @@ function TreeView({ jobs, workflowName, runNumber, slug, expandedJobs, setExpand
|
|
|
894
923
|
const matrixGroups = {};
|
|
895
924
|
for (const jobName of visibleJobNames) {
|
|
896
925
|
const matrix = jobs[jobName]?._matrix;
|
|
897
|
-
if (matrix?.originaljob) {
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
};
|
|
902
|
-
matrixGroups[matrix.originaljob].members.push(jobName);
|
|
903
|
-
}
|
|
926
|
+
if (matrix?.originaljob) (matrixGroups[matrix.originaljob] ??= {
|
|
927
|
+
originaljob: matrix.originaljob,
|
|
928
|
+
members: []
|
|
929
|
+
}).members.push(jobName);
|
|
904
930
|
}
|
|
905
931
|
for (const group of Object.values(matrixGroups)) group.members.sort((a, b) => (jobs[a]?._matrix?.index ?? 0) - (jobs[b]?._matrix?.index ?? 0));
|
|
906
932
|
const rendered = [];
|
|
@@ -911,12 +937,16 @@ function TreeView({ jobs, workflowName, runNumber, slug, expandedJobs, setExpand
|
|
|
911
937
|
if (seenMatrixGroups.has(matrixOrigin)) continue;
|
|
912
938
|
seenMatrixGroups.add(matrixOrigin);
|
|
913
939
|
const group = matrixGroups[matrixOrigin];
|
|
940
|
+
if (!group) continue;
|
|
914
941
|
const isGroupExpanded = expandedJobs.has(`matrix:${matrixOrigin}`);
|
|
915
942
|
const { aggStatus } = computeMatrixAggStatus(group.members.map((m) => jobs[m]?.status));
|
|
916
943
|
rendered.push(/* @__PURE__ */ jsxs("div", {
|
|
917
944
|
className: "border-b border-[var(--theme-border)]",
|
|
918
|
-
children: [/* @__PURE__ */ jsxs("
|
|
919
|
-
|
|
945
|
+
children: [/* @__PURE__ */ jsxs("button", {
|
|
946
|
+
type: "button",
|
|
947
|
+
"aria-expanded": isGroupExpanded,
|
|
948
|
+
"aria-controls": `matrix-panel-${matrixOrigin}`,
|
|
949
|
+
className: "flex items-center gap-3 px-5 py-3 cursor-pointer transition-colors w-full text-left",
|
|
920
950
|
onClick: () => toggleJob(`matrix:${matrixOrigin}`),
|
|
921
951
|
children: [
|
|
922
952
|
/* @__PURE__ */ jsx(motion.div, {
|
|
@@ -952,6 +982,7 @@ function TreeView({ jobs, workflowName, runNumber, slug, expandedJobs, setExpand
|
|
|
952
982
|
},
|
|
953
983
|
transition: { duration: .15 },
|
|
954
984
|
className: "overflow-hidden pl-4",
|
|
985
|
+
id: `matrix-panel-${matrixOrigin}`,
|
|
955
986
|
children: group.members.map((memberName) => /* @__PURE__ */ jsx(JobRow, {
|
|
956
987
|
jobName: memberName,
|
|
957
988
|
job: jobs[memberName],
|
|
@@ -993,9 +1024,11 @@ function TreeView({ jobs, workflowName, runNumber, slug, expandedJobs, setExpand
|
|
|
993
1024
|
function MatrixGroupSummaryItem({ matrixGroup, status, isExpanded, onToggle, jobs, isStepsOpen, onJobClick, onStepClick, onStepLogClick, onSubworkflowIcon, isSubworkflowExpanded, renderSubworkflow, preview }) {
|
|
994
1025
|
return /* @__PURE__ */ jsxs("div", {
|
|
995
1026
|
className: "py-1.5",
|
|
996
|
-
children: [/* @__PURE__ */ jsxs("
|
|
1027
|
+
children: [/* @__PURE__ */ jsxs("button", {
|
|
1028
|
+
type: "button",
|
|
1029
|
+
"aria-expanded": isExpanded,
|
|
997
1030
|
onClick: onToggle,
|
|
998
|
-
className: "cursor-pointer flex items-center gap-x-1.5",
|
|
1031
|
+
className: "cursor-pointer flex items-center gap-x-1.5 w-full text-left",
|
|
999
1032
|
children: [/* @__PURE__ */ jsx(Indicator, { status }), /* @__PURE__ */ jsxs("div", {
|
|
1000
1033
|
className: "font-semibold",
|
|
1001
1034
|
children: [
|
|
@@ -1038,18 +1071,23 @@ function MatrixGroupNode({ matrixGroup, jobNames, idPrefix, isExpanded, onToggle
|
|
|
1038
1071
|
const { aggStatus, statusLabel } = computeMatrixAggStatus(matrixMembers.map((m) => jobs[m]?.status));
|
|
1039
1072
|
return /* @__PURE__ */ jsxs("div", {
|
|
1040
1073
|
id: "node_" + idPrefix + jobNames[0],
|
|
1074
|
+
role: "none",
|
|
1041
1075
|
className: "relative m-24",
|
|
1042
1076
|
style: { zIndex: (activeDists?.has(jobNames[0]) ? 25 : 1) + zBase },
|
|
1043
1077
|
onMouseEnter,
|
|
1044
1078
|
onMouseLeave,
|
|
1079
|
+
onFocus: onMouseEnter,
|
|
1080
|
+
onBlur: onMouseLeave,
|
|
1045
1081
|
children: [/* @__PURE__ */ jsx("div", { className: "absolute inset-0 rounded-2xl bg-(--theme-panel-bg)" }), /* @__PURE__ */ jsxs("div", {
|
|
1046
1082
|
className: "relative border-solid shadow py-4 px-8 rounded-xl border-4 whitespace-nowrap bg-(--theme-panel-bg) text-2xl",
|
|
1047
1083
|
style: {
|
|
1048
1084
|
opacity: hoveredRelated && !hoveredRelated.has(jobNames[0]) ? .5 : 1,
|
|
1049
1085
|
transition: `opacity ${animT}s`
|
|
1050
1086
|
},
|
|
1051
|
-
children: [/* @__PURE__ */ jsxs("
|
|
1052
|
-
|
|
1087
|
+
children: [/* @__PURE__ */ jsxs("button", {
|
|
1088
|
+
type: "button",
|
|
1089
|
+
"aria-expanded": isExpanded,
|
|
1090
|
+
className: "cursor-pointer w-full text-left",
|
|
1053
1091
|
onClick: onToggle,
|
|
1054
1092
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
1055
1093
|
className: "font-semibold text-md p-0.5",
|
|
@@ -1086,6 +1124,11 @@ function MatrixGroupNode({ matrixGroup, jobNames, idPrefix, isExpanded, onToggle
|
|
|
1086
1124
|
}, "node_" + jobNames[0]);
|
|
1087
1125
|
}
|
|
1088
1126
|
//#endregion
|
|
1127
|
+
//#region src/workflow/types.ts
|
|
1128
|
+
function isJobRecord(value) {
|
|
1129
|
+
return typeof value === "object" && value !== null;
|
|
1130
|
+
}
|
|
1131
|
+
//#endregion
|
|
1089
1132
|
//#region src/workflow/DependencyGraph.tsx
|
|
1090
1133
|
function ViewToggle({ viewMode, setViewMode }) {
|
|
1091
1134
|
return /* @__PURE__ */ jsxs("div", {
|
|
@@ -1106,36 +1149,46 @@ function ViewToggle({ viewMode, setViewMode }) {
|
|
|
1106
1149
|
var addCleanupSteps = ({ jobs }) => {
|
|
1107
1150
|
const clonedJobs = structuredClone(jobs);
|
|
1108
1151
|
for (const job in jobs) {
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
run: step.cleanup,
|
|
1116
|
-
linkedStep: `${jobs[job].steps.length - index - 1}`
|
|
1117
|
-
};
|
|
1118
|
-
delete newStep.cleanup;
|
|
1119
|
-
delete clonedJobs[job].steps[index].cleanup;
|
|
1120
|
-
clonedJobs[job].steps.push(newStep);
|
|
1121
|
-
});
|
|
1122
|
-
if (Array.isArray(jobs[job].cleanup)) {
|
|
1123
|
-
jobs[job].cleanup.slice().reverse().forEach((step, index) => {
|
|
1152
|
+
const source = jobs[job];
|
|
1153
|
+
const cloned = clonedJobs[job];
|
|
1154
|
+
if (!source || !cloned) continue;
|
|
1155
|
+
if (Array.isArray(source.steps)) {
|
|
1156
|
+
const sourceSteps = source.steps;
|
|
1157
|
+
sourceSteps.slice().reverse().forEach((step, index) => {
|
|
1124
1158
|
if (!step.cleanup) return;
|
|
1125
|
-
const linkedName = step.name ? step.name : `
|
|
1159
|
+
const linkedName = step.name ? step.name : `Step ${sourceSteps.length - index - 1}`;
|
|
1126
1160
|
const newStep = {
|
|
1127
1161
|
...step,
|
|
1128
1162
|
name: `POST ${linkedName}`,
|
|
1129
1163
|
run: step.cleanup,
|
|
1130
|
-
linkedStep: `${
|
|
1164
|
+
linkedStep: `${sourceSteps.length - index - 1}`
|
|
1131
1165
|
};
|
|
1132
1166
|
delete newStep.cleanup;
|
|
1133
|
-
|
|
1134
|
-
|
|
1167
|
+
const clonedStep = cloned.steps[index];
|
|
1168
|
+
if (clonedStep) delete clonedStep.cleanup;
|
|
1169
|
+
cloned.steps.push(newStep);
|
|
1135
1170
|
});
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1171
|
+
}
|
|
1172
|
+
const sourceCleanup = source.cleanup;
|
|
1173
|
+
const clonedCleanup = cloned.cleanup;
|
|
1174
|
+
if (Array.isArray(sourceCleanup) && clonedCleanup) {
|
|
1175
|
+
sourceCleanup.slice().reverse().forEach((step, index) => {
|
|
1176
|
+
if (!step.cleanup) return;
|
|
1177
|
+
const linkedName = step.name ? step.name : `Cleanup ${sourceCleanup.length - index - 1}`;
|
|
1178
|
+
const newStep = {
|
|
1179
|
+
...step,
|
|
1180
|
+
name: `POST ${linkedName}`,
|
|
1181
|
+
run: step.cleanup,
|
|
1182
|
+
linkedStep: `${sourceCleanup.length - index - 1 + cloned.steps.length}`
|
|
1183
|
+
};
|
|
1184
|
+
delete newStep.cleanup;
|
|
1185
|
+
const clonedStep = clonedCleanup[index];
|
|
1186
|
+
if (clonedStep) delete clonedStep.cleanup;
|
|
1187
|
+
clonedCleanup.push(newStep);
|
|
1188
|
+
});
|
|
1189
|
+
for (const clonedStep of clonedCleanup) clonedStep.linkedStep = ".";
|
|
1190
|
+
cloned.steps = [...cloned.steps, ...clonedCleanup];
|
|
1191
|
+
delete cloned.cleanup;
|
|
1139
1192
|
}
|
|
1140
1193
|
}
|
|
1141
1194
|
return clonedJobs;
|
|
@@ -1157,22 +1210,27 @@ function offsetWithin(el, ancestor) {
|
|
|
1157
1210
|
function parsePrefixToPath(prefix) {
|
|
1158
1211
|
const parts = prefix.split("/").filter(Boolean);
|
|
1159
1212
|
const path = [];
|
|
1160
|
-
for (let i = 0; i + 2 < parts.length; i += 3)
|
|
1213
|
+
for (let i = 0; i + 2 < parts.length; i += 3) {
|
|
1214
|
+
const name = parts[i + 1];
|
|
1215
|
+
const step = parts[i + 2];
|
|
1216
|
+
if (parts[i] === "subworkflows" && name && step?.startsWith("step_")) path.push(name, "steps", Number(step.slice(5)), "subworkflow", "jobs");
|
|
1217
|
+
}
|
|
1161
1218
|
return path;
|
|
1162
1219
|
}
|
|
1163
1220
|
function computeGraphLayout(jobs, matrixGroups) {
|
|
1164
1221
|
const visibleJobs = structuredClone(jobs);
|
|
1165
|
-
for (const jobName of Object.keys(jobs ?? {})) if (jobs[jobName]
|
|
1222
|
+
for (const jobName of Object.keys(jobs ?? {})) if (jobs[jobName]?.if === false) delete visibleJobs[jobName];
|
|
1166
1223
|
collapseMatrixGroupsInLayout(matrixGroups, visibleJobs);
|
|
1167
1224
|
const allDeps = {};
|
|
1168
1225
|
for (const jobName of Object.keys(visibleJobs)) allDeps[jobName] = getAllDeps(jobName, visibleJobs, allDeps);
|
|
1169
1226
|
const filteredDeps = {};
|
|
1170
1227
|
for (const jobName of Object.keys(visibleJobs)) {
|
|
1171
|
-
const
|
|
1228
|
+
const needs = visibleJobs[jobName]?.needs;
|
|
1229
|
+
const oldNeeds = Array.isArray(needs) ? needs : [];
|
|
1172
1230
|
filteredDeps[jobName] = oldNeeds.filter((dep) => {
|
|
1173
1231
|
return !oldNeeds.some((other) => {
|
|
1174
1232
|
if (other === dep) return false;
|
|
1175
|
-
return allDeps[other]
|
|
1233
|
+
return allDeps[other]?.has(dep) === true;
|
|
1176
1234
|
});
|
|
1177
1235
|
}).sort();
|
|
1178
1236
|
}
|
|
@@ -1187,10 +1245,11 @@ function computeGraphLayout(jobs, matrixGroups) {
|
|
|
1187
1245
|
if (depended_on[jobName]) depended_on[jobName].sort();
|
|
1188
1246
|
});
|
|
1189
1247
|
const unfinished = structuredClone(visibleJobs);
|
|
1190
|
-
const
|
|
1248
|
+
const rootLevel = [];
|
|
1249
|
+
const deps = [rootLevel];
|
|
1191
1250
|
Object.keys(visibleJobs).map((jobName) => {
|
|
1192
|
-
if (filteredDeps[jobName]
|
|
1193
|
-
|
|
1251
|
+
if (filteredDeps[jobName]?.length === 0) {
|
|
1252
|
+
rootLevel.push(jobName);
|
|
1194
1253
|
delete unfinished[jobName];
|
|
1195
1254
|
}
|
|
1196
1255
|
});
|
|
@@ -1200,7 +1259,7 @@ function computeGraphLayout(jobs, matrixGroups) {
|
|
|
1200
1259
|
const unfinishedArr = Object.keys(unfinished);
|
|
1201
1260
|
prevLen = unfinishedArr.length;
|
|
1202
1261
|
unfinishedArr.map((jobName) => {
|
|
1203
|
-
if (filteredDeps[jobName].every((dep) => !unfinishedArr.includes(dep))) {
|
|
1262
|
+
if ((filteredDeps[jobName] ?? []).every((dep) => !unfinishedArr.includes(dep))) {
|
|
1204
1263
|
toAppend.push(jobName);
|
|
1205
1264
|
delete unfinished[jobName];
|
|
1206
1265
|
}
|
|
@@ -1211,17 +1270,19 @@ function computeGraphLayout(jobs, matrixGroups) {
|
|
|
1211
1270
|
deps.map((col) => {
|
|
1212
1271
|
const toAppend = [];
|
|
1213
1272
|
while (col.length > 0) {
|
|
1214
|
-
const
|
|
1273
|
+
const head = col[0];
|
|
1274
|
+
if (head === void 0) break;
|
|
1275
|
+
const grouped = [head];
|
|
1215
1276
|
const toRm = [0];
|
|
1216
1277
|
col.slice(1).map((jobName, j) => {
|
|
1217
|
-
if (visibleJobs[
|
|
1218
|
-
const depsA = depended_on[
|
|
1278
|
+
if (visibleJobs[head]?._matrixGroup || visibleJobs[jobName]?._matrixGroup) return;
|
|
1279
|
+
const depsA = depended_on[head];
|
|
1219
1280
|
const depsB = depended_on[jobName];
|
|
1220
|
-
const depsA2 = filteredDeps[
|
|
1281
|
+
const depsA2 = filteredDeps[head];
|
|
1221
1282
|
const depsB2 = filteredDeps[jobName];
|
|
1222
1283
|
if (!depsA && !depsB || depsA && depsB && depsA.length === depsB.length) {
|
|
1223
1284
|
if (!depsA2 && !depsB2 || depsA2 && depsB2 && depsA2.length === depsB2.length) {
|
|
1224
|
-
if ((!depsA || depsA.every((dep, i) => dep === depsB[i])) && (!depsA2 || depsA2.every((dep, i) => dep === depsB2[i]))) {
|
|
1285
|
+
if ((!depsA || depsA.every((dep, i) => dep === depsB?.[i])) && (!depsA2 || depsA2.every((dep, i) => dep === depsB2?.[i]))) {
|
|
1225
1286
|
grouped.push(jobName);
|
|
1226
1287
|
toRm.push(j + 1);
|
|
1227
1288
|
}
|
|
@@ -1233,9 +1294,15 @@ function computeGraphLayout(jobs, matrixGroups) {
|
|
|
1233
1294
|
}
|
|
1234
1295
|
finalDeps.push(toAppend);
|
|
1235
1296
|
});
|
|
1236
|
-
while (finalDeps.length > 0
|
|
1237
|
-
|
|
1238
|
-
|
|
1297
|
+
while (finalDeps.length > 0) {
|
|
1298
|
+
const first = finalDeps[0];
|
|
1299
|
+
if (!first) break;
|
|
1300
|
+
if (first.length === 0) {
|
|
1301
|
+
finalDeps.splice(0, 1);
|
|
1302
|
+
continue;
|
|
1303
|
+
}
|
|
1304
|
+
if (first[0]?.length !== 0) break;
|
|
1305
|
+
while (first.length > 0 && first[0]?.length === 0) first.splice(0, 1);
|
|
1239
1306
|
}
|
|
1240
1307
|
const ancestorDists = {};
|
|
1241
1308
|
const descendantDists = {};
|
|
@@ -1388,21 +1455,21 @@ function Subgraph({ jobs, pathPrefix, depth, preview, animT, expandedSubworkflow
|
|
|
1388
1455
|
const onStepClick = (j, s) => {
|
|
1389
1456
|
const stepStatus = jobs[j]?.steps?.[+s]?.status;
|
|
1390
1457
|
if (stepStatus === "skipped" || stepStatus === "skipped-failed") return;
|
|
1391
|
-
if (jobs[j]
|
|
1458
|
+
if (jobs[j]?.steps[+s]?.subworkflow) expandInline(j, +s);
|
|
1392
1459
|
else setSublogOpen(buildSubworkflowLogPath(pathPrefix, j, s));
|
|
1393
1460
|
};
|
|
1394
1461
|
const onStepLogClick = (j, s) => setSublogOpen(buildSubworkflowLogPath(pathPrefix, j, s));
|
|
1395
1462
|
const onSubworkflowIcon = (j, s) => openNew(j, s);
|
|
1396
1463
|
const isSubworkflowExpanded = (j, s) => expandedSubworkflows.has(`${pathPrefix}${j}:${s}`);
|
|
1397
1464
|
const renderSubworkflow = (j, s) => {
|
|
1398
|
-
const
|
|
1399
|
-
if (!
|
|
1465
|
+
const subJobs = jobs[j]?.steps?.[s]?.subworkflow?.jobs;
|
|
1466
|
+
if (!subJobs) return null;
|
|
1400
1467
|
return /* @__PURE__ */ jsx(SubworkflowWell, {
|
|
1401
1468
|
expanded: isSubworkflowExpanded(j, s),
|
|
1402
1469
|
onSettled: requestFit,
|
|
1403
1470
|
className: "my-2 rounded-lg border-4 border-(--theme-border)",
|
|
1404
1471
|
children: /* @__PURE__ */ jsx(Subgraph, {
|
|
1405
|
-
jobs:
|
|
1472
|
+
jobs: subJobs,
|
|
1406
1473
|
pathPrefix: `${pathPrefix}subworkflows/${j}/step_${s}/`,
|
|
1407
1474
|
depth: depth + 1,
|
|
1408
1475
|
preview,
|
|
@@ -1449,10 +1516,13 @@ function Subgraph({ jobs, pathPrefix, depth, preview, animT, expandedSubworkflow
|
|
|
1449
1516
|
}, "node_" + jobNames[0]);
|
|
1450
1517
|
return /* @__PURE__ */ jsxs("div", {
|
|
1451
1518
|
id: "node_" + pathPrefix + jobNames[0],
|
|
1519
|
+
role: "none",
|
|
1452
1520
|
className: "relative m-24",
|
|
1453
1521
|
style: { zIndex: (activeDists?.has(jobNames[0]) ? 25 : 1) + zBase },
|
|
1454
1522
|
onMouseEnter: () => setHoveredJob(jobNames[0]),
|
|
1455
1523
|
onMouseLeave: () => setHoveredJob(null),
|
|
1524
|
+
onFocus: () => setHoveredJob(jobNames[0]),
|
|
1525
|
+
onBlur: () => setHoveredJob(null),
|
|
1456
1526
|
children: [/* @__PURE__ */ jsx("div", { className: "absolute inset-0 rounded-2xl bg-(--theme-panel-bg)" }), /* @__PURE__ */ jsx("div", {
|
|
1457
1527
|
className: "relative border-solid shadow py-4 px-8 rounded-xl border-4 whitespace-nowrap bg-(--theme-panel-bg) text-2xl",
|
|
1458
1528
|
style: {
|
|
@@ -1474,7 +1544,7 @@ function Subgraph({ jobs, pathPrefix, depth, preview, animT, expandedSubworkflow
|
|
|
1474
1544
|
})
|
|
1475
1545
|
})]
|
|
1476
1546
|
}, "node_" + jobNames[0]);
|
|
1477
|
-
}) }, col[0][0]);
|
|
1547
|
+
}) }, col[0]?.[0]);
|
|
1478
1548
|
})
|
|
1479
1549
|
});
|
|
1480
1550
|
}, [
|
|
@@ -1512,8 +1582,8 @@ function Subgraph({ jobs, pathPrefix, depth, preview, animT, expandedSubworkflow
|
|
|
1512
1582
|
const nodeConnectorY = (el) => offsetWithin(el, wrapper).y + 37;
|
|
1513
1583
|
let colGap = 32;
|
|
1514
1584
|
if (dependencyCols.length >= 2) {
|
|
1515
|
-
const col0 = gid(dependencyCols[0][0][0]);
|
|
1516
|
-
const col1 = gid(dependencyCols[1][0][0]);
|
|
1585
|
+
const col0 = gid(dependencyCols[0]?.[0]?.[0] ?? "");
|
|
1586
|
+
const col1 = gid(dependencyCols[1]?.[0]?.[0] ?? "");
|
|
1517
1587
|
if (col0 && col1) colGap = ox(col1) - (ox(col0) + col0.offsetWidth);
|
|
1518
1588
|
}
|
|
1519
1589
|
let minAdy = Number.POSITIVE_INFINITY;
|
|
@@ -1581,6 +1651,7 @@ function Subgraph({ jobs, pathPrefix, depth, preview, animT, expandedSubworkflow
|
|
|
1581
1651
|
}
|
|
1582
1652
|
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
1583
1653
|
/* @__PURE__ */ jsxs("svg", {
|
|
1654
|
+
"aria-hidden": "true",
|
|
1584
1655
|
overflow: "visible",
|
|
1585
1656
|
className: "absolute pointer-events-none",
|
|
1586
1657
|
style: { zIndex: (isHighlighted || activeDists?.has(dep) && activeDists?.has(jobNames[0]) ? 30 : 10) + zBase },
|
|
@@ -1622,6 +1693,7 @@ function Subgraph({ jobs, pathPrefix, depth, preview, animT, expandedSubworkflow
|
|
|
1622
1693
|
]
|
|
1623
1694
|
}),
|
|
1624
1695
|
/* @__PURE__ */ jsxs("svg", {
|
|
1696
|
+
"aria-hidden": "true",
|
|
1625
1697
|
overflow: "visible",
|
|
1626
1698
|
className: "absolute pointer-events-none",
|
|
1627
1699
|
style: { zIndex: (isHighlighted ? 20 : -1) + zBase },
|
|
@@ -1642,6 +1714,7 @@ function Subgraph({ jobs, pathPrefix, depth, preview, animT, expandedSubworkflow
|
|
|
1642
1714
|
})]
|
|
1643
1715
|
}),
|
|
1644
1716
|
/* @__PURE__ */ jsxs("svg", {
|
|
1717
|
+
"aria-hidden": "true",
|
|
1645
1718
|
overflow: "visible",
|
|
1646
1719
|
className: "absolute pointer-events-none",
|
|
1647
1720
|
style: { zIndex: 20 + zBase },
|
|
@@ -1677,7 +1750,7 @@ function Subgraph({ jobs, pathPrefix, depth, preview, animT, expandedSubworkflow
|
|
|
1677
1750
|
})()]
|
|
1678
1751
|
})
|
|
1679
1752
|
] }, dep);
|
|
1680
|
-
}) }, jobNames[0])) }, col[0][0]));
|
|
1753
|
+
}) }, jobNames[0])) }, col[0]?.[0]));
|
|
1681
1754
|
})(), hasLiveNestedGraph ? buildBoxLayer() : memoizedBoxLayer]
|
|
1682
1755
|
});
|
|
1683
1756
|
}
|
|
@@ -1702,21 +1775,21 @@ function SidebarJobs({ jobs, pathPrefix, preview, stepsOpen, toggleSteps, expand
|
|
|
1702
1775
|
const onStepClick = (j, s) => {
|
|
1703
1776
|
const stepStatus = jobs[j]?.steps?.[+s]?.status;
|
|
1704
1777
|
if (stepStatus === "skipped" || stepStatus === "skipped-failed") return;
|
|
1705
|
-
if (jobs[j]
|
|
1778
|
+
if (jobs[j]?.steps[+s]?.subworkflow) expandInline(j, +s);
|
|
1706
1779
|
else setSublogOpen(buildSubworkflowLogPath(pathPrefix, j, s));
|
|
1707
1780
|
};
|
|
1708
1781
|
const onStepLogClick = (j, s) => setSublogOpen(buildSubworkflowLogPath(pathPrefix, j, s));
|
|
1709
1782
|
const onSubworkflowIcon = (j, s) => openNew(j, s);
|
|
1710
1783
|
const isSubworkflowExpanded = (j, s) => expandedSubworkflows.has(`${pathPrefix}${j}:${s}`);
|
|
1711
1784
|
const renderSubworkflow = (j, s) => {
|
|
1712
|
-
const
|
|
1713
|
-
if (!
|
|
1785
|
+
const subJobs = jobs[j]?.steps?.[s]?.subworkflow?.jobs;
|
|
1786
|
+
if (!subJobs) return null;
|
|
1714
1787
|
return /* @__PURE__ */ jsx(SidebarWell, {
|
|
1715
1788
|
expanded: isSubworkflowExpanded(j, s),
|
|
1716
1789
|
children: /* @__PURE__ */ jsx("div", {
|
|
1717
1790
|
className: "ml-6 mt-0.5 border-l border-(--theme-border) pl-4",
|
|
1718
1791
|
children: /* @__PURE__ */ jsx(SidebarJobs, {
|
|
1719
|
-
jobs:
|
|
1792
|
+
jobs: subJobs,
|
|
1720
1793
|
pathPrefix: `${pathPrefix}subworkflows/${j}/step_${s}/`,
|
|
1721
1794
|
preview,
|
|
1722
1795
|
stepsOpen,
|
|
@@ -1742,7 +1815,7 @@ function SidebarJobs({ jobs, pathPrefix, preview, stepsOpen, toggleSteps, expand
|
|
|
1742
1815
|
const mg = displayJobs[jobName]?._matrixGroup;
|
|
1743
1816
|
if (mg) return /* @__PURE__ */ jsx(MatrixGroupSummaryItem, {
|
|
1744
1817
|
matrixGroup: mg,
|
|
1745
|
-
status: displayJobs[jobName]?.status,
|
|
1818
|
+
status: displayJobs[jobName]?.status ?? "",
|
|
1746
1819
|
isExpanded: matrixOpen.has(pathPrefix + mg.originaljob),
|
|
1747
1820
|
onToggle: () => toggleMatrix(pathPrefix + mg.originaljob),
|
|
1748
1821
|
jobs,
|
|
@@ -1769,14 +1842,39 @@ function SidebarJobs({ jobs, pathPrefix, preview, stepsOpen, toggleSteps, expand
|
|
|
1769
1842
|
}, "job-" + pathPrefix + jobName);
|
|
1770
1843
|
}) });
|
|
1771
1844
|
}
|
|
1845
|
+
var RUN_STATUSES = [
|
|
1846
|
+
"started",
|
|
1847
|
+
"running",
|
|
1848
|
+
"completed",
|
|
1849
|
+
"error",
|
|
1850
|
+
"failed",
|
|
1851
|
+
"canceled",
|
|
1852
|
+
"skipped",
|
|
1853
|
+
"faulted",
|
|
1854
|
+
"canceling",
|
|
1855
|
+
"skipped-failed",
|
|
1856
|
+
""
|
|
1857
|
+
];
|
|
1858
|
+
function toStatus(value) {
|
|
1859
|
+
return RUN_STATUSES.find((status) => status === value) ?? "";
|
|
1860
|
+
}
|
|
1861
|
+
function walkJobPath(root, path) {
|
|
1862
|
+
let cursor = root;
|
|
1863
|
+
for (const key of path) {
|
|
1864
|
+
if (typeof cursor !== "object" || cursor === null) return {};
|
|
1865
|
+
cursor = Object.getOwnPropertyDescriptor(cursor, String(key))?.value;
|
|
1866
|
+
}
|
|
1867
|
+
return isJobRecord(cursor) ? cursor : {};
|
|
1868
|
+
}
|
|
1772
1869
|
function DependencyGraph({ run, preview = false, initialScale = 1, removeBorder, viewMode = "dag", setViewMode }) {
|
|
1773
1870
|
const animT = .125;
|
|
1774
1871
|
const minScale = .2;
|
|
1775
1872
|
const maxScale = .6;
|
|
1776
|
-
|
|
1777
|
-
const runNumber = run.number;
|
|
1778
|
-
const runSlug = run.slug;
|
|
1779
|
-
const workflowName = run.workflowName;
|
|
1873
|
+
const rootJobs = isJobRecord(run.executedJobs) ? run.executedJobs : {};
|
|
1874
|
+
const runNumber = run.number ?? 0;
|
|
1875
|
+
const runSlug = run.slug ?? "";
|
|
1876
|
+
const workflowName = run.workflowName ?? "";
|
|
1877
|
+
const runStatus = toStatus(run.status);
|
|
1780
1878
|
const [sublogOpen, setSublogOpen] = useState("");
|
|
1781
1879
|
const [stepsOpen, setStepsOpen] = useState(/* @__PURE__ */ new Set());
|
|
1782
1880
|
const [expandedSubworkflows, setExpandedSubworkflows] = useState(/* @__PURE__ */ new Set());
|
|
@@ -1834,9 +1932,7 @@ function DependencyGraph({ run, preview = false, initialScale = 1, removeBorder,
|
|
|
1834
1932
|
const timer = setInterval(() => setNow(DateTime.now()), 1e3);
|
|
1835
1933
|
return () => clearInterval(timer);
|
|
1836
1934
|
}, [isRunFinished]);
|
|
1837
|
-
|
|
1838
|
-
jobs = jobs[prop];
|
|
1839
|
-
});
|
|
1935
|
+
const jobs = walkJobPath(rootJobs, executedJobsPath[executedJobsPathIdx] ?? []);
|
|
1840
1936
|
const resetGraph = useCallback(() => {
|
|
1841
1937
|
setSublogOpen("");
|
|
1842
1938
|
setStepsOpen(/* @__PURE__ */ new Set());
|
|
@@ -1891,10 +1987,10 @@ function DependencyGraph({ run, preview = false, initialScale = 1, removeBorder,
|
|
|
1891
1987
|
sublogsLoading
|
|
1892
1988
|
]);
|
|
1893
1989
|
const jobAndStep = sublogOpen.split("/").slice(-3, -1);
|
|
1894
|
-
if (jobAndStep.length > 1) jobAndStep[1] = jobAndStep[1].split("_")[1];
|
|
1895
|
-
const
|
|
1896
|
-
const
|
|
1897
|
-
const
|
|
1990
|
+
if (jobAndStep.length > 1) jobAndStep[1] = jobAndStep[1].split("_")[1] ?? "";
|
|
1991
|
+
const sublogIsStep = jobAndStep.length > 1;
|
|
1992
|
+
const logName = jobAndStep.length > 1 ? "Job: " + (jobAndStep[0][0].toUpperCase() + jobAndStep[0].slice(1)).replace(/_/g, " ") + " \nStep: " + (jobs[jobAndStep[0]]?.steps[Number(jobAndStep[1])]?.name || "Step " + jobAndStep[1]) : "";
|
|
1993
|
+
const sublogIsSubworkflow = jobAndStep.length > 1 && jobs[jobAndStep[0]]?.steps[Number(jobAndStep[1])]?.subworkflow;
|
|
1898
1994
|
const matrixGroups = useMemo(() => detectMatrixGroups(jobs), [jobs]);
|
|
1899
1995
|
const { dependencyCols } = useMemo(() => computeGraphLayout(jobs, matrixGroups), [jobs, matrixGroups]);
|
|
1900
1996
|
const fitGraph = useCallback((animationMs = 0) => {
|
|
@@ -1950,18 +2046,20 @@ function DependencyGraph({ run, preview = false, initialScale = 1, removeBorder,
|
|
|
1950
2046
|
windowSize,
|
|
1951
2047
|
executedJobsPathIdx
|
|
1952
2048
|
]);
|
|
1953
|
-
const currentPath = executedJobsPath[executedJobsPathIdx];
|
|
2049
|
+
const currentPath = executedJobsPath[executedJobsPathIdx] ?? [];
|
|
1954
2050
|
const nestingDepth = currentPath.length / 5;
|
|
1955
2051
|
let pathAppend = "";
|
|
1956
|
-
for (let i = 0; i < nestingDepth; i++) pathAppend += `subworkflows/${currentPath[5 * i]}/step_${currentPath[5 * i + 2]
|
|
2052
|
+
for (let i = 0; i < nestingDepth; i++) pathAppend += `subworkflows/${currentPath[5 * i]}/step_${currentPath[5 * i + 2]?.toString()}/`;
|
|
1957
2053
|
let generalLogPath = "logs.out";
|
|
1958
2054
|
if (nestingDepth > 0) {
|
|
1959
2055
|
let parentPrefix = "";
|
|
1960
|
-
for (let i = 0; i < nestingDepth - 1; i++) parentPrefix += `subworkflows/${currentPath[5 * i]}/step_${currentPath[5 * i + 2]
|
|
1961
|
-
const lastJob = currentPath[5 * (nestingDepth - 1)];
|
|
1962
|
-
const lastStep = currentPath[5 * (nestingDepth - 1) + 2];
|
|
2056
|
+
for (let i = 0; i < nestingDepth - 1; i++) parentPrefix += `subworkflows/${currentPath[5 * i]}/step_${currentPath[5 * i + 2]?.toString()}/`;
|
|
2057
|
+
const lastJob = String(currentPath[5 * (nestingDepth - 1)] ?? "");
|
|
2058
|
+
const lastStep = currentPath[5 * (nestingDepth - 1) + 2] ?? "";
|
|
1963
2059
|
generalLogPath = buildSubworkflowLogPath(parentPrefix, lastJob, lastStep);
|
|
1964
2060
|
}
|
|
2061
|
+
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;
|
|
2062
|
+
const currentSublog = sublogOpen === "" ? "" : preview ? dumpYaml(jobs[jobAndStep[0]]?.steps[Number(jobAndStep[1])]) : sublogsError || !sublogs ? missingLogText : sublogs;
|
|
1965
2063
|
const expansionKeys = useMemo(() => collectExpansionKeys(jobs, pathAppend), [jobs, pathAppend]);
|
|
1966
2064
|
const hasExpandable = expansionKeys.subworkflowKeys.length > 0 || expansionKeys.matrixKeys.length > 0;
|
|
1967
2065
|
const allExpanded = hasExpandable && expansionKeys.subworkflowKeys.every((k) => expandedSubworkflows.has(k)) && expansionKeys.matrixKeys.every((k) => matrixOpen.has(k));
|
|
@@ -1982,20 +2080,20 @@ function DependencyGraph({ run, preview = false, initialScale = 1, removeBorder,
|
|
|
1982
2080
|
};
|
|
1983
2081
|
const nextStep = useCallback((backward) => {
|
|
1984
2082
|
const sublogSplit = sublogOpen.split("/");
|
|
1985
|
-
let job = sublogSplit[sublogSplit.length - 3];
|
|
2083
|
+
let job = sublogSplit[sublogSplit.length - 3] ?? "";
|
|
1986
2084
|
let step = parseInt(sublogSplit[sublogSplit.length - 2].slice(5), 10);
|
|
1987
2085
|
const jobArr = Object.keys(jobs);
|
|
1988
2086
|
let idx = jobArr.indexOf(job);
|
|
1989
2087
|
if (backward) if (0 < step) step -= 1;
|
|
1990
2088
|
else {
|
|
1991
2089
|
if (idx === 0) idx = jobArr.length;
|
|
1992
|
-
job = jobArr[idx - 1];
|
|
1993
|
-
step = jobs[job]
|
|
2090
|
+
job = jobArr[idx - 1] ?? "";
|
|
2091
|
+
step = (jobs[job]?.steps.length ?? 0) - 1;
|
|
1994
2092
|
}
|
|
1995
|
-
else if (jobs[job]
|
|
2093
|
+
else if ((jobs[job]?.steps.length ?? 0) - 1 > step) step += 1;
|
|
1996
2094
|
else {
|
|
1997
2095
|
if (idx === jobArr.length - 1) idx = -1;
|
|
1998
|
-
job = jobArr[idx + 1];
|
|
2096
|
+
job = jobArr[idx + 1] ?? "";
|
|
1999
2097
|
step = 0;
|
|
2000
2098
|
}
|
|
2001
2099
|
setSublogOpen(sublogSplit.slice(0, -3).join("/") + `/${job}/step_${step}/` + sublogSplit.slice(-1)[0]);
|
|
@@ -2005,14 +2103,10 @@ function DependencyGraph({ run, preview = false, initialScale = 1, removeBorder,
|
|
|
2005
2103
|
else if (e.key === "ArrowLeft") nextStep(true);
|
|
2006
2104
|
}, [nextStep]);
|
|
2007
2105
|
useEffect(() => {
|
|
2008
|
-
if (
|
|
2106
|
+
if (!sublogIsStep) return;
|
|
2009
2107
|
window.addEventListener("keydown", handleKeyDown);
|
|
2010
2108
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
2011
|
-
}, [
|
|
2012
|
-
handleKeyDown,
|
|
2013
|
-
sublogOpen,
|
|
2014
|
-
pathAppend
|
|
2015
|
-
]);
|
|
2109
|
+
}, [handleKeyDown, sublogIsStep]);
|
|
2016
2110
|
const summarySidebar = useMemo(() => /* @__PURE__ */ jsx(SidebarJobs, {
|
|
2017
2111
|
jobs,
|
|
2018
2112
|
pathPrefix: pathAppend,
|
|
@@ -2040,8 +2134,7 @@ function DependencyGraph({ run, preview = false, initialScale = 1, removeBorder,
|
|
|
2040
2134
|
if (!Array.isArray(dependencyCols) || dependencyCols.length === 0 || !Array.isArray(dependencyCols[0]) || dependencyCols[0].length === 0 || !Array.isArray(dependencyCols[0][0]) || dependencyCols[0][0].length === 0) return;
|
|
2041
2135
|
const startDt = run.createdAt ? DateTime.fromISO(run.createdAt) : now;
|
|
2042
2136
|
const runtime = toAbsHumanDuration(startDt, run.completedAt ? DateTime.fromISO(run.completedAt) : now);
|
|
2043
|
-
const
|
|
2044
|
-
const additionalBottomLeftBarComponents = notGeneralLogs ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2137
|
+
const additionalBottomLeftBarComponents = sublogIsStep ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2045
2138
|
/* @__PURE__ */ jsxs("button", {
|
|
2046
2139
|
type: "button",
|
|
2047
2140
|
className: "btn btn-neutral",
|
|
@@ -2059,7 +2152,7 @@ function DependencyGraph({ run, preview = false, initialScale = 1, removeBorder,
|
|
|
2059
2152
|
children: logName
|
|
2060
2153
|
})
|
|
2061
2154
|
] }) : void 0;
|
|
2062
|
-
const additionalBottomRightBarComponents = (!preview || sublogIsSubworkflow) && sublogOpen &&
|
|
2155
|
+
const additionalBottomRightBarComponents = (!preview || sublogIsSubworkflow) && sublogOpen && sublogIsStep ? /* @__PURE__ */ jsx("button", {
|
|
2063
2156
|
type: "button",
|
|
2064
2157
|
className: "btn btn-neutral",
|
|
2065
2158
|
onClick: () => {
|
|
@@ -2079,8 +2172,8 @@ function DependencyGraph({ run, preview = false, initialScale = 1, removeBorder,
|
|
|
2079
2172
|
slots.runSessions && /* @__PURE__ */ jsx("div", {
|
|
2080
2173
|
className: "mb-4 overflow-y-auto",
|
|
2081
2174
|
children: slots.runSessions({
|
|
2082
|
-
runId: run.id,
|
|
2083
|
-
runNumber
|
|
2175
|
+
runId: run.id ?? "",
|
|
2176
|
+
runNumber,
|
|
2084
2177
|
runActive: isRunActive(run.status)
|
|
2085
2178
|
})
|
|
2086
2179
|
}),
|
|
@@ -2136,7 +2229,7 @@ function DependencyGraph({ run, preview = false, initialScale = 1, removeBorder,
|
|
|
2136
2229
|
children: /* @__PURE__ */ jsxs(TooltipInfo, {
|
|
2137
2230
|
className: "flex items-center gap-x-1",
|
|
2138
2231
|
text: dagStrings.statusReason(run.statusReason) ?? "",
|
|
2139
|
-
children: [/* @__PURE__ */ jsx(Indicator, { status:
|
|
2232
|
+
children: [/* @__PURE__ */ jsx(Indicator, { status: runStatus }), dagStrings.statusLabel(runStatus)]
|
|
2140
2233
|
})
|
|
2141
2234
|
})]
|
|
2142
2235
|
}),
|
|
@@ -2173,7 +2266,7 @@ function DependencyGraph({ run, preview = false, initialScale = 1, removeBorder,
|
|
|
2173
2266
|
})
|
|
2174
2267
|
]
|
|
2175
2268
|
}),
|
|
2176
|
-
!preview && /* @__PURE__ */ jsx(AnnotationBanner, { executedJobs:
|
|
2269
|
+
!preview && /* @__PURE__ */ jsx(AnnotationBanner, { executedJobs: jobs }),
|
|
2177
2270
|
viewMode === "tree" && !preview ? /* @__PURE__ */ jsx("div", {
|
|
2178
2271
|
className: "panel w-full border",
|
|
2179
2272
|
children: /* @__PURE__ */ jsx(TreeView, {
|
|
@@ -2216,10 +2309,11 @@ function DependencyGraph({ run, preview = false, initialScale = 1, removeBorder,
|
|
|
2216
2309
|
children: allExpanded ? dagStrings.collapseAll : dagStrings.expandAll
|
|
2217
2310
|
}),
|
|
2218
2311
|
/* @__PURE__ */ jsx("button", {
|
|
2312
|
+
type: "button",
|
|
2219
2313
|
className: "btn btn-info w-21 cursor-pointer h-6",
|
|
2220
2314
|
"aria-label": "Reset view",
|
|
2221
2315
|
onClick: () => {
|
|
2222
|
-
if (executedJobsPath[executedJobsPathIdx]
|
|
2316
|
+
if ((executedJobsPath[executedJobsPathIdx]?.length ?? 0) > 0) {
|
|
2223
2317
|
resetGraph();
|
|
2224
2318
|
setExecutedJobsPath([[], ...executedJobsPath.slice(executedJobsPathIdx, 10)]);
|
|
2225
2319
|
setExecutedJobsPathIdx(0);
|
|
@@ -2230,6 +2324,7 @@ function DependencyGraph({ run, preview = false, initialScale = 1, removeBorder,
|
|
|
2230
2324
|
executedJobsPath.length > 1 && /* @__PURE__ */ jsxs("div", {
|
|
2231
2325
|
className: "flex",
|
|
2232
2326
|
children: [/* @__PURE__ */ jsx("button", {
|
|
2327
|
+
type: "button",
|
|
2233
2328
|
onClick: () => {
|
|
2234
2329
|
if (executedJobsPath.length > executedJobsPathIdx + 1) {
|
|
2235
2330
|
resetGraph();
|
|
@@ -2239,6 +2334,7 @@ function DependencyGraph({ run, preview = false, initialScale = 1, removeBorder,
|
|
|
2239
2334
|
className: "btn btn-info mr-1 cursor-pointer w-10 h-6",
|
|
2240
2335
|
children: "<"
|
|
2241
2336
|
}), /* @__PURE__ */ jsx("button", {
|
|
2337
|
+
type: "button",
|
|
2242
2338
|
onClick: () => {
|
|
2243
2339
|
if (executedJobsPathIdx - 1 >= 0) {
|
|
2244
2340
|
resetGraph();
|
|
@@ -2285,7 +2381,7 @@ function DependencyGraph({ run, preview = false, initialScale = 1, removeBorder,
|
|
|
2285
2381
|
children: /* @__PURE__ */ jsx("div", {
|
|
2286
2382
|
className: "flex w-full",
|
|
2287
2383
|
children: sublogsLoading && (!sublogs || !runNumber) ? /* @__PURE__ */ jsx(Loader, {
|
|
2288
|
-
text:
|
|
2384
|
+
text: dagStrings.loadingLogs,
|
|
2289
2385
|
size: 70,
|
|
2290
2386
|
textSize: 18
|
|
2291
2387
|
}) : preview ? /* @__PURE__ */ jsxs("div", { children: [slots.yamlViewer?.({
|
|
@@ -2324,9 +2420,10 @@ function DependencyGraph({ run, preview = false, initialScale = 1, removeBorder,
|
|
|
2324
2420
|
});
|
|
2325
2421
|
}
|
|
2326
2422
|
function DependencyGraphPreview(inputs) {
|
|
2423
|
+
const ymlJobs = inputs.yml?.["jobs"];
|
|
2327
2424
|
return /* @__PURE__ */ jsx(DependencyGraph, {
|
|
2328
2425
|
run: {
|
|
2329
|
-
executedJobs: addCleanupSteps({ jobs:
|
|
2426
|
+
executedJobs: addCleanupSteps({ jobs: isJobRecord(ymlJobs) ? ymlJobs : {} }),
|
|
2330
2427
|
number: 0,
|
|
2331
2428
|
workflowName: ""
|
|
2332
2429
|
},
|