@burdenoff/microfe-cosmicintersection 2026.830.1 → 2026.1012.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.
- package/dist/cosmicintersection/CosmicIntersectionRoutes.d.ts +1 -1
- package/dist/cosmicintersection/CosmicIntersectionRoutes.d.ts.map +1 -1
- package/dist/cosmicintersection/api/cosmicApi.d.ts +48 -48
- package/dist/cosmicintersection/api/cosmicApi.d.ts.map +1 -1
- package/dist/cosmicintersection/components/ActionMenu.d.ts +1 -1
- package/dist/cosmicintersection/components/ActionMenu.d.ts.map +1 -1
- package/dist/cosmicintersection/components/ActionMenu.js.map +1 -1
- package/dist/cosmicintersection/components/ActivityFeedPanel.d.ts +1 -1
- package/dist/cosmicintersection/components/ActivityFeedPanel.d.ts.map +1 -1
- package/dist/cosmicintersection/components/DiscussionPanel.d.ts +1 -1
- package/dist/cosmicintersection/components/DiscussionPanel.d.ts.map +1 -1
- package/dist/cosmicintersection/components/EmptyState.d.ts +1 -1
- package/dist/cosmicintersection/components/EmptyState.d.ts.map +1 -1
- package/dist/cosmicintersection/components/EntityFormShell.d.ts +1 -1
- package/dist/cosmicintersection/components/EntityFormShell.d.ts.map +1 -1
- package/dist/cosmicintersection/components/EntityTagsField.d.ts +1 -1
- package/dist/cosmicintersection/components/EntityTagsField.d.ts.map +1 -1
- package/dist/cosmicintersection/components/ErrorState.d.ts +1 -1
- package/dist/cosmicintersection/components/ErrorState.d.ts.map +1 -1
- package/dist/cosmicintersection/components/ErrorState.js.map +1 -1
- package/dist/cosmicintersection/components/FacetPanel.d.ts +1 -1
- package/dist/cosmicintersection/components/FacetPanel.d.ts.map +1 -1
- package/dist/cosmicintersection/components/FileUploadField.d.ts +2 -2
- package/dist/cosmicintersection/components/FileUploadField.d.ts.map +1 -1
- package/dist/cosmicintersection/components/FileUploadField.js +1 -0
- package/dist/cosmicintersection/components/FileUploadField.js.map +1 -1
- package/dist/cosmicintersection/components/LineageGraph.d.ts +1 -1
- package/dist/cosmicintersection/components/LineageGraph.d.ts.map +1 -1
- package/dist/cosmicintersection/components/LoadingState.d.ts +1 -1
- package/dist/cosmicintersection/components/LoadingState.d.ts.map +1 -1
- package/dist/cosmicintersection/components/PageLayout.d.ts +1 -1
- package/dist/cosmicintersection/components/PageLayout.d.ts.map +1 -1
- package/dist/cosmicintersection/components/Pagination.d.ts +1 -1
- package/dist/cosmicintersection/components/Pagination.d.ts.map +1 -1
- package/dist/cosmicintersection/components/Pagination.js.map +1 -1
- package/dist/cosmicintersection/components/ResultsChart.d.ts +1 -1
- package/dist/cosmicintersection/components/ResultsChart.d.ts.map +1 -1
- package/dist/cosmicintersection/components/SafeLink.d.ts +1 -1
- package/dist/cosmicintersection/components/SafeLink.d.ts.map +1 -1
- package/dist/cosmicintersection/components/StatusBadge.d.ts +1 -1
- package/dist/cosmicintersection/components/StatusBadge.d.ts.map +1 -1
- package/dist/cosmicintersection/components/StatusBadge.js.map +1 -1
- package/dist/cosmicintersection/components/StepDAG.d.ts +1 -1
- package/dist/cosmicintersection/components/StepDAG.d.ts.map +1 -1
- package/dist/cosmicintersection/context/CosmicIntersectionContext.d.ts +1 -1
- package/dist/cosmicintersection/context/CosmicIntersectionContext.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/access/AccessPage.d.ts +1 -1
- package/dist/cosmicintersection/pages/access/AccessPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/access/AccessPage.js.map +1 -1
- package/dist/cosmicintersection/pages/analyses/AnalysesPage.d.ts +1 -1
- package/dist/cosmicintersection/pages/analyses/AnalysesPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/analyses/AnalysesPage.js.map +1 -1
- package/dist/cosmicintersection/pages/collections/CollectionDetailPage.d.ts +1 -1
- package/dist/cosmicintersection/pages/collections/CollectionDetailPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/collections/CollectionFormPage.d.ts +1 -1
- package/dist/cosmicintersection/pages/collections/CollectionFormPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/collections/CollectionsPage.d.ts +1 -1
- package/dist/cosmicintersection/pages/collections/CollectionsPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/collections/CollectionsPage.js.map +1 -1
- package/dist/cosmicintersection/pages/dashboard/DashboardPage.d.ts +1 -1
- package/dist/cosmicintersection/pages/dashboard/DashboardPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/dashboard/DashboardPage.js.map +1 -1
- package/dist/cosmicintersection/pages/datasets/DatasetDetailPage.d.ts +1 -1
- package/dist/cosmicintersection/pages/datasets/DatasetDetailPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/datasets/DatasetFormPage.d.ts +1 -1
- package/dist/cosmicintersection/pages/datasets/DatasetFormPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/datasets/DatasetsPage.d.ts +1 -1
- package/dist/cosmicintersection/pages/datasets/DatasetsPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/datasets/DatasetsPage.js.map +1 -1
- package/dist/cosmicintersection/pages/discovery/DiscoveryPage.d.ts +1 -1
- package/dist/cosmicintersection/pages/discovery/DiscoveryPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/discovery/DiscoveryPage.js.map +1 -1
- package/dist/cosmicintersection/pages/lineage/LineagePage.d.ts +1 -1
- package/dist/cosmicintersection/pages/lineage/LineagePage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/lineage/LineagePage.js.map +1 -1
- package/dist/cosmicintersection/pages/notebooks/NotebookDetailPage.d.ts +1 -1
- package/dist/cosmicintersection/pages/notebooks/NotebookDetailPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/notebooks/NotebookFormPage.d.ts +1 -1
- package/dist/cosmicintersection/pages/notebooks/NotebookFormPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/notebooks/NotebooksPage.d.ts +1 -1
- package/dist/cosmicintersection/pages/notebooks/NotebooksPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/notebooks/NotebooksPage.js.map +1 -1
- package/dist/cosmicintersection/pages/pipelines/PipelineDetailPage.d.ts +1 -1
- package/dist/cosmicintersection/pages/pipelines/PipelineDetailPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/pipelines/PipelineFormPage.d.ts +1 -1
- package/dist/cosmicintersection/pages/pipelines/PipelineFormPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/pipelines/PipelinesPage.d.ts +1 -1
- package/dist/cosmicintersection/pages/pipelines/PipelinesPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/pipelines/PipelinesPage.js.map +1 -1
- package/dist/cosmicintersection/pages/releases/ReleaseFormPage.d.ts +1 -1
- package/dist/cosmicintersection/pages/releases/ReleaseFormPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/releases/ReleasesPage.d.ts +1 -1
- package/dist/cosmicintersection/pages/releases/ReleasesPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/releases/ReleasesPage.js.map +1 -1
- package/dist/cosmicintersection/pages/runs/RunDetailPage.d.ts +1 -1
- package/dist/cosmicintersection/pages/runs/RunDetailPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/runs/RunsPage.d.ts +1 -1
- package/dist/cosmicintersection/pages/runs/RunsPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/runs/RunsPage.js.map +1 -1
- package/dist/cosmicintersection/pages/sources/SourceDetailPage.d.ts +1 -1
- package/dist/cosmicintersection/pages/sources/SourceDetailPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/sources/SourceFormPage.d.ts +1 -1
- package/dist/cosmicintersection/pages/sources/SourceFormPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/sources/SourcesPage.d.ts +1 -1
- package/dist/cosmicintersection/pages/sources/SourcesPage.d.ts.map +1 -1
- package/dist/cosmicintersection/pages/sources/SourcesPage.js.map +1 -1
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +96 -17
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -1
- package/dist/shared/hooks/useTr.d.ts.map +1 -1
- package/dist/shared/hooks/useTr.js.map +1 -1
- package/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileUploadField.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/FileUploadField.tsx"],"names":[],"mappings":"AACA,OAAO,EAAmB,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AA8CjE,eAAO,MAAM,qBAAqB,gCAIjC,CAAC;AAaF,UAAU,mBAAmB;IAC3B,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;QACvB,MAAM;eAAa,MAAM;;QAAzB,MAAM;eAAa,MAAM;
|
|
1
|
+
{"version":3,"file":"FileUploadField.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/FileUploadField.tsx"],"names":[],"mappings":"AACA,OAAO,EAAmB,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AA8CjE,eAAO,MAAM,qBAAqB,gCAIjC,CAAC;AAaF,UAAU,mBAAmB;IAC3B,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;QACvB,MAAM;eAAa,MAAM;;QAAzB,MAAM;eAAa,MAAM;cAKrE;AAED,MAAM,WAAW,oBAAoB;IACnC,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,gFAAgF;IAChF,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,QAAQ,EACR,KAAK,EACL,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,QAAgB,EAChB,SAAS,GACV,EAAE,oBAAoB,+BA+KtB;AAED,eAAe,eAAe,CAAC"}
|
|
@@ -67,6 +67,7 @@ function x({ value: p, onChange: h, label: v, hint: y, folderId: x, accept: S, d
|
|
|
67
67
|
mutation: _,
|
|
68
68
|
variables: { input: {
|
|
69
69
|
sessionId: a.id,
|
|
70
|
+
fileSize: String(n.size),
|
|
70
71
|
...x ? { folderId: x } : {}
|
|
71
72
|
} }
|
|
72
73
|
}), c = s.data?.completeUpload?.fileId ?? s.data?.completeUpload?.file?.id;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileUploadField.js","names":[],"sources":["../../../src/cosmicintersection/components/FileUploadField.tsx"],"sourcesContent":["import { gql } from '@apollo/client';\nimport { useApolloClient, useQuery } from '@apollo/client/react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Download, FileUp, Loader2, Paperclip, X } from 'lucide-react';\nimport { useId, useRef, useState } from 'react';\n\nimport { notify } from '../lib/toast';\nimport { useTr } from '../../shared/hooks/useTr';\n\n/**\n * Generic artifact uploader backed by wspace-files-svc.\n *\n * Dataset/notebook/analysis blobs are NOT stored by this MFE — they live in\n * wspace-files as `File` records, and the Cos entities only hold the returned\n * `fileId` (CosDataset.fileId / CosNotebook.fileId / cosCompleteAnalysis.outputFileId).\n * This control performs the shared 3-step presigned upload (initiateUpload → PUT\n * → completeUpload) inline — the same protocol microfe-files uses — and hands the\n * resulting `fileId` back via `onChange`. It never keeps a local blob store and\n * accepts any file type.\n */\n\n// initiateUpload returns a presigned PUT URL + the upload session id.\nconst INITIATE_UPLOAD = gql`\n mutation CosInitiateUpload($input: InitiateUploadInput!) {\n initiateUpload(input: $input) {\n session {\n id\n }\n uploadUrl\n }\n }\n`;\n\n// completeUpload finalizes the session and returns the committed File id.\nconst COMPLETE_UPLOAD = gql`\n mutation CosCompleteUpload($input: CompleteUploadInput!) {\n completeUpload(input: $input) {\n fileId\n file {\n id\n }\n }\n }\n`;\n\n// Presigned, time-limited download URL for a stored File — used to render a\n// \"Download\" affordance for an already-attached artifact.\nexport const GET_FILE_DOWNLOAD_URL = gql`\n query CosGetFileDownloadUrl($id: ID!, $expiresIn: Int) {\n getFileDownloadUrl(id: $id, expiresIn: $expiresIn)\n }\n`;\n\n// One hour — artifact links are resolved on demand when a detail page renders.\nconst DOWNLOAD_URL_TTL_SECONDS = 3_600;\n\ninterface InitiateUploadResponse {\n initiateUpload?: { session?: { id: string } | null; uploadUrl?: string | null } | null;\n}\n\ninterface CompleteUploadResponse {\n completeUpload?: { fileId?: string | null; file?: { id: string } | null } | null;\n}\n\ninterface DownloadUrlResponse {\n getFileDownloadUrl?: string | null;\n}\n\n/**\n * Resolve a presigned download URL for an attached File id. Skips when no id is\n * present. Detail pages use this to render a \"Download\" link for a dataset/\n * notebook/analysis artifact.\n */\nexport function useFileDownloadUrl(fileId: string | null | undefined) {\n return useQuery<DownloadUrlResponse, { id: string; expiresIn: number }>(GET_FILE_DOWNLOAD_URL, {\n variables: { id: fileId ?? '', expiresIn: DOWNLOAD_URL_TTL_SECONDS },\n skip: !fileId,\n fetchPolicy: 'no-cache',\n });\n}\n\nexport interface FileUploadFieldProps {\n /** Current attached wspace-files File id, if any. */\n value?: string | null;\n /** Called with the new File id once an upload completes, or '' when cleared. */\n onChange: (fileId: string) => void | Promise<void>;\n label: string;\n hint?: string;\n /** Optional wspace-files folder id; when omitted the file lands in the root. */\n folderId?: string;\n /** `accept` attribute for the file input; defaults to any file type. */\n accept?: string;\n disabled?: boolean;\n className?: string;\n}\n\nexport function FileUploadField({\n value,\n onChange,\n label,\n hint,\n folderId,\n accept,\n disabled = false,\n className,\n}: FileUploadFieldProps) {\n const tr = useTr();\n const client = useApolloClient();\n const inputRef = useRef<HTMLInputElement | null>(null);\n const inputId = useId();\n const [uploading, setUploading] = useState(false);\n const [fileName, setFileName] = useState<string | null>(null);\n\n const download = useFileDownloadUrl(uploading ? null : value);\n const downloadUrl = download.data?.getFileDownloadUrl ?? null;\n\n const handleSelect = async (event: React.ChangeEvent<HTMLInputElement>) => {\n const file = event.target.files?.[0];\n // Reset the input so selecting the same file again re-triggers change.\n event.target.value = '';\n if (!file) {\n return;\n }\n\n setUploading(true);\n try {\n const extension = file.name.includes('.')\n ? file.name.substring(file.name.lastIndexOf('.') + 1)\n : '';\n const mimeType = file.type || 'application/octet-stream';\n\n const initiate = await client.mutate<InitiateUploadResponse>({\n mutation: INITIATE_UPLOAD,\n variables: {\n input: {\n fileName: file.name,\n fileSize: String(file.size),\n extension,\n mimeType,\n ...(folderId ? { folderId } : {}),\n },\n },\n });\n const session = initiate.data?.initiateUpload?.session;\n const uploadUrl = initiate.data?.initiateUpload?.uploadUrl;\n if (!session || !uploadUrl) {\n throw new Error(initiate.error?.message ?? tr('cosmicintersection.common.uploadStartError', 'Could not start the upload.'));\n }\n\n await new Promise<void>((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n xhr.addEventListener('load', () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n resolve();\n } else {\n reject(new Error(`Upload failed with status ${xhr.status}`));\n }\n });\n xhr.addEventListener('error', () => reject(new Error('Upload network error')));\n xhr.addEventListener('abort', () => reject(new Error('Upload aborted')));\n xhr.open('PUT', uploadUrl);\n xhr.setRequestHeader('Content-Type', mimeType);\n xhr.send(file);\n });\n\n const complete = await client.mutate<CompleteUploadResponse>({\n mutation: COMPLETE_UPLOAD,\n variables: {\n input: {\n sessionId: session.id,\n ...(folderId ? { folderId } : {}),\n },\n },\n });\n const uploadedId =\n complete.data?.completeUpload?.fileId ?? complete.data?.completeUpload?.file?.id;\n if (!uploadedId) {\n throw new Error(complete.error?.message ?? tr('cosmicintersection.common.uploadConfirmError', 'The file was uploaded but not confirmed.'));\n }\n\n setFileName(file.name);\n await onChange(uploadedId);\n notify.success(tr('cosmicintersection.common.uploadSuccess', 'File uploaded'));\n } catch (error) {\n notify.error(\n tr('cosmicintersection.common.uploadFailed', 'Upload failed'),\n error instanceof Error ? error.message : tr('cosmicintersection.common.uploadTryAgain', 'Please try again.'),\n );\n } finally {\n setUploading(false);\n }\n };\n\n const clear = async () => {\n setFileName(null);\n await onChange('');\n };\n\n return (\n <div className={className}>\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"flex size-12 shrink-0 items-center justify-center rounded-card border border-dashed border-border-default bg-bg-sunken text-text-secondary\">\n <Paperclip className=\"size-5\" aria-hidden=\"true\" />\n </div>\n <div className=\"space-y-1\">\n <div className=\"flex items-center gap-2\">\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"sm\"\n disabled={disabled || uploading}\n onClick={() => inputRef.current?.click()}\n >\n {uploading ? (\n <Loader2 className=\"size-4 animate-spin\" />\n ) : (\n <FileUp className=\"size-4\" />\n )}\n {uploading ? tr('cosmicintersection.common.uploading', 'Uploading…') : value ? tr('cosmicintersection.common.replaceFile', 'Replace file') : label}\n </Button>\n {value && !uploading ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => void clear()}\n disabled={disabled}\n >\n <X className=\"size-4\" />\n {tr('cosmicintersection.common.remove', 'Remove')}\n </Button>\n ) : null}\n </div>\n {value ? (\n <div className=\"flex flex-wrap items-center gap-2 text-xs text-text-secondary\">\n <span className=\"max-w-[16rem] truncate\">{fileName ?? `File ${value}`}</span>\n {downloadUrl ? (\n <a\n href={downloadUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 text-text-primary underline-offset-2 hover:underline\"\n >\n <Download className=\"size-3.5\" aria-hidden=\"true\" />\n {tr('cosmicintersection.common.download', 'Download')}\n </a>\n ) : null}\n </div>\n ) : hint ? (\n <p className=\"text-xs text-text-secondary\">{hint}</p>\n ) : null}\n </div>\n </div>\n <input\n ref={inputRef}\n id={inputId}\n type=\"file\"\n accept={accept}\n className=\"sr-only\"\n aria-label={label}\n onChange={(event) => void handleSelect(event)}\n />\n </div>\n );\n}\n\nexport default FileUploadField;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FileUploadField.js","names":[],"sources":["../../../src/cosmicintersection/components/FileUploadField.tsx"],"sourcesContent":["import { gql } from '@apollo/client';\nimport { useApolloClient, useQuery } from '@apollo/client/react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Download, FileUp, Loader2, Paperclip, X } from 'lucide-react';\nimport { useId, useRef, useState } from 'react';\n\nimport { notify } from '../lib/toast';\nimport { useTr } from '../../shared/hooks/useTr';\n\n/**\n * Generic artifact uploader backed by wspace-files-svc.\n *\n * Dataset/notebook/analysis blobs are NOT stored by this MFE — they live in\n * wspace-files as `File` records, and the Cos entities only hold the returned\n * `fileId` (CosDataset.fileId / CosNotebook.fileId / cosCompleteAnalysis.outputFileId).\n * This control performs the shared 3-step presigned upload (initiateUpload → PUT\n * → completeUpload) inline — the same protocol microfe-files uses — and hands the\n * resulting `fileId` back via `onChange`. It never keeps a local blob store and\n * accepts any file type.\n */\n\n// initiateUpload returns a presigned PUT URL + the upload session id.\nconst INITIATE_UPLOAD = gql`\n mutation CosInitiateUpload($input: InitiateUploadInput!) {\n initiateUpload(input: $input) {\n session {\n id\n }\n uploadUrl\n }\n }\n`;\n\n// completeUpload finalizes the session and returns the committed File id.\nconst COMPLETE_UPLOAD = gql`\n mutation CosCompleteUpload($input: CompleteUploadInput!) {\n completeUpload(input: $input) {\n fileId\n file {\n id\n }\n }\n }\n`;\n\n// Presigned, time-limited download URL for a stored File — used to render a\n// \"Download\" affordance for an already-attached artifact.\nexport const GET_FILE_DOWNLOAD_URL = gql`\n query CosGetFileDownloadUrl($id: ID!, $expiresIn: Int) {\n getFileDownloadUrl(id: $id, expiresIn: $expiresIn)\n }\n`;\n\n// One hour — artifact links are resolved on demand when a detail page renders.\nconst DOWNLOAD_URL_TTL_SECONDS = 3_600;\n\ninterface InitiateUploadResponse {\n initiateUpload?: { session?: { id: string } | null; uploadUrl?: string | null } | null;\n}\n\ninterface CompleteUploadResponse {\n completeUpload?: { fileId?: string | null; file?: { id: string } | null } | null;\n}\n\ninterface DownloadUrlResponse {\n getFileDownloadUrl?: string | null;\n}\n\n/**\n * Resolve a presigned download URL for an attached File id. Skips when no id is\n * present. Detail pages use this to render a \"Download\" link for a dataset/\n * notebook/analysis artifact.\n */\nexport function useFileDownloadUrl(fileId: string | null | undefined) {\n return useQuery<DownloadUrlResponse, { id: string; expiresIn: number }>(GET_FILE_DOWNLOAD_URL, {\n variables: { id: fileId ?? '', expiresIn: DOWNLOAD_URL_TTL_SECONDS },\n skip: !fileId,\n fetchPolicy: 'no-cache',\n });\n}\n\nexport interface FileUploadFieldProps {\n /** Current attached wspace-files File id, if any. */\n value?: string | null;\n /** Called with the new File id once an upload completes, or '' when cleared. */\n onChange: (fileId: string) => void | Promise<void>;\n label: string;\n hint?: string;\n /** Optional wspace-files folder id; when omitted the file lands in the root. */\n folderId?: string;\n /** `accept` attribute for the file input; defaults to any file type. */\n accept?: string;\n disabled?: boolean;\n className?: string;\n}\n\nexport function FileUploadField({\n value,\n onChange,\n label,\n hint,\n folderId,\n accept,\n disabled = false,\n className,\n}: FileUploadFieldProps) {\n const tr = useTr();\n const client = useApolloClient();\n const inputRef = useRef<HTMLInputElement | null>(null);\n const inputId = useId();\n const [uploading, setUploading] = useState(false);\n const [fileName, setFileName] = useState<string | null>(null);\n\n const download = useFileDownloadUrl(uploading ? null : value);\n const downloadUrl = download.data?.getFileDownloadUrl ?? null;\n\n const handleSelect = async (event: React.ChangeEvent<HTMLInputElement>) => {\n const file = event.target.files?.[0];\n // Reset the input so selecting the same file again re-triggers change.\n event.target.value = '';\n if (!file) {\n return;\n }\n\n setUploading(true);\n try {\n const extension = file.name.includes('.')\n ? file.name.substring(file.name.lastIndexOf('.') + 1)\n : '';\n const mimeType = file.type || 'application/octet-stream';\n\n const initiate = await client.mutate<InitiateUploadResponse>({\n mutation: INITIATE_UPLOAD,\n variables: {\n input: {\n fileName: file.name,\n fileSize: String(file.size),\n extension,\n mimeType,\n ...(folderId ? { folderId } : {}),\n },\n },\n });\n const session = initiate.data?.initiateUpload?.session;\n const uploadUrl = initiate.data?.initiateUpload?.uploadUrl;\n if (!session || !uploadUrl) {\n throw new Error(\n initiate.error?.message ??\n tr('cosmicintersection.common.uploadStartError', 'Could not start the upload.')\n );\n }\n\n await new Promise<void>((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n xhr.addEventListener('load', () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n resolve();\n } else {\n reject(new Error(`Upload failed with status ${xhr.status}`));\n }\n });\n xhr.addEventListener('error', () => reject(new Error('Upload network error')));\n xhr.addEventListener('abort', () => reject(new Error('Upload aborted')));\n xhr.open('PUT', uploadUrl);\n xhr.setRequestHeader('Content-Type', mimeType);\n xhr.send(file);\n });\n\n const complete = await client.mutate<CompleteUploadResponse>({\n mutation: COMPLETE_UPLOAD,\n variables: {\n input: {\n sessionId: session.id,\n fileSize: String(file.size),\n ...(folderId ? { folderId } : {}),\n },\n },\n });\n const uploadedId =\n complete.data?.completeUpload?.fileId ?? complete.data?.completeUpload?.file?.id;\n if (!uploadedId) {\n throw new Error(\n complete.error?.message ??\n tr(\n 'cosmicintersection.common.uploadConfirmError',\n 'The file was uploaded but not confirmed.'\n )\n );\n }\n\n setFileName(file.name);\n await onChange(uploadedId);\n notify.success(tr('cosmicintersection.common.uploadSuccess', 'File uploaded'));\n } catch (error) {\n notify.error(\n tr('cosmicintersection.common.uploadFailed', 'Upload failed'),\n error instanceof Error\n ? error.message\n : tr('cosmicintersection.common.uploadTryAgain', 'Please try again.')\n );\n } finally {\n setUploading(false);\n }\n };\n\n const clear = async () => {\n setFileName(null);\n await onChange('');\n };\n\n return (\n <div className={className}>\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"flex size-12 shrink-0 items-center justify-center rounded-card border border-dashed border-border-default bg-bg-sunken text-text-secondary\">\n <Paperclip className=\"size-5\" aria-hidden=\"true\" />\n </div>\n <div className=\"space-y-1\">\n <div className=\"flex items-center gap-2\">\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"sm\"\n disabled={disabled || uploading}\n onClick={() => inputRef.current?.click()}\n >\n {uploading ? (\n <Loader2 className=\"size-4 animate-spin\" />\n ) : (\n <FileUp className=\"size-4\" />\n )}\n {uploading\n ? tr('cosmicintersection.common.uploading', 'Uploading…')\n : value\n ? tr('cosmicintersection.common.replaceFile', 'Replace file')\n : label}\n </Button>\n {value && !uploading ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => void clear()}\n disabled={disabled}\n >\n <X className=\"size-4\" />\n {tr('cosmicintersection.common.remove', 'Remove')}\n </Button>\n ) : null}\n </div>\n {value ? (\n <div className=\"flex flex-wrap items-center gap-2 text-xs text-text-secondary\">\n <span className=\"max-w-[16rem] truncate\">{fileName ?? `File ${value}`}</span>\n {downloadUrl ? (\n <a\n href={downloadUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 text-text-primary underline-offset-2 hover:underline\"\n >\n <Download className=\"size-3.5\" aria-hidden=\"true\" />\n {tr('cosmicintersection.common.download', 'Download')}\n </a>\n ) : null}\n </div>\n ) : hint ? (\n <p className=\"text-xs text-text-secondary\">{hint}</p>\n ) : null}\n </div>\n </div>\n <input\n ref={inputRef}\n id={inputId}\n type=\"file\"\n accept={accept}\n className=\"sr-only\"\n aria-label={label}\n onChange={(event) => void handleSelect(event)}\n />\n </div>\n );\n}\n\nexport default FileUploadField;\n"],"mappings":"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"}
|
|
@@ -59,6 +59,6 @@ export interface LineageGraphProps {
|
|
|
59
59
|
onNavigate?: (route: string) => void;
|
|
60
60
|
className?: string;
|
|
61
61
|
}
|
|
62
|
-
export declare function LineageGraph({ model, mode, onNavigate, className }: LineageGraphProps): import("react
|
|
62
|
+
export declare function LineageGraph({ model, mode, onNavigate, className }: LineageGraphProps): import("react").JSX.Element | null;
|
|
63
63
|
export default LineageGraph;
|
|
64
64
|
//# sourceMappingURL=LineageGraph.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LineageGraph.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/LineageGraph.tsx"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EACb,UAAU,EACV,WAAW,EACX,WAAW,EACX,cAAc,EACd,UAAU,EACV,SAAS,EACV,MAAM,kBAAkB,CAAC;AAO1B,MAAM,MAAM,eAAe,GACzB,QAAQ,GAAG,YAAY,GAAG,SAAS,GAAG,KAAK,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;AAEpF,MAAM,WAAW,WAAW;IAC1B,wDAAwD;IACxD,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,eAAe,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wFAAwF;IACxF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,kFAAkF;AAClF,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACtC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACpC;;;;OAIG;IACH,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC;IACjE,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CAC1C;AA+MD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,YAAY,CAS5F;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,YAAY,CAyC5F;AAsJD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,YAAY,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,IAAa,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"LineageGraph.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/LineageGraph.tsx"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EACb,UAAU,EACV,WAAW,EACX,WAAW,EACX,cAAc,EACd,UAAU,EACV,SAAS,EACV,MAAM,kBAAkB,CAAC;AAO1B,MAAM,MAAM,eAAe,GACzB,QAAQ,GAAG,YAAY,GAAG,SAAS,GAAG,KAAK,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;AAEpF,MAAM,WAAW,WAAW;IAC1B,wDAAwD;IACxD,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,eAAe,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wFAAwF;IACxF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,kFAAkF;AAClF,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACtC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACpC;;;;OAIG;IACH,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC;IACjE,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CAC1C;AA+MD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,YAAY,CAS5F;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,YAAY,CAyC5F;AAsJD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,YAAY,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,IAAa,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,iBAAiB,sCAsL9F;AAED,eAAe,YAAY,CAAC"}
|
|
@@ -10,6 +10,6 @@ export interface LoadingStateProps {
|
|
|
10
10
|
* Consistent loading affordance for every CosmicIntersection query surface.
|
|
11
11
|
* Token-styled only — no raw palette colours.
|
|
12
12
|
*/
|
|
13
|
-
export declare function LoadingState({ variant, rows, label: labelProp, className, }: LoadingStateProps): import("react
|
|
13
|
+
export declare function LoadingState({ variant, rows, label: labelProp, className, }: LoadingStateProps): import("react").JSX.Element;
|
|
14
14
|
export default LoadingState;
|
|
15
15
|
//# sourceMappingURL=LoadingState.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LoadingState.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/LoadingState.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,iBAAiB;IAChC,gFAAgF;IAChF,OAAO,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC7B,yDAAyD;IACzD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAC3B,OAAmB,EACnB,IAAQ,EACR,KAAK,EAAE,SAAS,EAChB,SAAS,GACV,EAAE,iBAAiB
|
|
1
|
+
{"version":3,"file":"LoadingState.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/LoadingState.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,iBAAiB;IAChC,gFAAgF;IAChF,OAAO,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC7B,yDAAyD;IACzD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAC3B,OAAmB,EACnB,IAAQ,EACR,KAAK,EAAE,SAAS,EAChB,SAAS,GACV,EAAE,iBAAiB,+BAuBnB;AAED,eAAe,YAAY,CAAC"}
|
|
@@ -13,6 +13,6 @@ interface PageLayoutProps {
|
|
|
13
13
|
* description, right-aligned actions) over a scrollable content region. Token
|
|
14
14
|
* styling only.
|
|
15
15
|
*/
|
|
16
|
-
export declare function PageLayout({ title, description, actions, children, backPath }: PageLayoutProps): import("react
|
|
16
|
+
export declare function PageLayout({ title, description, actions, children, backPath }: PageLayoutProps): import("react").JSX.Element;
|
|
17
17
|
export default PageLayout;
|
|
18
18
|
//# sourceMappingURL=PageLayout.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PageLayout.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/PageLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,UAAU,eAAe;IACvB,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE,SAAS,CAAC;IACpB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,eAAe
|
|
1
|
+
{"version":3,"file":"PageLayout.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/PageLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,UAAU,eAAe;IACvB,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE,SAAS,CAAC;IACpB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,eAAe,+BAmC9F;AAED,eAAe,UAAU,CAAC"}
|
|
@@ -27,6 +27,6 @@ export interface PaginationProps {
|
|
|
27
27
|
loading?: boolean;
|
|
28
28
|
className?: string;
|
|
29
29
|
}
|
|
30
|
-
export declare function Pagination({ offset, limit, loadedCount, hasMore, onPrev, onNext, itemLabel, loading, className, }: PaginationProps): import("react
|
|
30
|
+
export declare function Pagination({ offset, limit, loadedCount, hasMore, onPrev, onNext, itemLabel, loading, className, }: PaginationProps): import("react").JSX.Element | null;
|
|
31
31
|
export default Pagination;
|
|
32
32
|
//# sourceMappingURL=Pagination.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Pagination.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/Pagination.tsx"],"names":[],"mappings":"AAiBA,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,mBAAmB,CAsBrF;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,kFAAkF;IAClF,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,KAAK,EACL,WAAW,EACX,OAAO,EACP,MAAM,EACN,MAAM,EACN,SAAmB,EACnB,OAAe,EACf,SAAS,GACV,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"Pagination.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/Pagination.tsx"],"names":[],"mappings":"AAiBA,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,mBAAmB,CAsBrF;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,kFAAkF;IAClF,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,KAAK,EACL,WAAW,EACX,OAAO,EACP,MAAM,EACN,MAAM,EACN,SAAmB,EACnB,OAAe,EACf,SAAS,GACV,EAAE,eAAe,sCAqDjB;AAED,eAAe,UAAU,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Pagination.js","names":[],"sources":["../../../src/cosmicintersection/components/Pagination.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { useTr } from '../../shared/hooks/useTr';\n\n/**\n * Offset/limit pagination for the CosmicIntersection list surfaces.\n *\n * The Cos* connection resolvers return `{ items, pageInfo { hasMore, cursor } }`\n * with NO total count, so paging is driven by `offset`/`limit` + the boolean\n * `hasMore` rather than a computable page count. `usePagination` owns the window;\n * the page feeds `limit`/`offset` into `PaginationInput`, then renders\n * `<Pagination>` with `hasMore` so Next gates correctly.\n */\n\nconst DEFAULT_PAGE_SIZE = 50;\n\nexport interface UsePaginationOptions {\n pageSize?: number;\n /** When this changes (a filter/search term), the window resets to page 1. */\n resetKey?: unknown;\n}\n\nexport interface UsePaginationResult {\n limit: number;\n offset: number;\n /** 1-based page index derived from offset/limit. */\n page: number;\n nextPage: () => void;\n prevPage: () => void;\n reset: () => void;\n}\n\nexport function usePagination(options: UsePaginationOptions = {}): UsePaginationResult {\n const { pageSize = DEFAULT_PAGE_SIZE, resetKey } = options;\n const [offset, setOffset] = useState(0);\n\n // Reset to the first page whenever resetKey changes (React's documented\n // derive-state-during-render pattern — no extra effect/render pass).\n const [prevResetKey, setPrevResetKey] = useState(resetKey);\n if (prevResetKey !== resetKey) {\n setPrevResetKey(resetKey);\n if (offset !== 0) {\n setOffset(0);\n }\n }\n\n return {\n limit: pageSize,\n offset,\n page: Math.floor(offset / Math.max(1, pageSize)) + 1,\n nextPage: () => setOffset((current) => current + pageSize),\n prevPage: () => setOffset((current) => Math.max(0, current - pageSize)),\n reset: () => setOffset(0),\n };\n}\n\nexport interface PaginationProps {\n offset: number;\n limit: number;\n /** Number of rows returned for the current page (`items.length`). */\n loadedCount: number;\n /** Whether the backend reports more rows after this page (`pageInfo.hasMore`). */\n hasMore: boolean;\n onPrev: () => void;\n onNext: () => void;\n /** Plural noun for the range label, e.g. \"datasets\". Defaults to \"items\". */\n itemLabel?: string;\n loading?: boolean;\n className?: string;\n}\n\nexport function Pagination({\n offset,\n limit,\n loadedCount,\n hasMore,\n onPrev,\n onNext,\n itemLabel = 'items',\n loading = false,\n className,\n}: PaginationProps) {\n const tr = useTr();\n // Nothing to page through: first page and no more results.\n if (offset === 0 && !hasMore && loadedCount === 0) {\n return null;\n }\n\n const rangeStart = loadedCount === 0 ? 0 : offset + 1;\n const rangeEnd = offset + loadedCount;\n const canPrev = offset > 0;\n const canNext = hasMore;\n const page = Math.floor(offset / Math.max(1, limit)) + 1;\n\n return (\n <div\n className={`flex flex-wrap items-center justify-between gap-3 pt-4 ${className ?? ''}`}\n role=\"navigation\"\n aria-label=\"Pagination\"\n >\n <p className=\"text-xs tabular-nums text-text-secondary\">\n {tr('cosmicintersection.common.showingResults', 'Showing {{from}}–{{to}} {{itemLabel}}', {
|
|
1
|
+
{"version":3,"file":"Pagination.js","names":[],"sources":["../../../src/cosmicintersection/components/Pagination.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { useTr } from '../../shared/hooks/useTr';\n\n/**\n * Offset/limit pagination for the CosmicIntersection list surfaces.\n *\n * The Cos* connection resolvers return `{ items, pageInfo { hasMore, cursor } }`\n * with NO total count, so paging is driven by `offset`/`limit` + the boolean\n * `hasMore` rather than a computable page count. `usePagination` owns the window;\n * the page feeds `limit`/`offset` into `PaginationInput`, then renders\n * `<Pagination>` with `hasMore` so Next gates correctly.\n */\n\nconst DEFAULT_PAGE_SIZE = 50;\n\nexport interface UsePaginationOptions {\n pageSize?: number;\n /** When this changes (a filter/search term), the window resets to page 1. */\n resetKey?: unknown;\n}\n\nexport interface UsePaginationResult {\n limit: number;\n offset: number;\n /** 1-based page index derived from offset/limit. */\n page: number;\n nextPage: () => void;\n prevPage: () => void;\n reset: () => void;\n}\n\nexport function usePagination(options: UsePaginationOptions = {}): UsePaginationResult {\n const { pageSize = DEFAULT_PAGE_SIZE, resetKey } = options;\n const [offset, setOffset] = useState(0);\n\n // Reset to the first page whenever resetKey changes (React's documented\n // derive-state-during-render pattern — no extra effect/render pass).\n const [prevResetKey, setPrevResetKey] = useState(resetKey);\n if (prevResetKey !== resetKey) {\n setPrevResetKey(resetKey);\n if (offset !== 0) {\n setOffset(0);\n }\n }\n\n return {\n limit: pageSize,\n offset,\n page: Math.floor(offset / Math.max(1, pageSize)) + 1,\n nextPage: () => setOffset((current) => current + pageSize),\n prevPage: () => setOffset((current) => Math.max(0, current - pageSize)),\n reset: () => setOffset(0),\n };\n}\n\nexport interface PaginationProps {\n offset: number;\n limit: number;\n /** Number of rows returned for the current page (`items.length`). */\n loadedCount: number;\n /** Whether the backend reports more rows after this page (`pageInfo.hasMore`). */\n hasMore: boolean;\n onPrev: () => void;\n onNext: () => void;\n /** Plural noun for the range label, e.g. \"datasets\". Defaults to \"items\". */\n itemLabel?: string;\n loading?: boolean;\n className?: string;\n}\n\nexport function Pagination({\n offset,\n limit,\n loadedCount,\n hasMore,\n onPrev,\n onNext,\n itemLabel = 'items',\n loading = false,\n className,\n}: PaginationProps) {\n const tr = useTr();\n // Nothing to page through: first page and no more results.\n if (offset === 0 && !hasMore && loadedCount === 0) {\n return null;\n }\n\n const rangeStart = loadedCount === 0 ? 0 : offset + 1;\n const rangeEnd = offset + loadedCount;\n const canPrev = offset > 0;\n const canNext = hasMore;\n const page = Math.floor(offset / Math.max(1, limit)) + 1;\n\n return (\n <div\n className={`flex flex-wrap items-center justify-between gap-3 pt-4 ${className ?? ''}`}\n role=\"navigation\"\n aria-label=\"Pagination\"\n >\n <p className=\"text-xs tabular-nums text-text-secondary\">\n {tr('cosmicintersection.common.showingResults', 'Showing {{from}}–{{to}} {{itemLabel}}', {\n from: rangeStart,\n to: rangeEnd,\n itemLabel,\n })}\n </p>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs tabular-nums text-text-secondary\">\n {tr('cosmicintersection.common.page', 'Page')} {page}\n </span>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={onPrev}\n disabled={!canPrev || loading}\n aria-label={tr('cosmicintersection.common.prev', 'Previous page')}\n >\n <ChevronLeft className=\"size-4\" />\n {tr('cosmicintersection.common.prev', 'Prev')}\n </Button>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={onNext}\n disabled={!canNext || loading}\n aria-label={tr('cosmicintersection.common.next', 'Next page')}\n >\n {tr('cosmicintersection.common.next', 'Next')}\n <ChevronRight className=\"size-4\" />\n </Button>\n </div>\n </div>\n );\n}\n\nexport default Pagination;\n"],"mappings":";;;;;;AAeA,IAAM,IAAoB;AAkB1B,SAAgB,EAAc,IAAgC,CAAC,GAAwB;CACrF,IAAM,EAAE,cAAW,GAAmB,gBAAa,GAC7C,CAAC,GAAQ,KAAa,EAAS,CAAC,GAIhC,CAAC,GAAc,KAAmB,EAAS,CAAQ;CAQzD,OAPI,MAAiB,MACnB,EAAgB,CAAQ,GACpB,MAAW,KACb,EAAU,CAAC,IAIR;EACL,OAAO;EACP;EACA,MAAM,KAAK,MAAM,IAAS,KAAK,IAAI,GAAG,CAAQ,CAAC,IAAI;EACnD,gBAAgB,GAAW,MAAY,IAAU,CAAQ;EACzD,gBAAgB,GAAW,MAAY,KAAK,IAAI,GAAG,IAAU,CAAQ,CAAC;EACtE,aAAa,EAAU,CAAC;CAC1B;AACF;AAiBA,SAAgB,EAAW,EACzB,WACA,UACA,gBACA,YACA,WACA,WACA,eAAY,SACZ,aAAU,IACV,gBACkB;CAClB,IAAM,IAAK,EAAM;CAEjB,IAAI,MAAW,KAAK,CAAC,KAAW,MAAgB,GAC9C,OAAO;CAGT,IAAM,IAAa,MAAgB,IAAI,IAAI,IAAS,GAC9C,IAAW,IAAS,GACpB,IAAU,IAAS,GACnB,IAAU,GACV,IAAO,KAAK,MAAM,IAAS,KAAK,IAAI,GAAG,CAAK,CAAC,IAAI;CAEvD,OACE,kBAAC,OAAD;EACE,WAAW,0DAA0D,KAAa;EAClF,MAAK;EACL,cAAW;YAHb,CAKE,kBAAC,KAAD;GAAG,WAAU;aACV,EAAG,4CAA4C,yCAAyC;IACvF,MAAM;IACN,IAAI;IACJ;GACF,CAAC;EACA,CAAA,GACH,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,QAAD;KAAM,WAAU;eAAhB;MACG,EAAG,kCAAkC,MAAM;MAAE;MAAE;KAC5C;;IACN,kBAAC,GAAD;KACE,MAAK;KACL,SAAQ;KACR,SAAS;KACT,UAAU,CAAC,KAAW;KACtB,cAAY,EAAG,kCAAkC,eAAe;eALlE,CAOE,kBAAC,GAAD,EAAa,WAAU,SAAU,CAAA,GAChC,EAAG,kCAAkC,MAAM,CACtC;;IACR,kBAAC,GAAD;KACE,MAAK;KACL,SAAQ;KACR,SAAS;KACT,UAAU,CAAC,KAAW;KACtB,cAAY,EAAG,kCAAkC,WAAW;eAL9D,CAOG,EAAG,kCAAkC,MAAM,GAC5C,kBAAC,GAAD,EAAc,WAAU,SAAU,CAAA,CAC5B;;GACL;IACF;;AAET"}
|
|
@@ -2,6 +2,6 @@ export interface ResultsChartProps {
|
|
|
2
2
|
results: Record<string, unknown>;
|
|
3
3
|
className?: string;
|
|
4
4
|
}
|
|
5
|
-
export declare function ResultsChart({ results, className }: ResultsChartProps): import("react
|
|
5
|
+
export declare function ResultsChart({ results, className }: ResultsChartProps): import("react").JSX.Element;
|
|
6
6
|
export default ResultsChart;
|
|
7
7
|
//# sourceMappingURL=ResultsChart.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResultsChart.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/ResultsChart.tsx"],"names":[],"mappings":"AA8YA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,iBAAiB
|
|
1
|
+
{"version":3,"file":"ResultsChart.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/ResultsChart.tsx"],"names":[],"mappings":"AA8YA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,iBAAiB,+BAiLrE;AAED,eAAe,YAAY,CAAC"}
|
|
@@ -30,6 +30,6 @@ export interface SafeLinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorEleme
|
|
|
30
30
|
* can never be activated. External links open in a new tab with
|
|
31
31
|
* `noopener noreferrer`; root-relative in-app links open in the same tab.
|
|
32
32
|
*/
|
|
33
|
-
export declare function SafeLink({ href, children, className, fallbackClassName, ...rest }: SafeLinkProps): import("react
|
|
33
|
+
export declare function SafeLink({ href, children, className, fallbackClassName, ...rest }: SafeLinkProps): import("react").JSX.Element;
|
|
34
34
|
export default SafeLink;
|
|
35
35
|
//# sourceMappingURL=SafeLink.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SafeLink.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/SafeLink.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE7D;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CA0BrE;AAED,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC1F,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,6EAA6E;IAC7E,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,iBAAiB,EAAE,GAAG,IAAI,EAAE,EAAE,aAAa
|
|
1
|
+
{"version":3,"file":"SafeLink.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/SafeLink.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE7D;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CA0BrE;AAED,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC1F,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,6EAA6E;IAC7E,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,iBAAiB,EAAE,GAAG,IAAI,EAAE,EAAE,aAAa,+BAmBhG;AAED,eAAe,QAAQ,CAAC"}
|
|
@@ -18,6 +18,6 @@ export interface StatusBadgeProps {
|
|
|
18
18
|
label?: string;
|
|
19
19
|
className?: string;
|
|
20
20
|
}
|
|
21
|
-
export declare function StatusBadge({ status, tone, label, className }: StatusBadgeProps): import("react
|
|
21
|
+
export declare function StatusBadge({ status, tone, label, className }: StatusBadgeProps): import("react").JSX.Element;
|
|
22
22
|
export default StatusBadge;
|
|
23
23
|
//# sourceMappingURL=StatusBadge.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StatusBadge.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/StatusBadge.tsx"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAiD9E,oFAAoF;AACpF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGrD;AAuBD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,qFAAqF;IACrF,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,WAAW,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,gBAAgB
|
|
1
|
+
{"version":3,"file":"StatusBadge.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/StatusBadge.tsx"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAiD9E,oFAAoF;AACpF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGrD;AAuBD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,qFAAqF;IACrF,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,WAAW,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,gBAAgB,+BAc/E;AAED,eAAe,WAAW,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StatusBadge.js","names":[],"sources":["../../../src/cosmicintersection/components/StatusBadge.tsx"],"sourcesContent":["import { useTr } from '../../shared/hooks/useTr';\n\n/**\n * StatusBadge — maps the Cos* enum values to the semantic status token families.\n *\n * One badge component covers every CosmicIntersection enum (dataset/source/\n * pipeline/run/step/notebook/analysis/release/grant status, plus access level).\n * Colour comes only from the `status-{success,info,warning,error,neutral}`\n * token families — never a raw palette colour — so it renders correctly in every\n * theme.\n */\n\nexport type StatusTone = 'success' | 'info' | 'warning' | 'error' | 'neutral';\n\nconst TONE_CLASS: Record<StatusTone, string> = {\n success: 'bg-status-success-bg-subtle text-status-success-text border-status-success-border',\n info: 'bg-status-info-bg-subtle text-status-info-text border-status-info-border',\n warning: 'bg-status-warning-bg-subtle text-status-warning-text border-status-warning-border',\n error: 'bg-status-error-bg-subtle text-status-error-text border-status-error-border',\n neutral: 'bg-status-neutral-bg-subtle text-status-neutral-text border-status-neutral-border',\n};\n\n// Every Cos* enum value → tone. Values are unique enough across enums that a\n// single map is unambiguous; unknown values fall back to neutral.\nconst STATUS_TONE: Record<string, StatusTone> = {\n // healthy / terminal-good\n AVAILABLE: 'success',\n CONNECTED: 'success',\n SUCCEEDED: 'success',\n COMPLETED: 'success',\n PUBLISHED: 'success',\n ACTIVE: 'success',\n PUBLIC: 'success',\n // in-flight / attention\n INGESTING: 'warning',\n SYNCING: 'warning',\n RUNNING: 'warning',\n DEGRADED: 'warning',\n PAUSED: 'warning',\n DEPRECATED: 'warning',\n EXPIRED: 'warning',\n EMBARGOED: 'warning',\n RESTRICTED: 'warning',\n UNDER_REVIEW: 'warning',\n // queued / neutral-info\n DRAFT: 'info',\n CONFIGURING: 'info',\n QUEUED: 'info',\n PENDING: 'info',\n WORKSPACE: 'info',\n // failed / removed\n ERROR: 'error',\n FAILED: 'error',\n CANCELLED: 'error',\n RETRACTED: 'error',\n REVOKED: 'error',\n DISABLED: 'error',\n // archived / inert\n ARCHIVED: 'neutral',\n};\n\n/** Turn an ENUM_VALUE into a human label, e.g. GROUND_SENSOR -> \"Ground sensor\". */\nexport function formatEnumLabel(value: string): string {\n const lower = value.replace(/_/g, ' ').toLowerCase();\n return lower.charAt(0).toUpperCase() + lower.slice(1);\n}\n\n/** Known Cos* enum values → translation keys under `cosmicintersection.status`. */\nconst STATUS_LABEL_KEYS: Record<string, string> = {\n DRAFT: 'cosmicintersection.status.draft',\n ACTIVE: 'cosmicintersection.status.active',\n ARCHIVED: 'cosmicintersection.status.archived',\n ERROR: 'cosmicintersection.status.error',\n PENDING: 'cosmicintersection.status.pending',\n RUNNING: 'cosmicintersection.status.running',\n SUCCEEDED: 'cosmicintersection.status.succeeded',\n COMPLETED: 'cosmicintersection.status.succeeded',\n PUBLISHED: 'cosmicintersection.status.succeeded',\n FAILED: 'cosmicintersection.status.failed',\n CANCELLED: 'cosmicintersection.status.cancelled',\n PAUSED: 'cosmicintersection.status.paused',\n DISABLED: 'cosmicintersection.status.disabled',\n ENABLED: 'cosmicintersection.status.enabled',\n PUBLIC: 'cosmicintersection.status.public',\n PRIVATE: 'cosmicintersection.status.private',\n RESTRICTED: 'cosmicintersection.status.restricted',\n};\n\nexport interface StatusBadgeProps {\n status: string;\n /** Override the derived tone (e.g. to force a colour for a domain-specific case). */\n tone?: StatusTone;\n /** Override the rendered label; defaults to a title-cased enum value. */\n label?: string;\n className?: string;\n}\n\nexport function StatusBadge({ status, tone, label, className }: StatusBadgeProps) {\n const tr = useTr();\n const resolvedTone: StatusTone = tone ?? STATUS_TONE[status] ?? 'neutral';\n const fallbackLabel = formatEnumLabel(status);\n const translatedLabel
|
|
1
|
+
{"version":3,"file":"StatusBadge.js","names":[],"sources":["../../../src/cosmicintersection/components/StatusBadge.tsx"],"sourcesContent":["import { useTr } from '../../shared/hooks/useTr';\n\n/**\n * StatusBadge — maps the Cos* enum values to the semantic status token families.\n *\n * One badge component covers every CosmicIntersection enum (dataset/source/\n * pipeline/run/step/notebook/analysis/release/grant status, plus access level).\n * Colour comes only from the `status-{success,info,warning,error,neutral}`\n * token families — never a raw palette colour — so it renders correctly in every\n * theme.\n */\n\nexport type StatusTone = 'success' | 'info' | 'warning' | 'error' | 'neutral';\n\nconst TONE_CLASS: Record<StatusTone, string> = {\n success: 'bg-status-success-bg-subtle text-status-success-text border-status-success-border',\n info: 'bg-status-info-bg-subtle text-status-info-text border-status-info-border',\n warning: 'bg-status-warning-bg-subtle text-status-warning-text border-status-warning-border',\n error: 'bg-status-error-bg-subtle text-status-error-text border-status-error-border',\n neutral: 'bg-status-neutral-bg-subtle text-status-neutral-text border-status-neutral-border',\n};\n\n// Every Cos* enum value → tone. Values are unique enough across enums that a\n// single map is unambiguous; unknown values fall back to neutral.\nconst STATUS_TONE: Record<string, StatusTone> = {\n // healthy / terminal-good\n AVAILABLE: 'success',\n CONNECTED: 'success',\n SUCCEEDED: 'success',\n COMPLETED: 'success',\n PUBLISHED: 'success',\n ACTIVE: 'success',\n PUBLIC: 'success',\n // in-flight / attention\n INGESTING: 'warning',\n SYNCING: 'warning',\n RUNNING: 'warning',\n DEGRADED: 'warning',\n PAUSED: 'warning',\n DEPRECATED: 'warning',\n EXPIRED: 'warning',\n EMBARGOED: 'warning',\n RESTRICTED: 'warning',\n UNDER_REVIEW: 'warning',\n // queued / neutral-info\n DRAFT: 'info',\n CONFIGURING: 'info',\n QUEUED: 'info',\n PENDING: 'info',\n WORKSPACE: 'info',\n // failed / removed\n ERROR: 'error',\n FAILED: 'error',\n CANCELLED: 'error',\n RETRACTED: 'error',\n REVOKED: 'error',\n DISABLED: 'error',\n // archived / inert\n ARCHIVED: 'neutral',\n};\n\n/** Turn an ENUM_VALUE into a human label, e.g. GROUND_SENSOR -> \"Ground sensor\". */\nexport function formatEnumLabel(value: string): string {\n const lower = value.replace(/_/g, ' ').toLowerCase();\n return lower.charAt(0).toUpperCase() + lower.slice(1);\n}\n\n/** Known Cos* enum values → translation keys under `cosmicintersection.status`. */\nconst STATUS_LABEL_KEYS: Record<string, string> = {\n DRAFT: 'cosmicintersection.status.draft',\n ACTIVE: 'cosmicintersection.status.active',\n ARCHIVED: 'cosmicintersection.status.archived',\n ERROR: 'cosmicintersection.status.error',\n PENDING: 'cosmicintersection.status.pending',\n RUNNING: 'cosmicintersection.status.running',\n SUCCEEDED: 'cosmicintersection.status.succeeded',\n COMPLETED: 'cosmicintersection.status.succeeded',\n PUBLISHED: 'cosmicintersection.status.succeeded',\n FAILED: 'cosmicintersection.status.failed',\n CANCELLED: 'cosmicintersection.status.cancelled',\n PAUSED: 'cosmicintersection.status.paused',\n DISABLED: 'cosmicintersection.status.disabled',\n ENABLED: 'cosmicintersection.status.enabled',\n PUBLIC: 'cosmicintersection.status.public',\n PRIVATE: 'cosmicintersection.status.private',\n RESTRICTED: 'cosmicintersection.status.restricted',\n};\n\nexport interface StatusBadgeProps {\n status: string;\n /** Override the derived tone (e.g. to force a colour for a domain-specific case). */\n tone?: StatusTone;\n /** Override the rendered label; defaults to a title-cased enum value. */\n label?: string;\n className?: string;\n}\n\nexport function StatusBadge({ status, tone, label, className }: StatusBadgeProps) {\n const tr = useTr();\n const resolvedTone: StatusTone = tone ?? STATUS_TONE[status] ?? 'neutral';\n const fallbackLabel = formatEnumLabel(status);\n const translatedLabel =\n label ??\n (STATUS_LABEL_KEYS[status] ? tr(STATUS_LABEL_KEYS[status], fallbackLabel) : fallbackLabel);\n return (\n <span\n className={`inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-xs font-medium ${TONE_CLASS[resolvedTone]} ${className ?? ''}`}\n >\n {translatedLabel}\n </span>\n );\n}\n\nexport default StatusBadge;\n"],"mappings":";;;AAcA,IAAM,IAAyC;CAC7C,SAAS;CACT,MAAM;CACN,SAAS;CACT,OAAO;CACP,SAAS;AACX,GAIM,IAA0C;CAE9C,WAAW;CACX,WAAW;CACX,WAAW;CACX,WAAW;CACX,WAAW;CACX,QAAQ;CACR,QAAQ;CAER,WAAW;CACX,SAAS;CACT,SAAS;CACT,UAAU;CACV,QAAQ;CACR,YAAY;CACZ,SAAS;CACT,WAAW;CACX,YAAY;CACZ,cAAc;CAEd,OAAO;CACP,aAAa;CACb,QAAQ;CACR,SAAS;CACT,WAAW;CAEX,OAAO;CACP,QAAQ;CACR,WAAW;CACX,WAAW;CACX,SAAS;CACT,UAAU;CAEV,UAAU;AACZ;AAGA,SAAgB,EAAgB,GAAuB;CACrD,IAAM,IAAQ,EAAM,QAAQ,MAAM,GAAG,EAAE,YAAY;CACnD,OAAO,EAAM,OAAO,CAAC,EAAE,YAAY,IAAI,EAAM,MAAM,CAAC;AACtD;AAGA,IAAM,IAA4C;CAChD,OAAO;CACP,QAAQ;CACR,UAAU;CACV,OAAO;CACP,SAAS;CACT,SAAS;CACT,WAAW;CACX,WAAW;CACX,WAAW;CACX,QAAQ;CACR,WAAW;CACX,QAAQ;CACR,UAAU;CACV,SAAS;CACT,QAAQ;CACR,SAAS;CACT,YAAY;AACd;AAWA,SAAgB,EAAY,EAAE,WAAQ,SAAM,UAAO,gBAA+B;CAChF,IAAM,IAAK,EAAM,GACX,IAA2B,KAAQ,EAAY,MAAW,WAC1D,IAAgB,EAAgB,CAAM,GACtC,IACJ,MACC,EAAkB,KAAU,EAAG,EAAkB,IAAS,CAAa,IAAI;CAC9E,OACE,kBAAC,QAAD;EACE,WAAW,sFAAsF,EAAW,GAAc,GAAG,KAAa;YAEzI;CACG,CAAA;AAEV"}
|
|
@@ -15,6 +15,6 @@ export interface StepDAGProps {
|
|
|
15
15
|
* Horizontal (md+) / vertical (mobile) step-flow diagram. Presentational only —
|
|
16
16
|
* callers decide where the step list comes from (pipeline definition or a run).
|
|
17
17
|
*/
|
|
18
|
-
export declare function StepDAG({ steps, className }: StepDAGProps): import("react
|
|
18
|
+
export declare function StepDAG({ steps, className }: StepDAGProps): import("react").JSX.Element | null;
|
|
19
19
|
export default StepDAG;
|
|
20
20
|
//# sourceMappingURL=StepDAG.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StepDAG.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/StepDAG.tsx"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGlE,MAAM,WAAW,WAAW;IAC1B,qFAAqF;IACrF,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,EAAE,WAAW,CAAC;IAClB,yDAAyD;IACzD,MAAM,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAoHD;;;GAGG;AACH,wBAAgB,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"StepDAG.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/components/StepDAG.tsx"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGlE,MAAM,WAAW,WAAW;IAC1B,qFAAqF;IACrF,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,EAAE,WAAW,CAAC;IAClB,yDAAyD;IACzD,MAAM,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAoHD;;;GAGG;AACH,wBAAgB,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,YAAY,sCAkBzD;AAED,eAAe,OAAO,CAAC"}
|
|
@@ -14,7 +14,7 @@ interface CosmicIntersectionProviderProps {
|
|
|
14
14
|
children: ReactNode;
|
|
15
15
|
props: CosmicIntersectionRootProps;
|
|
16
16
|
}
|
|
17
|
-
export declare function CosmicIntersectionProvider({ children, props }: CosmicIntersectionProviderProps): import("react
|
|
17
|
+
export declare function CosmicIntersectionProvider({ children, props }: CosmicIntersectionProviderProps): import("react").JSX.Element;
|
|
18
18
|
export declare function useCosmicIntersection(): CosmicIntersectionContextValue;
|
|
19
19
|
/**
|
|
20
20
|
* Hook for basePath-aware navigation. Returns a navigate function that
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CosmicIntersectionContext.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/context/CosmicIntersectionContext.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAmD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACxF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAC;AAE5D,UAAU,8BAA8B;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,WAAW,EAAE,2BAA2B,CAAC,aAAa,CAAC,CAAC;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,UAAU,+BAA+B;IACvC,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,EAAE,2BAA2B,CAAC;CACpC;AAED,wBAAgB,0BAA0B,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,+BAA+B
|
|
1
|
+
{"version":3,"file":"CosmicIntersectionContext.d.ts","sourceRoot":"","sources":["../../../src/cosmicintersection/context/CosmicIntersectionContext.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAmD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACxF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAC;AAE5D,UAAU,8BAA8B;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,WAAW,EAAE,2BAA2B,CAAC,aAAa,CAAC,CAAC;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,UAAU,+BAA+B;IACvC,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,EAAE,2BAA2B,CAAC;CACpC;AAED,wBAAgB,0BAA0B,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,+BAA+B,+BAmD9F;AAED,wBAAgB,qBAAqB,mCAMpC;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,WAjF1B,MAAM,KAAK,IAAI,CAiGjC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export default function AccessPage(): import("react
|
|
1
|
+
export default function AccessPage(): import("react").JSX.Element;
|
|
2
2
|
//# sourceMappingURL=AccessPage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AccessPage.d.ts","sourceRoot":"","sources":["../../../../src/cosmicintersection/pages/access/AccessPage.tsx"],"names":[],"mappings":"AAoFA,MAAM,CAAC,OAAO,UAAU,UAAU,
|
|
1
|
+
{"version":3,"file":"AccessPage.d.ts","sourceRoot":"","sources":["../../../../src/cosmicintersection/pages/access/AccessPage.tsx"],"names":[],"mappings":"AAoFA,MAAM,CAAC,OAAO,UAAU,UAAU,gCA0ejC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AccessPage.js","names":[],"sources":["../../../../src/cosmicintersection/pages/access/AccessPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { KeyRound, ShieldCheck } from 'lucide-react';\nimport {\n Badge,\n Button,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Input,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\n\nimport {\n useCosAccessGrantsQuery,\n useCosDatasetsQuery,\n useCosGrantAccessMutation,\n useCosRevokeAccessMutation,\n type CosDataAccessGrant,\n type CosGrantAccessInput,\n type CosGrantStatus,\n} from '../../api/cosmicApi';\nimport {\n EmptyState,\n ErrorState,\n LoadingState,\n PageLayout,\n StatusBadge,\n formatEnumLabel,\n} from '../../components';\nimport { ActionMenu } from '../../components/ActionMenu';\nimport { EntityTagsField } from '../../components/EntityTagsField';\nimport { notify } from '../../lib/toast';\nimport { useTr } from '../../../shared/hooks/useTr';\n\nconst ALL = 'ALL';\nconst GRANT_STATUSES: CosGrantStatus[] = ['PENDING', 'ACTIVE', 'EXPIRED', 'REVOKED'];\n\n/** Only live grants can be revoked. */\nfunction canRevoke(status: CosGrantStatus): boolean {\n return status === 'ACTIVE' || status === 'PENDING';\n}\n\nfunction formatDate(value?: string | null): string {\n if (!value) {\n return '—';\n }\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return '—';\n }\n return parsed.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });\n}\n\ninterface GrantFormState {\n datasetId: string;\n granteeId: string;\n scopes: string[];\n reason: string;\n expiresAt: string;\n}\n\nconst EMPTY_FORM: GrantFormState = {\n datasetId: '',\n granteeId: '',\n scopes: [],\n reason: '',\n expiresAt: '',\n};\n\nexport default function AccessPage() {\n const tr = useTr();\n const [datasetFilter, setDatasetFilter] = useState<string>(ALL);\n const [statusFilter, setStatusFilter] = useState<string>(ALL);\n\n const datasetsQuery = useCosDatasetsQuery({ pagination: { limit: 50, offset: 0 } });\n const datasets = useMemo(\n () => datasetsQuery.data?.cosListDatasets.items ?? [],\n [datasetsQuery.data]\n );\n const datasetName = useMemo(() => {\n const map = new Map<string, string>();\n for (const dataset of datasets) {\n map.set(dataset.id, dataset.name);\n }\n return map;\n }, [datasets]);\n\n const { data, loading, error, refetch } = useCosAccessGrantsQuery({\n datasetId: datasetFilter === ALL ? undefined : datasetFilter,\n status: statusFilter === ALL ? undefined : (statusFilter as CosGrantStatus),\n });\n const grants = useMemo(() => data?.cosListAccessGrants ?? [], [data]);\n\n const [grantAccess, { loading: granting }] = useCosGrantAccessMutation();\n const [revokeAccess] = useCosRevokeAccessMutation();\n\n const [dialogOpen, setDialogOpen] = useState(false);\n const [form, setForm] = useState<GrantFormState>(EMPTY_FORM);\n\n const openGrantDialog = () => {\n setForm({\n ...EMPTY_FORM,\n datasetId: datasetFilter === ALL ? '' : datasetFilter,\n });\n setDialogOpen(true);\n };\n\n const setField = <K extends keyof GrantFormState>(field: K, value: GrantFormState[K]) => {\n setForm((prev) => ({ ...prev, [field]: value }));\n };\n\n const submitGrant = async () => {\n if (!form.datasetId) {\n notify.error(\n tr('cosmicintersection.pages.access.datasetRequired', 'Dataset is required'),\n tr(\n 'cosmicintersection.pages.access.datasetRequiredDescription',\n 'Choose which dataset this grant applies to.',\n ),\n );\n return;\n }\n if (!form.granteeId.trim()) {\n notify.error(\n tr('cosmicintersection.pages.access.granteeRequired', 'Grantee is required'),\n tr(\n 'cosmicintersection.pages.access.granteeRequiredDescription',\n 'Enter the workspace User ID to grant access to.',\n ),\n );\n return;\n }\n\n let expiresAt: string | undefined;\n if (form.expiresAt) {\n const parsed = new Date(form.expiresAt);\n if (Number.isNaN(parsed.getTime())) {\n notify.error(\n tr('cosmicintersection.pages.access.invalidExpiry', 'Invalid expiry'),\n tr(\n 'cosmicintersection.pages.access.invalidExpiryDescription',\n 'Enter a valid expiry date or leave it blank.',\n ),\n );\n return;\n }\n expiresAt = parsed.toISOString();\n }\n\n const input: CosGrantAccessInput = {\n datasetId: form.datasetId,\n granteeId: form.granteeId.trim(),\n scopes: form.scopes.length ? form.scopes : undefined,\n reason: form.reason.trim() || undefined,\n expiresAt,\n };\n\n const response = await grantAccess({ variables: { input } });\n if (response.data?.cosGrantAccess?.id) {\n notify.success(tr('cosmicintersection.pages.access.accessGranted', 'Access granted'));\n setDialogOpen(false);\n setForm(EMPTY_FORM);\n await refetch();\n }\n };\n\n const handleRevoke = async (grant: CosDataAccessGrant) => {\n const response = await revokeAccess({ variables: { id: grant.id } });\n if (response.error) {\n throw new Error(response.error.message);\n }\n if (!response.data?.cosRevokeAccess?.id) {\n notify.error(\n tr('cosmicintersection.pages.access.revokeError', 'Could not revoke grant'),\n tr(\n 'cosmicintersection.pages.access.revokeErrorDescription',\n 'The server did not confirm the change.',\n ),\n );\n throw new Error('Revoke not confirmed');\n }\n notify.success(tr('cosmicintersection.pages.access.accessRevoked', 'Access revoked'));\n await refetch();\n };\n\n const grantButton = (\n <Button type=\"button\" onClick={openGrantDialog}>\n <KeyRound className=\"size-4\" />\n {tr('cosmicintersection.pages.access.grantAccess', 'Grant access')}\n </Button>\n );\n\n const showDatasetColumn = datasetFilter === ALL;\n\n const renderBody = () => {\n if (loading) {\n return (\n <LoadingState\n variant=\"rows\"\n rows={6}\n label={tr('cosmicintersection.pages.access.loading', 'Loading access grants…')}\n />\n );\n }\n if (error) {\n return <ErrorState message={error.message} onRetry={() => void refetch()} />;\n }\n if (grants.length === 0) {\n const filtered = datasetFilter !== ALL || statusFilter !== ALL;\n return (\n <EmptyState\n icon={ShieldCheck}\n title={\n filtered\n ? tr(\n 'cosmicintersection.pages.access.emptyFilterTitle',\n 'No grants match these filters',\n )\n : tr('cosmicintersection.pages.access.emptyTitle', 'No access grants yet')\n }\n description={\n filtered\n ? tr(\n 'cosmicintersection.pages.access.emptyFilterDescription',\n 'Try clearing the dataset or status filter to see more grants.',\n )\n : tr(\n 'cosmicintersection.pages.access.emptyDescription',\n 'Grant a workspace member scoped access to a restricted or embargoed dataset.',\n )\n }\n action={filtered ? undefined : grantButton}\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 {showDatasetColumn ? <TableHead>Dataset</TableHead> : null}\n <TableHead>Grantee</TableHead>\n <TableHead>Status</TableHead>\n <TableHead>Scopes</TableHead>\n <TableHead>Reason</TableHead>\n <TableHead>Granted</TableHead>\n <TableHead>Expires</TableHead>\n <TableHead>Revoked</TableHead>\n <TableHead className=\"text-right\">Actions</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {grants.map((grant) => (\n <TableRow key={grant.id}>\n {showDatasetColumn ? (\n <TableCell className=\"max-w-[12rem]\">\n <span className=\"line-clamp-1 text-sm text-text-primary\">\n {datasetName.get(grant.datasetId) ?? (\n <span className=\"font-mono text-xs text-text-secondary\">\n {grant.datasetId}\n </span>\n )}\n </span>\n </TableCell>\n ) : null}\n <TableCell className=\"max-w-[12rem]\">\n <span className=\"block truncate font-mono text-xs text-text-primary\">\n {grant.granteeId}\n </span>\n </TableCell>\n <TableCell>\n <StatusBadge status={grant.status} />\n </TableCell>\n <TableCell>\n <div className=\"flex max-w-[12rem] flex-wrap gap-1\">\n {grant.scopes.length === 0 ? (\n <span className=\"text-xs text-text-secondary\">—</span>\n ) : (\n grant.scopes.map((scope) => (\n <Badge key={scope} variant=\"outline\" className=\"text-xs\">\n {scope}\n </Badge>\n ))\n )}\n </div>\n </TableCell>\n <TableCell className=\"max-w-[14rem]\">\n {grant.reason ? (\n <span className=\"line-clamp-1 text-sm text-text-secondary\">\n {grant.reason}\n </span>\n ) : (\n <span className=\"text-sm text-text-secondary\">—</span>\n )}\n </TableCell>\n <TableCell className=\"whitespace-nowrap text-sm text-text-secondary\">\n {formatDate(grant.grantedAt)}\n </TableCell>\n <TableCell className=\"whitespace-nowrap text-sm text-text-secondary\">\n {formatDate(grant.expiresAt)}\n </TableCell>\n <TableCell className=\"whitespace-nowrap text-sm text-text-secondary\">\n {formatDate(grant.revokedAt)}\n </TableCell>\n <TableCell className=\"text-right\">\n {canRevoke(grant.status) ? (\n <ActionMenu\n ariaLabel={`Actions for grant to ${grant.granteeId}`}\n entityName={grant.granteeId}\n onDelete={() => handleRevoke(grant)}\n deleteLabel=\"Revoke grant\"\n />\n ) : (\n <span className=\"text-xs text-text-secondary\">—</span>\n )}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n\n {/* Mobile card list */}\n <ul className=\"space-y-3 md:hidden\">\n {grants.map((grant) => (\n <li key={grant.id} className=\"rounded-card border border-border-default bg-bg-elevated\">\n <div className=\"flex items-start justify-between gap-2 p-4\">\n <div className=\"min-w-0 flex-1 space-y-2\">\n <div className=\"flex flex-wrap items-center gap-2\">\n {showDatasetColumn ? (\n <span className=\"truncate text-sm font-medium text-text-primary\">\n {datasetName.get(grant.datasetId) ?? 'Dataset'}\n </span>\n ) : null}\n <StatusBadge status={grant.status} />\n </div>\n\n <div>\n <p className=\"text-xs text-text-secondary\">Grantee (User ID)</p>\n <p className=\"truncate font-mono text-xs text-text-primary\">\n {grant.granteeId}\n </p>\n </div>\n\n {grant.scopes.length > 0 ? (\n <div className=\"flex flex-wrap gap-1\">\n {grant.scopes.map((scope) => (\n <Badge key={scope} variant=\"outline\" className=\"text-xs\">\n {scope}\n </Badge>\n ))}\n </div>\n ) : null}\n\n {grant.reason ? (\n <p className=\"line-clamp-2 text-xs text-text-secondary\">{grant.reason}</p>\n ) : null}\n\n <div className=\"flex flex-wrap gap-x-3 gap-y-1 text-xs text-text-secondary\">\n <span>Granted {formatDate(grant.grantedAt)}</span>\n <span>Expires {formatDate(grant.expiresAt)}</span>\n {grant.revokedAt ? <span>Revoked {formatDate(grant.revokedAt)}</span> : null}\n </div>\n </div>\n\n {canRevoke(grant.status) ? (\n <ActionMenu\n ariaLabel={`Actions for grant to ${grant.granteeId}`}\n entityName={grant.granteeId}\n onDelete={() => handleRevoke(grant)}\n deleteLabel=\"Revoke grant\"\n />\n ) : null}\n </div>\n </li>\n ))}\n </ul>\n </>\n );\n };\n\n return (\n <PageLayout\n title={tr('cosmicintersection.pages.access.title', 'Data access')}\n description={tr(\n 'cosmicintersection.pages.access.description',\n 'Govern who can reach restricted and embargoed datasets, with scoped, expiring grants.',\n )}\n actions={grantButton}\n >\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"w-full max-w-[18rem]\">\n <Select value={datasetFilter} onValueChange={setDatasetFilter}>\n <SelectTrigger aria-label=\"Filter by dataset\">\n <SelectValue placeholder=\"All datasets\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All datasets</SelectItem>\n {datasets.map((dataset) => (\n <SelectItem key={dataset.id} value={dataset.id}>\n {dataset.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"w-full max-w-[14rem]\">\n <Select value={statusFilter} onValueChange={setStatusFilter}>\n <SelectTrigger aria-label=\"Filter by status\">\n <SelectValue placeholder=\"All statuses\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All statuses</SelectItem>\n {GRANT_STATUSES.map((status) => (\n <SelectItem key={status} value={status}>\n {formatEnumLabel(status)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n {renderBody()}\n </div>\n\n {/* Grant access dialog */}\n <Dialog\n open={dialogOpen}\n onOpenChange={(open) => (open || granting ? setDialogOpen(open) : setDialogOpen(false))}\n >\n <DialogContent className=\"max-h-[85vh] max-w-md overflow-y-auto\">\n <DialogHeader>\n <DialogTitle>\n {tr('cosmicintersection.pages.access.grantDataAccess', 'Grant data access')}\n </DialogTitle>\n <DialogDescription>\n {tr(\n 'cosmicintersection.pages.access.grantDataAccessDescription',\n \"Give a workspace member scoped access to a dataset. Access is identified by the member's User ID.\",\n )}\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"grant-dataset\">\n {tr('cosmicintersection.pages.access.dataset', 'Dataset')}\n </Label>\n <Select\n value={form.datasetId || undefined}\n onValueChange={(value) => setField('datasetId', value)}\n >\n <SelectTrigger\n id=\"grant-dataset\"\n aria-label={tr('cosmicintersection.pages.access.dataset', 'Dataset')}\n >\n <SelectValue\n placeholder={tr(\n 'cosmicintersection.pages.access.selectDataset',\n 'Select a dataset',\n )}\n />\n </SelectTrigger>\n <SelectContent>\n {datasets.map((dataset) => (\n <SelectItem key={dataset.id} value={dataset.id}>\n {dataset.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"grant-grantee\">\n {tr('cosmicintersection.pages.access.grantee', 'Grantee (User ID)')}\n </Label>\n <Input\n id=\"grant-grantee\"\n value={form.granteeId}\n onChange={(event) => setField('granteeId', event.target.value)}\n placeholder=\"e.g. 4fe35990-…\"\n className=\"font-mono\"\n />\n <p className=\"text-xs text-text-secondary\">\n {tr(\n 'cosmicintersection.pages.access.granteeHint',\n \"Paste the workspace member's User ID. You can copy it from the member's profile (\\\"Get ID\\\") or the workspace member directory.\",\n )}\n </p>\n </div>\n\n <EntityTagsField\n value={form.scopes}\n onChange={(scopes) => setField('scopes', scopes)}\n label={tr('cosmicintersection.pages.access.scopes', 'Scopes')}\n placeholder=\"e.g. read, download\"\n />\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"grant-reason\">\n {tr('cosmicintersection.pages.access.reason', 'Reason')}\n </Label>\n <Textarea\n id=\"grant-reason\"\n value={form.reason}\n onChange={(event) => setField('reason', event.target.value)}\n rows={2}\n placeholder={tr(\n 'cosmicintersection.pages.access.reasonPlaceholder',\n 'Why this member needs access.',\n )}\n />\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"grant-expires\">\n {tr('cosmicintersection.pages.access.expiresOptional', 'Expires (optional)')}\n </Label>\n <Input\n id=\"grant-expires\"\n type=\"datetime-local\"\n value={form.expiresAt}\n onChange={(event) => setField('expiresAt', event.target.value)}\n />\n <p className=\"text-xs text-text-secondary\">\n {tr(\n 'cosmicintersection.pages.access.expiresHint',\n 'Leave blank for an open-ended grant.',\n )}\n </p>\n </div>\n </div>\n\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setDialogOpen(false)}\n disabled={granting}\n >\n {tr('cosmicintersection.common.cancel', 'Cancel')}\n </Button>\n <Button type=\"button\" onClick={() => void submitGrant()} disabled={granting}>\n <KeyRound className=\"size-4\" />\n {granting\n ? tr('cosmicintersection.pages.access.granting', 'Granting…')\n : tr('cosmicintersection.pages.access.grantAccess', 'Grant access')}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AccessPage.js","names":[],"sources":["../../../../src/cosmicintersection/pages/access/AccessPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { KeyRound, ShieldCheck } from 'lucide-react';\nimport {\n Badge,\n Button,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Input,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\n\nimport {\n useCosAccessGrantsQuery,\n useCosDatasetsQuery,\n useCosGrantAccessMutation,\n useCosRevokeAccessMutation,\n type CosDataAccessGrant,\n type CosGrantAccessInput,\n type CosGrantStatus,\n} from '../../api/cosmicApi';\nimport {\n EmptyState,\n ErrorState,\n LoadingState,\n PageLayout,\n StatusBadge,\n formatEnumLabel,\n} from '../../components';\nimport { ActionMenu } from '../../components/ActionMenu';\nimport { EntityTagsField } from '../../components/EntityTagsField';\nimport { notify } from '../../lib/toast';\nimport { useTr } from '../../../shared/hooks/useTr';\n\nconst ALL = 'ALL';\nconst GRANT_STATUSES: CosGrantStatus[] = ['PENDING', 'ACTIVE', 'EXPIRED', 'REVOKED'];\n\n/** Only live grants can be revoked. */\nfunction canRevoke(status: CosGrantStatus): boolean {\n return status === 'ACTIVE' || status === 'PENDING';\n}\n\nfunction formatDate(value?: string | null): string {\n if (!value) {\n return '—';\n }\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return '—';\n }\n return parsed.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });\n}\n\ninterface GrantFormState {\n datasetId: string;\n granteeId: string;\n scopes: string[];\n reason: string;\n expiresAt: string;\n}\n\nconst EMPTY_FORM: GrantFormState = {\n datasetId: '',\n granteeId: '',\n scopes: [],\n reason: '',\n expiresAt: '',\n};\n\nexport default function AccessPage() {\n const tr = useTr();\n const [datasetFilter, setDatasetFilter] = useState<string>(ALL);\n const [statusFilter, setStatusFilter] = useState<string>(ALL);\n\n const datasetsQuery = useCosDatasetsQuery({ pagination: { limit: 50, offset: 0 } });\n const datasets = useMemo(\n () => datasetsQuery.data?.cosListDatasets.items ?? [],\n [datasetsQuery.data]\n );\n const datasetName = useMemo(() => {\n const map = new Map<string, string>();\n for (const dataset of datasets) {\n map.set(dataset.id, dataset.name);\n }\n return map;\n }, [datasets]);\n\n const { data, loading, error, refetch } = useCosAccessGrantsQuery({\n datasetId: datasetFilter === ALL ? undefined : datasetFilter,\n status: statusFilter === ALL ? undefined : (statusFilter as CosGrantStatus),\n });\n const grants = useMemo(() => data?.cosListAccessGrants ?? [], [data]);\n\n const [grantAccess, { loading: granting }] = useCosGrantAccessMutation();\n const [revokeAccess] = useCosRevokeAccessMutation();\n\n const [dialogOpen, setDialogOpen] = useState(false);\n const [form, setForm] = useState<GrantFormState>(EMPTY_FORM);\n\n const openGrantDialog = () => {\n setForm({\n ...EMPTY_FORM,\n datasetId: datasetFilter === ALL ? '' : datasetFilter,\n });\n setDialogOpen(true);\n };\n\n const setField = <K extends keyof GrantFormState>(field: K, value: GrantFormState[K]) => {\n setForm((prev) => ({ ...prev, [field]: value }));\n };\n\n const submitGrant = async () => {\n if (!form.datasetId) {\n notify.error(\n tr('cosmicintersection.pages.access.datasetRequired', 'Dataset is required'),\n tr(\n 'cosmicintersection.pages.access.datasetRequiredDescription',\n 'Choose which dataset this grant applies to.'\n )\n );\n return;\n }\n if (!form.granteeId.trim()) {\n notify.error(\n tr('cosmicintersection.pages.access.granteeRequired', 'Grantee is required'),\n tr(\n 'cosmicintersection.pages.access.granteeRequiredDescription',\n 'Enter the workspace User ID to grant access to.'\n )\n );\n return;\n }\n\n let expiresAt: string | undefined;\n if (form.expiresAt) {\n const parsed = new Date(form.expiresAt);\n if (Number.isNaN(parsed.getTime())) {\n notify.error(\n tr('cosmicintersection.pages.access.invalidExpiry', 'Invalid expiry'),\n tr(\n 'cosmicintersection.pages.access.invalidExpiryDescription',\n 'Enter a valid expiry date or leave it blank.'\n )\n );\n return;\n }\n expiresAt = parsed.toISOString();\n }\n\n const input: CosGrantAccessInput = {\n datasetId: form.datasetId,\n granteeId: form.granteeId.trim(),\n scopes: form.scopes.length ? form.scopes : undefined,\n reason: form.reason.trim() || undefined,\n expiresAt,\n };\n\n const response = await grantAccess({ variables: { input } });\n if (response.data?.cosGrantAccess?.id) {\n notify.success(tr('cosmicintersection.pages.access.accessGranted', 'Access granted'));\n setDialogOpen(false);\n setForm(EMPTY_FORM);\n await refetch();\n }\n };\n\n const handleRevoke = async (grant: CosDataAccessGrant) => {\n const response = await revokeAccess({ variables: { id: grant.id } });\n if (response.error) {\n throw new Error(response.error.message);\n }\n if (!response.data?.cosRevokeAccess?.id) {\n notify.error(\n tr('cosmicintersection.pages.access.revokeError', 'Could not revoke grant'),\n tr(\n 'cosmicintersection.pages.access.revokeErrorDescription',\n 'The server did not confirm the change.'\n )\n );\n throw new Error('Revoke not confirmed');\n }\n notify.success(tr('cosmicintersection.pages.access.accessRevoked', 'Access revoked'));\n await refetch();\n };\n\n const grantButton = (\n <Button type=\"button\" onClick={openGrantDialog}>\n <KeyRound className=\"size-4\" />\n {tr('cosmicintersection.pages.access.grantAccess', 'Grant access')}\n </Button>\n );\n\n const showDatasetColumn = datasetFilter === ALL;\n\n const renderBody = () => {\n if (loading) {\n return (\n <LoadingState\n variant=\"rows\"\n rows={6}\n label={tr('cosmicintersection.pages.access.loading', 'Loading access grants…')}\n />\n );\n }\n if (error) {\n return <ErrorState message={error.message} onRetry={() => void refetch()} />;\n }\n if (grants.length === 0) {\n const filtered = datasetFilter !== ALL || statusFilter !== ALL;\n return (\n <EmptyState\n icon={ShieldCheck}\n title={\n filtered\n ? tr(\n 'cosmicintersection.pages.access.emptyFilterTitle',\n 'No grants match these filters'\n )\n : tr('cosmicintersection.pages.access.emptyTitle', 'No access grants yet')\n }\n description={\n filtered\n ? tr(\n 'cosmicintersection.pages.access.emptyFilterDescription',\n 'Try clearing the dataset or status filter to see more grants.'\n )\n : tr(\n 'cosmicintersection.pages.access.emptyDescription',\n 'Grant a workspace member scoped access to a restricted or embargoed dataset.'\n )\n }\n action={filtered ? undefined : grantButton}\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 {showDatasetColumn ? <TableHead>Dataset</TableHead> : null}\n <TableHead>Grantee</TableHead>\n <TableHead>Status</TableHead>\n <TableHead>Scopes</TableHead>\n <TableHead>Reason</TableHead>\n <TableHead>Granted</TableHead>\n <TableHead>Expires</TableHead>\n <TableHead>Revoked</TableHead>\n <TableHead className=\"text-right\">Actions</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {grants.map((grant) => (\n <TableRow key={grant.id}>\n {showDatasetColumn ? (\n <TableCell className=\"max-w-[12rem]\">\n <span className=\"line-clamp-1 text-sm text-text-primary\">\n {datasetName.get(grant.datasetId) ?? (\n <span className=\"font-mono text-xs text-text-secondary\">\n {grant.datasetId}\n </span>\n )}\n </span>\n </TableCell>\n ) : null}\n <TableCell className=\"max-w-[12rem]\">\n <span className=\"block truncate font-mono text-xs text-text-primary\">\n {grant.granteeId}\n </span>\n </TableCell>\n <TableCell>\n <StatusBadge status={grant.status} />\n </TableCell>\n <TableCell>\n <div className=\"flex max-w-[12rem] flex-wrap gap-1\">\n {grant.scopes.length === 0 ? (\n <span className=\"text-xs text-text-secondary\">—</span>\n ) : (\n grant.scopes.map((scope) => (\n <Badge key={scope} variant=\"outline\" className=\"text-xs\">\n {scope}\n </Badge>\n ))\n )}\n </div>\n </TableCell>\n <TableCell className=\"max-w-[14rem]\">\n {grant.reason ? (\n <span className=\"line-clamp-1 text-sm text-text-secondary\">\n {grant.reason}\n </span>\n ) : (\n <span className=\"text-sm text-text-secondary\">—</span>\n )}\n </TableCell>\n <TableCell className=\"whitespace-nowrap text-sm text-text-secondary\">\n {formatDate(grant.grantedAt)}\n </TableCell>\n <TableCell className=\"whitespace-nowrap text-sm text-text-secondary\">\n {formatDate(grant.expiresAt)}\n </TableCell>\n <TableCell className=\"whitespace-nowrap text-sm text-text-secondary\">\n {formatDate(grant.revokedAt)}\n </TableCell>\n <TableCell className=\"text-right\">\n {canRevoke(grant.status) ? (\n <ActionMenu\n ariaLabel={`Actions for grant to ${grant.granteeId}`}\n entityName={grant.granteeId}\n onDelete={() => handleRevoke(grant)}\n deleteLabel=\"Revoke grant\"\n />\n ) : (\n <span className=\"text-xs text-text-secondary\">—</span>\n )}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n\n {/* Mobile card list */}\n <ul className=\"space-y-3 md:hidden\">\n {grants.map((grant) => (\n <li key={grant.id} className=\"rounded-card border border-border-default bg-bg-elevated\">\n <div className=\"flex items-start justify-between gap-2 p-4\">\n <div className=\"min-w-0 flex-1 space-y-2\">\n <div className=\"flex flex-wrap items-center gap-2\">\n {showDatasetColumn ? (\n <span className=\"truncate text-sm font-medium text-text-primary\">\n {datasetName.get(grant.datasetId) ?? 'Dataset'}\n </span>\n ) : null}\n <StatusBadge status={grant.status} />\n </div>\n\n <div>\n <p className=\"text-xs text-text-secondary\">Grantee (User ID)</p>\n <p className=\"truncate font-mono text-xs text-text-primary\">\n {grant.granteeId}\n </p>\n </div>\n\n {grant.scopes.length > 0 ? (\n <div className=\"flex flex-wrap gap-1\">\n {grant.scopes.map((scope) => (\n <Badge key={scope} variant=\"outline\" className=\"text-xs\">\n {scope}\n </Badge>\n ))}\n </div>\n ) : null}\n\n {grant.reason ? (\n <p className=\"line-clamp-2 text-xs text-text-secondary\">{grant.reason}</p>\n ) : null}\n\n <div className=\"flex flex-wrap gap-x-3 gap-y-1 text-xs text-text-secondary\">\n <span>Granted {formatDate(grant.grantedAt)}</span>\n <span>Expires {formatDate(grant.expiresAt)}</span>\n {grant.revokedAt ? <span>Revoked {formatDate(grant.revokedAt)}</span> : null}\n </div>\n </div>\n\n {canRevoke(grant.status) ? (\n <ActionMenu\n ariaLabel={`Actions for grant to ${grant.granteeId}`}\n entityName={grant.granteeId}\n onDelete={() => handleRevoke(grant)}\n deleteLabel=\"Revoke grant\"\n />\n ) : null}\n </div>\n </li>\n ))}\n </ul>\n </>\n );\n };\n\n return (\n <PageLayout\n title={tr('cosmicintersection.pages.access.title', 'Data access')}\n description={tr(\n 'cosmicintersection.pages.access.description',\n 'Govern who can reach restricted and embargoed datasets, with scoped, expiring grants.'\n )}\n actions={grantButton}\n >\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"w-full max-w-[18rem]\">\n <Select value={datasetFilter} onValueChange={setDatasetFilter}>\n <SelectTrigger aria-label=\"Filter by dataset\">\n <SelectValue placeholder=\"All datasets\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All datasets</SelectItem>\n {datasets.map((dataset) => (\n <SelectItem key={dataset.id} value={dataset.id}>\n {dataset.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"w-full max-w-[14rem]\">\n <Select value={statusFilter} onValueChange={setStatusFilter}>\n <SelectTrigger aria-label=\"Filter by status\">\n <SelectValue placeholder=\"All statuses\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={ALL}>All statuses</SelectItem>\n {GRANT_STATUSES.map((status) => (\n <SelectItem key={status} value={status}>\n {formatEnumLabel(status)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n {renderBody()}\n </div>\n\n {/* Grant access dialog */}\n <Dialog\n open={dialogOpen}\n onOpenChange={(open) => (open || granting ? setDialogOpen(open) : setDialogOpen(false))}\n >\n <DialogContent className=\"max-h-[85vh] max-w-md overflow-y-auto\">\n <DialogHeader>\n <DialogTitle>\n {tr('cosmicintersection.pages.access.grantDataAccess', 'Grant data access')}\n </DialogTitle>\n <DialogDescription>\n {tr(\n 'cosmicintersection.pages.access.grantDataAccessDescription',\n \"Give a workspace member scoped access to a dataset. Access is identified by the member's User ID.\"\n )}\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"grant-dataset\">\n {tr('cosmicintersection.pages.access.dataset', 'Dataset')}\n </Label>\n <Select\n value={form.datasetId || undefined}\n onValueChange={(value) => setField('datasetId', value)}\n >\n <SelectTrigger\n id=\"grant-dataset\"\n aria-label={tr('cosmicintersection.pages.access.dataset', 'Dataset')}\n >\n <SelectValue\n placeholder={tr(\n 'cosmicintersection.pages.access.selectDataset',\n 'Select a dataset'\n )}\n />\n </SelectTrigger>\n <SelectContent>\n {datasets.map((dataset) => (\n <SelectItem key={dataset.id} value={dataset.id}>\n {dataset.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"grant-grantee\">\n {tr('cosmicintersection.pages.access.grantee', 'Grantee (User ID)')}\n </Label>\n <Input\n id=\"grant-grantee\"\n value={form.granteeId}\n onChange={(event) => setField('granteeId', event.target.value)}\n placeholder=\"e.g. 4fe35990-…\"\n className=\"font-mono\"\n />\n <p className=\"text-xs text-text-secondary\">\n {tr(\n 'cosmicintersection.pages.access.granteeHint',\n 'Paste the workspace member\\'s User ID. You can copy it from the member\\'s profile (\"Get ID\") or the workspace member directory.'\n )}\n </p>\n </div>\n\n <EntityTagsField\n value={form.scopes}\n onChange={(scopes) => setField('scopes', scopes)}\n label={tr('cosmicintersection.pages.access.scopes', 'Scopes')}\n placeholder=\"e.g. read, download\"\n />\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"grant-reason\">\n {tr('cosmicintersection.pages.access.reason', 'Reason')}\n </Label>\n <Textarea\n id=\"grant-reason\"\n value={form.reason}\n onChange={(event) => setField('reason', event.target.value)}\n rows={2}\n placeholder={tr(\n 'cosmicintersection.pages.access.reasonPlaceholder',\n 'Why this member needs access.'\n )}\n />\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"grant-expires\">\n {tr('cosmicintersection.pages.access.expiresOptional', 'Expires (optional)')}\n </Label>\n <Input\n id=\"grant-expires\"\n type=\"datetime-local\"\n value={form.expiresAt}\n onChange={(event) => setField('expiresAt', event.target.value)}\n />\n <p className=\"text-xs text-text-secondary\">\n {tr(\n 'cosmicintersection.pages.access.expiresHint',\n 'Leave blank for an open-ended grant.'\n )}\n </p>\n </div>\n </div>\n\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setDialogOpen(false)}\n disabled={granting}\n >\n {tr('cosmicintersection.common.cancel', 'Cancel')}\n </Button>\n <Button type=\"button\" onClick={() => void submitGrant()} disabled={granting}>\n <KeyRound className=\"size-4\" />\n {granting\n ? tr('cosmicintersection.pages.access.granting', 'Granting…')\n : tr('cosmicintersection.pages.access.grantAccess', 'Grant access')}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export default function AnalysesPage(): import("react
|
|
1
|
+
export default function AnalysesPage(): import("react").JSX.Element;
|
|
2
2
|
//# sourceMappingURL=AnalysesPage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnalysesPage.d.ts","sourceRoot":"","sources":["../../../../src/cosmicintersection/pages/analyses/AnalysesPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AnalysesPage.d.ts","sourceRoot":"","sources":["../../../../src/cosmicintersection/pages/analyses/AnalysesPage.tsx"],"names":[],"mappings":"AA+kBA,MAAM,CAAC,OAAO,UAAU,YAAY,gCA6WnC"}
|