@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.
Files changed (164) 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 +102 -44
  4. package/dist/cosmicintersection/CosmicIntersectionRoutes.js.map +1 -1
  5. package/dist/cosmicintersection/api/cosmicApi.js +853 -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/EmptyState.js +35 -0
  10. package/dist/cosmicintersection/components/EmptyState.js.map +1 -0
  11. package/dist/cosmicintersection/components/EntityFormShell.js +57 -0
  12. package/dist/cosmicintersection/components/EntityFormShell.js.map +1 -0
  13. package/dist/cosmicintersection/components/EntityTagsField.js +77 -0
  14. package/dist/cosmicintersection/components/EntityTagsField.js.map +1 -0
  15. package/dist/cosmicintersection/components/ErrorState.js +40 -0
  16. package/dist/cosmicintersection/components/ErrorState.js.map +1 -0
  17. package/dist/cosmicintersection/components/FileUploadField.js +146 -0
  18. package/dist/cosmicintersection/components/FileUploadField.js.map +1 -0
  19. package/dist/cosmicintersection/components/LoadingState.js +23 -0
  20. package/dist/cosmicintersection/components/LoadingState.js.map +1 -0
  21. package/dist/cosmicintersection/components/PageLayout.js +46 -0
  22. package/dist/cosmicintersection/components/PageLayout.js.map +1 -0
  23. package/dist/cosmicintersection/components/Pagination.js +65 -0
  24. package/dist/cosmicintersection/components/Pagination.js.map +1 -0
  25. package/dist/cosmicintersection/components/SafeLink.js +35 -0
  26. package/dist/cosmicintersection/components/SafeLink.js.map +1 -0
  27. package/dist/cosmicintersection/components/StatusBadge.js +53 -0
  28. package/dist/cosmicintersection/components/StatusBadge.js.map +1 -0
  29. package/dist/cosmicintersection/components/index.js +11 -0
  30. package/dist/cosmicintersection/context/CosmicIntersectionContext.js +46 -0
  31. package/dist/cosmicintersection/context/CosmicIntersectionContext.js.map +1 -0
  32. package/dist/cosmicintersection/index.js +0 -2
  33. package/dist/cosmicintersection/lib/mutationResult.js +12 -0
  34. package/dist/cosmicintersection/lib/mutationResult.js.map +1 -0
  35. package/dist/cosmicintersection/lib/toast.js +36 -0
  36. package/dist/cosmicintersection/lib/toast.js.map +1 -0
  37. package/dist/cosmicintersection/pages/access/AccessPage.js +340 -0
  38. package/dist/cosmicintersection/pages/access/AccessPage.js.map +1 -0
  39. package/dist/cosmicintersection/pages/analyses/AnalysesPage.js +484 -0
  40. package/dist/cosmicintersection/pages/analyses/AnalysesPage.js.map +1 -0
  41. package/dist/cosmicintersection/pages/collections/CollectionDetailPage.js +164 -0
  42. package/dist/cosmicintersection/pages/collections/CollectionDetailPage.js.map +1 -0
  43. package/dist/cosmicintersection/pages/collections/CollectionFormPage.js +117 -0
  44. package/dist/cosmicintersection/pages/collections/CollectionFormPage.js.map +1 -0
  45. package/dist/cosmicintersection/pages/collections/CollectionsPage.js +103 -0
  46. package/dist/cosmicintersection/pages/collections/CollectionsPage.js.map +1 -0
  47. package/dist/cosmicintersection/pages/dashboard/DashboardPage.js +244 -0
  48. package/dist/cosmicintersection/pages/dashboard/DashboardPage.js.map +1 -0
  49. package/dist/cosmicintersection/pages/datasets/DatasetDetailPage.js +460 -0
  50. package/dist/cosmicintersection/pages/datasets/DatasetDetailPage.js.map +1 -0
  51. package/dist/cosmicintersection/pages/datasets/DatasetFormPage.js +218 -0
  52. package/dist/cosmicintersection/pages/datasets/DatasetFormPage.js.map +1 -0
  53. package/dist/cosmicintersection/pages/datasets/DatasetsPage.js +252 -0
  54. package/dist/cosmicintersection/pages/datasets/DatasetsPage.js.map +1 -0
  55. package/dist/cosmicintersection/pages/notebooks/NotebookDetailPage.js +393 -0
  56. package/dist/cosmicintersection/pages/notebooks/NotebookDetailPage.js.map +1 -0
  57. package/dist/cosmicintersection/pages/notebooks/NotebookFormPage.js +313 -0
  58. package/dist/cosmicintersection/pages/notebooks/NotebookFormPage.js.map +1 -0
  59. package/dist/cosmicintersection/pages/notebooks/NotebooksPage.js +203 -0
  60. package/dist/cosmicintersection/pages/notebooks/NotebooksPage.js.map +1 -0
  61. package/dist/cosmicintersection/pages/pipelines/PipelineDetailPage.js +244 -0
  62. package/dist/cosmicintersection/pages/pipelines/PipelineDetailPage.js.map +1 -0
  63. package/dist/cosmicintersection/pages/pipelines/PipelineFormPage.js +210 -0
  64. package/dist/cosmicintersection/pages/pipelines/PipelineFormPage.js.map +1 -0
  65. package/dist/cosmicintersection/pages/pipelines/PipelinesPage.js +193 -0
  66. package/dist/cosmicintersection/pages/pipelines/PipelinesPage.js.map +1 -0
  67. package/dist/cosmicintersection/pages/releases/ReleaseFormPage.js +184 -0
  68. package/dist/cosmicintersection/pages/releases/ReleaseFormPage.js.map +1 -0
  69. package/dist/cosmicintersection/pages/releases/ReleasesPage.js +368 -0
  70. package/dist/cosmicintersection/pages/releases/ReleasesPage.js.map +1 -0
  71. package/dist/cosmicintersection/pages/runs/RunDetailPage.js +375 -0
  72. package/dist/cosmicintersection/pages/runs/RunDetailPage.js.map +1 -0
  73. package/dist/cosmicintersection/pages/runs/RunsPage.js +180 -0
  74. package/dist/cosmicintersection/pages/runs/RunsPage.js.map +1 -0
  75. package/dist/cosmicintersection/pages/sources/SourceFormPage.js +229 -0
  76. package/dist/cosmicintersection/pages/sources/SourceFormPage.js.map +1 -0
  77. package/dist/cosmicintersection/pages/sources/SourcesPage.js +217 -0
  78. package/dist/cosmicintersection/pages/sources/SourcesPage.js.map +1 -0
  79. package/dist/cosmicintersection/utils/cn.js +10 -0
  80. package/dist/cosmicintersection/utils/cn.js.map +1 -0
  81. package/dist/index.js +2 -4
  82. package/dist/node_modules/clsx/dist/clsx.js +18 -0
  83. package/dist/node_modules/clsx/dist/clsx.js.map +1 -0
  84. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +1716 -0
  85. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
  86. package/package.json +2 -1
  87. package/dist/cosmicintersection/CosmicIntersectionRoot.d.ts +0 -5
  88. package/dist/cosmicintersection/CosmicIntersectionRoot.d.ts.map +0 -1
  89. package/dist/cosmicintersection/CosmicIntersectionRoutes.d.ts +0 -2
  90. package/dist/cosmicintersection/CosmicIntersectionRoutes.d.ts.map +0 -1
  91. package/dist/cosmicintersection/index.d.ts +0 -5
  92. package/dist/cosmicintersection/index.d.ts.map +0 -1
  93. package/dist/cosmicintersection/pages/AiDiscoveryPage.d.ts +0 -2
  94. package/dist/cosmicintersection/pages/AiDiscoveryPage.d.ts.map +0 -1
  95. package/dist/cosmicintersection/pages/AiDiscoveryPage.js +0 -363
  96. package/dist/cosmicintersection/pages/AiDiscoveryPage.js.map +0 -1
  97. package/dist/cosmicintersection/pages/DashboardPage.d.ts +0 -2
  98. package/dist/cosmicintersection/pages/DashboardPage.d.ts.map +0 -1
  99. package/dist/cosmicintersection/pages/DashboardPage.js +0 -306
  100. package/dist/cosmicintersection/pages/DashboardPage.js.map +0 -1
  101. package/dist/cosmicintersection/pages/SpaceScienceCitizenPage.d.ts +0 -2
  102. package/dist/cosmicintersection/pages/SpaceScienceCitizenPage.d.ts.map +0 -1
  103. package/dist/cosmicintersection/pages/SpaceScienceCitizenPage.js +0 -287
  104. package/dist/cosmicintersection/pages/SpaceScienceCitizenPage.js.map +0 -1
  105. package/dist/cosmicintersection/pages/SpaceScienceDataPage.d.ts +0 -2
  106. package/dist/cosmicintersection/pages/SpaceScienceDataPage.d.ts.map +0 -1
  107. package/dist/cosmicintersection/pages/SpaceScienceDataPage.js +0 -385
  108. package/dist/cosmicintersection/pages/SpaceScienceDataPage.js.map +0 -1
  109. package/dist/cosmicintersection/pages/SpaceScienceDataPage1.d.ts +0 -2
  110. package/dist/cosmicintersection/pages/SpaceScienceDataPage1.d.ts.map +0 -1
  111. package/dist/cosmicintersection/pages/SpaceScienceDataPage1.js +0 -420
  112. package/dist/cosmicintersection/pages/SpaceScienceDataPage1.js.map +0 -1
  113. package/dist/cosmicintersection/pages/SpaceScienceLearningPage.d.ts +0 -2
  114. package/dist/cosmicintersection/pages/SpaceScienceLearningPage.d.ts.map +0 -1
  115. package/dist/cosmicintersection/pages/SpaceScienceLearningPage.js +0 -309
  116. package/dist/cosmicintersection/pages/SpaceScienceLearningPage.js.map +0 -1
  117. package/dist/cosmicintersection/pages/SpaceScienceLearningPage1.d.ts +0 -2
  118. package/dist/cosmicintersection/pages/SpaceScienceLearningPage1.d.ts.map +0 -1
  119. package/dist/cosmicintersection/pages/SpaceScienceLearningPage1.js +0 -361
  120. package/dist/cosmicintersection/pages/SpaceScienceLearningPage1.js.map +0 -1
  121. package/dist/cosmicintersection/pages/SpaceSciencePage.d.ts +0 -2
  122. package/dist/cosmicintersection/pages/SpaceSciencePage.d.ts.map +0 -1
  123. package/dist/cosmicintersection/pages/SpaceSciencePage.js +0 -194
  124. package/dist/cosmicintersection/pages/SpaceSciencePage.js.map +0 -1
  125. package/dist/cosmicintersection/pages/SpaceScienceResearchPage.d.ts +0 -2
  126. package/dist/cosmicintersection/pages/SpaceScienceResearchPage.d.ts.map +0 -1
  127. package/dist/cosmicintersection/pages/SpaceScienceResearchPage.js +0 -290
  128. package/dist/cosmicintersection/pages/SpaceScienceResearchPage.js.map +0 -1
  129. package/dist/cosmicintersection/pages/SpaceScienceSimulationPage.d.ts +0 -2
  130. package/dist/cosmicintersection/pages/SpaceScienceSimulationPage.d.ts.map +0 -1
  131. package/dist/cosmicintersection/pages/SpaceScienceSimulationPage.js +0 -279
  132. package/dist/cosmicintersection/pages/SpaceScienceSimulationPage.js.map +0 -1
  133. package/dist/cosmicintersection/providers/CosmicIntersectionProvider.d.ts +0 -6
  134. package/dist/cosmicintersection/providers/CosmicIntersectionProvider.d.ts.map +0 -1
  135. package/dist/cosmicintersection/providers/CosmicIntersectionProvider.js +0 -27
  136. package/dist/cosmicintersection/providers/CosmicIntersectionProvider.js.map +0 -1
  137. package/dist/cosmicintersection/store/cosmicintersectionStore.d.ts +0 -18
  138. package/dist/cosmicintersection/store/cosmicintersectionStore.d.ts.map +0 -1
  139. package/dist/cosmicintersection/store/cosmicintersectionStore.js +0 -478
  140. package/dist/cosmicintersection/store/cosmicintersectionStore.js.map +0 -1
  141. package/dist/cosmicintersection/types/index.d.ts +0 -109
  142. package/dist/cosmicintersection/types/index.d.ts.map +0 -1
  143. package/dist/cosmicintersection/utils/cn.d.ts +0 -4
  144. package/dist/cosmicintersection/utils/cn.d.ts.map +0 -1
  145. package/dist/cosmicintersection/utils/i18n.d.ts +0 -6
  146. package/dist/cosmicintersection/utils/i18n.d.ts.map +0 -1
  147. package/dist/cosmicintersection/utils/i18n.js +0 -15
  148. package/dist/cosmicintersection/utils/i18n.js.map +0 -1
  149. package/dist/cosmicintersection/utils/navigation.d.ts +0 -2
  150. package/dist/cosmicintersection/utils/navigation.d.ts.map +0 -1
  151. package/dist/cosmicintersection/utils/navigation.js +0 -8
  152. package/dist/cosmicintersection/utils/navigation.js.map +0 -1
  153. package/dist/dev/main.d.ts +0 -2
  154. package/dist/dev/main.d.ts.map +0 -1
  155. package/dist/generated/global-operations.d.ts +0 -2
  156. package/dist/generated/global-operations.d.ts.map +0 -1
  157. package/dist/generated/global-types.d.ts +0 -18199
  158. package/dist/generated/global-types.d.ts.map +0 -1
  159. package/dist/generated/wspace-operations.d.ts +0 -2
  160. package/dist/generated/wspace-operations.d.ts.map +0 -1
  161. package/dist/generated/wspace-types.d.ts +0 -43046
  162. package/dist/generated/wspace-types.d.ts.map +0 -1
  163. package/dist/index.d.ts +0 -2
  164. package/dist/index.d.ts.map +0 -1
