@burdenoff/microfe-cosmicintersection 2026.704.2 → 2026.709.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 (186) hide show
  1. package/dist/cosmicintersection/CosmicIntersectionRoot.d.ts +15 -0
  2. package/dist/cosmicintersection/CosmicIntersectionRoot.d.ts.map +1 -0
  3. package/dist/cosmicintersection/CosmicIntersectionRoutes.d.ts +3 -0
  4. package/dist/cosmicintersection/CosmicIntersectionRoutes.d.ts.map +1 -0
  5. package/dist/cosmicintersection/CosmicIntersectionRoutes.js +39 -27
  6. package/dist/cosmicintersection/CosmicIntersectionRoutes.js.map +1 -1
  7. package/dist/cosmicintersection/api/cosmicApi.d.ts +728 -0
  8. package/dist/cosmicintersection/api/cosmicApi.d.ts.map +1 -0
  9. package/dist/cosmicintersection/api/cosmicApi.js +6 -0
  10. package/dist/cosmicintersection/api/cosmicApi.js.map +1 -1
  11. package/dist/cosmicintersection/components/ActionMenu.d.ts +41 -0
  12. package/dist/cosmicintersection/components/ActionMenu.d.ts.map +1 -0
  13. package/dist/cosmicintersection/components/ActivityFeedPanel.d.ts +10 -0
  14. package/dist/cosmicintersection/components/ActivityFeedPanel.d.ts.map +1 -0
  15. package/dist/cosmicintersection/components/DiscussionPanel.d.ts +14 -0
  16. package/dist/cosmicintersection/components/DiscussionPanel.d.ts.map +1 -0
  17. package/dist/cosmicintersection/components/DiscussionPanel.js +9 -9
  18. package/dist/cosmicintersection/components/EmptyState.d.ts +18 -0
  19. package/dist/cosmicintersection/components/EmptyState.d.ts.map +1 -0
  20. package/dist/cosmicintersection/components/EntityFormShell.d.ts +25 -0
  21. package/dist/cosmicintersection/components/EntityFormShell.d.ts.map +1 -0
  22. package/dist/cosmicintersection/components/EntityTagsField.d.ts +20 -0
  23. package/dist/cosmicintersection/components/EntityTagsField.d.ts.map +1 -0
  24. package/dist/cosmicintersection/components/ErrorState.d.ts +14 -0
  25. package/dist/cosmicintersection/components/ErrorState.d.ts.map +1 -0
  26. package/dist/cosmicintersection/components/FacetPanel.d.ts +21 -0
  27. package/dist/cosmicintersection/components/FacetPanel.d.ts.map +1 -0
  28. package/dist/cosmicintersection/components/FacetPanel.js +66 -0
  29. package/dist/cosmicintersection/components/FacetPanel.js.map +1 -0
  30. package/dist/cosmicintersection/components/FileUploadField.d.ts +35 -0
  31. package/dist/cosmicintersection/components/FileUploadField.d.ts.map +1 -0
  32. package/dist/cosmicintersection/components/FileUploadField.js +16 -16
  33. package/dist/cosmicintersection/components/LineageGraph.d.ts +59 -0
  34. package/dist/cosmicintersection/components/LineageGraph.d.ts.map +1 -0
  35. package/dist/cosmicintersection/components/LineageGraph.js +388 -0
  36. package/dist/cosmicintersection/components/LineageGraph.js.map +1 -0
  37. package/dist/cosmicintersection/components/LoadingState.d.ts +15 -0
  38. package/dist/cosmicintersection/components/LoadingState.d.ts.map +1 -0
  39. package/dist/cosmicintersection/components/PageLayout.d.ts +18 -0
  40. package/dist/cosmicintersection/components/PageLayout.d.ts.map +1 -0
  41. package/dist/cosmicintersection/components/Pagination.d.ts +32 -0
  42. package/dist/cosmicintersection/components/Pagination.d.ts.map +1 -0
  43. package/dist/cosmicintersection/components/ResultsChart.d.ts +7 -0
  44. package/dist/cosmicintersection/components/ResultsChart.d.ts.map +1 -0
  45. package/dist/cosmicintersection/components/ResultsChart.js +329 -0
  46. package/dist/cosmicintersection/components/ResultsChart.js.map +1 -0
  47. package/dist/cosmicintersection/components/SafeLink.d.ts +35 -0
  48. package/dist/cosmicintersection/components/SafeLink.d.ts.map +1 -0
  49. package/dist/cosmicintersection/components/StatusBadge.d.ts +23 -0
  50. package/dist/cosmicintersection/components/StatusBadge.d.ts.map +1 -0
  51. package/dist/cosmicintersection/components/StepDAG.d.ts +20 -0
  52. package/dist/cosmicintersection/components/StepDAG.d.ts.map +1 -0
  53. package/dist/cosmicintersection/components/StepDAG.js +104 -0
  54. package/dist/cosmicintersection/components/StepDAG.js.map +1 -0
  55. package/dist/cosmicintersection/components/index.d.ts +18 -0
  56. package/dist/cosmicintersection/components/index.d.ts.map +1 -0
  57. package/dist/cosmicintersection/context/CosmicIntersectionContext.d.ts +26 -0
  58. package/dist/cosmicintersection/context/CosmicIntersectionContext.d.ts.map +1 -0
  59. package/dist/cosmicintersection/index.d.ts +18 -0
  60. package/dist/cosmicintersection/index.d.ts.map +1 -0
  61. package/dist/cosmicintersection/lib/mutationResult.d.ts +23 -0
  62. package/dist/cosmicintersection/lib/mutationResult.d.ts.map +1 -0
  63. package/dist/cosmicintersection/lib/toast.d.ts +22 -0
  64. package/dist/cosmicintersection/lib/toast.d.ts.map +1 -0
  65. package/dist/cosmicintersection/pages/access/AccessPage.d.ts +2 -0
  66. package/dist/cosmicintersection/pages/access/AccessPage.d.ts.map +1 -0
  67. package/dist/cosmicintersection/pages/access/AccessPage.js +207 -155
  68. package/dist/cosmicintersection/pages/access/AccessPage.js.map +1 -1
  69. package/dist/cosmicintersection/pages/analyses/AnalysesPage.d.ts +2 -0
  70. package/dist/cosmicintersection/pages/analyses/AnalysesPage.d.ts.map +1 -0
  71. package/dist/cosmicintersection/pages/analyses/AnalysesPage.js +325 -165
  72. package/dist/cosmicintersection/pages/analyses/AnalysesPage.js.map +1 -1
  73. package/dist/cosmicintersection/pages/collections/CollectionDetailPage.d.ts +2 -0
  74. package/dist/cosmicintersection/pages/collections/CollectionDetailPage.d.ts.map +1 -0
  75. package/dist/cosmicintersection/pages/collections/CollectionDetailPage.js +138 -93
  76. package/dist/cosmicintersection/pages/collections/CollectionDetailPage.js.map +1 -1
  77. package/dist/cosmicintersection/pages/collections/CollectionFormPage.d.ts +2 -0
  78. package/dist/cosmicintersection/pages/collections/CollectionFormPage.d.ts.map +1 -0
  79. package/dist/cosmicintersection/pages/collections/CollectionFormPage.js.map +1 -1
  80. package/dist/cosmicintersection/pages/collections/CollectionsPage.d.ts +2 -0
  81. package/dist/cosmicintersection/pages/collections/CollectionsPage.d.ts.map +1 -0
  82. package/dist/cosmicintersection/pages/dashboard/DashboardPage.d.ts +2 -0
  83. package/dist/cosmicintersection/pages/dashboard/DashboardPage.d.ts.map +1 -0
  84. package/dist/cosmicintersection/pages/dashboard/DashboardPage.js +26 -15
  85. package/dist/cosmicintersection/pages/dashboard/DashboardPage.js.map +1 -1
  86. package/dist/cosmicintersection/pages/datasets/DatasetDetailPage.d.ts +2 -0
  87. package/dist/cosmicintersection/pages/datasets/DatasetDetailPage.d.ts.map +1 -0
  88. package/dist/cosmicintersection/pages/datasets/DatasetDetailPage.js +345 -219
  89. package/dist/cosmicintersection/pages/datasets/DatasetDetailPage.js.map +1 -1
  90. package/dist/cosmicintersection/pages/datasets/DatasetFormPage.d.ts +2 -0
  91. package/dist/cosmicintersection/pages/datasets/DatasetFormPage.d.ts.map +1 -0
  92. package/dist/cosmicintersection/pages/datasets/DatasetsPage.d.ts +2 -0
  93. package/dist/cosmicintersection/pages/datasets/DatasetsPage.d.ts.map +1 -0
  94. package/dist/cosmicintersection/pages/datasets/DatasetsPage.js +321 -163
  95. package/dist/cosmicintersection/pages/datasets/DatasetsPage.js.map +1 -1
  96. package/dist/cosmicintersection/pages/discovery/DiscoveryPage.d.ts +2 -0
  97. package/dist/cosmicintersection/pages/discovery/DiscoveryPage.d.ts.map +1 -0
  98. package/dist/cosmicintersection/pages/discovery/DiscoveryPage.js +358 -0
  99. package/dist/cosmicintersection/pages/discovery/DiscoveryPage.js.map +1 -0
  100. package/dist/cosmicintersection/pages/lineage/LineagePage.d.ts +2 -0
  101. package/dist/cosmicintersection/pages/lineage/LineagePage.d.ts.map +1 -0
  102. package/dist/cosmicintersection/pages/lineage/LineagePage.js +171 -0
  103. package/dist/cosmicintersection/pages/lineage/LineagePage.js.map +1 -0
  104. package/dist/cosmicintersection/pages/notebooks/NotebookDetailPage.d.ts +2 -0
  105. package/dist/cosmicintersection/pages/notebooks/NotebookDetailPage.d.ts.map +1 -0
  106. package/dist/cosmicintersection/pages/notebooks/NotebookDetailPage.js +232 -162
  107. package/dist/cosmicintersection/pages/notebooks/NotebookDetailPage.js.map +1 -1
  108. package/dist/cosmicintersection/pages/notebooks/NotebookFormPage.d.ts +2 -0
  109. package/dist/cosmicintersection/pages/notebooks/NotebookFormPage.d.ts.map +1 -0
  110. package/dist/cosmicintersection/pages/notebooks/NotebooksPage.d.ts +2 -0
  111. package/dist/cosmicintersection/pages/notebooks/NotebooksPage.d.ts.map +1 -0
  112. package/dist/cosmicintersection/pages/notebooks/NotebooksPage.js +143 -82
  113. package/dist/cosmicintersection/pages/notebooks/NotebooksPage.js.map +1 -1
  114. package/dist/cosmicintersection/pages/pipelines/PipelineDetailPage.d.ts +2 -0
  115. package/dist/cosmicintersection/pages/pipelines/PipelineDetailPage.d.ts.map +1 -0
  116. package/dist/cosmicintersection/pages/pipelines/PipelineDetailPage.js +286 -142
  117. package/dist/cosmicintersection/pages/pipelines/PipelineDetailPage.js.map +1 -1
  118. package/dist/cosmicintersection/pages/pipelines/PipelineFormPage.d.ts +2 -0
  119. package/dist/cosmicintersection/pages/pipelines/PipelineFormPage.d.ts.map +1 -0
  120. package/dist/cosmicintersection/pages/pipelines/PipelineFormPage.js +305 -103
  121. package/dist/cosmicintersection/pages/pipelines/PipelineFormPage.js.map +1 -1
  122. package/dist/cosmicintersection/pages/pipelines/PipelinesPage.d.ts +2 -0
  123. package/dist/cosmicintersection/pages/pipelines/PipelinesPage.d.ts.map +1 -0
  124. package/dist/cosmicintersection/pages/pipelines/PipelinesPage.js +183 -79
  125. package/dist/cosmicintersection/pages/pipelines/PipelinesPage.js.map +1 -1
  126. package/dist/cosmicintersection/pages/releases/ReleaseFormPage.d.ts +2 -0
  127. package/dist/cosmicintersection/pages/releases/ReleaseFormPage.d.ts.map +1 -0
  128. package/dist/cosmicintersection/pages/releases/ReleasesPage.d.ts +2 -0
  129. package/dist/cosmicintersection/pages/releases/ReleasesPage.d.ts.map +1 -0
  130. package/dist/cosmicintersection/pages/releases/ReleasesPage.js +262 -170
  131. package/dist/cosmicintersection/pages/releases/ReleasesPage.js.map +1 -1
  132. package/dist/cosmicintersection/pages/runs/RunDetailPage.d.ts +2 -0
  133. package/dist/cosmicintersection/pages/runs/RunDetailPage.d.ts.map +1 -0
  134. package/dist/cosmicintersection/pages/runs/RunDetailPage.js +179 -136
  135. package/dist/cosmicintersection/pages/runs/RunDetailPage.js.map +1 -1
  136. package/dist/cosmicintersection/pages/runs/RunsPage.d.ts +2 -0
  137. package/dist/cosmicintersection/pages/runs/RunsPage.d.ts.map +1 -0
  138. package/dist/cosmicintersection/pages/runs/RunsPage.js +124 -47
  139. package/dist/cosmicintersection/pages/runs/RunsPage.js.map +1 -1
  140. package/dist/cosmicintersection/pages/sources/SourceDetailPage.d.ts +2 -0
  141. package/dist/cosmicintersection/pages/sources/SourceDetailPage.d.ts.map +1 -0
  142. package/dist/cosmicintersection/pages/sources/SourceDetailPage.js +114 -85
  143. package/dist/cosmicintersection/pages/sources/SourceDetailPage.js.map +1 -1
  144. package/dist/cosmicintersection/pages/sources/SourceFormPage.d.ts +2 -0
  145. package/dist/cosmicintersection/pages/sources/SourceFormPage.d.ts.map +1 -0
  146. package/dist/cosmicintersection/pages/sources/SourcesPage.d.ts +2 -0
  147. package/dist/cosmicintersection/pages/sources/SourcesPage.d.ts.map +1 -0
  148. package/dist/cosmicintersection/pages/sources/SourcesPage.js +263 -152
  149. package/dist/cosmicintersection/pages/sources/SourcesPage.js.map +1 -1
  150. package/dist/cosmicintersection/types/index.d.ts +7 -0
  151. package/dist/cosmicintersection/types/index.d.ts.map +1 -0
  152. package/dist/cosmicintersection/utils/cn.d.ts +4 -0
  153. package/dist/cosmicintersection/utils/cn.d.ts.map +1 -0
  154. package/dist/cosmicintersection/utils/i18n.d.ts +15 -0
  155. package/dist/cosmicintersection/utils/i18n.d.ts.map +1 -0
  156. package/dist/cosmicintersection/utils/navigation.d.ts +2 -0
  157. package/dist/cosmicintersection/utils/navigation.d.ts.map +1 -0
  158. package/dist/dev/main.d.ts +2 -0
  159. package/dist/dev/main.d.ts.map +1 -0
  160. package/dist/generated/global-operations.d.ts +2 -0
  161. package/dist/generated/global-operations.d.ts.map +1 -0
  162. package/dist/generated/global-types.d.ts +18199 -0
  163. package/dist/generated/global-types.d.ts.map +1 -0
  164. package/dist/generated/wspace-operations.d.ts +2 -0
  165. package/dist/generated/wspace-operations.d.ts.map +1 -0
  166. package/dist/generated/wspace-types.d.ts +43046 -0
  167. package/dist/generated/wspace-types.d.ts.map +1 -0
  168. package/dist/index.d.ts +19 -0
  169. package/dist/index.d.ts.map +1 -0
  170. package/dist/index.js +2 -2
  171. package/dist/services/assistantApi.d.ts +66 -0
  172. package/dist/services/assistantApi.d.ts.map +1 -0
  173. package/dist/services/assistantApi.js +250 -0
  174. package/dist/services/assistantApi.js.map +1 -0
  175. package/dist/services/createSandboxAssistantTransport.d.ts +40 -0
  176. package/dist/services/createSandboxAssistantTransport.d.ts.map +1 -0
  177. package/dist/services/createSandboxAssistantTransport.js +120 -0
  178. package/dist/services/createSandboxAssistantTransport.js.map +1 -0
  179. package/dist/types/assistant.d.ts +48 -0
  180. package/dist/types/assistant.d.ts.map +1 -0
  181. package/dist/utils/pageContext.d.ts +28 -0
  182. package/dist/utils/pageContext.d.ts.map +1 -0
  183. package/dist/utils/pageContext.js +50 -0
  184. package/dist/utils/pageContext.js.map +1 -0
  185. package/package.json +5 -1
  186. package/dist/cosmicintersection/index.js +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"CollectionFormPage.js","names":[],"sources":["../../../../src/cosmicintersection/pages/collections/CollectionFormPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { Input, Switch, Textarea } from '@burdenoff/fe-libs/ui';\n\nimport {\n useCosCollectionQuery,\n useCosCreateCollectionMutation,\n useCosUpdateCollectionMutation,\n type CosCreateCollectionInput,\n type CosUpdateCollectionInput,\n} from '../../api/cosmicApi';\nimport { EntityFormShell, EntityTagsField, LoadingState } 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 { id = '' } = useParams<{ id: string }>();\n const isEdit = useMemo(() => Boolean(id), [id]);\n const { navigate } = useCosmicIntersection();\n\n const { data, loading: loadingCollection } = useCosCollectionQuery(id);\n const [createCollection, { loading: creating }] = useCosCreateCollectionMutation();\n const [updateCollection, { loading: updating }] = useCosUpdateCollectionMutation();\n\n const [form, setForm] = useState<CollectionFormState>(INITIAL_STATE);\n\n // Hydrate once the collection loads in edit mode. Derive-state-during-render\n // (keyed on the loaded id) rather than an effect, per platform lint.\n const [loadedId, setLoadedId] = useState<string | null>(null);\n if (isEdit && data?.cosCollection && loadedId !== data.cosCollection.id) {\n const collection = data.cosCollection;\n setLoadedId(collection.id);\n setForm({\n name: collection.name ?? '',\n slug: collection.slug ?? '',\n description: collection.description ?? '',\n isPublic: collection.isPublic,\n tags: collection.tags ?? [],\n });\n }\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 saving = creating || updating;\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 if (isEdit) {\n const input: CosUpdateCollectionInput = {\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 const response = await updateCollection({ variables: { id, input } });\n if (response.data?.cosUpdateCollection?.id) {\n notify.success('Collection updated');\n navigate(`collections/${id}`);\n }\n return;\n }\n\n const input: CosCreateCollectionInput = {\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 const response = await createCollection({ variables: { input } });\n const created = response.data?.cosCreateCollection;\n if (created?.id) {\n notify.success('Collection created');\n navigate(`collections/${created.id}`);\n }\n };\n\n if (isEdit && loadingCollection && !data?.cosCollection) {\n return <LoadingState label=\"Loading collection…\" />;\n }\n\n return (\n <EntityFormShell\n title={isEdit ? 'Edit collection' : '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={isEdit ? 'Back to collection' : 'Back to collections'}\n onBack={() => navigate(isEdit ? `collections/${id}` : 'collections')}\n onSubmit={(event) => void onSubmit(event)}\n submitLabel={isEdit ? 'Save collection' : 'Create collection'}\n saving={saving}\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 value={form.tags} onChange={(tags) => onChange('tags', tags)} disabled={saving} />\n </EntityFormShell>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAuBA,IAAM,IAAqC;CACzC,MAAM;CACN,MAAM;CACN,aAAa;CACb,UAAU;CACV,MAAM,EAAE;CACT,EAEK,IAAkB,6BAClB,IAAiB;AAEvB,SAAwB,IAAqB;CAC3C,IAAM,EAAE,QAAK,OAAO,GAA2B,EACzC,IAAS,QAAc,EAAQ,GAAK,CAAC,EAAG,CAAC,EACzC,EAAE,gBAAa,GAAuB,EAEtC,EAAE,SAAM,SAAS,MAAsB,EAAsB,EAAG,EAChE,CAAC,GAAkB,EAAE,SAAS,OAAc,GAAgC,EAC5E,CAAC,GAAkB,EAAE,SAAS,OAAc,GAAgC,EAE5E,CAAC,GAAM,KAAW,EAA8B,EAAc,EAI9D,CAAC,GAAU,KAAe,EAAwB,KAAK;AAC7D,KAAI,KAAU,GAAM,iBAAiB,MAAa,EAAK,cAAc,IAAI;EACvE,IAAM,IAAa,EAAK;AAExB,EADA,EAAY,EAAW,GAAG,EAC1B,EAAQ;GACN,MAAM,EAAW,QAAQ;GACzB,MAAM,EAAW,QAAQ;GACzB,aAAa,EAAW,eAAe;GACvC,UAAU,EAAW;GACrB,MAAM,EAAW,QAAQ,EAAE;GAC5B,CAAC;;CAGJ,IAAM,KACJ,GACA,MACG;AACH,KAAS,OAAU;GAAE,GAAG;IAAO,IAAQ;GAAO,EAAE;IAG5C,IAAS,KAAY,GAErB,IAAW,OAAO,MAA4C;AAGlE,MAFA,EAAM,gBAAgB,EAElB,CAAC,EAAK,KAAK,MAAM,EAAE;AACrB,KAAO,MAAM,oBAAoB,4CAA4C;AAC7E;;AAGF,MAAI,GAAQ;AASV,IADiB,MAAM,EAAiB,EAAE,WAAW;IAAE;IAAI,OAPnB;KACtC,MAAM,EAAK,KAAK,MAAM;KACtB,MAAM,EAAK,KAAK,MAAM,IAAI,KAAA;KAC1B,aAAa,EAAK,YAAY,MAAM,IAAI,KAAA;KACxC,UAAU,EAAK;KACf,MAAM,EAAK;KACZ;IACiE,EAAE,CAAC,EACxD,MAAM,qBAAqB,OACtC,EAAO,QAAQ,qBAAqB,EACpC,EAAS,eAAe,IAAK;AAE/B;;EAWF,IAAM,KADW,MAAM,EAAiB,EAAE,WAAW,EAAE,OAPf;GACtC,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,EAC6D,EAAE,CAAC,EACxC,MAAM;AAC/B,EAAI,GAAS,OACX,EAAO,QAAQ,qBAAqB,EACpC,EAAS,eAAe,EAAQ,KAAK;;AAQzC,QAJI,KAAU,KAAqB,CAAC,GAAM,gBACjC,kBAAC,GAAD,EAAc,OAAM,uBAAwB,CAAA,GAInD,kBAAC,GAAD;EACE,OAAO,IAAS,oBAAoB;EACpC,aAAY;EACZ,SAAQ;EACR,WAAW,IAAS,uBAAuB;EAC3C,cAAc,EAAS,IAAS,eAAe,MAAO,cAAc;EACpE,WAAW,MAAU,KAAK,EAAS,EAAM;EACzC,aAAa,IAAS,oBAAoB;EAClC;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;IAAiB,OAAO,EAAK;IAAM,WAAW,MAAS,EAAS,QAAQ,EAAK;IAAE,UAAU;IAAU,CAAA;GACnF"}
