@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":"PipelineFormPage.js","names":[],"sources":["../../../../src/cosmicintersection/pages/pipelines/PipelineFormPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport {\n Input,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\n\nimport {\n useCosCreatePipelineMutation,\n useCosPipelineQuery,\n useCosUpdatePipelineMutation,\n type CosPipelineTrigger,\n} from '../../api/cosmicApi';\nimport { EntityFormShell, EntityTagsField, formatEnumLabel } from '../../components';\nimport { useCosmicIntersection } from '../../context/CosmicIntersectionContext';\nimport { describeError, mutationSucceeded } from '../../lib/mutationResult';\nimport { notify } from '../../lib/toast';\n\nconst TRIGGER_OPTIONS: CosPipelineTrigger[] = ['MANUAL', 'SCHEDULED', 'ON_INGEST', 'WEBHOOK'];\n\ninterface PipelineFormState {\n name: string;\n description: string;\n trigger: CosPipelineTrigger;\n schedule: string;\n definition: string;\n tags: string[];\n}\n\nconst INITIAL_STATE: PipelineFormState = {\n name: '',\n description: '',\n trigger: 'MANUAL',\n schedule: '',\n definition: '',\n tags: [],\n};\n\n/** Parse the definition textarea into a JSON object, or throw a readable error. */\nfunction parseDefinition(raw: string): Record<string, unknown> | undefined {\n const trimmed = raw.trim();\n if (!trimmed) {\n return undefined;\n }\n const parsed = JSON.parse(trimmed) as unknown;\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw new Error('Definition must be a JSON object.');\n }\n return parsed as Record<string, unknown>;\n}\n\nexport default function PipelineFormPage() {\n const { id = '' } = useParams<{ id: string }>();\n const isEdit = Boolean(id);\n const { navigate } = useCosmicIntersection();\n\n const { data, loading: loadingPipeline } = useCosPipelineQuery(id);\n const [createPipeline, { loading: creating }] = useCosCreatePipelineMutation();\n const [updatePipeline, { loading: updating }] = useCosUpdatePipelineMutation();\n\n const [form, setForm] = useState<PipelineFormState>(INITIAL_STATE);\n\n // Hydrate the form once the edited pipeline loads. Derive-during-render (the\n // documented React pattern) keyed on the loaded id so a later refetch of the\n // same record never clobbers the user's in-progress edits.\n const loaded = isEdit ? data?.cosPipeline : null;\n const [hydratedId, setHydratedId] = useState<string | null>(null);\n if (loaded && loaded.id !== hydratedId) {\n setHydratedId(loaded.id);\n setForm({\n name: loaded.name ?? '',\n description: loaded.description ?? '',\n trigger: loaded.trigger ?? 'MANUAL',\n schedule: loaded.schedule ?? '',\n definition: loaded.definition ? JSON.stringify(loaded.definition, null, 2) : '',\n tags: loaded.tags ?? [],\n });\n }\n\n const setField = <K extends keyof PipelineFormState>(field: K, value: PipelineFormState[K]) => {\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 the pipeline a name before saving.');\n return;\n }\n\n let definition: Record<string, unknown> | undefined;\n try {\n definition = parseDefinition(form.definition);\n } catch (error) {\n notify.error('Invalid definition JSON', describeError(error) ?? 'Please provide valid JSON.');\n return;\n }\n\n const schedule = form.trigger === 'SCHEDULED' ? form.schedule.trim() : '';\n\n try {\n if (isEdit) {\n const response = await updatePipeline({\n variables: {\n id,\n input: {\n name: form.name.trim(),\n description: form.description.trim() || undefined,\n trigger: form.trigger,\n schedule: schedule || undefined,\n definition,\n tags: form.tags,\n },\n },\n });\n if (\n !mutationSucceeded(\n response,\n response.data?.cosUpdatePipeline?.id,\n 'Could not update pipeline'\n )\n ) {\n return;\n }\n notify.success('Pipeline updated', `“${form.name.trim()}” was saved.`);\n navigate(`pipelines/${id}`);\n return;\n }\n\n const response = await createPipeline({\n variables: {\n input: {\n name: form.name.trim(),\n description: form.description.trim() || undefined,\n trigger: form.trigger,\n schedule: schedule || undefined,\n definition,\n tags: form.tags,\n },\n },\n });\n const createdId = response.data?.cosCreatePipeline?.id;\n if (!mutationSucceeded(response, createdId, 'Could not create pipeline')) {\n return;\n }\n notify.success('Pipeline created', `“${form.name.trim()}” is ready.`);\n navigate(createdId ? `pipelines/${createdId}` : 'pipelines');\n } catch (error) {\n notify.error('Could not save pipeline', describeError(error));\n }\n };\n\n const saving = creating || updating;\n\n return (\n <EntityFormShell\n title={isEdit ? 'Edit pipeline' : 'New pipeline'}\n description=\"Define how raw data is ingested, processed and released.\"\n purpose=\"A pipeline chains ordered steps (ingest, calibrate, transform, analyze, export) over your datasets. Choose how it is triggered, add an optional cron schedule, and describe its steps as a JSON definition.\"\n backLabel={isEdit ? 'Back to pipeline' : 'Back to pipelines'}\n onBack={() => navigate(isEdit ? `pipelines/${id}` : 'pipelines')}\n onSubmit={onSubmit}\n submitLabel={isEdit ? 'Save changes' : 'Create pipeline'}\n saving={saving}\n submitDisabled={isEdit && loadingPipeline}\n >\n <div className=\"space-y-1\">\n <Label htmlFor=\"pipeline-name\">Name</Label>\n <Input\n id=\"pipeline-name\"\n value={form.name}\n onChange={(event) => setField('name', event.target.value)}\n placeholder=\"e.g. Kepler DR3 ingest\"\n required\n />\n </div>\n\n <div className=\"space-y-1\">\n <Label htmlFor=\"pipeline-description\">Description</Label>\n <Textarea\n id=\"pipeline-description\"\n value={form.description}\n onChange={(event) => setField('description', event.target.value)}\n rows={3}\n placeholder=\"What this pipeline does and when it runs.\"\n />\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n <div className=\"space-y-1\">\n <Label htmlFor=\"pipeline-trigger\">Trigger</Label>\n <Select\n value={form.trigger}\n onValueChange={(value) => setField('trigger', value as CosPipelineTrigger)}\n >\n <SelectTrigger id=\"pipeline-trigger\" aria-label=\"Trigger\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {TRIGGER_OPTIONS.map((option) => (\n <SelectItem key={option} value={option}>\n {formatEnumLabel(option)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {form.trigger === 'SCHEDULED' ? (\n <div className=\"space-y-1\">\n <Label htmlFor=\"pipeline-schedule\">Schedule (cron)</Label>\n <Input\n id=\"pipeline-schedule\"\n value={form.schedule}\n onChange={(event) => setField('schedule', event.target.value)}\n placeholder=\"0 2 * * *\"\n className=\"font-mono\"\n />\n <p className=\"text-xs text-text-secondary\">\n Standard 5-field cron expression, e.g. <span className=\"font-mono\">0 2 * * *</span>{' '}\n for daily at 02:00.\n </p>\n </div>\n ) : null}\n </div>\n\n <div className=\"space-y-1\">\n <Label htmlFor=\"pipeline-definition\">Definition (JSON)</Label>\n <Textarea\n id=\"pipeline-definition\"\n value={form.definition}\n onChange={(event) => setField('definition', event.target.value)}\n rows={8}\n spellCheck={false}\n className=\"font-mono text-xs\"\n placeholder={\n '{\\n \"steps\": [\\n { \"kind\": \"INGEST\", \"name\": \"Fetch raw frames\" }\\n ]\\n}'\n }\n />\n <p className=\"text-xs text-text-secondary\">\n Optional. A JSON object describing the pipeline steps. Leave blank to configure steps\n later.\n </p>\n </div>\n\n <EntityTagsField value={form.tags} onChange={(tags) => setField('tags', tags)} />\n </EntityFormShell>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"PipelineFormPage.js","names":[],"sources":["../../../../src/cosmicintersection/pages/pipelines/PipelineFormPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { ArrowDown, ArrowUp, GripVertical, Plus, Trash2 } from 'lucide-react';\nimport {\n Button,\n Input,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\n\nimport {\n useCosCreatePipelineMutation,\n useCosPipelineQuery,\n useCosUpdatePipelineMutation,\n type CosPipelineTrigger,\n type CosStepKind,\n} from '../../api/cosmicApi';\nimport { EntityFormShell, EntityTagsField, formatEnumLabel } from '../../components';\nimport { useCosmicIntersection } from '../../context/CosmicIntersectionContext';\nimport { describeError, mutationSucceeded } from '../../lib/mutationResult';\nimport { notify } from '../../lib/toast';\n\nconst TRIGGER_OPTIONS: CosPipelineTrigger[] = ['MANUAL', 'SCHEDULED', 'ON_INGEST', 'WEBHOOK'];\nconst STEP_KINDS: CosStepKind[] = [\n 'INGEST',\n 'CALIBRATE',\n 'TRANSFORM',\n 'ANALYZE',\n 'EXPORT',\n 'NOTIFY',\n];\n\nfunction isStepKind(value: unknown): value is CosStepKind {\n return typeof value === 'string' && (STEP_KINDS as string[]).includes(value);\n}\n\nlet stepIdSeq = 0;\nconst makeStepId = () => `step-${(stepIdSeq += 1)}`;\n\ninterface StepRow {\n id: string;\n kind: CosStepKind;\n name: string;\n}\n\ninterface PipelineFormState {\n name: string;\n description: string;\n trigger: CosPipelineTrigger;\n schedule: string;\n steps: StepRow[];\n tags: string[];\n}\n\nconst INITIAL_STATE: PipelineFormState = {\n name: '',\n description: '',\n trigger: 'MANUAL',\n schedule: '',\n steps: [],\n tags: [],\n};\n\n/** Parse an existing definition's `steps[]` into editable builder rows. */\nfunction definitionToRows(definition?: Record<string, unknown> | null): StepRow[] {\n if (!definition) {\n return [];\n }\n const raw = (definition as { steps?: unknown }).steps;\n if (!Array.isArray(raw)) {\n return [];\n }\n const rows: StepRow[] = [];\n for (const item of raw) {\n if (item && typeof item === 'object' && !Array.isArray(item)) {\n const kind = (item as { kind?: unknown }).kind;\n const name = (item as { name?: unknown }).name;\n if (isStepKind(kind)) {\n rows.push({ id: makeStepId(), kind, name: typeof name === 'string' ? name : '' });\n }\n }\n }\n return rows;\n}\n\n/** Serialize builder rows to the `steps[]` payload — omitting blank names. */\nfunction rowsToSteps(rows: StepRow[]): Record<string, unknown>[] {\n return rows.map((row) => {\n const step: Record<string, unknown> = { kind: row.kind };\n const name = row.name.trim();\n if (name) {\n step.name = name;\n }\n return step;\n });\n}\n\nexport default function PipelineFormPage() {\n const { id = '' } = useParams<{ id: string }>();\n const isEdit = Boolean(id);\n const { navigate } = useCosmicIntersection();\n\n const { data, loading: loadingPipeline } = useCosPipelineQuery(id);\n const [createPipeline, { loading: creating }] = useCosCreatePipelineMutation();\n const [updatePipeline, { loading: updating }] = useCosUpdatePipelineMutation();\n\n const [form, setForm] = useState<PipelineFormState>(INITIAL_STATE);\n // Extra top-level definition keys (anything other than `steps`) preserved\n // verbatim so editing steps never silently drops other configuration.\n const [baseDefinition, setBaseDefinition] = useState<Record<string, unknown>>({});\n const [jsonText, setJsonText] = useState('');\n const [jsonError, setJsonError] = useState<string | null>(null);\n\n // Hydrate the form once the edited pipeline loads. Derive-during-render keyed\n // on the loaded id so a later refetch never clobbers in-progress edits.\n const loaded = isEdit ? data?.cosPipeline : null;\n const [hydratedId, setHydratedId] = useState<string | null>(null);\n if (loaded && loaded.id !== hydratedId) {\n setHydratedId(loaded.id);\n setForm({\n name: loaded.name ?? '',\n description: loaded.description ?? '',\n trigger: loaded.trigger ?? 'MANUAL',\n schedule: loaded.schedule ?? '',\n steps: definitionToRows(loaded.definition),\n tags: loaded.tags ?? [],\n });\n const extra: Record<string, unknown> = { ...(loaded.definition ?? {}) };\n delete extra.steps;\n setBaseDefinition(extra);\n }\n\n const setField = <K extends keyof PipelineFormState>(field: K, value: PipelineFormState[K]) => {\n setForm((prev) => ({ ...prev, [field]: value }));\n };\n\n const serializedSteps = useMemo(\n () => JSON.stringify({ ...baseDefinition, steps: rowsToSteps(form.steps) }, null, 2),\n [baseDefinition, form.steps]\n );\n\n const addStep = () => {\n setField('steps', [...form.steps, { id: makeStepId(), kind: 'INGEST', name: '' }]);\n };\n\n const removeStep = (stepId: string) => {\n setField(\n 'steps',\n form.steps.filter((step) => step.id !== stepId)\n );\n };\n\n const updateStep = (stepId: string, patch: Partial<Omit<StepRow, 'id'>>) => {\n setField(\n 'steps',\n form.steps.map((step) => (step.id === stepId ? { ...step, ...patch } : step))\n );\n };\n\n const moveStep = (index: number, direction: -1 | 1) => {\n const target = index + direction;\n if (target < 0 || target >= form.steps.length) {\n return;\n }\n const next = [...form.steps];\n const [moved] = next.splice(index, 1);\n next.splice(target, 0, moved);\n setField('steps', next);\n };\n\n const applyJson = () => {\n let parsed: unknown;\n try {\n parsed = JSON.parse(jsonText);\n } catch (error) {\n setJsonError(describeError(error) ?? 'Invalid JSON.');\n return;\n }\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n setJsonError('Definition must be a JSON object with a \"steps\" array.');\n return;\n }\n const rawSteps = (parsed as { steps?: unknown }).steps;\n if (!Array.isArray(rawSteps)) {\n setJsonError('Definition must contain a \"steps\" array.');\n return;\n }\n const rows: StepRow[] = [];\n for (const item of rawSteps) {\n if (!item || typeof item !== 'object' || Array.isArray(item)) {\n setJsonError('Each step must be an object with a \"kind\".');\n return;\n }\n const kind = (item as { kind?: unknown }).kind;\n if (!isStepKind(kind)) {\n setJsonError(`Invalid step kind \"${String(kind)}\". Allowed: ${STEP_KINDS.join(', ')}.`);\n return;\n }\n const name = (item as { name?: unknown }).name;\n rows.push({ id: makeStepId(), kind, name: typeof name === 'string' ? name : '' });\n }\n const extra: Record<string, unknown> = { ...(parsed as Record<string, unknown>) };\n delete extra.steps;\n setBaseDefinition(extra);\n setField('steps', rows);\n setJsonError(null);\n notify.success('Steps updated', 'The builder now reflects your JSON.');\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 the pipeline a name before saving.');\n return;\n }\n\n // Build the definition from the builder (the single source of truth),\n // preserving any extra top-level keys.\n const stepsPayload = rowsToSteps(form.steps);\n const base: Record<string, unknown> = { ...baseDefinition };\n delete base.steps;\n let definition: Record<string, unknown> | undefined;\n if (stepsPayload.length > 0) {\n definition = { ...base, steps: stepsPayload };\n } else if (Object.keys(base).length > 0) {\n definition = base;\n } else {\n definition = undefined;\n }\n\n const schedule = form.trigger === 'SCHEDULED' ? form.schedule.trim() : '';\n\n try {\n if (isEdit) {\n const response = await updatePipeline({\n variables: {\n id,\n input: {\n name: form.name.trim(),\n description: form.description.trim() || undefined,\n trigger: form.trigger,\n schedule: schedule || undefined,\n definition,\n tags: form.tags,\n },\n },\n });\n if (\n !mutationSucceeded(\n response,\n response.data?.cosUpdatePipeline?.id,\n 'Could not update pipeline'\n )\n ) {\n return;\n }\n notify.success('Pipeline updated', `“${form.name.trim()}” was saved.`);\n navigate(`pipelines/${id}`);\n return;\n }\n\n const response = await createPipeline({\n variables: {\n input: {\n name: form.name.trim(),\n description: form.description.trim() || undefined,\n trigger: form.trigger,\n schedule: schedule || undefined,\n definition,\n tags: form.tags,\n },\n },\n });\n const createdId = response.data?.cosCreatePipeline?.id;\n if (!mutationSucceeded(response, createdId, 'Could not create pipeline')) {\n return;\n }\n notify.success('Pipeline created', `“${form.name.trim()}” is ready.`);\n navigate(createdId ? `pipelines/${createdId}` : 'pipelines');\n } catch (error) {\n notify.error('Could not save pipeline', describeError(error));\n }\n };\n\n const saving = creating || updating;\n\n return (\n <EntityFormShell\n title={isEdit ? 'Edit pipeline' : 'New pipeline'}\n description=\"Define how raw data is ingested, processed and released.\"\n purpose=\"A pipeline chains ordered steps (ingest, calibrate, transform, analyze, export) over your datasets. Choose how it is triggered, add an optional cron schedule, and build its steps below.\"\n backLabel={isEdit ? 'Back to pipeline' : 'Back to pipelines'}\n onBack={() => navigate(isEdit ? `pipelines/${id}` : 'pipelines')}\n onSubmit={onSubmit}\n submitLabel={isEdit ? 'Save changes' : 'Create pipeline'}\n saving={saving}\n submitDisabled={isEdit && loadingPipeline}\n >\n <div className=\"space-y-1\">\n <Label htmlFor=\"pipeline-name\">Name</Label>\n <Input\n id=\"pipeline-name\"\n value={form.name}\n onChange={(event) => setField('name', event.target.value)}\n placeholder=\"e.g. Kepler DR3 ingest\"\n required\n />\n </div>\n\n <div className=\"space-y-1\">\n <Label htmlFor=\"pipeline-description\">Description</Label>\n <Textarea\n id=\"pipeline-description\"\n value={form.description}\n onChange={(event) => setField('description', event.target.value)}\n rows={3}\n placeholder=\"What this pipeline does and when it runs.\"\n />\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n <div className=\"space-y-1\">\n <Label htmlFor=\"pipeline-trigger\">Trigger</Label>\n <Select\n value={form.trigger}\n onValueChange={(value) => setField('trigger', value as CosPipelineTrigger)}\n >\n <SelectTrigger id=\"pipeline-trigger\" aria-label=\"Trigger\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {TRIGGER_OPTIONS.map((option) => (\n <SelectItem key={option} value={option}>\n {formatEnumLabel(option)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {form.trigger === 'SCHEDULED' ? (\n <div className=\"space-y-1\">\n <Label htmlFor=\"pipeline-schedule\">Schedule (cron)</Label>\n <Input\n id=\"pipeline-schedule\"\n value={form.schedule}\n onChange={(event) => setField('schedule', event.target.value)}\n placeholder=\"0 2 * * *\"\n className=\"font-mono\"\n />\n <p className=\"text-xs text-text-secondary\">\n Standard 5-field cron expression, e.g. <span className=\"font-mono\">0 2 * * *</span>{' '}\n for daily at 02:00.\n </p>\n </div>\n ) : null}\n </div>\n\n {/* Structured step builder (mockup 12). */}\n <div className=\"space-y-2\">\n <Label>Definition — steps</Label>\n <p className=\"text-xs text-text-secondary\">\n The ordered stages this pipeline runs. Add a step, pick its kind, optionally name it, and\n reorder with the arrows.\n </p>\n\n {form.steps.length === 0 ? (\n <div className=\"rounded-card border border-dashed border-border-default bg-bg-sunken px-4 py-6 text-center\">\n <p className=\"text-sm text-text-secondary\">\n No steps yet. Add the first stage to start building the flow.\n </p>\n </div>\n ) : (\n <ol className=\"space-y-2\">\n {form.steps.map((step, index) => (\n <li\n key={step.id}\n className=\"flex items-center gap-2 rounded-card border border-border-default bg-bg-elevated p-2.5\"\n >\n <span className=\"flex items-center gap-1.5 text-text-secondary\">\n <GripVertical className=\"size-4 shrink-0\" aria-hidden=\"true\" />\n <span className=\"w-4 text-xs font-semibold tabular-nums\">{index + 1}</span>\n </span>\n\n <div className=\"grid min-w-0 flex-1 grid-cols-1 gap-2 sm:grid-cols-[10rem_1fr]\">\n <Select\n value={step.kind}\n onValueChange={(value) => updateStep(step.id, { kind: value as CosStepKind })}\n >\n <SelectTrigger aria-label={`Kind for step ${index + 1}`}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {STEP_KINDS.map((option) => (\n <SelectItem key={option} value={option}>\n {formatEnumLabel(option)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Input\n value={step.name}\n onChange={(event) => updateStep(step.id, { name: event.target.value })}\n placeholder=\"Optional step name\"\n aria-label={`Name for step ${index + 1}`}\n />\n </div>\n\n <div className=\"flex shrink-0 items-center gap-0.5\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n onClick={() => moveStep(index, -1)}\n disabled={index === 0}\n aria-label={`Move step ${index + 1} up`}\n >\n <ArrowUp className=\"size-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n onClick={() => moveStep(index, 1)}\n disabled={index === form.steps.length - 1}\n aria-label={`Move step ${index + 1} down`}\n >\n <ArrowDown className=\"size-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n onClick={() => removeStep(step.id)}\n aria-label={`Remove step ${index + 1}`}\n className=\"text-text-secondary hover:text-status-error-text\"\n >\n <Trash2 className=\"size-4\" />\n </Button>\n </div>\n </li>\n ))}\n </ol>\n )}\n\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={addStep}>\n <Plus className=\"size-4\" />\n Add step\n </Button>\n\n <details\n className=\"group mt-2 rounded-card border border-border-default bg-bg-sunken\"\n onToggle={(event) => {\n if (event.currentTarget.open) {\n setJsonText(serializedSteps);\n setJsonError(null);\n }\n }}\n >\n <summary className=\"flex cursor-pointer list-none items-center justify-between px-4 py-2.5 text-sm font-medium text-text-secondary transition-colors hover:text-text-primary\">\n Advanced — edit as JSON\n <span className=\"text-xs transition-transform group-open:rotate-180\">▾</span>\n </summary>\n <div className=\"space-y-2 border-t border-border-seam p-4\">\n <Textarea\n value={jsonText}\n onChange={(event) => {\n setJsonText(event.target.value);\n setJsonError(null);\n }}\n rows={8}\n spellCheck={false}\n className=\"font-mono text-xs\"\n aria-label=\"Definition JSON\"\n />\n {jsonError ? <p className=\"text-xs text-status-error-text\">{jsonError}</p> : null}\n <div className=\"flex items-center justify-between gap-2\">\n <p className=\"text-xs text-text-secondary\">\n Edit the raw definition, then apply it back to the builder above.\n </p>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={applyJson}>\n Apply to builder\n </Button>\n </div>\n </div>\n </details>\n </div>\n\n <EntityTagsField value={form.tags} onChange={(tags) => setField('tags', tags)} />\n </EntityFormShell>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export default function PipelinesPage(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=PipelinesPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PipelinesPage.d.ts","sourceRoot":"","sources":["../../../../src/cosmicintersection/pages/pipelines/PipelinesPage.tsx"],"names":[],"mappings":"AAkDA,MAAM,CAAC,OAAO,UAAU,aAAa,4CA8SpC"}
@@ -87,75 +87,178 @@ function R() {
87
87
  onClick: () => R("pipelines/create"),
88
88
  children: [/* @__PURE__ */ v(S, { className: "size-4" }), "New pipeline"]
89
89
  }) : void 0
