@burdenoff/microfe-cosmicintersection 2026.704.2 → 2026.704.3

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.
Files changed (50) hide show
  1. package/dist/cosmicintersection/CosmicIntersectionRoutes.js +39 -27
  2. package/dist/cosmicintersection/CosmicIntersectionRoutes.js.map +1 -1
  3. package/dist/cosmicintersection/api/cosmicApi.js +6 -0
  4. package/dist/cosmicintersection/api/cosmicApi.js.map +1 -1
  5. package/dist/cosmicintersection/components/FacetPanel.js +66 -0
  6. package/dist/cosmicintersection/components/FacetPanel.js.map +1 -0
  7. package/dist/cosmicintersection/components/LineageGraph.js +388 -0
  8. package/dist/cosmicintersection/components/LineageGraph.js.map +1 -0
  9. package/dist/cosmicintersection/components/ResultsChart.js +329 -0
  10. package/dist/cosmicintersection/components/ResultsChart.js.map +1 -0
  11. package/dist/cosmicintersection/components/StepDAG.js +104 -0
  12. package/dist/cosmicintersection/components/StepDAG.js.map +1 -0
  13. package/dist/cosmicintersection/pages/access/AccessPage.js +207 -155
  14. package/dist/cosmicintersection/pages/access/AccessPage.js.map +1 -1
  15. package/dist/cosmicintersection/pages/analyses/AnalysesPage.js +325 -165
  16. package/dist/cosmicintersection/pages/analyses/AnalysesPage.js.map +1 -1
  17. package/dist/cosmicintersection/pages/collections/CollectionDetailPage.js +138 -93
  18. package/dist/cosmicintersection/pages/collections/CollectionDetailPage.js.map +1 -1
  19. package/dist/cosmicintersection/pages/collections/CollectionFormPage.js.map +1 -1
  20. package/dist/cosmicintersection/pages/dashboard/DashboardPage.js +26 -15
  21. package/dist/cosmicintersection/pages/dashboard/DashboardPage.js.map +1 -1
  22. package/dist/cosmicintersection/pages/datasets/DatasetDetailPage.js +345 -219
  23. package/dist/cosmicintersection/pages/datasets/DatasetDetailPage.js.map +1 -1
  24. package/dist/cosmicintersection/pages/datasets/DatasetsPage.js +321 -163
  25. package/dist/cosmicintersection/pages/datasets/DatasetsPage.js.map +1 -1
  26. package/dist/cosmicintersection/pages/discovery/DiscoveryPage.js +358 -0
  27. package/dist/cosmicintersection/pages/discovery/DiscoveryPage.js.map +1 -0
  28. package/dist/cosmicintersection/pages/lineage/LineagePage.js +171 -0
  29. package/dist/cosmicintersection/pages/lineage/LineagePage.js.map +1 -0
  30. package/dist/cosmicintersection/pages/notebooks/NotebookDetailPage.js +232 -162
  31. package/dist/cosmicintersection/pages/notebooks/NotebookDetailPage.js.map +1 -1
  32. package/dist/cosmicintersection/pages/notebooks/NotebooksPage.js +143 -82
  33. package/dist/cosmicintersection/pages/notebooks/NotebooksPage.js.map +1 -1
  34. package/dist/cosmicintersection/pages/pipelines/PipelineDetailPage.js +286 -142
  35. package/dist/cosmicintersection/pages/pipelines/PipelineDetailPage.js.map +1 -1
  36. package/dist/cosmicintersection/pages/pipelines/PipelineFormPage.js +305 -103
  37. package/dist/cosmicintersection/pages/pipelines/PipelineFormPage.js.map +1 -1
  38. package/dist/cosmicintersection/pages/pipelines/PipelinesPage.js +183 -79
  39. package/dist/cosmicintersection/pages/pipelines/PipelinesPage.js.map +1 -1
  40. package/dist/cosmicintersection/pages/releases/ReleasesPage.js +262 -170
  41. package/dist/cosmicintersection/pages/releases/ReleasesPage.js.map +1 -1
  42. package/dist/cosmicintersection/pages/runs/RunDetailPage.js +179 -136
  43. package/dist/cosmicintersection/pages/runs/RunDetailPage.js.map +1 -1
  44. package/dist/cosmicintersection/pages/runs/RunsPage.js +124 -47
  45. package/dist/cosmicintersection/pages/runs/RunsPage.js.map +1 -1
  46. package/dist/cosmicintersection/pages/sources/SourceDetailPage.js +114 -85
  47. package/dist/cosmicintersection/pages/sources/SourceDetailPage.js.map +1 -1
  48. package/dist/cosmicintersection/pages/sources/SourcesPage.js +263 -152
  49. package/dist/cosmicintersection/pages/sources/SourcesPage.js.map +1 -1
  50. package/package.json +1 -1
@@ -1,21 +1,21 @@
1
1
  import { useCosmicIntersection as e } from "../../context/CosmicIntersectionContext.js";
2
2
  import { notify as t } from "../../lib/toast.js";
3
- import { useCosArchiveSourceMutation as n, useCosMarkSourceSyncedMutation as r, useCosSourcesQuery as i } from "../../api/cosmicApi.js";
4
- import a from "../../components/ActionMenu.js";
5
- import o from "../../components/EmptyState.js";
6
- import s from "../../components/ErrorState.js";
7
- import c from "../../components/LoadingState.js";
8
- import l from "../../components/SafeLink.js";
9
- import u from "../../components/PageLayout.js";
10
- import d, { usePagination as f } from "../../components/Pagination.js";
11
- import p, { formatEnumLabel as m } from "../../components/StatusBadge.js";
3
+ import { useCosArchiveSourceMutation as n, useCosMarkSourceSyncedMutation as r, useCosSourcesQuery as ee } from "../../api/cosmicApi.js";
4
+ import i from "../../components/ActionMenu.js";
5
+ import a from "../../components/EmptyState.js";
6
+ import o from "../../components/ErrorState.js";
7
+ import s from "../../components/LoadingState.js";
8
+ import c from "../../components/SafeLink.js";
9
+ import l from "../../components/PageLayout.js";
10
+ import u, { usePagination as d } from "../../components/Pagination.js";
11
+ import f, { formatEnumLabel as p } from "../../components/StatusBadge.js";
12
12
  import "../../components/index.js";