1
+ {"version":3,"file":"CollectionFormPage.js","names":[],"sources":["../../../../src/cosmicintersection/pages/collections/CollectionFormPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { Input, Switch, Textarea } from '@burdenoff/fe-libs/ui';\n\nimport {\n useCosCollectionQuery,\n useCosCreateCollectionMutation,\n useCosUpdateCollectionMutation,\n type CosCreateCollectionInput,\n type CosUpdateCollectionInput,\n} from '../../api/cosmicApi';\nimport { EntityFormShell, EntityTagsField, LoadingState } 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 { id = '' } = useParams<{ id: string }>();\n const isEdit = useMemo(() => Boolean(id), [id]);\n const { navigate } = useCosmicIntersection();\n\n const { data, loading: loadingCollection } = useCosCollectionQuery(id);\n const [createCollection, { loading: creating }] = useCosCreateCollectionMutation();\n const [updateCollection, { loading: updating }] = useCosUpdateCollectionMutation();\n\n const [form, setForm] = useState<CollectionFormState>(INITIAL_STATE);\n\n // Hydrate once the collection loads in edit mode. Derive-state-during-render\n // (keyed on the loaded id) rather than an effect, per platform lint.\n const [loadedId, setLoadedId] = useState<string | null>(null);\n if (isEdit && data?.cosCollection && loadedId !== data.cosCollection.id) {\n const collection = data.cosCollection;\n setLoadedId(collection.id);\n setForm({\n name: collection.name ?? '',\n slug: collection.slug ?? '',\n description: collection.description ?? '',\n isPublic: collection.isPublic,\n tags: collection.tags ?? [],\n });\n }\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 saving = creating || updating;\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 if (isEdit) {\n const input: CosUpdateCollectionInput = {\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 const response = await updateCollection({ variables: { id, input } });\n if (response.data?.cosUpdateCollection?.id) {\n notify.success('Collection updated');\n navigate(`collections/${id}`);\n }\n return;\n }\n\n const input: CosCreateCollectionInput = {\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 const response = await createCollection({ variables: { input } });\n const created = response.data?.cosCreateCollection;\n if (created?.id) {\n notify.success('Collection created');\n navigate(`collections/${created.id}`);\n }\n };\n\n if (isEdit && loadingCollection && !data?.cosCollection) {\n return <LoadingState label=\"Loading collection…\" />;\n }\n\n return (\n <EntityFormShell\n title={isEdit ? 'Edit collection' : '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={isEdit ? 'Back to collection' : 'Back to collections'}\n onBack={() => navigate(isEdit ? `collections/${id}` : 'collections')}\n onSubmit={(event) => void onSubmit(event)}\n submitLabel={isEdit ? 'Save collection' : 'Create collection'}\n saving={saving}\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={saving}\n />\n </EntityFormShell>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export default function CollectionsPage(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=CollectionsPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CollectionsPage.d.ts","sourceRoot":"","sources":["../../../../src/cosmicintersection/pages/collections/CollectionsPage.tsx"],"names":[],"mappings":"AAYA,MAAM,CAAC,OAAO,UAAU,eAAe,4CA+HtC"}
@@ -0,0 +1,2 @@
1
+ export default function DashboardPage(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=DashboardPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DashboardPage.d.ts","sourceRoot":"","sources":["../../../../src/cosmicintersection/pages/dashboard/DashboardPage.tsx"],"names":[],"mappings":"AAwEA,MAAM,CAAC,OAAO,UAAU,aAAa,4CA6MpC"}
@@ -23,15 +23,18 @@ function w({ label: e, count: t, icon: n, loading: r, onClick: i }) {
23
23
  return /* @__PURE__ */ d("button", {
24
24
  type: "button",
25
25
  onClick: i,
26
- className: "flex flex-col gap-2 rounded-card border border-border-default bg-bg-elevated p-4 text-left transition-colors hover:border-border-strong hover:bg-bg-sunken focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
26
+ className: "group flex flex-col gap-2 rounded-card border border-border-default bg-bg-elevated p-4 text-left transition-colors hover:border-border-strong hover:bg-bg-sunken focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
27
27
  children: [/* @__PURE__ */ d("div", {
28
28
  className: "flex items-center justify-between",
29
29
  children: [/* @__PURE__ */ u("span", {
30
30
  className: "text-sm font-medium text-text-secondary",
31
31
  children: e
32
- }), /* @__PURE__ */ u(n, {
33
- className: "size-5 text-text-secondary",
34
- "aria-hidden": "true"
32
+ }), /* @__PURE__ */ u("span", {
33
+ className: "flex size-8 items-center justify-center rounded-button border border-border-default bg-bg-sunken text-text-secondary transition-colors group-hover:border-border-strong",
34
+ children: /* @__PURE__ */ u(n, {
35
+ className: "size-4",
36
+ "aria-hidden": "true"
37
+ })
35
38
  })]
36
39
  }), /* @__PURE__ */ u("span", {
37
40
  className: "text-2xl font-semibold tabular-nums text-text-primary",
@@ -220,17 +223,25 @@ function T() {
220
223
  className: "flex w-full items-center justify-between gap-3 rounded-card border border-border-default bg-bg-elevated px-4 py-3 text-left transition-colors hover:border-border-strong hover:bg-bg-sunken",
221
224
  children: [/* @__PURE__ */ d("div", {
222
225
  className: "min-w-0",
223
- children: [/* @__PURE__ */ u("p", {
224
- className: "truncate font-medium text-text-primary",
225
- children: e.title
226
- }), /* @__PURE__ */ d("p", {
227
- className: "text-xs text-text-secondary",
228
- children: [
229
- "v",
230
- e.version,
231
- e.publishedAt ? ` · Published ${S(e.publishedAt)}` : ""
232
- ]
233
- })]
226
+ children: [
227
+ /* @__PURE__ */ u("p", {
228
+ className: "truncate font-medium text-text-primary",
229
+ children: e.title
230
+ }),
231
+ /* @__PURE__ */ d("p", {
232
+ className: "text-xs text-text-secondary",
233
+ children: [
234
+ "v",
235
+ e.version,
236
+ e.publishedAt ? ` · Published ${S(e.publishedAt)}` : ""
237
+ ]
238
+ }),
239
+ e.doi ? /* @__PURE__ */ d("p", {
240
+ className: "mt-0.5 truncate font-mono text-xs text-text-tertiary",
241
+ title: e.doi,
242
+ children: ["DOI: ", e.doi]
243
+ }) : null
244
+ ]
234
245
  }), /* @__PURE__ */ u(l, { status: e.status })]
235
246
  }) }, e.id))
236
247
  })]
@@ -1 +1 @@
1
- {"version":3,"file":"DashboardPage.js","names":[],"sources":["../../../../src/cosmicintersection/pages/dashboard/DashboardPage.tsx"],"sourcesContent":["import type { LucideIcon } from 'lucide-react';\nimport {\n Boxes,\n Database,\n FileText,\n NotebookPen,\n Plus,\n Radar,\n Rocket,\n Workflow,\n} from 'lucide-react';\nimport { Button } from '@burdenoff/fe-libs/ui';\n\nimport {\n useCosDatasetsQuery,\n useCosNotebooksQuery,\n useCosPipelinesQuery,\n useCosReleasesQuery,\n useCosRunsQuery,\n useCosSourcesQuery,\n type CosConnection,\n} from '../../api/cosmicApi';\nimport { EmptyState, PageLayout, StatusBadge } from '../../components';\nimport { useCosmicIntersection } from '../../context/CosmicIntersectionContext';\n\nconst TILE_LIMIT = 50;\n\nfunction formatDateTime(raw: string | null | undefined): string {\n if (!raw) {\n return '—';\n }\n const date = new Date(raw);\n return Number.isNaN(date.getTime()) ? '—' : date.toLocaleString();\n}\n\n/** \"13\" or \"50+\" — the honest count of the page we fetched, never a fabricated total. */\nfunction connectionCount<T>(connection: CosConnection<T> | undefined): string {\n if (!connection) {\n return '—';\n }\n const loaded = connection.items.length;\n return connection.pageInfo?.hasMore ? `${loaded}+` : String(loaded);\n}\n\ninterface SummaryTileProps {\n label: string;\n count: string;\n icon: LucideIcon;\n loading: boolean;\n onClick: () => void;\n}\n\nfunction SummaryTile({ label, count, icon: Icon, loading, onClick }: SummaryTileProps) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className=\"flex flex-col gap-2 rounded-card border border-border-default bg-bg-elevated p-4 text-left transition-colors hover:border-border-strong hover:bg-bg-sunken focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus\"\n >\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm font-medium text-text-secondary\">{label}</span>\n <Icon className=\"size-5 text-text-secondary\" aria-hidden=\"true\" />\n </div>\n <span className=\"text-2xl font-semibold tabular-nums text-text-primary\">\n {loading ? '…' : count}\n </span>\n </button>\n );\n}\n\nexport default function DashboardPage() {\n const { navigate } = useCosmicIntersection();\n\n const datasetsQuery = useCosDatasetsQuery({ pagination: { limit: TILE_LIMIT, offset: 0 } });\n const sourcesQuery = useCosSourcesQuery({ pagination: { limit: TILE_LIMIT, offset: 0 } });\n const pipelinesQuery = useCosPipelinesQuery({ pagination: { limit: TILE_LIMIT, offset: 0 } });\n const runsQuery = useCosRunsQuery({ pagination: { limit: TILE_LIMIT, offset: 0 } });\n const notebooksQuery = useCosNotebooksQuery({ pagination: { limit: TILE_LIMIT, offset: 0 } });\n const releasesQuery = useCosReleasesQuery({ pagination: { limit: TILE_LIMIT, offset: 0 } });\n const publishedQuery = useCosReleasesQuery({\n status: 'PUBLISHED',\n pagination: { limit: 5, offset: 0 },\n });\n\n const recentRuns = (runsQuery.data?.cosListRuns?.items ?? []).slice(0, 6);\n const publishedReleases = publishedQuery.data?.cosListReleases?.items ?? [];\n\n return (\n <PageLayout\n title=\"CosmicIntersection\"\n description=\"A federation workspace for science data — sources, datasets, pipelines, notebooks and releases in one place.\"\n actions={\n <Button type=\"button\" onClick={() => navigate('datasets/create')}>\n <Plus className=\"size-4\" />\n New dataset\n </Button>\n }\n >\n <div className=\"space-y-6\">\n {/* Summary tiles */}\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-6\">\n <SummaryTile\n label=\"Datasets\"\n icon={Database}\n loading={datasetsQuery.loading}\n count={connectionCount(datasetsQuery.data?.cosListDatasets)}\n onClick={() => navigate('datasets')}\n />\n <SummaryTile\n label=\"Sources\"\n icon={Radar}\n loading={sourcesQuery.loading}\n count={connectionCount(sourcesQuery.data?.cosListSources)}\n onClick={() => navigate('sources')}\n />\n <SummaryTile\n label=\"Pipelines\"\n icon={Workflow}\n loading={pipelinesQuery.loading}\n count={connectionCount(pipelinesQuery.data?.cosListPipelines)}\n onClick={() => navigate('pipelines')}\n />\n <SummaryTile\n label=\"Runs\"\n icon={Boxes}\n loading={runsQuery.loading}\n count={connectionCount(runsQuery.data?.cosListRuns)}\n onClick={() => navigate('runs')}\n />\n <SummaryTile\n label=\"Notebooks\"\n icon={NotebookPen}\n loading={notebooksQuery.loading}\n count={connectionCount(notebooksQuery.data?.cosListNotebooks)}\n onClick={() => navigate('notebooks')}\n />\n <SummaryTile\n label=\"Releases\"\n icon={FileText}\n loading={releasesQuery.loading}\n count={connectionCount(releasesQuery.data?.cosListReleases)}\n onClick={() => navigate('releases')}\n />\n </div>\n\n {/* Quick actions */}\n <div className=\"rounded-card border border-border-default bg-bg-elevated p-5\">\n <h2 className=\"text-sm font-semibold text-text-primary\">Quick actions</h2>\n <div className=\"mt-3 flex flex-wrap gap-2\">\n <Button type=\"button\" variant=\"outline\" onClick={() => navigate('datasets/create')}>\n <Database className=\"size-4\" />\n Register dataset\n </Button>\n <Button type=\"button\" variant=\"outline\" onClick={() => navigate('sources/create')}>\n <Radar className=\"size-4\" />\n Connect source\n </Button>\n <Button type=\"button\" variant=\"outline\" onClick={() => navigate('pipelines/create')}>\n <Workflow className=\"size-4\" />\n Create pipeline\n </Button>\n </div>\n </div>\n\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-2\">\n {/* Recent runs */}\n <section className=\"space-y-3\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Recent runs</h2>\n <button\n type=\"button\"\n onClick={() => navigate('runs')}\n className=\"text-sm text-text-secondary underline-offset-2 hover:text-text-primary hover:underline\"\n >\n View all\n </button>\n </div>\n {runsQuery.loading ? (\n <div className=\"space-y-2\">\n {Array.from({ length: 3 }).map((_, index) => (\n <div key={index} className=\"h-14 animate-pulse rounded-card bg-bg-sunken\" />\n ))}\n </div>\n ) : recentRuns.length === 0 ? (\n <EmptyState\n icon={Boxes}\n title=\"No pipeline runs yet.\"\n description=\"Start a pipeline run to see execution history here.\"\n />\n ) : (\n <ul className=\"space-y-2\">\n {recentRuns.map((run) => (\n <li key={run.id}>\n <button\n type=\"button\"\n onClick={() => navigate(`runs/${run.id}`)}\n className=\"flex w-full items-center justify-between gap-3 rounded-card border border-border-default bg-bg-elevated px-4 py-3 text-left transition-colors hover:border-border-strong hover:bg-bg-sunken\"\n >\n <div className=\"min-w-0\">\n <p className=\"font-medium text-text-primary\">Run #{run.runNumber}</p>\n <p className=\"text-xs text-text-secondary\">\n {run.startedAt\n ? `Started ${formatDateTime(run.startedAt)}`\n : 'Not started'}\n </p>\n </div>\n <StatusBadge status={run.status} />\n </button>\n </li>\n ))}\n </ul>\n )}\n </section>\n\n {/* Recently published releases */}\n <section className=\"space-y-3\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Recently published</h2>\n <button\n type=\"button\"\n onClick={() => navigate('releases')}\n className=\"text-sm text-text-secondary underline-offset-2 hover:text-text-primary hover:underline\"\n >\n View all\n </button>\n </div>\n {publishedQuery.loading ? (\n <div className=\"space-y-2\">\n {Array.from({ length: 3 }).map((_, index) => (\n <div key={index} className=\"h-14 animate-pulse rounded-card bg-bg-sunken\" />\n ))}\n </div>\n ) : publishedReleases.length === 0 ? (\n <EmptyState\n icon={Rocket}\n title=\"No published releases yet.\"\n description=\"Publish a release to share datasets and notebooks with a citable version.\"\n />\n ) : (\n <ul className=\"space-y-2\">\n {publishedReleases.map((release) => (\n <li key={release.id}>\n <button\n type=\"button\"\n onClick={() => navigate('releases')}\n className=\"flex w-full items-center justify-between gap-3 rounded-card border border-border-default bg-bg-elevated px-4 py-3 text-left transition-colors hover:border-border-strong hover:bg-bg-sunken\"\n >\n <div className=\"min-w-0\">\n <p className=\"truncate font-medium text-text-primary\">{release.title}</p>\n <p className=\"text-xs text-text-secondary\">\n v{release.version}\n {release.publishedAt\n ? ` · Published ${formatDateTime(release.publishedAt)}`\n : ''}\n </p>\n </div>\n <StatusBadge status={release.status} />\n </button>\n </li>\n ))}\n </ul>\n )}\n </section>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"DashboardPage.js","names":[],"sources":["../../../../src/cosmicintersection/pages/dashboard/DashboardPage.tsx"],"sourcesContent":["import type { LucideIcon } from 'lucide-react';\nimport {\n Boxes,\n Database,\n FileText,\n NotebookPen,\n Plus,\n Radar,\n Rocket,\n Workflow,\n} from 'lucide-react';\nimport { Button } from '@burdenoff/fe-libs/ui';\n\nimport {\n useCosDatasetsQuery,\n useCosNotebooksQuery,\n useCosPipelinesQuery,\n useCosReleasesQuery,\n useCosRunsQuery,\n useCosSourcesQuery,\n type CosConnection,\n} from '../../api/cosmicApi';\nimport { EmptyState, PageLayout, StatusBadge } from '../../components';\nimport { useCosmicIntersection } from '../../context/CosmicIntersectionContext';\n\nconst TILE_LIMIT = 50;\n\nfunction formatDateTime(raw: string | null | undefined): string {\n if (!raw) {\n return '—';\n }\n const date = new Date(raw);\n return Number.isNaN(date.getTime()) ? '—' : date.toLocaleString();\n}\n\n/** \"13\" or \"50+\" — the honest count of the page we fetched, never a fabricated total. */\nfunction connectionCount<T>(connection: CosConnection<T> | undefined): string {\n if (!connection) {\n return '—';\n }\n const loaded = connection.items.length;\n return connection.pageInfo?.hasMore ? `${loaded}+` : String(loaded);\n}\n\ninterface SummaryTileProps {\n label: string;\n count: string;\n icon: LucideIcon;\n loading: boolean;\n onClick: () => void;\n}\n\nfunction SummaryTile({ label, count, icon: Icon, loading, onClick }: SummaryTileProps) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className=\"group flex flex-col gap-2 rounded-card border border-border-default bg-bg-elevated p-4 text-left transition-colors hover:border-border-strong hover:bg-bg-sunken focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus\"\n >\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm font-medium text-text-secondary\">{label}</span>\n <span className=\"flex size-8 items-center justify-center rounded-button border border-border-default bg-bg-sunken text-text-secondary transition-colors group-hover:border-border-strong\">\n <Icon className=\"size-4\" aria-hidden=\"true\" />\n </span>\n </div>\n <span className=\"text-2xl font-semibold tabular-nums text-text-primary\">\n {loading ? '…' : count}\n </span>\n </button>\n );\n}\n\nexport default function DashboardPage() {\n const { navigate } = useCosmicIntersection();\n\n const datasetsQuery = useCosDatasetsQuery({ pagination: { limit: TILE_LIMIT, offset: 0 } });\n const sourcesQuery = useCosSourcesQuery({ pagination: { limit: TILE_LIMIT, offset: 0 } });\n const pipelinesQuery = useCosPipelinesQuery({ pagination: { limit: TILE_LIMIT, offset: 0 } });\n const runsQuery = useCosRunsQuery({ pagination: { limit: TILE_LIMIT, offset: 0 } });\n const notebooksQuery = useCosNotebooksQuery({ pagination: { limit: TILE_LIMIT, offset: 0 } });\n const releasesQuery = useCosReleasesQuery({ pagination: { limit: TILE_LIMIT, offset: 0 } });\n const publishedQuery = useCosReleasesQuery({\n status: 'PUBLISHED',\n pagination: { limit: 5, offset: 0 },\n });\n\n const recentRuns = (runsQuery.data?.cosListRuns?.items ?? []).slice(0, 6);\n const publishedReleases = publishedQuery.data?.cosListReleases?.items ?? [];\n\n return (\n <PageLayout\n title=\"CosmicIntersection\"\n description=\"A federation workspace for science data — sources, datasets, pipelines, notebooks and releases in one place.\"\n actions={\n <Button type=\"button\" onClick={() => navigate('datasets/create')}>\n <Plus className=\"size-4\" />\n New dataset\n </Button>\n }\n >\n <div className=\"space-y-6\">\n {/* Summary tiles */}\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-6\">\n <SummaryTile\n label=\"Datasets\"\n icon={Database}\n loading={datasetsQuery.loading}\n count={connectionCount(datasetsQuery.data?.cosListDatasets)}\n onClick={() => navigate('datasets')}\n />\n <SummaryTile\n label=\"Sources\"\n icon={Radar}\n loading={sourcesQuery.loading}\n count={connectionCount(sourcesQuery.data?.cosListSources)}\n onClick={() => navigate('sources')}\n />\n <SummaryTile\n label=\"Pipelines\"\n icon={Workflow}\n loading={pipelinesQuery.loading}\n count={connectionCount(pipelinesQuery.data?.cosListPipelines)}\n onClick={() => navigate('pipelines')}\n />\n <SummaryTile\n label=\"Runs\"\n icon={Boxes}\n loading={runsQuery.loading}\n count={connectionCount(runsQuery.data?.cosListRuns)}\n onClick={() => navigate('runs')}\n />\n <SummaryTile\n label=\"Notebooks\"\n icon={NotebookPen}\n loading={notebooksQuery.loading}\n count={connectionCount(notebooksQuery.data?.cosListNotebooks)}\n onClick={() => navigate('notebooks')}\n />\n <SummaryTile\n label=\"Releases\"\n icon={FileText}\n loading={releasesQuery.loading}\n count={connectionCount(releasesQuery.data?.cosListReleases)}\n onClick={() => navigate('releases')}\n />\n </div>\n\n {/* Quick actions */}\n <div className=\"rounded-card border border-border-default bg-bg-elevated p-5\">\n <h2 className=\"text-sm font-semibold text-text-primary\">Quick actions</h2>\n <div className=\"mt-3 flex flex-wrap gap-2\">\n <Button type=\"button\" variant=\"outline\" onClick={() => navigate('datasets/create')}>\n <Database className=\"size-4\" />\n Register dataset\n </Button>\n <Button type=\"button\" variant=\"outline\" onClick={() => navigate('sources/create')}>\n <Radar className=\"size-4\" />\n Connect source\n </Button>\n <Button type=\"button\" variant=\"outline\" onClick={() => navigate('pipelines/create')}>\n <Workflow className=\"size-4\" />\n Create pipeline\n </Button>\n </div>\n </div>\n\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-2\">\n {/* Recent runs */}\n <section className=\"space-y-3\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Recent runs</h2>\n <button\n type=\"button\"\n onClick={() => navigate('runs')}\n className=\"text-sm text-text-secondary underline-offset-2 hover:text-text-primary hover:underline\"\n >\n View all\n </button>\n </div>\n {runsQuery.loading ? (\n <div className=\"space-y-2\">\n {Array.from({ length: 3 }).map((_, index) => (\n <div key={index} className=\"h-14 animate-pulse rounded-card bg-bg-sunken\" />\n ))}\n </div>\n ) : recentRuns.length === 0 ? (\n <EmptyState\n icon={Boxes}\n title=\"No pipeline runs yet.\"\n description=\"Start a pipeline run to see execution history here.\"\n />\n ) : (\n <ul className=\"space-y-2\">\n {recentRuns.map((run) => (\n <li key={run.id}>\n <button\n type=\"button\"\n onClick={() => navigate(`runs/${run.id}`)}\n className=\"flex w-full items-center justify-between gap-3 rounded-card border border-border-default bg-bg-elevated px-4 py-3 text-left transition-colors hover:border-border-strong hover:bg-bg-sunken\"\n >\n <div className=\"min-w-0\">\n <p className=\"font-medium text-text-primary\">Run #{run.runNumber}</p>\n <p className=\"text-xs text-text-secondary\">\n {run.startedAt\n ? `Started ${formatDateTime(run.startedAt)}`\n : 'Not started'}\n </p>\n </div>\n <StatusBadge status={run.status} />\n </button>\n </li>\n ))}\n </ul>\n )}\n </section>\n\n {/* Recently published releases */}\n <section className=\"space-y-3\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Recently published</h2>\n <button\n type=\"button\"\n onClick={() => navigate('releases')}\n className=\"text-sm text-text-secondary underline-offset-2 hover:text-text-primary hover:underline\"\n >\n View all\n </button>\n </div>\n {publishedQuery.loading ? (\n <div className=\"space-y-2\">\n {Array.from({ length: 3 }).map((_, index) => (\n <div key={index} className=\"h-14 animate-pulse rounded-card bg-bg-sunken\" />\n ))}\n </div>\n ) : publishedReleases.length === 0 ? (\n <EmptyState\n icon={Rocket}\n title=\"No published releases yet.\"\n description=\"Publish a release to share datasets and notebooks with a citable version.\"\n />\n ) : (\n <ul className=\"space-y-2\">\n {publishedReleases.map((release) => (\n <li key={release.id}>\n <button\n type=\"button\"\n onClick={() => navigate('releases')}\n className=\"flex w-full items-center justify-between gap-3 rounded-card border border-border-default bg-bg-elevated px-4 py-3 text-left transition-colors hover:border-border-strong hover:bg-bg-sunken\"\n >\n <div className=\"min-w-0\">\n <p className=\"truncate font-medium text-text-primary\">{release.title}</p>\n <p className=\"text-xs text-text-secondary\">\n v{release.version}\n {release.publishedAt\n ? ` · Published ${formatDateTime(release.publishedAt)}`\n : ''}\n </p>\n {release.doi ? (\n <p\n className=\"mt-0.5 truncate font-mono text-xs text-text-tertiary\"\n title={release.doi}\n >\n DOI: {release.doi}\n </p>\n ) : null}\n </div>\n <StatusBadge status={release.status} />\n </button>\n </li>\n ))}\n </ul>\n )}\n </section>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;AAyBA,IAAM,IAAa;AAEnB,SAAS,EAAe,GAAwC;AAC9D,KAAI,CAAC,EACH,QAAO;CAET,IAAM,IAAO,IAAI,KAAK,EAAI;AAC1B,QAAO,OAAO,MAAM,EAAK,SAAS,CAAC,GAAG,MAAM,EAAK,gBAAgB;;AAInE,SAAS,EAAmB,GAAkD;AAC5E,KAAI,CAAC,EACH,QAAO;CAET,IAAM,IAAS,EAAW,MAAM;AAChC,QAAO,EAAW,UAAU,UAAU,GAAG,EAAO,KAAK,OAAO,EAAO;;AAWrE,SAAS,EAAY,EAAE,UAAO,UAAO,MAAM,GAAM,YAAS,cAA6B;AACrF,QACE,kBAAC,UAAD;EACE,MAAK;EACI;EACT,WAAU;YAHZ,CAKE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,QAAD;IAAM,WAAU;cAA2C;IAAa,CAAA,EACxE,kBAAC,QAAD;IAAM,WAAU;cACd,kBAAC,GAAD;KAAM,WAAU;KAAS,eAAY;KAAS,CAAA;IACzC,CAAA,CACH;MACN,kBAAC,QAAD;GAAM,WAAU;aACb,IAAU,MAAM;GACZ,CAAA,CACA;;;AAIb,SAAwB,IAAgB;CACtC,IAAM,EAAE,gBAAa,GAAuB,EAEtC,IAAgB,EAAoB,EAAE,YAAY;EAAE,OAAO;EAAY,QAAQ;EAAG,EAAE,CAAC,EACrF,IAAe,EAAmB,EAAE,YAAY;EAAE,OAAO;EAAY,QAAQ;EAAG,EAAE,CAAC,EACnF,IAAiB,EAAqB,EAAE,YAAY;EAAE,OAAO;EAAY,QAAQ;EAAG,EAAE,CAAC,EACvF,IAAY,EAAgB,EAAE,YAAY;EAAE,OAAO;EAAY,QAAQ;EAAG,EAAE,CAAC,EAC7E,IAAiB,EAAqB,EAAE,YAAY;EAAE,OAAO;EAAY,QAAQ;EAAG,EAAE,CAAC,EACvF,IAAgB,EAAoB,EAAE,YAAY;EAAE,OAAO;EAAY,QAAQ;EAAG,EAAE,CAAC,EACrF,IAAiB,EAAoB;EACzC,QAAQ;EACR,YAAY;GAAE,OAAO;GAAG,QAAQ;GAAG;EACpC,CAAC,EAEI,KAAc,EAAU,MAAM,aAAa,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE,EACnE,IAAoB,EAAe,MAAM,iBAAiB,SAAS,EAAE;AAE3E,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,GAAD;GAAQ,MAAK;GAAS,eAAe,EAAS,kBAAkB;aAAhE,CACE,kBAAC,GAAD,EAAM,WAAU,UAAW,CAAA,EAAA,cAEpB;;YAGX,kBAAC,OAAD;GAAK,WAAU;aAAf;IAEE,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,GAAD;OACE,OAAM;OACN,MAAM;OACN,SAAS,EAAc;OACvB,OAAO,EAAgB,EAAc,MAAM,gBAAgB;OAC3D,eAAe,EAAS,WAAW;OACnC,CAAA;MACF,kBAAC,GAAD;OACE,OAAM;OACN,MAAM;OACN,SAAS,EAAa;OACtB,OAAO,EAAgB,EAAa,MAAM,eAAe;OACzD,eAAe,EAAS,UAAU;OAClC,CAAA;MACF,kBAAC,GAAD;OACE,OAAM;OACN,MAAM;OACN,SAAS,EAAe;OACxB,OAAO,EAAgB,EAAe,MAAM,iBAAiB;OAC7D,eAAe,EAAS,YAAY;OACpC,CAAA;MACF,kBAAC,GAAD;OACE,OAAM;OACN,MAAM;OACN,SAAS,EAAU;OACnB,OAAO,EAAgB,EAAU,MAAM,YAAY;OACnD,eAAe,EAAS,OAAO;OAC/B,CAAA;MACF,kBAAC,GAAD;OACE,OAAM;OACN,MAAM;OACN,SAAS,EAAe;OACxB,OAAO,EAAgB,EAAe,MAAM,iBAAiB;OAC7D,eAAe,EAAS,YAAY;OACpC,CAAA;MACF,kBAAC,GAAD;OACE,OAAM;OACN,MAAM;OACN,SAAS,EAAc;OACvB,OAAO,EAAgB,EAAc,MAAM,gBAAgB;OAC3D,eAAe,EAAS,WAAW;OACnC,CAAA;MACE;;IAGN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBAA0C;MAAkB,CAAA,EAC1E,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,GAAD;QAAQ,MAAK;QAAS,SAAQ;QAAU,eAAe,EAAS,kBAAkB;kBAAlF,CACE,kBAAC,GAAD,EAAU,WAAU,UAAW,CAAA,EAAA,mBAExB;;OACT,kBAAC,GAAD;QAAQ,MAAK;QAAS,SAAQ;QAAU,eAAe,EAAS,iBAAiB;kBAAjF,CACE,kBAAC,GAAD,EAAO,WAAU,UAAW,CAAA,EAAA,iBAErB;;OACT,kBAAC,GAAD;QAAQ,MAAK;QAAS,SAAQ;QAAU,eAAe,EAAS,mBAAmB;kBAAnF,CACE,kBAAC,GAAD,EAAU,WAAU,UAAW,CAAA,EAAA,kBAExB;;OACL;QACF;;IAEN,kBAAC,OAAD;KAAK,WAAU;eAAf,CAEE,kBAAC,WAAD;MAAS,WAAU;gBAAnB,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,MAAD;QAAI,WAAU;kBAA0C;QAAgB,CAAA,EACxE,kBAAC,UAAD;QACE,MAAK;QACL,eAAe,EAAS,OAAO;QAC/B,WAAU;kBACX;QAEQ,CAAA,CACL;UACL,EAAU,UACT,kBAAC,OAAD;OAAK,WAAU;iBACZ,MAAM,KAAK,EAAE,QAAQ,GAAG,CAAC,CAAC,KAAK,GAAG,MACjC,kBAAC,OAAD,EAAiB,WAAU,gDAAiD,EAAlE,EAAkE,CAC5E;OACE,CAAA,GACJ,EAAW,WAAW,IACxB,kBAAC,GAAD;OACE,MAAM;OACN,OAAM;OACN,aAAY;OACZ,CAAA,GAEF,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAW,KAAK,MACf,kBAAC,MAAD,EAAA,UACE,kBAAC,UAAD;QACE,MAAK;QACL,eAAe,EAAS,QAAQ,EAAI,KAAK;QACzC,WAAU;kBAHZ,CAKE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,KAAD;UAAG,WAAU;oBAAb,CAA6C,SAAM,EAAI,UAAc;aACrE,kBAAC,KAAD;UAAG,WAAU;oBACV,EAAI,YACD,WAAW,EAAe,EAAI,UAAU,KACxC;UACF,CAAA,CACA;YACN,kBAAC,GAAD,EAAa,QAAQ,EAAI,QAAU,CAAA,CAC5B;WACN,EAhBI,EAAI,GAgBR,CACL;OACC,CAAA,CAEC;SAGV,kBAAC,WAAD;MAAS,WAAU;gBAAnB,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,MAAD;QAAI,WAAU;kBAA0C;QAAuB,CAAA,EAC/E,kBAAC,UAAD;QACE,MAAK;QACL,eAAe,EAAS,WAAW;QACnC,WAAU;kBACX;QAEQ,CAAA,CACL;UACL,EAAe,UACd,kBAAC,OAAD;OAAK,WAAU;iBACZ,MAAM,KAAK,EAAE,QAAQ,GAAG,CAAC,CAAC,KAAK,GAAG,MACjC,kBAAC,OAAD,EAAiB,WAAU,gDAAiD,EAAlE,EAAkE,CAC5E;OACE,CAAA,GACJ,EAAkB,WAAW,IAC/B,kBAAC,GAAD;OACE,MAAM;OACN,OAAM;OACN,aAAY;OACZ,CAAA,GAEF,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAkB,KAAK,MACtB,kBAAC,MAAD,EAAA,UACE,kBAAC,UAAD;QACE,MAAK;QACL,eAAe,EAAS,WAAW;QACnC,WAAU;kBAHZ,CAKE,kBAAC,OAAD;SAAK,WAAU;mBAAf;UACE,kBAAC,KAAD;WAAG,WAAU;qBAA0C,EAAQ;WAAU,CAAA;UACzE,kBAAC,KAAD;WAAG,WAAU;qBAAb;YAA2C;YACvC,EAAQ;YACT,EAAQ,cACL,gBAAgB,EAAe,EAAQ,YAAY,KACnD;YACF;;UACH,EAAQ,MACP,kBAAC,KAAD;WACE,WAAU;WACV,OAAO,EAAQ;qBAFjB,CAGC,SACO,EAAQ,IACZ;eACF;UACA;YACN,kBAAC,GAAD,EAAa,QAAQ,EAAQ,QAAU,CAAA,CAChC;WACN,EAzBI,EAAQ,GAyBZ,CACL;OACC,CAAA,CAEC;QACN;;IACF;;EACK,CAAA"}
@@ -0,0 +1,2 @@
1
+ export default function DatasetDetailPage(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=DatasetDetailPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DatasetDetailPage.d.ts","sourceRoot":"","sources":["../../../../src/cosmicintersection/pages/datasets/DatasetDetailPage.tsx"],"names":[],"mappings":"AA6HA,MAAM,CAAC,OAAO,UAAU,iBAAiB,4CA8jBxC"}