@burdenoff/microfe-cosmicintersection 2026.525.1 → 2026.704.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/dist/cosmicintersection/CosmicIntersectionRoot.js +38 -113
  2. package/dist/cosmicintersection/CosmicIntersectionRoot.js.map +1 -1
  3. package/dist/cosmicintersection/CosmicIntersectionRoutes.js +110 -44
  4. package/dist/cosmicintersection/CosmicIntersectionRoutes.js.map +1 -1
  5. package/dist/cosmicintersection/api/cosmicApi.js +918 -0
  6. package/dist/cosmicintersection/api/cosmicApi.js.map +1 -0
  7. package/dist/cosmicintersection/components/ActionMenu.js +106 -0
  8. package/dist/cosmicintersection/components/ActionMenu.js.map +1 -0
  9. package/dist/cosmicintersection/components/ActivityFeedPanel.js +68 -0
  10. package/dist/cosmicintersection/components/ActivityFeedPanel.js.map +1 -0
  11. package/dist/cosmicintersection/components/DiscussionPanel.js +57 -0
  12. package/dist/cosmicintersection/components/DiscussionPanel.js.map +1 -0
  13. package/dist/cosmicintersection/components/EmptyState.js +35 -0
  14. package/dist/cosmicintersection/components/EmptyState.js.map +1 -0
  15. package/dist/cosmicintersection/components/EntityFormShell.js +57 -0
  16. package/dist/cosmicintersection/components/EntityFormShell.js.map +1 -0
  17. package/dist/cosmicintersection/components/EntityTagsField.js +77 -0
  18. package/dist/cosmicintersection/components/EntityTagsField.js.map +1 -0
  19. package/dist/cosmicintersection/components/ErrorState.js +40 -0
  20. package/dist/cosmicintersection/components/ErrorState.js.map +1 -0
  21. package/dist/cosmicintersection/components/FileUploadField.js +146 -0
  22. package/dist/cosmicintersection/components/FileUploadField.js.map +1 -0
  23. package/dist/cosmicintersection/components/LoadingState.js +23 -0
  24. package/dist/cosmicintersection/components/LoadingState.js.map +1 -0
  25. package/dist/cosmicintersection/components/PageLayout.js +46 -0
  26. package/dist/cosmicintersection/components/PageLayout.js.map +1 -0
  27. package/dist/cosmicintersection/components/Pagination.js +65 -0
  28. package/dist/cosmicintersection/components/Pagination.js.map +1 -0
  29. package/dist/cosmicintersection/components/SafeLink.js +35 -0
  30. package/dist/cosmicintersection/components/SafeLink.js.map +1 -0
  31. package/dist/cosmicintersection/components/StatusBadge.js +53 -0
  32. package/dist/cosmicintersection/components/StatusBadge.js.map +1 -0
  33. package/dist/cosmicintersection/components/index.js +13 -0
  34. package/dist/cosmicintersection/context/CosmicIntersectionContext.js +46 -0
  35. package/dist/cosmicintersection/context/CosmicIntersectionContext.js.map +1 -0
  36. package/dist/cosmicintersection/index.js +0 -2
  37. package/dist/cosmicintersection/lib/mutationResult.js +12 -0
  38. package/dist/cosmicintersection/lib/mutationResult.js.map +1 -0
  39. package/dist/cosmicintersection/lib/toast.js +36 -0
  40. package/dist/cosmicintersection/lib/toast.js.map +1 -0
  41. package/dist/cosmicintersection/pages/access/AccessPage.js +347 -0
  42. package/dist/cosmicintersection/pages/access/AccessPage.js.map +1 -0
  43. package/dist/cosmicintersection/pages/analyses/AnalysesPage.js +484 -0
  44. package/dist/cosmicintersection/pages/analyses/AnalysesPage.js.map +1 -0
  45. package/dist/cosmicintersection/pages/collections/CollectionDetailPage.js +177 -0
  46. package/dist/cosmicintersection/pages/collections/CollectionDetailPage.js.map +1 -0
  47. package/dist/cosmicintersection/pages/collections/CollectionFormPage.js +143 -0
  48. package/dist/cosmicintersection/pages/collections/CollectionFormPage.js.map +1 -0
  49. package/dist/cosmicintersection/pages/collections/CollectionsPage.js +112 -0
  50. package/dist/cosmicintersection/pages/collections/CollectionsPage.js.map +1 -0
  51. package/dist/cosmicintersection/pages/dashboard/DashboardPage.js +246 -0
  52. package/dist/cosmicintersection/pages/dashboard/DashboardPage.js.map +1 -0
  53. package/dist/cosmicintersection/pages/datasets/DatasetDetailPage.js +480 -0
  54. package/dist/cosmicintersection/pages/datasets/DatasetDetailPage.js.map +1 -0
  55. package/dist/cosmicintersection/pages/datasets/DatasetFormPage.js +218 -0
  56. package/dist/cosmicintersection/pages/datasets/DatasetFormPage.js.map +1 -0
  57. package/dist/cosmicintersection/pages/datasets/DatasetsPage.js +252 -0
  58. package/dist/cosmicintersection/pages/datasets/DatasetsPage.js.map +1 -0
  59. package/dist/cosmicintersection/pages/notebooks/NotebookDetailPage.js +402 -0
  60. package/dist/cosmicintersection/pages/notebooks/NotebookDetailPage.js.map +1 -0
  61. package/dist/cosmicintersection/pages/notebooks/NotebookFormPage.js +313 -0
  62. package/dist/cosmicintersection/pages/notebooks/NotebookFormPage.js.map +1 -0
  63. package/dist/cosmicintersection/pages/notebooks/NotebooksPage.js +203 -0
  64. package/dist/cosmicintersection/pages/notebooks/NotebooksPage.js.map +1 -0
  65. package/dist/cosmicintersection/pages/pipelines/PipelineDetailPage.js +244 -0
  66. package/dist/cosmicintersection/pages/pipelines/PipelineDetailPage.js.map +1 -0
  67. package/dist/cosmicintersection/pages/pipelines/PipelineFormPage.js +210 -0
  68. package/dist/cosmicintersection/pages/pipelines/PipelineFormPage.js.map +1 -0
  69. package/dist/cosmicintersection/pages/pipelines/PipelinesPage.js +193 -0
  70. package/dist/cosmicintersection/pages/pipelines/PipelinesPage.js.map +1 -0
  71. package/dist/cosmicintersection/pages/releases/ReleaseFormPage.js +184 -0
  72. package/dist/cosmicintersection/pages/releases/ReleaseFormPage.js.map +1 -0
  73. package/dist/cosmicintersection/pages/releases/ReleasesPage.js +418 -0
  74. package/dist/cosmicintersection/pages/releases/ReleasesPage.js.map +1 -0
  75. package/dist/cosmicintersection/pages/runs/RunDetailPage.js +380 -0
  76. package/dist/cosmicintersection/pages/runs/RunDetailPage.js.map +1 -0
  77. package/dist/cosmicintersection/pages/runs/RunsPage.js +165 -0
  78. package/dist/cosmicintersection/pages/runs/RunsPage.js.map +1 -0
  79. package/dist/cosmicintersection/pages/sources/SourceDetailPage.js +205 -0
  80. package/dist/cosmicintersection/pages/sources/SourceDetailPage.js.map +1 -0
  81. package/dist/cosmicintersection/pages/sources/SourceFormPage.js +229 -0
  82. package/dist/cosmicintersection/pages/sources/SourceFormPage.js.map +1 -0
  83. package/dist/cosmicintersection/pages/sources/SourcesPage.js +223 -0
  84. package/dist/cosmicintersection/pages/sources/SourcesPage.js.map +1 -0
  85. package/dist/cosmicintersection/utils/cn.js +10 -0
  86. package/dist/cosmicintersection/utils/cn.js.map +1 -0
  87. package/dist/index.js +2 -4
  88. package/dist/node_modules/clsx/dist/clsx.js +18 -0
  89. package/dist/node_modules/clsx/dist/clsx.js.map +1 -0
  90. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +1716 -0
  91. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
  92. package/package.json +2 -1
  93. package/dist/cosmicintersection/pages/AiDiscoveryPage.js +0 -363
  94. package/dist/cosmicintersection/pages/AiDiscoveryPage.js.map +0 -1
  95. package/dist/cosmicintersection/pages/DashboardPage.js +0 -306
  96. package/dist/cosmicintersection/pages/DashboardPage.js.map +0 -1
  97. package/dist/cosmicintersection/pages/SpaceScienceCitizenPage.js +0 -287
  98. package/dist/cosmicintersection/pages/SpaceScienceCitizenPage.js.map +0 -1
  99. package/dist/cosmicintersection/pages/SpaceScienceDataPage.js +0 -385
  100. package/dist/cosmicintersection/pages/SpaceScienceDataPage.js.map +0 -1
  101. package/dist/cosmicintersection/pages/SpaceScienceDataPage1.js +0 -420
  102. package/dist/cosmicintersection/pages/SpaceScienceDataPage1.js.map +0 -1
  103. package/dist/cosmicintersection/pages/SpaceScienceLearningPage.js +0 -309
  104. package/dist/cosmicintersection/pages/SpaceScienceLearningPage.js.map +0 -1
  105. package/dist/cosmicintersection/pages/SpaceScienceLearningPage1.js +0 -361
  106. package/dist/cosmicintersection/pages/SpaceScienceLearningPage1.js.map +0 -1
  107. package/dist/cosmicintersection/pages/SpaceSciencePage.js +0 -194
  108. package/dist/cosmicintersection/pages/SpaceSciencePage.js.map +0 -1
  109. package/dist/cosmicintersection/pages/SpaceScienceResearchPage.js +0 -290
  110. package/dist/cosmicintersection/pages/SpaceScienceResearchPage.js.map +0 -1
  111. package/dist/cosmicintersection/pages/SpaceScienceSimulationPage.js +0 -279
  112. package/dist/cosmicintersection/pages/SpaceScienceSimulationPage.js.map +0 -1
  113. package/dist/cosmicintersection/providers/CosmicIntersectionProvider.js +0 -27
  114. package/dist/cosmicintersection/providers/CosmicIntersectionProvider.js.map +0 -1
  115. package/dist/cosmicintersection/store/cosmicintersectionStore.js +0 -478
  116. package/dist/cosmicintersection/store/cosmicintersectionStore.js.map +0 -1
  117. package/dist/cosmicintersection/utils/i18n.js +0 -15
  118. package/dist/cosmicintersection/utils/i18n.js.map +0 -1
  119. package/dist/cosmicintersection/utils/navigation.js +0 -8
  120. package/dist/cosmicintersection/utils/navigation.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toast.js","names":[],"sources":["../../../src/cosmicintersection/lib/toast.ts"],"sourcesContent":["import { toast } from 'sonner';\n\n/**\n * Module-wide toast API. sonner is a global singleton; the matching <Toaster>\n * is owned by the HOST app shell (mounted once via AppShellProvider). Every\n * page/component surfaces feedback through these helpers instead of hand-rolling\n * fixed-position toast markup, so success/error notifications stay consistent\n * with the rest of the platform.\n *\n * Durations follow the notification spec: success/info auto-dismiss, errors stay\n * until the user dismisses them (sonner renders a close button and announces via\n * aria-live).\n */\nexport const notify = {\n success(message: string, description?: string): void {\n toast.success(message, { description, duration: 4000 });\n },\n info(message: string, description?: string): void {\n toast.info(message, { description, duration: 4000 });\n },\n warning(message: string, description?: string): void {\n toast.warning(message, { description, duration: 8000 });\n },\n error(message: string, description?: string): void {\n toast.error(message, { description, duration: Infinity, closeButton: true });\n },\n dismiss(id?: string | number): void {\n toast.dismiss(id);\n },\n};\n\nexport { toast };\n"],"mappings":";;AAaA,IAAa,IAAS;CACpB,QAAQ,GAAiB,GAA4B;AACnD,IAAM,QAAQ,GAAS;GAAE;GAAa,UAAU;GAAM,CAAC;;CAEzD,KAAK,GAAiB,GAA4B;AAChD,IAAM,KAAK,GAAS;GAAE;GAAa,UAAU;GAAM,CAAC;;CAEtD,QAAQ,GAAiB,GAA4B;AACnD,IAAM,QAAQ,GAAS;GAAE;GAAa,UAAU;GAAM,CAAC;;CAEzD,MAAM,GAAiB,GAA4B;AACjD,IAAM,MAAM,GAAS;GAAE;GAAa,UAAU;GAAU,aAAa;GAAM,CAAC;;CAE9E,QAAQ,GAA4B;AAClC,IAAM,QAAQ,EAAG;;CAEpB"}
