@burdenoff/microfe-cosmicintersection 2026.525.1 → 2026.704.2
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/cosmicintersection/CosmicIntersectionRoot.js +38 -113
- package/dist/cosmicintersection/CosmicIntersectionRoot.js.map +1 -1
- package/dist/cosmicintersection/CosmicIntersectionRoutes.js +110 -44
- package/dist/cosmicintersection/CosmicIntersectionRoutes.js.map +1 -1
- package/dist/cosmicintersection/api/cosmicApi.js +918 -0
- package/dist/cosmicintersection/api/cosmicApi.js.map +1 -0
- package/dist/cosmicintersection/components/ActionMenu.js +106 -0
- package/dist/cosmicintersection/components/ActionMenu.js.map +1 -0
- package/dist/cosmicintersection/components/ActivityFeedPanel.js +68 -0
- package/dist/cosmicintersection/components/ActivityFeedPanel.js.map +1 -0
- package/dist/cosmicintersection/components/DiscussionPanel.js +57 -0
- package/dist/cosmicintersection/components/DiscussionPanel.js.map +1 -0
- package/dist/cosmicintersection/components/EmptyState.js +35 -0
- package/dist/cosmicintersection/components/EmptyState.js.map +1 -0
- package/dist/cosmicintersection/components/EntityFormShell.js +57 -0
- package/dist/cosmicintersection/components/EntityFormShell.js.map +1 -0
- package/dist/cosmicintersection/components/EntityTagsField.js +77 -0
- package/dist/cosmicintersection/components/EntityTagsField.js.map +1 -0
- package/dist/cosmicintersection/components/ErrorState.js +40 -0
- package/dist/cosmicintersection/components/ErrorState.js.map +1 -0
- package/dist/cosmicintersection/components/FileUploadField.js +146 -0
- package/dist/cosmicintersection/components/FileUploadField.js.map +1 -0
- package/dist/cosmicintersection/components/LoadingState.js +23 -0
- package/dist/cosmicintersection/components/LoadingState.js.map +1 -0
- package/dist/cosmicintersection/components/PageLayout.js +46 -0
- package/dist/cosmicintersection/components/PageLayout.js.map +1 -0
- package/dist/cosmicintersection/components/Pagination.js +65 -0
- package/dist/cosmicintersection/components/Pagination.js.map +1 -0
- package/dist/cosmicintersection/components/SafeLink.js +35 -0
- package/dist/cosmicintersection/components/SafeLink.js.map +1 -0
- package/dist/cosmicintersection/components/StatusBadge.js +53 -0
- package/dist/cosmicintersection/components/StatusBadge.js.map +1 -0
- package/dist/cosmicintersection/components/index.js +13 -0
- package/dist/cosmicintersection/context/CosmicIntersectionContext.js +46 -0
- package/dist/cosmicintersection/context/CosmicIntersectionContext.js.map +1 -0
- package/dist/cosmicintersection/index.js +0 -2
- package/dist/cosmicintersection/lib/mutationResult.js +12 -0
- package/dist/cosmicintersection/lib/mutationResult.js.map +1 -0
- package/dist/cosmicintersection/lib/toast.js +36 -0
- package/dist/cosmicintersection/lib/toast.js.map +1 -0
- package/dist/cosmicintersection/pages/access/AccessPage.js +347 -0
- package/dist/cosmicintersection/pages/access/AccessPage.js.map +1 -0
- package/dist/cosmicintersection/pages/analyses/AnalysesPage.js +484 -0
- package/dist/cosmicintersection/pages/analyses/AnalysesPage.js.map +1 -0
- package/dist/cosmicintersection/pages/collections/CollectionDetailPage.js +177 -0
- package/dist/cosmicintersection/pages/collections/CollectionDetailPage.js.map +1 -0
- package/dist/cosmicintersection/pages/collections/CollectionFormPage.js +143 -0
- package/dist/cosmicintersection/pages/collections/CollectionFormPage.js.map +1 -0
- package/dist/cosmicintersection/pages/collections/CollectionsPage.js +112 -0
- package/dist/cosmicintersection/pages/collections/CollectionsPage.js.map +1 -0
- package/dist/cosmicintersection/pages/dashboard/DashboardPage.js +246 -0
- package/dist/cosmicintersection/pages/dashboard/DashboardPage.js.map +1 -0
- package/dist/cosmicintersection/pages/datasets/DatasetDetailPage.js +480 -0
- package/dist/cosmicintersection/pages/datasets/DatasetDetailPage.js.map +1 -0
- package/dist/cosmicintersection/pages/datasets/DatasetFormPage.js +218 -0
- package/dist/cosmicintersection/pages/datasets/DatasetFormPage.js.map +1 -0
- package/dist/cosmicintersection/pages/datasets/DatasetsPage.js +252 -0
- package/dist/cosmicintersection/pages/datasets/DatasetsPage.js.map +1 -0
- package/dist/cosmicintersection/pages/notebooks/NotebookDetailPage.js +402 -0
- package/dist/cosmicintersection/pages/notebooks/NotebookDetailPage.js.map +1 -0
- package/dist/cosmicintersection/pages/notebooks/NotebookFormPage.js +313 -0
- package/dist/cosmicintersection/pages/notebooks/NotebookFormPage.js.map +1 -0
- package/dist/cosmicintersection/pages/notebooks/NotebooksPage.js +203 -0
- package/dist/cosmicintersection/pages/notebooks/NotebooksPage.js.map +1 -0
- package/dist/cosmicintersection/pages/pipelines/PipelineDetailPage.js +244 -0
- package/dist/cosmicintersection/pages/pipelines/PipelineDetailPage.js.map +1 -0
- package/dist/cosmicintersection/pages/pipelines/PipelineFormPage.js +210 -0
- package/dist/cosmicintersection/pages/pipelines/PipelineFormPage.js.map +1 -0
- package/dist/cosmicintersection/pages/pipelines/PipelinesPage.js +193 -0
- package/dist/cosmicintersection/pages/pipelines/PipelinesPage.js.map +1 -0
- package/dist/cosmicintersection/pages/releases/ReleaseFormPage.js +184 -0
- package/dist/cosmicintersection/pages/releases/ReleaseFormPage.js.map +1 -0
- package/dist/cosmicintersection/pages/releases/ReleasesPage.js +418 -0
- package/dist/cosmicintersection/pages/releases/ReleasesPage.js.map +1 -0
- package/dist/cosmicintersection/pages/runs/RunDetailPage.js +380 -0
- package/dist/cosmicintersection/pages/runs/RunDetailPage.js.map +1 -0
- package/dist/cosmicintersection/pages/runs/RunsPage.js +165 -0
- package/dist/cosmicintersection/pages/runs/RunsPage.js.map +1 -0
- package/dist/cosmicintersection/pages/sources/SourceDetailPage.js +205 -0
- package/dist/cosmicintersection/pages/sources/SourceDetailPage.js.map +1 -0
- package/dist/cosmicintersection/pages/sources/SourceFormPage.js +229 -0
- package/dist/cosmicintersection/pages/sources/SourceFormPage.js.map +1 -0
- package/dist/cosmicintersection/pages/sources/SourcesPage.js +223 -0
- package/dist/cosmicintersection/pages/sources/SourcesPage.js.map +1 -0
- package/dist/cosmicintersection/utils/cn.js +10 -0
- package/dist/cosmicintersection/utils/cn.js.map +1 -0
- package/dist/index.js +2 -4
- package/dist/node_modules/clsx/dist/clsx.js +18 -0
- package/dist/node_modules/clsx/dist/clsx.js.map +1 -0
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +1716 -0
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
- package/package.json +2 -1
- package/dist/cosmicintersection/pages/AiDiscoveryPage.js +0 -363
- package/dist/cosmicintersection/pages/AiDiscoveryPage.js.map +0 -1
- package/dist/cosmicintersection/pages/DashboardPage.js +0 -306
- package/dist/cosmicintersection/pages/DashboardPage.js.map +0 -1
- package/dist/cosmicintersection/pages/SpaceScienceCitizenPage.js +0 -287
- package/dist/cosmicintersection/pages/SpaceScienceCitizenPage.js.map +0 -1
- package/dist/cosmicintersection/pages/SpaceScienceDataPage.js +0 -385
- package/dist/cosmicintersection/pages/SpaceScienceDataPage.js.map +0 -1
- package/dist/cosmicintersection/pages/SpaceScienceDataPage1.js +0 -420
- package/dist/cosmicintersection/pages/SpaceScienceDataPage1.js.map +0 -1
- package/dist/cosmicintersection/pages/SpaceScienceLearningPage.js +0 -309
- package/dist/cosmicintersection/pages/SpaceScienceLearningPage.js.map +0 -1
- package/dist/cosmicintersection/pages/SpaceScienceLearningPage1.js +0 -361
- package/dist/cosmicintersection/pages/SpaceScienceLearningPage1.js.map +0 -1
- package/dist/cosmicintersection/pages/SpaceSciencePage.js +0 -194
- package/dist/cosmicintersection/pages/SpaceSciencePage.js.map +0 -1
- package/dist/cosmicintersection/pages/SpaceScienceResearchPage.js +0 -290
- package/dist/cosmicintersection/pages/SpaceScienceResearchPage.js.map +0 -1
- package/dist/cosmicintersection/pages/SpaceScienceSimulationPage.js +0 -279
- package/dist/cosmicintersection/pages/SpaceScienceSimulationPage.js.map +0 -1
- package/dist/cosmicintersection/providers/CosmicIntersectionProvider.js +0 -27
- package/dist/cosmicintersection/providers/CosmicIntersectionProvider.js.map +0 -1
- package/dist/cosmicintersection/store/cosmicintersectionStore.js +0 -478
- package/dist/cosmicintersection/store/cosmicintersectionStore.js.map +0 -1
- package/dist/cosmicintersection/utils/i18n.js +0 -15
- package/dist/cosmicintersection/utils/i18n.js.map +0 -1
- package/dist/cosmicintersection/utils/navigation.js +0 -8
- package/dist/cosmicintersection/utils/navigation.js.map +0 -1
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
import { useCosmicIntersection as e } from "../../context/CosmicIntersectionContext.js";
|
|
2
|
+
import { notify as t } from "../../lib/toast.js";
|
|
3
|
+
import { useCosAddRunStepMutation as n, useCosRunQuery as r, useCosRunStepsQuery as ee, useCosTransitionRunMutation as i } from "../../api/cosmicApi.js";
|
|
4
|
+
import a from "../../components/EmptyState.js";
|
|
5
|
+
import o from "../../components/ErrorState.js";
|
|
6
|
+
import s from "../../components/LoadingState.js";
|
|
7
|
+
import c from "../../components/ActivityFeedPanel.js";
|
|
8
|
+
import l from "../../components/SafeLink.js";
|
|
9
|
+
import u from "../../components/PageLayout.js";
|
|
10
|
+
import d, { formatEnumLabel as f } from "../../components/StatusBadge.js";
|
|
11
|
+
import "../../components/index.js";
|
|
12
|
+
import { describeError as te, mutationSucceeded as p } from "../../lib/mutationResult.js";
|
|
13
|
+
import { useMemo as ne, useState as m } from "react";
|
|
14
|
+
import { jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
15
|
+
import { useParams as _ } from "react-router-dom";
|
|
16
|
+
import { ListTree as re, Plus as v } from "lucide-react";
|
|
17
|
+
import { Button as y, Card as b, CardContent as x, CardHeader as S, CardTitle as C, Dialog as ie, DialogContent as w, DialogDescription as ae, DialogFooter as oe, DialogHeader as T, DialogTitle as se, Input as E, Label as D, Select as ce, SelectContent as le, SelectItem as ue, SelectTrigger as de, SelectValue as fe, Textarea as pe } from "@burdenoff/fe-libs/ui";
|
|
18
|
+
//#region src/cosmicintersection/pages/runs/RunDetailPage.tsx
|
|
19
|
+
var me = [
|
|
20
|
+
"INGEST",
|
|
21
|
+
"CALIBRATE",
|
|
22
|
+
"TRANSFORM",
|
|
23
|
+
"ANALYZE",
|
|
24
|
+
"EXPORT",
|
|
25
|
+
"NOTIFY"
|
|
26
|
+
], he = {
|
|
27
|
+
QUEUED: ["RUNNING", "CANCELLED"],
|
|
28
|
+
RUNNING: [
|
|
29
|
+
"SUCCEEDED",
|
|
30
|
+
"FAILED",
|
|
31
|
+
"CANCELLED"
|
|
32
|
+
],
|
|
33
|
+
SUCCEEDED: [],
|
|
34
|
+
FAILED: [],
|
|
35
|
+
CANCELLED: []
|
|
36
|
+
};
|
|
37
|
+
function O(e) {
|
|
38
|
+
if (!e) return "—";
|
|
39
|
+
let t = new Date(e);
|
|
40
|
+
return Number.isNaN(t.getTime()) ? "—" : t.toLocaleString();
|
|
41
|
+
}
|
|
42
|
+
function k(e) {
|
|
43
|
+
if (e == null) return "—";
|
|
44
|
+
if (e < 1e3) return `${e} ms`;
|
|
45
|
+
let t = e / 1e3;
|
|
46
|
+
return t < 60 ? `${t.toFixed(1)} s` : `${Math.floor(t / 60)}m ${Math.round(t % 60)}s`;
|
|
47
|
+
}
|
|
48
|
+
function A({ label: e, children: t }) {
|
|
49
|
+
return /* @__PURE__ */ g("div", {
|
|
50
|
+
className: "flex flex-col gap-1 border-b border-border-seam py-3 last:border-0 sm:flex-row sm:items-start sm:gap-4",
|
|
51
|
+
children: [/* @__PURE__ */ h("span", {
|
|
52
|
+
className: "w-40 shrink-0 text-sm font-medium text-text-secondary",
|
|
53
|
+
children: e
|
|
54
|
+
}), /* @__PURE__ */ h("span", {
|
|
55
|
+
className: "min-w-0 text-sm text-text-primary",
|
|
56
|
+
children: t
|
|
57
|
+
})]
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
function j({ value: e }) {
|
|
61
|
+
return !e || Object.keys(e).length === 0 ? /* @__PURE__ */ h("span", {
|
|
62
|
+
className: "text-sm text-text-secondary",
|
|
63
|
+
children: "—"
|
|
64
|
+
}) : /* @__PURE__ */ h("pre", {
|
|
65
|
+
className: "overflow-x-auto rounded-card border border-border-default bg-bg-sunken p-3 font-mono text-xs text-text-primary",
|
|
66
|
+
children: JSON.stringify(e, null, 2)
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
function M() {
|
|
70
|
+
let { id: M = "" } = _(), { navigate: N } = e(), { data: P, loading: F, error: I, refetch: L } = r(M), { data: R, loading: ge, error: _e, refetch: z } = ee(M), [ve, { loading: ye }] = i(), [be, { loading: B }] = n(), [xe, V] = m(!1), [H, U] = m(""), [W, G] = m("INGEST"), [K, q] = m(""), [J, Y] = m(""), X = P?.cosRun, Z = ne(() => [...R?.cosListRunSteps ?? []].sort((e, t) => e.position - t.position), [R]), Se = async (e) => {
|
|
71
|
+
if (!X) return;
|
|
72
|
+
let n = await ve({ variables: {
|
|
73
|
+
id: X.id,
|
|
74
|
+
status: e
|
|
75
|
+
} });
|
|
76
|
+
p(n, n.data?.cosTransitionRun?.id, "Could not update the run") && (t.success("Run updated", `Run #${X.runNumber} moved to ${f(e)}.`), await Promise.all([L(), z()]));
|
|
77
|
+
}, Q = () => {
|
|
78
|
+
U(""), G("INGEST"), q(""), Y("");
|
|
79
|
+
}, Ce = async () => {
|
|
80
|
+
if (!X) return;
|
|
81
|
+
if (!H.trim()) {
|
|
82
|
+
t.error("Step name is required", "Give the step a name before adding it.");
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
let e;
|
|
86
|
+
if (J.trim()) try {
|
|
87
|
+
let t = JSON.parse(J.trim());
|
|
88
|
+
if (typeof t != "object" || !t || Array.isArray(t)) throw Error("Inputs must be a JSON object.");
|
|
89
|
+
e = t;
|
|
90
|
+
} catch (e) {
|
|
91
|
+
t.error("Invalid inputs JSON", te(e) ?? "Please provide valid JSON.");
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
let n = K.trim() ? Number(K.trim()) : void 0;
|
|
95
|
+
if (n !== void 0 && (Number.isNaN(n) || n < 0)) {
|
|
96
|
+
t.error("Invalid position", "Position must be a non-negative number.");
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
let r = await be({ variables: { input: {
|
|
100
|
+
runId: X.id,
|
|
101
|
+
name: H.trim(),
|
|
102
|
+
kind: W,
|
|
103
|
+
inputs: e,
|
|
104
|
+
position: n
|
|
105
|
+
} } });
|
|
106
|
+
p(r, r.data?.cosAddRunStep?.id, "Could not add the step") && (t.success("Step added", `“${H.trim()}” was added to the run.`), V(!1), Q(), await z());
|
|
107
|
+
};
|
|
108
|
+
if (F) return /* @__PURE__ */ h(u, {
|
|
109
|
+
title: "Run",
|
|
110
|
+
backPath: "runs",
|
|
111
|
+
children: /* @__PURE__ */ h(s, { label: "Loading run…" })
|
|
112
|
+
});
|
|
113
|
+
if (I) return /* @__PURE__ */ h(u, {
|
|
114
|
+
title: "Run",
|
|
115
|
+
backPath: "runs",
|
|
116
|
+
children: /* @__PURE__ */ h(o, { onRetry: () => void L() })
|
|
117
|
+
});
|
|
118
|
+
if (!X) return /* @__PURE__ */ h(u, {
|
|
119
|
+
title: "Run",
|
|
120
|
+
backPath: "runs",
|
|
121
|
+
children: /* @__PURE__ */ h(a, {
|
|
122
|
+
title: "Run not found",
|
|
123
|
+
description: "This run may have been removed or you may not have access to it.",
|
|
124
|
+
action: /* @__PURE__ */ h(y, {
|
|
125
|
+
type: "button",
|
|
126
|
+
variant: "outline",
|
|
127
|
+
onClick: () => N("runs"),
|
|
128
|
+
children: "Back to runs"
|
|
129
|
+
})
|
|
130
|
+
})
|
|
131
|
+
});
|
|
132
|
+
let $ = he[X.status] ?? [];
|
|
133
|
+
return /* @__PURE__ */ g(u, {
|
|
134
|
+
title: `Run #${X.runNumber}`,
|
|
135
|
+
description: X.pipeline ? `Pipeline: ${X.pipeline.name}` : void 0,
|
|
136
|
+
backPath: "runs",
|
|
137
|
+
actions: /* @__PURE__ */ g("div", {
|
|
138
|
+
className: "flex flex-wrap items-center gap-2",
|
|
139
|
+
children: [$.map((e) => /* @__PURE__ */ h(y, {
|
|
140
|
+
type: "button",
|
|
141
|
+
variant: e === "CANCELLED" || e === "FAILED" ? "outline" : "default",
|
|
142
|
+
onClick: () => void Se(e),
|
|
143
|
+
disabled: ye,
|
|
144
|
+
children: `Mark ${f(e)}`
|
|
145
|
+
}, e)), /* @__PURE__ */ g(y, {
|
|
146
|
+
type: "button",
|
|
147
|
+
variant: "outline",
|
|
148
|
+
onClick: () => V(!0),
|
|
149
|
+
children: [/* @__PURE__ */ h(v, { className: "size-4" }), "Add step"]
|
|
150
|
+
})]
|
|
151
|
+
}),
|
|
152
|
+
children: [/* @__PURE__ */ g("div", {
|
|
153
|
+
className: "space-y-6",
|
|
154
|
+
children: [
|
|
155
|
+
/* @__PURE__ */ g(b, { children: [/* @__PURE__ */ h(S, { children: /* @__PURE__ */ h(C, { children: "Overview" }) }), /* @__PURE__ */ g(x, { children: [
|
|
156
|
+
/* @__PURE__ */ h(A, {
|
|
157
|
+
label: "Status",
|
|
158
|
+
children: /* @__PURE__ */ h(d, { status: X.status })
|
|
159
|
+
}),
|
|
160
|
+
/* @__PURE__ */ h(A, {
|
|
161
|
+
label: "Pipeline",
|
|
162
|
+
children: X.pipeline ? /* @__PURE__ */ h("button", {
|
|
163
|
+
type: "button",
|
|
164
|
+
className: "text-text-primary underline-offset-2 hover:underline",
|
|
165
|
+
onClick: () => N(`pipelines/${X.pipelineId}`),
|
|
166
|
+
children: X.pipeline.name
|
|
167
|
+
}) : /* @__PURE__ */ h("span", {
|
|
168
|
+
className: "font-mono text-xs",
|
|
169
|
+
children: X.pipelineId
|
|
170
|
+
})
|
|
171
|
+
}),
|
|
172
|
+
/* @__PURE__ */ h(A, {
|
|
173
|
+
label: "Dataset",
|
|
174
|
+
children: X.datasetId ? /* @__PURE__ */ h("button", {
|
|
175
|
+
type: "button",
|
|
176
|
+
className: "text-text-primary underline-offset-2 hover:underline",
|
|
177
|
+
onClick: () => N(`datasets/${X.datasetId}`),
|
|
178
|
+
children: /* @__PURE__ */ h("span", {
|
|
179
|
+
className: "font-mono text-xs",
|
|
180
|
+
children: X.datasetId
|
|
181
|
+
})
|
|
182
|
+
}) : "—"
|
|
183
|
+
}),
|
|
184
|
+
/* @__PURE__ */ h(A, {
|
|
185
|
+
label: "Triggered by",
|
|
186
|
+
children: X.triggeredBy || "—"
|
|
187
|
+
}),
|
|
188
|
+
/* @__PURE__ */ h(A, {
|
|
189
|
+
label: "Started",
|
|
190
|
+
children: O(X.startedAt)
|
|
191
|
+
}),
|
|
192
|
+
/* @__PURE__ */ h(A, {
|
|
193
|
+
label: "Finished",
|
|
194
|
+
children: O(X.finishedAt)
|
|
195
|
+
}),
|
|
196
|
+
/* @__PURE__ */ h(A, {
|
|
197
|
+
label: "Duration",
|
|
198
|
+
children: k(X.durationMs)
|
|
199
|
+
}),
|
|
200
|
+
X.errorMessage ? /* @__PURE__ */ h(A, {
|
|
201
|
+
label: "Error",
|
|
202
|
+
children: /* @__PURE__ */ h("span", {
|
|
203
|
+
className: "text-status-error-text",
|
|
204
|
+
children: X.errorMessage
|
|
205
|
+
})
|
|
206
|
+
}) : null,
|
|
207
|
+
$.length === 0 ? /* @__PURE__ */ h(A, {
|
|
208
|
+
label: "Discuss",
|
|
209
|
+
children: /* @__PURE__ */ h(l, {
|
|
210
|
+
href: "/conversations",
|
|
211
|
+
className: "text-text-primary underline-offset-2 hover:underline",
|
|
212
|
+
children: "Open discussions"
|
|
213
|
+
})
|
|
214
|
+
}) : null
|
|
215
|
+
] })] }),
|
|
216
|
+
/* @__PURE__ */ g("div", {
|
|
217
|
+
className: "grid grid-cols-1 gap-6 lg:grid-cols-2",
|
|
218
|
+
children: [/* @__PURE__ */ g(b, { children: [/* @__PURE__ */ h(S, { children: /* @__PURE__ */ h(C, { children: "Parameters" }) }), /* @__PURE__ */ h(x, { children: /* @__PURE__ */ h(j, { value: X.params }) })] }), /* @__PURE__ */ g(b, { children: [/* @__PURE__ */ h(S, { children: /* @__PURE__ */ h(C, { children: "Metrics" }) }), /* @__PURE__ */ h(x, { children: /* @__PURE__ */ h(j, { value: X.metrics }) })] })]
|
|
219
|
+
}),
|
|
220
|
+
/* @__PURE__ */ g(b, { children: [/* @__PURE__ */ h(S, { children: /* @__PURE__ */ h(C, { children: "Steps" }) }), /* @__PURE__ */ h(x, { children: ge ? /* @__PURE__ */ h(s, {
|
|
221
|
+
variant: "rows",
|
|
222
|
+
rows: 4,
|
|
223
|
+
label: "Loading steps…"
|
|
224
|
+
}) : _e ? /* @__PURE__ */ h(o, {
|
|
225
|
+
message: "Could not load steps.",
|
|
226
|
+
onRetry: () => void z()
|
|
227
|
+
}) : Z.length === 0 ? /* @__PURE__ */ h(a, {
|
|
228
|
+
icon: re,
|
|
229
|
+
title: "No steps yet",
|
|
230
|
+
description: "Add steps to record the ingest, calibration, transform, analyze or export stages of this run.",
|
|
231
|
+
action: /* @__PURE__ */ g(y, {
|
|
232
|
+
type: "button",
|
|
233
|
+
onClick: () => V(!0),
|
|
234
|
+
children: [/* @__PURE__ */ h(v, { className: "size-4" }), "Add step"]
|
|
235
|
+
})
|
|
236
|
+
}) : /* @__PURE__ */ h("ol", {
|
|
237
|
+
className: "space-y-3",
|
|
238
|
+
children: Z.map((e) => /* @__PURE__ */ g("li", {
|
|
239
|
+
className: "flex flex-col gap-2 rounded-card border border-border-default bg-bg-elevated p-4 sm:flex-row sm:items-start sm:justify-between",
|
|
240
|
+
children: [/* @__PURE__ */ g("div", {
|
|
241
|
+
className: "flex min-w-0 items-start gap-3",
|
|
242
|
+
children: [/* @__PURE__ */ h("span", {
|
|
243
|
+
className: "mt-0.5 flex size-7 shrink-0 items-center justify-center rounded-full bg-bg-sunken text-xs font-semibold tabular-nums text-text-secondary",
|
|
244
|
+
children: e.position
|
|
245
|
+
}), /* @__PURE__ */ g("div", {
|
|
246
|
+
className: "min-w-0",
|
|
247
|
+
children: [
|
|
248
|
+
/* @__PURE__ */ g("div", {
|
|
249
|
+
className: "flex flex-wrap items-center gap-2",
|
|
250
|
+
children: [/* @__PURE__ */ h("span", {
|
|
251
|
+
className: "font-medium text-text-primary",
|
|
252
|
+
children: e.name
|
|
253
|
+
}), /* @__PURE__ */ h(d, {
|
|
254
|
+
status: e.kind,
|
|
255
|
+
tone: "neutral"
|
|
256
|
+
})]
|
|
257
|
+
}),
|
|
258
|
+
e.errorMessage ? /* @__PURE__ */ h("p", {
|
|
259
|
+
className: "mt-1 text-xs text-status-error-text",
|
|
260
|
+
children: e.errorMessage
|
|
261
|
+
}) : null,
|
|
262
|
+
/* @__PURE__ */ g("p", {
|
|
263
|
+
className: "mt-1 text-xs text-text-secondary",
|
|
264
|
+
children: ["Duration: ", k(e.durationMs)]
|
|
265
|
+
})
|
|
266
|
+
]
|
|
267
|
+
})]
|
|
268
|
+
}), /* @__PURE__ */ h("div", {
|
|
269
|
+
className: "shrink-0",
|
|
270
|
+
children: /* @__PURE__ */ h(d, { status: e.status })
|
|
271
|
+
})]
|
|
272
|
+
}, e.id))
|
|
273
|
+
}) })] }),
|
|
274
|
+
/* @__PURE__ */ g(b, { children: [/* @__PURE__ */ h(S, { children: /* @__PURE__ */ h(C, { children: "Activity" }) }), /* @__PURE__ */ h(x, { children: /* @__PURE__ */ h(c, {
|
|
275
|
+
resourceId: X.id,
|
|
276
|
+
resourceType: "cosmicintersection-run"
|
|
277
|
+
}) })] })
|
|
278
|
+
]
|
|
279
|
+
}), /* @__PURE__ */ h(ie, {
|
|
280
|
+
open: xe,
|
|
281
|
+
onOpenChange: (e) => {
|
|
282
|
+
B || (V(e), e || Q());
|
|
283
|
+
},
|
|
284
|
+
children: /* @__PURE__ */ g(w, { children: [
|
|
285
|
+
/* @__PURE__ */ g(T, { children: [/* @__PURE__ */ h(se, { children: "Add step" }), /* @__PURE__ */ h(ae, { children: "Record a stage of this run — its kind, order and optional inputs." })] }),
|
|
286
|
+
/* @__PURE__ */ g("div", {
|
|
287
|
+
className: "space-y-4",
|
|
288
|
+
children: [
|
|
289
|
+
/* @__PURE__ */ g("div", {
|
|
290
|
+
className: "space-y-1",
|
|
291
|
+
children: [/* @__PURE__ */ h(D, {
|
|
292
|
+
htmlFor: "step-name",
|
|
293
|
+
children: "Name"
|
|
294
|
+
}), /* @__PURE__ */ h(E, {
|
|
295
|
+
id: "step-name",
|
|
296
|
+
value: H,
|
|
297
|
+
onChange: (e) => U(e.target.value),
|
|
298
|
+
placeholder: "e.g. Calibrate flat fields"
|
|
299
|
+
})]
|
|
300
|
+
}),
|
|
301
|
+
/* @__PURE__ */ g("div", {
|
|
302
|
+
className: "grid grid-cols-1 gap-4 sm:grid-cols-2",
|
|
303
|
+
children: [/* @__PURE__ */ g("div", {
|
|
304
|
+
className: "space-y-1",
|
|
305
|
+
children: [/* @__PURE__ */ h(D, {
|
|
306
|
+
htmlFor: "step-kind",
|
|
307
|
+
children: "Kind"
|
|
308
|
+
}), /* @__PURE__ */ g(ce, {
|
|
309
|
+
value: W,
|
|
310
|
+
onValueChange: (e) => G(e),
|
|
311
|
+
children: [/* @__PURE__ */ h(de, {
|
|
312
|
+
id: "step-kind",
|
|
313
|
+
"aria-label": "Step kind",
|
|
314
|
+
children: /* @__PURE__ */ h(fe, {})
|
|
315
|
+
}), /* @__PURE__ */ h(le, { children: me.map((e) => /* @__PURE__ */ h(ue, {
|
|
316
|
+
value: e,
|
|
317
|
+
children: f(e)
|
|
318
|
+
}, e)) })]
|
|
319
|
+
})]
|
|
320
|
+
}), /* @__PURE__ */ g("div", {
|
|
321
|
+
className: "space-y-1",
|
|
322
|
+
children: [/* @__PURE__ */ h(D, {
|
|
323
|
+
htmlFor: "step-position",
|
|
324
|
+
children: "Position"
|
|
325
|
+
}), /* @__PURE__ */ h(E, {
|
|
326
|
+
id: "step-position",
|
|
327
|
+
type: "number",
|
|
328
|
+
min: "0",
|
|
329
|
+
value: K,
|
|
330
|
+
onChange: (e) => q(e.target.value),
|
|
331
|
+
placeholder: "Auto"
|
|
332
|
+
})]
|
|
333
|
+
})]
|
|
334
|
+
}),
|
|
335
|
+
/* @__PURE__ */ g("div", {
|
|
336
|
+
className: "space-y-1",
|
|
337
|
+
children: [
|
|
338
|
+
/* @__PURE__ */ h(D, {
|
|
339
|
+
htmlFor: "step-inputs",
|
|
340
|
+
children: "Inputs (JSON)"
|
|
341
|
+
}),
|
|
342
|
+
/* @__PURE__ */ h(pe, {
|
|
343
|
+
id: "step-inputs",
|
|
344
|
+
value: J,
|
|
345
|
+
onChange: (e) => Y(e.target.value),
|
|
346
|
+
rows: 4,
|
|
347
|
+
spellCheck: !1,
|
|
348
|
+
className: "font-mono text-xs",
|
|
349
|
+
placeholder: "{\n \"source\": \"raw-frames\"\n}"
|
|
350
|
+
}),
|
|
351
|
+
/* @__PURE__ */ h("p", {
|
|
352
|
+
className: "text-xs text-text-secondary",
|
|
353
|
+
children: "Optional. A JSON object of step inputs."
|
|
354
|
+
})
|
|
355
|
+
]
|
|
356
|
+
})
|
|
357
|
+
]
|
|
358
|
+
}),
|
|
359
|
+
/* @__PURE__ */ g(oe, { children: [/* @__PURE__ */ h(y, {
|
|
360
|
+
type: "button",
|
|
361
|
+
variant: "outline",
|
|
362
|
+
onClick: () => {
|
|
363
|
+
V(!1), Q();
|
|
364
|
+
},
|
|
365
|
+
disabled: B,
|
|
366
|
+
children: "Cancel"
|
|
367
|
+
}), /* @__PURE__ */ g(y, {
|
|
368
|
+
type: "button",
|
|
369
|
+
onClick: () => void Ce(),
|
|
370
|
+
disabled: B,
|
|
371
|
+
children: [/* @__PURE__ */ h(v, { className: "size-4" }), B ? "Adding…" : "Add step"]
|
|
372
|
+
})] })
|
|
373
|
+
] })
|
|
374
|
+
})]
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
//#endregion
|
|
378
|
+
export { M as default };
|
|
379
|
+
|
|
380
|
+
//# sourceMappingURL=RunDetailPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RunDetailPage.js","names":[],"sources":["../../../../src/cosmicintersection/pages/runs/RunDetailPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { ListTree, Plus } from 'lucide-react';\nimport {\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Input,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\n\nimport {\n useCosAddRunStepMutation,\n useCosRunQuery,\n useCosRunStepsQuery,\n useCosTransitionRunMutation,\n type CosRunStatus,\n type CosStepKind,\n} from '../../api/cosmicApi';\nimport {\n ActivityFeedPanel,\n EmptyState,\n ErrorState,\n LoadingState,\n PageLayout,\n SafeLink,\n StatusBadge,\n formatEnumLabel,\n} from '../../components';\nimport { useCosmicIntersection } from '../../context/CosmicIntersectionContext';\nimport { describeError, mutationSucceeded } from '../../lib/mutationResult';\nimport { notify } from '../../lib/toast';\n\nconst STEP_KIND_OPTIONS: CosStepKind[] = [\n 'INGEST',\n 'CALIBRATE',\n 'TRANSFORM',\n 'ANALYZE',\n 'EXPORT',\n 'NOTIFY',\n];\n\n// Valid forward transitions for the run state machine. Terminal states have none.\nconst NEXT_STATUSES: Record<CosRunStatus, CosRunStatus[]> = {\n QUEUED: ['RUNNING', 'CANCELLED'],\n RUNNING: ['SUCCEEDED', 'FAILED', 'CANCELLED'],\n SUCCEEDED: [],\n FAILED: [],\n CANCELLED: [],\n};\n\nfunction formatDate(value?: string | null): string {\n if (!value) {\n return '—';\n }\n const date = new Date(value);\n return Number.isNaN(date.getTime()) ? '—' : date.toLocaleString();\n}\n\nfunction formatDuration(ms?: number | null): string {\n if (ms === null || ms === undefined) {\n return '—';\n }\n if (ms < 1000) {\n return `${ms} ms`;\n }\n const seconds = ms / 1000;\n if (seconds < 60) {\n return `${seconds.toFixed(1)} s`;\n }\n const minutes = Math.floor(seconds / 60);\n const rest = Math.round(seconds % 60);\n return `${minutes}m ${rest}s`;\n}\n\nfunction DetailRow({ label, children }: { label: string; children: React.ReactNode }) {\n return (\n <div className=\"flex flex-col gap-1 border-b border-border-seam py-3 last:border-0 sm:flex-row sm:items-start sm:gap-4\">\n <span className=\"w-40 shrink-0 text-sm font-medium text-text-secondary\">{label}</span>\n <span className=\"min-w-0 text-sm text-text-primary\">{children}</span>\n </div>\n );\n}\n\nfunction JsonBlock({ value }: { value?: Record<string, unknown> | null }) {\n if (!value || Object.keys(value).length === 0) {\n return <span className=\"text-sm text-text-secondary\">—</span>;\n }\n return (\n <pre className=\"overflow-x-auto rounded-card border border-border-default bg-bg-sunken p-3 font-mono text-xs text-text-primary\">\n {JSON.stringify(value, null, 2)}\n </pre>\n );\n}\n\nexport default function RunDetailPage() {\n const { id = '' } = useParams<{ id: string }>();\n const { navigate } = useCosmicIntersection();\n\n const { data, loading, error, refetch } = useCosRunQuery(id);\n const {\n data: stepsData,\n loading: stepsLoading,\n error: stepsError,\n refetch: refetchSteps,\n } = useCosRunStepsQuery(id);\n\n const [transitionRun, { loading: transitioning }] = useCosTransitionRunMutation();\n const [addStep, { loading: addingStep }] = useCosAddRunStepMutation();\n\n const [stepDialogOpen, setStepDialogOpen] = useState(false);\n const [stepName, setStepName] = useState('');\n const [stepKind, setStepKind] = useState<CosStepKind>('INGEST');\n const [stepPosition, setStepPosition] = useState('');\n const [stepInputs, setStepInputs] = useState('');\n\n const run = data?.cosRun;\n const steps = useMemo(\n () => [...(stepsData?.cosListRunSteps ?? [])].sort((a, b) => a.position - b.position),\n [stepsData]\n );\n\n const handleTransition = async (nextStatus: CosRunStatus) => {\n if (!run) {\n return;\n }\n const response = await transitionRun({ variables: { id: run.id, status: nextStatus } });\n if (\n !mutationSucceeded(response, response.data?.cosTransitionRun?.id, 'Could not update the run')\n ) {\n return;\n }\n notify.success('Run updated', `Run #${run.runNumber} moved to ${formatEnumLabel(nextStatus)}.`);\n await Promise.all([refetch(), refetchSteps()]);\n };\n\n const resetStepForm = () => {\n setStepName('');\n setStepKind('INGEST');\n setStepPosition('');\n setStepInputs('');\n };\n\n const handleAddStep = async () => {\n if (!run) {\n return;\n }\n if (!stepName.trim()) {\n notify.error('Step name is required', 'Give the step a name before adding it.');\n return;\n }\n\n let inputs: Record<string, unknown> | undefined;\n if (stepInputs.trim()) {\n try {\n const parsed = JSON.parse(stepInputs.trim()) as unknown;\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw new Error('Inputs must be a JSON object.');\n }\n inputs = parsed as Record<string, unknown>;\n } catch (parseError) {\n notify.error(\n 'Invalid inputs JSON',\n describeError(parseError) ?? 'Please provide valid JSON.'\n );\n return;\n }\n }\n\n const positionValue = stepPosition.trim() ? Number(stepPosition.trim()) : undefined;\n if (positionValue !== undefined && (Number.isNaN(positionValue) || positionValue < 0)) {\n notify.error('Invalid position', 'Position must be a non-negative number.');\n return;\n }\n\n const response = await addStep({\n variables: {\n input: {\n runId: run.id,\n name: stepName.trim(),\n kind: stepKind,\n inputs,\n position: positionValue,\n },\n },\n });\n if (!mutationSucceeded(response, response.data?.cosAddRunStep?.id, 'Could not add the step')) {\n return;\n }\n notify.success('Step added', `“${stepName.trim()}” was added to the run.`);\n setStepDialogOpen(false);\n resetStepForm();\n await refetchSteps();\n };\n\n if (loading) {\n return (\n <PageLayout title=\"Run\" backPath=\"runs\">\n <LoadingState label=\"Loading run…\" />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout title=\"Run\" backPath=\"runs\">\n <ErrorState onRetry={() => void refetch()} />\n </PageLayout>\n );\n }\n\n if (!run) {\n return (\n <PageLayout title=\"Run\" backPath=\"runs\">\n <EmptyState\n title=\"Run not found\"\n description=\"This run may have been removed or you may not have access to it.\"\n action={\n <Button type=\"button\" variant=\"outline\" onClick={() => navigate('runs')}>\n Back to runs\n </Button>\n }\n />\n </PageLayout>\n );\n }\n\n const validTransitions = NEXT_STATUSES[run.status] ?? [];\n\n return (\n <PageLayout\n title={`Run #${run.runNumber}`}\n description={run.pipeline ? `Pipeline: ${run.pipeline.name}` : undefined}\n backPath=\"runs\"\n actions={\n <div className=\"flex flex-wrap items-center gap-2\">\n {validTransitions.map((next) => (\n <Button\n key={next}\n type=\"button\"\n variant={next === 'CANCELLED' || next === 'FAILED' ? 'outline' : 'default'}\n onClick={() => void handleTransition(next)}\n disabled={transitioning}\n >\n {`Mark ${formatEnumLabel(next)}`}\n </Button>\n ))}\n <Button type=\"button\" variant=\"outline\" onClick={() => setStepDialogOpen(true)}>\n <Plus className=\"size-4\" />\n Add step\n </Button>\n </div>\n }\n >\n <div className=\"space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle>Overview</CardTitle>\n </CardHeader>\n <CardContent>\n <DetailRow label=\"Status\">\n <StatusBadge status={run.status} />\n </DetailRow>\n <DetailRow label=\"Pipeline\">\n {run.pipeline ? (\n <button\n type=\"button\"\n className=\"text-text-primary underline-offset-2 hover:underline\"\n onClick={() => navigate(`pipelines/${run.pipelineId}`)}\n >\n {run.pipeline.name}\n </button>\n ) : (\n <span className=\"font-mono text-xs\">{run.pipelineId}</span>\n )}\n </DetailRow>\n <DetailRow label=\"Dataset\">\n {run.datasetId ? (\n <button\n type=\"button\"\n className=\"text-text-primary underline-offset-2 hover:underline\"\n onClick={() => navigate(`datasets/${run.datasetId}`)}\n >\n <span className=\"font-mono text-xs\">{run.datasetId}</span>\n </button>\n ) : (\n '—'\n )}\n </DetailRow>\n <DetailRow label=\"Triggered by\">{run.triggeredBy || '—'}</DetailRow>\n <DetailRow label=\"Started\">{formatDate(run.startedAt)}</DetailRow>\n <DetailRow label=\"Finished\">{formatDate(run.finishedAt)}</DetailRow>\n <DetailRow label=\"Duration\">{formatDuration(run.durationMs)}</DetailRow>\n {run.errorMessage ? (\n <DetailRow label=\"Error\">\n <span className=\"text-status-error-text\">{run.errorMessage}</span>\n </DetailRow>\n ) : null}\n {validTransitions.length === 0 ? (\n <DetailRow label=\"Discuss\">\n <SafeLink\n href=\"/conversations\"\n className=\"text-text-primary underline-offset-2 hover:underline\"\n >\n Open discussions\n </SafeLink>\n </DetailRow>\n ) : null}\n </CardContent>\n </Card>\n\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle>Parameters</CardTitle>\n </CardHeader>\n <CardContent>\n <JsonBlock value={run.params} />\n </CardContent>\n </Card>\n <Card>\n <CardHeader>\n <CardTitle>Metrics</CardTitle>\n </CardHeader>\n <CardContent>\n <JsonBlock value={run.metrics} />\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle>Steps</CardTitle>\n </CardHeader>\n <CardContent>\n {stepsLoading ? (\n <LoadingState variant=\"rows\" rows={4} label=\"Loading steps…\" />\n ) : stepsError ? (\n <ErrorState message=\"Could not load steps.\" onRetry={() => void refetchSteps()} />\n ) : steps.length === 0 ? (\n <EmptyState\n icon={ListTree}\n title=\"No steps yet\"\n description=\"Add steps to record the ingest, calibration, transform, analyze or export stages of this run.\"\n action={\n <Button type=\"button\" onClick={() => setStepDialogOpen(true)}>\n <Plus className=\"size-4\" />\n Add step\n </Button>\n }\n />\n ) : (\n <ol className=\"space-y-3\">\n {steps.map((step) => (\n <li\n key={step.id}\n className=\"flex flex-col gap-2 rounded-card border border-border-default bg-bg-elevated p-4 sm:flex-row sm:items-start sm:justify-between\"\n >\n <div className=\"flex min-w-0 items-start gap-3\">\n <span className=\"mt-0.5 flex size-7 shrink-0 items-center justify-center rounded-full bg-bg-sunken text-xs font-semibold tabular-nums text-text-secondary\">\n {step.position}\n </span>\n <div className=\"min-w-0\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"font-medium text-text-primary\">{step.name}</span>\n <StatusBadge status={step.kind} tone=\"neutral\" />\n </div>\n {step.errorMessage ? (\n <p className=\"mt-1 text-xs text-status-error-text\">{step.errorMessage}</p>\n ) : null}\n <p className=\"mt-1 text-xs text-text-secondary\">\n Duration: {formatDuration(step.durationMs)}\n </p>\n </div>\n </div>\n <div className=\"shrink-0\">\n <StatusBadge status={step.status} />\n </div>\n </li>\n ))}\n </ol>\n )}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Activity</CardTitle>\n </CardHeader>\n <CardContent>\n <ActivityFeedPanel resourceId={run.id} resourceType=\"cosmicintersection-run\" />\n </CardContent>\n </Card>\n </div>\n\n <Dialog\n open={stepDialogOpen}\n onOpenChange={(next) => {\n if (addingStep) {\n return;\n }\n setStepDialogOpen(next);\n if (!next) {\n resetStepForm();\n }\n }}\n >\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Add step</DialogTitle>\n <DialogDescription>\n Record a stage of this run — its kind, order and optional inputs.\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-1\">\n <Label htmlFor=\"step-name\">Name</Label>\n <Input\n id=\"step-name\"\n value={stepName}\n onChange={(event) => setStepName(event.target.value)}\n placeholder=\"e.g. Calibrate flat fields\"\n />\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div className=\"space-y-1\">\n <Label htmlFor=\"step-kind\">Kind</Label>\n <Select\n value={stepKind}\n onValueChange={(value) => setStepKind(value as CosStepKind)}\n >\n <SelectTrigger id=\"step-kind\" aria-label=\"Step kind\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {STEP_KIND_OPTIONS.map((option) => (\n <SelectItem key={option} value={option}>\n {formatEnumLabel(option)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-1\">\n <Label htmlFor=\"step-position\">Position</Label>\n <Input\n id=\"step-position\"\n type=\"number\"\n min=\"0\"\n value={stepPosition}\n onChange={(event) => setStepPosition(event.target.value)}\n placeholder=\"Auto\"\n />\n </div>\n </div>\n\n <div className=\"space-y-1\">\n <Label htmlFor=\"step-inputs\">Inputs (JSON)</Label>\n <Textarea\n id=\"step-inputs\"\n value={stepInputs}\n onChange={(event) => setStepInputs(event.target.value)}\n rows={4}\n spellCheck={false}\n className=\"font-mono text-xs\"\n placeholder={'{\\n \"source\": \"raw-frames\"\\n}'}\n />\n <p className=\"text-xs text-text-secondary\">Optional. A JSON object of step inputs.</p>\n </div>\n </div>\n\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => {\n setStepDialogOpen(false);\n resetStepForm();\n }}\n disabled={addingStep}\n >\n Cancel\n </Button>\n <Button type=\"button\" onClick={() => void handleAddStep()} disabled={addingStep}>\n <Plus className=\"size-4\" />\n {addingStep ? 'Adding…' : 'Add step'}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { useCosmicIntersection as e } from "../../context/CosmicIntersectionContext.js";
|
|
2
|
+
import { useCosPipelinesQuery as t, useCosRunsQuery as n } from "../../api/cosmicApi.js";
|
|
3
|
+
import r from "../../components/EmptyState.js";
|
|
4
|
+
import i from "../../components/ErrorState.js";
|
|
5
|
+
import a from "../../components/LoadingState.js";
|
|
6
|
+
import o from "../../components/PageLayout.js";
|
|
7
|
+
import s, { usePagination as c } from "../../components/Pagination.js";
|
|
8
|
+
import l, { formatEnumLabel as u } from "../../components/StatusBadge.js";
|
|
9
|
+
import "../../components/index.js";
|
|
10
|
+
import { useMemo as d, useState as f } from "react";
|
|
11
|
+
import { Fragment as p, jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
12
|
+
import { Activity as g, Eye as _ } from "lucide-react";
|
|
13
|
+
import { Button as v, Select as y, SelectContent as b, SelectItem as x, SelectTrigger as S, SelectValue as C, Table as w, TableBody as T, TableCell as E, TableHead as D, TableHeader as O, TableRow as k } from "@burdenoff/fe-libs/ui";
|
|
14
|
+
//#region src/cosmicintersection/pages/runs/RunsPage.tsx
|
|
15
|
+
var A = [
|
|
16
|
+
"QUEUED",
|
|
17
|
+
"RUNNING",
|
|
18
|
+
"SUCCEEDED",
|
|
19
|
+
"FAILED",
|
|
20
|
+
"CANCELLED"
|
|
21
|
+
], j = "ALL";
|
|
22
|
+
function M(e) {
|
|
23
|
+
if (!e) return "—";
|
|
24
|
+
let t = new Date(e);
|
|
25
|
+
return Number.isNaN(t.getTime()) ? "—" : t.toLocaleString();
|
|
26
|
+
}
|
|
27
|
+
function N(e) {
|
|
28
|
+
if (e == null) return "—";
|
|
29
|
+
if (e < 1e3) return `${e} ms`;
|
|
30
|
+
let t = e / 1e3;
|
|
31
|
+
return t < 60 ? `${t.toFixed(1)} s` : `${Math.floor(t / 60)}m ${Math.round(t % 60)}s`;
|
|
32
|
+
}
|
|
33
|
+
function P() {
|
|
34
|
+
let { navigate: P } = e(), [F, I] = f(j), [L, R] = f(j), z = c({ resetKey: `${F}:${L}` }), { data: B } = t({ pagination: {
|
|
35
|
+
limit: 100,
|
|
36
|
+
offset: 0
|
|
37
|
+
} }), V = d(() => B?.cosListPipelines.items ?? [], [B]), H = d(() => {
|
|
38
|
+
let e = /* @__PURE__ */ new Map();
|
|
39
|
+
return V.forEach((t) => e.set(t.id, t.name)), e;
|
|
40
|
+
}, [V]), { data: U, loading: W, error: G, refetch: K } = n({
|
|
41
|
+
status: F === j ? void 0 : F,
|
|
42
|
+
pipelineId: L === j ? void 0 : L,
|
|
43
|
+
pagination: {
|
|
44
|
+
limit: z.limit,
|
|
45
|
+
offset: z.offset
|
|
46
|
+
}
|
|
47
|
+
}), q = d(() => U?.cosListRuns.items ?? [], [U]), J = U?.cosListRuns.pageInfo;
|
|
48
|
+
return /* @__PURE__ */ m(o, {
|
|
49
|
+
title: "Runs",
|
|
50
|
+
description: "Every pipeline execution, with status, timings and outcomes.",
|
|
51
|
+
actions: /* @__PURE__ */ h(v, {
|
|
52
|
+
type: "button",
|
|
53
|
+
variant: "outline",
|
|
54
|
+
onClick: () => P("pipelines"),
|
|
55
|
+
children: [/* @__PURE__ */ m(_, { className: "size-4" }), "View pipelines"]
|
|
56
|
+
}),
|
|
57
|
+
children: /* @__PURE__ */ h("div", {
|
|
58
|
+
className: "space-y-4",
|
|
59
|
+
children: [/* @__PURE__ */ h("div", {
|
|
60
|
+
className: "flex flex-wrap items-center gap-3",
|
|
61
|
+
children: [/* @__PURE__ */ h("label", {
|
|
62
|
+
className: "flex items-center gap-2 text-sm text-text-secondary",
|
|
63
|
+
children: [/* @__PURE__ */ m("span", { children: "Status" }), /* @__PURE__ */ h(y, {
|
|
64
|
+
value: F,
|
|
65
|
+
onValueChange: (e) => I(e),
|
|
66
|
+
children: [/* @__PURE__ */ m(S, {
|
|
67
|
+
"aria-label": "Filter by status",
|
|
68
|
+
className: "w-40",
|
|
69
|
+
children: /* @__PURE__ */ m(C, {})
|
|
70
|
+
}), /* @__PURE__ */ h(b, { children: [/* @__PURE__ */ m(x, {
|
|
71
|
+
value: j,
|
|
72
|
+
children: "All statuses"
|
|
73
|
+
}), A.map((e) => /* @__PURE__ */ m(x, {
|
|
74
|
+
value: e,
|
|
75
|
+
children: u(e)
|
|
76
|
+
}, e))] })]
|
|
77
|
+
})]
|
|
78
|
+
}), /* @__PURE__ */ h("label", {
|
|
79
|
+
className: "flex items-center gap-2 text-sm text-text-secondary",
|
|
80
|
+
children: [/* @__PURE__ */ m("span", { children: "Pipeline" }), /* @__PURE__ */ h(y, {
|
|
81
|
+
value: L,
|
|
82
|
+
onValueChange: (e) => R(e),
|
|
83
|
+
children: [/* @__PURE__ */ m(S, {
|
|
84
|
+
"aria-label": "Filter by pipeline",
|
|
85
|
+
className: "w-56",
|
|
86
|
+
children: /* @__PURE__ */ m(C, {})
|
|
87
|
+
}), /* @__PURE__ */ h(b, { children: [/* @__PURE__ */ m(x, {
|
|
88
|
+
value: j,
|
|
89
|
+
children: "All pipelines"
|
|
90
|
+
}), V.map((e) => /* @__PURE__ */ m(x, {
|
|
91
|
+
value: e.id,
|
|
92
|
+
children: e.name
|
|
93
|
+
}, e.id))] })]
|
|
94
|
+
})]
|
|
95
|
+
})]
|
|
96
|
+
}), W ? /* @__PURE__ */ m(a, {
|
|
97
|
+
variant: "rows",
|
|
98
|
+
rows: 6,
|
|
99
|
+
label: "Loading runs…"
|
|
100
|
+
}) : G ? /* @__PURE__ */ m(i, {
|
|
101
|
+
message: "We could not load pipeline runs. Please try again.",
|
|
102
|
+
onRetry: () => void K()
|
|
103
|
+
}) : q.length === 0 ? /* @__PURE__ */ m(r, {
|
|
104
|
+
icon: g,
|
|
105
|
+
title: F === j && L === j ? "No runs yet" : "No runs match these filters",
|
|
106
|
+
description: F === j && L === j ? "Runs appear here once you start a pipeline. Each run tracks its steps, timings and metrics." : "Try a different status or pipeline filter."
|
|
107
|
+
}) : /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m("div", {
|
|
108
|
+
className: "overflow-x-auto rounded-card border border-border-default bg-bg-elevated",
|
|
109
|
+
children: /* @__PURE__ */ h(w, { children: [/* @__PURE__ */ m(O, { children: /* @__PURE__ */ h(k, { children: [
|
|
110
|
+
/* @__PURE__ */ m(D, { children: "Run" }),
|
|
111
|
+
/* @__PURE__ */ m(D, { children: "Pipeline" }),
|
|
112
|
+
/* @__PURE__ */ m(D, { children: "Status" }),
|
|
113
|
+
/* @__PURE__ */ m(D, { children: "Started" }),
|
|
114
|
+
/* @__PURE__ */ m(D, { children: "Finished" }),
|
|
115
|
+
/* @__PURE__ */ m(D, { children: "Duration" })
|
|
116
|
+
] }) }), /* @__PURE__ */ m(T, { children: q.map((e) => /* @__PURE__ */ h(k, {
|
|
117
|
+
className: "cursor-pointer",
|
|
118
|
+
onClick: () => P(`runs/${e.id}`),
|
|
119
|
+
children: [
|
|
120
|
+
/* @__PURE__ */ h(E, {
|
|
121
|
+
className: "font-medium text-text-primary",
|
|
122
|
+
children: ["#", e.runNumber]
|
|
123
|
+
}),
|
|
124
|
+
/* @__PURE__ */ m(E, {
|
|
125
|
+
className: "text-text-secondary",
|
|
126
|
+
children: /* @__PURE__ */ m("span", {
|
|
127
|
+
className: "truncate",
|
|
128
|
+
children: H.get(e.pipelineId) ?? /* @__PURE__ */ m("span", {
|
|
129
|
+
className: "font-mono text-xs",
|
|
130
|
+
children: e.pipelineId
|
|
131
|
+
})
|
|
132
|
+
})
|
|
133
|
+
}),
|
|
134
|
+
/* @__PURE__ */ m(E, { children: /* @__PURE__ */ m(l, { status: e.status }) }),
|
|
135
|
+
/* @__PURE__ */ m(E, {
|
|
136
|
+
className: "whitespace-nowrap text-text-secondary",
|
|
137
|
+
children: M(e.startedAt)
|
|
138
|
+
}),
|
|
139
|
+
/* @__PURE__ */ m(E, {
|
|
140
|
+
className: "whitespace-nowrap text-text-secondary",
|
|
141
|
+
children: M(e.finishedAt)
|
|
142
|
+
}),
|
|
143
|
+
/* @__PURE__ */ m(E, {
|
|
144
|
+
className: "tabular-nums text-text-secondary",
|
|
145
|
+
children: N(e.durationMs)
|
|
146
|
+
})
|
|
147
|
+
]
|
|
148
|
+
}, e.id)) })] })
|
|
149
|
+
}), /* @__PURE__ */ m(s, {
|
|
150
|
+
offset: z.offset,
|
|
151
|
+
limit: z.limit,
|
|
152
|
+
loadedCount: q.length,
|
|
153
|
+
hasMore: J?.hasMore ?? !1,
|
|
154
|
+
onPrev: z.prevPage,
|
|
155
|
+
onNext: z.nextPage,
|
|
156
|
+
itemLabel: "runs",
|
|
157
|
+
loading: W
|
|
158
|
+
})] })]
|
|
159
|
+
})
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
//#endregion
|
|
163
|
+
export { P as default };
|
|
164
|
+
|
|
165
|
+
//# sourceMappingURL=RunsPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RunsPage.js","names":[],"sources":["../../../../src/cosmicintersection/pages/runs/RunsPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { Activity, Eye } from 'lucide-react';\nimport {\n Button,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@burdenoff/fe-libs/ui';\n\nimport { useCosPipelinesQuery, useCosRunsQuery, type CosRunStatus } from '../../api/cosmicApi';\nimport {\n EmptyState,\n ErrorState,\n LoadingState,\n PageLayout,\n Pagination,\n StatusBadge,\n formatEnumLabel,\n usePagination,\n} from '../../components';\nimport { useCosmicIntersection } from '../../context/CosmicIntersectionContext';\n\nconst STATUS_OPTIONS: CosRunStatus[] = ['QUEUED', 'RUNNING', 'SUCCEEDED', 'FAILED', 'CANCELLED'];\nconst ALL = 'ALL';\n\nfunction formatDate(value?: string | null): string {\n if (!value) {\n return '—';\n }\n const date = new Date(value);\n return Number.isNaN(date.getTime()) ? '—' : date.toLocaleString();\n}\n\nfunction formatDuration(ms?: number | null): string {\n if (ms === null || ms === undefined) {\n return '—';\n }\n if (ms < 1000) {\n return `${ms} ms`;\n }\n const seconds = ms / 1000;\n if (seconds < 60) {\n return `${seconds.toFixed(1)} s`;\n }\n const minutes = Math.floor(seconds / 60);\n const rest = Math.round(seconds % 60);\n return `${minutes}m ${rest}s`;\n}\n\nexport default function RunsPage() {\n const { navigate } = useCosmicIntersection();\n const [status, setStatus] = useState<CosRunStatus | typeof ALL>(ALL);\n const [pipelineId, setPipelineId] = useState<string | typeof ALL>(ALL);\n const pagination = usePagination({ resetKey: `${status}:${pipelineId}` });\n\n // Load pipelines to populate the filter and to resolve run -> pipeline names.\n const { data: pipelinesData } = useCosPipelinesQuery({ pagination: { limit: 100, offset: 0 } });\n const pipelines = useMemo(() => pipelinesData?.cosListPipelines.items ?? [], [pipelinesData]);\n const pipelineNameById = useMemo(() => {\n const map = new Map<string, string>();\n pipelines.forEach((pipeline) => map.set(pipeline.id, pipeline.name));\n return map;\n }, [pipelines]);\n\n const { data, loading, error, refetch } = useCosRunsQuery({\n status: status === ALL ? undefined : status,\n pipelineId: pipelineId === ALL ? undefined : pipelineId,\n pagination: { limit: pagination.limit, offset: pagination.offset },\n });\n\n const runs = useMemo(() => data?.cosListRuns.items ?? [], [data]);\n const pageInfo = data?.cosListRuns.pageInfo;\n\n const renderBody = () => {\n if (loading) {\n return <LoadingState variant=\"rows\" rows={6} label=\"Loading runs…\" />;\n }\n if (error) {\n return (\n <ErrorState\n message=\"We could not load pipeline runs. Please try again.\"\n onRetry={() => void refetch()}\n />\n );\n }\n if (runs.length === 0) {\n return (\n <EmptyState\n icon={Activity}\n title={\n status === ALL && pipelineId === ALL ? 'No runs yet' : 'No runs match these filters'\n }\n description={\n status === ALL && pipelineId === ALL\n ? 'Runs appear here once you start a pipeline. Each run tracks its steps, timings and metrics.'\n : 'Try a different status or pipeline filter.'\n }\n />\n );\n }\n\n return (\n <>\n <div className=\"overflow-x-auto rounded-card border border-border-default bg-bg-elevated\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Run</TableHead>\n <TableHead>Pipeline</TableHead>\n <TableHead>Status</TableHead>\n <TableHead>Started</TableHead>\n <TableHead>Finished</TableHead>\n <TableHead>Duration</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {runs.map((run) => (\n <TableRow\n key={run.id}\n className=\"cursor-pointer\"\n onClick={() => navigate(`runs/${run.id}`)}\n >\n <TableCell className=\"font-medium text-text-primary\">#{run.runNumber}</TableCell>\n <TableCell className=\"text-text-secondary\">\n <span className=\"truncate\">\n {pipelineNameById.get(run.pipelineId) ?? (\n <span className=\"font-mono text-xs\">{run.pipelineId}</span>\n )}\n </span>\n </TableCell>\n <TableCell>\n <StatusBadge status={run.status} />\n </TableCell>\n <TableCell className=\"whitespace-nowrap text-text-secondary\">\n {formatDate(run.startedAt)}\n </TableCell>\n <TableCell className=\"whitespace-nowrap text-text-secondary\">\n {formatDate(run.finishedAt)}\n </TableCell>\n <TableCell className=\"tabular-nums text-text-secondary\">\n {formatDuration(run.durationMs)}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n\n <Pagination\n offset={pagination.offset}\n limit={pagination.limit}\n loadedCount={runs.length}\n hasMore={pageInfo?.hasMore ?? false}\n onPrev={pagination.prevPage}\n onNext={pagination.nextPage}\n itemLabel=\"runs\"\n loading={loading}\n />\n </>\n );\n };\n\n return (\n <PageLayout\n title=\"Runs\"\n description=\"Every pipeline execution, with status, timings and outcomes.\"\n actions={\n <Button type=\"button\" variant=\"outline\" onClick={() => navigate('pipelines')}>\n <Eye className=\"size-4\" />\n View pipelines\n </Button>\n }\n >\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <label className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <span>Status</span>\n <Select\n value={status}\n onValueChange={(value) => setStatus(value as CosRunStatus | typeof ALL)}\n >\n <SelectTrigger aria-label=\"Filter by status\" className=\"w-40\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All statuses</SelectItem>\n {STATUS_OPTIONS.map((option) => (\n <SelectItem key={option} value={option}>\n {formatEnumLabel(option)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </label>\n\n <label className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <span>Pipeline</span>\n <Select\n value={pipelineId}\n onValueChange={(value) => setPipelineId(value as string | typeof ALL)}\n >\n <SelectTrigger aria-label=\"Filter by pipeline\" className=\"w-56\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All pipelines</SelectItem>\n {pipelines.map((pipeline) => (\n <SelectItem key={pipeline.id} value={pipeline.id}>\n {pipeline.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </label>\n </div>\n\n {renderBody()}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AA8BA,IAAM,IAAiC;CAAC;CAAU;CAAW;CAAa;CAAU;CAAY,EAC1F,IAAM;AAEZ,SAAS,EAAW,GAA+B;AACjD,KAAI,CAAC,EACH,QAAO;CAET,IAAM,IAAO,IAAI,KAAK,EAAM;AAC5B,QAAO,OAAO,MAAM,EAAK,SAAS,CAAC,GAAG,MAAM,EAAK,gBAAgB;;AAGnE,SAAS,EAAe,GAA4B;AAClD,KAAI,KAAO,KACT,QAAO;AAET,KAAI,IAAK,IACP,QAAO,GAAG,EAAG;CAEf,IAAM,IAAU,IAAK;AAMrB,QALI,IAAU,KACL,GAAG,EAAQ,QAAQ,EAAE,CAAC,MAIxB,GAFS,KAAK,MAAM,IAAU,GAAG,CAEtB,IADL,KAAK,MAAM,IAAU,GAAG,CACV;;AAG7B,SAAwB,IAAW;CACjC,IAAM,EAAE,gBAAa,GAAuB,EACtC,CAAC,GAAQ,KAAa,EAAoC,EAAI,EAC9D,CAAC,GAAY,KAAiB,EAA8B,EAAI,EAChE,IAAa,EAAc,EAAE,UAAU,GAAG,EAAO,GAAG,KAAc,CAAC,EAGnE,EAAE,MAAM,MAAkB,EAAqB,EAAE,YAAY;EAAE,OAAO;EAAK,QAAQ;EAAG,EAAE,CAAC,EACzF,IAAY,QAAc,GAAe,iBAAiB,SAAS,EAAE,EAAE,CAAC,EAAc,CAAC,EACvF,IAAmB,QAAc;EACrC,IAAM,oBAAM,IAAI,KAAqB;AAErC,SADA,EAAU,SAAS,MAAa,EAAI,IAAI,EAAS,IAAI,EAAS,KAAK,CAAC,EAC7D;IACN,CAAC,EAAU,CAAC,EAET,EAAE,SAAM,YAAS,UAAO,eAAY,EAAgB;EACxD,QAAQ,MAAW,IAAM,KAAA,IAAY;EACrC,YAAY,MAAe,IAAM,KAAA,IAAY;EAC7C,YAAY;GAAE,OAAO,EAAW;GAAO,QAAQ,EAAW;GAAQ;EACnE,CAAC,EAEI,IAAO,QAAc,GAAM,YAAY,SAAS,EAAE,EAAE,CAAC,EAAK,CAAC,EAC3D,IAAW,GAAM,YAAY;AA2FnC,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,GAAD;GAAQ,MAAK;GAAS,SAAQ;GAAU,eAAe,EAAS,YAAY;aAA5E,CACE,kBAAC,GAAD,EAAK,WAAU,UAAW,CAAA,EAAA,iBAEnB;;YAGX,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,SAAD;KAAO,WAAU;eAAjB,CACE,kBAAC,QAAD,EAAA,UAAM,UAAa,CAAA,EACnB,kBAAC,GAAD;MACE,OAAO;MACP,gBAAgB,MAAU,EAAU,EAAmC;gBAFzE,CAIE,kBAAC,GAAD;OAAe,cAAW;OAAmB,WAAU;iBACrD,kBAAC,GAAD,EAAe,CAAA;OACD,CAAA,EAChB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;OAAY,OAAO;iBAAK;OAAyB,CAAA,EAChD,EAAe,KAAK,MACnB,kBAAC,GAAD;OAAyB,OAAO;iBAC7B,EAAgB,EAAO;OACb,EAFI,EAEJ,CACb,CACY,EAAA,CAAA,CACT;QACH;QAER,kBAAC,SAAD;KAAO,WAAU;eAAjB,CACE,kBAAC,QAAD,EAAA,UAAM,YAAe,CAAA,EACrB,kBAAC,GAAD;MACE,OAAO;MACP,gBAAgB,MAAU,EAAc,EAA6B;gBAFvE,CAIE,kBAAC,GAAD;OAAe,cAAW;OAAqB,WAAU;iBACvD,kBAAC,GAAD,EAAe,CAAA;OACD,CAAA,EAChB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;OAAY,OAAO;iBAAK;OAA0B,CAAA,EACjD,EAAU,KAAK,MACd,kBAAC,GAAD;OAA8B,OAAO,EAAS;iBAC3C,EAAS;OACC,EAFI,EAAS,GAEb,CACb,CACY,EAAA,CAAA,CACT;QACH;OACJ;OA5IN,IACK,kBAAC,GAAD;IAAc,SAAQ;IAAO,MAAM;IAAG,OAAM;IAAkB,CAAA,GAEnE,IAEA,kBAAC,GAAD;IACE,SAAQ;IACR,eAAe,KAAK,GAAS;IAC7B,CAAA,GAGF,EAAK,WAAW,IAEhB,kBAAC,GAAD;IACE,MAAM;IACN,OACE,MAAW,KAAO,MAAe,IAAM,gBAAgB;IAEzD,aACE,MAAW,KAAO,MAAe,IAC7B,gGACA;IAEN,CAAA,GAKJ,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAA;KACE,kBAAC,GAAD,EAAA,UAAW,OAAe,CAAA;KAC1B,kBAAC,GAAD,EAAA,UAAW,YAAoB,CAAA;KAC/B,kBAAC,GAAD,EAAA,UAAW,UAAkB,CAAA;KAC7B,kBAAC,GAAD,EAAA,UAAW,WAAmB,CAAA;KAC9B,kBAAC,GAAD,EAAA,UAAW,YAAoB,CAAA;KAC/B,kBAAC,GAAD,EAAA,UAAW,YAAoB,CAAA;KACtB,EAAA,CAAA,EACC,CAAA,EACd,kBAAC,GAAD,EAAA,UACG,EAAK,KAAK,MACT,kBAAC,GAAD;KAEE,WAAU;KACV,eAAe,EAAS,QAAQ,EAAI,KAAK;eAH3C;MAKE,kBAAC,GAAD;OAAW,WAAU;iBAArB,CAAqD,KAAE,EAAI,UAAsB;;MACjF,kBAAC,GAAD;OAAW,WAAU;iBACnB,kBAAC,QAAD;QAAM,WAAU;kBACb,EAAiB,IAAI,EAAI,WAAW,IACnC,kBAAC,QAAD;SAAM,WAAU;mBAAqB,EAAI;SAAkB,CAAA;QAExD,CAAA;OACG,CAAA;MACZ,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAa,QAAQ,EAAI,QAAU,CAAA,EACzB,CAAA;MACZ,kBAAC,GAAD;OAAW,WAAU;iBAClB,EAAW,EAAI,UAAU;OAChB,CAAA;MACZ,kBAAC,GAAD;OAAW,WAAU;iBAClB,EAAW,EAAI,WAAW;OACjB,CAAA;MACZ,kBAAC,GAAD;OAAW,WAAU;iBAClB,EAAe,EAAI,WAAW;OACrB,CAAA;MACH;OAxBJ,EAAI,GAwBA,CACX,EACQ,CAAA,CACN,EAAA,CAAA;IACJ,CAAA,EAEN,kBAAC,GAAD;IACE,QAAQ,EAAW;IACnB,OAAO,EAAW;IAClB,aAAa,EAAK;IAClB,SAAS,GAAU,WAAW;IAC9B,QAAQ,EAAW;IACnB,QAAQ,EAAW;IACnB,WAAU;IACD;IACT,CAAA,CACD,EAAA,CAAA,CA2DG;;EACK,CAAA"}
|