90
- }) : /* @__PURE__ */ y(_, { children: [/* @__PURE__ */ v("div", {
91
- className: "overflow-x-auto rounded-card border border-border-default bg-bg-elevated",
92
- children: /* @__PURE__ */ y(k, { children: [/* @__PURE__ */ v(N, { children: /* @__PURE__ */ y(P, { children: [
93
- /* @__PURE__ */ v(M, { children: "Name" }),
94
- /* @__PURE__ */ v(M, { children: "Status" }),
95
- /* @__PURE__ */ v(M, { children: "Trigger" }),
96
- /* @__PURE__ */ v(M, { children: "Schedule" }),
97
- /* @__PURE__ */ v(M, { children: "Last run" }),
98
- /* @__PURE__ */ v(M, {
99
- className: "text-right",
100
- children: "Version"
101
- }),
102
- /* @__PURE__ */ v(M, { children: "Tags" }),
103
- /* @__PURE__ */ v(M, {
104
- className: "w-12 text-right",
105
- children: /* @__PURE__ */ v("span", {
106
- className: "sr-only",
107
- children: "Actions"
90
+ }) : /* @__PURE__ */ y(_, { children: [
91
+ /* @__PURE__ */ v("div", {
92
+ className: "hidden rounded-card border border-border-default bg-bg-elevated md:block",
93
+ children: /* @__PURE__ */ y(k, { children: [/* @__PURE__ */ v(N, { children: /* @__PURE__ */ y(P, { children: [
94
+ /* @__PURE__ */ v(M, { children: "Name" }),
95
+ /* @__PURE__ */ v(M, { children: "Status" }),
96
+ /* @__PURE__ */ v(M, { children: "Trigger" }),
97
+ /* @__PURE__ */ v(M, { children: "Schedule" }),
98
+ /* @__PURE__ */ v(M, { children: "Last run" }),
99
+ /* @__PURE__ */ v(M, {
100
+ className: "text-right",
101
+ children: "Version"
102
+ }),
103
+ /* @__PURE__ */ v(M, { children: "Tags" }),
104
+ /* @__PURE__ */ v(M, {
105
+ className: "w-12 text-right",
106
+ children: /* @__PURE__ */ v("span", {
107
+ className: "sr-only",
108
+ children: "Actions"
109
+ })
108
110
  })
109
- })
110
- ] }) }), /* @__PURE__ */ v(A, { children: J.map((e) => /* @__PURE__ */ y(P, {
111
- className: "cursor-pointer",
112
- onClick: () => R(`pipelines/${e.id}`),
113
- children: [
114
- /* @__PURE__ */ v(j, {
115
- className: "font-medium text-text-primary",
116
- children: /* @__PURE__ */ y("div", {
117
- className: "flex flex-col",
118
- children: [/* @__PURE__ */ v("span", {
119
- className: "truncate",
120
- children: e.name
121
- }), e.description ? /* @__PURE__ */ v("span", {
122
- className: "mt-0.5 line-clamp-1 text-xs text-text-secondary",
123
- children: e.description
111
+ ] }) }), /* @__PURE__ */ v(A, { children: J.map((e) => /* @__PURE__ */ y(P, {
112
+ className: "cursor-pointer",
113
+ onClick: () => R(`pipelines/${e.id}`),
114
+ children: [
115
+ /* @__PURE__ */ v(j, {
116
+ className: "font-medium text-text-primary",
117
+ children: /* @__PURE__ */ y("div", {
118
+ className: "flex flex-col",
119
+ children: [/* @__PURE__ */ v("span", {
120
+ className: "truncate",
121
+ children: e.name
122
+ }), e.description ? /* @__PURE__ */ v("span", {
123
+ className: "mt-0.5 line-clamp-1 text-xs text-text-secondary",
124
+ children: e.description
125
+ }) : null]
126
+ })
127
+ }),
128
+ /* @__PURE__ */ v(j, { children: /* @__PURE__ */ v(f, { status: e.status }) }),
129
+ /* @__PURE__ */ v(j, {
130
+ className: "text-text-secondary",
131
+ children: p(e.trigger)
132
+ }),
133
+ /* @__PURE__ */ v(j, {
134
+ className: "font-mono text-xs text-text-secondary",
135
+ children: e.schedule || "—"
136
+ }),
137
+ /* @__PURE__ */ v(j, {
138
+ className: "whitespace-nowrap text-text-secondary",
139
+ children: L(e.lastRunAt)
140
+ }),
141
+ /* @__PURE__ */ y(j, {
142
+ className: "text-right tabular-nums text-text-secondary",
143
+ children: ["v", e.version]
144
+ }),
145
+ /* @__PURE__ */ v(j, { children: /* @__PURE__ */ y("div", {
146
+ className: "flex max-w-[12rem] flex-wrap gap-1",
147
+ children: [e.tags.length === 0 ? /* @__PURE__ */ v("span", {
148
+ className: "text-xs text-text-secondary",
149
+ children: "—"
150
+ }) : e.tags.slice(0, 3).map((e) => /* @__PURE__ */ v("span", {
151
+ className: "rounded-full bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary",
152
+ children: e
153
+ }, e)), e.tags.length > 3 ? /* @__PURE__ */ y("span", {
154
+ className: "text-xs text-text-secondary",
155
+ children: ["+", e.tags.length - 3]
124
156
  }) : null]
157
+ }) }),
158
+ /* @__PURE__ */ v(j, {
159
+ className: "text-right",
160
+ children: /* @__PURE__ */ v(a, {
161
+ ariaLabel: `Actions for ${e.name}`,
162
+ entityName: e.name,
163
+ onView: () => R(`pipelines/${e.id}`),
164
+ onEdit: () => R(`pipelines/${e.id}/edit`),
165
+ onDelete: () => Z(e),
166
+ deleteLabel: "Archive pipeline",
167
+ extraItems: [{
168
+ key: "start",
169
+ label: "Start run",
170
+ icon: x,
171
+ onSelect: () => void X(e),
172
+ disabled: e.status === "ARCHIVED"
173
+ }]
174
+ })
125
175
  })
126
- }),
127
- /* @__PURE__ */ v(j, { children: /* @__PURE__ */ v(f, { status: e.status }) }),
128
- /* @__PURE__ */ v(j, {
129
- className: "text-text-secondary",
130
- children: p(e.trigger)
131
- }),
132
- /* @__PURE__ */ v(j, {
133
- className: "font-mono text-xs text-text-secondary",
134
- children: e.schedule || "—"
135
- }),
136
- /* @__PURE__ */ v(j, {
137
- className: "whitespace-nowrap text-text-secondary",
138
- children: L(e.lastRunAt)
139
- }),
140
- /* @__PURE__ */ y(j, {
141
- className: "text-right tabular-nums text-text-secondary",
142
- children: ["v", e.version]
143
- }),
144
- /* @__PURE__ */ v(j, { children: /* @__PURE__ */ y("div", {
145
- className: "flex max-w-[12rem] flex-wrap gap-1",
146
- children: [e.tags.length === 0 ? /* @__PURE__ */ v("span", {
147
- className: "text-xs text-text-secondary",
148
- children: "—"
149
- }) : e.tags.slice(0, 3).map((e) => /* @__PURE__ */ v("span", {
150
- className: "rounded-full bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary",
151
- children: e
152
- }, e)), e.tags.length > 3 ? /* @__PURE__ */ y("span", {
153
- className: "text-xs text-text-secondary",
154
- children: ["+", e.tags.length - 3]
155
- }) : null]
156
- }) }),
157
- /* @__PURE__ */ v(j, {
158
- className: "text-right",
176
+ ]
177
+ }, e.id)) })] })
178
+ }),
179
+ /* @__PURE__ */ v("ul", {
180
+ className: "space-y-3 md:hidden",
181
+ children: J.map((e) => /* @__PURE__ */ y("li", {
182
+ className: "relative",
183
+ children: [/* @__PURE__ */ y("button", {
184
+ type: "button",
185
+ onClick: () => R(`pipelines/${e.id}`),
186
+ className: "flex w-full flex-col gap-2 rounded-card border border-border-default bg-bg-elevated p-4 pr-12 text-left transition-colors hover:border-border-strong",
187
+ children: [
188
+ /* @__PURE__ */ y("div", {
189
+ className: "flex items-start justify-between gap-2",
190
+ children: [/* @__PURE__ */ y("span", {
191
+ className: "min-w-0 font-medium text-text-primary",
192
+ children: [/* @__PURE__ */ v("span", {
193
+ className: "block truncate",
194
+ children: e.name
195
+ }), e.description ? /* @__PURE__ */ v("span", {
196
+ className: "mt-0.5 line-clamp-1 text-xs font-normal text-text-secondary",
197
+ children: e.description
198
+ }) : null]
199
+ }), /* @__PURE__ */ v(f, {
200
+ status: e.status,
201
+ className: "shrink-0"
202
+ })]
203
+ }),
204
+ /* @__PURE__ */ y("dl", {
205
+ className: "grid grid-cols-2 gap-x-3 gap-y-1 text-xs",
206
+ children: [
207
+ /* @__PURE__ */ y("div", {
208
+ className: "flex flex-col",
209
+ children: [/* @__PURE__ */ v("dt", {
210
+ className: "text-text-secondary",
211
+ children: "Trigger"
212
+ }), /* @__PURE__ */ v("dd", {
213
+ className: "text-text-primary",
214
+ children: p(e.trigger)
215
+ })]
216
+ }),
217
+ /* @__PURE__ */ y("div", {
218
+ className: "flex flex-col",
219
+ children: [/* @__PURE__ */ v("dt", {
220
+ className: "text-text-secondary",
221
+ children: "Version"
222
+ }), /* @__PURE__ */ y("dd", {
223
+ className: "tabular-nums text-text-primary",
224
+ children: ["v", e.version]
225
+ })]
226
+ }),
227
+ /* @__PURE__ */ y("div", {
228
+ className: "flex flex-col",
229
+ children: [/* @__PURE__ */ v("dt", {
230
+ className: "text-text-secondary",
231
+ children: "Schedule"
232
+ }), /* @__PURE__ */ v("dd", {
233
+ className: "font-mono text-text-primary",
234
+ children: e.schedule || "—"
235
+ })]
236
+ }),
237
+ /* @__PURE__ */ y("div", {
238
+ className: "flex flex-col",
239
+ children: [/* @__PURE__ */ v("dt", {
240
+ className: "text-text-secondary",
241
+ children: "Last run"
242
+ }), /* @__PURE__ */ v("dd", {
243
+ className: "text-text-primary",
244
+ children: L(e.lastRunAt)
245
+ })]
246
+ })
247
+ ]
248
+ }),
249
+ e.tags.length > 0 ? /* @__PURE__ */ y("div", {
250
+ className: "flex flex-wrap gap-1",
251
+ children: [e.tags.slice(0, 4).map((e) => /* @__PURE__ */ v("span", {
252
+ className: "rounded-full bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary",
253
+ children: e
254
+ }, e)), e.tags.length > 4 ? /* @__PURE__ */ y("span", {
255
+ className: "text-xs text-text-secondary",
256
+ children: ["+", e.tags.length - 4]
257
+ }) : null]
258
+ }) : null
259
+ ]
260
+ }), /* @__PURE__ */ v("div", {
261
+ className: "absolute right-2 top-2",
159
262
  children: /* @__PURE__ */ v(a, {
160
263
  ariaLabel: `Actions for ${e.name}`,
161
264
  entityName: e.name,
@@ -171,19 +274,20 @@ function R() {
171
274
  disabled: e.status === "ARCHIVED"
172
275
  }]
173
276
  })
174
- })
175
- ]
176
- }, e.id)) })] })
177
- }), /* @__PURE__ */ v(u, {
178
- offset: V.offset,
179
- limit: V.limit,
180
- loadedCount: J.length,
181
- hasMore: Y?.hasMore ?? !1,
182
- onPrev: V.prevPage,
183
- onNext: V.nextPage,
184
- itemLabel: "pipelines",
185
- loading: U
186
- })] })]
277
+ })]
278
+ }, e.id))
279
+ }),
280
+ /* @__PURE__ */ v(u, {
281
+ offset: V.offset,
282
+ limit: V.limit,
283
+ loadedCount: J.length,
284
+ hasMore: Y?.hasMore ?? !1,
285
+ onPrev: V.prevPage,
286
+ onNext: V.nextPage,
287
+ itemLabel: "pipelines",
288
+ loading: U
289
+ })
290
+ ] })]
187
291
  })
