@burdenoff/microfe-cosmicintersection 2026.704.1 → 2026.704.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cosmicintersection/CosmicIntersectionRoutes.js +31 -23
- package/dist/cosmicintersection/CosmicIntersectionRoutes.js.map +1 -1
- package/dist/cosmicintersection/api/cosmicApi.js +131 -66
- package/dist/cosmicintersection/api/cosmicApi.js.map +1 -1
- package/dist/cosmicintersection/components/ActivityFeedPanel.js +68 -0
- package/dist/cosmicintersection/components/ActivityFeedPanel.js.map +1 -0
- package/dist/cosmicintersection/components/DiscussionPanel.js +57 -0
- package/dist/cosmicintersection/components/DiscussionPanel.js.map +1 -0
- package/dist/cosmicintersection/components/index.js +5 -3
- package/dist/cosmicintersection/pages/access/AccessPage.js +24 -17
- package/dist/cosmicintersection/pages/access/AccessPage.js.map +1 -1
- package/dist/cosmicintersection/pages/analyses/AnalysesPage.js +12 -12
- package/dist/cosmicintersection/pages/collections/CollectionDetailPage.js +109 -96
- package/dist/cosmicintersection/pages/collections/CollectionDetailPage.js.map +1 -1
- package/dist/cosmicintersection/pages/collections/CollectionFormPage.js +87 -61
- package/dist/cosmicintersection/pages/collections/CollectionFormPage.js.map +1 -1
- package/dist/cosmicintersection/pages/collections/CollectionsPage.js +51 -42
- package/dist/cosmicintersection/pages/collections/CollectionsPage.js.map +1 -1
- package/dist/cosmicintersection/pages/dashboard/DashboardPage.js +5 -3
- package/dist/cosmicintersection/pages/dashboard/DashboardPage.js.map +1 -1
- package/dist/cosmicintersection/pages/datasets/DatasetDetailPage.js +172 -152
- package/dist/cosmicintersection/pages/datasets/DatasetDetailPage.js.map +1 -1
- package/dist/cosmicintersection/pages/datasets/DatasetFormPage.js +7 -7
- package/dist/cosmicintersection/pages/notebooks/NotebookDetailPage.js +205 -196
- package/dist/cosmicintersection/pages/notebooks/NotebookDetailPage.js.map +1 -1
- package/dist/cosmicintersection/pages/releases/ReleasesPage.js +211 -161
- package/dist/cosmicintersection/pages/releases/ReleasesPage.js.map +1 -1
- package/dist/cosmicintersection/pages/runs/RunDetailPage.js +113 -108
- package/dist/cosmicintersection/pages/runs/RunDetailPage.js.map +1 -1
- package/dist/cosmicintersection/pages/runs/RunsPage.js +86 -101
- package/dist/cosmicintersection/pages/runs/RunsPage.js.map +1 -1
- package/dist/cosmicintersection/pages/sources/SourceDetailPage.js +205 -0
- package/dist/cosmicintersection/pages/sources/SourceDetailPage.js.map +1 -0
- package/dist/cosmicintersection/pages/sources/SourcesPage.js +110 -104
- package/dist/cosmicintersection/pages/sources/SourcesPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReleasesPage.js","names":[],"sources":["../../../../src/cosmicintersection/pages/releases/ReleasesPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { BookOpen, ExternalLink, Plus, Rocket } from 'lucide-react';\nimport {\n Badge,\n Button,\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Input,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@burdenoff/fe-libs/ui';\n\nimport {\n useCosPublishReleaseMutation,\n useCosReleasesQuery,\n type CosRelease,\n type CosReleaseStatus,\n} from '../../api/cosmicApi';\nimport {\n EmptyState,\n ErrorState,\n LoadingState,\n PageLayout,\n Pagination,\n SafeLink,\n StatusBadge,\n formatEnumLabel,\n usePagination,\n} from '../../components';\nimport { ActionMenu } from '../../components/ActionMenu';\nimport { useCosmicIntersection } from '../../context/CosmicIntersectionContext';\nimport { notify } from '../../lib/toast';\n\nconst ALL = 'ALL';\n\nconst RELEASE_STATUSES: CosReleaseStatus[] = ['DRAFT', 'UNDER_REVIEW', 'PUBLISHED', 'RETRACTED'];\n\n/** A release can be published only while it is still in a pre-publication state. */\nfunction canPublish(status: CosReleaseStatus): boolean {\n return status === 'DRAFT' || status === 'UNDER_REVIEW';\n}\n\nfunction formatDate(value?: string | null): string {\n if (!value) {\n return '—';\n }\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return '—';\n }\n return parsed.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });\n}\n\nfunction doiUrl(doi: string): string {\n const trimmed = doi.trim();\n return /^https?:\\/\\//i.test(trimmed)\n ? trimmed\n : `https://doi.org/${trimmed.replace(/^doi:/i, '')}`;\n}\n\nexport default function ReleasesPage() {\n const { navigate } = useCosmicIntersection();\n const [statusFilter, setStatusFilter] = useState<string>(ALL);\n const pagination = usePagination({ pageSize: 20, resetKey: statusFilter });\n\n const { data, loading, error, refetch } = useCosReleasesQuery({\n status: statusFilter === ALL ? undefined : (statusFilter as CosReleaseStatus),\n pagination: { limit: pagination.limit, offset: pagination.offset },\n });\n\n const [publishRelease, { loading: publishing }] = useCosPublishReleaseMutation();\n\n const releases = useMemo(() => data?.cosListReleases.items ?? [], [data]);\n const pageInfo = data?.cosListReleases.pageInfo;\n\n // Detail (View) dialog — rendered from row data, no extra fetch needed.\n const [detail, setDetail] = useState<CosRelease | null>(null);\n\n // Publish dialog — captures an optional DOI before transitioning the release.\n const [publishTarget, setPublishTarget] = useState<CosRelease | null>(null);\n const [doiDraft, setDoiDraft] = useState('');\n\n const openPublish = (release: CosRelease) => {\n setDoiDraft(release.doi ?? '');\n setPublishTarget(release);\n };\n\n const submitPublish = async () => {\n if (!publishTarget) {\n return;\n }\n const doi = doiDraft.trim();\n const response = await publishRelease({\n variables: { id: publishTarget.id, doi: doi || undefined },\n });\n if (response.data?.cosPublishRelease?.id) {\n notify.success('Release published', `“${publishTarget.title}” is now public.`);\n setPublishTarget(null);\n setDoiDraft('');\n await refetch();\n }\n };\n\n const newButton = (\n <Button type=\"button\" onClick={() => navigate('releases/create')}>\n <Plus className=\"size-4\" />\n New release\n </Button>\n );\n\n const renderBody = () => {\n if (loading) {\n return <LoadingState variant=\"rows\" rows={6} label=\"Loading releases…\" />;\n }\n if (error) {\n return <ErrorState message={error.message} onRetry={() => void refetch()} />;\n }\n if (releases.length === 0) {\n const filtered = statusFilter !== ALL;\n return (\n <EmptyState\n icon={Rocket}\n title={filtered ? 'No releases match this filter' : 'No releases yet'}\n description={\n filtered\n ? 'Try clearing the status filter to see more releases.'\n : 'Package datasets and notebooks into a citable, versioned release for publication.'\n }\n action={filtered ? undefined : newButton}\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>Title</TableHead>\n <TableHead>Version</TableHead>\n <TableHead>Status</TableHead>\n <TableHead>DOI</TableHead>\n <TableHead>Authors</TableHead>\n <TableHead>Published</TableHead>\n <TableHead>License</TableHead>\n <TableHead className=\"text-right\">Actions</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {releases.map((release) => (\n <TableRow key={release.id}>\n <TableCell>\n <button\n type=\"button\"\n onClick={() => setDetail(release)}\n className=\"text-left font-medium text-text-primary underline-offset-2 hover:underline focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border-focus\"\n >\n {release.title}\n </button>\n </TableCell>\n <TableCell className=\"whitespace-nowrap text-sm text-text-secondary\">\n {release.version || '—'}\n </TableCell>\n <TableCell>\n <StatusBadge status={release.status} />\n </TableCell>\n <TableCell className=\"max-w-[14rem]\">\n {release.doi ? (\n <SafeLink\n href={doiUrl(release.doi)}\n className=\"inline-flex items-center gap-1 truncate text-sm text-text-primary underline-offset-2 hover:underline\"\n fallbackClassName=\"block truncate text-sm text-text-secondary\"\n >\n <span className=\"truncate\">{release.doi}</span>\n <ExternalLink className=\"size-3.5 shrink-0\" aria-hidden=\"true\" />\n </SafeLink>\n ) : (\n <span className=\"text-sm text-text-secondary\">—</span>\n )}\n </TableCell>\n <TableCell className=\"max-w-[14rem]\">\n {release.authors.length === 0 ? (\n <span className=\"text-sm text-text-secondary\">—</span>\n ) : (\n <span className=\"line-clamp-1 text-sm text-text-secondary\">\n {release.authors.join(', ')}\n </span>\n )}\n </TableCell>\n <TableCell className=\"whitespace-nowrap text-sm text-text-secondary\">\n {formatDate(release.publishedAt)}\n </TableCell>\n <TableCell className=\"whitespace-nowrap text-sm text-text-secondary\">\n {release.license || '—'}\n </TableCell>\n <TableCell className=\"text-right\">\n <ActionMenu\n ariaLabel={`Actions for ${release.title}`}\n onView={() => setDetail(release)}\n extraItems={\n canPublish(release.status)\n ? [\n {\n key: 'publish',\n label: 'Publish',\n icon: Rocket,\n onSelect: () => openPublish(release),\n },\n ]\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={releases.length}\n hasMore={pageInfo?.hasMore ?? false}\n onPrev={pagination.prevPage}\n onNext={pagination.nextPage}\n itemLabel=\"releases\"\n loading={loading}\n />\n </>\n );\n };\n\n return (\n <PageLayout\n title=\"Releases\"\n description=\"Citable, versioned publications that bundle datasets and notebooks for the community.\"\n actions={newButton}\n >\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"w-full max-w-[14rem]\">\n <Select value={statusFilter} onValueChange={setStatusFilter}>\n <SelectTrigger aria-label=\"Filter by status\">\n <SelectValue placeholder=\"All statuses\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All statuses</SelectItem>\n {RELEASE_STATUSES.map((status) => (\n <SelectItem key={status} value={status}>\n {formatEnumLabel(status)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n {renderBody()}\n </div>\n\n {/* View / detail dialog */}\n <Dialog open={detail !== null} onOpenChange={(open) => (open ? undefined : setDetail(null))}>\n <DialogContent className=\"max-w-lg\">\n {detail ? (\n <>\n <DialogHeader>\n <DialogTitle className=\"flex items-center gap-2\">\n <BookOpen className=\"size-5 text-text-secondary\" aria-hidden=\"true\" />\n {detail.title}\n </DialogTitle>\n <DialogDescription>\n Version {detail.version || '—'} · <StatusBadge status={detail.status} />\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-4 text-sm\">\n <div>\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n Abstract\n </p>\n <p className=\"mt-1 whitespace-pre-wrap text-text-primary\">\n {detail.abstract?.trim() || 'No abstract provided.'}\n </p>\n </div>\n\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n Authors\n </p>\n <p className=\"mt-1 text-text-primary\">\n {detail.authors.length ? detail.authors.join(', ') : '—'}\n </p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n License\n </p>\n <p className=\"mt-1 text-text-primary\">{detail.license || '—'}</p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n Published\n </p>\n <p className=\"mt-1 text-text-primary\">{formatDate(detail.publishedAt)}</p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n DOI\n </p>\n <p className=\"mt-1\">\n {detail.doi ? (\n <SafeLink\n href={doiUrl(detail.doi)}\n className=\"inline-flex items-center gap-1 text-text-primary underline-offset-2 hover:underline\"\n fallbackClassName=\"text-text-secondary\"\n >\n {detail.doi}\n <ExternalLink className=\"size-3.5\" aria-hidden=\"true\" />\n </SafeLink>\n ) : (\n <span className=\"text-text-secondary\">Not assigned</span>\n )}\n </p>\n </div>\n </div>\n\n <div>\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n Datasets ({detail.datasetIds.length})\n </p>\n <div className=\"mt-1 flex flex-wrap gap-1\">\n {detail.datasetIds.length === 0 ? (\n <span className=\"text-text-secondary\">None linked.</span>\n ) : (\n detail.datasetIds.map((id) => (\n <Badge key={id} variant=\"outline\" className=\"font-mono text-xs\">\n {id}\n </Badge>\n ))\n )}\n </div>\n </div>\n\n <div>\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n Notebook\n </p>\n <p className=\"mt-1\">\n {detail.notebookId ? (\n <Badge variant=\"outline\" className=\"font-mono text-xs\">\n {detail.notebookId}\n </Badge>\n ) : (\n <span className=\"text-text-secondary\">None linked.</span>\n )}\n </p>\n </div>\n </div>\n\n <DialogFooter>\n {canPublish(detail.status) ? (\n <Button\n type=\"button\"\n onClick={() => {\n const target = detail;\n setDetail(null);\n openPublish(target);\n }}\n >\n <Rocket className=\"size-4\" />\n Publish\n </Button>\n ) : null}\n <DialogClose asChild>\n <Button type=\"button\" variant=\"outline\">\n Close\n </Button>\n </DialogClose>\n </DialogFooter>\n </>\n ) : null}\n </DialogContent>\n </Dialog>\n\n {/* Publish dialog */}\n <Dialog\n open={publishTarget !== null}\n onOpenChange={(open) => (open || publishing ? undefined : setPublishTarget(null))}\n >\n <DialogContent className=\"max-w-md\">\n <DialogHeader>\n <DialogTitle>Publish release</DialogTitle>\n <DialogDescription>\n {publishTarget\n ? `Publish “${publishTarget.title}” to make it publicly citable. You can attach a DOI now or later.`\n : ''}\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"release-doi\">DOI (optional)</Label>\n <Input\n id=\"release-doi\"\n value={doiDraft}\n onChange={(event) => setDoiDraft(event.target.value)}\n placeholder=\"10.1234/cosmic.2026.0001\"\n />\n <p className=\"text-xs text-text-secondary\">\n A Digital Object Identifier makes the release permanently referenceable.\n </p>\n </div>\n\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setPublishTarget(null)}\n disabled={publishing}\n >\n Cancel\n </Button>\n <Button type=\"button\" onClick={() => void submitPublish()} disabled={publishing}>\n <Rocket className=\"size-4\" />\n {publishing ? 'Publishing…' : 'Publish release'}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ReleasesPage.js","names":[],"sources":["../../../../src/cosmicintersection/pages/releases/ReleasesPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { BookOpen, Database, ExternalLink, NotebookPen, Plus, Rocket } from 'lucide-react';\nimport {\n Button,\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Input,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@burdenoff/fe-libs/ui';\n\nimport {\n useCosDatasetsQuery,\n useCosNotebooksQuery,\n useCosPublishReleaseMutation,\n useCosReleasesQuery,\n type CosRelease,\n type CosReleaseStatus,\n} from '../../api/cosmicApi';\nimport {\n DiscussionPanel,\n EmptyState,\n ErrorState,\n LoadingState,\n PageLayout,\n Pagination,\n SafeLink,\n StatusBadge,\n formatEnumLabel,\n usePagination,\n} from '../../components';\nimport { ActionMenu } from '../../components/ActionMenu';\nimport { useCosmicIntersection } from '../../context/CosmicIntersectionContext';\nimport { notify } from '../../lib/toast';\n\nconst ALL = 'ALL';\n\nconst RELEASE_STATUSES: CosReleaseStatus[] = ['DRAFT', 'UNDER_REVIEW', 'PUBLISHED', 'RETRACTED'];\n\n/** A release can be published only while it is still in a pre-publication state. */\nfunction canPublish(status: CosReleaseStatus): boolean {\n return status === 'DRAFT' || status === 'UNDER_REVIEW';\n}\n\nfunction formatDate(value?: string | null): string {\n if (!value) {\n return '—';\n }\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return '—';\n }\n return parsed.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });\n}\n\nfunction doiUrl(doi: string): string {\n const trimmed = doi.trim();\n return /^https?:\\/\\//i.test(trimmed)\n ? trimmed\n : `https://doi.org/${trimmed.replace(/^doi:/i, '')}`;\n}\n\nexport default function ReleasesPage() {\n const { navigate } = useCosmicIntersection();\n const [statusFilter, setStatusFilter] = useState<string>(ALL);\n const pagination = usePagination({ pageSize: 20, resetKey: statusFilter });\n\n const { data, loading, error, refetch } = useCosReleasesQuery({\n status: statusFilter === ALL ? undefined : (statusFilter as CosReleaseStatus),\n pagination: { limit: pagination.limit, offset: pagination.offset },\n });\n\n const [publishRelease, { loading: publishing }] = useCosPublishReleaseMutation();\n\n const releases = useMemo(() => data?.cosListReleases.items ?? [], [data]);\n const pageInfo = data?.cosListReleases.pageInfo;\n\n // Resolve the release's linked dataset/notebook UUIDs to human names so the\n // detail dialog can render navigable buttons instead of raw ids.\n const datasetsQuery = useCosDatasetsQuery({ pagination: { limit: 100, offset: 0 } });\n const notebooksQuery = useCosNotebooksQuery({ pagination: { limit: 100, offset: 0 } });\n const datasetNameById = useMemo(() => {\n const map = new Map<string, string>();\n for (const dataset of datasetsQuery.data?.cosListDatasets.items ?? []) {\n map.set(dataset.id, dataset.name);\n }\n return map;\n }, [datasetsQuery.data]);\n const notebookTitleById = useMemo(() => {\n const map = new Map<string, string>();\n for (const notebook of notebooksQuery.data?.cosListNotebooks.items ?? []) {\n map.set(notebook.id, notebook.title);\n }\n return map;\n }, [notebooksQuery.data]);\n\n // Detail (View) dialog — rendered from row data, no extra fetch needed.\n const [detail, setDetail] = useState<CosRelease | null>(null);\n\n // Close the dialog before navigating to a linked entity.\n const goToLinked = (path: string) => {\n setDetail(null);\n navigate(path);\n };\n\n // Publish dialog — captures an optional DOI before transitioning the release.\n const [publishTarget, setPublishTarget] = useState<CosRelease | null>(null);\n const [doiDraft, setDoiDraft] = useState('');\n\n const openPublish = (release: CosRelease) => {\n setDoiDraft(release.doi ?? '');\n setPublishTarget(release);\n };\n\n const submitPublish = async () => {\n if (!publishTarget) {\n return;\n }\n const doi = doiDraft.trim();\n const response = await publishRelease({\n variables: { id: publishTarget.id, doi: doi || undefined },\n });\n if (response.data?.cosPublishRelease?.id) {\n notify.success('Release published', `“${publishTarget.title}” is now public.`);\n setPublishTarget(null);\n setDoiDraft('');\n await refetch();\n }\n };\n\n const newButton = (\n <Button type=\"button\" onClick={() => navigate('releases/create')}>\n <Plus className=\"size-4\" />\n New release\n </Button>\n );\n\n const renderBody = () => {\n if (loading) {\n return <LoadingState variant=\"rows\" rows={6} label=\"Loading releases…\" />;\n }\n if (error) {\n return <ErrorState message={error.message} onRetry={() => void refetch()} />;\n }\n if (releases.length === 0) {\n const filtered = statusFilter !== ALL;\n return (\n <EmptyState\n icon={Rocket}\n title={filtered ? 'No releases match this filter' : 'No releases yet'}\n description={\n filtered\n ? 'Try clearing the status filter to see more releases.'\n : 'Package datasets and notebooks into a citable, versioned release for publication.'\n }\n action={filtered ? undefined : newButton}\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>Title</TableHead>\n <TableHead>Version</TableHead>\n <TableHead>Status</TableHead>\n <TableHead>DOI</TableHead>\n <TableHead>Authors</TableHead>\n <TableHead>Published</TableHead>\n <TableHead>License</TableHead>\n <TableHead className=\"text-right\">Actions</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {releases.map((release) => (\n <TableRow key={release.id}>\n <TableCell>\n <button\n type=\"button\"\n onClick={() => setDetail(release)}\n className=\"text-left font-medium text-text-primary underline-offset-2 hover:underline focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border-focus\"\n >\n {release.title}\n </button>\n </TableCell>\n <TableCell className=\"whitespace-nowrap text-sm text-text-secondary\">\n {release.version || '—'}\n </TableCell>\n <TableCell>\n <StatusBadge status={release.status} />\n </TableCell>\n <TableCell className=\"max-w-[14rem]\">\n {release.doi ? (\n <SafeLink\n href={doiUrl(release.doi)}\n className=\"inline-flex items-center gap-1 truncate text-sm text-text-primary underline-offset-2 hover:underline\"\n fallbackClassName=\"block truncate text-sm text-text-secondary\"\n >\n <span className=\"truncate\">{release.doi}</span>\n <ExternalLink className=\"size-3.5 shrink-0\" aria-hidden=\"true\" />\n </SafeLink>\n ) : (\n <span className=\"text-sm text-text-secondary\">—</span>\n )}\n </TableCell>\n <TableCell className=\"max-w-[14rem]\">\n {release.authors.length === 0 ? (\n <span className=\"text-sm text-text-secondary\">—</span>\n ) : (\n <span className=\"line-clamp-1 text-sm text-text-secondary\">\n {release.authors.join(', ')}\n </span>\n )}\n </TableCell>\n <TableCell className=\"whitespace-nowrap text-sm text-text-secondary\">\n {formatDate(release.publishedAt)}\n </TableCell>\n <TableCell className=\"whitespace-nowrap text-sm text-text-secondary\">\n {release.license || '—'}\n </TableCell>\n <TableCell className=\"text-right\">\n <ActionMenu\n ariaLabel={`Actions for ${release.title}`}\n onView={() => setDetail(release)}\n extraItems={\n canPublish(release.status)\n ? [\n {\n key: 'publish',\n label: 'Publish',\n icon: Rocket,\n onSelect: () => openPublish(release),\n },\n ]\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={releases.length}\n hasMore={pageInfo?.hasMore ?? false}\n onPrev={pagination.prevPage}\n onNext={pagination.nextPage}\n itemLabel=\"releases\"\n loading={loading}\n />\n </>\n );\n };\n\n return (\n <PageLayout\n title=\"Releases\"\n description=\"Citable, versioned publications that bundle datasets and notebooks for the community.\"\n actions={newButton}\n >\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"w-full max-w-[14rem]\">\n <Select value={statusFilter} onValueChange={setStatusFilter}>\n <SelectTrigger aria-label=\"Filter by status\">\n <SelectValue placeholder=\"All statuses\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All statuses</SelectItem>\n {RELEASE_STATUSES.map((status) => (\n <SelectItem key={status} value={status}>\n {formatEnumLabel(status)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n {renderBody()}\n </div>\n\n {/* View / detail dialog */}\n <Dialog open={detail !== null} onOpenChange={(open) => (open ? undefined : setDetail(null))}>\n <DialogContent className=\"max-h-[85vh] max-w-lg overflow-y-auto\">\n {detail ? (\n <>\n <DialogHeader>\n <DialogTitle className=\"flex items-center gap-2\">\n <BookOpen className=\"size-5 text-text-secondary\" aria-hidden=\"true\" />\n {detail.title}\n </DialogTitle>\n <DialogDescription>\n Version {detail.version || '—'} · <StatusBadge status={detail.status} />\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-4 text-sm\">\n <div>\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n Abstract\n </p>\n <p className=\"mt-1 whitespace-pre-wrap text-text-primary\">\n {detail.abstract?.trim() || 'No abstract provided.'}\n </p>\n </div>\n\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n Authors\n </p>\n <p className=\"mt-1 text-text-primary\">\n {detail.authors.length ? detail.authors.join(', ') : '—'}\n </p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n License\n </p>\n <p className=\"mt-1 text-text-primary\">{detail.license || '—'}</p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n Published\n </p>\n <p className=\"mt-1 text-text-primary\">{formatDate(detail.publishedAt)}</p>\n </div>\n <div>\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n DOI\n </p>\n <p className=\"mt-1\">\n {detail.doi ? (\n <SafeLink\n href={doiUrl(detail.doi)}\n className=\"inline-flex items-center gap-1 text-text-primary underline-offset-2 hover:underline\"\n fallbackClassName=\"text-text-secondary\"\n >\n {detail.doi}\n <ExternalLink className=\"size-3.5\" aria-hidden=\"true\" />\n </SafeLink>\n ) : (\n <span className=\"text-text-secondary\">Not assigned</span>\n )}\n </p>\n </div>\n </div>\n\n <div>\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n Datasets ({detail.datasetIds.length})\n </p>\n <div className=\"mt-1 flex flex-wrap gap-1.5\">\n {detail.datasetIds.length === 0 ? (\n <span className=\"text-text-secondary\">None linked.</span>\n ) : (\n detail.datasetIds.map((datasetId) => {\n const name = datasetNameById.get(datasetId);\n return (\n <Button\n key={datasetId}\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"h-auto gap-1 px-2 py-1\"\n onClick={() => goToLinked(`datasets/${datasetId}`)}\n >\n <Database className=\"size-3.5\" aria-hidden=\"true\" />\n <span className={name ? '' : 'font-mono text-xs'}>\n {name ?? datasetId}\n </span>\n </Button>\n );\n })\n )}\n </div>\n </div>\n\n <div>\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n Notebook\n </p>\n <div className=\"mt-1\">\n {detail.notebookId ? (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"h-auto gap-1 px-2 py-1\"\n onClick={() => goToLinked(`notebooks/${detail.notebookId}`)}\n >\n <NotebookPen className=\"size-3.5\" aria-hidden=\"true\" />\n <span className={notebookTitleById.get(detail.notebookId) ? '' : 'font-mono text-xs'}>\n {notebookTitleById.get(detail.notebookId) ?? detail.notebookId}\n </span>\n </Button>\n ) : (\n <span className=\"text-text-secondary\">None linked.</span>\n )}\n </div>\n </div>\n\n <div>\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n Discussion\n </p>\n <div className=\"mt-2\">\n <DiscussionPanel\n entityType=\"cosmicintersection-release\"\n entityId={detail.id}\n title={detail.title}\n widgetKey=\"release-discussion\"\n />\n </div>\n </div>\n </div>\n\n <DialogFooter>\n {canPublish(detail.status) ? (\n <Button\n type=\"button\"\n onClick={() => {\n const target = detail;\n setDetail(null);\n openPublish(target);\n }}\n >\n <Rocket className=\"size-4\" />\n Publish\n </Button>\n ) : null}\n <DialogClose asChild>\n <Button type=\"button\" variant=\"outline\">\n Close\n </Button>\n </DialogClose>\n </DialogFooter>\n </>\n ) : null}\n </DialogContent>\n </Dialog>\n\n {/* Publish dialog */}\n <Dialog\n open={publishTarget !== null}\n onOpenChange={(open) => (open || publishing ? undefined : setPublishTarget(null))}\n >\n <DialogContent className=\"max-w-md\">\n <DialogHeader>\n <DialogTitle>Publish release</DialogTitle>\n <DialogDescription>\n {publishTarget\n ? `Publish “${publishTarget.title}” to make it publicly citable. You can attach a DOI now or later.`\n : ''}\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"release-doi\">DOI (optional)</Label>\n <Input\n id=\"release-doi\"\n value={doiDraft}\n onChange={(event) => setDoiDraft(event.target.value)}\n placeholder=\"10.1234/cosmic.2026.0001\"\n />\n <p className=\"text-xs text-text-secondary\">\n A Digital Object Identifier makes the release permanently referenceable.\n </p>\n </div>\n\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setPublishTarget(null)}\n disabled={publishing}\n >\n Cancel\n </Button>\n <Button type=\"button\" onClick={() => void submitPublish()} disabled={publishing}>\n <Rocket className=\"size-4\" />\n {publishing ? 'Publishing…' : 'Publish release'}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,28 +1,29 @@
|
|
|
1
1
|
import { useCosmicIntersection as e } from "../../context/CosmicIntersectionContext.js";
|
|
2
2
|
import { notify as t } from "../../lib/toast.js";
|
|
3
|
-
import { useCosAddRunStepMutation as n, useCosRunQuery as r, useCosRunStepsQuery as ee, useCosTransitionRunMutation as
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
3
|
+
import { useCosAddRunStepMutation as n, useCosRunQuery as r, useCosRunStepsQuery as ee, useCosTransitionRunMutation as i } from "../../api/cosmicApi.js";
|
|
4
|
+
import a from "../../components/EmptyState.js";
|
|
5
|
+
import o from "../../components/ErrorState.js";
|
|
6
|
+
import s from "../../components/LoadingState.js";
|
|
7
|
+
import c from "../../components/ActivityFeedPanel.js";
|
|
8
|
+
import l from "../../components/SafeLink.js";
|
|
9
|
+
import u from "../../components/PageLayout.js";
|
|
10
|
+
import d, { formatEnumLabel as f } from "../../components/StatusBadge.js";
|
|
10
11
|
import "../../components/index.js";
|
|
11
|
-
import { describeError as
|
|
12
|
-
import { useMemo as
|
|
13
|
-
import { jsx as
|
|
14
|
-
import { useParams as
|
|
15
|
-
import { ListTree as
|
|
16
|
-
import { Button as
|
|
12
|
+
import { describeError as te, mutationSucceeded as p } from "../../lib/mutationResult.js";
|
|
13
|
+
import { useMemo as ne, useState as m } from "react";
|
|
14
|
+
import { jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
15
|
+
import { useParams as _ } from "react-router-dom";
|
|
16
|
+
import { ListTree as re, Plus as v } from "lucide-react";
|
|
17
|
+
import { Button as y, Card as b, CardContent as x, CardHeader as S, CardTitle as C, Dialog as ie, DialogContent as w, DialogDescription as ae, DialogFooter as oe, DialogHeader as T, DialogTitle as se, Input as E, Label as D, Select as ce, SelectContent as le, SelectItem as ue, SelectTrigger as de, SelectValue as fe, Textarea as pe } from "@burdenoff/fe-libs/ui";
|
|
17
18
|
//#region src/cosmicintersection/pages/runs/RunDetailPage.tsx
|
|
18
|
-
var
|
|
19
|
+
var me = [
|
|
19
20
|
"INGEST",
|
|
20
21
|
"CALIBRATE",
|
|
21
22
|
"TRANSFORM",
|
|
22
23
|
"ANALYZE",
|
|
23
24
|
"EXPORT",
|
|
24
25
|
"NOTIFY"
|
|
25
|
-
],
|
|
26
|
+
], he = {
|
|
26
27
|
QUEUED: ["RUNNING", "CANCELLED"],
|
|
27
28
|
RUNNING: [
|
|
28
29
|
"SUCCEEDED",
|
|
@@ -45,37 +46,37 @@ function k(e) {
|
|
|
45
46
|
return t < 60 ? `${t.toFixed(1)} s` : `${Math.floor(t / 60)}m ${Math.round(t % 60)}s`;
|
|
46
47
|
}
|
|
47
48
|
function A({ label: e, children: t }) {
|
|
48
|
-
return /* @__PURE__ */
|
|
49
|
+
return /* @__PURE__ */ g("div", {
|
|
49
50
|
className: "flex flex-col gap-1 border-b border-border-seam py-3 last:border-0 sm:flex-row sm:items-start sm:gap-4",
|
|
50
|
-
children: [/* @__PURE__ */
|
|
51
|
+
children: [/* @__PURE__ */ h("span", {
|
|
51
52
|
className: "w-40 shrink-0 text-sm font-medium text-text-secondary",
|
|
52
53
|
children: e
|
|
53
|
-
}), /* @__PURE__ */
|
|
54
|
+
}), /* @__PURE__ */ h("span", {
|
|
54
55
|
className: "min-w-0 text-sm text-text-primary",
|
|
55
56
|
children: t
|
|
56
57
|
})]
|
|
57
58
|
});
|
|
58
59
|
}
|
|
59
60
|
function j({ value: e }) {
|
|
60
|
-
return !e || Object.keys(e).length === 0 ? /* @__PURE__ */
|
|
61
|
+
return !e || Object.keys(e).length === 0 ? /* @__PURE__ */ h("span", {
|
|
61
62
|
className: "text-sm text-text-secondary",
|
|
62
63
|
children: "—"
|
|
63
|
-
}) : /* @__PURE__ */
|
|
64
|
+
}) : /* @__PURE__ */ h("pre", {
|
|
64
65
|
className: "overflow-x-auto rounded-card border border-border-default bg-bg-sunken p-3 font-mono text-xs text-text-primary",
|
|
65
66
|
children: JSON.stringify(e, null, 2)
|
|
66
67
|
});
|
|
67
68
|
}
|
|
68
69
|
function M() {
|
|
69
|
-
let { id: M = "" } =
|
|
70
|
+
let { id: M = "" } = _(), { navigate: N } = e(), { data: P, loading: F, error: I, refetch: L } = r(M), { data: R, loading: ge, error: _e, refetch: z } = ee(M), [ve, { loading: ye }] = i(), [be, { loading: B }] = n(), [xe, V] = m(!1), [H, U] = m(""), [W, G] = m("INGEST"), [K, q] = m(""), [J, Y] = m(""), X = P?.cosRun, Z = ne(() => [...R?.cosListRunSteps ?? []].sort((e, t) => e.position - t.position), [R]), Se = async (e) => {
|
|
70
71
|
if (!X) return;
|
|
71
|
-
let n = await
|
|
72
|
+
let n = await ve({ variables: {
|
|
72
73
|
id: X.id,
|
|
73
74
|
status: e
|
|
74
75
|
} });
|
|
75
|
-
|
|
76
|
+
p(n, n.data?.cosTransitionRun?.id, "Could not update the run") && (t.success("Run updated", `Run #${X.runNumber} moved to ${f(e)}.`), await Promise.all([L(), z()]));
|
|
76
77
|
}, Q = () => {
|
|
77
78
|
U(""), G("INGEST"), q(""), Y("");
|
|
78
|
-
},
|
|
79
|
+
}, Ce = async () => {
|
|
79
80
|
if (!X) return;
|
|
80
81
|
if (!H.trim()) {
|
|
81
82
|
t.error("Step name is required", "Give the step a name before adding it.");
|
|
@@ -87,7 +88,7 @@ function M() {
|
|
|
87
88
|
if (typeof t != "object" || !t || Array.isArray(t)) throw Error("Inputs must be a JSON object.");
|
|
88
89
|
e = t;
|
|
89
90
|
} catch (e) {
|
|
90
|
-
t.error("Invalid inputs JSON",
|
|
91
|
+
t.error("Invalid inputs JSON", te(e) ?? "Please provide valid JSON.");
|
|
91
92
|
return;
|
|
92
93
|
}
|
|
93
94
|
let n = K.trim() ? Number(K.trim()) : void 0;
|
|
@@ -95,32 +96,32 @@ function M() {
|
|
|
95
96
|
t.error("Invalid position", "Position must be a non-negative number.");
|
|
96
97
|
return;
|
|
97
98
|
}
|
|
98
|
-
let r = await
|
|
99
|
+
let r = await be({ variables: { input: {
|
|
99
100
|
runId: X.id,
|
|
100
101
|
name: H.trim(),
|
|
101
102
|
kind: W,
|
|
102
103
|
inputs: e,
|
|
103
104
|
position: n
|
|
104
105
|
} } });
|
|
105
|
-
|
|
106
|
+
p(r, r.data?.cosAddRunStep?.id, "Could not add the step") && (t.success("Step added", `“${H.trim()}” was added to the run.`), V(!1), Q(), await z());
|
|
106
107
|
};
|
|
107
|
-
if (F) return /* @__PURE__ */
|
|
108
|
+
if (F) return /* @__PURE__ */ h(u, {
|
|
108
109
|
title: "Run",
|
|
109
110
|
backPath: "runs",
|
|
110
|
-
children: /* @__PURE__ */
|
|
111
|
+
children: /* @__PURE__ */ h(s, { label: "Loading run…" })
|
|
111
112
|
});
|
|
112
|
-
if (I) return /* @__PURE__ */
|
|
113
|
+
if (I) return /* @__PURE__ */ h(u, {
|
|
113
114
|
title: "Run",
|
|
114
115
|
backPath: "runs",
|
|
115
|
-
children: /* @__PURE__ */
|
|
116
|
+
children: /* @__PURE__ */ h(o, { onRetry: () => void L() })
|
|
116
117
|
});
|
|
117
|
-
if (!X) return /* @__PURE__ */
|
|
118
|
+
if (!X) return /* @__PURE__ */ h(u, {
|
|
118
119
|
title: "Run",
|
|
119
120
|
backPath: "runs",
|
|
120
|
-
children: /* @__PURE__ */
|
|
121
|
+
children: /* @__PURE__ */ h(a, {
|
|
121
122
|
title: "Run not found",
|
|
122
123
|
description: "This run may have been removed or you may not have access to it.",
|
|
123
|
-
action: /* @__PURE__ */
|
|
124
|
+
action: /* @__PURE__ */ h(y, {
|
|
124
125
|
type: "button",
|
|
125
126
|
variant: "outline",
|
|
126
127
|
onClick: () => N("runs"),
|
|
@@ -128,196 +129,200 @@ function M() {
|
|
|
128
129
|
})
|
|
129
130
|
})
|
|
130
131
|
});
|
|
131
|
-
let $ =
|
|
132
|
-
return /* @__PURE__ */
|
|
132
|
+
let $ = he[X.status] ?? [];
|
|
133
|
+
return /* @__PURE__ */ g(u, {
|
|
133
134
|
title: `Run #${X.runNumber}`,
|
|
134
135
|
description: X.pipeline ? `Pipeline: ${X.pipeline.name}` : void 0,
|
|
135
136
|
backPath: "runs",
|
|
136
|
-
actions: /* @__PURE__ */
|
|
137
|
+
actions: /* @__PURE__ */ g("div", {
|
|
137
138
|
className: "flex flex-wrap items-center gap-2",
|
|
138
|
-
children: [$.map((e) => /* @__PURE__ */
|
|
139
|
+
children: [$.map((e) => /* @__PURE__ */ h(y, {
|
|
139
140
|
type: "button",
|
|
140
141
|
variant: e === "CANCELLED" || e === "FAILED" ? "outline" : "default",
|
|
141
|
-
onClick: () => void
|
|
142
|
-
disabled:
|
|
143
|
-
children: `Mark ${
|
|
144
|
-
}, e)), /* @__PURE__ */
|
|
142
|
+
onClick: () => void Se(e),
|
|
143
|
+
disabled: ye,
|
|
144
|
+
children: `Mark ${f(e)}`
|
|
145
|
+
}, e)), /* @__PURE__ */ g(y, {
|
|
145
146
|
type: "button",
|
|
146
147
|
variant: "outline",
|
|
147
148
|
onClick: () => V(!0),
|
|
148
|
-
children: [/* @__PURE__ */
|
|
149
|
+
children: [/* @__PURE__ */ h(v, { className: "size-4" }), "Add step"]
|
|
149
150
|
})]
|
|
150
151
|
}),
|
|
151
|
-
children: [/* @__PURE__ */
|
|
152
|
+
children: [/* @__PURE__ */ g("div", {
|
|
152
153
|
className: "space-y-6",
|
|
153
154
|
children: [
|
|
154
|
-
/* @__PURE__ */
|
|
155
|
-
/* @__PURE__ */
|
|
155
|
+
/* @__PURE__ */ g(b, { children: [/* @__PURE__ */ h(S, { children: /* @__PURE__ */ h(C, { children: "Overview" }) }), /* @__PURE__ */ g(x, { children: [
|
|
156
|
+
/* @__PURE__ */ h(A, {
|
|
156
157
|
label: "Status",
|
|
157
|
-
children: /* @__PURE__ */
|
|
158
|
+
children: /* @__PURE__ */ h(d, { status: X.status })
|
|
158
159
|
}),
|
|
159
|
-
/* @__PURE__ */
|
|
160
|
+
/* @__PURE__ */ h(A, {
|
|
160
161
|
label: "Pipeline",
|
|
161
|
-
children: X.pipeline ? /* @__PURE__ */
|
|
162
|
+
children: X.pipeline ? /* @__PURE__ */ h("button", {
|
|
162
163
|
type: "button",
|
|
163
164
|
className: "text-text-primary underline-offset-2 hover:underline",
|
|
164
165
|
onClick: () => N(`pipelines/${X.pipelineId}`),
|
|
165
166
|
children: X.pipeline.name
|
|
166
|
-
}) : /* @__PURE__ */
|
|
167
|
+
}) : /* @__PURE__ */ h("span", {
|
|
167
168
|
className: "font-mono text-xs",
|
|
168
169
|
children: X.pipelineId
|
|
169
170
|
})
|
|
170
171
|
}),
|
|
171
|
-
/* @__PURE__ */
|
|
172
|
+
/* @__PURE__ */ h(A, {
|
|
172
173
|
label: "Dataset",
|
|
173
|
-
children: X.datasetId ? /* @__PURE__ */
|
|
174
|
+
children: X.datasetId ? /* @__PURE__ */ h("button", {
|
|
174
175
|
type: "button",
|
|
175
176
|
className: "text-text-primary underline-offset-2 hover:underline",
|
|
176
177
|
onClick: () => N(`datasets/${X.datasetId}`),
|
|
177
|
-
children: /* @__PURE__ */
|
|
178
|
+
children: /* @__PURE__ */ h("span", {
|
|
178
179
|
className: "font-mono text-xs",
|
|
179
180
|
children: X.datasetId
|
|
180
181
|
})
|
|
181
182
|
}) : "—"
|
|
182
183
|
}),
|
|
183
|
-
/* @__PURE__ */
|
|
184
|
+
/* @__PURE__ */ h(A, {
|
|
184
185
|
label: "Triggered by",
|
|
185
186
|
children: X.triggeredBy || "—"
|
|
186
187
|
}),
|
|
187
|
-
/* @__PURE__ */
|
|
188
|
+
/* @__PURE__ */ h(A, {
|
|
188
189
|
label: "Started",
|
|
189
190
|
children: O(X.startedAt)
|
|
190
191
|
}),
|
|
191
|
-
/* @__PURE__ */
|
|
192
|
+
/* @__PURE__ */ h(A, {
|
|
192
193
|
label: "Finished",
|
|
193
194
|
children: O(X.finishedAt)
|
|
194
195
|
}),
|
|
195
|
-
/* @__PURE__ */
|
|
196
|
+
/* @__PURE__ */ h(A, {
|
|
196
197
|
label: "Duration",
|
|
197
198
|
children: k(X.durationMs)
|
|
198
199
|
}),
|
|
199
|
-
X.errorMessage ? /* @__PURE__ */
|
|
200
|
+
X.errorMessage ? /* @__PURE__ */ h(A, {
|
|
200
201
|
label: "Error",
|
|
201
|
-
children: /* @__PURE__ */
|
|
202
|
+
children: /* @__PURE__ */ h("span", {
|
|
202
203
|
className: "text-status-error-text",
|
|
203
204
|
children: X.errorMessage
|
|
204
205
|
})
|
|
205
206
|
}) : null,
|
|
206
|
-
$.length === 0 ? /* @__PURE__ */
|
|
207
|
+
$.length === 0 ? /* @__PURE__ */ h(A, {
|
|
207
208
|
label: "Discuss",
|
|
208
|
-
children: /* @__PURE__ */
|
|
209
|
+
children: /* @__PURE__ */ h(l, {
|
|
209
210
|
href: "/conversations",
|
|
210
211
|
className: "text-text-primary underline-offset-2 hover:underline",
|
|
211
212
|
children: "Open discussions"
|
|
212
213
|
})
|
|
213
214
|
}) : null
|
|
214
215
|
] })] }),
|
|
215
|
-
/* @__PURE__ */
|
|
216
|
+
/* @__PURE__ */ g("div", {
|
|
216
217
|
className: "grid grid-cols-1 gap-6 lg:grid-cols-2",
|
|
217
|
-
children: [/* @__PURE__ */
|
|
218
|
+
children: [/* @__PURE__ */ g(b, { children: [/* @__PURE__ */ h(S, { children: /* @__PURE__ */ h(C, { children: "Parameters" }) }), /* @__PURE__ */ h(x, { children: /* @__PURE__ */ h(j, { value: X.params }) })] }), /* @__PURE__ */ g(b, { children: [/* @__PURE__ */ h(S, { children: /* @__PURE__ */ h(C, { children: "Metrics" }) }), /* @__PURE__ */ h(x, { children: /* @__PURE__ */ h(j, { value: X.metrics }) })] })]
|
|
218
219
|
}),
|
|
219
|
-
/* @__PURE__ */
|
|
220
|
+
/* @__PURE__ */ g(b, { children: [/* @__PURE__ */ h(S, { children: /* @__PURE__ */ h(C, { children: "Steps" }) }), /* @__PURE__ */ h(x, { children: ge ? /* @__PURE__ */ h(s, {
|
|
220
221
|
variant: "rows",
|
|
221
222
|
rows: 4,
|
|
222
223
|
label: "Loading steps…"
|
|
223
|
-
}) :
|
|
224
|
+
}) : _e ? /* @__PURE__ */ h(o, {
|
|
224
225
|
message: "Could not load steps.",
|
|
225
226
|
onRetry: () => void z()
|
|
226
|
-
}) : Z.length === 0 ? /* @__PURE__ */
|
|
227
|
-
icon:
|
|
227
|
+
}) : Z.length === 0 ? /* @__PURE__ */ h(a, {
|
|
228
|
+
icon: re,
|
|
228
229
|
title: "No steps yet",
|
|
229
230
|
description: "Add steps to record the ingest, calibration, transform, analyze or export stages of this run.",
|
|
230
|
-
action: /* @__PURE__ */
|
|
231
|
+
action: /* @__PURE__ */ g(y, {
|
|
231
232
|
type: "button",
|
|
232
233
|
onClick: () => V(!0),
|
|
233
|
-
children: [/* @__PURE__ */
|
|
234
|
+
children: [/* @__PURE__ */ h(v, { className: "size-4" }), "Add step"]
|
|
234
235
|
})
|
|
235
|
-
}) : /* @__PURE__ */
|
|
236
|
+
}) : /* @__PURE__ */ h("ol", {
|
|
236
237
|
className: "space-y-3",
|
|
237
|
-
children: Z.map((e) => /* @__PURE__ */
|
|
238
|
+
children: Z.map((e) => /* @__PURE__ */ g("li", {
|
|
238
239
|
className: "flex flex-col gap-2 rounded-card border border-border-default bg-bg-elevated p-4 sm:flex-row sm:items-start sm:justify-between",
|
|
239
|
-
children: [/* @__PURE__ */
|
|
240
|
+
children: [/* @__PURE__ */ g("div", {
|
|
240
241
|
className: "flex min-w-0 items-start gap-3",
|
|
241
|
-
children: [/* @__PURE__ */
|
|
242
|
+
children: [/* @__PURE__ */ h("span", {
|
|
242
243
|
className: "mt-0.5 flex size-7 shrink-0 items-center justify-center rounded-full bg-bg-sunken text-xs font-semibold tabular-nums text-text-secondary",
|
|
243
244
|
children: e.position
|
|
244
|
-
}), /* @__PURE__ */
|
|
245
|
+
}), /* @__PURE__ */ g("div", {
|
|
245
246
|
className: "min-w-0",
|
|
246
247
|
children: [
|
|
247
|
-
/* @__PURE__ */
|
|
248
|
+
/* @__PURE__ */ g("div", {
|
|
248
249
|
className: "flex flex-wrap items-center gap-2",
|
|
249
|
-
children: [/* @__PURE__ */
|
|
250
|
+
children: [/* @__PURE__ */ h("span", {
|
|
250
251
|
className: "font-medium text-text-primary",
|
|
251
252
|
children: e.name
|
|
252
|
-
}), /* @__PURE__ */
|
|
253
|
+
}), /* @__PURE__ */ h(d, {
|
|
253
254
|
status: e.kind,
|
|
254
255
|
tone: "neutral"
|
|
255
256
|
})]
|
|
256
257
|
}),
|
|
257
|
-
e.errorMessage ? /* @__PURE__ */
|
|
258
|
+
e.errorMessage ? /* @__PURE__ */ h("p", {
|
|
258
259
|
className: "mt-1 text-xs text-status-error-text",
|
|
259
260
|
children: e.errorMessage
|
|
260
261
|
}) : null,
|
|
261
|
-
/* @__PURE__ */
|
|
262
|
+
/* @__PURE__ */ g("p", {
|
|
262
263
|
className: "mt-1 text-xs text-text-secondary",
|
|
263
264
|
children: ["Duration: ", k(e.durationMs)]
|
|
264
265
|
})
|
|
265
266
|
]
|
|
266
267
|
})]
|
|
267
|
-
}), /* @__PURE__ */
|
|
268
|
+
}), /* @__PURE__ */ h("div", {
|
|
268
269
|
className: "shrink-0",
|
|
269
|
-
children: /* @__PURE__ */
|
|
270
|
+
children: /* @__PURE__ */ h(d, { status: e.status })
|
|
270
271
|
})]
|
|
271
272
|
}, e.id))
|
|
273
|
+
}) })] }),
|
|
274
|
+
/* @__PURE__ */ g(b, { children: [/* @__PURE__ */ h(S, { children: /* @__PURE__ */ h(C, { children: "Activity" }) }), /* @__PURE__ */ h(x, { children: /* @__PURE__ */ h(c, {
|
|
275
|
+
resourceId: X.id,
|
|
276
|
+
resourceType: "cosmicintersection-run"
|
|
272
277
|
}) })] })
|
|
273
278
|
]
|
|
274
|
-
}), /* @__PURE__ */
|
|
275
|
-
open:
|
|
279
|
+
}), /* @__PURE__ */ h(ie, {
|
|
280
|
+
open: xe,
|
|
276
281
|
onOpenChange: (e) => {
|
|
277
282
|
B || (V(e), e || Q());
|
|
278
283
|
},
|
|
279
|
-
children: /* @__PURE__ */
|
|
280
|
-
/* @__PURE__ */
|
|
281
|
-
/* @__PURE__ */
|
|
284
|
+
children: /* @__PURE__ */ g(w, { children: [
|
|
285
|
+
/* @__PURE__ */ g(T, { children: [/* @__PURE__ */ h(se, { children: "Add step" }), /* @__PURE__ */ h(ae, { children: "Record a stage of this run — its kind, order and optional inputs." })] }),
|
|
286
|
+
/* @__PURE__ */ g("div", {
|
|
282
287
|
className: "space-y-4",
|
|
283
288
|
children: [
|
|
284
|
-
/* @__PURE__ */
|
|
289
|
+
/* @__PURE__ */ g("div", {
|
|
285
290
|
className: "space-y-1",
|
|
286
|
-
children: [/* @__PURE__ */
|
|
291
|
+
children: [/* @__PURE__ */ h(D, {
|
|
287
292
|
htmlFor: "step-name",
|
|
288
293
|
children: "Name"
|
|
289
|
-
}), /* @__PURE__ */
|
|
294
|
+
}), /* @__PURE__ */ h(E, {
|
|
290
295
|
id: "step-name",
|
|
291
296
|
value: H,
|
|
292
297
|
onChange: (e) => U(e.target.value),
|
|
293
298
|
placeholder: "e.g. Calibrate flat fields"
|
|
294
299
|
})]
|
|
295
300
|
}),
|
|
296
|
-
/* @__PURE__ */
|
|
301
|
+
/* @__PURE__ */ g("div", {
|
|
297
302
|
className: "grid grid-cols-1 gap-4 sm:grid-cols-2",
|
|
298
|
-
children: [/* @__PURE__ */
|
|
303
|
+
children: [/* @__PURE__ */ g("div", {
|
|
299
304
|
className: "space-y-1",
|
|
300
|
-
children: [/* @__PURE__ */
|
|
305
|
+
children: [/* @__PURE__ */ h(D, {
|
|
301
306
|
htmlFor: "step-kind",
|
|
302
307
|
children: "Kind"
|
|
303
|
-
}), /* @__PURE__ */
|
|
308
|
+
}), /* @__PURE__ */ g(ce, {
|
|
304
309
|
value: W,
|
|
305
310
|
onValueChange: (e) => G(e),
|
|
306
|
-
children: [/* @__PURE__ */
|
|
311
|
+
children: [/* @__PURE__ */ h(de, {
|
|
307
312
|
id: "step-kind",
|
|
308
313
|
"aria-label": "Step kind",
|
|
309
|
-
children: /* @__PURE__ */
|
|
310
|
-
}), /* @__PURE__ */
|
|
314
|
+
children: /* @__PURE__ */ h(fe, {})
|
|
315
|
+
}), /* @__PURE__ */ h(le, { children: me.map((e) => /* @__PURE__ */ h(ue, {
|
|
311
316
|
value: e,
|
|
312
|
-
children:
|
|
317
|
+
children: f(e)
|
|
313
318
|
}, e)) })]
|
|
314
319
|
})]
|
|
315
|
-
}), /* @__PURE__ */
|
|
320
|
+
}), /* @__PURE__ */ g("div", {
|
|
316
321
|
className: "space-y-1",
|
|
317
|
-
children: [/* @__PURE__ */
|
|
322
|
+
children: [/* @__PURE__ */ h(D, {
|
|
318
323
|
htmlFor: "step-position",
|
|
319
324
|
children: "Position"
|
|
320
|
-
}), /* @__PURE__ */
|
|
325
|
+
}), /* @__PURE__ */ h(E, {
|
|
321
326
|
id: "step-position",
|
|
322
327
|
type: "number",
|
|
323
328
|
min: "0",
|
|
@@ -327,14 +332,14 @@ function M() {
|
|
|
327
332
|
})]
|
|
328
333
|
})]
|
|
329
334
|
}),
|
|
330
|
-
/* @__PURE__ */
|
|
335
|
+
/* @__PURE__ */ g("div", {
|
|
331
336
|
className: "space-y-1",
|
|
332
337
|
children: [
|
|
333
|
-
/* @__PURE__ */
|
|
338
|
+
/* @__PURE__ */ h(D, {
|
|
334
339
|
htmlFor: "step-inputs",
|
|
335
340
|
children: "Inputs (JSON)"
|
|
336
341
|
}),
|
|
337
|
-
/* @__PURE__ */
|
|
342
|
+
/* @__PURE__ */ h(pe, {
|
|
338
343
|
id: "step-inputs",
|
|
339
344
|
value: J,
|
|
340
345
|
onChange: (e) => Y(e.target.value),
|
|
@@ -343,7 +348,7 @@ function M() {
|
|
|
343
348
|
className: "font-mono text-xs",
|
|
344
349
|
placeholder: "{\n \"source\": \"raw-frames\"\n}"
|
|
345
350
|
}),
|
|
346
|
-
/* @__PURE__ */
|
|
351
|
+
/* @__PURE__ */ h("p", {
|
|
347
352
|
className: "text-xs text-text-secondary",
|
|
348
353
|
children: "Optional. A JSON object of step inputs."
|
|
349
354
|
})
|
|
@@ -351,7 +356,7 @@ function M() {
|
|
|
351
356
|
})
|
|
352
357
|
]
|
|
353
358
|
}),
|
|
354
|
-
/* @__PURE__ */
|
|
359
|
+
/* @__PURE__ */ g(oe, { children: [/* @__PURE__ */ h(y, {
|
|
355
360
|
type: "button",
|
|
356
361
|
variant: "outline",
|
|
357
362
|
onClick: () => {
|
|
@@ -359,11 +364,11 @@ function M() {
|
|
|
359
364
|
},
|
|
360
365
|
disabled: B,
|
|
361
366
|
children: "Cancel"
|
|
362
|
-
}), /* @__PURE__ */
|
|
367
|
+
}), /* @__PURE__ */ g(y, {
|
|
363
368
|
type: "button",
|
|
364
|
-
onClick: () => void
|
|
369
|
+
onClick: () => void Ce(),
|
|
365
370
|
disabled: B,
|
|
366
|
-
children: [/* @__PURE__ */
|
|
371
|
+
children: [/* @__PURE__ */ h(v, { className: "size-4" }), B ? "Adding…" : "Add step"]
|
|
367
372
|
})] })
|
|
368
373
|
] })
|
|
369
374
|
})]
|