@@ -0,0 +1,347 @@
1
+ import { notify as e } from "../../lib/toast.js";
2
+ import { useCosAccessGrantsQuery as t, useCosDatasetsQuery as n, useCosGrantAccessMutation as r, useCosRevokeAccessMutation as ee } from "../../api/cosmicApi.js";
3
+ import te from "../../components/ActionMenu.js";
4
+ import i from "../../components/EmptyState.js";
5
+ import ne from "../../components/ErrorState.js";
6
+ import re from "../../components/LoadingState.js";
7
+ import ie from "../../components/EntityTagsField.js";
8
+ import ae from "../../components/PageLayout.js";
9
+ import a, { formatEnumLabel as o } from "../../components/StatusBadge.js";
10
+ import "../../components/index.js";
11
+ import { useMemo as s, useState as c } from "react";
12
+ import { jsx as l, jsxs as u } from "react/jsx-runtime";
13
+ import { KeyRound as d, ShieldCheck as oe } from "lucide-react";
14
+ import { Badge as f, Button as p, Dialog as m, DialogContent as h, DialogDescription as g, DialogFooter as se, DialogHeader as _, DialogTitle as v, Input as y, Label as b, Select as x, SelectContent as S, SelectItem as C, SelectTrigger as w, SelectValue as T, Table as ce, TableBody as le, TableCell as E, TableHead as D, TableHeader as O, TableRow as k, Textarea as A } from "@burdenoff/fe-libs/ui";
15
+ //#region src/cosmicintersection/pages/access/AccessPage.tsx
16
+ var j = "ALL", M = [
17
+ "PENDING",
18
+ "ACTIVE",
19
+ "EXPIRED",
20
+ "REVOKED"
21
+ ];
22
+ function N(e) {
23
+ return e === "ACTIVE" || e === "PENDING";
24
+ }
25
+ function P(e) {
26
+ if (!e) return "—";
27
+ let t = new Date(e);
28
+ return Number.isNaN(t.getTime()) ? "—" : t.toLocaleDateString(void 0, {
29
+ year: "numeric",
30
+ month: "short",
31
+ day: "numeric"
32
+ });
33
+ }
34
+ var F = {
35
+ datasetId: "",
36
+ granteeId: "",
37
+ scopes: [],
38
+ reason: "",
39
+ expiresAt: ""
40
+ };
41
+ function I() {
42
+ let [I, L] = c(j), [R, z] = c(j), B = n({ pagination: {
43
+ limit: 50,
44
+ offset: 0
45
+ } }), V = s(() => B.data?.cosListDatasets.items ?? [], [B.data]), H = s(() => {
46
+ let e = /* @__PURE__ */ new Map();
47
+ for (let t of V) e.set(t.id, t.name);
48
+ return e;
49
+ }, [V]), { data: U, loading: ue, error: W, refetch: G } = t({
50
+ datasetId: I === j ? void 0 : I,
51
+ status: R === j ? void 0 : R
52
+ }), K = s(() => U?.cosListAccessGrants ?? [], [U]), [de, { loading: q }] = r(), [fe] = ee(), [pe, J] = c(!1), [Y, X] = c(F), me = () => {
53
+ X({
54
+ ...F,
55
+ datasetId: I === j ? "" : I
56
+ }), J(!0);
57
+ }, Z = (e, t) => {
58
+ X((n) => ({
59
+ ...n,
60
+ [e]: t
61
+ }));
62
+ }, he = async () => {
63
+ if (!Y.datasetId) {
64
+ e.error("Dataset is required", "Choose which dataset this grant applies to.");
65
+ return;
66
+ }
67
+ if (!Y.granteeId.trim()) {
68
+ e.error("Grantee is required", "Enter the workspace User ID to grant access to.");
69
+ return;
70
+ }
71
+ let t;
72
+ if (Y.expiresAt) {
73
+ let n = new Date(Y.expiresAt);
74
+ if (Number.isNaN(n.getTime())) {
75
+ e.error("Invalid expiry", "Enter a valid expiry date or leave it blank.");
76
+ return;
77
+ }
78
+ t = n.toISOString();
79
+ }
80
+ (await de({ variables: { input: {
81
+ datasetId: Y.datasetId,
82
+ granteeId: Y.granteeId.trim(),
83
+ scopes: Y.scopes.length ? Y.scopes : void 0,
84
+ reason: Y.reason.trim() || void 0,
85
+ expiresAt: t
86
+ } } })).data?.cosGrantAccess?.id && (e.success("Access granted"), J(!1), X(F), await G());
87
+ }, ge = async (t) => {
88
+ let n = await fe({ variables: { id: t.id } });
89
+ if (n.error) throw Error(n.error.message);
90
+ if (!n.data?.cosRevokeAccess?.id) throw e.error("Could not revoke grant", "The server did not confirm the change."), Error("Revoke not confirmed");
91
+ e.success("Access revoked"), await G();
92
+ }, Q = /* @__PURE__ */ u(p, {
93
+ type: "button",
94
+ onClick: me,
95
+ children: [/* @__PURE__ */ l(d, { className: "size-4" }), "Grant access"]
96
+ }), $ = I === j;
97
+ return /* @__PURE__ */ u(ae, {
98
+ title: "Data access",
99
+ description: "Govern who can reach restricted and embargoed datasets, with scoped, expiring grants.",
100
+ actions: Q,
101
+ children: [/* @__PURE__ */ u("div", {
102
+ className: "space-y-4",
103
+ children: [/* @__PURE__ */ u("div", {
104
+ className: "flex flex-wrap items-center gap-3",
105
+ children: [/* @__PURE__ */ l("div", {
106
+ className: "w-full max-w-[18rem]",
107
+ children: /* @__PURE__ */ u(x, {
108
+ value: I,
109
+ onValueChange: L,
110
+ children: [/* @__PURE__ */ l(w, {
111
+ "aria-label": "Filter by dataset",
112
+ children: /* @__PURE__ */ l(T, { placeholder: "All datasets" })
113
+ }), /* @__PURE__ */ u(S, { children: [/* @__PURE__ */ l(C, {
114
+ value: j,
115
+ children: "All datasets"
116
+ }), V.map((e) => /* @__PURE__ */ l(C, {
117
+ value: e.id,
118
+ children: e.name
119
+ }, e.id))] })]
120
+ })
121
+ }), /* @__PURE__ */ l("div", {
122
+ className: "w-full max-w-[14rem]",
123
+ children: /* @__PURE__ */ u(x, {
124
+ value: R,
125
+ onValueChange: z,
126
+ children: [/* @__PURE__ */ l(w, {
127
+ "aria-label": "Filter by status",
128
+ children: /* @__PURE__ */ l(T, { placeholder: "All statuses" })
129
+ }), /* @__PURE__ */ u(S, { children: [/* @__PURE__ */ l(C, {
130
+ value: j,
131
+ children: "All statuses"
132
+ }), M.map((e) => /* @__PURE__ */ l(C, {
133
+ value: e,
134
+ children: o(e)
135
+ }, e))] })]
136
+ })
137
+ })]
138
+ }), (() => {
139
+ if (ue) return /* @__PURE__ */ l(re, {
140
+ variant: "rows",
141
+ rows: 6,
142
+ label: "Loading access grants…"
143
+ });
144
+ if (W) return /* @__PURE__ */ l(ne, {
145
+ message: W.message,
146
+ onRetry: () => void G()
147
+ });
148
+ if (K.length === 0) {
149
+ let e = I !== j || R !== j;
150
+ return /* @__PURE__ */ l(i, {
151
+ icon: oe,
152
+ title: e ? "No grants match these filters" : "No access grants yet",
153
+ description: e ? "Try clearing the dataset or status filter to see more grants." : "Grant a workspace member scoped access to a restricted or embargoed dataset.",
154
+ action: e ? void 0 : Q
155
+ });
156
+ }
157
+ return /* @__PURE__ */ l("div", {
158
+ className: "overflow-x-auto rounded-card border border-border-default bg-bg-elevated",
159
+ children: /* @__PURE__ */ u(ce, { children: [/* @__PURE__ */ l(O, { children: /* @__PURE__ */ u(k, { children: [
160
+ $ ? /* @__PURE__ */ l(D, { children: "Dataset" }) : null,
161
+ /* @__PURE__ */ l(D, { children: "Grantee" }),
162
+ /* @__PURE__ */ l(D, { children: "Status" }),
163
+ /* @__PURE__ */ l(D, { children: "Scopes" }),
164
+ /* @__PURE__ */ l(D, { children: "Reason" }),
165
+ /* @__PURE__ */ l(D, { children: "Granted" }),
166
+ /* @__PURE__ */ l(D, { children: "Expires" }),
167
+ /* @__PURE__ */ l(D, { children: "Revoked" }),
168
+ /* @__PURE__ */ l(D, {
169
+ className: "text-right",
170
+ children: "Actions"
171
+ })
172
+ ] }) }), /* @__PURE__ */ l(le, { children: K.map((e) => /* @__PURE__ */ u(k, { children: [
173
+ $ ? /* @__PURE__ */ l(E, {
174
+ className: "max-w-[12rem]",
175
+ children: /* @__PURE__ */ l("span", {
176
+ className: "line-clamp-1 text-sm text-text-primary",
177
+ children: H.get(e.datasetId) ?? /* @__PURE__ */ l("span", {
178
+ className: "font-mono text-xs text-text-secondary",
179
+ children: e.datasetId
180
+ })
181
+ })
182
+ }) : null,
183
+ /* @__PURE__ */ l(E, {
184
+ className: "max-w-[12rem]",
185
+ children: /* @__PURE__ */ l("span", {
186
+ className: "block truncate font-mono text-xs text-text-primary",
187
+ children: e.granteeId
188
+ })
189
+ }),
190
+ /* @__PURE__ */ l(E, { children: /* @__PURE__ */ l(a, { status: e.status }) }),
191
+ /* @__PURE__ */ l(E, { children: /* @__PURE__ */ l("div", {
192
+ className: "flex max-w-[12rem] flex-wrap gap-1",
193
+ children: e.scopes.length === 0 ? /* @__PURE__ */ l("span", {
194
+ className: "text-xs text-text-secondary",
195
+ children: "—"
196
+ }) : e.scopes.map((e) => /* @__PURE__ */ l(f, {
197
+ variant: "outline",
198
+ className: "text-xs",
199
+ children: e
200
+ }, e))
201
+ }) }),
202
+ /* @__PURE__ */ l(E, {
203
+ className: "max-w-[14rem]",
204
+ children: e.reason ? /* @__PURE__ */ l("span", {
205
+ className: "line-clamp-1 text-sm text-text-secondary",
206
+ children: e.reason
207
+ }) : /* @__PURE__ */ l("span", {
208
+ className: "text-sm text-text-secondary",
209
+ children: "—"
210
+ })
211
+ }),
212
+ /* @__PURE__ */ l(E, {
213
+ className: "whitespace-nowrap text-sm text-text-secondary",
214
+ children: P(e.grantedAt)
215
+ }),
216
+ /* @__PURE__ */ l(E, {
217
+ className: "whitespace-nowrap text-sm text-text-secondary",
218
+ children: P(e.expiresAt)
219
+ }),
220
+ /* @__PURE__ */ l(E, {
221
+ className: "whitespace-nowrap text-sm text-text-secondary",
222
+ children: P(e.revokedAt)
223
+ }),
224
+ /* @__PURE__ */ l(E, {
225
+ className: "text-right",
226
+ children: N(e.status) ? /* @__PURE__ */ l(te, {
227
+ ariaLabel: `Actions for grant to ${e.granteeId}`,
228
+ entityName: e.granteeId,
229
+ onDelete: () => ge(e),
230
+ deleteLabel: "Revoke grant"
231
+ }) : /* @__PURE__ */ l("span", {
232
+ className: "text-xs text-text-secondary",
233
+ children: "—"
234
+ })
235
+ })
236
+ ] }, e.id)) })] })
237
+ });
238
+ })()]
239
+ }), /* @__PURE__ */ l(m, {
240
+ open: pe,
241
+ onOpenChange: (e) => J(e || q ? e : !1),
242
+ children: /* @__PURE__ */ u(h, {
243
+ className: "max-h-[85vh] max-w-md overflow-y-auto",
244
+ children: [
245
+ /* @__PURE__ */ u(_, { children: [/* @__PURE__ */ l(v, { children: "Grant data access" }), /* @__PURE__ */ l(g, { children: "Give a workspace member scoped access to a dataset. Access is identified by the member's User ID." })] }),
246
+ /* @__PURE__ */ u("div", {
247
+ className: "space-y-4",
248
+ children: [
249
+ /* @__PURE__ */ u("div", {
250
+ className: "space-y-1.5",
251
+ children: [/* @__PURE__ */ l(b, {
252
+ htmlFor: "grant-dataset",
253
+ children: "Dataset"
254
+ }), /* @__PURE__ */ u(x, {
255
+ value: Y.datasetId || void 0,
256
+ onValueChange: (e) => Z("datasetId", e),
257
+ children: [/* @__PURE__ */ l(w, {
258
+ id: "grant-dataset",
259
+ "aria-label": "Dataset",
260
+ children: /* @__PURE__ */ l(T, { placeholder: "Select a dataset" })
261
+ }), /* @__PURE__ */ l(S, { children: V.map((e) => /* @__PURE__ */ l(C, {
262
+ value: e.id,
263
+ children: e.name
264
+ }, e.id)) })]
265
+ })]
266
+ }),
267
+ /* @__PURE__ */ u("div", {
268
+ className: "space-y-1.5",
269
+ children: [
270
+ /* @__PURE__ */ l(b, {
271
+ htmlFor: "grant-grantee",
272
+ children: "Grantee (User ID)"
273
+ }),
274
+ /* @__PURE__ */ l(y, {
275
+ id: "grant-grantee",
276
+ value: Y.granteeId,
277
+ onChange: (e) => Z("granteeId", e.target.value),
278
+ placeholder: "e.g. 4fe35990-…",
279
+ className: "font-mono"
280
+ }),
281
+ /* @__PURE__ */ l("p", {
282
+ className: "text-xs text-text-secondary",
283
+ children: "Paste the workspace member's User ID. You can copy it from the member's profile (“Get ID”) or the workspace member directory."
284
+ })
285
+ ]
286
+ }),
287
+ /* @__PURE__ */ l(ie, {
288
+ value: Y.scopes,
289
+ onChange: (e) => Z("scopes", e),
290
+ label: "Scopes",
291
+ placeholder: "e.g. read, download"
292
+ }),
293
+ /* @__PURE__ */ u("div", {
294
+ className: "space-y-1.5",
295
+ children: [/* @__PURE__ */ l(b, {
296
+ htmlFor: "grant-reason",
297
+ children: "Reason"
298
+ }), /* @__PURE__ */ l(A, {
299
+ id: "grant-reason",
300
+ value: Y.reason,
301
+ onChange: (e) => Z("reason", e.target.value),
302
+ rows: 2,
303
+ placeholder: "Why this member needs access."
304
+ })]
305
+ }),
306
+ /* @__PURE__ */ u("div", {
307
+ className: "space-y-1.5",
308
+ children: [
309
+ /* @__PURE__ */ l(b, {
310
+ htmlFor: "grant-expires",
311
+ children: "Expires (optional)"
312
+ }),
313
+ /* @__PURE__ */ l(y, {
314
+ id: "grant-expires",
315
+ type: "datetime-local",
316
+ value: Y.expiresAt,
317
+ onChange: (e) => Z("expiresAt", e.target.value)
318
+ }),
319
+ /* @__PURE__ */ l("p", {
320
+ className: "text-xs text-text-secondary",
321
+ children: "Leave blank for an open-ended grant."
322
+ })
323
+ ]
324
+ })
325
+ ]
326
+ }),
327
+ /* @__PURE__ */ u(se, { children: [/* @__PURE__ */ l(p, {
328
+ type: "button",
329
+ variant: "outline",
330
+ onClick: () => J(!1),
331
+ disabled: q,
332
+ children: "Cancel"
333
+ }), /* @__PURE__ */ u(p, {
334
+ type: "button",
335
+ onClick: () => void he(),
336
+ disabled: q,
337
+ children: [/* @__PURE__ */ l(d, { className: "size-4" }), q ? "Granting…" : "Grant access"]
338
+ })] })
339
+ ]
340
+ })
341
+ })]
342
+ });
343
+ }
344
+ //#endregion
345
+ export { I as default };
346
+
347
+ //# sourceMappingURL=AccessPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AccessPage.js","names":[],"sources":["../../../../src/cosmicintersection/pages/access/AccessPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { KeyRound, ShieldCheck } 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 Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\n\nimport {\n useCosAccessGrantsQuery,\n useCosDatasetsQuery,\n useCosGrantAccessMutation,\n useCosRevokeAccessMutation,\n type CosDataAccessGrant,\n type CosGrantAccessInput,\n type CosGrantStatus,\n} from '../../api/cosmicApi';\nimport {\n EmptyState,\n ErrorState,\n LoadingState,\n PageLayout,\n StatusBadge,\n formatEnumLabel,\n} from '../../components';\nimport { ActionMenu } from '../../components/ActionMenu';\nimport { EntityTagsField } from '../../components/EntityTagsField';\nimport { notify } from '../../lib/toast';\n\nconst ALL = 'ALL';\nconst GRANT_STATUSES: CosGrantStatus[] = ['PENDING', 'ACTIVE', 'EXPIRED', 'REVOKED'];\n\n/** Only live grants can be revoked. */\nfunction canRevoke(status: CosGrantStatus): boolean {\n return status === 'ACTIVE' || status === 'PENDING';\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\ninterface GrantFormState {\n datasetId: string;\n granteeId: string;\n scopes: string[];\n reason: string;\n expiresAt: string;\n}\n\nconst EMPTY_FORM: GrantFormState = {\n datasetId: '',\n granteeId: '',\n scopes: [],\n reason: '',\n expiresAt: '',\n};\n\nexport default function AccessPage() {\n const [datasetFilter, setDatasetFilter] = useState<string>(ALL);\n const [statusFilter, setStatusFilter] = useState<string>(ALL);\n\n const datasetsQuery = useCosDatasetsQuery({ pagination: { limit: 50, offset: 0 } });\n const datasets = useMemo(\n () => datasetsQuery.data?.cosListDatasets.items ?? [],\n [datasetsQuery.data]\n );\n const datasetName = useMemo(() => {\n const map = new Map<string, string>();\n for (const dataset of datasets) {\n map.set(dataset.id, dataset.name);\n }\n return map;\n }, [datasets]);\n\n const { data, loading, error, refetch } = useCosAccessGrantsQuery({\n datasetId: datasetFilter === ALL ? undefined : datasetFilter,\n status: statusFilter === ALL ? undefined : (statusFilter as CosGrantStatus),\n });\n const grants = useMemo(() => data?.cosListAccessGrants ?? [], [data]);\n\n const [grantAccess, { loading: granting }] = useCosGrantAccessMutation();\n const [revokeAccess] = useCosRevokeAccessMutation();\n\n const [dialogOpen, setDialogOpen] = useState(false);\n const [form, setForm] = useState<GrantFormState>(EMPTY_FORM);\n\n const openGrantDialog = () => {\n setForm({\n ...EMPTY_FORM,\n datasetId: datasetFilter === ALL ? '' : datasetFilter,\n });\n setDialogOpen(true);\n };\n\n const setField = <K extends keyof GrantFormState>(field: K, value: GrantFormState[K]) => {\n setForm((prev) => ({ ...prev, [field]: value }));\n };\n\n const submitGrant = async () => {\n if (!form.datasetId) {\n notify.error('Dataset is required', 'Choose which dataset this grant applies to.');\n return;\n }\n if (!form.granteeId.trim()) {\n notify.error('Grantee is required', 'Enter the workspace User ID to grant access to.');\n return;\n }\n\n let expiresAt: string | undefined;\n if (form.expiresAt) {\n const parsed = new Date(form.expiresAt);\n if (Number.isNaN(parsed.getTime())) {\n notify.error('Invalid expiry', 'Enter a valid expiry date or leave it blank.');\n return;\n }\n expiresAt = parsed.toISOString();\n }\n\n const input: CosGrantAccessInput = {\n datasetId: form.datasetId,\n granteeId: form.granteeId.trim(),\n scopes: form.scopes.length ? form.scopes : undefined,\n reason: form.reason.trim() || undefined,\n expiresAt,\n };\n\n const response = await grantAccess({ variables: { input } });\n if (response.data?.cosGrantAccess?.id) {\n notify.success('Access granted');\n setDialogOpen(false);\n setForm(EMPTY_FORM);\n await refetch();\n }\n };\n\n const handleRevoke = async (grant: CosDataAccessGrant) => {\n const response = await revokeAccess({ variables: { id: grant.id } });\n if (response.error) {\n throw new Error(response.error.message);\n }\n if (!response.data?.cosRevokeAccess?.id) {\n notify.error('Could not revoke grant', 'The server did not confirm the change.');\n throw new Error('Revoke not confirmed');\n }\n notify.success('Access revoked');\n await refetch();\n };\n\n const grantButton = (\n <Button type=\"button\" onClick={openGrantDialog}>\n <KeyRound className=\"size-4\" />\n Grant access\n </Button>\n );\n\n const showDatasetColumn = datasetFilter === ALL;\n\n const renderBody = () => {\n if (loading) {\n return <LoadingState variant=\"rows\" rows={6} label=\"Loading access grants…\" />;\n }\n if (error) {\n return <ErrorState message={error.message} onRetry={() => void refetch()} />;\n }\n if (grants.length === 0) {\n const filtered = datasetFilter !== ALL || statusFilter !== ALL;\n return (\n <EmptyState\n icon={ShieldCheck}\n title={filtered ? 'No grants match these filters' : 'No access grants yet'}\n description={\n filtered\n ? 'Try clearing the dataset or status filter to see more grants.'\n : 'Grant a workspace member scoped access to a restricted or embargoed dataset.'\n }\n action={filtered ? undefined : grantButton}\n />\n );\n }\n\n return (\n <div className=\"overflow-x-auto rounded-card border border-border-default bg-bg-elevated\">\n <Table>\n <TableHeader>\n <TableRow>\n {showDatasetColumn ? <TableHead>Dataset</TableHead> : null}\n <TableHead>Grantee</TableHead>\n <TableHead>Status</TableHead>\n <TableHead>Scopes</TableHead>\n <TableHead>Reason</TableHead>\n <TableHead>Granted</TableHead>\n <TableHead>Expires</TableHead>\n <TableHead>Revoked</TableHead>\n <TableHead className=\"text-right\">Actions</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {grants.map((grant) => (\n <TableRow key={grant.id}>\n {showDatasetColumn ? (\n <TableCell className=\"max-w-[12rem]\">\n <span className=\"line-clamp-1 text-sm text-text-primary\">\n {datasetName.get(grant.datasetId) ?? (\n <span className=\"font-mono text-xs text-text-secondary\">\n {grant.datasetId}\n </span>\n )}\n </span>\n </TableCell>\n ) : null}\n <TableCell className=\"max-w-[12rem]\">\n <span className=\"block truncate font-mono text-xs text-text-primary\">\n {grant.granteeId}\n </span>\n </TableCell>\n <TableCell>\n <StatusBadge status={grant.status} />\n </TableCell>\n <TableCell>\n <div className=\"flex max-w-[12rem] flex-wrap gap-1\">\n {grant.scopes.length === 0 ? (\n <span className=\"text-xs text-text-secondary\">—</span>\n ) : (\n grant.scopes.map((scope) => (\n <Badge key={scope} variant=\"outline\" className=\"text-xs\">\n {scope}\n </Badge>\n ))\n )}\n </div>\n </TableCell>\n <TableCell className=\"max-w-[14rem]\">\n {grant.reason ? (\n <span className=\"line-clamp-1 text-sm text-text-secondary\">{grant.reason}</span>\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(grant.grantedAt)}\n </TableCell>\n <TableCell className=\"whitespace-nowrap text-sm text-text-secondary\">\n {formatDate(grant.expiresAt)}\n </TableCell>\n <TableCell className=\"whitespace-nowrap text-sm text-text-secondary\">\n {formatDate(grant.revokedAt)}\n </TableCell>\n <TableCell className=\"text-right\">\n {canRevoke(grant.status) ? (\n <ActionMenu\n ariaLabel={`Actions for grant to ${grant.granteeId}`}\n entityName={grant.granteeId}\n onDelete={() => handleRevoke(grant)}\n deleteLabel=\"Revoke grant\"\n />\n ) : (\n <span className=\"text-xs text-text-secondary\">—</span>\n )}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n );\n };\n\n return (\n <PageLayout\n title=\"Data access\"\n description=\"Govern who can reach restricted and embargoed datasets, with scoped, expiring grants.\"\n actions={grantButton}\n >\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"w-full max-w-[18rem]\">\n <Select value={datasetFilter} onValueChange={setDatasetFilter}>\n <SelectTrigger aria-label=\"Filter by dataset\">\n <SelectValue placeholder=\"All datasets\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All datasets</SelectItem>\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 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 {GRANT_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\n {/* Grant access dialog */}\n <Dialog\n open={dialogOpen}\n onOpenChange={(open) => (open || granting ? setDialogOpen(open) : setDialogOpen(false))}\n >\n <DialogContent className=\"max-h-[85vh] max-w-md overflow-y-auto\">\n <DialogHeader>\n <DialogTitle>Grant data access</DialogTitle>\n <DialogDescription>\n Give a workspace member scoped access to a dataset. Access is identified by the\n member&apos;s User ID.\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"grant-dataset\">Dataset</Label>\n <Select\n value={form.datasetId || undefined}\n onValueChange={(value) => setField('datasetId', value)}\n >\n <SelectTrigger id=\"grant-dataset\" aria-label=\"Dataset\">\n <SelectValue placeholder=\"Select a dataset\" />\n </SelectTrigger>\n <SelectContent>\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\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"grant-grantee\">Grantee (User ID)</Label>\n <Input\n id=\"grant-grantee\"\n value={form.granteeId}\n onChange={(event) => setField('granteeId', event.target.value)}\n placeholder=\"e.g. 4fe35990-…\"\n className=\"font-mono\"\n />\n <p className=\"text-xs text-text-secondary\">\n Paste the workspace member&apos;s User ID. You can copy it from the member&apos;s\n profile (&ldquo;Get ID&rdquo;) or the workspace member directory.\n </p>\n </div>\n\n <EntityTagsField\n value={form.scopes}\n onChange={(scopes) => setField('scopes', scopes)}\n label=\"Scopes\"\n placeholder=\"e.g. read, download\"\n />\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"grant-reason\">Reason</Label>\n <Textarea\n id=\"grant-reason\"\n value={form.reason}\n onChange={(event) => setField('reason', event.target.value)}\n rows={2}\n placeholder=\"Why this member needs access.\"\n />\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"grant-expires\">Expires (optional)</Label>\n <Input\n id=\"grant-expires\"\n type=\"datetime-local\"\n value={form.expiresAt}\n onChange={(event) => setField('expiresAt', event.target.value)}\n />\n <p className=\"text-xs text-text-secondary\">Leave blank for an open-ended grant.</p>\n </div>\n </div>\n\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setDialogOpen(false)}\n disabled={granting}\n >\n Cancel\n </Button>\n <Button type=\"button\" onClick={() => void submitGrant()} disabled={granting}>\n <KeyRound className=\"size-4\" />\n {granting ? 'Granting…' : 'Grant access'}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}