188
292
  });
189
293
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PipelinesPage.js","names":[],"sources":["../../../../src/cosmicintersection/pages/pipelines/PipelinesPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { GitBranch, Play, Plus } from 'lucide-react';\nimport {\n Button,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@burdenoff/fe-libs/ui';\n\nimport {\n useCosArchivePipelineMutation,\n useCosPipelinesQuery,\n useCosStartRunMutation,\n type CosPipeline,\n type CosPipelineStatus,\n} from '../../api/cosmicApi';\nimport {\n ActionMenu,\n EmptyState,\n ErrorState,\n LoadingState,\n PageLayout,\n Pagination,\n StatusBadge,\n formatEnumLabel,\n usePagination,\n} from '../../components';\nimport { useCosmicIntersection } from '../../context/CosmicIntersectionContext';\nimport { mutationSucceeded } from '../../lib/mutationResult';\nimport { notify } from '../../lib/toast';\n\nconst STATUS_OPTIONS: CosPipelineStatus[] = ['DRAFT', 'ACTIVE', 'PAUSED', 'ARCHIVED'];\nconst ALL = 'ALL';\n\nfunction formatDate(value?: string | null): string {\n if (!value) {\n return '—';\n }\n const date = new Date(value);\n return Number.isNaN(date.getTime()) ? '—' : date.toLocaleString();\n}\n\nexport default function PipelinesPage() {\n const { navigate } = useCosmicIntersection();\n const [status, setStatus] = useState<CosPipelineStatus | typeof ALL>(ALL);\n const pagination = usePagination({ resetKey: status });\n\n const { data, loading, error, refetch } = useCosPipelinesQuery({\n status: status === ALL ? undefined : status,\n pagination: { limit: pagination.limit, offset: pagination.offset },\n });\n\n const [startRun] = useCosStartRunMutation();\n const [archivePipeline] = useCosArchivePipelineMutation();\n\n const pipelines = useMemo(() => data?.cosListPipelines.items ?? [], [data]);\n const pageInfo = data?.cosListPipelines.pageInfo;\n\n const handleStartRun = async (pipeline: CosPipeline) => {\n const response = await startRun({ variables: { input: { pipelineId: pipeline.id } } });\n const runId = response.data?.cosStartRun?.id;\n if (!mutationSucceeded(response, runId, 'Could not start a run')) {\n return;\n }\n notify.success('Run started', `A new run for “${pipeline.name}” is queued.`);\n await refetch();\n if (runId) {\n navigate(`runs/${runId}`);\n }\n };\n\n const handleArchive = async (pipeline: CosPipeline) => {\n const response = await archivePipeline({ variables: { id: pipeline.id } });\n if (\n !mutationSucceeded(response, response.data?.cosArchivePipeline, 'Could not archive pipeline')\n ) {\n throw new Error('Archive not confirmed');\n }\n await refetch();\n notify.success('Pipeline archived', `“${pipeline.name}” was archived.`);\n };\n\n const renderBody = () => {\n if (loading) {\n return <LoadingState variant=\"rows\" rows={6} label=\"Loading pipelines…\" />;\n }\n if (error) {\n return (\n <ErrorState\n message=\"We could not load your pipelines. Please try again.\"\n onRetry={() => void refetch()}\n />\n );\n }\n if (pipelines.length === 0) {\n return (\n <EmptyState\n icon={GitBranch}\n title={status === ALL ? 'No pipelines yet' : 'No pipelines match this filter'}\n description={\n status === ALL\n ? 'Pipelines orchestrate ingest, calibration, transform and export steps over your datasets.'\n : 'Try a different status filter to see more pipelines.'\n }\n action={\n status === ALL ? (\n <Button type=\"button\" onClick={() => navigate('pipelines/create')}>\n <Plus className=\"size-4\" />\n New pipeline\n </Button>\n ) : undefined\n }\n />\n );\n }\n\n return (\n <>\n <div className=\"overflow-x-auto 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>Trigger</TableHead>\n <TableHead>Schedule</TableHead>\n <TableHead>Last run</TableHead>\n <TableHead className=\"text-right\">Version</TableHead>\n <TableHead>Tags</TableHead>\n <TableHead className=\"w-12 text-right\">\n <span className=\"sr-only\">Actions</span>\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {pipelines.map((pipeline) => (\n <TableRow\n key={pipeline.id}\n className=\"cursor-pointer\"\n onClick={() => navigate(`pipelines/${pipeline.id}`)}\n >\n <TableCell className=\"font-medium text-text-primary\">\n <div className=\"flex flex-col\">\n <span className=\"truncate\">{pipeline.name}</span>\n {pipeline.description ? (\n <span className=\"mt-0.5 line-clamp-1 text-xs text-text-secondary\">\n {pipeline.description}\n </span>\n ) : null}\n </div>\n </TableCell>\n <TableCell>\n <StatusBadge status={pipeline.status} />\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {formatEnumLabel(pipeline.trigger)}\n </TableCell>\n <TableCell className=\"font-mono text-xs text-text-secondary\">\n {pipeline.schedule || '—'}\n </TableCell>\n <TableCell className=\"whitespace-nowrap text-text-secondary\">\n {formatDate(pipeline.lastRunAt)}\n </TableCell>\n <TableCell className=\"text-right tabular-nums text-text-secondary\">\n v{pipeline.version}\n </TableCell>\n <TableCell>\n <div className=\"flex max-w-[12rem] flex-wrap gap-1\">\n {pipeline.tags.length === 0 ? (\n <span className=\"text-xs text-text-secondary\">—</span>\n ) : (\n pipeline.tags.slice(0, 3).map((tag) => (\n <span\n key={tag}\n className=\"rounded-full bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary\"\n >\n {tag}\n </span>\n ))\n )}\n {pipeline.tags.length > 3 ? (\n <span className=\"text-xs text-text-secondary\">\n +{pipeline.tags.length - 3}\n </span>\n ) : null}\n </div>\n </TableCell>\n <TableCell className=\"text-right\">\n <ActionMenu\n ariaLabel={`Actions for ${pipeline.name}`}\n entityName={pipeline.name}\n onView={() => navigate(`pipelines/${pipeline.id}`)}\n onEdit={() => navigate(`pipelines/${pipeline.id}/edit`)}\n onDelete={() => handleArchive(pipeline)}\n deleteLabel=\"Archive pipeline\"\n extraItems={[\n {\n key: 'start',\n label: 'Start run',\n icon: Play,\n onSelect: () => void handleStartRun(pipeline),\n disabled: pipeline.status === 'ARCHIVED',\n },\n ]}\n />\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n\n <Pagination\n offset={pagination.offset}\n limit={pagination.limit}\n loadedCount={pipelines.length}\n hasMore={pageInfo?.hasMore ?? false}\n onPrev={pagination.prevPage}\n onNext={pagination.nextPage}\n itemLabel=\"pipelines\"\n loading={loading}\n />\n </>\n );\n };\n\n return (\n <PageLayout\n title=\"Pipelines\"\n description=\"Orchestrate ingest, calibration, transform and export steps across your data.\"\n actions={\n <Button type=\"button\" onClick={() => navigate('pipelines/create')}>\n <Plus className=\"size-4\" />\n New pipeline\n </Button>\n }\n >\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <label className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <span>Status</span>\n <Select\n value={status}\n onValueChange={(value) => setStatus(value as CosPipelineStatus | typeof ALL)}\n >\n <SelectTrigger aria-label=\"Filter by status\" className=\"w-44\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All statuses</SelectItem>\n {STATUS_OPTIONS.map((option) => (\n <SelectItem key={option} value={option}>\n {formatEnumLabel(option)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </label>\n </div>\n\n {renderBody()}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"PipelinesPage.js","names":[],"sources":["../../../../src/cosmicintersection/pages/pipelines/PipelinesPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { GitBranch, Play, Plus } from 'lucide-react';\nimport {\n Button,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@burdenoff/fe-libs/ui';\n\nimport {\n useCosArchivePipelineMutation,\n useCosPipelinesQuery,\n useCosStartRunMutation,\n type CosPipeline,\n type CosPipelineStatus,\n} from '../../api/cosmicApi';\nimport {\n ActionMenu,\n EmptyState,\n ErrorState,\n LoadingState,\n PageLayout,\n Pagination,\n StatusBadge,\n formatEnumLabel,\n usePagination,\n} from '../../components';\nimport { useCosmicIntersection } from '../../context/CosmicIntersectionContext';\nimport { mutationSucceeded } from '../../lib/mutationResult';\nimport { notify } from '../../lib/toast';\n\nconst STATUS_OPTIONS: CosPipelineStatus[] = ['DRAFT', 'ACTIVE', 'PAUSED', 'ARCHIVED'];\nconst ALL = 'ALL';\n\nfunction formatDate(value?: string | null): string {\n if (!value) {\n return '—';\n }\n const date = new Date(value);\n return Number.isNaN(date.getTime()) ? '—' : date.toLocaleString();\n}\n\nexport default function PipelinesPage() {\n const { navigate } = useCosmicIntersection();\n const [status, setStatus] = useState<CosPipelineStatus | typeof ALL>(ALL);\n const pagination = usePagination({ resetKey: status });\n\n const { data, loading, error, refetch } = useCosPipelinesQuery({\n status: status === ALL ? undefined : status,\n pagination: { limit: pagination.limit, offset: pagination.offset },\n });\n\n const [startRun] = useCosStartRunMutation();\n const [archivePipeline] = useCosArchivePipelineMutation();\n\n const pipelines = useMemo(() => data?.cosListPipelines.items ?? [], [data]);\n const pageInfo = data?.cosListPipelines.pageInfo;\n\n const handleStartRun = async (pipeline: CosPipeline) => {\n const response = await startRun({ variables: { input: { pipelineId: pipeline.id } } });\n const runId = response.data?.cosStartRun?.id;\n if (!mutationSucceeded(response, runId, 'Could not start a run')) {\n return;\n }\n notify.success('Run started', `A new run for “${pipeline.name}” is queued.`);\n await refetch();\n if (runId) {\n navigate(`runs/${runId}`);\n }\n };\n\n const handleArchive = async (pipeline: CosPipeline) => {\n const response = await archivePipeline({ variables: { id: pipeline.id } });\n if (\n !mutationSucceeded(response, response.data?.cosArchivePipeline, 'Could not archive pipeline')\n ) {\n throw new Error('Archive not confirmed');\n }\n await refetch();\n notify.success('Pipeline archived', `“${pipeline.name}” was archived.`);\n };\n\n const renderBody = () => {\n if (loading) {\n return <LoadingState variant=\"rows\" rows={6} label=\"Loading pipelines…\" />;\n }\n if (error) {\n return (\n <ErrorState\n message=\"We could not load your pipelines. Please try again.\"\n onRetry={() => void refetch()}\n />\n );\n }\n if (pipelines.length === 0) {\n return (\n <EmptyState\n icon={GitBranch}\n title={status === ALL ? 'No pipelines yet' : 'No pipelines match this filter'}\n description={\n status === ALL\n ? 'Pipelines orchestrate ingest, calibration, transform and export steps over your datasets.'\n : 'Try a different status filter to see more pipelines.'\n }\n action={\n status === ALL ? (\n <Button type=\"button\" onClick={() => navigate('pipelines/create')}>\n <Plus className=\"size-4\" />\n New pipeline\n </Button>\n ) : undefined\n }\n />\n );\n }\n\n return (\n <>\n {/* Desktop: table. */}\n <div className=\"hidden rounded-card border border-border-default bg-bg-elevated md:block\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Name</TableHead>\n <TableHead>Status</TableHead>\n <TableHead>Trigger</TableHead>\n <TableHead>Schedule</TableHead>\n <TableHead>Last run</TableHead>\n <TableHead className=\"text-right\">Version</TableHead>\n <TableHead>Tags</TableHead>\n <TableHead className=\"w-12 text-right\">\n <span className=\"sr-only\">Actions</span>\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {pipelines.map((pipeline) => (\n <TableRow\n key={pipeline.id}\n className=\"cursor-pointer\"\n onClick={() => navigate(`pipelines/${pipeline.id}`)}\n >\n <TableCell className=\"font-medium text-text-primary\">\n <div className=\"flex flex-col\">\n <span className=\"truncate\">{pipeline.name}</span>\n {pipeline.description ? (\n <span className=\"mt-0.5 line-clamp-1 text-xs text-text-secondary\">\n {pipeline.description}\n </span>\n ) : null}\n </div>\n </TableCell>\n <TableCell>\n <StatusBadge status={pipeline.status} />\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {formatEnumLabel(pipeline.trigger)}\n </TableCell>\n <TableCell className=\"font-mono text-xs text-text-secondary\">\n {pipeline.schedule || '—'}\n </TableCell>\n <TableCell className=\"whitespace-nowrap text-text-secondary\">\n {formatDate(pipeline.lastRunAt)}\n </TableCell>\n <TableCell className=\"text-right tabular-nums text-text-secondary\">\n v{pipeline.version}\n </TableCell>\n <TableCell>\n <div className=\"flex max-w-[12rem] flex-wrap gap-1\">\n {pipeline.tags.length === 0 ? (\n <span className=\"text-xs text-text-secondary\">—</span>\n ) : (\n pipeline.tags.slice(0, 3).map((tag) => (\n <span\n key={tag}\n className=\"rounded-full bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary\"\n >\n {tag}\n </span>\n ))\n )}\n {pipeline.tags.length > 3 ? (\n <span className=\"text-xs text-text-secondary\">\n +{pipeline.tags.length - 3}\n </span>\n ) : null}\n </div>\n </TableCell>\n <TableCell className=\"text-right\">\n <ActionMenu\n ariaLabel={`Actions for ${pipeline.name}`}\n entityName={pipeline.name}\n onView={() => navigate(`pipelines/${pipeline.id}`)}\n onEdit={() => navigate(`pipelines/${pipeline.id}/edit`)}\n onDelete={() => handleArchive(pipeline)}\n deleteLabel=\"Archive pipeline\"\n extraItems={[\n {\n key: 'start',\n label: 'Start run',\n icon: Play,\n onSelect: () => void handleStartRun(pipeline),\n disabled: pipeline.status === 'ARCHIVED',\n },\n ]}\n />\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n\n {/* Mobile: stacked cards. */}\n <ul className=\"space-y-3 md:hidden\">\n {pipelines.map((pipeline) => (\n <li key={pipeline.id} className=\"relative\">\n <button\n type=\"button\"\n onClick={() => navigate(`pipelines/${pipeline.id}`)}\n className=\"flex w-full flex-col gap-2 rounded-card border border-border-default bg-bg-elevated p-4 pr-12 text-left transition-colors hover:border-border-strong\"\n >\n <div className=\"flex items-start justify-between gap-2\">\n <span className=\"min-w-0 font-medium text-text-primary\">\n <span className=\"block truncate\">{pipeline.name}</span>\n {pipeline.description ? (\n <span className=\"mt-0.5 line-clamp-1 text-xs font-normal text-text-secondary\">\n {pipeline.description}\n </span>\n ) : null}\n </span>\n <StatusBadge status={pipeline.status} className=\"shrink-0\" />\n </div>\n <dl className=\"grid grid-cols-2 gap-x-3 gap-y-1 text-xs\">\n <div className=\"flex flex-col\">\n <dt className=\"text-text-secondary\">Trigger</dt>\n <dd className=\"text-text-primary\">{formatEnumLabel(pipeline.trigger)}</dd>\n </div>\n <div className=\"flex flex-col\">\n <dt className=\"text-text-secondary\">Version</dt>\n <dd className=\"tabular-nums text-text-primary\">v{pipeline.version}</dd>\n </div>\n <div className=\"flex flex-col\">\n <dt className=\"text-text-secondary\">Schedule</dt>\n <dd className=\"font-mono text-text-primary\">{pipeline.schedule || '—'}</dd>\n </div>\n <div className=\"flex flex-col\">\n <dt className=\"text-text-secondary\">Last run</dt>\n <dd className=\"text-text-primary\">{formatDate(pipeline.lastRunAt)}</dd>\n </div>\n </dl>\n {pipeline.tags.length > 0 ? (\n <div className=\"flex flex-wrap gap-1\">\n {pipeline.tags.slice(0, 4).map((tag) => (\n <span\n key={tag}\n className=\"rounded-full bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary\"\n >\n {tag}\n </span>\n ))}\n {pipeline.tags.length > 4 ? (\n <span className=\"text-xs text-text-secondary\">\n +{pipeline.tags.length - 4}\n </span>\n ) : null}\n </div>\n ) : null}\n </button>\n <div className=\"absolute right-2 top-2\">\n <ActionMenu\n ariaLabel={`Actions for ${pipeline.name}`}\n entityName={pipeline.name}\n onView={() => navigate(`pipelines/${pipeline.id}`)}\n onEdit={() => navigate(`pipelines/${pipeline.id}/edit`)}\n onDelete={() => handleArchive(pipeline)}\n deleteLabel=\"Archive pipeline\"\n extraItems={[\n {\n key: 'start',\n label: 'Start run',\n icon: Play,\n onSelect: () => void handleStartRun(pipeline),\n disabled: pipeline.status === 'ARCHIVED',\n },\n ]}\n />\n </div>\n </li>\n ))}\n </ul>\n\n <Pagination\n offset={pagination.offset}\n limit={pagination.limit}\n loadedCount={pipelines.length}\n hasMore={pageInfo?.hasMore ?? false}\n onPrev={pagination.prevPage}\n onNext={pagination.nextPage}\n itemLabel=\"pipelines\"\n loading={loading}\n />\n </>\n );\n };\n\n return (\n <PageLayout\n title=\"Pipelines\"\n description=\"Orchestrate ingest, calibration, transform and export steps across your data.\"\n actions={\n <Button type=\"button\" onClick={() => navigate('pipelines/create')}>\n <Plus className=\"size-4\" />\n New pipeline\n </Button>\n }\n >\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <label className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <span>Status</span>\n <Select\n value={status}\n onValueChange={(value) => setStatus(value as CosPipelineStatus | typeof ALL)}\n >\n <SelectTrigger aria-label=\"Filter by status\" className=\"w-44\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All statuses</SelectItem>\n {STATUS_OPTIONS.map((option) => (\n <SelectItem key={option} value={option}>\n {formatEnumLabel(option)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </label>\n </div>\n\n {renderBody()}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAuCA,IAAM,IAAsC;CAAC;CAAS;CAAU;CAAU;CAAW,EAC/E,IAAM;AAEZ,SAAS,EAAW,GAA+B;AACjD,KAAI,CAAC,EACH,QAAO;CAET,IAAM,IAAO,IAAI,KAAK,EAAM;AAC5B,QAAO,OAAO,MAAM,EAAK,SAAS,CAAC,GAAG,MAAM,EAAK,gBAAgB;;AAGnE,SAAwB,IAAgB;CACtC,IAAM,EAAE,gBAAa,GAAuB,EACtC,CAAC,GAAQ,KAAa,EAAyC,EAAI,EACnE,IAAa,EAAc,EAAE,UAAU,GAAQ,CAAC,EAEhD,EAAE,SAAM,YAAS,UAAO,eAAY,EAAqB;EAC7D,QAAQ,MAAW,IAAM,KAAA,IAAY;EACrC,YAAY;GAAE,OAAO,EAAW;GAAO,QAAQ,EAAW;GAAQ;EACnE,CAAC,EAEI,CAAC,KAAY,GAAwB,EACrC,CAAC,KAAmB,GAA+B,EAEnD,IAAY,QAAc,GAAM,iBAAiB,SAAS,EAAE,EAAE,CAAC,EAAK,CAAC,EACrE,IAAW,GAAM,iBAAiB,UAElC,IAAiB,OAAO,MAA0B;EACtD,IAAM,IAAW,MAAM,EAAS,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,EAAS,IAAI,EAAE,EAAE,CAAC,EAChF,IAAQ,EAAS,MAAM,aAAa;AACrC,IAAkB,GAAU,GAAO,wBAAwB,KAGhE,EAAO,QAAQ,eAAe,kBAAkB,EAAS,KAAK,cAAc,EAC5E,MAAM,GAAS,EACX,KACF,EAAS,QAAQ,IAAQ;IAIvB,IAAgB,OAAO,MAA0B;EACrD,IAAM,IAAW,MAAM,EAAgB,EAAE,WAAW,EAAE,IAAI,EAAS,IAAI,EAAE,CAAC;AAC1E,MACE,CAAC,EAAkB,GAAU,EAAS,MAAM,oBAAoB,6BAA6B,CAE7F,OAAU,MAAM,wBAAwB;AAG1C,EADA,MAAM,GAAS,EACf,EAAO,QAAQ,qBAAqB,IAAI,EAAS,KAAK,iBAAiB;;AAmOzE,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,GAAD;GAAQ,MAAK;GAAS,eAAe,EAAS,mBAAmB;aAAjE,CACE,kBAAC,GAAD,EAAM,WAAU,UAAW,CAAA,EAAA,eAEpB;;YAGX,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,SAAD;KAAO,WAAU;eAAjB,CACE,kBAAC,QAAD,EAAA,UAAM,UAAa,CAAA,EACnB,kBAAC,GAAD;MACE,OAAO;MACP,gBAAgB,MAAU,EAAU,EAAwC;gBAF9E,CAIE,kBAAC,GAAD;OAAe,cAAW;OAAmB,WAAU;iBACrD,kBAAC,GAAD,EAAe,CAAA;OACD,CAAA,EAChB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;OAAY,OAAO;iBAAK;OAAyB,CAAA,EAChD,EAAe,KAAK,MACnB,kBAAC,GAAD;OAAyB,OAAO;iBAC7B,EAAgB,EAAO;OACb,EAFI,EAEJ,CACb,CACY,EAAA,CAAA,CACT;QACH;;IACJ,CAAA,EA/PN,IACK,kBAAC,GAAD;IAAc,SAAQ;IAAO,MAAM;IAAG,OAAM;IAAuB,CAAA,GAExE,IAEA,kBAAC,GAAD;IACE,SAAQ;IACR,eAAe,KAAK,GAAS;IAC7B,CAAA,GAGF,EAAU,WAAW,IAErB,kBAAC,GAAD;IACE,MAAM;IACN,OAAO,MAAW,IAAM,qBAAqB;IAC7C,aACE,MAAW,IACP,8FACA;IAEN,QACE,MAAW,IACT,kBAAC,GAAD;KAAQ,MAAK;KAAS,eAAe,EAAS,mBAAmB;eAAjE,CACE,kBAAC,GAAD,EAAM,WAAU,UAAW,CAAA,EAAA,eAEpB;SACP,KAAA;IAEN,CAAA,GAKJ,kBAAA,GAAA,EAAA,UAAA;IAEE,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,WAAmB,CAAA;MAC9B,kBAAC,GAAD,EAAA,UAAW,YAAoB,CAAA;MAC/B,kBAAC,GAAD,EAAA,UAAW,YAAoB,CAAA;MAC/B,kBAAC,GAAD;OAAW,WAAU;iBAAa;OAAmB,CAAA;MACrD,kBAAC,GAAD,EAAA,UAAW,QAAgB,CAAA;MAC3B,kBAAC,GAAD;OAAW,WAAU;iBACnB,kBAAC,QAAD;QAAM,WAAU;kBAAU;QAAc,CAAA;OAC9B,CAAA;MACH,EAAA,CAAA,EACC,CAAA,EACd,kBAAC,GAAD,EAAA,UACG,EAAU,KAAK,MACd,kBAAC,GAAD;MAEE,WAAU;MACV,eAAe,EAAS,aAAa,EAAS,KAAK;gBAHrD;OAKE,kBAAC,GAAD;QAAW,WAAU;kBACnB,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,QAAD;UAAM,WAAU;oBAAY,EAAS;UAAY,CAAA,EAChD,EAAS,cACR,kBAAC,QAAD;UAAM,WAAU;oBACb,EAAS;UACL,CAAA,GACL,KACA;;QACI,CAAA;OACZ,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAa,QAAQ,EAAS,QAAU,CAAA,EAC9B,CAAA;OACZ,kBAAC,GAAD;QAAW,WAAU;kBAClB,EAAgB,EAAS,QAAQ;QACxB,CAAA;OACZ,kBAAC,GAAD;QAAW,WAAU;kBAClB,EAAS,YAAY;QACZ,CAAA;OACZ,kBAAC,GAAD;QAAW,WAAU;kBAClB,EAAW,EAAS,UAAU;QACrB,CAAA;OACZ,kBAAC,GAAD;QAAW,WAAU;kBAArB,CAAmE,KAC/D,EAAS,QACD;;OACZ,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACG,EAAS,KAAK,WAAW,IACxB,kBAAC,QAAD;SAAM,WAAU;mBAA8B;SAAQ,CAAA,GAEtD,EAAS,KAAK,MAAM,GAAG,EAAE,CAAC,KAAK,MAC7B,kBAAC,QAAD;SAEE,WAAU;mBAET;SACI,EAJA,EAIA,CACP,EAEH,EAAS,KAAK,SAAS,IACtB,kBAAC,QAAD;SAAM,WAAU;mBAAhB,CAA8C,KAC1C,EAAS,KAAK,SAAS,EACpB;aACL,KACA;WACI,CAAA;OACZ,kBAAC,GAAD;QAAW,WAAU;kBACnB,kBAAC,GAAD;SACE,WAAW,eAAe,EAAS;SACnC,YAAY,EAAS;SACrB,cAAc,EAAS,aAAa,EAAS,KAAK;SAClD,cAAc,EAAS,aAAa,EAAS,GAAG,OAAO;SACvD,gBAAgB,EAAc,EAAS;SACvC,aAAY;SACZ,YAAY,CACV;UACE,KAAK;UACL,OAAO;UACP,MAAM;UACN,gBAAgB,KAAK,EAAe,EAAS;UAC7C,UAAU,EAAS,WAAW;UAC/B,CACF;SACD,CAAA;QACQ,CAAA;OACH;QArEJ,EAAS,GAqEL,CACX,EACQ,CAAA,CACN,EAAA,CAAA;KACJ,CAAA;IAGN,kBAAC,MAAD;KAAI,WAAU;eACX,EAAU,KAAK,MACd,kBAAC,MAAD;MAAsB,WAAU;gBAAhC,CACE,kBAAC,UAAD;OACE,MAAK;OACL,eAAe,EAAS,aAAa,EAAS,KAAK;OACnD,WAAU;iBAHZ;QAKE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,QAAD;UAAM,WAAU;oBAAhB,CACE,kBAAC,QAAD;WAAM,WAAU;qBAAkB,EAAS;WAAY,CAAA,EACtD,EAAS,cACR,kBAAC,QAAD;WAAM,WAAU;qBACb,EAAS;WACL,CAAA,GACL,KACC;aACP,kBAAC,GAAD;UAAa,QAAQ,EAAS;UAAQ,WAAU;UAAa,CAAA,CACzD;;QACN,kBAAC,MAAD;SAAI,WAAU;mBAAd;UACE,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,MAAD;YAAI,WAAU;sBAAsB;YAAY,CAAA,EAChD,kBAAC,MAAD;YAAI,WAAU;sBAAqB,EAAgB,EAAS,QAAQ;YAAM,CAAA,CACtE;;UACN,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,MAAD;YAAI,WAAU;sBAAsB;YAAY,CAAA,EAChD,kBAAC,MAAD;YAAI,WAAU;sBAAd,CAA+C,KAAE,EAAS,QAAa;cACnE;;UACN,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,MAAD;YAAI,WAAU;sBAAsB;YAAa,CAAA,EACjD,kBAAC,MAAD;YAAI,WAAU;sBAA+B,EAAS,YAAY;YAAS,CAAA,CACvE;;UACN,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,MAAD;YAAI,WAAU;sBAAsB;YAAa,CAAA,EACjD,kBAAC,MAAD;YAAI,WAAU;sBAAqB,EAAW,EAAS,UAAU;YAAM,CAAA,CACnE;;UACH;;QACJ,EAAS,KAAK,SAAS,IACtB,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACG,EAAS,KAAK,MAAM,GAAG,EAAE,CAAC,KAAK,MAC9B,kBAAC,QAAD;UAEE,WAAU;oBAET;UACI,EAJA,EAIA,CACP,EACD,EAAS,KAAK,SAAS,IACtB,kBAAC,QAAD;UAAM,WAAU;oBAAhB,CAA8C,KAC1C,EAAS,KAAK,SAAS,EACpB;cACL,KACA;aACJ;QACG;UACT,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD;QACE,WAAW,eAAe,EAAS;QACnC,YAAY,EAAS;QACrB,cAAc,EAAS,aAAa,EAAS,KAAK;QAClD,cAAc,EAAS,aAAa,EAAS,GAAG,OAAO;QACvD,gBAAgB,EAAc,EAAS;QACvC,aAAY;QACZ,YAAY,CACV;SACE,KAAK;SACL,OAAO;SACP,MAAM;SACN,gBAAgB,KAAK,EAAe,EAAS;SAC7C,UAAU,EAAS,WAAW;SAC/B,CACF;QACD,CAAA;OACE,CAAA,CACH;QAxEI,EAAS,GAwEb,CACL;KACC,CAAA;IAEL,kBAAC,GAAD;KACE,QAAQ,EAAW;KACnB,OAAO,EAAW;KAClB,aAAa,EAAU;KACvB,SAAS,GAAU,WAAW;KAC9B,QAAQ,EAAW;KACnB,QAAQ,EAAW;KACnB,WAAU;KACD;KACT,CAAA;IACD,EAAA,CAAA,CAuCG;;EACK,CAAA"}
@@ -0,0 +1,2 @@
1
+ export default function ReleaseFormPage(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=ReleaseFormPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReleaseFormPage.d.ts","sourceRoot":"","sources":["../../../../src/cosmicintersection/pages/releases/ReleaseFormPage.tsx"],"names":[],"mappings":"AAyBA,MAAM,CAAC,OAAO,UAAU,eAAe,4CA2KtC"}
@@ -0,0 +1,2 @@
1
+ export default function ReleasesPage(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=ReleasesPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReleasesPage.d.ts","sourceRoot":"","sources":["../../../../src/cosmicintersection/pages/releases/ReleasesPage.tsx"],"names":[],"mappings":"AA6EA,MAAM,CAAC,OAAO,UAAU,YAAY,4CAohBnC"}