13
- import { useMemo as h, useState as g } from "react";
14
- import { Fragment as _, jsx as v, jsxs as y } from "react/jsx-runtime";
15
- import { Plus as ee, Radio as b, RefreshCw as x } from "lucide-react";
16
- import { Badge as S, Button as C, Select as w, SelectContent as T, SelectItem as E, SelectTrigger as D, SelectValue as O, Table as k, TableBody as A, TableCell as j, TableHead as M, TableHeader as N, TableRow as P } from "@burdenoff/fe-libs/ui";
13
+ import { useMemo as m, useState as h } from "react";
14
+ import { Fragment as g, jsx as _, jsxs as v } from "react/jsx-runtime";
15
+ import { Archive as y, FileInput as b, FlaskConical as x, Plus as S, Radio as C, RadioTower as w, RefreshCw as T, Satellite as E, Telescope as D, Webhook as O } from "lucide-react";
16
+ import { Badge as k, Button as A, Select as j, SelectContent as M, SelectItem as N, SelectTrigger as P, SelectValue as F, Table as te, TableBody as ne, TableCell as I, TableHead as L, TableHeader as R, TableRow as z } from "@burdenoff/fe-libs/ui";
17
17
  //#region src/cosmicintersection/pages/sources/SourcesPage.tsx