@@ -0,0 +1,164 @@
1
+ import { useCosmicIntersection as e } from "../../context/CosmicIntersectionContext.js";
2
+ import { useCosCollectionsQuery as t, useCosDatasetsQuery as n } from "../../api/cosmicApi.js";
3
+ import r from "../../components/ActionMenu.js";
4
+ import i from "../../components/EmptyState.js";
5
+ import a from "../../components/ErrorState.js";
6
+ import o from "../../components/LoadingState.js";
7
+ import s from "../../components/PageLayout.js";
8
+ import c, { usePagination as l } from "../../components/Pagination.js";
9
+ import u from "../../components/StatusBadge.js";
10
+ import "../../components/index.js";
11
+ import { useMemo as d } from "react";
12
+ import { Fragment as f, jsx as p, jsxs as m } from "react/jsx-runtime";
13
+ import { useParams as h } from "react-router-dom";
14
+ import { Database as g, FolderOpen as _, Globe as v, Lock as y } from "lucide-react";
15
+ import { Badge as b, Table as x, TableBody as S, TableCell as C, TableHead as w, TableHeader as T, TableRow as E } from "@burdenoff/fe-libs/ui";
16
+ //#region src/cosmicintersection/pages/collections/CollectionDetailPage.tsx
17
+ function D(e) {
18
+ if (!e) return "—";
19
+ let t = new Date(e);
20
+ return Number.isNaN(t.getTime()) ? "—" : t.toLocaleDateString(void 0, {
21
+ year: "numeric",
22
+ month: "short",
23
+ day: "numeric"
24
+ });
25
+ }
26
+ function O() {
27
+ let { id: O = "" } = h(), { navigate: k } = e(), { data: A, loading: j, error: M, refetch: N } = t(), P = d(() => A?.cosListCollections.find((e) => e.id === O) ?? null, [A, O]), F = l({
28
+ pageSize: 20,
29
+ resetKey: O
30
+ }), { data: I, loading: L, error: R, refetch: z } = n({
31
+ collectionId: O,
32
+ pagination: {
33
+ limit: F.limit,
34
+ offset: F.offset
35
+ }
36
+ }), B = I?.cosListDatasets.items ?? [], V = I?.cosListDatasets.pageInfo;
37
+ return j ? /* @__PURE__ */ p(s, {
38
+ title: "Collection",
39
+ backPath: "collections",
40
+ children: /* @__PURE__ */ p(o, { label: "Loading collection…" })
41
+ }) : M ? /* @__PURE__ */ p(s, {
42
+ title: "Collection",
43
+ backPath: "collections",
44
+ children: /* @__PURE__ */ p(a, {
45
+ message: M.message,
46
+ onRetry: () => void N()
47
+ })
48
+ }) : P ? /* @__PURE__ */ p(s, {
49
+ title: P.name,
50
+ description: P.slug ? `/${P.slug}` : void 0,
51
+ backPath: "collections",
52
+ actions: P.isPublic ? /* @__PURE__ */ m(b, {
53
+ variant: "outline",
54
+ className: "gap-1 border-status-success-border bg-status-success-bg-subtle text-status-success-text",
55
+ children: [/* @__PURE__ */ p(v, {
56
+ className: "size-3",
57
+ "aria-hidden": "true"
58
+ }), "Public"]
59
+ }) : /* @__PURE__ */ m(b, {
60
+ variant: "secondary",
61
+ className: "gap-1",
62
+ children: [/* @__PURE__ */ p(y, {
63
+ className: "size-3",
64
+ "aria-hidden": "true"
65
+ }), "Private"]
66
+ }),
67
+ children: /* @__PURE__ */ m("div", {
68
+ className: "space-y-6",
69
+ children: [/* @__PURE__ */ m("div", {
70
+ className: "rounded-card border border-border-default bg-bg-elevated p-5",
71
+ children: [
72
+ /* @__PURE__ */ p("h2", {
73
+ className: "text-sm font-semibold text-text-primary",
74
+ children: "About"
75
+ }),
76
+ /* @__PURE__ */ p("p", {
77
+ className: "mt-2 text-sm text-text-secondary",
78
+ children: P.description ?? "No description provided."
79
+ }),
80
+ P.tags.length > 0 ? /* @__PURE__ */ p("div", {
81
+ className: "mt-4 flex flex-wrap gap-1",
82
+ children: P.tags.map((e) => /* @__PURE__ */ p(b, {
83
+ variant: "outline",
84
+ className: "text-xs",
85
+ children: e
86
+ }, e))
87
+ }) : null
88
+ ]
89
+ }), /* @__PURE__ */ m("div", {
90
+ className: "space-y-3",
91
+ children: [/* @__PURE__ */ p("h2", {
92
+ className: "text-sm font-semibold text-text-primary",
93
+ children: "Datasets"
94
+ }), L ? /* @__PURE__ */ p(o, {
95
+ variant: "rows",
96
+ rows: 4,
97
+ label: "Loading datasets…"
98
+ }) : R ? /* @__PURE__ */ p(a, {
99
+ message: R.message,
100
+ onRetry: () => void z()
101
+ }) : B.length === 0 ? /* @__PURE__ */ p(i, {
102
+ icon: g,
103
+ title: "No datasets in this collection",
104
+ description: "Assign a dataset to this collection to see it listed here."
105
+ }) : /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p("div", {
106
+ className: "overflow-hidden rounded-card border border-border-default bg-bg-elevated",
107
+ children: /* @__PURE__ */ m(x, { children: [/* @__PURE__ */ p(T, { children: /* @__PURE__ */ m(E, { children: [
108
+ /* @__PURE__ */ p(w, { children: "Name" }),
109
+ /* @__PURE__ */ p(w, { children: "Status" }),
110
+ /* @__PURE__ */ p(w, { children: "Access" }),
111
+ /* @__PURE__ */ p(w, { children: "Updated" }),
112
+ /* @__PURE__ */ p(w, {
113
+ className: "text-right",
114
+ children: "Actions"
115
+ })
116
+ ] }) }), /* @__PURE__ */ p(S, { children: B.map((e) => /* @__PURE__ */ m(E, {
117
+ className: "cursor-pointer",
118
+ onClick: () => k(`datasets/${e.id}`),
119
+ children: [
120
+ /* @__PURE__ */ p(C, {
121
+ className: "font-medium text-text-primary",
122
+ children: e.name
123
+ }),
124
+ /* @__PURE__ */ p(C, { children: /* @__PURE__ */ p(u, { status: e.status }) }),
125
+ /* @__PURE__ */ p(C, { children: /* @__PURE__ */ p(u, { status: e.accessLevel }) }),
126
+ /* @__PURE__ */ p(C, {
127
+ className: "whitespace-nowrap text-sm text-text-secondary",
128
+ children: D(e.updatedAt)
129
+ }),
130
+ /* @__PURE__ */ p(C, {
131
+ className: "text-right",
132
+ children: /* @__PURE__ */ p(r, {
133
+ ariaLabel: `Actions for ${e.name}`,
134
+ onView: () => k(`datasets/${e.id}`)
135
+ })
136
+ })
137
+ ]
138
+ }, e.id)) })] })
139
+ }), /* @__PURE__ */ p(c, {
140
+ offset: F.offset,
141
+ limit: F.limit,
142
+ loadedCount: B.length,
143
+ hasMore: V?.hasMore ?? !1,
144
+ onPrev: F.prevPage,
145
+ onNext: F.nextPage,
146
+ itemLabel: "datasets",
147
+ loading: L
148
+ })] })]
149
+ })]
150
+ })
151
+ }) : /* @__PURE__ */ p(s, {
152
+ title: "Collection",
153
+ backPath: "collections",
154
+ children: /* @__PURE__ */ p(i, {
155
+ icon: _,
156
+ title: "Collection not found",
157
+ description: "This collection may have been removed or you may not have access to it."
158
+ })
159
+ });
160
+ }
161
+ //#endregion
162
+ export { O as default };
163
+
164
+ //# sourceMappingURL=CollectionDetailPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CollectionDetailPage.js","names":[],"sources":["../../../../src/cosmicintersection/pages/collections/CollectionDetailPage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { Database, FolderOpen, Globe, Lock } from 'lucide-react';\nimport {\n Badge,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@burdenoff/fe-libs/ui';\n\nimport { useCosCollectionsQuery, useCosDatasetsQuery } from '../../api/cosmicApi';\nimport {\n ActionMenu,\n EmptyState,\n ErrorState,\n LoadingState,\n PageLayout,\n Pagination,\n StatusBadge,\n usePagination,\n} from '../../components';\nimport { useCosmicIntersection } from '../../context/CosmicIntersectionContext';\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 CollectionDetailPage() {\n const { id = '' } = useParams<{ id: string }>();\n const { navigate } = useCosmicIntersection();\n\n // No cosCollection(id) query exists — resolve the header from the list query.\n const {\n data: collectionsData,\n loading: loadingCollections,\n error: collectionsError,\n refetch: refetchCollections,\n } = useCosCollectionsQuery();\n\n const collection = useMemo(\n () => collectionsData?.cosListCollections.find((item) => item.id === id) ?? null,\n [collectionsData, id]\n );\n\n const pagination = usePagination({ pageSize: 20, resetKey: id });\n const {\n data: datasetsData,\n loading: loadingDatasets,\n error: datasetsError,\n refetch: refetchDatasets,\n } = useCosDatasetsQuery({\n collectionId: id,\n pagination: { limit: pagination.limit, offset: pagination.offset },\n });\n\n const datasets = datasetsData?.cosListDatasets.items ?? [];\n const pageInfo = datasetsData?.cosListDatasets.pageInfo;\n\n if (loadingCollections) {\n return (\n <PageLayout title=\"Collection\" backPath=\"collections\">\n <LoadingState label=\"Loading collection…\" />\n </PageLayout>\n );\n }\n\n if (collectionsError) {\n return (\n <PageLayout title=\"Collection\" backPath=\"collections\">\n <ErrorState message={collectionsError.message} onRetry={() => void refetchCollections()} />\n </PageLayout>\n );\n }\n\n if (!collection) {\n return (\n <PageLayout title=\"Collection\" backPath=\"collections\">\n <EmptyState\n icon={FolderOpen}\n title=\"Collection not found\"\n description=\"This collection may have been removed or you may not have access to it.\"\n />\n </PageLayout>\n );\n }\n\n const renderDatasets = () => {\n if (loadingDatasets) {\n return <LoadingState variant=\"rows\" rows={4} label=\"Loading datasets…\" />;\n }\n if (datasetsError) {\n return <ErrorState message={datasetsError.message} onRetry={() => void refetchDatasets()} />;\n }\n if (datasets.length === 0) {\n return (\n <EmptyState\n icon={Database}\n title=\"No datasets in this collection\"\n description=\"Assign a dataset to this collection to see it listed here.\"\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>Status</TableHead>\n <TableHead>Access</TableHead>\n <TableHead>Updated</TableHead>\n <TableHead className=\"text-right\">Actions</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {datasets.map((dataset) => (\n <TableRow\n key={dataset.id}\n className=\"cursor-pointer\"\n onClick={() => navigate(`datasets/${dataset.id}`)}\n >\n <TableCell className=\"font-medium text-text-primary\">{dataset.name}</TableCell>\n <TableCell>\n <StatusBadge status={dataset.status} />\n </TableCell>\n <TableCell>\n <StatusBadge status={dataset.accessLevel} />\n </TableCell>\n <TableCell className=\"whitespace-nowrap text-sm text-text-secondary\">\n {formatDate(dataset.updatedAt)}\n </TableCell>\n <TableCell className=\"text-right\">\n <ActionMenu\n ariaLabel={`Actions for ${dataset.name}`}\n onView={() => navigate(`datasets/${dataset.id}`)}\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={datasets.length}\n hasMore={pageInfo?.hasMore ?? false}\n onPrev={pagination.prevPage}\n onNext={pagination.nextPage}\n itemLabel=\"datasets\"\n loading={loadingDatasets}\n />\n </>\n );\n };\n\n return (\n <PageLayout\n title={collection.name}\n description={collection.slug ? `/${collection.slug}` : undefined}\n backPath=\"collections\"\n actions={\n collection.isPublic ? (\n <Badge\n variant=\"outline\"\n className=\"gap-1 border-status-success-border bg-status-success-bg-subtle text-status-success-text\"\n >\n <Globe className=\"size-3\" aria-hidden=\"true\" />\n Public\n </Badge>\n ) : (\n <Badge variant=\"secondary\" className=\"gap-1\">\n <Lock className=\"size-3\" aria-hidden=\"true\" />\n Private\n </Badge>\n )\n }\n >\n <div className=\"space-y-6\">\n <div className=\"rounded-card border border-border-default bg-bg-elevated p-5\">\n <h2 className=\"text-sm font-semibold text-text-primary\">About</h2>\n <p className=\"mt-2 text-sm text-text-secondary\">\n {collection.description ?? 'No description provided.'}\n </p>\n {collection.tags.length > 0 ? (\n <div className=\"mt-4 flex flex-wrap gap-1\">\n {collection.tags.map((tag) => (\n <Badge key={tag} variant=\"outline\" className=\"text-xs\">\n {tag}\n </Badge>\n ))}\n </div>\n ) : null}\n </div>\n\n <div className=\"space-y-3\">\n <h2 className=\"text-sm font-semibold text-text-primary\">Datasets</h2>\n {renderDatasets()}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA0BA,SAAS,EAAW,GAA+B;AACjD,KAAI,CAAC,EACH,QAAO;CAET,IAAM,IAAS,IAAI,KAAK,EAAM;AAI9B,QAHI,OAAO,MAAM,EAAO,SAAS,CAAC,GACzB,MAEF,EAAO,mBAAmB,KAAA,GAAW;EAAE,MAAM;EAAW,OAAO;EAAS,KAAK;EAAW,CAAC;;AAGlG,SAAwB,IAAuB;CAC7C,IAAM,EAAE,QAAK,OAAO,GAA2B,EACzC,EAAE,gBAAa,GAAuB,EAGtC,EACJ,MAAM,GACN,SAAS,GACT,OAAO,GACP,SAAS,MACP,GAAwB,EAEtB,IAAa,QACX,GAAiB,mBAAmB,MAAM,MAAS,EAAK,OAAO,EAAG,IAAI,MAC5E,CAAC,GAAiB,EAAG,CACtB,EAEK,IAAa,EAAc;EAAE,UAAU;EAAI,UAAU;EAAI,CAAC,EAC1D,EACJ,MAAM,GACN,SAAS,GACT,OAAO,GACP,SAAS,MACP,EAAoB;EACtB,cAAc;EACd,YAAY;GAAE,OAAO,EAAW;GAAO,QAAQ,EAAW;GAAQ;EACnE,CAAC,EAEI,IAAW,GAAc,gBAAgB,SAAS,EAAE,EACpD,IAAW,GAAc,gBAAgB;AAuG/C,QArGI,IAEA,kBAAC,GAAD;EAAY,OAAM;EAAa,UAAS;YACtC,kBAAC,GAAD,EAAc,OAAM,uBAAwB,CAAA;EACjC,CAAA,GAIb,IAEA,kBAAC,GAAD;EAAY,OAAM;EAAa,UAAS;YACtC,kBAAC,GAAD;GAAY,SAAS,EAAiB;GAAS,eAAe,KAAK,GAAoB;GAAI,CAAA;EAChF,CAAA,GAIZ,IAsFH,kBAAC,GAAD;EACE,OAAO,EAAW;EAClB,aAAa,EAAW,OAAO,IAAI,EAAW,SAAS,KAAA;EACvD,UAAS;EACT,SACE,EAAW,WACT,kBAAC,GAAD;GACE,SAAQ;GACR,WAAU;aAFZ,CAIE,kBAAC,GAAD;IAAO,WAAU;IAAS,eAAY;IAAS,CAAA,EAAA,SAEzC;OAER,kBAAC,GAAD;GAAO,SAAQ;GAAY,WAAU;aAArC,CACE,kBAAC,GAAD;IAAM,WAAU;IAAS,eAAY;IAAS,CAAA,EAAA,UAExC;;YAIZ,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,MAAD;MAAI,WAAU;gBAA0C;MAAU,CAAA;KAClE,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAW,eAAe;MACzB,CAAA;KACH,EAAW,KAAK,SAAS,IACxB,kBAAC,OAAD;MAAK,WAAU;gBACZ,EAAW,KAAK,KAAK,MACpB,kBAAC,GAAD;OAAiB,SAAQ;OAAU,WAAU;iBAC1C;OACK,EAFI,EAEJ,CACR;MACE,CAAA,GACJ;KACA;OAEN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,MAAD;KAAI,WAAU;eAA0C;KAAa,CAAA,EAhHvE,IACK,kBAAC,GAAD;KAAc,SAAQ;KAAO,MAAM;KAAG,OAAM;KAAsB,CAAA,GAEvE,IACK,kBAAC,GAAD;KAAY,SAAS,EAAc;KAAS,eAAe,KAAK,GAAiB;KAAI,CAAA,GAE1F,EAAS,WAAW,IAEpB,kBAAC,GAAD;KACE,MAAM;KACN,OAAM;KACN,aAAY;KACZ,CAAA,GAKJ,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAA;MACE,kBAAC,GAAD,EAAA,UAAW,QAAgB,CAAA;MAC3B,kBAAC,GAAD,EAAA,UAAW,UAAkB,CAAA;MAC7B,kBAAC,GAAD,EAAA,UAAW,UAAkB,CAAA;MAC7B,kBAAC,GAAD,EAAA,UAAW,WAAmB,CAAA;MAC9B,kBAAC,GAAD;OAAW,WAAU;iBAAa;OAAmB,CAAA;MAC5C,EAAA,CAAA,EACC,CAAA,EACd,kBAAC,GAAD,EAAA,UACG,EAAS,KAAK,MACb,kBAAC,GAAD;MAEE,WAAU;MACV,eAAe,EAAS,YAAY,EAAQ,KAAK;gBAHnD;OAKE,kBAAC,GAAD;QAAW,WAAU;kBAAiC,EAAQ;QAAiB,CAAA;OAC/E,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAa,QAAQ,EAAQ,QAAU,CAAA,EAC7B,CAAA;OACZ,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAa,QAAQ,EAAQ,aAAe,CAAA,EAClC,CAAA;OACZ,kBAAC,GAAD;QAAW,WAAU;kBAClB,EAAW,EAAQ,UAAU;QACpB,CAAA;OACZ,kBAAC,GAAD;QAAW,WAAU;kBACnB,kBAAC,GAAD;SACE,WAAW,eAAe,EAAQ;SAClC,cAAc,EAAS,YAAY,EAAQ,KAAK;SAChD,CAAA;QACQ,CAAA;OACH;QApBJ,EAAQ,GAoBJ,CACX,EACQ,CAAA,CACN,EAAA,CAAA;KACJ,CAAA,EAEN,kBAAC,GAAD;KACE,QAAQ,EAAW;KACnB,OAAO,EAAW;KAClB,aAAa,EAAS;KACtB,SAAS,GAAU,WAAW;KAC9B,QAAQ,EAAW;KACnB,QAAQ,EAAW;KACnB,WAAU;KACV,SAAS;KACT,CAAA,CACD,EAAA,CAAA,CA8CK;MACF;;EACK,CAAA,GA/HX,kBAAC,GAAD;EAAY,OAAM;EAAa,UAAS;YACtC,kBAAC,GAAD;GACE,MAAM;GACN,OAAM;GACN,aAAY;GACZ,CAAA;EACS,CAAA"}
@@ -0,0 +1,117 @@
1
+ import { useCosmicIntersection as e } from "../../context/CosmicIntersectionContext.js";
2
+ import { notify as t } from "../../lib/toast.js";
3
+ import { useCosCreateCollectionMutation as n } from "../../api/cosmicApi.js";
4
+ import r from "../../components/EntityFormShell.js";
5
+ import i from "../../components/EntityTagsField.js";
6
+ import "../../components/index.js";
7
+ import { useState as a } from "react";
8
+ import { jsx as o, jsxs as s } from "react/jsx-runtime";
9
+ import { Input as c, Switch as l, Textarea as u } from "@burdenoff/fe-libs/ui";
10
+ //#region src/cosmicintersection/pages/collections/CollectionFormPage.tsx
11
+ var d = {
12
+ name: "",
13
+ slug: "",
14
+ description: "",
15
+ isPublic: !1,
16
+ tags: []
17
+ }, f = "block space-y-1.5 text-sm", p = "font-medium text-text-primary";
18
+ function m() {
19
+ let { navigate: m } = e(), [h, { loading: g }] = n(), [_, v] = a(d), y = (e, t) => {
20
+ v((n) => ({
21
+ ...n,
22
+ [e]: t
23
+ }));
24
+ }, b = async (e) => {
25
+ if (e.preventDefault(), !_.name.trim()) {
26
+ t.error("Name is required", "Give this collection a recognizable name.");
27
+ return;
28
+ }
29
+ let n = (await h({ variables: { input: {
30
+ name: _.name.trim(),
31
+ slug: _.slug.trim() || void 0,
32
+ description: _.description.trim() || void 0,
33
+ isPublic: _.isPublic,
34
+ tags: _.tags
35
+ } } })).data?.cosCreateCollection;
36
+ n?.id && (t.success("Collection created"), m(`collections/${n.id}`));
37
+ };
38
+ return /* @__PURE__ */ s(r, {
39
+ title: "New collection",
40
+ description: "Group related datasets into a shareable, themed collection.",
41
+ purpose: "Collections curate datasets by mission, survey or research theme so collaborators can browse a coherent set instead of a flat list. Mark a collection public to make it discoverable across the workspace.",
42
+ backLabel: "Back to collections",
43
+ onBack: () => m("collections"),
44
+ onSubmit: (e) => void b(e),
45
+ submitLabel: "Create collection",
46
+ saving: g,
47
+ children: [
48
+ /* @__PURE__ */ s("div", {
49
+ className: "grid grid-cols-1 gap-4 md:grid-cols-2",
50
+ children: [/* @__PURE__ */ s("label", {
51
+ className: f,
52
+ children: [/* @__PURE__ */ o("span", {
53
+ className: p,
54
+ children: "Name"
55
+ }), /* @__PURE__ */ o(c, {
56
+ value: _.name,
57
+ onChange: (e) => y("name", e.target.value),
58
+ placeholder: "e.g. Kepler Mission Data",
59
+ required: !0
60
+ })]
61
+ }), /* @__PURE__ */ s("label", {
62
+ className: f,
63
+ children: [
64
+ /* @__PURE__ */ o("span", {
65
+ className: p,
66
+ children: "Slug"
67
+ }),
68
+ /* @__PURE__ */ o(c, {
69
+ value: _.slug,
70
+ onChange: (e) => y("slug", e.target.value),
71
+ placeholder: "kepler-mission"
72
+ }),
73
+ /* @__PURE__ */ o("span", {
74
+ className: "text-xs text-text-secondary",
75
+ children: "Optional URL-friendly identifier for sharing."
76
+ })
77
+ ]
78
+ })]
79
+ }),
80
+ /* @__PURE__ */ s("label", {
81
+ className: f,
82
+ children: [/* @__PURE__ */ o("span", {
83
+ className: p,
84
+ children: "Description"
85
+ }), /* @__PURE__ */ o(u, {
86
+ value: _.description,
87
+ onChange: (e) => y("description", e.target.value),
88
+ rows: 3,
89
+ placeholder: "What this collection groups together and who it is for."
90
+ })]
91
+ }),
92
+ /* @__PURE__ */ s("div", {
93
+ className: "flex items-center justify-between gap-4 rounded-card border border-border-default bg-bg-sunken px-4 py-3",
94
+ children: [/* @__PURE__ */ s("div", { children: [/* @__PURE__ */ o("p", {
95
+ className: "text-sm font-medium text-text-primary",
96
+ children: "Public collection"
97
+ }), /* @__PURE__ */ o("p", {
98
+ className: "text-xs text-text-secondary",
99
+ children: "Make this collection discoverable across the workspace."
100
+ })] }), /* @__PURE__ */ o(l, {
101
+ checked: _.isPublic,
102
+ onCheckedChange: (e) => y("isPublic", e),
103
+ "aria-label": "Public collection"
104
+ })]
105
+ }),
106
+ /* @__PURE__ */ o(i, {
107
+ value: _.tags,
108
+ onChange: (e) => y("tags", e),
109
+ disabled: g
110
+ })
111
+ ]
112
+ });
113
+ }
114
+ //#endregion
115
+ export { m as default };
116
+
117
+ //# sourceMappingURL=CollectionFormPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CollectionFormPage.js","names":[],"sources":["../../../../src/cosmicintersection/pages/collections/CollectionFormPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { Input, Switch, Textarea } from '@burdenoff/fe-libs/ui';\n\nimport { useCosCreateCollectionMutation } from '../../api/cosmicApi';\nimport { EntityFormShell, EntityTagsField } from '../../components';\nimport { useCosmicIntersection } from '../../context/CosmicIntersectionContext';\nimport { notify } from '../../lib/toast';\n\ninterface CollectionFormState {\n name: string;\n slug: string;\n description: string;\n isPublic: boolean;\n tags: string[];\n}\n\nconst INITIAL_STATE: CollectionFormState = {\n name: '',\n slug: '',\n description: '',\n isPublic: false,\n tags: [],\n};\n\nconst fieldLabelClass = 'block space-y-1.5 text-sm';\nconst fieldSpanClass = 'font-medium text-text-primary';\n\nexport default function CollectionFormPage() {\n const { navigate } = useCosmicIntersection();\n const [createCollection, { loading: creating }] = useCosCreateCollectionMutation();\n const [form, setForm] = useState<CollectionFormState>(INITIAL_STATE);\n\n const onChange = <K extends keyof CollectionFormState>(\n field: K,\n value: CollectionFormState[K]\n ) => {\n setForm((prev) => ({ ...prev, [field]: value }));\n };\n\n const onSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n\n if (!form.name.trim()) {\n notify.error('Name is required', 'Give this collection a recognizable name.');\n return;\n }\n\n const response = await createCollection({\n variables: {\n input: {\n name: form.name.trim(),\n slug: form.slug.trim() || undefined,\n description: form.description.trim() || undefined,\n isPublic: form.isPublic,\n tags: form.tags,\n },\n },\n });\n\n const created = response.data?.cosCreateCollection;\n if (created?.id) {\n notify.success('Collection created');\n navigate(`collections/${created.id}`);\n }\n };\n\n return (\n <EntityFormShell\n title=\"New collection\"\n description=\"Group related datasets into a shareable, themed collection.\"\n purpose=\"Collections curate datasets by mission, survey or research theme so collaborators can browse a coherent set instead of a flat list. Mark a collection public to make it discoverable across the workspace.\"\n backLabel=\"Back to collections\"\n onBack={() => navigate('collections')}\n onSubmit={(event) => void onSubmit(event)}\n submitLabel=\"Create collection\"\n saving={creating}\n >\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n <label className={fieldLabelClass}>\n <span className={fieldSpanClass}>Name</span>\n <Input\n value={form.name}\n onChange={(event) => onChange('name', event.target.value)}\n placeholder=\"e.g. Kepler Mission Data\"\n required\n />\n </label>\n <label className={fieldLabelClass}>\n <span className={fieldSpanClass}>Slug</span>\n <Input\n value={form.slug}\n onChange={(event) => onChange('slug', event.target.value)}\n placeholder=\"kepler-mission\"\n />\n <span className=\"text-xs text-text-secondary\">\n Optional URL-friendly identifier for sharing.\n </span>\n </label>\n </div>\n\n <label className={fieldLabelClass}>\n <span className={fieldSpanClass}>Description</span>\n <Textarea\n value={form.description}\n onChange={(event) => onChange('description', event.target.value)}\n rows={3}\n placeholder=\"What this collection groups together and who it is for.\"\n />\n </label>\n\n <div className=\"flex items-center justify-between gap-4 rounded-card border border-border-default bg-bg-sunken px-4 py-3\">\n <div>\n <p className=\"text-sm font-medium text-text-primary\">Public collection</p>\n <p className=\"text-xs text-text-secondary\">\n Make this collection discoverable across the workspace.\n </p>\n </div>\n <Switch\n checked={form.isPublic}\n onCheckedChange={(checked) => onChange('isPublic', checked)}\n aria-label=\"Public collection\"\n />\n </div>\n\n <EntityTagsField\n value={form.tags}\n onChange={(tags) => onChange('tags', tags)}\n disabled={creating}\n />\n </EntityFormShell>\n );\n}\n"],"mappings":";;;;;;;;;;AAgBA,IAAM,IAAqC;CACzC,MAAM;CACN,MAAM;CACN,aAAa;CACb,UAAU;CACV,MAAM,EAAE;CACT,EAEK,IAAkB,6BAClB,IAAiB;AAEvB,SAAwB,IAAqB;CAC3C,IAAM,EAAE,gBAAa,GAAuB,EACtC,CAAC,GAAkB,EAAE,SAAS,OAAc,GAAgC,EAC5E,CAAC,GAAM,KAAW,EAA8B,EAAc,EAE9D,KACJ,GACA,MACG;AACH,KAAS,OAAU;GAAE,GAAG;IAAO,IAAQ;GAAO,EAAE;IAG5C,IAAW,OAAO,MAA4C;AAGlE,MAFA,EAAM,gBAAgB,EAElB,CAAC,EAAK,KAAK,MAAM,EAAE;AACrB,KAAO,MAAM,oBAAoB,4CAA4C;AAC7E;;EAeF,IAAM,KAZW,MAAM,EAAiB,EACtC,WAAW,EACT,OAAO;GACL,MAAM,EAAK,KAAK,MAAM;GACtB,MAAM,EAAK,KAAK,MAAM,IAAI,KAAA;GAC1B,aAAa,EAAK,YAAY,MAAM,IAAI,KAAA;GACxC,UAAU,EAAK;GACf,MAAM,EAAK;GACZ,EACF,EACF,CAAC,EAEuB,MAAM;AAC/B,EAAI,GAAS,OACX,EAAO,QAAQ,qBAAqB,EACpC,EAAS,eAAe,EAAQ,KAAK;;AAIzC,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SAAQ;EACR,WAAU;EACV,cAAc,EAAS,cAAc;EACrC,WAAW,MAAU,KAAK,EAAS,EAAM;EACzC,aAAY;EACZ,QAAQ;YARV;GAUE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,SAAD;KAAO,WAAW;eAAlB,CACE,kBAAC,QAAD;MAAM,WAAW;gBAAgB;MAAW,CAAA,EAC5C,kBAAC,GAAD;MACE,OAAO,EAAK;MACZ,WAAW,MAAU,EAAS,QAAQ,EAAM,OAAO,MAAM;MACzD,aAAY;MACZ,UAAA;MACA,CAAA,CACI;QACR,kBAAC,SAAD;KAAO,WAAW;eAAlB;MACE,kBAAC,QAAD;OAAM,WAAW;iBAAgB;OAAW,CAAA;MAC5C,kBAAC,GAAD;OACE,OAAO,EAAK;OACZ,WAAW,MAAU,EAAS,QAAQ,EAAM,OAAO,MAAM;OACzD,aAAY;OACZ,CAAA;MACF,kBAAC,QAAD;OAAM,WAAU;iBAA8B;OAEvC,CAAA;MACD;OACJ;;GAEN,kBAAC,SAAD;IAAO,WAAW;cAAlB,CACE,kBAAC,QAAD;KAAM,WAAW;eAAgB;KAAkB,CAAA,EACnD,kBAAC,GAAD;KACE,OAAO,EAAK;KACZ,WAAW,MAAU,EAAS,eAAe,EAAM,OAAO,MAAM;KAChE,MAAM;KACN,aAAY;KACZ,CAAA,CACI;;GAER,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;KAAG,WAAU;eAAwC;KAAqB,CAAA,EAC1E,kBAAC,KAAD;KAAG,WAAU;eAA8B;KAEvC,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,GAAD;KACE,SAAS,EAAK;KACd,kBAAkB,MAAY,EAAS,YAAY,EAAQ;KAC3D,cAAW;KACX,CAAA,CACE;;GAEN,kBAAC,GAAD;IACE,OAAO,EAAK;IACZ,WAAW,MAAS,EAAS,QAAQ,EAAK;IAC1C,UAAU;IACV,CAAA;GACc"}
@@ -0,0 +1,103 @@
1
+ import { useCosmicIntersection as e } from "../../context/CosmicIntersectionContext.js";
2
+ import { useCosCollectionsQuery as t } from "../../api/cosmicApi.js";
3
+ import n from "../../components/ActionMenu.js";
4
+ import r from "../../components/EmptyState.js";
5
+ import i from "../../components/ErrorState.js";
6
+ import a from "../../components/LoadingState.js";
7
+ import o from "../../components/PageLayout.js";
8
+ import "../../components/index.js";
9
+ import { jsx as s, jsxs as c } from "react/jsx-runtime";
10
+ import { FolderOpen as l, Globe as u, Lock as d, Plus as f } from "lucide-react";
11
+ import { Badge as p, Button as m } from "@burdenoff/fe-libs/ui";
12
+ //#region src/cosmicintersection/pages/collections/CollectionsPage.tsx
13
+ function h() {
14
+ let { navigate: h } = e(), { data: g, loading: _, error: v, refetch: y } = t(), b = g?.cosListCollections ?? [], x = /* @__PURE__ */ c(m, {
15
+ type: "button",
16
+ onClick: () => h("collections/create"),
17
+ children: [/* @__PURE__ */ s(f, { className: "size-4" }), "New collection"]
18
+ });
19
+ return /* @__PURE__ */ s(o, {
20
+ title: "Collections",
21
+ description: "Curated groupings of datasets by mission, survey or research theme.",
22
+ actions: x,
23
+ children: _ ? /* @__PURE__ */ s(a, {
24
+ variant: "rows",
25
+ rows: 4,
26
+ label: "Loading collections…"
27
+ }) : v ? /* @__PURE__ */ s(i, {
28
+ message: v.message,
29
+ onRetry: () => void y()
30
+ }) : b.length === 0 ? /* @__PURE__ */ s(r, {
31
+ icon: l,
32
+ title: "No collections yet",
33
+ description: "Group related datasets — by mission, survey or research theme — into a shareable collection.",
34
+ action: x
35
+ }) : /* @__PURE__ */ s("div", {
36
+ className: "grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3",
37
+ children: b.map((e) => /* @__PURE__ */ c("div", {
38
+ role: "button",
39
+ tabIndex: 0,
40
+ "aria-label": `Open ${e.name}`,
41
+ onClick: () => h(`collections/${e.id}`),
42
+ onKeyDown: (t) => {
43
+ (t.key === "Enter" || t.key === " ") && (t.preventDefault(), h(`collections/${e.id}`));
44
+ },
45
+ className: "flex cursor-pointer flex-col gap-3 rounded-card border border-border-default bg-bg-elevated p-5 text-left outline-none transition-colors hover:bg-bg-sunken focus-visible:ring-2 focus-visible:ring-border-focus",
46
+ children: [
47
+ /* @__PURE__ */ c("div", {
48
+ className: "flex items-start justify-between gap-3",
49
+ children: [/* @__PURE__ */ c("div", {
50
+ className: "min-w-0",
51
+ children: [/* @__PURE__ */ s("h2", {
52
+ className: "truncate text-base font-semibold text-text-primary",
53
+ children: e.name
54
+ }), e.slug ? /* @__PURE__ */ c("p", {
55
+ className: "mt-0.5 truncate text-xs text-text-secondary",
56
+ children: ["/", e.slug]
57
+ }) : null]
58
+ }), /* @__PURE__ */ c("div", {
59
+ className: "flex shrink-0 items-center gap-2",
60
+ children: [e.isPublic ? /* @__PURE__ */ c(p, {
61
+ variant: "outline",
62
+ className: "gap-1 border-status-success-border bg-status-success-bg-subtle text-status-success-text",
63
+ children: [/* @__PURE__ */ s(u, {
64
+ className: "size-3",
65
+ "aria-hidden": "true"
66
+ }), "Public"]
67
+ }) : /* @__PURE__ */ c(p, {
68
+ variant: "secondary",
69
+ className: "gap-1",
70
+ children: [/* @__PURE__ */ s(d, {
71
+ className: "size-3",
72
+ "aria-hidden": "true"
73
+ }), "Private"]
74
+ }), /* @__PURE__ */ s(n, {
75
+ ariaLabel: `Actions for ${e.name}`,
76
+ onView: () => h(`collections/${e.id}`)
77
+ })]
78
+ })]
79
+ }),
80
+ /* @__PURE__ */ s("p", {
81
+ className: "line-clamp-2 min-h-[2.5rem] text-sm text-text-secondary",
82
+ children: e.description ?? "No description provided."
83
+ }),
84
+ e.tags.length > 0 ? /* @__PURE__ */ c("div", {
85
+ className: "flex flex-wrap gap-1",
86
+ children: [e.tags.slice(0, 4).map((e) => /* @__PURE__ */ s(p, {
87
+ variant: "outline",
88
+ className: "text-xs",
89
+ children: e
90
+ }, e)), e.tags.length > 4 ? /* @__PURE__ */ c("span", {
91
+ className: "text-xs text-text-secondary",
92
+ children: ["+", e.tags.length - 4]
93
+ }) : null]
94
+ }) : null
95
+ ]
96
+ }, e.id))
97
+ })
98
+ });
99
+ }
100
+ //#endregion
101
+ export { h as default };
102
+
103
+ //# sourceMappingURL=CollectionsPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CollectionsPage.js","names":[],"sources":["../../../../src/cosmicintersection/pages/collections/CollectionsPage.tsx"],"sourcesContent":["import { FolderOpen, Globe, Lock, Plus } from 'lucide-react';\nimport { Badge, Button } from '@burdenoff/fe-libs/ui';\n\nimport { useCosCollectionsQuery } from '../../api/cosmicApi';\nimport { ActionMenu, EmptyState, ErrorState, LoadingState, PageLayout } from '../../components';\nimport { useCosmicIntersection } from '../../context/CosmicIntersectionContext';\n\nexport default function CollectionsPage() {\n const { navigate } = useCosmicIntersection();\n const { data, loading, error, refetch } = useCosCollectionsQuery();\n\n const collections = data?.cosListCollections ?? [];\n\n const newButton = (\n <Button type=\"button\" onClick={() => navigate('collections/create')}>\n <Plus className=\"size-4\" />\n New collection\n </Button>\n );\n\n const renderBody = () => {\n if (loading) {\n return <LoadingState variant=\"rows\" rows={4} label=\"Loading collections…\" />;\n }\n if (error) {\n return <ErrorState message={error.message} onRetry={() => void refetch()} />;\n }\n if (collections.length === 0) {\n return (\n <EmptyState\n icon={FolderOpen}\n title=\"No collections yet\"\n description=\"Group related datasets — by mission, survey or research theme — into a shareable collection.\"\n action={newButton}\n />\n );\n }\n\n return (\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3\">\n {collections.map((collection) => (\n <div\n key={collection.id}\n role=\"button\"\n tabIndex={0}\n aria-label={`Open ${collection.name}`}\n onClick={() => navigate(`collections/${collection.id}`)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n navigate(`collections/${collection.id}`);\n }\n }}\n className=\"flex cursor-pointer flex-col gap-3 rounded-card border border-border-default bg-bg-elevated p-5 text-left 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=\"min-w-0\">\n <h2 className=\"truncate text-base font-semibold text-text-primary\">\n {collection.name}\n </h2>\n {collection.slug ? (\n <p className=\"mt-0.5 truncate text-xs text-text-secondary\">/{collection.slug}</p>\n ) : null}\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">\n {collection.isPublic ? (\n <Badge\n variant=\"outline\"\n className=\"gap-1 border-status-success-border bg-status-success-bg-subtle text-status-success-text\"\n >\n <Globe className=\"size-3\" aria-hidden=\"true\" />\n Public\n </Badge>\n ) : (\n <Badge variant=\"secondary\" className=\"gap-1\">\n <Lock className=\"size-3\" aria-hidden=\"true\" />\n Private\n </Badge>\n )}\n <ActionMenu\n ariaLabel={`Actions for ${collection.name}`}\n onView={() => navigate(`collections/${collection.id}`)}\n />\n </div>\n </div>\n\n <p className=\"line-clamp-2 min-h-[2.5rem] text-sm text-text-secondary\">\n {collection.description ?? 'No description provided.'}\n </p>\n\n {collection.tags.length > 0 ? (\n <div className=\"flex flex-wrap gap-1\">\n {collection.tags.slice(0, 4).map((tag) => (\n <Badge key={tag} variant=\"outline\" className=\"text-xs\">\n {tag}\n </Badge>\n ))}\n {collection.tags.length > 4 ? (\n <span className=\"text-xs text-text-secondary\">+{collection.tags.length - 4}</span>\n ) : null}\n </div>\n ) : null}\n </div>\n ))}\n </div>\n );\n };\n\n return (\n <PageLayout\n title=\"Collections\"\n description=\"Curated groupings of datasets by mission, survey or research theme.\"\n actions={newButton}\n >\n {renderBody()}\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAOA,SAAwB,IAAkB;CACxC,IAAM,EAAE,gBAAa,GAAuB,EACtC,EAAE,SAAM,YAAS,UAAO,eAAY,GAAwB,EAE5D,IAAc,GAAM,sBAAsB,EAAE,EAE5C,IACJ,kBAAC,GAAD;EAAQ,MAAK;EAAS,eAAe,EAAS,qBAAqB;YAAnE,CACE,kBAAC,GAAD,EAAM,WAAU,UAAW,CAAA,EAAA,iBAEpB;;AA2FX,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SAAS;YA3FP,IACK,kBAAC,GAAD;GAAc,SAAQ;GAAO,MAAM;GAAG,OAAM;GAAyB,CAAA,GAE1E,IACK,kBAAC,GAAD;GAAY,SAAS,EAAM;GAAS,eAAe,KAAK,GAAS;GAAI,CAAA,GAE1E,EAAY,WAAW,IAEvB,kBAAC,GAAD;GACE,MAAM;GACN,OAAM;GACN,aAAY;GACZ,QAAQ;GACR,CAAA,GAKJ,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAY,KAAK,MAChB,kBAAC,OAAD;IAEE,MAAK;IACL,UAAU;IACV,cAAY,QAAQ,EAAW;IAC/B,eAAe,EAAS,eAAe,EAAW,KAAK;IACvD,YAAY,MAAU;AACpB,MAAI,EAAM,QAAQ,WAAW,EAAM,QAAQ,SACzC,EAAM,gBAAgB,EACtB,EAAS,eAAe,EAAW,KAAK;;IAG5C,WAAU;cAZZ;KAcE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,MAAD;QAAI,WAAU;kBACX,EAAW;QACT,CAAA,EACJ,EAAW,OACV,kBAAC,KAAD;QAAG,WAAU;kBAAb,CAA2D,KAAE,EAAW,KAAS;YAC/E,KACA;UACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACG,EAAW,WACV,kBAAC,GAAD;QACE,SAAQ;QACR,WAAU;kBAFZ,CAIE,kBAAC,GAAD;SAAO,WAAU;SAAS,eAAY;SAAS,CAAA,EAAA,SAEzC;YAER,kBAAC,GAAD;QAAO,SAAQ;QAAY,WAAU;kBAArC,CACE,kBAAC,GAAD;SAAM,WAAU;SAAS,eAAY;SAAS,CAAA,EAAA,UAExC;WAEV,kBAAC,GAAD;QACE,WAAW,eAAe,EAAW;QACrC,cAAc,EAAS,eAAe,EAAW,KAAK;QACtD,CAAA,CACE;SACF;;KAEN,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAW,eAAe;MACzB,CAAA;KAEH,EAAW,KAAK,SAAS,IACxB,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACG,EAAW,KAAK,MAAM,GAAG,EAAE,CAAC,KAAK,MAChC,kBAAC,GAAD;OAAiB,SAAQ;OAAU,WAAU;iBAC1C;OACK,EAFI,EAEJ,CACR,EACD,EAAW,KAAK,SAAS,IACxB,kBAAC,QAAD;OAAM,WAAU;iBAAhB,CAA8C,KAAE,EAAW,KAAK,SAAS,EAAS;WAChF,KACA;UACJ;KACA;MA5DC,EAAW,GA4DZ,CACN;GACE,CAAA;EAWK,CAAA"}