@burdenoff/microfe-cosmicintersection 2026.512.1 → 2026.704.1
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 +102 -44
- package/dist/cosmicintersection/CosmicIntersectionRoutes.js.map +1 -1
- package/dist/cosmicintersection/api/cosmicApi.js +853 -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/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 +11 -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 +340 -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 +164 -0
- package/dist/cosmicintersection/pages/collections/CollectionDetailPage.js.map +1 -0
- package/dist/cosmicintersection/pages/collections/CollectionFormPage.js +117 -0
- package/dist/cosmicintersection/pages/collections/CollectionFormPage.js.map +1 -0
- package/dist/cosmicintersection/pages/collections/CollectionsPage.js +103 -0
- package/dist/cosmicintersection/pages/collections/CollectionsPage.js.map +1 -0
- package/dist/cosmicintersection/pages/dashboard/DashboardPage.js +244 -0
- package/dist/cosmicintersection/pages/dashboard/DashboardPage.js.map +1 -0
- package/dist/cosmicintersection/pages/datasets/DatasetDetailPage.js +460 -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 +393 -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 +368 -0
- package/dist/cosmicintersection/pages/releases/ReleasesPage.js.map +1 -0
- package/dist/cosmicintersection/pages/runs/RunDetailPage.js +375 -0
- package/dist/cosmicintersection/pages/runs/RunDetailPage.js.map +1 -0
- package/dist/cosmicintersection/pages/runs/RunsPage.js +180 -0
- package/dist/cosmicintersection/pages/runs/RunsPage.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 +217 -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/CosmicIntersectionRoot.d.ts +0 -5
- package/dist/cosmicintersection/CosmicIntersectionRoot.d.ts.map +0 -1
- package/dist/cosmicintersection/CosmicIntersectionRoutes.d.ts +0 -2
- package/dist/cosmicintersection/CosmicIntersectionRoutes.d.ts.map +0 -1
- package/dist/cosmicintersection/index.d.ts +0 -5
- package/dist/cosmicintersection/index.d.ts.map +0 -1
- package/dist/cosmicintersection/pages/AiDiscoveryPage.d.ts +0 -2
- package/dist/cosmicintersection/pages/AiDiscoveryPage.d.ts.map +0 -1
- package/dist/cosmicintersection/pages/AiDiscoveryPage.js +0 -363
- package/dist/cosmicintersection/pages/AiDiscoveryPage.js.map +0 -1
- package/dist/cosmicintersection/pages/DashboardPage.d.ts +0 -2
- package/dist/cosmicintersection/pages/DashboardPage.d.ts.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.d.ts +0 -2
- package/dist/cosmicintersection/pages/SpaceScienceCitizenPage.d.ts.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.d.ts +0 -2
- package/dist/cosmicintersection/pages/SpaceScienceDataPage.d.ts.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.d.ts +0 -2
- package/dist/cosmicintersection/pages/SpaceScienceDataPage1.d.ts.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.d.ts +0 -2
- package/dist/cosmicintersection/pages/SpaceScienceLearningPage.d.ts.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.d.ts +0 -2
- package/dist/cosmicintersection/pages/SpaceScienceLearningPage1.d.ts.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.d.ts +0 -2
- package/dist/cosmicintersection/pages/SpaceSciencePage.d.ts.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.d.ts +0 -2
- package/dist/cosmicintersection/pages/SpaceScienceResearchPage.d.ts.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.d.ts +0 -2
- package/dist/cosmicintersection/pages/SpaceScienceSimulationPage.d.ts.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.d.ts +0 -6
- package/dist/cosmicintersection/providers/CosmicIntersectionProvider.d.ts.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.d.ts +0 -18
- package/dist/cosmicintersection/store/cosmicintersectionStore.d.ts.map +0 -1
- package/dist/cosmicintersection/store/cosmicintersectionStore.js +0 -478
- package/dist/cosmicintersection/store/cosmicintersectionStore.js.map +0 -1
- package/dist/cosmicintersection/types/index.d.ts +0 -109
- package/dist/cosmicintersection/types/index.d.ts.map +0 -1
- package/dist/cosmicintersection/utils/cn.d.ts +0 -4
- package/dist/cosmicintersection/utils/cn.d.ts.map +0 -1
- package/dist/cosmicintersection/utils/i18n.d.ts +0 -6
- package/dist/cosmicintersection/utils/i18n.d.ts.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.d.ts +0 -2
- package/dist/cosmicintersection/utils/navigation.d.ts.map +0 -1
- package/dist/cosmicintersection/utils/navigation.js +0 -8
- package/dist/cosmicintersection/utils/navigation.js.map +0 -1
- package/dist/dev/main.d.ts +0 -2
- package/dist/dev/main.d.ts.map +0 -1
- package/dist/generated/global-operations.d.ts +0 -2
- package/dist/generated/global-operations.d.ts.map +0 -1
- package/dist/generated/global-types.d.ts +0 -18199
- package/dist/generated/global-types.d.ts.map +0 -1
- package/dist/generated/wspace-operations.d.ts +0 -2
- package/dist/generated/wspace-operations.d.ts.map +0 -1
- package/dist/generated/wspace-types.d.ts +0 -43046
- package/dist/generated/wspace-types.d.ts.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +0 -1
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
import { useCosmicIntersection as e } from "../../context/CosmicIntersectionContext.js";
|
|
2
|
+
import { notify as t } from "../../lib/toast.js";
|
|
3
|
+
import { useCosAnalysesQuery as n, useCosCompleteAnalysisMutation as r, useCosDatasetsQuery as i, useCosNotebooksQuery as a, useCosRunAnalysisMutation as o } from "../../api/cosmicApi.js";
|
|
4
|
+
import s from "../../components/ActionMenu.js";
|
|
5
|
+
import c from "../../components/EmptyState.js";
|
|
6
|
+
import l from "../../components/ErrorState.js";
|
|
7
|
+
import u, { useFileDownloadUrl as d } from "../../components/FileUploadField.js";
|
|
8
|
+
import f from "../../components/LoadingState.js";
|
|
9
|
+
import p from "../../components/PageLayout.js";
|
|
10
|
+
import m from "../../components/StatusBadge.js";
|
|
11
|
+
import "../../components/index.js";
|
|
12
|
+
import { useMemo as h, useState as g } from "react";
|
|
13
|
+
import { jsx as _, jsxs as v } from "react/jsx-runtime";
|
|
14
|
+
import { Beaker as y, Download as b, ExternalLink as x, Play as S, Sparkles as C } from "lucide-react";
|
|
15
|
+
import { Badge as w, Button as T, Dialog as E, DialogContent as D, DialogDescription as O, DialogFooter as k, DialogHeader as A, DialogTitle as j, Input as M, Label as N, Select as P, SelectContent as F, SelectItem as I, SelectTrigger as L, SelectValue as R, Switch as z, Table as B, TableBody as V, TableCell as H, TableHead as U, TableHeader as W, TableRow as G, Textarea as K } from "@burdenoff/fe-libs/ui";
|
|
16
|
+
//#region src/cosmicintersection/pages/analyses/AnalysesPage.tsx
|
|
17
|
+
var q = [
|
|
18
|
+
{
|
|
19
|
+
value: "PENDING",
|
|
20
|
+
label: "Pending"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
value: "RUNNING",
|
|
24
|
+
label: "Running"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
value: "COMPLETED",
|
|
28
|
+
label: "Completed"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
value: "FAILED",
|
|
32
|
+
label: "Failed"
|
|
33
|
+
}
|
|
34
|
+
], J = "ALL";
|
|
35
|
+
function Y(e) {
|
|
36
|
+
if (!e) return "—";
|
|
37
|
+
let t = new Date(e);
|
|
38
|
+
return Number.isNaN(t.getTime()) ? "—" : t.toLocaleString(void 0, {
|
|
39
|
+
year: "numeric",
|
|
40
|
+
month: "short",
|
|
41
|
+
day: "numeric",
|
|
42
|
+
hour: "2-digit",
|
|
43
|
+
minute: "2-digit"
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
function X({ fileId: e }) {
|
|
47
|
+
let { data: t, loading: n } = d(e), r = t?.getFileDownloadUrl ?? null;
|
|
48
|
+
return n ? /* @__PURE__ */ _("span", {
|
|
49
|
+
className: "text-xs text-text-secondary",
|
|
50
|
+
children: "Resolving…"
|
|
51
|
+
}) : r ? /* @__PURE__ */ v("a", {
|
|
52
|
+
href: r,
|
|
53
|
+
target: "_blank",
|
|
54
|
+
rel: "noopener noreferrer",
|
|
55
|
+
className: "inline-flex items-center gap-1 text-sm text-text-primary underline-offset-2 hover:underline",
|
|
56
|
+
children: [/* @__PURE__ */ _(b, {
|
|
57
|
+
className: "size-3.5",
|
|
58
|
+
"aria-hidden": "true"
|
|
59
|
+
}), "Download"]
|
|
60
|
+
}) : /* @__PURE__ */ v("span", {
|
|
61
|
+
className: "text-xs text-text-secondary",
|
|
62
|
+
children: ["File ", e]
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
function Z(e) {
|
|
66
|
+
let t = e.trim();
|
|
67
|
+
if (!t) return {
|
|
68
|
+
ok: !0,
|
|
69
|
+
value: void 0
|
|
70
|
+
};
|
|
71
|
+
try {
|
|
72
|
+
let e = JSON.parse(t);
|
|
73
|
+
return typeof e != "object" || !e || Array.isArray(e) ? {
|
|
74
|
+
ok: !1,
|
|
75
|
+
error: "Results must be a JSON object."
|
|
76
|
+
} : {
|
|
77
|
+
ok: !0,
|
|
78
|
+
value: e
|
|
79
|
+
};
|
|
80
|
+
} catch {
|
|
81
|
+
return {
|
|
82
|
+
ok: !1,
|
|
83
|
+
error: "Results are not valid JSON."
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function Q({ open: e, onOpenChange: n, onCompleted: r }) {
|
|
88
|
+
let [s, c] = g(""), [l, u] = g(""), [d, f] = g(!1), [p, m] = g("NOTEBOOK"), [h, y] = g(""), { data: b, loading: x } = a({ pagination: {
|
|
89
|
+
limit: 100,
|
|
90
|
+
offset: 0
|
|
91
|
+
} }), { data: C, loading: w } = i({ pagination: {
|
|
92
|
+
limit: 100,
|
|
93
|
+
offset: 0
|
|
94
|
+
} }), [B, { loading: V }] = o(), H = b?.cosListNotebooks.items ?? [], U = C?.cosListDatasets.items ?? [], W = () => {
|
|
95
|
+
c(""), u(""), f(!1), m("NOTEBOOK"), y("");
|
|
96
|
+
};
|
|
97
|
+
return /* @__PURE__ */ _(E, {
|
|
98
|
+
open: e,
|
|
99
|
+
onOpenChange: (e) => {
|
|
100
|
+
V || n(e);
|
|
101
|
+
},
|
|
102
|
+
children: /* @__PURE__ */ _(D, { children: /* @__PURE__ */ v("form", {
|
|
103
|
+
onSubmit: async (e) => {
|
|
104
|
+
e.preventDefault();
|
|
105
|
+
let i = s.trim();
|
|
106
|
+
if (!i) {
|
|
107
|
+
t.error("Title is required", "Give the analysis a descriptive title.");
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (!h) {
|
|
111
|
+
t.error("Select a source", `Choose a ${p === "NOTEBOOK" ? "notebook" : "dataset"} to analyse.`);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
let a = await B({ variables: { input: {
|
|
115
|
+
title: i,
|
|
116
|
+
method: l.trim() || void 0,
|
|
117
|
+
aiAssisted: d,
|
|
118
|
+
...p === "NOTEBOOK" ? { notebookId: h } : { datasetId: h }
|
|
119
|
+
} } });
|
|
120
|
+
a.error || !a.data?.cosRunAnalysis?.id || (t.success("Analysis started", `“${i}” is now running.`), W(), n(!1), r());
|
|
121
|
+
},
|
|
122
|
+
className: "space-y-4",
|
|
123
|
+
children: [
|
|
124
|
+
/* @__PURE__ */ v(A, { children: [/* @__PURE__ */ _(j, { children: "Run analysis" }), /* @__PURE__ */ _(O, { children: "Launch a new analysis against a notebook or a dataset. Exactly one source is required." })] }),
|
|
125
|
+
/* @__PURE__ */ v("div", {
|
|
126
|
+
className: "space-y-1.5",
|
|
127
|
+
children: [/* @__PURE__ */ _(N, {
|
|
128
|
+
htmlFor: "run-title",
|
|
129
|
+
children: "Title"
|
|
130
|
+
}), /* @__PURE__ */ _(M, {
|
|
131
|
+
id: "run-title",
|
|
132
|
+
value: s,
|
|
133
|
+
onChange: (e) => c(e.target.value),
|
|
134
|
+
placeholder: "e.g. Spectral line fitting",
|
|
135
|
+
required: !0
|
|
136
|
+
})]
|
|
137
|
+
}),
|
|
138
|
+
/* @__PURE__ */ v("div", {
|
|
139
|
+
className: "grid grid-cols-1 gap-4 sm:grid-cols-2",
|
|
140
|
+
children: [/* @__PURE__ */ v("div", {
|
|
141
|
+
className: "space-y-1.5",
|
|
142
|
+
children: [/* @__PURE__ */ _(N, {
|
|
143
|
+
htmlFor: "run-source-kind",
|
|
144
|
+
children: "Source type"
|
|
145
|
+
}), /* @__PURE__ */ v(P, {
|
|
146
|
+
value: p,
|
|
147
|
+
onValueChange: (e) => {
|
|
148
|
+
m(e), y("");
|
|
149
|
+
},
|
|
150
|
+
children: [/* @__PURE__ */ _(L, {
|
|
151
|
+
id: "run-source-kind",
|
|
152
|
+
"aria-label": "Source type",
|
|
153
|
+
children: /* @__PURE__ */ _(R, {})
|
|
154
|
+
}), /* @__PURE__ */ v(F, { children: [/* @__PURE__ */ _(I, {
|
|
155
|
+
value: "NOTEBOOK",
|
|
156
|
+
children: "Notebook"
|
|
157
|
+
}), /* @__PURE__ */ _(I, {
|
|
158
|
+
value: "DATASET",
|
|
159
|
+
children: "Dataset"
|
|
160
|
+
})] })]
|
|
161
|
+
})]
|
|
162
|
+
}), /* @__PURE__ */ v("div", {
|
|
163
|
+
className: "space-y-1.5",
|
|
164
|
+
children: [/* @__PURE__ */ _(N, {
|
|
165
|
+
htmlFor: "run-source-id",
|
|
166
|
+
children: p === "NOTEBOOK" ? "Notebook" : "Dataset"
|
|
167
|
+
}), /* @__PURE__ */ v(P, {
|
|
168
|
+
value: h,
|
|
169
|
+
onValueChange: (e) => y(e),
|
|
170
|
+
children: [/* @__PURE__ */ _(L, {
|
|
171
|
+
id: "run-source-id",
|
|
172
|
+
"aria-label": "Analysis source",
|
|
173
|
+
children: /* @__PURE__ */ _(R, { placeholder: (p === "NOTEBOOK" ? x : w) ? "Loading…" : `Select a ${p === "NOTEBOOK" ? "notebook" : "dataset"}` })
|
|
174
|
+
}), /* @__PURE__ */ _(F, { children: p === "NOTEBOOK" ? H.map((e) => /* @__PURE__ */ _(I, {
|
|
175
|
+
value: e.id,
|
|
176
|
+
children: e.title
|
|
177
|
+
}, e.id)) : U.map((e) => /* @__PURE__ */ _(I, {
|
|
178
|
+
value: e.id,
|
|
179
|
+
children: e.name
|
|
180
|
+
}, e.id)) })]
|
|
181
|
+
})]
|
|
182
|
+
})]
|
|
183
|
+
}),
|
|
184
|
+
/* @__PURE__ */ v("div", {
|
|
185
|
+
className: "space-y-1.5",
|
|
186
|
+
children: [/* @__PURE__ */ _(N, {
|
|
187
|
+
htmlFor: "run-method",
|
|
188
|
+
children: "Method"
|
|
189
|
+
}), /* @__PURE__ */ _(M, {
|
|
190
|
+
id: "run-method",
|
|
191
|
+
value: l,
|
|
192
|
+
onChange: (e) => u(e.target.value),
|
|
193
|
+
placeholder: "e.g. gaussian-fit"
|
|
194
|
+
})]
|
|
195
|
+
}),
|
|
196
|
+
/* @__PURE__ */ v("div", {
|
|
197
|
+
className: "flex items-center gap-3",
|
|
198
|
+
children: [/* @__PURE__ */ _(z, {
|
|
199
|
+
id: "run-ai",
|
|
200
|
+
checked: d,
|
|
201
|
+
onCheckedChange: (e) => f(e)
|
|
202
|
+
}), /* @__PURE__ */ _(N, {
|
|
203
|
+
htmlFor: "run-ai",
|
|
204
|
+
className: "cursor-pointer",
|
|
205
|
+
children: "AI-assisted analysis"
|
|
206
|
+
})]
|
|
207
|
+
}),
|
|
208
|
+
/* @__PURE__ */ v(k, { children: [/* @__PURE__ */ _(T, {
|
|
209
|
+
type: "button",
|
|
210
|
+
variant: "outline",
|
|
211
|
+
onClick: () => n(!1),
|
|
212
|
+
disabled: V,
|
|
213
|
+
children: "Cancel"
|
|
214
|
+
}), /* @__PURE__ */ v(T, {
|
|
215
|
+
type: "submit",
|
|
216
|
+
disabled: V,
|
|
217
|
+
children: [/* @__PURE__ */ _(S, { className: "size-4" }), V ? "Starting…" : "Run analysis"]
|
|
218
|
+
})] })
|
|
219
|
+
]
|
|
220
|
+
}) })
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
function $({ analysis: e, onOpenChange: n, onCompleted: i }) {
|
|
224
|
+
let [a, o] = g("COMPLETED"), [s, c] = g(""), [l, d] = g(""), [f, { loading: p }] = r();
|
|
225
|
+
return /* @__PURE__ */ _(E, {
|
|
226
|
+
open: !!e,
|
|
227
|
+
onOpenChange: (e) => {
|
|
228
|
+
p || n(e);
|
|
229
|
+
},
|
|
230
|
+
children: /* @__PURE__ */ _(D, { children: /* @__PURE__ */ v("form", {
|
|
231
|
+
onSubmit: async (r) => {
|
|
232
|
+
if (r.preventDefault(), !e) return;
|
|
233
|
+
let o = Z(s);
|
|
234
|
+
if (!o.ok) {
|
|
235
|
+
t.error("Invalid results", o.error);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
let c = await f({ variables: {
|
|
239
|
+
id: e.id,
|
|
240
|
+
status: a,
|
|
241
|
+
results: o.value,
|
|
242
|
+
outputFileId: l || void 0
|
|
243
|
+
} });
|
|
244
|
+
c.error || !c.data?.cosCompleteAnalysis || (t.success(a === "COMPLETED" ? "Analysis completed" : "Analysis marked failed", `“${e.title}” was updated.`), n(!1), i());
|
|
245
|
+
},
|
|
246
|
+
className: "space-y-4",
|
|
247
|
+
children: [
|
|
248
|
+
/* @__PURE__ */ v(A, { children: [/* @__PURE__ */ _(j, { children: "Complete analysis" }), /* @__PURE__ */ v(O, { children: [
|
|
249
|
+
"Record the outcome for ",
|
|
250
|
+
e ? `“${e.title}”` : "this analysis",
|
|
251
|
+
". Attach results or an output artifact if you have them."
|
|
252
|
+
] })] }),
|
|
253
|
+
/* @__PURE__ */ v("div", {
|
|
254
|
+
className: "space-y-1.5",
|
|
255
|
+
children: [/* @__PURE__ */ _(N, {
|
|
256
|
+
htmlFor: "complete-status",
|
|
257
|
+
children: "Outcome"
|
|
258
|
+
}), /* @__PURE__ */ v(P, {
|
|
259
|
+
value: a,
|
|
260
|
+
onValueChange: (e) => o(e),
|
|
261
|
+
children: [/* @__PURE__ */ _(L, {
|
|
262
|
+
id: "complete-status",
|
|
263
|
+
"aria-label": "Outcome",
|
|
264
|
+
children: /* @__PURE__ */ _(R, {})
|
|
265
|
+
}), /* @__PURE__ */ v(F, { children: [/* @__PURE__ */ _(I, {
|
|
266
|
+
value: "COMPLETED",
|
|
267
|
+
children: "Completed"
|
|
268
|
+
}), /* @__PURE__ */ _(I, {
|
|
269
|
+
value: "FAILED",
|
|
270
|
+
children: "Failed"
|
|
271
|
+
})] })]
|
|
272
|
+
})]
|
|
273
|
+
}),
|
|
274
|
+
/* @__PURE__ */ v("div", {
|
|
275
|
+
className: "space-y-1.5",
|
|
276
|
+
children: [
|
|
277
|
+
/* @__PURE__ */ _(N, {
|
|
278
|
+
htmlFor: "complete-results",
|
|
279
|
+
children: "Results (JSON)"
|
|
280
|
+
}),
|
|
281
|
+
/* @__PURE__ */ _(K, {
|
|
282
|
+
id: "complete-results",
|
|
283
|
+
value: s,
|
|
284
|
+
onChange: (e) => c(e.target.value),
|
|
285
|
+
rows: 4,
|
|
286
|
+
className: "font-mono text-xs",
|
|
287
|
+
placeholder: "{ \"snr\": 12.4, \"detections\": 3 }"
|
|
288
|
+
}),
|
|
289
|
+
/* @__PURE__ */ _("p", {
|
|
290
|
+
className: "text-xs text-text-secondary",
|
|
291
|
+
children: "Optional structured results as a JSON object."
|
|
292
|
+
})
|
|
293
|
+
]
|
|
294
|
+
}),
|
|
295
|
+
/* @__PURE__ */ _(u, {
|
|
296
|
+
value: l,
|
|
297
|
+
onChange: (e) => d(e),
|
|
298
|
+
label: "Attach output file",
|
|
299
|
+
hint: "Optional output artifact (plots, tables, exports). Stored in workspace files."
|
|
300
|
+
}),
|
|
301
|
+
/* @__PURE__ */ v(k, { children: [/* @__PURE__ */ _(T, {
|
|
302
|
+
type: "button",
|
|
303
|
+
variant: "outline",
|
|
304
|
+
onClick: () => n(!1),
|
|
305
|
+
disabled: p,
|
|
306
|
+
children: "Cancel"
|
|
307
|
+
}), /* @__PURE__ */ _(T, {
|
|
308
|
+
type: "submit",
|
|
309
|
+
disabled: p,
|
|
310
|
+
children: p ? "Saving…" : "Save outcome"
|
|
311
|
+
})] })
|
|
312
|
+
]
|
|
313
|
+
}) })
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
function ee() {
|
|
317
|
+
let { navigate: t } = e(), [r, o] = g(void 0), [u, d] = g(!1), [b, E] = g(null), { data: D, loading: O, error: k, refetch: A } = n({ status: r }), { data: j } = a({ pagination: {
|
|
318
|
+
limit: 100,
|
|
319
|
+
offset: 0
|
|
320
|
+
} }), { data: M } = i({ pagination: {
|
|
321
|
+
limit: 100,
|
|
322
|
+
offset: 0
|
|
323
|
+
} }), N = D?.cosListAnalyses ?? [], z = h(() => {
|
|
324
|
+
let e = /* @__PURE__ */ new Map();
|
|
325
|
+
for (let t of j?.cosListNotebooks.items ?? []) e.set(t.id, t.title);
|
|
326
|
+
return e;
|
|
327
|
+
}, [j]), K = h(() => {
|
|
328
|
+
let e = /* @__PURE__ */ new Map();
|
|
329
|
+
for (let t of M?.cosListDatasets.items ?? []) e.set(t.id, t.name);
|
|
330
|
+
return e;
|
|
331
|
+
}, [M]);
|
|
332
|
+
return /* @__PURE__ */ v(p, {
|
|
333
|
+
title: "Analyses",
|
|
334
|
+
description: "Analysis runs executed over notebooks and federated datasets.",
|
|
335
|
+
actions: /* @__PURE__ */ v(T, {
|
|
336
|
+
type: "button",
|
|
337
|
+
onClick: () => d(!0),
|
|
338
|
+
children: [/* @__PURE__ */ _(S, { className: "size-4" }), "Run analysis"]
|
|
339
|
+
}),
|
|
340
|
+
children: [
|
|
341
|
+
/* @__PURE__ */ v("div", {
|
|
342
|
+
className: "space-y-4",
|
|
343
|
+
children: [/* @__PURE__ */ v("div", {
|
|
344
|
+
className: "flex flex-wrap items-center gap-3",
|
|
345
|
+
children: [/* @__PURE__ */ _("label", {
|
|
346
|
+
className: "text-sm text-text-secondary",
|
|
347
|
+
htmlFor: "analysis-status-filter",
|
|
348
|
+
children: "Status"
|
|
349
|
+
}), /* @__PURE__ */ v(P, {
|
|
350
|
+
value: r ?? J,
|
|
351
|
+
onValueChange: (e) => o(e === J ? void 0 : e),
|
|
352
|
+
children: [/* @__PURE__ */ _(L, {
|
|
353
|
+
id: "analysis-status-filter",
|
|
354
|
+
className: "w-48",
|
|
355
|
+
"aria-label": "Filter by status",
|
|
356
|
+
children: /* @__PURE__ */ _(R, {})
|
|
357
|
+
}), /* @__PURE__ */ v(F, { children: [/* @__PURE__ */ _(I, {
|
|
358
|
+
value: J,
|
|
359
|
+
children: "All statuses"
|
|
360
|
+
}), q.map((e) => /* @__PURE__ */ _(I, {
|
|
361
|
+
value: e.value,
|
|
362
|
+
children: e.label
|
|
363
|
+
}, e.value))] })]
|
|
364
|
+
})]
|
|
365
|
+
}), O ? /* @__PURE__ */ _(f, {
|
|
366
|
+
variant: "rows",
|
|
367
|
+
rows: 6,
|
|
368
|
+
label: "Loading analyses…"
|
|
369
|
+
}) : k ? /* @__PURE__ */ _(l, {
|
|
370
|
+
message: "We could not load analyses. Please try again.",
|
|
371
|
+
onRetry: () => void A()
|
|
372
|
+
}) : N.length === 0 ? /* @__PURE__ */ _(c, {
|
|
373
|
+
icon: y,
|
|
374
|
+
title: r ? "No analyses match this filter." : "No analyses yet.",
|
|
375
|
+
description: r ? "Try a different status filter." : "Run an analysis against a notebook or dataset to see results here.",
|
|
376
|
+
action: r ? void 0 : /* @__PURE__ */ v(T, {
|
|
377
|
+
type: "button",
|
|
378
|
+
onClick: () => d(!0),
|
|
379
|
+
children: [/* @__PURE__ */ _(S, { className: "size-4" }), "Run analysis"]
|
|
380
|
+
})
|
|
381
|
+
}) : /* @__PURE__ */ _("div", {
|
|
382
|
+
className: "rounded-card border border-border-default bg-bg-elevated",
|
|
383
|
+
children: /* @__PURE__ */ v(B, { children: [/* @__PURE__ */ _(W, { children: /* @__PURE__ */ v(G, { children: [
|
|
384
|
+
/* @__PURE__ */ _(U, { children: "Title" }),
|
|
385
|
+
/* @__PURE__ */ _(U, { children: "Method" }),
|
|
386
|
+
/* @__PURE__ */ _(U, { children: "AI" }),
|
|
387
|
+
/* @__PURE__ */ _(U, { children: "Status" }),
|
|
388
|
+
/* @__PURE__ */ _(U, { children: "Source" }),
|
|
389
|
+
/* @__PURE__ */ _(U, { children: "Started" }),
|
|
390
|
+
/* @__PURE__ */ _(U, { children: "Finished" }),
|
|
391
|
+
/* @__PURE__ */ _(U, { children: "Output" }),
|
|
392
|
+
/* @__PURE__ */ _(U, {
|
|
393
|
+
className: "w-12 text-right",
|
|
394
|
+
children: "Actions"
|
|
395
|
+
})
|
|
396
|
+
] }) }), /* @__PURE__ */ _(V, { children: N.map((e) => {
|
|
397
|
+
let n = e.status === "PENDING" || e.status === "RUNNING", r = e.notebookId ? z.get(e.notebookId) ?? "Notebook" : e.datasetId ? K.get(e.datasetId) ?? "Dataset" : null, i = e.notebookId ? `notebooks/${e.notebookId}` : e.datasetId ? `datasets/${e.datasetId}` : null;
|
|
398
|
+
return /* @__PURE__ */ v(G, { children: [
|
|
399
|
+
/* @__PURE__ */ _(H, {
|
|
400
|
+
className: "font-medium text-text-primary",
|
|
401
|
+
children: e.title
|
|
402
|
+
}),
|
|
403
|
+
/* @__PURE__ */ _(H, {
|
|
404
|
+
className: "text-text-secondary",
|
|
405
|
+
children: e.method ?? "—"
|
|
406
|
+
}),
|
|
407
|
+
/* @__PURE__ */ _(H, { children: e.aiAssisted ? /* @__PURE__ */ v(w, {
|
|
408
|
+
variant: "secondary",
|
|
409
|
+
className: "gap-1",
|
|
410
|
+
children: [/* @__PURE__ */ _(C, {
|
|
411
|
+
className: "size-3",
|
|
412
|
+
"aria-hidden": "true"
|
|
413
|
+
}), "AI"]
|
|
414
|
+
}) : /* @__PURE__ */ _("span", {
|
|
415
|
+
className: "text-text-secondary",
|
|
416
|
+
children: "—"
|
|
417
|
+
}) }),
|
|
418
|
+
/* @__PURE__ */ _(H, { children: /* @__PURE__ */ _(m, { status: e.status }) }),
|
|
419
|
+
/* @__PURE__ */ _(H, { children: r && i ? /* @__PURE__ */ v("button", {
|
|
420
|
+
type: "button",
|
|
421
|
+
onClick: () => t(i),
|
|
422
|
+
className: "inline-flex max-w-[12rem] items-center gap-1 truncate text-sm text-text-primary underline-offset-2 hover:underline",
|
|
423
|
+
children: [/* @__PURE__ */ _(x, {
|
|
424
|
+
className: "size-3.5 shrink-0",
|
|
425
|
+
"aria-hidden": "true"
|
|
426
|
+
}), /* @__PURE__ */ _("span", {
|
|
427
|
+
className: "truncate",
|
|
428
|
+
children: r
|
|
429
|
+
})]
|
|
430
|
+
}) : /* @__PURE__ */ _("span", {
|
|
431
|
+
className: "text-text-secondary",
|
|
432
|
+
children: "—"
|
|
433
|
+
}) }),
|
|
434
|
+
/* @__PURE__ */ _(H, {
|
|
435
|
+
className: "whitespace-nowrap text-text-secondary",
|
|
436
|
+
children: Y(e.startedAt)
|
|
437
|
+
}),
|
|
438
|
+
/* @__PURE__ */ _(H, {
|
|
439
|
+
className: "whitespace-nowrap text-text-secondary",
|
|
440
|
+
children: Y(e.finishedAt)
|
|
441
|
+
}),
|
|
442
|
+
/* @__PURE__ */ _(H, { children: e.outputFile?.id ? /* @__PURE__ */ _(X, { fileId: e.outputFile.id }) : e.results && Object.keys(e.results).length > 0 ? /* @__PURE__ */ _("span", {
|
|
443
|
+
className: "text-xs text-text-secondary",
|
|
444
|
+
children: "Results recorded"
|
|
445
|
+
}) : /* @__PURE__ */ _("span", {
|
|
446
|
+
className: "text-text-secondary",
|
|
447
|
+
children: "—"
|
|
448
|
+
}) }),
|
|
449
|
+
/* @__PURE__ */ _(H, {
|
|
450
|
+
className: "text-right",
|
|
451
|
+
children: /* @__PURE__ */ _(s, {
|
|
452
|
+
ariaLabel: `Actions for ${e.title}`,
|
|
453
|
+
onView: i ? () => t(i) : void 0,
|
|
454
|
+
extraItems: n ? [{
|
|
455
|
+
key: "complete",
|
|
456
|
+
label: "Complete…",
|
|
457
|
+
icon: y,
|
|
458
|
+
onSelect: () => E(e)
|
|
459
|
+
}] : []
|
|
460
|
+
})
|
|
461
|
+
})
|
|
462
|
+
] }, e.id);
|
|
463
|
+
}) })] })
|
|
464
|
+
})]
|
|
465
|
+
}),
|
|
466
|
+
/* @__PURE__ */ _(Q, {
|
|
467
|
+
open: u,
|
|
468
|
+
onOpenChange: d,
|
|
469
|
+
onCompleted: () => void A()
|
|
470
|
+
}),
|
|
471
|
+
/* @__PURE__ */ _($, {
|
|
472
|
+
analysis: b,
|
|
473
|
+
onOpenChange: (e) => {
|
|
474
|
+
e || E(null);
|
|
475
|
+
},
|
|
476
|
+
onCompleted: () => void A()
|
|
477
|
+
}, b?.id ?? "none")
|
|
478
|
+
]
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
//#endregion
|
|
482
|
+
export { ee as default };
|
|
483
|
+
|
|
484
|
+
//# sourceMappingURL=AnalysesPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnalysesPage.js","names":[],"sources":["../../../../src/cosmicintersection/pages/analyses/AnalysesPage.tsx"],"sourcesContent":["/**\n * AnalysesPage — every analysis run across the workspace.\n *\n * Lists `cosListAnalyses` (a plain array, no pagination) with a status filter.\n * A \"Run analysis\" dialog launches a new `cosRunAnalysis` against EITHER a\n * notebook OR a dataset (the schema requires one), chosen via a small selector.\n * In-flight (PENDING / RUNNING) analyses expose a \"Complete\" action that calls\n * `cosCompleteAnalysis` with COMPLETED | FAILED, optional results JSON, and an\n * optional output artifact uploaded through FileUploadField. All values are read\n * from the backend — nothing is fabricated.\n */\nimport { useMemo, useState, type FormEvent } from 'react';\nimport { Beaker, Download, ExternalLink, Play, Sparkles } from 'lucide-react';\nimport {\n Badge,\n Button,\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 Switch,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\n\nimport {\n useCosAnalysesQuery,\n useCosCompleteAnalysisMutation,\n useCosDatasetsQuery,\n useCosNotebooksQuery,\n useCosRunAnalysisMutation,\n type CosAnalysis,\n type CosAnalysisStatus,\n} from '../../api/cosmicApi';\nimport {\n ActionMenu,\n EmptyState,\n ErrorState,\n FileUploadField,\n LoadingState,\n PageLayout,\n StatusBadge,\n useFileDownloadUrl,\n} from '../../components';\nimport { useCosmicIntersection } from '../../context/CosmicIntersectionContext';\nimport { notify } from '../../lib/toast';\n\nconst STATUS_OPTIONS: { value: CosAnalysisStatus; label: string }[] = [\n { value: 'PENDING', label: 'Pending' },\n { value: 'RUNNING', label: 'Running' },\n { value: 'COMPLETED', label: 'Completed' },\n { value: 'FAILED', label: 'Failed' },\n];\n\nconst ALL = 'ALL';\n\nfunction formatDateTime(value?: string | null): string {\n if (!value) {\n return '—';\n }\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) {\n return '—';\n }\n return date.toLocaleString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n}\n\n/** Presigned download link for an analysis output artifact. */\nfunction FileDownloadLink({ fileId }: { fileId: string }) {\n const { data, loading } = useFileDownloadUrl(fileId);\n const url = data?.getFileDownloadUrl ?? null;\n if (loading) {\n return <span className=\"text-xs text-text-secondary\">Resolving…</span>;\n }\n if (!url) {\n return <span className=\"text-xs text-text-secondary\">File {fileId}</span>;\n }\n return (\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 text-sm text-text-primary underline-offset-2 hover:underline\"\n >\n <Download className=\"size-3.5\" aria-hidden=\"true\" />\n Download\n </a>\n );\n}\n\n/** Parse optional results JSON; blank -> undefined, invalid -> error. */\nfunction parseResults(\n raw: string\n): { ok: true; value?: Record<string, unknown> } | { ok: false; error: string } {\n const trimmed = raw.trim();\n if (!trimmed) {\n return { ok: true, value: undefined };\n }\n try {\n const parsed: unknown = JSON.parse(trimmed);\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n return { ok: false, error: 'Results must be a JSON object.' };\n }\n return { ok: true, value: parsed as Record<string, unknown> };\n } catch {\n return { ok: false, error: 'Results are not valid JSON.' };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Run analysis dialog\n// ---------------------------------------------------------------------------\n\ntype RunSourceKind = 'NOTEBOOK' | 'DATASET';\n\ninterface RunDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onCompleted: () => void;\n}\n\nfunction RunAnalysisDialog({ open, onOpenChange, onCompleted }: RunDialogProps) {\n const [title, setTitle] = useState('');\n const [method, setMethod] = useState('');\n const [aiAssisted, setAiAssisted] = useState(false);\n const [sourceKind, setSourceKind] = useState<RunSourceKind>('NOTEBOOK');\n const [sourceId, setSourceId] = useState('');\n\n const { data: notebooksData, loading: notebooksLoading } = useCosNotebooksQuery({\n pagination: { limit: 100, offset: 0 },\n });\n const { data: datasetsData, loading: datasetsLoading } = useCosDatasetsQuery({\n pagination: { limit: 100, offset: 0 },\n });\n const [runAnalysis, { loading }] = useCosRunAnalysisMutation();\n\n const notebooks = notebooksData?.cosListNotebooks.items ?? [];\n const datasets = datasetsData?.cosListDatasets.items ?? [];\n\n const reset = () => {\n setTitle('');\n setMethod('');\n setAiAssisted(false);\n setSourceKind('NOTEBOOK');\n setSourceId('');\n };\n\n const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n const trimmed = title.trim();\n if (!trimmed) {\n notify.error('Title is required', 'Give the analysis a descriptive title.');\n return;\n }\n if (!sourceId) {\n notify.error(\n 'Select a source',\n `Choose a ${sourceKind === 'NOTEBOOK' ? 'notebook' : 'dataset'} to analyse.`\n );\n return;\n }\n const response = await runAnalysis({\n variables: {\n input: {\n title: trimmed,\n method: method.trim() || undefined,\n aiAssisted,\n ...(sourceKind === 'NOTEBOOK' ? { notebookId: sourceId } : { datasetId: sourceId }),\n },\n },\n });\n if (response.error || !response.data?.cosRunAnalysis?.id) {\n return;\n }\n notify.success('Analysis started', `“${trimmed}” is now running.`);\n reset();\n onOpenChange(false);\n onCompleted();\n };\n\n const sourceLoading = sourceKind === 'NOTEBOOK' ? notebooksLoading : datasetsLoading;\n\n return (\n <Dialog\n open={open}\n onOpenChange={(next) => {\n if (!loading) {\n onOpenChange(next);\n }\n }}\n >\n <DialogContent>\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n <DialogHeader>\n <DialogTitle>Run analysis</DialogTitle>\n <DialogDescription>\n Launch a new analysis against a notebook or a dataset. Exactly one source is required.\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"run-title\">Title</Label>\n <Input\n id=\"run-title\"\n value={title}\n onChange={(event) => setTitle(event.target.value)}\n placeholder=\"e.g. Spectral line fitting\"\n required\n />\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"run-source-kind\">Source type</Label>\n <Select\n value={sourceKind}\n onValueChange={(value) => {\n setSourceKind(value as RunSourceKind);\n setSourceId('');\n }}\n >\n <SelectTrigger id=\"run-source-kind\" aria-label=\"Source type\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"NOTEBOOK\">Notebook</SelectItem>\n <SelectItem value=\"DATASET\">Dataset</SelectItem>\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"run-source-id\">\n {sourceKind === 'NOTEBOOK' ? 'Notebook' : 'Dataset'}\n </Label>\n <Select value={sourceId} onValueChange={(value) => setSourceId(value)}>\n <SelectTrigger id=\"run-source-id\" aria-label=\"Analysis source\">\n <SelectValue\n placeholder={\n sourceLoading\n ? 'Loading…'\n : `Select a ${sourceKind === 'NOTEBOOK' ? 'notebook' : 'dataset'}`\n }\n />\n </SelectTrigger>\n <SelectContent>\n {sourceKind === 'NOTEBOOK'\n ? notebooks.map((notebook) => (\n <SelectItem key={notebook.id} value={notebook.id}>\n {notebook.title}\n </SelectItem>\n ))\n : datasets.map((dataset) => (\n <SelectItem key={dataset.id} value={dataset.id}>\n {dataset.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"run-method\">Method</Label>\n <Input\n id=\"run-method\"\n value={method}\n onChange={(event) => setMethod(event.target.value)}\n placeholder=\"e.g. gaussian-fit\"\n />\n </div>\n\n <div className=\"flex items-center gap-3\">\n <Switch\n id=\"run-ai\"\n checked={aiAssisted}\n onCheckedChange={(checked) => setAiAssisted(checked)}\n />\n <Label htmlFor=\"run-ai\" className=\"cursor-pointer\">\n AI-assisted analysis\n </Label>\n </div>\n\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => onOpenChange(false)}\n disabled={loading}\n >\n Cancel\n </Button>\n <Button type=\"submit\" disabled={loading}>\n <Play className=\"size-4\" />\n {loading ? 'Starting…' : 'Run analysis'}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Complete analysis dialog\n// ---------------------------------------------------------------------------\n\ninterface CompleteDialogProps {\n analysis: CosAnalysis | null;\n onOpenChange: (open: boolean) => void;\n onCompleted: () => void;\n}\n\nfunction CompleteAnalysisDialog({ analysis, onOpenChange, onCompleted }: CompleteDialogProps) {\n const [status, setStatus] = useState<'COMPLETED' | 'FAILED'>('COMPLETED');\n const [results, setResults] = useState('');\n const [outputFileId, setOutputFileId] = useState('');\n const [completeAnalysis, { loading }] = useCosCompleteAnalysisMutation();\n\n const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n if (!analysis) {\n return;\n }\n const parsed = parseResults(results);\n if (!parsed.ok) {\n notify.error('Invalid results', parsed.error);\n return;\n }\n const response = await completeAnalysis({\n variables: {\n id: analysis.id,\n status,\n results: parsed.value,\n outputFileId: outputFileId || undefined,\n },\n });\n if (response.error || !response.data?.cosCompleteAnalysis) {\n return;\n }\n notify.success(\n status === 'COMPLETED' ? 'Analysis completed' : 'Analysis marked failed',\n `“${analysis.title}” was updated.`\n );\n onOpenChange(false);\n onCompleted();\n };\n\n return (\n <Dialog\n open={Boolean(analysis)}\n onOpenChange={(next) => {\n if (!loading) {\n onOpenChange(next);\n }\n }}\n >\n <DialogContent>\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n <DialogHeader>\n <DialogTitle>Complete analysis</DialogTitle>\n <DialogDescription>\n Record the outcome for {analysis ? `“${analysis.title}”` : 'this analysis'}. Attach\n results or an output artifact if you have them.\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"complete-status\">Outcome</Label>\n <Select\n value={status}\n onValueChange={(value) => setStatus(value as 'COMPLETED' | 'FAILED')}\n >\n <SelectTrigger id=\"complete-status\" aria-label=\"Outcome\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"COMPLETED\">Completed</SelectItem>\n <SelectItem value=\"FAILED\">Failed</SelectItem>\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"complete-results\">Results (JSON)</Label>\n <Textarea\n id=\"complete-results\"\n value={results}\n onChange={(event) => setResults(event.target.value)}\n rows={4}\n className=\"font-mono text-xs\"\n placeholder='{ \"snr\": 12.4, \"detections\": 3 }'\n />\n <p className=\"text-xs text-text-secondary\">\n Optional structured results as a JSON object.\n </p>\n </div>\n\n <FileUploadField\n value={outputFileId}\n onChange={(fileId) => setOutputFileId(fileId)}\n label=\"Attach output file\"\n hint=\"Optional output artifact (plots, tables, exports). Stored in workspace files.\"\n />\n\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => onOpenChange(false)}\n disabled={loading}\n >\n Cancel\n </Button>\n <Button type=\"submit\" disabled={loading}>\n {loading ? 'Saving…' : 'Save outcome'}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Page\n// ---------------------------------------------------------------------------\n\nexport default function AnalysesPage() {\n const { navigate } = useCosmicIntersection();\n const [statusFilter, setStatusFilter] = useState<CosAnalysisStatus | undefined>(undefined);\n const [runOpen, setRunOpen] = useState(false);\n const [completing, setCompleting] = useState<CosAnalysis | null>(null);\n\n const { data, loading, error, refetch } = useCosAnalysesQuery({ status: statusFilter });\n const { data: notebooksData } = useCosNotebooksQuery({ pagination: { limit: 100, offset: 0 } });\n const { data: datasetsData } = useCosDatasetsQuery({ pagination: { limit: 100, offset: 0 } });\n\n const analyses = data?.cosListAnalyses ?? [];\n\n const notebookNames = useMemo(() => {\n const map = new Map<string, string>();\n for (const notebook of notebooksData?.cosListNotebooks.items ?? []) {\n map.set(notebook.id, notebook.title);\n }\n return map;\n }, [notebooksData]);\n\n const datasetNames = useMemo(() => {\n const map = new Map<string, string>();\n for (const dataset of datasetsData?.cosListDatasets.items ?? []) {\n map.set(dataset.id, dataset.name);\n }\n return map;\n }, [datasetsData]);\n\n const actions = (\n <Button type=\"button\" onClick={() => setRunOpen(true)}>\n <Play className=\"size-4\" />\n Run analysis\n </Button>\n );\n\n return (\n <PageLayout\n title=\"Analyses\"\n description=\"Analysis runs executed over notebooks and federated datasets.\"\n actions={actions}\n >\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <label className=\"text-sm text-text-secondary\" htmlFor=\"analysis-status-filter\">\n Status\n </label>\n <Select\n value={statusFilter ?? ALL}\n onValueChange={(value) =>\n setStatusFilter(value === ALL ? undefined : (value as CosAnalysisStatus))\n }\n >\n <SelectTrigger\n id=\"analysis-status-filter\"\n className=\"w-48\"\n aria-label=\"Filter by status\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All statuses</SelectItem>\n {STATUS_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {loading ? (\n <LoadingState variant=\"rows\" rows={6} label=\"Loading analyses…\" />\n ) : error ? (\n <ErrorState\n message=\"We could not load analyses. Please try again.\"\n onRetry={() => void refetch()}\n />\n ) : analyses.length === 0 ? (\n <EmptyState\n icon={Beaker}\n title={statusFilter ? 'No analyses match this filter.' : 'No analyses yet.'}\n description={\n statusFilter\n ? 'Try a different status filter.'\n : 'Run an analysis against a notebook or dataset to see results here.'\n }\n action={\n statusFilter ? undefined : (\n <Button type=\"button\" onClick={() => setRunOpen(true)}>\n <Play className=\"size-4\" />\n Run analysis\n </Button>\n )\n }\n />\n ) : (\n <div className=\"rounded-card border border-border-default bg-bg-elevated\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Title</TableHead>\n <TableHead>Method</TableHead>\n <TableHead>AI</TableHead>\n <TableHead>Status</TableHead>\n <TableHead>Source</TableHead>\n <TableHead>Started</TableHead>\n <TableHead>Finished</TableHead>\n <TableHead>Output</TableHead>\n <TableHead className=\"w-12 text-right\">Actions</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {analyses.map((analysis) => {\n const inFlight = analysis.status === 'PENDING' || analysis.status === 'RUNNING';\n const sourceLabel = analysis.notebookId\n ? (notebookNames.get(analysis.notebookId) ?? 'Notebook')\n : analysis.datasetId\n ? (datasetNames.get(analysis.datasetId) ?? 'Dataset')\n : null;\n const sourcePath = analysis.notebookId\n ? `notebooks/${analysis.notebookId}`\n : analysis.datasetId\n ? `datasets/${analysis.datasetId}`\n : null;\n return (\n <TableRow key={analysis.id}>\n <TableCell className=\"font-medium text-text-primary\">\n {analysis.title}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {analysis.method ?? '—'}\n </TableCell>\n <TableCell>\n {analysis.aiAssisted ? (\n <Badge variant=\"secondary\" className=\"gap-1\">\n <Sparkles className=\"size-3\" aria-hidden=\"true\" />\n AI\n </Badge>\n ) : (\n <span className=\"text-text-secondary\">—</span>\n )}\n </TableCell>\n <TableCell>\n <StatusBadge status={analysis.status} />\n </TableCell>\n <TableCell>\n {sourceLabel && sourcePath ? (\n <button\n type=\"button\"\n onClick={() => navigate(sourcePath)}\n className=\"inline-flex max-w-[12rem] items-center gap-1 truncate text-sm text-text-primary underline-offset-2 hover:underline\"\n >\n <ExternalLink className=\"size-3.5 shrink-0\" aria-hidden=\"true\" />\n <span className=\"truncate\">{sourceLabel}</span>\n </button>\n ) : (\n <span className=\"text-text-secondary\">—</span>\n )}\n </TableCell>\n <TableCell className=\"whitespace-nowrap text-text-secondary\">\n {formatDateTime(analysis.startedAt)}\n </TableCell>\n <TableCell className=\"whitespace-nowrap text-text-secondary\">\n {formatDateTime(analysis.finishedAt)}\n </TableCell>\n <TableCell>\n {analysis.outputFile?.id ? (\n <FileDownloadLink fileId={analysis.outputFile.id} />\n ) : analysis.results && Object.keys(analysis.results).length > 0 ? (\n <span className=\"text-xs text-text-secondary\">Results recorded</span>\n ) : (\n <span className=\"text-text-secondary\">—</span>\n )}\n </TableCell>\n <TableCell className=\"text-right\">\n <ActionMenu\n ariaLabel={`Actions for ${analysis.title}`}\n onView={sourcePath ? () => navigate(sourcePath) : undefined}\n extraItems={\n inFlight\n ? [\n {\n key: 'complete',\n label: 'Complete…',\n icon: Beaker,\n onSelect: () => setCompleting(analysis),\n },\n ]\n : []\n }\n />\n </TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </Table>\n </div>\n )}\n </div>\n\n <RunAnalysisDialog\n open={runOpen}\n onOpenChange={setRunOpen}\n onCompleted={() => void refetch()}\n />\n <CompleteAnalysisDialog\n key={completing?.id ?? 'none'}\n analysis={completing}\n onOpenChange={(open) => {\n if (!open) {\n setCompleting(null);\n }\n }}\n onCompleted={() => void refetch()}\n />\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|