18
- var F = "ALL", I = [
18
+ var B = "ALL", V = [
19
19
  "TELESCOPE",
20
20
  "SATELLITE",
21
21
  "GROUND_SENSOR",
@@ -24,15 +24,24 @@ var F = "ALL", I = [
24
24
  "STREAM",
25
25
  "FILE_DROP",
26
26
  "SIMULATION"
27
- ], L = [
27
+ ], H = [
28
28
  "CONFIGURING",
29
29
  "CONNECTED",
30
30
  "SYNCING",
31
31
  "DEGRADED",
32
32
  "ERROR",
33
33
  "DISABLED"
34
- ];
35
- function R(e) {
34
+ ], U = {
35
+ TELESCOPE: D,
36
+ SATELLITE: E,
37
+ GROUND_SENSOR: w,
38
+ ARCHIVE: y,
39
+ API: O,
40
+ STREAM: C,
41
+ FILE_DROP: b,
42
+ SIMULATION: x
43
+ };
44
+ function W(e) {
36
45
  if (!e) return "—";
37
46
  let t = new Date(e);
38
47
  return Number.isNaN(t.getTime()) ? "—" : t.toLocaleDateString(void 0, {
@@ -41,183 +50,285 @@ function R(e) {
41
50
  day: "numeric"
42
51
  });
43
52
  }
44
- function z() {
45
- let { navigate: z } = e(), [B, V] = g(F), [H, U] = g(F), W = f({
53
+ function G() {
54
+ let { navigate: y } = e(), [b, x] = h(B), [w, E] = h(B), D = d({
46
55
  pageSize: 20,
47
- resetKey: `${B}|${H}`
48
- }), { data: G, loading: K, error: q, refetch: J } = i({
49
- type: B === F ? void 0 : B,
50
- status: H === F ? void 0 : H,
56
+ resetKey: `${b}|${w}`
57
+ }), { data: O, loading: G, error: K, refetch: q } = ee({
58
+ type: b === B ? void 0 : b,
59
+ status: w === B ? void 0 : w,
51
60
  pagination: {
52
- limit: W.limit,
53
- offset: W.offset
61
+ limit: D.limit,
62
+ offset: D.offset
54
63
  }
55
- }), [Y] = r(), [X] = n(), Z = h(() => G?.cosListSources.items ?? [], [G]), Q = G?.cosListSources.pageInfo, te = async (e) => {
56
- (await Y({ variables: { id: e.id } })).data?.cosMarkSourceSynced && (t.success("Source marked synced", `“${e.name}” is now up to date.`), await J());
57
- }, ne = async (e) => {
58
- let n = await X({ variables: { id: e.id } });
64
+ }), [J] = r(), [Y] = n(), X = m(() => O?.cosListSources.items ?? [], [O]), re = O?.cosListSources.pageInfo, Z = async (e) => {
65
+ (await J({ variables: { id: e.id } })).data?.cosMarkSourceSynced && (t.success("Source marked synced", `“${e.name}” is now up to date.`), await q());
66
+ }, Q = async (e) => {
67
+ let n = await Y({ variables: { id: e.id } });
59
68
  if (n.error) throw Error(n.error.message);
60
69
  if (!n.data?.cosArchiveSource) throw t.error("Could not archive source", "The server did not confirm the change."), Error("Archive not confirmed");
61
- t.success("Source archived"), await J();
62
- }, $ = /* @__PURE__ */ y(C, {
70
+ t.success("Source archived"), await q();
71
+ }, $ = /* @__PURE__ */ v(A, {
63
72
  type: "button",
64
- onClick: () => z("sources/create"),
65
- children: [/* @__PURE__ */ v(ee, { className: "size-4" }), "New source"]
73
+ onClick: () => y("sources/create"),
74
+ children: [/* @__PURE__ */ _(S, { className: "size-4" }), "New source"]
66
75
  });
67
- return /* @__PURE__ */ v(u, {
76
+ return /* @__PURE__ */ _(l, {
68
77
  title: "Data sources",
69
78
  description: "Instruments, archives and feeds that supply raw data into your federation.",
70
79
  actions: $,
71
- children: /* @__PURE__ */ y("div", {
80
+ children: /* @__PURE__ */ v("div", {
72
81
  className: "space-y-4",
73
- children: [/* @__PURE__ */ y("div", {
82
+ children: [/* @__PURE__ */ v("div", {
74
83
  className: "flex flex-wrap items-center gap-3",
75
- children: [/* @__PURE__ */ v("div", {
84
+ children: [/* @__PURE__ */ _("div", {
76
85
  className: "w-full max-w-[14rem]",
77
- children: /* @__PURE__ */ y(w, {
78
- value: B,
79
- onValueChange: V,
80
- children: [/* @__PURE__ */ v(D, {
86
+ children: /* @__PURE__ */ v(j, {
87
+ value: b,
88
+ onValueChange: x,
89
+ children: [/* @__PURE__ */ _(P, {
81
90
  "aria-label": "Filter by type",
82
- children: /* @__PURE__ */ v(O, { placeholder: "All types" })
83
- }), /* @__PURE__ */ y(T, { children: [/* @__PURE__ */ v(E, {
84
- value: F,
91
+ children: /* @__PURE__ */ _(F, { placeholder: "All types" })
92
+ }), /* @__PURE__ */ v(M, { children: [/* @__PURE__ */ _(N, {
93
+ value: B,
85
94
  children: "All types"
86
- }), I.map((e) => /* @__PURE__ */ v(E, {
95
+ }), V.map((e) => /* @__PURE__ */ _(N, {
87
96
  value: e,
88
- children: m(e)
97
+ children: p(e)
89
98
  }, e))] })]
90
99
  })
91
- }), /* @__PURE__ */ v("div", {
100
+ }), /* @__PURE__ */ _("div", {
92
101
  className: "w-full max-w-[14rem]",
93
- children: /* @__PURE__ */ y(w, {
94
- value: H,
95
- onValueChange: U,
96
- children: [/* @__PURE__ */ v(D, {
102
+ children: /* @__PURE__ */ v(j, {
103
+ value: w,
104
+ onValueChange: E,
105
+ children: [/* @__PURE__ */ _(P, {
97
106
  "aria-label": "Filter by status",
98
- children: /* @__PURE__ */ v(O, { placeholder: "All statuses" })
99
- }), /* @__PURE__ */ y(T, { children: [/* @__PURE__ */ v(E, {
100
- value: F,
107
+ children: /* @__PURE__ */ _(F, { placeholder: "All statuses" })
108
+ }), /* @__PURE__ */ v(M, { children: [/* @__PURE__ */ _(N, {
109
+ value: B,
101
110
  children: "All statuses"
102
- }), L.map((e) => /* @__PURE__ */ v(E, {
111
+ }), H.map((e) => /* @__PURE__ */ _(N, {
103
112
  value: e,
104
- children: m(e)
113
+ children: p(e)
105
114
  }, e))] })]
106
115
  })
107
116
  })]
108
117
  }), (() => {
109
- if (K) return /* @__PURE__ */ v(c, {
118
+ if (G) return /* @__PURE__ */ _(s, {
110
119
  variant: "rows",
111
120
  rows: 6,
112
121
  label: "Loading sources…"
113
122
  });
114
- if (q) return /* @__PURE__ */ v(s, {
115
- message: q.message,
116
- onRetry: () => void J()
123
+ if (K) return /* @__PURE__ */ _(o, {
124
+ message: K.message,
125
+ onRetry: () => void q()
117
126
  });
118
- if (Z.length === 0) {
119
- let e = B !== F || H !== F;
120
- return /* @__PURE__ */ v(o, {
121
- icon: b,
127
+ if (X.length === 0) {
128
+ let e = b !== B || w !== B;
129
+ return /* @__PURE__ */ _(a, {
130
+ icon: C,
122
131
  title: e ? "No sources match these filters" : "No data sources yet",
123
132
  description: e ? "Try clearing the type or status filter to see more sources." : "Connect a telescope, satellite feed, archive or API to start ingesting scientific data.",
124
133
  action: e ? void 0 : $
125
134
  });
126
135
  }
127
- return /* @__PURE__ */ y(_, { children: [/* @__PURE__ */ v("div", {
128
- className: "overflow-hidden rounded-card border border-border-default bg-bg-elevated",
129
- children: /* @__PURE__ */ y(k, { children: [/* @__PURE__ */ v(N, { children: /* @__PURE__ */ y(P, { children: [
130
- /* @__PURE__ */ v(M, { children: "Name" }),
131
- /* @__PURE__ */ v(M, { children: "Type" }),
132
- /* @__PURE__ */ v(M, { children: "Status" }),
133
- /* @__PURE__ */ v(M, { children: "Endpoint" }),
134
- /* @__PURE__ */ v(M, { children: "Last synced" }),
135
- /* @__PURE__ */ v(M, { children: "Tags" }),
136
- /* @__PURE__ */ v(M, {
137
- className: "text-right",
138
- children: "Actions"
139
- })
140
- ] }) }), /* @__PURE__ */ v(A, { children: Z.map((e) => /* @__PURE__ */ y(P, {
141
- className: "cursor-pointer",
142
- onClick: () => z(`sources/${e.id}`),
143
- children: [
144
- /* @__PURE__ */ y(j, { children: [/* @__PURE__ */ v("div", {
145
- className: "font-medium text-text-primary",
146
- children: e.name
147
- }), e.description ? /* @__PURE__ */ v("div", {
148
- className: "mt-0.5 line-clamp-1 max-w-xs text-xs text-text-secondary",
149
- children: e.description
150
- }) : null] }),
151
- /* @__PURE__ */ v(j, { children: /* @__PURE__ */ v(S, {
152
- variant: "secondary",
153
- children: m(e.type)
154
- }) }),
155
- /* @__PURE__ */ v(j, { children: /* @__PURE__ */ v(p, { status: e.status }) }),
156
- /* @__PURE__ */ v(j, {
157
- className: "max-w-[16rem]",
158
- onClick: (e) => e.stopPropagation(),
159
- children: e.endpoint ? /* @__PURE__ */ v(l, {
160
- href: e.endpoint,
161
- className: "block truncate text-sm text-text-primary underline-offset-2 hover:underline",
162
- fallbackClassName: "block truncate text-sm text-text-secondary",
163
- children: e.endpoint
164
- }) : /* @__PURE__ */ v("span", {
165
- className: "text-sm text-text-secondary",
166
- children: "—"
167
- })
168
- }),
169
- /* @__PURE__ */ v(j, {
170
- className: "whitespace-nowrap text-sm text-text-secondary",
171
- children: R(e.lastSyncedAt)
172
- }),
173
- /* @__PURE__ */ v(j, { children: /* @__PURE__ */ y("div", {
174
- className: "flex max-w-[12rem] flex-wrap gap-1",
175
- children: [e.tags.length === 0 ? /* @__PURE__ */ v("span", {
176
- className: "text-xs text-text-secondary",
177
- children: "—"
178
- }) : e.tags.slice(0, 3).map((e) => /* @__PURE__ */ v(S, {
179
- variant: "outline",
180
- className: "text-xs",
181
- children: e
182
- }, e)), e.tags.length > 3 ? /* @__PURE__ */ y("span", {
183
- className: "text-xs text-text-secondary",
184
- children: ["+", e.tags.length - 3]
185
- }) : null]
186
- }) }),
187
- /* @__PURE__ */ v(j, {
136
+ return /* @__PURE__ */ v(g, { children: [
137
+ /* @__PURE__ */ _("div", {
138
+ className: "hidden overflow-hidden rounded-card border border-border-default bg-bg-elevated md:block",
139
+ children: /* @__PURE__ */ v(te, { children: [/* @__PURE__ */ _(R, { children: /* @__PURE__ */ v(z, { children: [
140
+ /* @__PURE__ */ _(L, { children: "Name" }),
141
+ /* @__PURE__ */ _(L, { children: "Type" }),
142
+ /* @__PURE__ */ _(L, { children: "Status" }),
143
+ /* @__PURE__ */ _(L, { children: "Endpoint" }),
144
+ /* @__PURE__ */ _(L, { children: "Last synced" }),
145
+ /* @__PURE__ */ _(L, { children: "Tags" }),
146
+ /* @__PURE__ */ _(L, {
188
147
  className: "text-right",
189
- children: /* @__PURE__ */ v(a, {
190
- ariaLabel: `Actions for ${e.name}`,
191
- entityName: e.name,
192
- onView: () => z(`sources/${e.id}`),
193
- onEdit: () => z(`sources/${e.id}/edit`),
194
- onDelete: () => ne(e),
195
- deleteLabel: "Archive source",
196
- extraItems: [{
197
- key: "mark-synced",
198
- label: "Mark synced",
199
- icon: x,
200
- onSelect: () => void te(e)
201
- }]
202
- })
148
+ children: "Actions"
203
149
  })
204
- ]
205
- }, e.id)) })] })
206
- }), /* @__PURE__ */ v(d, {
207
- offset: W.offset,
208
- limit: W.limit,
209
- loadedCount: Z.length,
210
- hasMore: Q?.hasMore ?? !1,
211
- onPrev: W.prevPage,
212
- onNext: W.nextPage,
213
- itemLabel: "sources",
214
- loading: K
215
- })] });
150
+ ] }) }), /* @__PURE__ */ _(ne, { children: X.map((e) => /* @__PURE__ */ v(z, {
151
+ className: "cursor-pointer",
152
+ onClick: () => y(`sources/${e.id}`),
153
+ children: [
154
+ /* @__PURE__ */ _(I, { children: /* @__PURE__ */ v("div", {
155
+ className: "flex items-start gap-2.5",
156
+ children: [/* @__PURE__ */ _("span", {
157
+ className: "mt-0.5 flex size-7 shrink-0 items-center justify-center rounded-button bg-bg-sunken text-text-secondary",
158
+ children: /* @__PURE__ */ _(U[e.type] ?? C, {
159
+ className: "size-4",
160
+ "aria-hidden": "true"
161
+ })
162
+ }), /* @__PURE__ */ v("div", {
163
+ className: "min-w-0",
164
+ children: [/* @__PURE__ */ _("div", {
165
+ className: "font-medium text-text-primary",
166
+ children: e.name
167
+ }), e.description ? /* @__PURE__ */ _("div", {
168
+ className: "mt-0.5 line-clamp-1 max-w-xs text-xs text-text-secondary",
169
+ children: e.description
170
+ }) : null]
171
+ })]
172
+ }) }),
173
+ /* @__PURE__ */ _(I, { children: /* @__PURE__ */ _(k, {
174
+ variant: "secondary",
175
+ children: p(e.type)
176
+ }) }),
177
+ /* @__PURE__ */ _(I, { children: /* @__PURE__ */ _(f, { status: e.status }) }),
178
+ /* @__PURE__ */ _(I, {
179
+ className: "max-w-[16rem]",
180
+ onClick: (e) => e.stopPropagation(),
181
+ children: e.endpoint ? /* @__PURE__ */ _(c, {
182
+ href: e.endpoint,
183
+ className: "block truncate text-sm text-text-primary underline-offset-2 hover:underline",
184
+ fallbackClassName: "block truncate text-sm text-text-secondary",
185
+ children: e.endpoint
186
+ }) : /* @__PURE__ */ _("span", {
187
+ className: "text-sm text-text-secondary",
188
+ children: "—"
189
+ })
190
+ }),
191
+ /* @__PURE__ */ _(I, {
192
+ className: "whitespace-nowrap text-sm text-text-secondary",
193
+ children: W(e.lastSyncedAt)
194
+ }),
195
+ /* @__PURE__ */ _(I, { children: /* @__PURE__ */ v("div", {
196
+ className: "flex max-w-[12rem] flex-wrap gap-1",
197
+ children: [e.tags.length === 0 ? /* @__PURE__ */ _("span", {
198
+ className: "text-xs text-text-secondary",
199
+ children: "—"
200
+ }) : e.tags.slice(0, 3).map((e) => /* @__PURE__ */ _(k, {
201
+ variant: "outline",
202
+ className: "text-xs",
203
+ children: e
204
+ }, e)), e.tags.length > 3 ? /* @__PURE__ */ v("span", {
205
+ className: "text-xs text-text-secondary",
206
+ children: ["+", e.tags.length - 3]
207
+ }) : null]
208
+ }) }),
209
+ /* @__PURE__ */ _(I, {
210
+ className: "text-right",
211
+ children: /* @__PURE__ */ _(i, {
212
+ ariaLabel: `Actions for ${e.name}`,
213
+ entityName: e.name,
214
+ onView: () => y(`sources/${e.id}`),
215
+ onEdit: () => y(`sources/${e.id}/edit`),
216
+ onDelete: () => Q(e),
217
+ deleteLabel: "Archive source",
218
+ extraItems: [{
219
+ key: "mark-synced",
220
+ label: "Mark synced",
221
+ icon: T,
222
+ onSelect: () => void Z(e)
223
+ }]
224
+ })
225
+ })
226
+ ]
227
+ }, e.id)) })] })
228
+ }),
229
+ /* @__PURE__ */ _("ul", {
230
+ className: "space-y-3 md:hidden",
231
+ children: X.map((e) => {
232
+ let t = U[e.type] ?? C;
233
+ return /* @__PURE__ */ _("li", { children: /* @__PURE__ */ v("div", {
234
+ role: "button",
235
+ tabIndex: 0,
236
+ "aria-label": `Open ${e.name}`,
237
+ onClick: () => y(`sources/${e.id}`),
238
+ onKeyDown: (t) => {
239
+ (t.key === "Enter" || t.key === " ") && (t.preventDefault(), y(`sources/${e.id}`));
240
+ },
241
+ className: "flex flex-col gap-3 rounded-card border border-border-default bg-bg-elevated p-4 outline-none transition-colors hover:bg-bg-sunken focus-visible:ring-2 focus-visible:ring-border-focus",
242
+ children: [
243
+ /* @__PURE__ */ v("div", {
244
+ className: "flex items-start justify-between gap-3",
245
+ children: [/* @__PURE__ */ v("div", {
246
+ className: "flex min-w-0 items-start gap-2.5",
247
+ children: [/* @__PURE__ */ _("span", {
248
+ className: "mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-button bg-bg-sunken text-text-secondary",
249
+ children: /* @__PURE__ */ _(t, {
250
+ className: "size-4",
251
+ "aria-hidden": "true"
252
+ })
253
+ }), /* @__PURE__ */ v("div", {
254
+ className: "min-w-0",
255
+ children: [/* @__PURE__ */ _("p", {
256
+ className: "font-medium text-text-primary",
257
+ children: e.name
258
+ }), e.description ? /* @__PURE__ */ _("p", {
259
+ className: "mt-0.5 line-clamp-2 text-xs text-text-secondary",
260
+ children: e.description
261
+ }) : null]
262
+ })]
263
+ }), /* @__PURE__ */ _("div", {
264
+ onClick: (e) => e.stopPropagation(),
265
+ children: /* @__PURE__ */ _(i, {
266
+ ariaLabel: `Actions for ${e.name}`,
267
+ entityName: e.name,
268
+ onView: () => y(`sources/${e.id}`),
269
+ onEdit: () => y(`sources/${e.id}/edit`),
270
+ onDelete: () => Q(e),
271
+ deleteLabel: "Archive source",
272
+ extraItems: [{
273
+ key: "mark-synced",
274
+ label: "Mark synced",
275
+ icon: T,
276
+ onSelect: () => void Z(e)
277
+ }]
278
+ })
279
+ })]
280
+ }),
281
+ /* @__PURE__ */ v("div", {
282
+ className: "flex flex-wrap items-center gap-1.5",
283
+ children: [/* @__PURE__ */ _(k, {
284
+ variant: "secondary",
285
+ children: p(e.type)
286
+ }), /* @__PURE__ */ _(f, { status: e.status })]
287
+ }),
288
+ e.endpoint ? /* @__PURE__ */ _("div", {
289
+ onClick: (e) => e.stopPropagation(),
290
+ children: /* @__PURE__ */ _(c, {
291
+ href: e.endpoint,
292
+ className: "block truncate text-sm text-text-primary underline-offset-2 hover:underline",
293
+ fallbackClassName: "block truncate text-sm text-text-secondary",
294
+ children: e.endpoint
295
+ })
296
+ }) : null,
297
+ /* @__PURE__ */ v("div", {
298
+ className: "flex items-center justify-between gap-2 text-xs text-text-secondary",
299
+ children: [/* @__PURE__ */ _("span", { children: "Last synced" }), /* @__PURE__ */ _("span", { children: W(e.lastSyncedAt) })]
300
+ }),
301
+ e.tags.length > 0 ? /* @__PURE__ */ v("div", {
302
+ className: "flex flex-wrap gap-1",
303
+ children: [e.tags.slice(0, 4).map((e) => /* @__PURE__ */ _(k, {
304
+ variant: "outline",
305
+ className: "text-xs",
306
+ children: e
307
+ }, e)), e.tags.length > 4 ? /* @__PURE__ */ v("span", {
308
+ className: "text-xs text-text-secondary",
309
+ children: ["+", e.tags.length - 4]
310
+ }) : null]
311
+ }) : null
312
+ ]
313
+ }) }, e.id);
314
+ })
315
+ }),
316
+ /* @__PURE__ */ _(u, {
317
+ offset: D.offset,
318
+ limit: D.limit,
319
+ loadedCount: X.length,
320
+ hasMore: re?.hasMore ?? !1,
321
+ onPrev: D.prevPage,
322
+ onNext: D.nextPage,
323
+ itemLabel: "sources",
324
+ loading: G
325
+ })
326
+ ] });
216
327
  })()]
217
328
  })
218
329
  });
219
330
  }
220
331
  //#endregion
221
- export { z as default };
332
+ export { G as default };
222
333
 
223
334
  //# sourceMappingURL=SourcesPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SourcesPage.js","names":[],"sources":["../../../../src/cosmicintersection/pages/sources/SourcesPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { Plus, RefreshCw, Radio } from 'lucide-react';\nimport {\n Badge,\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 {\n useCosArchiveSourceMutation,\n useCosMarkSourceSyncedMutation,\n useCosSourcesQuery,\n type CosSource,\n type CosSourceStatus,\n type CosSourceType,\n} from '../../api/cosmicApi';\nimport {\n ActionMenu,\n EmptyState,\n ErrorState,\n LoadingState,\n PageLayout,\n Pagination,\n SafeLink,\n StatusBadge,\n formatEnumLabel,\n usePagination,\n} from '../../components';\nimport { useCosmicIntersection } from '../../context/CosmicIntersectionContext';\nimport { notify } from '../../lib/toast';\n\nconst ALL = 'ALL';\n\nconst SOURCE_TYPES: CosSourceType[] = [\n 'TELESCOPE',\n 'SATELLITE',\n 'GROUND_SENSOR',\n 'ARCHIVE',\n 'API',\n 'STREAM',\n 'FILE_DROP',\n 'SIMULATION',\n];\n\nconst SOURCE_STATUSES: CosSourceStatus[] = [\n 'CONFIGURING',\n 'CONNECTED',\n 'SYNCING',\n 'DEGRADED',\n 'ERROR',\n 'DISABLED',\n];\n\nfunction formatDate(value?: string | null): string {\n if (!value) {\n return '—';\n }\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return '—';\n }\n return parsed.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });\n}\n\nexport default function SourcesPage() {\n const { navigate } = useCosmicIntersection();\n const [typeFilter, setTypeFilter] = useState<string>(ALL);\n const [statusFilter, setStatusFilter] = useState<string>(ALL);\n const pagination = usePagination({ pageSize: 20, resetKey: `${typeFilter}|${statusFilter}` });\n\n const { data, loading, error, refetch } = useCosSourcesQuery({\n type: typeFilter === ALL ? undefined : (typeFilter as CosSourceType),\n status: statusFilter === ALL ? undefined : (statusFilter as CosSourceStatus),\n pagination: { limit: pagination.limit, offset: pagination.offset },\n });\n\n const [markSynced] = useCosMarkSourceSyncedMutation();\n const [archiveSource] = useCosArchiveSourceMutation();\n\n const sources = useMemo(() => data?.cosListSources.items ?? [], [data]);\n const pageInfo = data?.cosListSources.pageInfo;\n\n const handleMarkSynced = async (source: CosSource) => {\n const response = await markSynced({ variables: { id: source.id } });\n if (response.data?.cosMarkSourceSynced) {\n notify.success('Source marked synced', `“${source.name}” is now up to date.`);\n await refetch();\n }\n };\n\n const handleArchive = async (source: CosSource) => {\n const response = await archiveSource({ variables: { id: source.id } });\n if (response.error) {\n throw new Error(response.error.message);\n }\n if (!response.data?.cosArchiveSource) {\n notify.error('Could not archive source', 'The server did not confirm the change.');\n throw new Error('Archive not confirmed');\n }\n notify.success('Source archived');\n await refetch();\n };\n\n const newButton = (\n <Button type=\"button\" onClick={() => navigate('sources/create')}>\n <Plus className=\"size-4\" />\n New source\n </Button>\n );\n\n const renderBody = () => {\n if (loading) {\n return <LoadingState variant=\"rows\" rows={6} label=\"Loading sources…\" />;\n }\n if (error) {\n return <ErrorState message={error.message} onRetry={() => void refetch()} />;\n }\n if (sources.length === 0) {\n const filtered = typeFilter !== ALL || statusFilter !== ALL;\n return (\n <EmptyState\n icon={Radio}\n title={filtered ? 'No sources match these filters' : 'No data sources yet'}\n description={\n filtered\n ? 'Try clearing the type or status filter to see more sources.'\n : 'Connect a telescope, satellite feed, archive or API to start ingesting scientific data.'\n }\n action={filtered ? undefined : newButton}\n />\n );\n }\n\n return (\n <>\n <div className=\"overflow-hidden rounded-card border border-border-default bg-bg-elevated\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Name</TableHead>\n <TableHead>Type</TableHead>\n <TableHead>Status</TableHead>\n <TableHead>Endpoint</TableHead>\n <TableHead>Last synced</TableHead>\n <TableHead>Tags</TableHead>\n <TableHead className=\"text-right\">Actions</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {sources.map((source) => (\n <TableRow\n key={source.id}\n className=\"cursor-pointer\"\n onClick={() => navigate(`sources/${source.id}`)}\n >\n <TableCell>\n <div className=\"font-medium text-text-primary\">{source.name}</div>\n {source.description ? (\n <div className=\"mt-0.5 line-clamp-1 max-w-xs text-xs text-text-secondary\">\n {source.description}\n </div>\n ) : null}\n </TableCell>\n <TableCell>\n <Badge variant=\"secondary\">{formatEnumLabel(source.type)}</Badge>\n </TableCell>\n <TableCell>\n <StatusBadge status={source.status} />\n </TableCell>\n <TableCell\n className=\"max-w-[16rem]\"\n onClick={(event) => event.stopPropagation()}\n >\n {source.endpoint ? (\n <SafeLink\n href={source.endpoint}\n className=\"block truncate text-sm text-text-primary underline-offset-2 hover:underline\"\n fallbackClassName=\"block truncate text-sm text-text-secondary\"\n >\n {source.endpoint}\n </SafeLink>\n ) : (\n <span className=\"text-sm text-text-secondary\">—</span>\n )}\n </TableCell>\n <TableCell className=\"whitespace-nowrap text-sm text-text-secondary\">\n {formatDate(source.lastSyncedAt)}\n </TableCell>\n <TableCell>\n <div className=\"flex max-w-[12rem] flex-wrap gap-1\">\n {source.tags.length === 0 ? (\n <span className=\"text-xs text-text-secondary\">—</span>\n ) : (\n source.tags.slice(0, 3).map((tag) => (\n <Badge key={tag} variant=\"outline\" className=\"text-xs\">\n {tag}\n </Badge>\n ))\n )}\n {source.tags.length > 3 ? (\n <span className=\"text-xs text-text-secondary\">\n +{source.tags.length - 3}\n </span>\n ) : null}\n </div>\n </TableCell>\n <TableCell className=\"text-right\">\n <ActionMenu\n ariaLabel={`Actions for ${source.name}`}\n entityName={source.name}\n onView={() => navigate(`sources/${source.id}`)}\n onEdit={() => navigate(`sources/${source.id}/edit`)}\n onDelete={() => handleArchive(source)}\n deleteLabel=\"Archive source\"\n extraItems={[\n {\n key: 'mark-synced',\n label: 'Mark synced',\n icon: RefreshCw,\n onSelect: () => void handleMarkSynced(source),\n },\n ]}\n />\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n\n <Pagination\n offset={pagination.offset}\n limit={pagination.limit}\n loadedCount={sources.length}\n hasMore={pageInfo?.hasMore ?? false}\n onPrev={pagination.prevPage}\n onNext={pagination.nextPage}\n itemLabel=\"sources\"\n loading={loading}\n />\n </>\n );\n };\n\n return (\n <PageLayout\n title=\"Data sources\"\n description=\"Instruments, archives and feeds that supply raw data into your federation.\"\n actions={newButton}\n >\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"w-full max-w-[14rem]\">\n <Select value={typeFilter} onValueChange={setTypeFilter}>\n <SelectTrigger aria-label=\"Filter by type\">\n <SelectValue placeholder=\"All types\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All types</SelectItem>\n {SOURCE_TYPES.map((type) => (\n <SelectItem key={type} value={type}>\n {formatEnumLabel(type)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"w-full max-w-[14rem]\">\n <Select value={statusFilter} onValueChange={setStatusFilter}>\n <SelectTrigger aria-label=\"Filter by status\">\n <SelectValue placeholder=\"All statuses\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All statuses</SelectItem>\n {SOURCE_STATUSES.map((status) => (\n <SelectItem key={status} value={status}>\n {formatEnumLabel(status)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n {renderBody()}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"SourcesPage.js","names":[],"sources":["../../../../src/cosmicintersection/pages/sources/SourcesPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n Archive,\n FileInput,\n FlaskConical,\n Plus,\n Radio,\n RadioTower,\n RefreshCw,\n Satellite,\n Telescope,\n Webhook,\n type LucideIcon,\n} from 'lucide-react';\nimport {\n Badge,\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 {\n useCosArchiveSourceMutation,\n useCosMarkSourceSyncedMutation,\n useCosSourcesQuery,\n type CosSource,\n type CosSourceStatus,\n type CosSourceType,\n} from '../../api/cosmicApi';\nimport {\n ActionMenu,\n EmptyState,\n ErrorState,\n LoadingState,\n PageLayout,\n Pagination,\n SafeLink,\n StatusBadge,\n formatEnumLabel,\n usePagination,\n} from '../../components';\nimport { useCosmicIntersection } from '../../context/CosmicIntersectionContext';\nimport { notify } from '../../lib/toast';\n\nconst ALL = 'ALL';\n\nconst SOURCE_TYPES: CosSourceType[] = [\n 'TELESCOPE',\n 'SATELLITE',\n 'GROUND_SENSOR',\n 'ARCHIVE',\n 'API',\n 'STREAM',\n 'FILE_DROP',\n 'SIMULATION',\n];\n\nconst SOURCE_STATUSES: CosSourceStatus[] = [\n 'CONFIGURING',\n 'CONNECTED',\n 'SYNCING',\n 'DEGRADED',\n 'ERROR',\n 'DISABLED',\n];\n\n/** Per-type glyph to aid scannability (mockup 06). */\nconst SOURCE_TYPE_ICON: Record<CosSourceType, LucideIcon> = {\n TELESCOPE: Telescope,\n SATELLITE: Satellite,\n GROUND_SENSOR: RadioTower,\n ARCHIVE: Archive,\n API: Webhook,\n STREAM: Radio,\n FILE_DROP: FileInput,\n SIMULATION: FlaskConical,\n};\n\nfunction formatDate(value?: string | null): string {\n if (!value) {\n return '—';\n }\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return '—';\n }\n return parsed.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });\n}\n\nexport default function SourcesPage() {\n const { navigate } = useCosmicIntersection();\n const [typeFilter, setTypeFilter] = useState<string>(ALL);\n const [statusFilter, setStatusFilter] = useState<string>(ALL);\n const pagination = usePagination({ pageSize: 20, resetKey: `${typeFilter}|${statusFilter}` });\n\n const { data, loading, error, refetch } = useCosSourcesQuery({\n type: typeFilter === ALL ? undefined : (typeFilter as CosSourceType),\n status: statusFilter === ALL ? undefined : (statusFilter as CosSourceStatus),\n pagination: { limit: pagination.limit, offset: pagination.offset },\n });\n\n const [markSynced] = useCosMarkSourceSyncedMutation();\n const [archiveSource] = useCosArchiveSourceMutation();\n\n const sources = useMemo(() => data?.cosListSources.items ?? [], [data]);\n const pageInfo = data?.cosListSources.pageInfo;\n\n const handleMarkSynced = async (source: CosSource) => {\n const response = await markSynced({ variables: { id: source.id } });\n if (response.data?.cosMarkSourceSynced) {\n notify.success('Source marked synced', `“${source.name}” is now up to date.`);\n await refetch();\n }\n };\n\n const handleArchive = async (source: CosSource) => {\n const response = await archiveSource({ variables: { id: source.id } });\n if (response.error) {\n throw new Error(response.error.message);\n }\n if (!response.data?.cosArchiveSource) {\n notify.error('Could not archive source', 'The server did not confirm the change.');\n throw new Error('Archive not confirmed');\n }\n notify.success('Source archived');\n await refetch();\n };\n\n const newButton = (\n <Button type=\"button\" onClick={() => navigate('sources/create')}>\n <Plus className=\"size-4\" />\n New source\n </Button>\n );\n\n const renderBody = () => {\n if (loading) {\n return <LoadingState variant=\"rows\" rows={6} label=\"Loading sources…\" />;\n }\n if (error) {\n return <ErrorState message={error.message} onRetry={() => void refetch()} />;\n }\n if (sources.length === 0) {\n const filtered = typeFilter !== ALL || statusFilter !== ALL;\n return (\n <EmptyState\n icon={Radio}\n title={filtered ? 'No sources match these filters' : 'No data sources yet'}\n description={\n filtered\n ? 'Try clearing the type or status filter to see more sources.'\n : 'Connect a telescope, satellite feed, archive or API to start ingesting scientific data.'\n }\n action={filtered ? undefined : newButton}\n />\n );\n }\n\n return (\n <>\n {/* Desktop / tablet: table */}\n <div className=\"hidden overflow-hidden rounded-card border border-border-default bg-bg-elevated md:block\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Name</TableHead>\n <TableHead>Type</TableHead>\n <TableHead>Status</TableHead>\n <TableHead>Endpoint</TableHead>\n <TableHead>Last synced</TableHead>\n <TableHead>Tags</TableHead>\n <TableHead className=\"text-right\">Actions</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {sources.map((source) => {\n const TypeIcon = SOURCE_TYPE_ICON[source.type] ?? Radio;\n return (\n <TableRow\n key={source.id}\n className=\"cursor-pointer\"\n onClick={() => navigate(`sources/${source.id}`)}\n >\n <TableCell>\n <div className=\"flex items-start gap-2.5\">\n <span className=\"mt-0.5 flex size-7 shrink-0 items-center justify-center rounded-button bg-bg-sunken text-text-secondary\">\n <TypeIcon className=\"size-4\" aria-hidden=\"true\" />\n </span>\n <div className=\"min-w-0\">\n <div className=\"font-medium text-text-primary\">{source.name}</div>\n {source.description ? (\n <div className=\"mt-0.5 line-clamp-1 max-w-xs text-xs text-text-secondary\">\n {source.description}\n </div>\n ) : null}\n </div>\n </div>\n </TableCell>\n <TableCell>\n <Badge variant=\"secondary\">{formatEnumLabel(source.type)}</Badge>\n </TableCell>\n <TableCell>\n <StatusBadge status={source.status} />\n </TableCell>\n <TableCell\n className=\"max-w-[16rem]\"\n onClick={(event) => event.stopPropagation()}\n >\n {source.endpoint ? (\n <SafeLink\n href={source.endpoint}\n className=\"block truncate text-sm text-text-primary underline-offset-2 hover:underline\"\n fallbackClassName=\"block truncate text-sm text-text-secondary\"\n >\n {source.endpoint}\n </SafeLink>\n ) : (\n <span className=\"text-sm text-text-secondary\">—</span>\n )}\n </TableCell>\n <TableCell className=\"whitespace-nowrap text-sm text-text-secondary\">\n {formatDate(source.lastSyncedAt)}\n </TableCell>\n <TableCell>\n <div className=\"flex max-w-[12rem] flex-wrap gap-1\">\n {source.tags.length === 0 ? (\n <span className=\"text-xs text-text-secondary\">—</span>\n ) : (\n source.tags.slice(0, 3).map((tag) => (\n <Badge key={tag} variant=\"outline\" className=\"text-xs\">\n {tag}\n </Badge>\n ))\n )}\n {source.tags.length > 3 ? (\n <span className=\"text-xs text-text-secondary\">\n +{source.tags.length - 3}\n </span>\n ) : null}\n </div>\n </TableCell>\n <TableCell className=\"text-right\">\n <ActionMenu\n ariaLabel={`Actions for ${source.name}`}\n entityName={source.name}\n onView={() => navigate(`sources/${source.id}`)}\n onEdit={() => navigate(`sources/${source.id}/edit`)}\n onDelete={() => handleArchive(source)}\n deleteLabel=\"Archive source\"\n extraItems={[\n {\n key: 'mark-synced',\n label: 'Mark synced',\n icon: RefreshCw,\n onSelect: () => void handleMarkSynced(source),\n },\n ]}\n />\n </TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </Table>\n </div>\n\n {/* Mobile: stacked cards */}\n <ul className=\"space-y-3 md:hidden\">\n {sources.map((source) => {\n const TypeIcon = SOURCE_TYPE_ICON[source.type] ?? Radio;\n return (\n <li key={source.id}>\n <div\n role=\"button\"\n tabIndex={0}\n aria-label={`Open ${source.name}`}\n onClick={() => navigate(`sources/${source.id}`)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n navigate(`sources/${source.id}`);\n }\n }}\n className=\"flex flex-col gap-3 rounded-card border border-border-default bg-bg-elevated p-4 outline-none transition-colors hover:bg-bg-sunken focus-visible:ring-2 focus-visible:ring-border-focus\"\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex min-w-0 items-start gap-2.5\">\n <span className=\"mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-button bg-bg-sunken text-text-secondary\">\n <TypeIcon className=\"size-4\" aria-hidden=\"true\" />\n </span>\n <div className=\"min-w-0\">\n <p className=\"font-medium text-text-primary\">{source.name}</p>\n {source.description ? (\n <p className=\"mt-0.5 line-clamp-2 text-xs text-text-secondary\">\n {source.description}\n </p>\n ) : null}\n </div>\n </div>\n <div onClick={(event) => event.stopPropagation()}>\n <ActionMenu\n ariaLabel={`Actions for ${source.name}`}\n entityName={source.name}\n onView={() => navigate(`sources/${source.id}`)}\n onEdit={() => navigate(`sources/${source.id}/edit`)}\n onDelete={() => handleArchive(source)}\n deleteLabel=\"Archive source\"\n extraItems={[\n {\n key: 'mark-synced',\n label: 'Mark synced',\n icon: RefreshCw,\n onSelect: () => void handleMarkSynced(source),\n },\n ]}\n />\n </div>\n </div>\n\n <div className=\"flex flex-wrap items-center gap-1.5\">\n <Badge variant=\"secondary\">{formatEnumLabel(source.type)}</Badge>\n <StatusBadge status={source.status} />\n </div>\n\n {source.endpoint ? (\n <div onClick={(event) => event.stopPropagation()}>\n <SafeLink\n href={source.endpoint}\n className=\"block truncate text-sm text-text-primary underline-offset-2 hover:underline\"\n fallbackClassName=\"block truncate text-sm text-text-secondary\"\n >\n {source.endpoint}\n </SafeLink>\n </div>\n ) : null}\n\n <div className=\"flex items-center justify-between gap-2 text-xs text-text-secondary\">\n <span>Last synced</span>\n <span>{formatDate(source.lastSyncedAt)}</span>\n </div>\n\n {source.tags.length > 0 ? (\n <div className=\"flex flex-wrap gap-1\">\n {source.tags.slice(0, 4).map((tag) => (\n <Badge key={tag} variant=\"outline\" className=\"text-xs\">\n {tag}\n </Badge>\n ))}\n {source.tags.length > 4 ? (\n <span className=\"text-xs text-text-secondary\">\n +{source.tags.length - 4}\n </span>\n ) : null}\n </div>\n ) : null}\n </div>\n </li>\n );\n })}\n </ul>\n\n <Pagination\n offset={pagination.offset}\n limit={pagination.limit}\n loadedCount={sources.length}\n hasMore={pageInfo?.hasMore ?? false}\n onPrev={pagination.prevPage}\n onNext={pagination.nextPage}\n itemLabel=\"sources\"\n loading={loading}\n />\n </>\n );\n };\n\n return (\n <PageLayout\n title=\"Data sources\"\n description=\"Instruments, archives and feeds that supply raw data into your federation.\"\n actions={newButton}\n >\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"w-full max-w-[14rem]\">\n <Select value={typeFilter} onValueChange={setTypeFilter}>\n <SelectTrigger aria-label=\"Filter by type\">\n <SelectValue placeholder=\"All types\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All types</SelectItem>\n {SOURCE_TYPES.map((type) => (\n <SelectItem key={type} value={type}>\n {formatEnumLabel(type)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"w-full max-w-[14rem]\">\n <Select value={statusFilter} onValueChange={setStatusFilter}>\n <SelectTrigger aria-label=\"Filter by status\">\n <SelectValue placeholder=\"All statuses\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All statuses</SelectItem>\n {SOURCE_STATUSES.map((status) => (\n <SelectItem key={status} value={status}>\n {formatEnumLabel(status)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n {renderBody()}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-cosmicintersection",
3
- "version": "2026.704.2",
3
+ "version": "2026.704.3",
4
4
  "description": "Burdenoff CosmicIntersection Microfrontend",
5
5
  "type": "module",
6
6
  "files": [