@burdenoff/microfe-cosmicintersection 2026.827.1 → 2026.830.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/components/ActionMenu.d.ts +1 -1
- package/dist/cosmicintersection/components/ActionMenu.d.ts.map +1 -1
- package/dist/cosmicintersection/components/ActionMenu.js +51 -54
- package/dist/cosmicintersection/components/ActionMenu.js.map +1 -1
- package/dist/cosmicintersection/components/EntityFormShell.d.ts +1 -1
- package/dist/cosmicintersection/components/EntityFormShell.d.ts.map +1 -1
- package/dist/cosmicintersection/components/EntityFormShell.js +29 -27
- package/dist/cosmicintersection/components/EntityFormShell.js.map +1 -1
- package/dist/cosmicintersection/components/ErrorState.d.ts +1 -1
- package/dist/cosmicintersection/components/ErrorState.d.ts.map +1 -1
- package/dist/cosmicintersection/components/ErrorState.js +19 -17
- package/dist/cosmicintersection/components/ErrorState.js.map +1 -1
- package/dist/cosmicintersection/components/FileUploadField.d.ts.map +1 -1
- package/dist/cosmicintersection/components/FileUploadField.js +61 -60
- package/dist/cosmicintersection/components/FileUploadField.js.map +1 -1
- package/dist/cosmicintersection/components/LoadingState.d.ts +1 -1
- package/dist/cosmicintersection/components/LoadingState.d.ts.map +1 -1
- package/dist/cosmicintersection/components/LoadingState.js +15 -13
- package/dist/cosmicintersection/components/LoadingState.js.map +1 -1
- package/dist/cosmicintersection/components/PageLayout.d.ts.map +1 -1
- package/dist/cosmicintersection/components/PageLayout.js +28 -27
- package/dist/cosmicintersection/components/PageLayout.js.map +1 -1
- package/dist/cosmicintersection/components/Pagination.d.ts.map +1 -1
- package/dist/cosmicintersection/components/Pagination.js +38 -35
- package/dist/cosmicintersection/components/Pagination.js.map +1 -1
- package/dist/cosmicintersection/components/StatusBadge.d.ts.map +1 -1
- package/dist/cosmicintersection/components/StatusBadge.js +30 -9
- package/dist/cosmicintersection/components/StatusBadge.js.map +1 -1
- package/dist/cosmicintersection/pages/access/AccessPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/access/AccessPage.js +147 -146
- package/dist/cosmicintersection/pages/access/AccessPage.js.map +1 -1
- package/dist/cosmicintersection/pages/analyses/AnalysesPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/analyses/AnalysesPage.js +260 -259
- package/dist/cosmicintersection/pages/analyses/AnalysesPage.js.map +1 -1
- package/dist/cosmicintersection/pages/collections/CollectionsPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/collections/CollectionsPage.js +63 -62
- package/dist/cosmicintersection/pages/collections/CollectionsPage.js.map +1 -1
- package/dist/cosmicintersection/pages/dashboard/DashboardPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/dashboard/DashboardPage.js +132 -131
- package/dist/cosmicintersection/pages/dashboard/DashboardPage.js.map +1 -1
- package/dist/cosmicintersection/pages/datasets/DatasetsPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/datasets/DatasetsPage.js +178 -177
- package/dist/cosmicintersection/pages/datasets/DatasetsPage.js.map +1 -1
- package/dist/cosmicintersection/pages/discovery/DiscoveryPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/discovery/DiscoveryPage.js +138 -145
- package/dist/cosmicintersection/pages/discovery/DiscoveryPage.js.map +1 -1
- package/dist/cosmicintersection/pages/lineage/LineagePage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/lineage/LineagePage.js +78 -88
- package/dist/cosmicintersection/pages/lineage/LineagePage.js.map +1 -1
- package/dist/cosmicintersection/pages/notebooks/NotebooksPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/notebooks/NotebooksPage.js +125 -124
- package/dist/cosmicintersection/pages/notebooks/NotebooksPage.js.map +1 -1
- package/dist/cosmicintersection/pages/pipelines/PipelinesPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/pipelines/PipelinesPage.js +152 -151
- package/dist/cosmicintersection/pages/pipelines/PipelinesPage.js.map +1 -1
- package/dist/cosmicintersection/pages/releases/ReleasesPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/releases/ReleasesPage.js +175 -174
- package/dist/cosmicintersection/pages/releases/ReleasesPage.js.map +1 -1
- package/dist/cosmicintersection/pages/runs/RunsPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/runs/RunsPage.js +197 -188
- package/dist/cosmicintersection/pages/runs/RunsPage.js.map +1 -1
- package/dist/cosmicintersection/pages/sources/SourcesPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/sources/SourcesPage.js +65 -64
- package/dist/cosmicintersection/pages/sources/SourcesPage.js.map +1 -1
- package/dist/dev/main.d.ts.map +1 -1
- package/dist/shared/hooks/useTr.d.ts +12 -0
- package/dist/shared/hooks/useTr.d.ts.map +1 -0
- package/dist/shared/hooks/useTr.js +16 -0
- package/dist/shared/hooks/useTr.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,242 +1,251 @@
|
|
|
1
1
|
import { useCosmicIntersection as e } from "../../context/CosmicIntersectionContext.js";
|
|
2
2
|
import { useCosPipelinesQuery as t, useCosRunsQuery as n } from "../../api/cosmicApi.js";
|
|
3
|
-
import r from "
|
|
4
|
-
import i from "../../components/
|
|
5
|
-
import a from "../../components/
|
|
6
|
-
import o from "../../components/
|
|
7
|
-
import s
|
|
8
|
-
import
|
|
3
|
+
import { useTr as r } from "../../../shared/hooks/useTr.js";
|
|
4
|
+
import i from "../../components/EmptyState.js";
|
|
5
|
+
import a from "../../components/ErrorState.js";
|
|
6
|
+
import o from "../../components/LoadingState.js";
|
|
7
|
+
import s from "../../components/PageLayout.js";
|
|
8
|
+
import c, { usePagination as l } from "../../components/Pagination.js";
|
|
9
|
+
import u, { formatEnumLabel as d } from "../../components/StatusBadge.js";
|
|
9
10
|
import "../../components/index.js";
|
|
10
|
-
import { useMemo as
|
|
11
|
-
import { Fragment as
|
|
12
|
-
import { Activity as
|
|
13
|
-
import { Button as
|
|
11
|
+
import { useMemo as f, useState as p } from "react";
|
|
12
|
+
import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
13
|
+
import { Activity as _, Eye as v } from "lucide-react";
|
|
14
|
+
import { Button as y, Select as b, SelectContent as x, SelectItem as S, SelectTrigger as C, SelectValue as w, Table as T, TableBody as E, TableCell as D, TableHead as O, TableHeader as k, TableRow as A } from "@burdenoff/fe-libs/ui";
|
|
14
15
|
//#region src/cosmicintersection/pages/runs/RunsPage.tsx
|
|
15
|
-
var
|
|
16
|
+
var j = [
|
|
16
17
|
"QUEUED",
|
|
17
18
|
"RUNNING",
|
|
18
19
|
"SUCCEEDED",
|
|
19
20
|
"FAILED",
|
|
20
21
|
"CANCELLED"
|
|
21
|
-
],
|
|
22
|
-
function
|
|
22
|
+
], M = "ALL";
|
|
23
|
+
function N(e) {
|
|
23
24
|
if (!e) return "—";
|
|
24
25
|
let t = new Date(e);
|
|
25
26
|
return Number.isNaN(t.getTime()) ? "—" : t.toLocaleString();
|
|
26
27
|
}
|
|
27
|
-
function
|
|
28
|
+
function P(e) {
|
|
28
29
|
if (e == null) return "—";
|
|
29
30
|
if (e < 1e3) return `${e} ms`;
|
|
30
31
|
let t = e / 1e3;
|
|
31
32
|
return t < 60 ? `${t.toFixed(1)} s` : `${Math.floor(t / 60)}m ${Math.round(t % 60)}s`;
|
|
32
33
|
}
|
|
33
|
-
function
|
|
34
|
-
let { navigate:
|
|
34
|
+
function F() {
|
|
35
|
+
let { navigate: F } = e(), I = r(), [L, R] = p(M), [z, B] = p(M), V = l({ resetKey: `${L}:${z}` }), { data: H } = t({ pagination: {
|
|
35
36
|
limit: 100,
|
|
36
37
|
offset: 0
|
|
37
|
-
} }),
|
|
38
|
+
} }), U = f(() => H?.cosListPipelines.items ?? [], [H]), W = f(() => {
|
|
38
39
|
let e = /* @__PURE__ */ new Map();
|
|
39
|
-
return
|
|
40
|
-
}, [
|
|
41
|
-
status:
|
|
42
|
-
pipelineId:
|
|
40
|
+
return U.forEach((t) => e.set(t.id, t.name)), e;
|
|
41
|
+
}, [U]), { data: G, loading: K, error: q, refetch: J } = n({
|
|
42
|
+
status: L === M ? void 0 : L,
|
|
43
|
+
pipelineId: z === M ? void 0 : z,
|
|
43
44
|
pagination: {
|
|
44
|
-
limit:
|
|
45
|
-
offset:
|
|
45
|
+
limit: V.limit,
|
|
46
|
+
offset: V.offset
|
|
46
47
|
}
|
|
47
|
-
}),
|
|
48
|
-
return /* @__PURE__ */
|
|
49
|
-
title: "Runs",
|
|
50
|
-
description: "Every pipeline execution, with status, timings and outcomes.",
|
|
51
|
-
actions: /* @__PURE__ */
|
|
48
|
+
}), Y = f(() => G?.cosListRuns.items ?? [], [G]), X = G?.cosListRuns.pageInfo;
|
|
49
|
+
return /* @__PURE__ */ h(s, {
|
|
50
|
+
title: I("cosmicintersection.pages.runs.title", "Runs"),
|
|
51
|
+
description: I("cosmicintersection.pages.runs.description", "Every pipeline execution, with status, timings and outcomes."),
|
|
52
|
+
actions: /* @__PURE__ */ g(y, {
|
|
52
53
|
type: "button",
|
|
53
54
|
variant: "outline",
|
|
54
|
-
onClick: () =>
|
|
55
|
-
children: [/* @__PURE__ */
|
|
55
|
+
onClick: () => F("pipelines"),
|
|
56
|
+
children: [/* @__PURE__ */ h(v, { className: "size-4" }), I("cosmicintersection.pages.runs.viewPipelines", "View pipelines")]
|
|
56
57
|
}),
|
|
57
|
-
children: /* @__PURE__ */
|
|
58
|
+
children: /* @__PURE__ */ g("div", {
|
|
58
59
|
className: "space-y-4",
|
|
59
|
-
children: [/* @__PURE__ */
|
|
60
|
+
children: [/* @__PURE__ */ g("div", {
|
|
60
61
|
className: "flex flex-wrap items-center gap-3",
|
|
61
|
-
children: [/* @__PURE__ */
|
|
62
|
+
children: [/* @__PURE__ */ g("label", {
|
|
62
63
|
className: "flex items-center gap-2 text-sm text-text-secondary",
|
|
63
|
-
children: [/* @__PURE__ */
|
|
64
|
-
value:
|
|
65
|
-
onValueChange: (e) =>
|
|
66
|
-
children: [/* @__PURE__ */
|
|
64
|
+
children: [/* @__PURE__ */ h("span", { children: "Status" }), /* @__PURE__ */ g(b, {
|
|
65
|
+
value: L,
|
|
66
|
+
onValueChange: (e) => R(e),
|
|
67
|
+
children: [/* @__PURE__ */ h(C, {
|
|
67
68
|
"aria-label": "Filter by status",
|
|
68
69
|
className: "w-40",
|
|
69
|
-
children: /* @__PURE__ */
|
|
70
|
-
}), /* @__PURE__ */
|
|
71
|
-
value:
|
|
70
|
+
children: /* @__PURE__ */ h(w, {})
|
|
71
|
+
}), /* @__PURE__ */ g(x, { children: [/* @__PURE__ */ h(S, {
|
|
72
|
+
value: M,
|
|
72
73
|
children: "All statuses"
|
|
73
|
-
}),
|
|
74
|
+
}), j.map((e) => /* @__PURE__ */ h(S, {
|
|
74
75
|
value: e,
|
|
75
|
-
children:
|
|
76
|
+
children: d(e)
|
|
76
77
|
}, e))] })]
|
|
77
78
|
})]
|
|
78
|
-
}), /* @__PURE__ */
|
|
79
|
+
}), /* @__PURE__ */ g("label", {
|
|
79
80
|
className: "flex items-center gap-2 text-sm text-text-secondary",
|
|
80
|
-
children: [/* @__PURE__ */
|
|
81
|
-
value:
|
|
82
|
-
onValueChange: (e) =>
|
|
83
|
-
children: [/* @__PURE__ */
|
|
81
|
+
children: [/* @__PURE__ */ h("span", { children: "Pipeline" }), /* @__PURE__ */ g(b, {
|
|
82
|
+
value: z,
|
|
83
|
+
onValueChange: (e) => B(e),
|
|
84
|
+
children: [/* @__PURE__ */ h(C, {
|
|
84
85
|
"aria-label": "Filter by pipeline",
|
|
85
86
|
className: "w-56",
|
|
86
|
-
children: /* @__PURE__ */
|
|
87
|
-
}), /* @__PURE__ */
|
|
88
|
-
value:
|
|
87
|
+
children: /* @__PURE__ */ h(w, {})
|
|
88
|
+
}), /* @__PURE__ */ g(x, { children: [/* @__PURE__ */ h(S, {
|
|
89
|
+
value: M,
|
|
89
90
|
children: "All pipelines"
|
|
90
|
-
}),
|
|
91
|
+
}), U.map((e) => /* @__PURE__ */ h(S, {
|
|
91
92
|
value: e.id,
|
|
92
93
|
children: e.name
|
|
93
94
|
}, e.id))] })]
|
|
94
95
|
})]
|
|
95
96
|
})]
|
|
96
|
-
}),
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
/* @__PURE__ */
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
/* @__PURE__ */ h(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
children: H.get(e.pipelineId) ?? /* @__PURE__ */ m("span", {
|
|
131
|
-
className: "font-mono text-xs",
|
|
132
|
-
children: e.pipelineId
|
|
133
|
-
})
|
|
134
|
-
})
|
|
135
|
-
}),
|
|
136
|
-
/* @__PURE__ */ m(E, { children: /* @__PURE__ */ m(l, { status: e.status }) }),
|
|
137
|
-
/* @__PURE__ */ m(E, {
|
|
138
|
-
className: "whitespace-nowrap text-text-secondary",
|
|
139
|
-
children: M(e.startedAt)
|
|
140
|
-
}),
|
|
141
|
-
/* @__PURE__ */ m(E, {
|
|
142
|
-
className: "whitespace-nowrap text-text-secondary",
|
|
143
|
-
children: M(e.finishedAt)
|
|
144
|
-
}),
|
|
145
|
-
/* @__PURE__ */ m(E, {
|
|
146
|
-
className: "tabular-nums text-text-secondary",
|
|
147
|
-
children: N(e.durationMs)
|
|
148
|
-
}),
|
|
149
|
-
/* @__PURE__ */ m(E, {
|
|
150
|
-
className: "text-text-secondary",
|
|
151
|
-
children: e.triggeredBy || "—"
|
|
152
|
-
})
|
|
153
|
-
]
|
|
154
|
-
}, e.id)) })] })
|
|
155
|
-
}),
|
|
156
|
-
/* @__PURE__ */ m("ul", {
|
|
157
|
-
className: "space-y-3 md:hidden",
|
|
158
|
-
children: q.map((e) => /* @__PURE__ */ m("li", { children: /* @__PURE__ */ h("button", {
|
|
159
|
-
type: "button",
|
|
160
|
-
onClick: () => P(`runs/${e.id}`),
|
|
161
|
-
className: "flex w-full flex-col gap-2 rounded-card border border-border-default bg-bg-elevated p-4 text-left transition-colors hover:border-border-strong",
|
|
162
|
-
children: [
|
|
163
|
-
/* @__PURE__ */ h("div", {
|
|
164
|
-
className: "flex items-center justify-between gap-2",
|
|
165
|
-
children: [/* @__PURE__ */ h("span", {
|
|
97
|
+
}), (() => {
|
|
98
|
+
if (K) return /* @__PURE__ */ h(o, {
|
|
99
|
+
variant: "rows",
|
|
100
|
+
rows: 6,
|
|
101
|
+
label: I("cosmicintersection.pages.runs.loading", "Loading runs…")
|
|
102
|
+
});
|
|
103
|
+
if (q) return /* @__PURE__ */ h(a, {
|
|
104
|
+
message: I("cosmicintersection.pages.runs.error", "We could not load pipeline runs. Please try again."),
|
|
105
|
+
onRetry: () => void J()
|
|
106
|
+
});
|
|
107
|
+
if (Y.length === 0) {
|
|
108
|
+
let e = L === M && z === M;
|
|
109
|
+
return /* @__PURE__ */ h(i, {
|
|
110
|
+
icon: _,
|
|
111
|
+
title: e ? I("cosmicintersection.pages.runs.emptyTitle", "No runs yet") : I("cosmicintersection.pages.runs.emptyFilterTitle", "No runs match these filters"),
|
|
112
|
+
description: e ? I("cosmicintersection.pages.runs.emptyDescription", "Runs appear here once you start a pipeline. Each run tracks its steps, timings and metrics.") : I("cosmicintersection.pages.runs.emptyFilterDescription", "Try a different status or pipeline filter.")
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
return /* @__PURE__ */ g(m, { children: [
|
|
116
|
+
/* @__PURE__ */ h("div", {
|
|
117
|
+
className: "hidden rounded-card border border-border-default bg-bg-elevated md:block",
|
|
118
|
+
children: /* @__PURE__ */ g(T, { children: [/* @__PURE__ */ h(k, { children: /* @__PURE__ */ g(A, { children: [
|
|
119
|
+
/* @__PURE__ */ h(O, { children: "Run" }),
|
|
120
|
+
/* @__PURE__ */ h(O, { children: "Pipeline" }),
|
|
121
|
+
/* @__PURE__ */ h(O, { children: "Status" }),
|
|
122
|
+
/* @__PURE__ */ h(O, { children: "Started" }),
|
|
123
|
+
/* @__PURE__ */ h(O, { children: "Finished" }),
|
|
124
|
+
/* @__PURE__ */ h(O, { children: "Duration" }),
|
|
125
|
+
/* @__PURE__ */ h(O, { children: "Triggered by" })
|
|
126
|
+
] }) }), /* @__PURE__ */ h(E, { children: Y.map((e) => /* @__PURE__ */ g(A, {
|
|
127
|
+
className: "cursor-pointer",
|
|
128
|
+
onClick: () => F(`runs/${e.id}`),
|
|
129
|
+
children: [
|
|
130
|
+
/* @__PURE__ */ g(D, {
|
|
166
131
|
className: "font-medium text-text-primary",
|
|
167
132
|
children: ["#", e.runNumber]
|
|
168
|
-
}),
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
133
|
+
}),
|
|
134
|
+
/* @__PURE__ */ h(D, {
|
|
135
|
+
className: "text-text-secondary",
|
|
136
|
+
children: /* @__PURE__ */ h("span", {
|
|
137
|
+
className: "truncate",
|
|
138
|
+
children: W.get(e.pipelineId) ?? /* @__PURE__ */ h("span", {
|
|
139
|
+
className: "font-mono text-xs",
|
|
140
|
+
children: e.pipelineId
|
|
141
|
+
})
|
|
142
|
+
})
|
|
143
|
+
}),
|
|
144
|
+
/* @__PURE__ */ h(D, { children: /* @__PURE__ */ h(u, { status: e.status }) }),
|
|
145
|
+
/* @__PURE__ */ h(D, {
|
|
146
|
+
className: "whitespace-nowrap text-text-secondary",
|
|
147
|
+
children: N(e.startedAt)
|
|
148
|
+
}),
|
|
149
|
+
/* @__PURE__ */ h(D, {
|
|
150
|
+
className: "whitespace-nowrap text-text-secondary",
|
|
151
|
+
children: N(e.finishedAt)
|
|
152
|
+
}),
|
|
153
|
+
/* @__PURE__ */ h(D, {
|
|
154
|
+
className: "tabular-nums text-text-secondary",
|
|
155
|
+
children: P(e.durationMs)
|
|
156
|
+
}),
|
|
157
|
+
/* @__PURE__ */ h(D, {
|
|
158
|
+
className: "text-text-secondary",
|
|
159
|
+
children: e.triggeredBy || "—"
|
|
175
160
|
})
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
})]
|
|
199
|
-
}),
|
|
200
|
-
/* @__PURE__ */ h("div", {
|
|
201
|
-
className: "flex flex-col",
|
|
202
|
-
children: [/* @__PURE__ */ m("dt", {
|
|
203
|
-
className: "text-text-secondary",
|
|
204
|
-
children: "Finished"
|
|
205
|
-
}), /* @__PURE__ */ m("dd", {
|
|
206
|
-
className: "text-text-primary",
|
|
207
|
-
children: M(e.finishedAt)
|
|
208
|
-
})]
|
|
209
|
-
}),
|
|
210
|
-
/* @__PURE__ */ h("div", {
|
|
211
|
-
className: "flex flex-col",
|
|
212
|
-
children: [/* @__PURE__ */ m("dt", {
|
|
213
|
-
className: "text-text-secondary",
|
|
214
|
-
children: "Triggered by"
|
|
215
|
-
}), /* @__PURE__ */ m("dd", {
|
|
216
|
-
className: "text-text-primary",
|
|
217
|
-
children: e.triggeredBy || "—"
|
|
218
|
-
})]
|
|
161
|
+
]
|
|
162
|
+
}, e.id)) })] })
|
|
163
|
+
}),
|
|
164
|
+
/* @__PURE__ */ h("ul", {
|
|
165
|
+
className: "space-y-3 md:hidden",
|
|
166
|
+
children: Y.map((e) => /* @__PURE__ */ h("li", { children: /* @__PURE__ */ g("button", {
|
|
167
|
+
type: "button",
|
|
168
|
+
onClick: () => F(`runs/${e.id}`),
|
|
169
|
+
className: "flex w-full flex-col gap-2 rounded-card border border-border-default bg-bg-elevated p-4 text-left transition-colors hover:border-border-strong",
|
|
170
|
+
children: [
|
|
171
|
+
/* @__PURE__ */ g("div", {
|
|
172
|
+
className: "flex items-center justify-between gap-2",
|
|
173
|
+
children: [/* @__PURE__ */ g("span", {
|
|
174
|
+
className: "font-medium text-text-primary",
|
|
175
|
+
children: ["#", e.runNumber]
|
|
176
|
+
}), /* @__PURE__ */ h(u, { status: e.status })]
|
|
177
|
+
}),
|
|
178
|
+
/* @__PURE__ */ h("p", {
|
|
179
|
+
className: "truncate text-sm text-text-secondary",
|
|
180
|
+
children: W.get(e.pipelineId) ?? /* @__PURE__ */ h("span", {
|
|
181
|
+
className: "font-mono text-xs",
|
|
182
|
+
children: e.pipelineId
|
|
219
183
|
})
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
184
|
+
}),
|
|
185
|
+
/* @__PURE__ */ g("dl", {
|
|
186
|
+
className: "grid grid-cols-2 gap-x-3 gap-y-1 text-xs",
|
|
187
|
+
children: [
|
|
188
|
+
/* @__PURE__ */ g("div", {
|
|
189
|
+
className: "flex flex-col",
|
|
190
|
+
children: [/* @__PURE__ */ h("dt", {
|
|
191
|
+
className: "text-text-secondary",
|
|
192
|
+
children: "Started"
|
|
193
|
+
}), /* @__PURE__ */ h("dd", {
|
|
194
|
+
className: "text-text-primary",
|
|
195
|
+
children: N(e.startedAt)
|
|
196
|
+
})]
|
|
197
|
+
}),
|
|
198
|
+
/* @__PURE__ */ g("div", {
|
|
199
|
+
className: "flex flex-col",
|
|
200
|
+
children: [/* @__PURE__ */ h("dt", {
|
|
201
|
+
className: "text-text-secondary",
|
|
202
|
+
children: "Duration"
|
|
203
|
+
}), /* @__PURE__ */ h("dd", {
|
|
204
|
+
className: "tabular-nums text-text-primary",
|
|
205
|
+
children: P(e.durationMs)
|
|
206
|
+
})]
|
|
207
|
+
}),
|
|
208
|
+
/* @__PURE__ */ g("div", {
|
|
209
|
+
className: "flex flex-col",
|
|
210
|
+
children: [/* @__PURE__ */ h("dt", {
|
|
211
|
+
className: "text-text-secondary",
|
|
212
|
+
children: "Finished"
|
|
213
|
+
}), /* @__PURE__ */ h("dd", {
|
|
214
|
+
className: "text-text-primary",
|
|
215
|
+
children: N(e.finishedAt)
|
|
216
|
+
})]
|
|
217
|
+
}),
|
|
218
|
+
/* @__PURE__ */ g("div", {
|
|
219
|
+
className: "flex flex-col",
|
|
220
|
+
children: [/* @__PURE__ */ h("dt", {
|
|
221
|
+
className: "text-text-secondary",
|
|
222
|
+
children: "Triggered by"
|
|
223
|
+
}), /* @__PURE__ */ h("dd", {
|
|
224
|
+
className: "text-text-primary",
|
|
225
|
+
children: e.triggeredBy || "—"
|
|
226
|
+
})]
|
|
227
|
+
})
|
|
228
|
+
]
|
|
229
|
+
})
|
|
230
|
+
]
|
|
231
|
+
}) }, e.id))
|
|
232
|
+
}),
|
|
233
|
+
/* @__PURE__ */ h(c, {
|
|
234
|
+
offset: V.offset,
|
|
235
|
+
limit: V.limit,
|
|
236
|
+
loadedCount: Y.length,
|
|
237
|
+
hasMore: X?.hasMore ?? !1,
|
|
238
|
+
onPrev: V.prevPage,
|
|
239
|
+
onNext: V.nextPage,
|
|
240
|
+
itemLabel: I("cosmicintersection.pages.runs.itemLabel", "runs"),
|
|
241
|
+
loading: K
|
|
242
|
+
})
|
|
243
|
+
] });
|
|
244
|
+
})()]
|
|
236
245
|
})
|
|
237
246
|
});
|
|
238
247
|
}
|
|
239
248
|
//#endregion
|
|
240
|
-
export {
|
|
249
|
+
export { F as default };
|
|
241
250
|
|
|
242
251
|
//# sourceMappingURL=RunsPage.js.map
|
|
@@ -1 +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 {/* Desktop: table. */}\n <div className=\"hidden rounded-card border border-border-default bg-bg-elevated md:block\">\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 <TableHead>Triggered by</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 <TableCell className=\"text-text-secondary\">{run.triggeredBy || '—'}</TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n\n {/* Mobile: stacked cards. */}\n <ul className=\"space-y-3 md:hidden\">\n {runs.map((run) => (\n <li key={run.id}>\n <button\n type=\"button\"\n onClick={() => navigate(`runs/${run.id}`)}\n className=\"flex w-full flex-col gap-2 rounded-card border border-border-default bg-bg-elevated p-4 text-left transition-colors hover:border-border-strong\"\n >\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"font-medium text-text-primary\">#{run.runNumber}</span>\n <StatusBadge status={run.status} />\n </div>\n <p className=\"truncate text-sm text-text-secondary\">\n {pipelineNameById.get(run.pipelineId) ?? (\n <span className=\"font-mono text-xs\">{run.pipelineId}</span>\n )}\n </p>\n <dl className=\"grid grid-cols-2 gap-x-3 gap-y-1 text-xs\">\n <div className=\"flex flex-col\">\n <dt className=\"text-text-secondary\">Started</dt>\n <dd className=\"text-text-primary\">{formatDate(run.startedAt)}</dd>\n </div>\n <div className=\"flex flex-col\">\n <dt className=\"text-text-secondary\">Duration</dt>\n <dd className=\"tabular-nums text-text-primary\">\n {formatDuration(run.durationMs)}\n </dd>\n </div>\n <div className=\"flex flex-col\">\n <dt className=\"text-text-secondary\">Finished</dt>\n <dd className=\"text-text-primary\">{formatDate(run.finishedAt)}</dd>\n </div>\n <div className=\"flex flex-col\">\n <dt className=\"text-text-secondary\">Triggered by</dt>\n <dd className=\"text-text-primary\">{run.triggeredBy || '—'}</dd>\n </div>\n </dl>\n </button>\n </li>\n ))}\n </ul>\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":"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"}
|
|
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';\nimport { useTr } from '../../../shared/hooks/useTr';\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 tr = useTr();\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 (\n <LoadingState\n variant=\"rows\"\n rows={6}\n label={tr('cosmicintersection.pages.runs.loading', 'Loading runs…')}\n />\n );\n }\n if (error) {\n return (\n <ErrorState\n message={tr(\n 'cosmicintersection.pages.runs.error',\n 'We could not load pipeline runs. Please try again.'\n )}\n onRetry={() => void refetch()}\n />\n );\n }\n if (runs.length === 0) {\n const noFilters = status === ALL && pipelineId === ALL;\n return (\n <EmptyState\n icon={Activity}\n title={\n noFilters\n ? tr('cosmicintersection.pages.runs.emptyTitle', 'No runs yet')\n : tr('cosmicintersection.pages.runs.emptyFilterTitle', 'No runs match these filters')\n }\n description={\n noFilters\n ? tr(\n 'cosmicintersection.pages.runs.emptyDescription',\n 'Runs appear here once you start a pipeline. Each run tracks its steps, timings and metrics.'\n )\n : tr(\n 'cosmicintersection.pages.runs.emptyFilterDescription',\n 'Try a different status or pipeline filter.'\n )\n }\n />\n );\n }\n\n return (\n <>\n {/* Desktop: table. */}\n <div className=\"hidden rounded-card border border-border-default bg-bg-elevated md:block\">\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 <TableHead>Triggered by</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 <TableCell className=\"text-text-secondary\">{run.triggeredBy || '—'}</TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n\n {/* Mobile: stacked cards. */}\n <ul className=\"space-y-3 md:hidden\">\n {runs.map((run) => (\n <li key={run.id}>\n <button\n type=\"button\"\n onClick={() => navigate(`runs/${run.id}`)}\n className=\"flex w-full flex-col gap-2 rounded-card border border-border-default bg-bg-elevated p-4 text-left transition-colors hover:border-border-strong\"\n >\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"font-medium text-text-primary\">#{run.runNumber}</span>\n <StatusBadge status={run.status} />\n </div>\n <p className=\"truncate text-sm text-text-secondary\">\n {pipelineNameById.get(run.pipelineId) ?? (\n <span className=\"font-mono text-xs\">{run.pipelineId}</span>\n )}\n </p>\n <dl className=\"grid grid-cols-2 gap-x-3 gap-y-1 text-xs\">\n <div className=\"flex flex-col\">\n <dt className=\"text-text-secondary\">Started</dt>\n <dd className=\"text-text-primary\">{formatDate(run.startedAt)}</dd>\n </div>\n <div className=\"flex flex-col\">\n <dt className=\"text-text-secondary\">Duration</dt>\n <dd className=\"tabular-nums text-text-primary\">\n {formatDuration(run.durationMs)}\n </dd>\n </div>\n <div className=\"flex flex-col\">\n <dt className=\"text-text-secondary\">Finished</dt>\n <dd className=\"text-text-primary\">{formatDate(run.finishedAt)}</dd>\n </div>\n <div className=\"flex flex-col\">\n <dt className=\"text-text-secondary\">Triggered by</dt>\n <dd className=\"text-text-primary\">{run.triggeredBy || '—'}</dd>\n </div>\n </dl>\n </button>\n </li>\n ))}\n </ul>\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={tr('cosmicintersection.pages.runs.itemLabel', 'runs')}\n loading={loading}\n />\n </>\n );\n };\n\n return (\n <PageLayout\n title={tr('cosmicintersection.pages.runs.title', 'Runs')}\n description={tr(\n 'cosmicintersection.pages.runs.description',\n 'Every pipeline execution, with status, timings and outcomes.'\n )}\n actions={\n <Button type=\"button\" variant=\"outline\" onClick={() => navigate('pipelines')}>\n <Eye className=\"size-4\" />\n {tr('cosmicintersection.pages.runs.viewPipelines', '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":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SourcesPage.d.ts","sourceRoot":"","sources":["../../../../src/cosmicintersection/pages/sources/SourcesPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SourcesPage.d.ts","sourceRoot":"","sources":["../../../../src/cosmicintersection/pages/sources/SourcesPage.tsx"],"names":[],"mappings":"AAmGA,MAAM,CAAC,OAAO,UAAU,WAAW,4CA0YlC"}
|