@burdenoff/microfe-cosmicintersection 2026.704.1 → 2026.704.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cosmicintersection/CosmicIntersectionRoutes.js +31 -23
- package/dist/cosmicintersection/CosmicIntersectionRoutes.js.map +1 -1
- package/dist/cosmicintersection/api/cosmicApi.js +131 -66
- package/dist/cosmicintersection/api/cosmicApi.js.map +1 -1
- package/dist/cosmicintersection/components/ActivityFeedPanel.js +68 -0
- package/dist/cosmicintersection/components/ActivityFeedPanel.js.map +1 -0
- package/dist/cosmicintersection/components/DiscussionPanel.js +57 -0
- package/dist/cosmicintersection/components/DiscussionPanel.js.map +1 -0
- package/dist/cosmicintersection/components/index.js +5 -3
- package/dist/cosmicintersection/pages/access/AccessPage.js +24 -17
- package/dist/cosmicintersection/pages/access/AccessPage.js.map +1 -1
- package/dist/cosmicintersection/pages/analyses/AnalysesPage.js +12 -12
- package/dist/cosmicintersection/pages/collections/CollectionDetailPage.js +109 -96
- package/dist/cosmicintersection/pages/collections/CollectionDetailPage.js.map +1 -1
- package/dist/cosmicintersection/pages/collections/CollectionFormPage.js +87 -61
- package/dist/cosmicintersection/pages/collections/CollectionFormPage.js.map +1 -1
- package/dist/cosmicintersection/pages/collections/CollectionsPage.js +51 -42
- package/dist/cosmicintersection/pages/collections/CollectionsPage.js.map +1 -1
- package/dist/cosmicintersection/pages/dashboard/DashboardPage.js +5 -3
- package/dist/cosmicintersection/pages/dashboard/DashboardPage.js.map +1 -1
- package/dist/cosmicintersection/pages/datasets/DatasetDetailPage.js +172 -152
- package/dist/cosmicintersection/pages/datasets/DatasetDetailPage.js.map +1 -1
- package/dist/cosmicintersection/pages/datasets/DatasetFormPage.js +7 -7
- package/dist/cosmicintersection/pages/notebooks/NotebookDetailPage.js +205 -196
- package/dist/cosmicintersection/pages/notebooks/NotebookDetailPage.js.map +1 -1
- package/dist/cosmicintersection/pages/releases/ReleasesPage.js +211 -161
- package/dist/cosmicintersection/pages/releases/ReleasesPage.js.map +1 -1
- package/dist/cosmicintersection/pages/runs/RunDetailPage.js +113 -108
- package/dist/cosmicintersection/pages/runs/RunDetailPage.js.map +1 -1
- package/dist/cosmicintersection/pages/runs/RunsPage.js +86 -101
- package/dist/cosmicintersection/pages/runs/RunsPage.js.map +1 -1
- package/dist/cosmicintersection/pages/sources/SourceDetailPage.js +205 -0
- package/dist/cosmicintersection/pages/sources/SourceDetailPage.js.map +1 -0
- package/dist/cosmicintersection/pages/sources/SourcesPage.js +110 -104
- package/dist/cosmicintersection/pages/sources/SourcesPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cosmicApi.js","names":[],"sources":["../../../src/cosmicintersection/api/cosmicApi.ts"],"sourcesContent":["/**\n * cosmicApi — hand-written typed data layer for the CosmicIntersection MFE.\n *\n * Mirrors the pattern in microfe-eventfullymanaged's eventApi.ts: inline `gql`\n * documents + `@apollo/client/react` hooks, with hand-written response/variables\n * types that track the wspace-cosmicintersection-svc subgraph SDL exactly. The\n * Apollo client is provided by the HOST app shell via React context (integrated\n * mode) — this module never constructs a client. Every `cos*` operation runs on\n * the workspace gateway (the default client in context).\n *\n * Scalar mapping: BigInt -> string, JSON -> Record<string, unknown>,\n * DateTime -> string (ISO).\n */\nimport { gql, type ErrorLike } from '@apollo/client';\nimport { useMutation, useQuery } from '@apollo/client/react';\n\nimport { notify } from '../lib/toast';\n\n/**\n * Shared mutation error sink. The gateway client runs with `errorPolicy: 'all'`,\n * so in-band GraphQL errors also invoke `onError`; wiring this on every write\n * mutation guarantees a failure is always surfaced to the user even if a caller\n * forgets to inspect the resolved result.\n */\nconst onMutationError = (error: ErrorLike): void => {\n notify.error('Something went wrong', error.message || 'Please try again.');\n};\n\n// ============================================================================\n// ENUMS (string-literal unions — exact SDL values)\n// ============================================================================\n\nexport type CosDatasetStatus = 'DRAFT' | 'INGESTING' | 'AVAILABLE' | 'DEPRECATED' | 'ARCHIVED';\nexport type CosAccessLevel = 'PUBLIC' | 'WORKSPACE' | 'RESTRICTED' | 'EMBARGOED';\nexport type CosSourceType =\n | 'TELESCOPE'\n | 'SATELLITE'\n | 'GROUND_SENSOR'\n | 'ARCHIVE'\n | 'API'\n | 'STREAM'\n | 'FILE_DROP'\n | 'SIMULATION';\nexport type CosSourceStatus =\n | 'CONFIGURING'\n | 'CONNECTED'\n | 'SYNCING'\n | 'DEGRADED'\n | 'ERROR'\n | 'DISABLED';\nexport type CosFieldType =\n | 'STRING'\n | 'INTEGER'\n | 'FLOAT'\n | 'BOOLEAN'\n | 'TIMESTAMP'\n | 'COORDINATE'\n | 'SPECTRUM'\n | 'GEOMETRY'\n | 'IMAGE_REF'\n | 'JSON';\nexport type CosPipelineStatus = 'DRAFT' | 'ACTIVE' | 'PAUSED' | 'ARCHIVED';\nexport type CosPipelineTrigger = 'MANUAL' | 'SCHEDULED' | 'ON_INGEST' | 'WEBHOOK';\nexport type CosRunStatus = 'QUEUED' | 'RUNNING' | 'SUCCEEDED' | 'FAILED' | 'CANCELLED';\nexport type CosStepKind = 'INGEST' | 'CALIBRATE' | 'TRANSFORM' | 'ANALYZE' | 'EXPORT' | 'NOTIFY';\nexport type CosNotebookStatus = 'DRAFT' | 'RUNNING' | 'PUBLISHED' | 'ARCHIVED';\nexport type CosAnalysisStatus = 'PENDING' | 'RUNNING' | 'COMPLETED' | 'FAILED';\nexport type CosReleaseStatus = 'DRAFT' | 'UNDER_REVIEW' | 'PUBLISHED' | 'RETRACTED';\nexport type CosGrantStatus = 'PENDING' | 'ACTIVE' | 'EXPIRED' | 'REVOKED';\n\n// ============================================================================\n// ENTITY TYPES\n// ============================================================================\n\n/** Federated wspace-files File stub — only `{ id }` is resolvable in this subgraph. */\nexport interface CosFileRef {\n id: string;\n}\n\nexport interface CosSchemaField {\n id: string;\n workspaceId: string;\n datasetId: string;\n name: string;\n fieldType: CosFieldType;\n unit?: string | null;\n description?: string | null;\n nullable: boolean;\n position: number;\n provenance?: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CosDataset {\n id: string;\n workspaceId: string;\n name: string;\n description?: string | null;\n status: CosDatasetStatus;\n accessLevel: CosAccessLevel;\n format?: string | null;\n sourceId?: string | null;\n collectionId?: string | null;\n /** BigInt returned as a numeric string. */\n rowCount: string;\n /** BigInt returned as a numeric string. */\n sizeBytes: string;\n version: number;\n lineageCaptured: boolean;\n coverage?: Record<string, unknown> | null;\n ingestedAt?: string | null;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n // Relations — only present when the operation selects them (detail queries).\n source?: CosSource | null;\n collection?: CosCollection | null;\n file?: CosFileRef | null;\n schemaFields?: CosSchemaField[];\n}\n\nexport interface CosSource {\n id: string;\n workspaceId: string;\n name: string;\n description?: string | null;\n type: CosSourceType;\n status: CosSourceStatus;\n endpoint?: string | null;\n config?: Record<string, unknown> | null;\n lastSyncedAt?: string | null;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n // Relation — present only on detail queries.\n datasets?: CosDataset[];\n}\n\nexport interface CosCollection {\n id: string;\n workspaceId: string;\n name: string;\n slug?: string | null;\n description?: string | null;\n isPublic: boolean;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n // Relation — present only on detail queries.\n datasets?: CosDataset[];\n}\n\nexport interface CosPipeline {\n id: string;\n workspaceId: string;\n name: string;\n description?: string | null;\n status: CosPipelineStatus;\n trigger: CosPipelineTrigger;\n schedule?: string | null;\n definition?: Record<string, unknown> | null;\n version: number;\n lastRunAt?: string | null;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n // Relation — present only on detail queries.\n runs?: CosPipelineRun[];\n}\n\nexport interface CosPipelineRun {\n id: string;\n workspaceId: string;\n pipelineId: string;\n runNumber: number;\n status: CosRunStatus;\n datasetId?: string | null;\n params?: Record<string, unknown> | null;\n metrics?: Record<string, unknown> | null;\n triggeredBy?: string | null;\n startedAt?: string | null;\n finishedAt?: string | null;\n durationMs?: number | null;\n errorMessage?: string | null;\n createdAt: string;\n updatedAt: string;\n // Relations — present only on detail queries.\n pipeline?: CosPipeline | null;\n steps?: CosPipelineStep[];\n}\n\nexport interface CosPipelineStep {\n id: string;\n workspaceId: string;\n runId: string;\n name: string;\n kind: CosStepKind;\n position: number;\n status: CosRunStatus;\n inputs?: Record<string, unknown> | null;\n outputs?: Record<string, unknown> | null;\n logsRef?: string | null;\n startedAt?: string | null;\n finishedAt?: string | null;\n durationMs?: number | null;\n errorMessage?: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CosNotebook {\n id: string;\n workspaceId: string;\n title: string;\n description?: string | null;\n status: CosNotebookStatus;\n runtime?: string | null;\n environment?: Record<string, unknown> | null;\n datasetIds: string[];\n isShared: boolean;\n shareSlug?: string | null;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n // Relations — present only on detail queries.\n file?: CosFileRef | null;\n analyses?: CosAnalysis[];\n releases?: CosRelease[];\n}\n\nexport interface CosAnalysis {\n id: string;\n workspaceId: string;\n title: string;\n status: CosAnalysisStatus;\n method?: string | null;\n aiAssisted: boolean;\n notebookId?: string | null;\n datasetId?: string | null;\n results?: Record<string, unknown> | null;\n outputFile?: CosFileRef | null;\n startedAt?: string | null;\n finishedAt?: string | null;\n errorMessage?: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CosRelease {\n id: string;\n workspaceId: string;\n title: string;\n version: string;\n status: CosReleaseStatus;\n abstract?: string | null;\n authors: string[];\n datasetIds: string[];\n notebookId?: string | null;\n doi?: string | null;\n license?: string | null;\n publishedAt?: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CosDataAccessGrant {\n id: string;\n workspaceId: string;\n datasetId: string;\n granteeId: string;\n status: CosGrantStatus;\n scopes: string[];\n reason?: string | null;\n grantedAt?: string | null;\n expiresAt?: string | null;\n revokedAt?: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\n// ============================================================================\n// PAGINATION / CONNECTIONS\n// ============================================================================\n\nexport interface CosPageInfo {\n hasMore: boolean;\n cursor?: string | null;\n}\n\nexport interface CosConnection<T> {\n items: T[];\n pageInfo: CosPageInfo;\n}\n\n/** Offset-based pagination input (PaginationInput in the SDL; limit defaults to 50). */\nexport interface CosPaginationInput {\n limit?: number;\n offset?: number;\n cursor?: string;\n}\n\n// ============================================================================\n// INPUT TYPES\n// ============================================================================\n\nexport interface CosCreateDatasetInput {\n name: string;\n description?: string;\n status?: CosDatasetStatus;\n accessLevel?: CosAccessLevel;\n format?: string;\n sourceId?: string;\n collectionId?: string;\n fileId?: string;\n coverage?: Record<string, unknown>;\n tags?: string[];\n}\n\nexport interface CosUpdateDatasetInput {\n name?: string;\n description?: string;\n accessLevel?: CosAccessLevel;\n format?: string;\n collectionId?: string;\n coverage?: Record<string, unknown>;\n tags?: string[];\n}\n\nexport interface CosAddSchemaFieldInput {\n datasetId: string;\n name: string;\n fieldType?: CosFieldType;\n unit?: string;\n description?: string;\n nullable?: boolean;\n position?: number;\n provenance?: string;\n}\n\nexport interface CosCreateSourceInput {\n name: string;\n type?: CosSourceType;\n status?: CosSourceStatus;\n description?: string;\n endpoint?: string;\n credentialRef?: string;\n config?: Record<string, unknown>;\n tags?: string[];\n}\n\nexport interface CosUpdateSourceInput {\n name?: string;\n type?: CosSourceType;\n status?: CosSourceStatus;\n description?: string;\n endpoint?: string;\n credentialRef?: string;\n config?: Record<string, unknown>;\n tags?: string[];\n}\n\nexport interface CosCreateCollectionInput {\n name: string;\n slug?: string;\n description?: string;\n isPublic?: boolean;\n tags?: string[];\n}\n\nexport interface CosCreatePipelineInput {\n name: string;\n description?: string;\n trigger?: CosPipelineTrigger;\n schedule?: string;\n definition?: Record<string, unknown>;\n tags?: string[];\n}\n\nexport interface CosUpdatePipelineInput {\n name?: string;\n description?: string;\n status?: CosPipelineStatus;\n trigger?: CosPipelineTrigger;\n schedule?: string;\n definition?: Record<string, unknown>;\n tags?: string[];\n}\n\nexport interface CosStartRunInput {\n pipelineId: string;\n datasetId?: string;\n params?: Record<string, unknown>;\n}\n\nexport interface CosAddRunStepInput {\n runId: string;\n name: string;\n kind?: CosStepKind;\n inputs?: Record<string, unknown>;\n position?: number;\n}\n\nexport interface CosCreateNotebookInput {\n title: string;\n description?: string;\n runtime?: string;\n environment?: Record<string, unknown>;\n datasetIds?: string[];\n fileId?: string;\n tags?: string[];\n}\n\nexport interface CosUpdateNotebookInput {\n title?: string;\n description?: string;\n status?: CosNotebookStatus;\n runtime?: string;\n environment?: Record<string, unknown>;\n datasetIds?: string[];\n isShared?: boolean;\n shareSlug?: string;\n tags?: string[];\n}\n\nexport interface CosRunAnalysisInput {\n title: string;\n method?: string;\n aiAssisted?: boolean;\n notebookId?: string;\n datasetId?: string;\n}\n\nexport interface CosCreateReleaseInput {\n title: string;\n version?: string;\n abstract?: string;\n authors?: string[];\n datasetIds?: string[];\n notebookId?: string;\n license?: string;\n}\n\nexport interface CosGrantAccessInput {\n datasetId: string;\n granteeId: string;\n scopes?: string[];\n reason?: string;\n expiresAt?: string;\n}\n\n// ============================================================================\n// GQL DOCUMENTS — QUERIES\n// ============================================================================\n\nexport const COS_HEALTH_QUERY = gql`\n query CosHealth {\n cosHealth\n }\n`;\n\nexport const COS_DATASETS_QUERY = gql`\n query CosListDatasets(\n $collectionId: ID\n $sourceId: ID\n $status: CosDatasetStatus\n $pagination: PaginationInput\n ) {\n cosListDatasets(\n collectionId: $collectionId\n sourceId: $sourceId\n status: $status\n pagination: $pagination\n ) {\n items {\n id\n workspaceId\n name\n description\n status\n accessLevel\n format\n sourceId\n collectionId\n rowCount\n sizeBytes\n version\n lineageCaptured\n ingestedAt\n tags\n createdAt\n updatedAt\n }\n pageInfo {\n hasMore\n cursor\n }\n }\n }\n`;\n\nexport const COS_DATASET_QUERY = gql`\n query CosDataset($id: ID!) {\n cosDataset(id: $id) {\n id\n workspaceId\n name\n description\n status\n accessLevel\n format\n sourceId\n collectionId\n rowCount\n sizeBytes\n version\n lineageCaptured\n coverage\n ingestedAt\n tags\n createdAt\n updatedAt\n file {\n id\n }\n source {\n id\n name\n type\n status\n }\n collection {\n id\n name\n slug\n }\n schemaFields {\n id\n datasetId\n name\n fieldType\n unit\n description\n nullable\n position\n provenance\n createdAt\n updatedAt\n }\n }\n }\n`;\n\nexport const COS_SOURCES_QUERY = gql`\n query CosListSources(\n $type: CosSourceType\n $status: CosSourceStatus\n $pagination: PaginationInput\n ) {\n cosListSources(type: $type, status: $status, pagination: $pagination) {\n items {\n id\n workspaceId\n name\n description\n type\n status\n endpoint\n config\n lastSyncedAt\n tags\n createdAt\n updatedAt\n }\n pageInfo {\n hasMore\n cursor\n }\n }\n }\n`;\n\nexport const COS_SOURCE_QUERY = gql`\n query CosSource($id: ID!) {\n cosSource(id: $id) {\n id\n workspaceId\n name\n description\n type\n status\n endpoint\n config\n lastSyncedAt\n tags\n createdAt\n updatedAt\n datasets {\n id\n name\n status\n accessLevel\n rowCount\n updatedAt\n }\n }\n }\n`;\n\nexport const COS_COLLECTIONS_QUERY = gql`\n query CosListCollections {\n cosListCollections {\n id\n workspaceId\n name\n slug\n description\n isPublic\n tags\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_SCHEMA_FIELDS_QUERY = gql`\n query CosListSchemaFields($datasetId: ID!) {\n cosListSchemaFields(datasetId: $datasetId) {\n id\n workspaceId\n datasetId\n name\n fieldType\n unit\n description\n nullable\n position\n provenance\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_PIPELINES_QUERY = gql`\n query CosListPipelines($status: CosPipelineStatus, $pagination: PaginationInput) {\n cosListPipelines(status: $status, pagination: $pagination) {\n items {\n id\n workspaceId\n name\n description\n status\n trigger\n schedule\n version\n lastRunAt\n tags\n createdAt\n updatedAt\n }\n pageInfo {\n hasMore\n cursor\n }\n }\n }\n`;\n\nexport const COS_PIPELINE_QUERY = gql`\n query CosPipeline($id: ID!) {\n cosPipeline(id: $id) {\n id\n workspaceId\n name\n description\n status\n trigger\n schedule\n definition\n version\n lastRunAt\n tags\n createdAt\n updatedAt\n runs {\n id\n runNumber\n status\n datasetId\n startedAt\n finishedAt\n durationMs\n createdAt\n }\n }\n }\n`;\n\nexport const COS_RUNS_QUERY = gql`\n query CosListRuns($pipelineId: ID, $status: CosRunStatus, $pagination: PaginationInput) {\n cosListRuns(pipelineId: $pipelineId, status: $status, pagination: $pagination) {\n items {\n id\n workspaceId\n pipelineId\n runNumber\n status\n datasetId\n triggeredBy\n startedAt\n finishedAt\n durationMs\n errorMessage\n createdAt\n updatedAt\n }\n pageInfo {\n hasMore\n cursor\n }\n }\n }\n`;\n\nexport const COS_RUN_QUERY = gql`\n query CosRun($id: ID!) {\n cosRun(id: $id) {\n id\n workspaceId\n pipelineId\n runNumber\n status\n datasetId\n params\n metrics\n triggeredBy\n startedAt\n finishedAt\n durationMs\n errorMessage\n createdAt\n updatedAt\n pipeline {\n id\n name\n status\n }\n steps {\n id\n runId\n name\n kind\n position\n status\n startedAt\n finishedAt\n durationMs\n errorMessage\n }\n }\n }\n`;\n\nexport const COS_RUN_STEPS_QUERY = gql`\n query CosListRunSteps($runId: ID!) {\n cosListRunSteps(runId: $runId) {\n id\n workspaceId\n runId\n name\n kind\n position\n status\n inputs\n outputs\n logsRef\n startedAt\n finishedAt\n durationMs\n errorMessage\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_NOTEBOOKS_QUERY = gql`\n query CosListNotebooks($status: CosNotebookStatus, $pagination: PaginationInput) {\n cosListNotebooks(status: $status, pagination: $pagination) {\n items {\n id\n workspaceId\n title\n description\n status\n runtime\n datasetIds\n isShared\n shareSlug\n tags\n createdAt\n updatedAt\n }\n pageInfo {\n hasMore\n cursor\n }\n }\n }\n`;\n\nexport const COS_NOTEBOOK_QUERY = gql`\n query CosNotebook($id: ID!) {\n cosNotebook(id: $id) {\n id\n workspaceId\n title\n description\n status\n runtime\n environment\n datasetIds\n isShared\n shareSlug\n tags\n createdAt\n updatedAt\n file {\n id\n }\n analyses {\n id\n title\n status\n aiAssisted\n method\n createdAt\n }\n releases {\n id\n title\n version\n status\n publishedAt\n }\n }\n }\n`;\n\nexport const COS_ANALYSES_QUERY = gql`\n query CosListAnalyses($datasetId: ID, $notebookId: ID, $status: CosAnalysisStatus) {\n cosListAnalyses(datasetId: $datasetId, notebookId: $notebookId, status: $status) {\n id\n workspaceId\n title\n status\n method\n aiAssisted\n notebookId\n datasetId\n results\n outputFile {\n id\n }\n startedAt\n finishedAt\n errorMessage\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_RELEASES_QUERY = gql`\n query CosListReleases($status: CosReleaseStatus, $pagination: PaginationInput) {\n cosListReleases(status: $status, pagination: $pagination) {\n items {\n id\n workspaceId\n title\n version\n status\n abstract\n authors\n datasetIds\n notebookId\n doi\n license\n publishedAt\n createdAt\n updatedAt\n }\n pageInfo {\n hasMore\n cursor\n }\n }\n }\n`;\n\nexport const COS_ACCESS_GRANTS_QUERY = gql`\n query CosListAccessGrants($datasetId: ID, $status: CosGrantStatus) {\n cosListAccessGrants(datasetId: $datasetId, status: $status) {\n id\n workspaceId\n datasetId\n granteeId\n status\n scopes\n reason\n grantedAt\n expiresAt\n revokedAt\n createdAt\n updatedAt\n }\n }\n`;\n\n// ============================================================================\n// GQL DOCUMENTS — MUTATIONS\n// ============================================================================\n\nexport const COS_CREATE_DATASET_MUTATION = gql`\n mutation CosCreateDataset($input: CosCreateDatasetInput!) {\n cosCreateDataset(input: $input) {\n id\n name\n status\n accessLevel\n sourceId\n collectionId\n tags\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_UPDATE_DATASET_MUTATION = gql`\n mutation CosUpdateDataset($id: ID!, $input: CosUpdateDatasetInput!) {\n cosUpdateDataset(id: $id, input: $input) {\n id\n name\n description\n status\n accessLevel\n format\n collectionId\n tags\n updatedAt\n }\n }\n`;\n\nexport const COS_PUBLISH_DATASET_MUTATION = gql`\n mutation CosPublishDataset($id: ID!) {\n cosPublishDataset(id: $id) {\n id\n status\n ingestedAt\n updatedAt\n }\n }\n`;\n\nexport const COS_ARCHIVE_DATASET_MUTATION = gql`\n mutation CosArchiveDataset($id: ID!) {\n cosArchiveDataset(id: $id)\n }\n`;\n\nexport const COS_ADD_SCHEMA_FIELD_MUTATION = gql`\n mutation CosAddSchemaField($input: CosAddSchemaFieldInput!) {\n cosAddSchemaField(input: $input) {\n id\n workspaceId\n datasetId\n name\n fieldType\n unit\n description\n nullable\n position\n provenance\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_CREATE_SOURCE_MUTATION = gql`\n mutation CosCreateSource($input: CosCreateSourceInput!) {\n cosCreateSource(input: $input) {\n id\n name\n type\n status\n endpoint\n tags\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_UPDATE_SOURCE_MUTATION = gql`\n mutation CosUpdateSource($id: ID!, $input: CosUpdateSourceInput!) {\n cosUpdateSource(id: $id, input: $input) {\n id\n name\n description\n type\n status\n endpoint\n tags\n updatedAt\n }\n }\n`;\n\nexport const COS_MARK_SOURCE_SYNCED_MUTATION = gql`\n mutation CosMarkSourceSynced($id: ID!) {\n cosMarkSourceSynced(id: $id) {\n id\n status\n lastSyncedAt\n updatedAt\n }\n }\n`;\n\nexport const COS_ARCHIVE_SOURCE_MUTATION = gql`\n mutation CosArchiveSource($id: ID!) {\n cosArchiveSource(id: $id)\n }\n`;\n\nexport const COS_CREATE_COLLECTION_MUTATION = gql`\n mutation CosCreateCollection($input: CosCreateCollectionInput!) {\n cosCreateCollection(input: $input) {\n id\n name\n slug\n description\n isPublic\n tags\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_CREATE_PIPELINE_MUTATION = gql`\n mutation CosCreatePipeline($input: CosCreatePipelineInput!) {\n cosCreatePipeline(input: $input) {\n id\n name\n status\n trigger\n schedule\n version\n tags\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_UPDATE_PIPELINE_MUTATION = gql`\n mutation CosUpdatePipeline($id: ID!, $input: CosUpdatePipelineInput!) {\n cosUpdatePipeline(id: $id, input: $input) {\n id\n name\n description\n status\n trigger\n schedule\n tags\n updatedAt\n }\n }\n`;\n\nexport const COS_ARCHIVE_PIPELINE_MUTATION = gql`\n mutation CosArchivePipeline($id: ID!) {\n cosArchivePipeline(id: $id)\n }\n`;\n\nexport const COS_START_RUN_MUTATION = gql`\n mutation CosStartRun($input: CosStartRunInput!) {\n cosStartRun(input: $input) {\n id\n pipelineId\n runNumber\n status\n datasetId\n startedAt\n createdAt\n }\n }\n`;\n\nexport const COS_TRANSITION_RUN_MUTATION = gql`\n mutation CosTransitionRun($id: ID!, $status: CosRunStatus!) {\n cosTransitionRun(id: $id, status: $status) {\n id\n status\n startedAt\n finishedAt\n durationMs\n updatedAt\n }\n }\n`;\n\nexport const COS_ADD_RUN_STEP_MUTATION = gql`\n mutation CosAddRunStep($input: CosAddRunStepInput!) {\n cosAddRunStep(input: $input) {\n id\n runId\n name\n kind\n position\n status\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_CREATE_NOTEBOOK_MUTATION = gql`\n mutation CosCreateNotebook($input: CosCreateNotebookInput!) {\n cosCreateNotebook(input: $input) {\n id\n title\n status\n runtime\n datasetIds\n tags\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_UPDATE_NOTEBOOK_MUTATION = gql`\n mutation CosUpdateNotebook($id: ID!, $input: CosUpdateNotebookInput!) {\n cosUpdateNotebook(id: $id, input: $input) {\n id\n title\n description\n status\n runtime\n datasetIds\n isShared\n shareSlug\n tags\n updatedAt\n }\n }\n`;\n\nexport const COS_ARCHIVE_NOTEBOOK_MUTATION = gql`\n mutation CosArchiveNotebook($id: ID!) {\n cosArchiveNotebook(id: $id)\n }\n`;\n\nexport const COS_RUN_ANALYSIS_MUTATION = gql`\n mutation CosRunAnalysis($input: CosRunAnalysisInput!) {\n cosRunAnalysis(input: $input) {\n id\n title\n status\n method\n aiAssisted\n notebookId\n datasetId\n startedAt\n createdAt\n }\n }\n`;\n\nexport const COS_COMPLETE_ANALYSIS_MUTATION = gql`\n mutation CosCompleteAnalysis(\n $id: ID!\n $status: CosAnalysisStatus!\n $results: JSON\n $outputFileId: ID\n ) {\n cosCompleteAnalysis(id: $id, status: $status, results: $results, outputFileId: $outputFileId) {\n id\n status\n results\n finishedAt\n errorMessage\n outputFile {\n id\n }\n updatedAt\n }\n }\n`;\n\nexport const COS_CREATE_RELEASE_MUTATION = gql`\n mutation CosCreateRelease($input: CosCreateReleaseInput!) {\n cosCreateRelease(input: $input) {\n id\n title\n version\n status\n authors\n datasetIds\n notebookId\n license\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_PUBLISH_RELEASE_MUTATION = gql`\n mutation CosPublishRelease($id: ID!, $doi: String) {\n cosPublishRelease(id: $id, doi: $doi) {\n id\n status\n doi\n publishedAt\n updatedAt\n }\n }\n`;\n\nexport const COS_GRANT_ACCESS_MUTATION = gql`\n mutation CosGrantAccess($input: CosGrantAccessInput!) {\n cosGrantAccess(input: $input) {\n id\n datasetId\n granteeId\n status\n scopes\n reason\n grantedAt\n expiresAt\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_REVOKE_ACCESS_MUTATION = gql`\n mutation CosRevokeAccess($id: ID!) {\n cosRevokeAccess(id: $id) {\n id\n status\n revokedAt\n updatedAt\n }\n }\n`;\n\n// ============================================================================\n// RESPONSE / VARIABLES TYPES\n// ============================================================================\n\nexport interface CosHealthQueryData {\n cosHealth: string;\n}\n\nexport interface CosDatasetsQueryData {\n cosListDatasets: CosConnection<CosDataset>;\n}\nexport interface CosDatasetsQueryVars {\n collectionId?: string;\n sourceId?: string;\n status?: CosDatasetStatus;\n pagination?: CosPaginationInput;\n}\n\nexport interface CosDatasetQueryData {\n cosDataset: CosDataset | null;\n}\n\nexport interface CosSourcesQueryData {\n cosListSources: CosConnection<CosSource>;\n}\nexport interface CosSourcesQueryVars {\n type?: CosSourceType;\n status?: CosSourceStatus;\n pagination?: CosPaginationInput;\n}\n\nexport interface CosSourceQueryData {\n cosSource: CosSource | null;\n}\n\nexport interface CosCollectionsQueryData {\n cosListCollections: CosCollection[];\n}\n\nexport interface CosSchemaFieldsQueryData {\n cosListSchemaFields: CosSchemaField[];\n}\n\nexport interface CosPipelinesQueryData {\n cosListPipelines: CosConnection<CosPipeline>;\n}\nexport interface CosPipelinesQueryVars {\n status?: CosPipelineStatus;\n pagination?: CosPaginationInput;\n}\n\nexport interface CosPipelineQueryData {\n cosPipeline: CosPipeline | null;\n}\n\nexport interface CosRunsQueryData {\n cosListRuns: CosConnection<CosPipelineRun>;\n}\nexport interface CosRunsQueryVars {\n pipelineId?: string;\n status?: CosRunStatus;\n pagination?: CosPaginationInput;\n}\n\nexport interface CosRunQueryData {\n cosRun: CosPipelineRun | null;\n}\n\nexport interface CosRunStepsQueryData {\n cosListRunSteps: CosPipelineStep[];\n}\n\nexport interface CosNotebooksQueryData {\n cosListNotebooks: CosConnection<CosNotebook>;\n}\nexport interface CosNotebooksQueryVars {\n status?: CosNotebookStatus;\n pagination?: CosPaginationInput;\n}\n\nexport interface CosNotebookQueryData {\n cosNotebook: CosNotebook | null;\n}\n\nexport interface CosAnalysesQueryData {\n cosListAnalyses: CosAnalysis[];\n}\nexport interface CosAnalysesQueryVars {\n datasetId?: string;\n notebookId?: string;\n status?: CosAnalysisStatus;\n}\n\nexport interface CosReleasesQueryData {\n cosListReleases: CosConnection<CosRelease>;\n}\nexport interface CosReleasesQueryVars {\n status?: CosReleaseStatus;\n pagination?: CosPaginationInput;\n}\n\nexport interface CosAccessGrantsQueryData {\n cosListAccessGrants: CosDataAccessGrant[];\n}\nexport interface CosAccessGrantsQueryVars {\n datasetId?: string;\n status?: CosGrantStatus;\n}\n\n// ============================================================================\n// QUERY HOOKS\n// ============================================================================\n\nexport const useCosHealthQuery = () => useQuery<CosHealthQueryData>(COS_HEALTH_QUERY);\n\nexport const useCosDatasetsQuery = (variables: CosDatasetsQueryVars = {}) =>\n useQuery<CosDatasetsQueryData, CosDatasetsQueryVars>(COS_DATASETS_QUERY, { variables });\n\nexport const useCosDatasetQuery = (id: string) =>\n useQuery<CosDatasetQueryData, { id: string }>(COS_DATASET_QUERY, {\n variables: { id },\n skip: !id,\n });\n\nexport const useCosSourcesQuery = (variables: CosSourcesQueryVars = {}) =>\n useQuery<CosSourcesQueryData, CosSourcesQueryVars>(COS_SOURCES_QUERY, { variables });\n\nexport const useCosSourceQuery = (id: string) =>\n useQuery<CosSourceQueryData, { id: string }>(COS_SOURCE_QUERY, {\n variables: { id },\n skip: !id,\n });\n\nexport const useCosCollectionsQuery = () =>\n useQuery<CosCollectionsQueryData>(COS_COLLECTIONS_QUERY);\n\nexport const useCosSchemaFieldsQuery = (datasetId: string) =>\n useQuery<CosSchemaFieldsQueryData, { datasetId: string }>(COS_SCHEMA_FIELDS_QUERY, {\n variables: { datasetId },\n skip: !datasetId,\n });\n\nexport const useCosPipelinesQuery = (variables: CosPipelinesQueryVars = {}) =>\n useQuery<CosPipelinesQueryData, CosPipelinesQueryVars>(COS_PIPELINES_QUERY, { variables });\n\nexport const useCosPipelineQuery = (id: string) =>\n useQuery<CosPipelineQueryData, { id: string }>(COS_PIPELINE_QUERY, {\n variables: { id },\n skip: !id,\n });\n\nexport const useCosRunsQuery = (variables: CosRunsQueryVars = {}) =>\n useQuery<CosRunsQueryData, CosRunsQueryVars>(COS_RUNS_QUERY, { variables });\n\nexport const useCosRunQuery = (id: string) =>\n useQuery<CosRunQueryData, { id: string }>(COS_RUN_QUERY, {\n variables: { id },\n skip: !id,\n });\n\nexport const useCosRunStepsQuery = (runId: string) =>\n useQuery<CosRunStepsQueryData, { runId: string }>(COS_RUN_STEPS_QUERY, {\n variables: { runId },\n skip: !runId,\n });\n\nexport const useCosNotebooksQuery = (variables: CosNotebooksQueryVars = {}) =>\n useQuery<CosNotebooksQueryData, CosNotebooksQueryVars>(COS_NOTEBOOKS_QUERY, { variables });\n\nexport const useCosNotebookQuery = (id: string) =>\n useQuery<CosNotebookQueryData, { id: string }>(COS_NOTEBOOK_QUERY, {\n variables: { id },\n skip: !id,\n });\n\nexport const useCosAnalysesQuery = (variables: CosAnalysesQueryVars = {}) =>\n useQuery<CosAnalysesQueryData, CosAnalysesQueryVars>(COS_ANALYSES_QUERY, { variables });\n\nexport const useCosReleasesQuery = (variables: CosReleasesQueryVars = {}) =>\n useQuery<CosReleasesQueryData, CosReleasesQueryVars>(COS_RELEASES_QUERY, { variables });\n\nexport const useCosAccessGrantsQuery = (variables: CosAccessGrantsQueryVars = {}) =>\n useQuery<CosAccessGrantsQueryData, CosAccessGrantsQueryVars>(COS_ACCESS_GRANTS_QUERY, {\n variables,\n });\n\n// ============================================================================\n// MUTATION HOOKS\n// ============================================================================\n\nexport const useCosCreateDatasetMutation = () =>\n useMutation<{ cosCreateDataset: CosDataset }, { input: CosCreateDatasetInput }>(\n COS_CREATE_DATASET_MUTATION,\n {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_DATASETS_QUERY }],\n }\n );\n\nexport const useCosUpdateDatasetMutation = () =>\n useMutation<{ cosUpdateDataset: CosDataset }, { id: string; input: CosUpdateDatasetInput }>(\n COS_UPDATE_DATASET_MUTATION,\n {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_DATASETS_QUERY }],\n }\n );\n\nexport const useCosPublishDatasetMutation = () =>\n useMutation<{ cosPublishDataset: CosDataset }, { id: string }>(COS_PUBLISH_DATASET_MUTATION, {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_DATASETS_QUERY }],\n });\n\nexport const useCosArchiveDatasetMutation = () =>\n useMutation<{ cosArchiveDataset: boolean }, { id: string }>(COS_ARCHIVE_DATASET_MUTATION, {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_DATASETS_QUERY }],\n });\n\nexport const useCosAddSchemaFieldMutation = () =>\n useMutation<{ cosAddSchemaField: CosSchemaField }, { input: CosAddSchemaFieldInput }>(\n COS_ADD_SCHEMA_FIELD_MUTATION,\n { errorPolicy: 'all', onError: onMutationError }\n );\n\nexport const useCosCreateSourceMutation = () =>\n useMutation<{ cosCreateSource: CosSource }, { input: CosCreateSourceInput }>(\n COS_CREATE_SOURCE_MUTATION,\n { errorPolicy: 'all', onError: onMutationError, refetchQueries: [{ query: COS_SOURCES_QUERY }] }\n );\n\nexport const useCosUpdateSourceMutation = () =>\n useMutation<{ cosUpdateSource: CosSource }, { id: string; input: CosUpdateSourceInput }>(\n COS_UPDATE_SOURCE_MUTATION,\n { errorPolicy: 'all', onError: onMutationError, refetchQueries: [{ query: COS_SOURCES_QUERY }] }\n );\n\nexport const useCosMarkSourceSyncedMutation = () =>\n useMutation<{ cosMarkSourceSynced: CosSource }, { id: string }>(COS_MARK_SOURCE_SYNCED_MUTATION, {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_SOURCES_QUERY }],\n });\n\nexport const useCosArchiveSourceMutation = () =>\n useMutation<{ cosArchiveSource: boolean }, { id: string }>(COS_ARCHIVE_SOURCE_MUTATION, {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_SOURCES_QUERY }],\n });\n\nexport const useCosCreateCollectionMutation = () =>\n useMutation<{ cosCreateCollection: CosCollection }, { input: CosCreateCollectionInput }>(\n COS_CREATE_COLLECTION_MUTATION,\n {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_COLLECTIONS_QUERY }],\n }\n );\n\nexport const useCosCreatePipelineMutation = () =>\n useMutation<{ cosCreatePipeline: CosPipeline }, { input: CosCreatePipelineInput }>(\n COS_CREATE_PIPELINE_MUTATION,\n {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_PIPELINES_QUERY }],\n }\n );\n\nexport const useCosUpdatePipelineMutation = () =>\n useMutation<{ cosUpdatePipeline: CosPipeline }, { id: string; input: CosUpdatePipelineInput }>(\n COS_UPDATE_PIPELINE_MUTATION,\n {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_PIPELINES_QUERY }],\n }\n );\n\nexport const useCosArchivePipelineMutation = () =>\n useMutation<{ cosArchivePipeline: boolean }, { id: string }>(COS_ARCHIVE_PIPELINE_MUTATION, {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_PIPELINES_QUERY }],\n });\n\nexport const useCosStartRunMutation = () =>\n useMutation<{ cosStartRun: CosPipelineRun }, { input: CosStartRunInput }>(\n COS_START_RUN_MUTATION,\n {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_RUNS_QUERY }],\n }\n );\n\nexport const useCosTransitionRunMutation = () =>\n useMutation<{ cosTransitionRun: CosPipelineRun }, { id: string; status: CosRunStatus }>(\n COS_TRANSITION_RUN_MUTATION,\n { errorPolicy: 'all', onError: onMutationError, refetchQueries: [{ query: COS_RUNS_QUERY }] }\n );\n\nexport const useCosAddRunStepMutation = () =>\n useMutation<{ cosAddRunStep: CosPipelineStep }, { input: CosAddRunStepInput }>(\n COS_ADD_RUN_STEP_MUTATION,\n { errorPolicy: 'all', onError: onMutationError }\n );\n\nexport const useCosCreateNotebookMutation = () =>\n useMutation<{ cosCreateNotebook: CosNotebook }, { input: CosCreateNotebookInput }>(\n COS_CREATE_NOTEBOOK_MUTATION,\n {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_NOTEBOOKS_QUERY }],\n }\n );\n\nexport const useCosUpdateNotebookMutation = () =>\n useMutation<{ cosUpdateNotebook: CosNotebook }, { id: string; input: CosUpdateNotebookInput }>(\n COS_UPDATE_NOTEBOOK_MUTATION,\n {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_NOTEBOOKS_QUERY }],\n }\n );\n\nexport const useCosArchiveNotebookMutation = () =>\n useMutation<{ cosArchiveNotebook: boolean }, { id: string }>(COS_ARCHIVE_NOTEBOOK_MUTATION, {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_NOTEBOOKS_QUERY }],\n });\n\nexport const useCosRunAnalysisMutation = () =>\n useMutation<{ cosRunAnalysis: CosAnalysis }, { input: CosRunAnalysisInput }>(\n COS_RUN_ANALYSIS_MUTATION,\n {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_ANALYSES_QUERY }],\n }\n );\n\nexport const useCosCompleteAnalysisMutation = () =>\n useMutation<\n { cosCompleteAnalysis: CosAnalysis },\n {\n id: string;\n status: Extract<CosAnalysisStatus, 'COMPLETED' | 'FAILED'>;\n results?: Record<string, unknown>;\n outputFileId?: string;\n }\n >(COS_COMPLETE_ANALYSIS_MUTATION, {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_ANALYSES_QUERY }],\n });\n\nexport const useCosCreateReleaseMutation = () =>\n useMutation<{ cosCreateRelease: CosRelease }, { input: CosCreateReleaseInput }>(\n COS_CREATE_RELEASE_MUTATION,\n {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_RELEASES_QUERY }],\n }\n );\n\nexport const useCosPublishReleaseMutation = () =>\n useMutation<{ cosPublishRelease: CosRelease }, { id: string; doi?: string }>(\n COS_PUBLISH_RELEASE_MUTATION,\n {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_RELEASES_QUERY }],\n }\n );\n\nexport const useCosGrantAccessMutation = () =>\n useMutation<{ cosGrantAccess: CosDataAccessGrant }, { input: CosGrantAccessInput }>(\n COS_GRANT_ACCESS_MUTATION,\n {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_ACCESS_GRANTS_QUERY }],\n }\n );\n\nexport const useCosRevokeAccessMutation = () =>\n useMutation<{ cosRevokeAccess: CosDataAccessGrant }, { id: string }>(COS_REVOKE_ACCESS_MUTATION, {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_ACCESS_GRANTS_QUERY }],\n });\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cosmicApi.js","names":[],"sources":["../../../src/cosmicintersection/api/cosmicApi.ts"],"sourcesContent":["/**\n * cosmicApi — hand-written typed data layer for the CosmicIntersection MFE.\n *\n * Mirrors the pattern in microfe-eventfullymanaged's eventApi.ts: inline `gql`\n * documents + `@apollo/client/react` hooks, with hand-written response/variables\n * types that track the wspace-cosmicintersection-svc subgraph SDL exactly. The\n * Apollo client is provided by the HOST app shell via React context (integrated\n * mode) — this module never constructs a client. Every `cos*` operation runs on\n * the workspace gateway (the default client in context).\n *\n * Scalar mapping: BigInt -> string, JSON -> Record<string, unknown>,\n * DateTime -> string (ISO).\n */\nimport { gql, type ErrorLike } from '@apollo/client';\nimport { useMutation, useQuery } from '@apollo/client/react';\n\nimport { notify } from '../lib/toast';\n\n/**\n * Shared mutation error sink. The gateway client runs with `errorPolicy: 'all'`,\n * so in-band GraphQL errors also invoke `onError`; wiring this on every write\n * mutation guarantees a failure is always surfaced to the user even if a caller\n * forgets to inspect the resolved result.\n */\nconst onMutationError = (error: ErrorLike): void => {\n notify.error('Something went wrong', error.message || 'Please try again.');\n};\n\n// ============================================================================\n// ENUMS (string-literal unions — exact SDL values)\n// ============================================================================\n\nexport type CosDatasetStatus = 'DRAFT' | 'INGESTING' | 'AVAILABLE' | 'DEPRECATED' | 'ARCHIVED';\nexport type CosAccessLevel = 'PUBLIC' | 'WORKSPACE' | 'RESTRICTED' | 'EMBARGOED';\nexport type CosSourceType =\n | 'TELESCOPE'\n | 'SATELLITE'\n | 'GROUND_SENSOR'\n | 'ARCHIVE'\n | 'API'\n | 'STREAM'\n | 'FILE_DROP'\n | 'SIMULATION';\nexport type CosSourceStatus =\n | 'CONFIGURING'\n | 'CONNECTED'\n | 'SYNCING'\n | 'DEGRADED'\n | 'ERROR'\n | 'DISABLED';\nexport type CosFieldType =\n | 'STRING'\n | 'INTEGER'\n | 'FLOAT'\n | 'BOOLEAN'\n | 'TIMESTAMP'\n | 'COORDINATE'\n | 'SPECTRUM'\n | 'GEOMETRY'\n | 'IMAGE_REF'\n | 'JSON';\nexport type CosPipelineStatus = 'DRAFT' | 'ACTIVE' | 'PAUSED' | 'ARCHIVED';\nexport type CosPipelineTrigger = 'MANUAL' | 'SCHEDULED' | 'ON_INGEST' | 'WEBHOOK';\nexport type CosRunStatus = 'QUEUED' | 'RUNNING' | 'SUCCEEDED' | 'FAILED' | 'CANCELLED';\nexport type CosStepKind = 'INGEST' | 'CALIBRATE' | 'TRANSFORM' | 'ANALYZE' | 'EXPORT' | 'NOTIFY';\nexport type CosNotebookStatus = 'DRAFT' | 'RUNNING' | 'PUBLISHED' | 'ARCHIVED';\nexport type CosAnalysisStatus = 'PENDING' | 'RUNNING' | 'COMPLETED' | 'FAILED';\nexport type CosReleaseStatus = 'DRAFT' | 'UNDER_REVIEW' | 'PUBLISHED' | 'RETRACTED';\nexport type CosGrantStatus = 'PENDING' | 'ACTIVE' | 'EXPIRED' | 'REVOKED';\n\n// ============================================================================\n// ENTITY TYPES\n// ============================================================================\n\n/** Federated wspace-files File stub — only `{ id }` is resolvable in this subgraph. */\nexport interface CosFileRef {\n id: string;\n}\n\nexport interface CosSchemaField {\n id: string;\n workspaceId: string;\n datasetId: string;\n name: string;\n fieldType: CosFieldType;\n unit?: string | null;\n description?: string | null;\n nullable: boolean;\n position: number;\n provenance?: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CosDataset {\n id: string;\n workspaceId: string;\n name: string;\n description?: string | null;\n status: CosDatasetStatus;\n accessLevel: CosAccessLevel;\n format?: string | null;\n sourceId?: string | null;\n collectionId?: string | null;\n /** BigInt returned as a numeric string. */\n rowCount: string;\n /** BigInt returned as a numeric string. */\n sizeBytes: string;\n version: number;\n lineageCaptured: boolean;\n coverage?: Record<string, unknown> | null;\n ingestedAt?: string | null;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n // Relations — only present when the operation selects them (detail queries).\n source?: CosSource | null;\n collection?: CosCollection | null;\n file?: CosFileRef | null;\n schemaFields?: CosSchemaField[];\n}\n\nexport interface CosSource {\n id: string;\n workspaceId: string;\n name: string;\n description?: string | null;\n type: CosSourceType;\n status: CosSourceStatus;\n endpoint?: string | null;\n config?: Record<string, unknown> | null;\n lastSyncedAt?: string | null;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n // Relation — present only on detail queries.\n datasets?: CosDataset[];\n}\n\nexport interface CosCollection {\n id: string;\n workspaceId: string;\n name: string;\n slug?: string | null;\n description?: string | null;\n isPublic: boolean;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n // Relation — present only on detail queries.\n datasets?: CosDataset[];\n}\n\nexport interface CosPipeline {\n id: string;\n workspaceId: string;\n name: string;\n description?: string | null;\n status: CosPipelineStatus;\n trigger: CosPipelineTrigger;\n schedule?: string | null;\n definition?: Record<string, unknown> | null;\n version: number;\n lastRunAt?: string | null;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n // Relation — present only on detail queries.\n runs?: CosPipelineRun[];\n}\n\nexport interface CosPipelineRun {\n id: string;\n workspaceId: string;\n pipelineId: string;\n runNumber: number;\n status: CosRunStatus;\n datasetId?: string | null;\n params?: Record<string, unknown> | null;\n metrics?: Record<string, unknown> | null;\n triggeredBy?: string | null;\n startedAt?: string | null;\n finishedAt?: string | null;\n durationMs?: number | null;\n errorMessage?: string | null;\n createdAt: string;\n updatedAt: string;\n // Relations — present only on detail queries.\n pipeline?: CosPipeline | null;\n steps?: CosPipelineStep[];\n}\n\nexport interface CosPipelineStep {\n id: string;\n workspaceId: string;\n runId: string;\n name: string;\n kind: CosStepKind;\n position: number;\n status: CosRunStatus;\n inputs?: Record<string, unknown> | null;\n outputs?: Record<string, unknown> | null;\n logsRef?: string | null;\n startedAt?: string | null;\n finishedAt?: string | null;\n durationMs?: number | null;\n errorMessage?: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CosNotebook {\n id: string;\n workspaceId: string;\n title: string;\n description?: string | null;\n status: CosNotebookStatus;\n runtime?: string | null;\n environment?: Record<string, unknown> | null;\n datasetIds: string[];\n isShared: boolean;\n shareSlug?: string | null;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n // Relations — present only on detail queries.\n file?: CosFileRef | null;\n analyses?: CosAnalysis[];\n releases?: CosRelease[];\n}\n\nexport interface CosAnalysis {\n id: string;\n workspaceId: string;\n title: string;\n status: CosAnalysisStatus;\n method?: string | null;\n aiAssisted: boolean;\n notebookId?: string | null;\n datasetId?: string | null;\n results?: Record<string, unknown> | null;\n outputFile?: CosFileRef | null;\n startedAt?: string | null;\n finishedAt?: string | null;\n errorMessage?: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CosRelease {\n id: string;\n workspaceId: string;\n title: string;\n version: string;\n status: CosReleaseStatus;\n abstract?: string | null;\n authors: string[];\n datasetIds: string[];\n notebookId?: string | null;\n doi?: string | null;\n license?: string | null;\n publishedAt?: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CosDataAccessGrant {\n id: string;\n workspaceId: string;\n datasetId: string;\n granteeId: string;\n status: CosGrantStatus;\n scopes: string[];\n reason?: string | null;\n grantedAt?: string | null;\n expiresAt?: string | null;\n revokedAt?: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\n// ============================================================================\n// PAGINATION / CONNECTIONS\n// ============================================================================\n\nexport interface CosPageInfo {\n hasMore: boolean;\n cursor?: string | null;\n}\n\nexport interface CosConnection<T> {\n items: T[];\n pageInfo: CosPageInfo;\n}\n\n/** Offset-based pagination input (PaginationInput in the SDL; limit defaults to 50). */\nexport interface CosPaginationInput {\n limit?: number;\n offset?: number;\n cursor?: string;\n}\n\n// ============================================================================\n// INPUT TYPES\n// ============================================================================\n\nexport interface CosCreateDatasetInput {\n name: string;\n description?: string;\n status?: CosDatasetStatus;\n accessLevel?: CosAccessLevel;\n format?: string;\n sourceId?: string;\n collectionId?: string;\n fileId?: string;\n coverage?: Record<string, unknown>;\n tags?: string[];\n}\n\nexport interface CosUpdateDatasetInput {\n name?: string;\n description?: string;\n accessLevel?: CosAccessLevel;\n format?: string;\n collectionId?: string;\n coverage?: Record<string, unknown>;\n tags?: string[];\n}\n\nexport interface CosAddSchemaFieldInput {\n datasetId: string;\n name: string;\n fieldType?: CosFieldType;\n unit?: string;\n description?: string;\n nullable?: boolean;\n position?: number;\n provenance?: string;\n}\n\nexport interface CosCreateSourceInput {\n name: string;\n type?: CosSourceType;\n status?: CosSourceStatus;\n description?: string;\n endpoint?: string;\n credentialRef?: string;\n config?: Record<string, unknown>;\n tags?: string[];\n}\n\nexport interface CosUpdateSourceInput {\n name?: string;\n type?: CosSourceType;\n status?: CosSourceStatus;\n description?: string;\n endpoint?: string;\n credentialRef?: string;\n config?: Record<string, unknown>;\n tags?: string[];\n}\n\nexport interface CosCreateCollectionInput {\n name: string;\n slug?: string;\n description?: string;\n isPublic?: boolean;\n tags?: string[];\n}\n\n/** All fields optional — only the provided keys are updated (CosUpdateCollectionInput in the SDL). */\nexport interface CosUpdateCollectionInput {\n name?: string;\n slug?: string;\n description?: string;\n isPublic?: boolean;\n tags?: string[];\n}\n\nexport interface CosCreatePipelineInput {\n name: string;\n description?: string;\n trigger?: CosPipelineTrigger;\n schedule?: string;\n definition?: Record<string, unknown>;\n tags?: string[];\n}\n\nexport interface CosUpdatePipelineInput {\n name?: string;\n description?: string;\n status?: CosPipelineStatus;\n trigger?: CosPipelineTrigger;\n schedule?: string;\n definition?: Record<string, unknown>;\n tags?: string[];\n}\n\nexport interface CosStartRunInput {\n pipelineId: string;\n datasetId?: string;\n params?: Record<string, unknown>;\n}\n\nexport interface CosAddRunStepInput {\n runId: string;\n name: string;\n kind?: CosStepKind;\n inputs?: Record<string, unknown>;\n position?: number;\n}\n\nexport interface CosCreateNotebookInput {\n title: string;\n description?: string;\n runtime?: string;\n environment?: Record<string, unknown>;\n datasetIds?: string[];\n fileId?: string;\n tags?: string[];\n}\n\nexport interface CosUpdateNotebookInput {\n title?: string;\n description?: string;\n status?: CosNotebookStatus;\n runtime?: string;\n environment?: Record<string, unknown>;\n datasetIds?: string[];\n isShared?: boolean;\n shareSlug?: string;\n tags?: string[];\n}\n\nexport interface CosRunAnalysisInput {\n title: string;\n method?: string;\n aiAssisted?: boolean;\n notebookId?: string;\n datasetId?: string;\n}\n\nexport interface CosCreateReleaseInput {\n title: string;\n version?: string;\n abstract?: string;\n authors?: string[];\n datasetIds?: string[];\n notebookId?: string;\n license?: string;\n}\n\nexport interface CosGrantAccessInput {\n datasetId: string;\n granteeId: string;\n scopes?: string[];\n reason?: string;\n expiresAt?: string;\n}\n\n// ============================================================================\n// GQL DOCUMENTS — QUERIES\n// ============================================================================\n\nexport const COS_HEALTH_QUERY = gql`\n query CosHealth {\n cosHealth\n }\n`;\n\nexport const COS_DATASETS_QUERY = gql`\n query CosListDatasets(\n $collectionId: ID\n $sourceId: ID\n $status: CosDatasetStatus\n $pagination: PaginationInput\n ) {\n cosListDatasets(\n collectionId: $collectionId\n sourceId: $sourceId\n status: $status\n pagination: $pagination\n ) {\n items {\n id\n workspaceId\n name\n description\n status\n accessLevel\n format\n sourceId\n collectionId\n rowCount\n sizeBytes\n version\n lineageCaptured\n ingestedAt\n tags\n createdAt\n updatedAt\n }\n pageInfo {\n hasMore\n cursor\n }\n }\n }\n`;\n\nexport const COS_DATASET_QUERY = gql`\n query CosDataset($id: ID!) {\n cosDataset(id: $id) {\n id\n workspaceId\n name\n description\n status\n accessLevel\n format\n sourceId\n collectionId\n rowCount\n sizeBytes\n version\n lineageCaptured\n coverage\n ingestedAt\n tags\n createdAt\n updatedAt\n file {\n id\n }\n source {\n id\n name\n type\n status\n }\n collection {\n id\n name\n slug\n }\n schemaFields {\n id\n datasetId\n name\n fieldType\n unit\n description\n nullable\n position\n provenance\n createdAt\n updatedAt\n }\n }\n }\n`;\n\nexport const COS_SOURCES_QUERY = gql`\n query CosListSources(\n $type: CosSourceType\n $status: CosSourceStatus\n $pagination: PaginationInput\n ) {\n cosListSources(type: $type, status: $status, pagination: $pagination) {\n items {\n id\n workspaceId\n name\n description\n type\n status\n endpoint\n config\n lastSyncedAt\n tags\n createdAt\n updatedAt\n }\n pageInfo {\n hasMore\n cursor\n }\n }\n }\n`;\n\nexport const COS_SOURCE_QUERY = gql`\n query CosSource($id: ID!) {\n cosSource(id: $id) {\n id\n workspaceId\n name\n description\n type\n status\n endpoint\n config\n lastSyncedAt\n tags\n createdAt\n updatedAt\n datasets {\n id\n name\n status\n accessLevel\n rowCount\n updatedAt\n }\n }\n }\n`;\n\nexport const COS_COLLECTIONS_QUERY = gql`\n query CosListCollections {\n cosListCollections {\n id\n workspaceId\n name\n slug\n description\n isPublic\n tags\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_COLLECTION_QUERY = gql`\n query CosCollection($id: ID!) {\n cosCollection(id: $id) {\n id\n workspaceId\n name\n slug\n description\n isPublic\n tags\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_SCHEMA_FIELDS_QUERY = gql`\n query CosListSchemaFields($datasetId: ID!) {\n cosListSchemaFields(datasetId: $datasetId) {\n id\n workspaceId\n datasetId\n name\n fieldType\n unit\n description\n nullable\n position\n provenance\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_PIPELINES_QUERY = gql`\n query CosListPipelines($status: CosPipelineStatus, $pagination: PaginationInput) {\n cosListPipelines(status: $status, pagination: $pagination) {\n items {\n id\n workspaceId\n name\n description\n status\n trigger\n schedule\n version\n lastRunAt\n tags\n createdAt\n updatedAt\n }\n pageInfo {\n hasMore\n cursor\n }\n }\n }\n`;\n\nexport const COS_PIPELINE_QUERY = gql`\n query CosPipeline($id: ID!) {\n cosPipeline(id: $id) {\n id\n workspaceId\n name\n description\n status\n trigger\n schedule\n definition\n version\n lastRunAt\n tags\n createdAt\n updatedAt\n runs {\n id\n runNumber\n status\n datasetId\n startedAt\n finishedAt\n durationMs\n createdAt\n }\n }\n }\n`;\n\nexport const COS_RUNS_QUERY = gql`\n query CosListRuns($pipelineId: ID, $status: CosRunStatus, $pagination: PaginationInput) {\n cosListRuns(pipelineId: $pipelineId, status: $status, pagination: $pagination) {\n items {\n id\n workspaceId\n pipelineId\n runNumber\n status\n datasetId\n triggeredBy\n startedAt\n finishedAt\n durationMs\n errorMessage\n createdAt\n updatedAt\n }\n pageInfo {\n hasMore\n cursor\n }\n }\n }\n`;\n\nexport const COS_RUN_QUERY = gql`\n query CosRun($id: ID!) {\n cosRun(id: $id) {\n id\n workspaceId\n pipelineId\n runNumber\n status\n datasetId\n params\n metrics\n triggeredBy\n startedAt\n finishedAt\n durationMs\n errorMessage\n createdAt\n updatedAt\n pipeline {\n id\n name\n status\n }\n steps {\n id\n runId\n name\n kind\n position\n status\n startedAt\n finishedAt\n durationMs\n errorMessage\n }\n }\n }\n`;\n\nexport const COS_RUN_STEPS_QUERY = gql`\n query CosListRunSteps($runId: ID!) {\n cosListRunSteps(runId: $runId) {\n id\n workspaceId\n runId\n name\n kind\n position\n status\n inputs\n outputs\n logsRef\n startedAt\n finishedAt\n durationMs\n errorMessage\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_NOTEBOOKS_QUERY = gql`\n query CosListNotebooks($status: CosNotebookStatus, $pagination: PaginationInput) {\n cosListNotebooks(status: $status, pagination: $pagination) {\n items {\n id\n workspaceId\n title\n description\n status\n runtime\n datasetIds\n isShared\n shareSlug\n tags\n createdAt\n updatedAt\n }\n pageInfo {\n hasMore\n cursor\n }\n }\n }\n`;\n\nexport const COS_NOTEBOOK_QUERY = gql`\n query CosNotebook($id: ID!) {\n cosNotebook(id: $id) {\n id\n workspaceId\n title\n description\n status\n runtime\n environment\n datasetIds\n isShared\n shareSlug\n tags\n createdAt\n updatedAt\n file {\n id\n }\n analyses {\n id\n title\n status\n aiAssisted\n method\n createdAt\n }\n releases {\n id\n title\n version\n status\n publishedAt\n }\n }\n }\n`;\n\nexport const COS_ANALYSES_QUERY = gql`\n query CosListAnalyses($datasetId: ID, $notebookId: ID, $status: CosAnalysisStatus) {\n cosListAnalyses(datasetId: $datasetId, notebookId: $notebookId, status: $status) {\n id\n workspaceId\n title\n status\n method\n aiAssisted\n notebookId\n datasetId\n results\n outputFile {\n id\n }\n startedAt\n finishedAt\n errorMessage\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_RELEASES_QUERY = gql`\n query CosListReleases($status: CosReleaseStatus, $pagination: PaginationInput) {\n cosListReleases(status: $status, pagination: $pagination) {\n items {\n id\n workspaceId\n title\n version\n status\n abstract\n authors\n datasetIds\n notebookId\n doi\n license\n publishedAt\n createdAt\n updatedAt\n }\n pageInfo {\n hasMore\n cursor\n }\n }\n }\n`;\n\nexport const COS_ACCESS_GRANTS_QUERY = gql`\n query CosListAccessGrants($datasetId: ID, $status: CosGrantStatus) {\n cosListAccessGrants(datasetId: $datasetId, status: $status) {\n id\n workspaceId\n datasetId\n granteeId\n status\n scopes\n reason\n grantedAt\n expiresAt\n revokedAt\n createdAt\n updatedAt\n }\n }\n`;\n\n// ============================================================================\n// PLATFORM REUSE — activity feed (wspace-activity-svc, federated on the\n// workspace supergraph). The cos mutation-audit plugin already writes these\n// ActivityLog rows via be-sdk `trackOperation`; this is the read surface,\n// scoped to a single cos entity by `resourceId`. Only scalar fields are\n// selected so no cross-subgraph entity resolution is required.\n// ============================================================================\n\nexport const COS_ACTIVITY_BY_RESOURCE_QUERY = gql`\n query CosResourceActivity($filter: ActivityLogFilter) {\n getActivities(filter: $filter) {\n id\n action\n description\n resourceType\n resourceId\n userId\n timestamp\n }\n }\n`;\n\n// ============================================================================\n// GQL DOCUMENTS — MUTATIONS\n// ============================================================================\n\nexport const COS_CREATE_DATASET_MUTATION = gql`\n mutation CosCreateDataset($input: CosCreateDatasetInput!) {\n cosCreateDataset(input: $input) {\n id\n name\n status\n accessLevel\n sourceId\n collectionId\n tags\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_UPDATE_DATASET_MUTATION = gql`\n mutation CosUpdateDataset($id: ID!, $input: CosUpdateDatasetInput!) {\n cosUpdateDataset(id: $id, input: $input) {\n id\n name\n description\n status\n accessLevel\n format\n collectionId\n tags\n updatedAt\n }\n }\n`;\n\nexport const COS_PUBLISH_DATASET_MUTATION = gql`\n mutation CosPublishDataset($id: ID!) {\n cosPublishDataset(id: $id) {\n id\n status\n ingestedAt\n updatedAt\n }\n }\n`;\n\nexport const COS_ARCHIVE_DATASET_MUTATION = gql`\n mutation CosArchiveDataset($id: ID!) {\n cosArchiveDataset(id: $id)\n }\n`;\n\nexport const COS_ADD_SCHEMA_FIELD_MUTATION = gql`\n mutation CosAddSchemaField($input: CosAddSchemaFieldInput!) {\n cosAddSchemaField(input: $input) {\n id\n workspaceId\n datasetId\n name\n fieldType\n unit\n description\n nullable\n position\n provenance\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_CREATE_SOURCE_MUTATION = gql`\n mutation CosCreateSource($input: CosCreateSourceInput!) {\n cosCreateSource(input: $input) {\n id\n name\n type\n status\n endpoint\n tags\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_UPDATE_SOURCE_MUTATION = gql`\n mutation CosUpdateSource($id: ID!, $input: CosUpdateSourceInput!) {\n cosUpdateSource(id: $id, input: $input) {\n id\n name\n description\n type\n status\n endpoint\n tags\n updatedAt\n }\n }\n`;\n\nexport const COS_MARK_SOURCE_SYNCED_MUTATION = gql`\n mutation CosMarkSourceSynced($id: ID!) {\n cosMarkSourceSynced(id: $id) {\n id\n status\n lastSyncedAt\n updatedAt\n }\n }\n`;\n\nexport const COS_ARCHIVE_SOURCE_MUTATION = gql`\n mutation CosArchiveSource($id: ID!) {\n cosArchiveSource(id: $id)\n }\n`;\n\nexport const COS_CREATE_COLLECTION_MUTATION = gql`\n mutation CosCreateCollection($input: CosCreateCollectionInput!) {\n cosCreateCollection(input: $input) {\n id\n name\n slug\n description\n isPublic\n tags\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_UPDATE_COLLECTION_MUTATION = gql`\n mutation CosUpdateCollection($id: ID!, $input: CosUpdateCollectionInput!) {\n cosUpdateCollection(id: $id, input: $input) {\n id\n name\n slug\n description\n isPublic\n tags\n updatedAt\n }\n }\n`;\n\nexport const COS_ARCHIVE_COLLECTION_MUTATION = gql`\n mutation CosArchiveCollection($id: ID!) {\n cosArchiveCollection(id: $id)\n }\n`;\n\nexport const COS_CREATE_PIPELINE_MUTATION = gql`\n mutation CosCreatePipeline($input: CosCreatePipelineInput!) {\n cosCreatePipeline(input: $input) {\n id\n name\n status\n trigger\n schedule\n version\n tags\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_UPDATE_PIPELINE_MUTATION = gql`\n mutation CosUpdatePipeline($id: ID!, $input: CosUpdatePipelineInput!) {\n cosUpdatePipeline(id: $id, input: $input) {\n id\n name\n description\n status\n trigger\n schedule\n tags\n updatedAt\n }\n }\n`;\n\nexport const COS_ARCHIVE_PIPELINE_MUTATION = gql`\n mutation CosArchivePipeline($id: ID!) {\n cosArchivePipeline(id: $id)\n }\n`;\n\nexport const COS_START_RUN_MUTATION = gql`\n mutation CosStartRun($input: CosStartRunInput!) {\n cosStartRun(input: $input) {\n id\n pipelineId\n runNumber\n status\n datasetId\n startedAt\n createdAt\n }\n }\n`;\n\nexport const COS_TRANSITION_RUN_MUTATION = gql`\n mutation CosTransitionRun($id: ID!, $status: CosRunStatus!) {\n cosTransitionRun(id: $id, status: $status) {\n id\n status\n startedAt\n finishedAt\n durationMs\n updatedAt\n }\n }\n`;\n\nexport const COS_ADD_RUN_STEP_MUTATION = gql`\n mutation CosAddRunStep($input: CosAddRunStepInput!) {\n cosAddRunStep(input: $input) {\n id\n runId\n name\n kind\n position\n status\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_CREATE_NOTEBOOK_MUTATION = gql`\n mutation CosCreateNotebook($input: CosCreateNotebookInput!) {\n cosCreateNotebook(input: $input) {\n id\n title\n status\n runtime\n datasetIds\n tags\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_UPDATE_NOTEBOOK_MUTATION = gql`\n mutation CosUpdateNotebook($id: ID!, $input: CosUpdateNotebookInput!) {\n cosUpdateNotebook(id: $id, input: $input) {\n id\n title\n description\n status\n runtime\n datasetIds\n isShared\n shareSlug\n tags\n updatedAt\n }\n }\n`;\n\nexport const COS_ARCHIVE_NOTEBOOK_MUTATION = gql`\n mutation CosArchiveNotebook($id: ID!) {\n cosArchiveNotebook(id: $id)\n }\n`;\n\nexport const COS_RUN_ANALYSIS_MUTATION = gql`\n mutation CosRunAnalysis($input: CosRunAnalysisInput!) {\n cosRunAnalysis(input: $input) {\n id\n title\n status\n method\n aiAssisted\n notebookId\n datasetId\n startedAt\n createdAt\n }\n }\n`;\n\nexport const COS_COMPLETE_ANALYSIS_MUTATION = gql`\n mutation CosCompleteAnalysis(\n $id: ID!\n $status: CosAnalysisStatus!\n $results: JSON\n $outputFileId: ID\n ) {\n cosCompleteAnalysis(id: $id, status: $status, results: $results, outputFileId: $outputFileId) {\n id\n status\n results\n finishedAt\n errorMessage\n outputFile {\n id\n }\n updatedAt\n }\n }\n`;\n\nexport const COS_CREATE_RELEASE_MUTATION = gql`\n mutation CosCreateRelease($input: CosCreateReleaseInput!) {\n cosCreateRelease(input: $input) {\n id\n title\n version\n status\n authors\n datasetIds\n notebookId\n license\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_PUBLISH_RELEASE_MUTATION = gql`\n mutation CosPublishRelease($id: ID!, $doi: String) {\n cosPublishRelease(id: $id, doi: $doi) {\n id\n status\n doi\n publishedAt\n updatedAt\n }\n }\n`;\n\nexport const COS_GRANT_ACCESS_MUTATION = gql`\n mutation CosGrantAccess($input: CosGrantAccessInput!) {\n cosGrantAccess(input: $input) {\n id\n datasetId\n granteeId\n status\n scopes\n reason\n grantedAt\n expiresAt\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const COS_REVOKE_ACCESS_MUTATION = gql`\n mutation CosRevokeAccess($id: ID!) {\n cosRevokeAccess(id: $id) {\n id\n status\n revokedAt\n updatedAt\n }\n }\n`;\n\n// ============================================================================\n// RESPONSE / VARIABLES TYPES\n// ============================================================================\n\nexport interface CosHealthQueryData {\n cosHealth: string;\n}\n\nexport interface CosDatasetsQueryData {\n cosListDatasets: CosConnection<CosDataset>;\n}\nexport interface CosDatasetsQueryVars {\n collectionId?: string;\n sourceId?: string;\n status?: CosDatasetStatus;\n pagination?: CosPaginationInput;\n}\n\nexport interface CosDatasetQueryData {\n cosDataset: CosDataset | null;\n}\n\nexport interface CosSourcesQueryData {\n cosListSources: CosConnection<CosSource>;\n}\nexport interface CosSourcesQueryVars {\n type?: CosSourceType;\n status?: CosSourceStatus;\n pagination?: CosPaginationInput;\n}\n\nexport interface CosSourceQueryData {\n cosSource: CosSource | null;\n}\n\nexport interface CosCollectionsQueryData {\n cosListCollections: CosCollection[];\n}\n\nexport interface CosCollectionQueryData {\n cosCollection: CosCollection | null;\n}\n\nexport interface CosSchemaFieldsQueryData {\n cosListSchemaFields: CosSchemaField[];\n}\n\nexport interface CosPipelinesQueryData {\n cosListPipelines: CosConnection<CosPipeline>;\n}\nexport interface CosPipelinesQueryVars {\n status?: CosPipelineStatus;\n pagination?: CosPaginationInput;\n}\n\nexport interface CosPipelineQueryData {\n cosPipeline: CosPipeline | null;\n}\n\nexport interface CosRunsQueryData {\n cosListRuns: CosConnection<CosPipelineRun>;\n}\nexport interface CosRunsQueryVars {\n pipelineId?: string;\n status?: CosRunStatus;\n pagination?: CosPaginationInput;\n}\n\nexport interface CosRunQueryData {\n cosRun: CosPipelineRun | null;\n}\n\nexport interface CosRunStepsQueryData {\n cosListRunSteps: CosPipelineStep[];\n}\n\nexport interface CosNotebooksQueryData {\n cosListNotebooks: CosConnection<CosNotebook>;\n}\nexport interface CosNotebooksQueryVars {\n status?: CosNotebookStatus;\n pagination?: CosPaginationInput;\n}\n\nexport interface CosNotebookQueryData {\n cosNotebook: CosNotebook | null;\n}\n\nexport interface CosAnalysesQueryData {\n cosListAnalyses: CosAnalysis[];\n}\nexport interface CosAnalysesQueryVars {\n datasetId?: string;\n notebookId?: string;\n status?: CosAnalysisStatus;\n}\n\nexport interface CosReleasesQueryData {\n cosListReleases: CosConnection<CosRelease>;\n}\nexport interface CosReleasesQueryVars {\n status?: CosReleaseStatus;\n pagination?: CosPaginationInput;\n}\n\nexport interface CosAccessGrantsQueryData {\n cosListAccessGrants: CosDataAccessGrant[];\n}\nexport interface CosAccessGrantsQueryVars {\n datasetId?: string;\n status?: CosGrantStatus;\n}\n\n/** A single platform activity record (subset of wspace-activity-svc ActivityLog). */\nexport interface CosActivityEntry {\n id: string;\n action: string;\n description?: string | null;\n resourceType?: string | null;\n resourceId?: string | null;\n userId: string;\n timestamp: string;\n}\n\nexport interface CosActivityQueryData {\n getActivities: CosActivityEntry[];\n}\n\n/** Mirrors ActivityLogFilter — only the fields the cos activity panel needs. */\nexport interface CosActivityFilter {\n workspaceId?: string;\n resourceId?: string;\n resourceType?: string;\n limit?: number;\n offset?: number;\n}\n\nexport interface CosActivityQueryVars {\n filter?: CosActivityFilter;\n}\n\n// ============================================================================\n// QUERY HOOKS\n// ============================================================================\n\nexport const useCosHealthQuery = () => useQuery<CosHealthQueryData>(COS_HEALTH_QUERY);\n\nexport const useCosDatasetsQuery = (variables: CosDatasetsQueryVars = {}) =>\n useQuery<CosDatasetsQueryData, CosDatasetsQueryVars>(COS_DATASETS_QUERY, { variables });\n\nexport const useCosDatasetQuery = (id: string) =>\n useQuery<CosDatasetQueryData, { id: string }>(COS_DATASET_QUERY, {\n variables: { id },\n skip: !id,\n });\n\nexport const useCosSourcesQuery = (variables: CosSourcesQueryVars = {}) =>\n useQuery<CosSourcesQueryData, CosSourcesQueryVars>(COS_SOURCES_QUERY, { variables });\n\nexport const useCosSourceQuery = (id: string) =>\n useQuery<CosSourceQueryData, { id: string }>(COS_SOURCE_QUERY, {\n variables: { id },\n skip: !id,\n });\n\nexport const useCosCollectionsQuery = () =>\n useQuery<CosCollectionsQueryData>(COS_COLLECTIONS_QUERY);\n\nexport const useCosCollectionQuery = (id: string) =>\n useQuery<CosCollectionQueryData, { id: string }>(COS_COLLECTION_QUERY, {\n variables: { id },\n skip: !id,\n });\n\nexport const useCosSchemaFieldsQuery = (datasetId: string) =>\n useQuery<CosSchemaFieldsQueryData, { datasetId: string }>(COS_SCHEMA_FIELDS_QUERY, {\n variables: { datasetId },\n skip: !datasetId,\n });\n\nexport const useCosPipelinesQuery = (variables: CosPipelinesQueryVars = {}) =>\n useQuery<CosPipelinesQueryData, CosPipelinesQueryVars>(COS_PIPELINES_QUERY, { variables });\n\nexport const useCosPipelineQuery = (id: string) =>\n useQuery<CosPipelineQueryData, { id: string }>(COS_PIPELINE_QUERY, {\n variables: { id },\n skip: !id,\n });\n\nexport const useCosRunsQuery = (variables: CosRunsQueryVars = {}) =>\n useQuery<CosRunsQueryData, CosRunsQueryVars>(COS_RUNS_QUERY, { variables });\n\nexport const useCosRunQuery = (id: string) =>\n useQuery<CosRunQueryData, { id: string }>(COS_RUN_QUERY, {\n variables: { id },\n skip: !id,\n });\n\nexport const useCosRunStepsQuery = (runId: string) =>\n useQuery<CosRunStepsQueryData, { runId: string }>(COS_RUN_STEPS_QUERY, {\n variables: { runId },\n skip: !runId,\n });\n\nexport const useCosNotebooksQuery = (variables: CosNotebooksQueryVars = {}) =>\n useQuery<CosNotebooksQueryData, CosNotebooksQueryVars>(COS_NOTEBOOKS_QUERY, { variables });\n\nexport const useCosNotebookQuery = (id: string) =>\n useQuery<CosNotebookQueryData, { id: string }>(COS_NOTEBOOK_QUERY, {\n variables: { id },\n skip: !id,\n });\n\nexport const useCosAnalysesQuery = (variables: CosAnalysesQueryVars = {}) =>\n useQuery<CosAnalysesQueryData, CosAnalysesQueryVars>(COS_ANALYSES_QUERY, { variables });\n\nexport const useCosReleasesQuery = (variables: CosReleasesQueryVars = {}) =>\n useQuery<CosReleasesQueryData, CosReleasesQueryVars>(COS_RELEASES_QUERY, { variables });\n\nexport const useCosAccessGrantsQuery = (variables: CosAccessGrantsQueryVars = {}) =>\n useQuery<CosAccessGrantsQueryData, CosAccessGrantsQueryVars>(COS_ACCESS_GRANTS_QUERY, {\n variables,\n });\n\n/**\n * Resource-scoped platform activity for a single cos entity. RBAC on\n * `getActivities` scopes on `filter.workspaceId`, so both a workspaceId and the\n * entity's resourceId are required — the query is skipped until both are known.\n */\nexport const useCosResourceActivityQuery = (params: {\n workspaceId?: string;\n resourceId: string;\n resourceType?: string;\n limit?: number;\n}) => {\n const { workspaceId, resourceId, resourceType, limit = 20 } = params;\n return useQuery<CosActivityQueryData, CosActivityQueryVars>(COS_ACTIVITY_BY_RESOURCE_QUERY, {\n variables: { filter: { workspaceId, resourceId, resourceType, limit } },\n skip: !workspaceId || !resourceId,\n fetchPolicy: 'cache-and-network',\n });\n};\n\n// ============================================================================\n// MUTATION HOOKS\n// ============================================================================\n\nexport const useCosCreateDatasetMutation = () =>\n useMutation<{ cosCreateDataset: CosDataset }, { input: CosCreateDatasetInput }>(\n COS_CREATE_DATASET_MUTATION,\n {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_DATASETS_QUERY }],\n }\n );\n\nexport const useCosUpdateDatasetMutation = () =>\n useMutation<{ cosUpdateDataset: CosDataset }, { id: string; input: CosUpdateDatasetInput }>(\n COS_UPDATE_DATASET_MUTATION,\n {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_DATASETS_QUERY }],\n }\n );\n\nexport const useCosPublishDatasetMutation = () =>\n useMutation<{ cosPublishDataset: CosDataset }, { id: string }>(COS_PUBLISH_DATASET_MUTATION, {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_DATASETS_QUERY }],\n });\n\nexport const useCosArchiveDatasetMutation = () =>\n useMutation<{ cosArchiveDataset: boolean }, { id: string }>(COS_ARCHIVE_DATASET_MUTATION, {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_DATASETS_QUERY }],\n });\n\nexport const useCosAddSchemaFieldMutation = () =>\n useMutation<{ cosAddSchemaField: CosSchemaField }, { input: CosAddSchemaFieldInput }>(\n COS_ADD_SCHEMA_FIELD_MUTATION,\n { errorPolicy: 'all', onError: onMutationError }\n );\n\nexport const useCosCreateSourceMutation = () =>\n useMutation<{ cosCreateSource: CosSource }, { input: CosCreateSourceInput }>(\n COS_CREATE_SOURCE_MUTATION,\n { errorPolicy: 'all', onError: onMutationError, refetchQueries: [{ query: COS_SOURCES_QUERY }] }\n );\n\nexport const useCosUpdateSourceMutation = () =>\n useMutation<{ cosUpdateSource: CosSource }, { id: string; input: CosUpdateSourceInput }>(\n COS_UPDATE_SOURCE_MUTATION,\n { errorPolicy: 'all', onError: onMutationError, refetchQueries: [{ query: COS_SOURCES_QUERY }] }\n );\n\nexport const useCosMarkSourceSyncedMutation = () =>\n useMutation<{ cosMarkSourceSynced: CosSource }, { id: string }>(COS_MARK_SOURCE_SYNCED_MUTATION, {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_SOURCES_QUERY }],\n });\n\nexport const useCosArchiveSourceMutation = () =>\n useMutation<{ cosArchiveSource: boolean }, { id: string }>(COS_ARCHIVE_SOURCE_MUTATION, {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_SOURCES_QUERY }],\n });\n\nexport const useCosCreateCollectionMutation = () =>\n useMutation<{ cosCreateCollection: CosCollection }, { input: CosCreateCollectionInput }>(\n COS_CREATE_COLLECTION_MUTATION,\n {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_COLLECTIONS_QUERY }],\n }\n );\n\nexport const useCosUpdateCollectionMutation = () =>\n useMutation<\n { cosUpdateCollection: CosCollection },\n { id: string; input: CosUpdateCollectionInput }\n >(COS_UPDATE_COLLECTION_MUTATION, {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_COLLECTIONS_QUERY }],\n });\n\nexport const useCosArchiveCollectionMutation = () =>\n useMutation<{ cosArchiveCollection: boolean }, { id: string }>(COS_ARCHIVE_COLLECTION_MUTATION, {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_COLLECTIONS_QUERY }],\n });\n\nexport const useCosCreatePipelineMutation = () =>\n useMutation<{ cosCreatePipeline: CosPipeline }, { input: CosCreatePipelineInput }>(\n COS_CREATE_PIPELINE_MUTATION,\n {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_PIPELINES_QUERY }],\n }\n );\n\nexport const useCosUpdatePipelineMutation = () =>\n useMutation<{ cosUpdatePipeline: CosPipeline }, { id: string; input: CosUpdatePipelineInput }>(\n COS_UPDATE_PIPELINE_MUTATION,\n {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_PIPELINES_QUERY }],\n }\n );\n\nexport const useCosArchivePipelineMutation = () =>\n useMutation<{ cosArchivePipeline: boolean }, { id: string }>(COS_ARCHIVE_PIPELINE_MUTATION, {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_PIPELINES_QUERY }],\n });\n\nexport const useCosStartRunMutation = () =>\n useMutation<{ cosStartRun: CosPipelineRun }, { input: CosStartRunInput }>(\n COS_START_RUN_MUTATION,\n {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_RUNS_QUERY }],\n }\n );\n\nexport const useCosTransitionRunMutation = () =>\n useMutation<{ cosTransitionRun: CosPipelineRun }, { id: string; status: CosRunStatus }>(\n COS_TRANSITION_RUN_MUTATION,\n { errorPolicy: 'all', onError: onMutationError, refetchQueries: [{ query: COS_RUNS_QUERY }] }\n );\n\nexport const useCosAddRunStepMutation = () =>\n useMutation<{ cosAddRunStep: CosPipelineStep }, { input: CosAddRunStepInput }>(\n COS_ADD_RUN_STEP_MUTATION,\n { errorPolicy: 'all', onError: onMutationError }\n );\n\nexport const useCosCreateNotebookMutation = () =>\n useMutation<{ cosCreateNotebook: CosNotebook }, { input: CosCreateNotebookInput }>(\n COS_CREATE_NOTEBOOK_MUTATION,\n {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_NOTEBOOKS_QUERY }],\n }\n );\n\nexport const useCosUpdateNotebookMutation = () =>\n useMutation<{ cosUpdateNotebook: CosNotebook }, { id: string; input: CosUpdateNotebookInput }>(\n COS_UPDATE_NOTEBOOK_MUTATION,\n {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_NOTEBOOKS_QUERY }],\n }\n );\n\nexport const useCosArchiveNotebookMutation = () =>\n useMutation<{ cosArchiveNotebook: boolean }, { id: string }>(COS_ARCHIVE_NOTEBOOK_MUTATION, {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_NOTEBOOKS_QUERY }],\n });\n\nexport const useCosRunAnalysisMutation = () =>\n useMutation<{ cosRunAnalysis: CosAnalysis }, { input: CosRunAnalysisInput }>(\n COS_RUN_ANALYSIS_MUTATION,\n {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_ANALYSES_QUERY }],\n }\n );\n\nexport const useCosCompleteAnalysisMutation = () =>\n useMutation<\n { cosCompleteAnalysis: CosAnalysis },\n {\n id: string;\n status: Extract<CosAnalysisStatus, 'COMPLETED' | 'FAILED'>;\n results?: Record<string, unknown>;\n outputFileId?: string;\n }\n >(COS_COMPLETE_ANALYSIS_MUTATION, {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_ANALYSES_QUERY }],\n });\n\nexport const useCosCreateReleaseMutation = () =>\n useMutation<{ cosCreateRelease: CosRelease }, { input: CosCreateReleaseInput }>(\n COS_CREATE_RELEASE_MUTATION,\n {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_RELEASES_QUERY }],\n }\n );\n\nexport const useCosPublishReleaseMutation = () =>\n useMutation<{ cosPublishRelease: CosRelease }, { id: string; doi?: string }>(\n COS_PUBLISH_RELEASE_MUTATION,\n {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_RELEASES_QUERY }],\n }\n );\n\nexport const useCosGrantAccessMutation = () =>\n useMutation<{ cosGrantAccess: CosDataAccessGrant }, { input: CosGrantAccessInput }>(\n COS_GRANT_ACCESS_MUTATION,\n {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_ACCESS_GRANTS_QUERY }],\n }\n );\n\nexport const useCosRevokeAccessMutation = () =>\n useMutation<{ cosRevokeAccess: CosDataAccessGrant }, { id: string }>(COS_REVOKE_ACCESS_MUTATION, {\n errorPolicy: 'all',\n onError: onMutationError,\n refetchQueries: [{ query: COS_ACCESS_GRANTS_QUERY }],\n });\n"],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { useCosmicIntersection as e } from "../context/CosmicIntersectionContext.js";
|
|
2
|
+
import { useCosResourceActivityQuery as t } from "../api/cosmicApi.js";
|
|
3
|
+
import n from "./EmptyState.js";
|
|
4
|
+
import r from "./ErrorState.js";
|
|
5
|
+
import i from "./LoadingState.js";
|
|
6
|
+
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
7
|
+
import { History as s } from "lucide-react";
|
|
8
|
+
//#region src/cosmicintersection/components/ActivityFeedPanel.tsx
|
|
9
|
+
function c(e) {
|
|
10
|
+
return e.length <= 14 ? e : `${e.slice(0, 8)}…${e.slice(-4)}`;
|
|
11
|
+
}
|
|
12
|
+
function l(e) {
|
|
13
|
+
let t = new Date(e);
|
|
14
|
+
return Number.isNaN(t.getTime()) ? "—" : t.toLocaleString(void 0, {
|
|
15
|
+
year: "numeric",
|
|
16
|
+
month: "short",
|
|
17
|
+
day: "numeric",
|
|
18
|
+
hour: "2-digit",
|
|
19
|
+
minute: "2-digit"
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
function u({ resourceId: u, resourceType: d, limit: f, emptyDescription: p }) {
|
|
23
|
+
let { workspaceId: m } = e(), { data: h, loading: g, error: _, refetch: v } = t({
|
|
24
|
+
workspaceId: m,
|
|
25
|
+
resourceId: u,
|
|
26
|
+
resourceType: d,
|
|
27
|
+
limit: f
|
|
28
|
+
}), y = h?.getActivities ?? [];
|
|
29
|
+
return g && y.length === 0 ? /* @__PURE__ */ a(i, {
|
|
30
|
+
variant: "rows",
|
|
31
|
+
rows: 3,
|
|
32
|
+
label: "Loading activity…"
|
|
33
|
+
}) : _ ? /* @__PURE__ */ a(r, {
|
|
34
|
+
message: "We could not load activity for this record.",
|
|
35
|
+
onRetry: () => void v()
|
|
36
|
+
}) : y.length === 0 ? /* @__PURE__ */ a(n, {
|
|
37
|
+
icon: s,
|
|
38
|
+
title: "No activity recorded yet.",
|
|
39
|
+
description: p ?? "Changes to this record — updates, publishes and access grants — will appear here."
|
|
40
|
+
}) : /* @__PURE__ */ a("ul", {
|
|
41
|
+
className: "divide-y divide-border-seam rounded-card border border-border-default bg-bg-elevated",
|
|
42
|
+
children: y.map((e) => /* @__PURE__ */ o("li", {
|
|
43
|
+
className: "flex items-start justify-between gap-3 px-4 py-3",
|
|
44
|
+
children: [/* @__PURE__ */ o("div", {
|
|
45
|
+
className: "min-w-0",
|
|
46
|
+
children: [/* @__PURE__ */ a("p", {
|
|
47
|
+
className: "text-sm font-medium text-text-primary",
|
|
48
|
+
children: e.description?.trim() || e.action
|
|
49
|
+
}), /* @__PURE__ */ o("p", {
|
|
50
|
+
className: "mt-0.5 text-xs text-text-secondary",
|
|
51
|
+
children: [
|
|
52
|
+
e.description?.trim() ? `${e.action} · ` : "",
|
|
53
|
+
"by ",
|
|
54
|
+
c(e.userId)
|
|
55
|
+
]
|
|
56
|
+
})]
|
|
57
|
+
}), /* @__PURE__ */ a("time", {
|
|
58
|
+
dateTime: e.timestamp,
|
|
59
|
+
className: "shrink-0 whitespace-nowrap text-xs text-text-secondary",
|
|
60
|
+
children: l(e.timestamp)
|
|
61
|
+
})]
|
|
62
|
+
}, e.id))
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
export { u as default };
|
|
67
|
+
|
|
68
|
+
//# sourceMappingURL=ActivityFeedPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ActivityFeedPanel.js","names":[],"sources":["../../../src/cosmicintersection/components/ActivityFeedPanel.tsx"],"sourcesContent":["/**\n * ActivityFeedPanel — compact, resource-scoped audit trail for a cos entity,\n * reusing the platform wspace-activity-svc `getActivities` query (federated on\n * the workspace supergraph). The cos mutation-audit plugin already records these\n * ActivityLog rows via be-sdk `trackOperation`; this is purely the read surface.\n *\n * No fabricated data: when the backend has no activity for this resource the\n * panel shows an honest empty state rather than inventing history.\n */\nimport { History } from 'lucide-react';\n\nimport { useCosResourceActivityQuery } from '../api/cosmicApi';\nimport { useCosmicIntersection } from '../context/CosmicIntersectionContext';\nimport { EmptyState } from './EmptyState';\nimport { ErrorState } from './ErrorState';\nimport { LoadingState } from './LoadingState';\n\nfunction shortActor(userId: string): string {\n if (userId.length <= 14) {\n return userId;\n }\n return `${userId.slice(0, 8)}…${userId.slice(-4)}`;\n}\n\nfunction formatTimestamp(value: string): string {\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) {\n return '—';\n }\n return date.toLocaleString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n}\n\nexport interface ActivityFeedPanelProps {\n /** The cos entity id whose activity is shown (ActivityLog.resourceId). */\n resourceId: string;\n resourceType?: string;\n limit?: number;\n emptyDescription?: string;\n}\n\nexport function ActivityFeedPanel({\n resourceId,\n resourceType,\n limit,\n emptyDescription,\n}: ActivityFeedPanelProps) {\n const { workspaceId } = useCosmicIntersection();\n const { data, loading, error, refetch } = useCosResourceActivityQuery({\n workspaceId,\n resourceId,\n resourceType,\n limit,\n });\n\n const activities = data?.getActivities ?? [];\n\n if (loading && activities.length === 0) {\n return <LoadingState variant=\"rows\" rows={3} label=\"Loading activity…\" />;\n }\n\n if (error) {\n return (\n <ErrorState\n message=\"We could not load activity for this record.\"\n onRetry={() => void refetch()}\n />\n );\n }\n\n if (activities.length === 0) {\n return (\n <EmptyState\n icon={History}\n title=\"No activity recorded yet.\"\n description={\n emptyDescription ??\n 'Changes to this record — updates, publishes and access grants — will appear here.'\n }\n />\n );\n }\n\n return (\n <ul className=\"divide-y divide-border-seam rounded-card border border-border-default bg-bg-elevated\">\n {activities.map((entry) => {\n const primary = entry.description?.trim() || entry.action;\n return (\n <li key={entry.id} className=\"flex items-start justify-between gap-3 px-4 py-3\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-medium text-text-primary\">{primary}</p>\n <p className=\"mt-0.5 text-xs text-text-secondary\">\n {entry.description?.trim() ? `${entry.action} · ` : ''}by {shortActor(entry.userId)}\n </p>\n </div>\n <time\n dateTime={entry.timestamp}\n className=\"shrink-0 whitespace-nowrap text-xs text-text-secondary\"\n >\n {formatTimestamp(entry.timestamp)}\n </time>\n </li>\n );\n })}\n </ul>\n );\n}\n\nexport default ActivityFeedPanel;\n"],"mappings":";;;;;;;;AAiBA,SAAS,EAAW,GAAwB;AAI1C,QAHI,EAAO,UAAU,KACZ,IAEF,GAAG,EAAO,MAAM,GAAG,EAAE,CAAC,GAAG,EAAO,MAAM,GAAG;;AAGlD,SAAS,EAAgB,GAAuB;CAC9C,IAAM,IAAO,IAAI,KAAK,EAAM;AAI5B,QAHI,OAAO,MAAM,EAAK,SAAS,CAAC,GACvB,MAEF,EAAK,eAAe,KAAA,GAAW;EACpC,MAAM;EACN,OAAO;EACP,KAAK;EACL,MAAM;EACN,QAAQ;EACT,CAAC;;AAWJ,SAAgB,EAAkB,EAChC,eACA,iBACA,UACA,uBACyB;CACzB,IAAM,EAAE,mBAAgB,GAAuB,EACzC,EAAE,SAAM,YAAS,UAAO,eAAY,EAA4B;EACpE;EACA;EACA;EACA;EACD,CAAC,EAEI,IAAa,GAAM,iBAAiB,EAAE;AA4B5C,QA1BI,KAAW,EAAW,WAAW,IAC5B,kBAAC,GAAD;EAAc,SAAQ;EAAO,MAAM;EAAG,OAAM;EAAsB,CAAA,GAGvE,IAEA,kBAAC,GAAD;EACE,SAAQ;EACR,eAAe,KAAK,GAAS;EAC7B,CAAA,GAIF,EAAW,WAAW,IAEtB,kBAAC,GAAD;EACE,MAAM;EACN,OAAM;EACN,aACE,KACA;EAEF,CAAA,GAKJ,kBAAC,MAAD;EAAI,WAAU;YACX,EAAW,KAAK,MAGb,kBAAC,MAAD;GAAmB,WAAU;aAA7B,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,KAAD;KAAG,WAAU;eAJH,EAAM,aAAa,MAAM,IAAI,EAAM;KAIqB,CAAA,EAClE,kBAAC,KAAD;KAAG,WAAU;eAAb;MACG,EAAM,aAAa,MAAM,GAAG,GAAG,EAAM,OAAO,OAAO;MAAG;MAAI,EAAW,EAAM,OAAO;MACjF;OACA;OACN,kBAAC,QAAD;IACE,UAAU,EAAM;IAChB,WAAU;cAET,EAAgB,EAAM,UAAU;IAC5B,CAAA,CACJ;KAbI,EAAM,GAaV,CAEP;EACC,CAAA"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import e from "./SafeLink.js";
|
|
2
|
+
import { Component as t, useMemo as n } from "react";
|
|
3
|
+
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
4
|
+
import { MessagesSquare as a } from "lucide-react";
|
|
5
|
+
import { ContextConversationWidget as o } from "@burdenoff/fe-libs/shared";
|
|
6
|
+
import { useRegisterPageConversationContext as s } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
7
|
+
//#region src/cosmicintersection/components/DiscussionPanel.tsx
|
|
8
|
+
var c = class extends t {
|
|
9
|
+
state = { failed: !1 };
|
|
10
|
+
static getDerivedStateFromError() {
|
|
11
|
+
return { failed: !0 };
|
|
12
|
+
}
|
|
13
|
+
componentDidCatch() {}
|
|
14
|
+
render() {
|
|
15
|
+
return this.state.failed ? this.props.fallback : this.props.children;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
function l({ entityType: e, entityId: t, title: i, widgetKey: a }) {
|
|
19
|
+
return s(n(() => ({
|
|
20
|
+
entityType: e,
|
|
21
|
+
entityId: t,
|
|
22
|
+
contextTitle: i
|
|
23
|
+
}), [
|
|
24
|
+
e,
|
|
25
|
+
t,
|
|
26
|
+
i
|
|
27
|
+
])), /* @__PURE__ */ r(o, { widgetKey: a });
|
|
28
|
+
}
|
|
29
|
+
function u({ entityType: t, entityId: n, title: o, widgetKey: s, fallbackHref: u = "/conversations" }) {
|
|
30
|
+
return /* @__PURE__ */ r(c, {
|
|
31
|
+
fallback: /* @__PURE__ */ i("div", {
|
|
32
|
+
className: "flex flex-wrap items-center gap-2 rounded-card border border-border-default bg-bg-elevated px-4 py-3 text-sm text-text-secondary",
|
|
33
|
+
children: [
|
|
34
|
+
/* @__PURE__ */ r(a, {
|
|
35
|
+
className: "size-4",
|
|
36
|
+
"aria-hidden": "true"
|
|
37
|
+
}),
|
|
38
|
+
/* @__PURE__ */ r("span", { children: "Discuss this with your team." }),
|
|
39
|
+
/* @__PURE__ */ r(e, {
|
|
40
|
+
href: u,
|
|
41
|
+
className: "text-text-primary underline-offset-2 hover:underline",
|
|
42
|
+
children: "Open conversations"
|
|
43
|
+
})
|
|
44
|
+
]
|
|
45
|
+
}),
|
|
46
|
+
children: /* @__PURE__ */ r(l, {
|
|
47
|
+
entityType: t,
|
|
48
|
+
entityId: n,
|
|
49
|
+
title: o,
|
|
50
|
+
widgetKey: s
|
|
51
|
+
})
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
//#endregion
|
|
55
|
+
export { u as default };
|
|
56
|
+
|
|
57
|
+
//# sourceMappingURL=DiscussionPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DiscussionPanel.js","names":[],"sources":["../../../src/cosmicintersection/components/DiscussionPanel.tsx"],"sourcesContent":["/**\n * DiscussionPanel — entity-scoped discussion for a cos record, reusing the\n * platform wspace-conversations-svc widget (no bespoke comment UI).\n *\n * The fe-libs `ContextConversationWidget` binds its thread to the page's\n * conversation context. We drive that binding from the MFE via the public\n * `useRegisterPageConversationContext` hook (setting `entityType` + `entityId`),\n * exactly like microfe-eventfullymanaged. The widget itself only accepts a\n * `widgetKey`, so the entity is supplied through the register hook rather than\n * props.\n *\n * The widget REQUIRES the host shell's `PageConversationContextProvider` (plus\n * the auth / active-context / gateway providers) to be mounted around the MFE.\n * When the shell has not yet mounted it, those hooks throw during render; the\n * error boundary below catches that and degrades to the working `/conversations`\n * deep-link so a detail page never crashes.\n */\nimport { Component, useMemo, type ReactNode } from 'react';\nimport { MessagesSquare } from 'lucide-react';\nimport { ContextConversationWidget } from '@burdenoff/fe-libs/shared';\nimport { useRegisterPageConversationContext } from '@burdenoff/fe-libs/shared/providers/shell';\n\nimport { SafeLink } from './SafeLink';\n\ninterface DiscussionBoundaryProps {\n fallback: ReactNode;\n children: ReactNode;\n}\n\ninterface DiscussionBoundaryState {\n failed: boolean;\n}\n\n/**\n * Renders `fallback` if the embedded conversation widget throws (e.g. the host\n * shell has not mounted the conversation page-context provider yet). The failure\n * is deterministic per mount, so once tripped we stay on the fallback.\n */\nclass DiscussionBoundary extends Component<DiscussionBoundaryProps, DiscussionBoundaryState> {\n state: DiscussionBoundaryState = { failed: false };\n\n static getDerivedStateFromError(): DiscussionBoundaryState {\n return { failed: true };\n }\n\n componentDidCatch(): void {\n // Intentionally swallowed: absence of the shell conversation provider is an\n // expected degradation, surfaced to the user via the deep-link fallback.\n }\n\n render(): ReactNode {\n return this.state.failed ? this.props.fallback : this.props.children;\n }\n}\n\ninterface DiscussionThreadProps {\n entityType: string;\n entityId: string;\n title: string;\n widgetKey: string;\n}\n\nfunction DiscussionThread({ entityType, entityId, title, widgetKey }: DiscussionThreadProps) {\n // Stable object identity: `useRegisterPageConversationContext` keys its effect\n // on this reference, so a fresh inline object each render would loop the shared\n // provider. Memoize on the primitive inputs.\n const conversationContext = useMemo(\n () => ({ entityType, entityId, contextTitle: title }),\n [entityType, entityId, title]\n );\n useRegisterPageConversationContext(conversationContext);\n return <ContextConversationWidget widgetKey={widgetKey} />;\n}\n\nexport interface DiscussionPanelProps {\n /** Stable entity-type discriminator, e.g. `cosmicintersection-dataset`. */\n entityType: string;\n entityId: string;\n /** Human title used for the conversation context label. */\n title: string;\n /** Distinguishes this widget's thread from others on the same entity. */\n widgetKey: string;\n /** In-app deep-link used when the shell conversation provider is unavailable. */\n fallbackHref?: string;\n}\n\nexport function DiscussionPanel({\n entityType,\n entityId,\n title,\n widgetKey,\n fallbackHref = '/conversations',\n}: DiscussionPanelProps) {\n const fallback = (\n <div className=\"flex flex-wrap items-center gap-2 rounded-card border border-border-default bg-bg-elevated px-4 py-3 text-sm text-text-secondary\">\n <MessagesSquare className=\"size-4\" aria-hidden=\"true\" />\n <span>Discuss this with your team.</span>\n <SafeLink\n href={fallbackHref}\n className=\"text-text-primary underline-offset-2 hover:underline\"\n >\n Open conversations\n </SafeLink>\n </div>\n );\n\n return (\n <DiscussionBoundary fallback={fallback}>\n <DiscussionThread\n entityType={entityType}\n entityId={entityId}\n title={title}\n widgetKey={widgetKey}\n />\n </DiscussionBoundary>\n );\n}\n\nexport default DiscussionPanel;\n"],"mappings":";;;;;;;AAsCA,IAAM,IAAN,cAAiC,EAA4D;CAC3F,QAAiC,EAAE,QAAQ,IAAO;CAElD,OAAO,2BAAoD;AACzD,SAAO,EAAE,QAAQ,IAAM;;CAGzB,oBAA0B;CAK1B,SAAoB;AAClB,SAAO,KAAK,MAAM,SAAS,KAAK,MAAM,WAAW,KAAK,MAAM;;;AAWhE,SAAS,EAAiB,EAAE,eAAY,aAAU,UAAO,gBAAoC;AAS3F,QADA,EAJ4B,SACnB;EAAE;EAAY;EAAU,cAAc;EAAO,GACpD;EAAC;EAAY;EAAU;EAAM,CAC9B,CACsD,EAChD,kBAAC,GAAD,EAAsC,cAAa,CAAA;;AAe5D,SAAgB,EAAgB,EAC9B,eACA,aACA,UACA,cACA,kBAAe,oBACQ;AAcvB,QACE,kBAAC,GAAD;EAA8B,UAb9B,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,GAAD;KAAgB,WAAU;KAAS,eAAY;KAAS,CAAA;IACxD,kBAAC,QAAD,EAAA,UAAM,gCAAmC,CAAA;IACzC,kBAAC,GAAD;KACE,MAAM;KACN,WAAU;eACX;KAEU,CAAA;IACP;;YAKJ,kBAAC,GAAD;GACc;GACF;GACH;GACI;GACX,CAAA;EACiB,CAAA"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import "./ActionMenu.js";
|
|
2
2
|
import "./EmptyState.js";
|
|
3
|
+
import "./ErrorState.js";
|
|
4
|
+
import "./LoadingState.js";
|
|
5
|
+
import "./ActivityFeedPanel.js";
|
|
6
|
+
import "./SafeLink.js";
|
|
7
|
+
import "./DiscussionPanel.js";
|
|
3
8
|
import "./EntityFormShell.js";
|
|
4
9
|
import "./EntityTagsField.js";
|
|
5
|
-
import "./ErrorState.js";
|
|
6
10
|
import "./FileUploadField.js";
|
|
7
|
-
import "./LoadingState.js";
|
|
8
11
|
import "./PageLayout.js";
|
|
9
12
|
import "./Pagination.js";
|
|
10
|
-
import "./SafeLink.js";
|
|
11
13
|
import "./StatusBadge.js";
|
|
@@ -2,9 +2,9 @@ import { notify as e } from "../../lib/toast.js";
|
|
|
2
2
|
import { useCosAccessGrantsQuery as t, useCosDatasetsQuery as n, useCosGrantAccessMutation as r, useCosRevokeAccessMutation as ee } from "../../api/cosmicApi.js";
|
|
3
3
|
import te from "../../components/ActionMenu.js";
|
|
4
4
|
import i from "../../components/EmptyState.js";
|
|
5
|
-
import ne from "../../components/
|
|
6
|
-
import re from "../../components/
|
|
7
|
-
import ie from "../../components/
|
|
5
|
+
import ne from "../../components/ErrorState.js";
|
|
6
|
+
import re from "../../components/LoadingState.js";
|
|
7
|
+
import ie from "../../components/EntityTagsField.js";
|
|
8
8
|
import ae from "../../components/PageLayout.js";
|
|
9
9
|
import a, { formatEnumLabel as o } from "../../components/StatusBadge.js";
|
|
10
10
|
import "../../components/index.js";
|
|
@@ -136,12 +136,12 @@ function I() {
|
|
|
136
136
|
})
|
|
137
137
|
})]
|
|
138
138
|
}), (() => {
|
|
139
|
-
if (ue) return /* @__PURE__ */ l(
|
|
139
|
+
if (ue) return /* @__PURE__ */ l(re, {
|
|
140
140
|
variant: "rows",
|
|
141
141
|
rows: 6,
|
|
142
142
|
label: "Loading access grants…"
|
|
143
143
|
});
|
|
144
|
-
if (W) return /* @__PURE__ */ l(
|
|
144
|
+
if (W) return /* @__PURE__ */ l(ne, {
|
|
145
145
|
message: W.message,
|
|
146
146
|
onRetry: () => void G()
|
|
147
147
|
});
|
|
@@ -240,7 +240,7 @@ function I() {
|
|
|
240
240
|
open: pe,
|
|
241
241
|
onOpenChange: (e) => J(e || q ? e : !1),
|
|
242
242
|
children: /* @__PURE__ */ u(h, {
|
|
243
|
-
className: "max-w-md",
|
|
243
|
+
className: "max-h-[85vh] max-w-md overflow-y-auto",
|
|
244
244
|
children: [
|
|
245
245
|
/* @__PURE__ */ u(_, { children: [/* @__PURE__ */ l(v, { children: "Grant data access" }), /* @__PURE__ */ l(g, { children: "Give a workspace member scoped access to a dataset. Access is identified by the member's User ID." })] }),
|
|
246
246
|
/* @__PURE__ */ u("div", {
|
|
@@ -266,18 +266,25 @@ function I() {
|
|
|
266
266
|
}),
|
|
267
267
|
/* @__PURE__ */ u("div", {
|
|
268
268
|
className: "space-y-1.5",
|
|
269
|
-
children: [
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
269
|
+
children: [
|
|
270
|
+
/* @__PURE__ */ l(b, {
|
|
271
|
+
htmlFor: "grant-grantee",
|
|
272
|
+
children: "Grantee (User ID)"
|
|
273
|
+
}),
|
|
274
|
+
/* @__PURE__ */ l(y, {
|
|
275
|
+
id: "grant-grantee",
|
|
276
|
+
value: Y.granteeId,
|
|
277
|
+
onChange: (e) => Z("granteeId", e.target.value),
|
|
278
|
+
placeholder: "e.g. 4fe35990-…",
|
|
279
|
+
className: "font-mono"
|
|
280
|
+
}),
|
|
281
|
+
/* @__PURE__ */ l("p", {
|
|
282
|
+
className: "text-xs text-text-secondary",
|
|
283
|
+
children: "Paste the workspace member's User ID. You can copy it from the member's profile (“Get ID”) or the workspace member directory."
|
|
284
|
+
})
|
|
285
|
+
]
|
|
279
286
|
}),
|
|
280
|
-
/* @__PURE__ */ l(
|
|
287
|
+
/* @__PURE__ */ l(ie, {
|
|
281
288
|
value: Y.scopes,
|
|
282
289
|
onChange: (e) => Z("scopes", e),
|
|
283
290
|
label: "Scopes",
|
|
@@ -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';\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 [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('Dataset is required', 'Choose which dataset this grant applies to.');\n return;\n }\n if (!form.granteeId.trim()) {\n notify.error('Grantee is required', 'Enter the workspace User ID to grant access to.');\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('Invalid expiry', 'Enter a valid expiry date or leave it blank.');\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('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('Could not revoke grant', 'The server did not confirm the change.');\n throw new Error('Revoke not confirmed');\n }\n notify.success('Access revoked');\n await refetch();\n };\n\n const grantButton = (\n <Button type=\"button\" onClick={openGrantDialog}>\n <KeyRound className=\"size-4\" />\n Grant access\n </Button>\n );\n\n const showDatasetColumn = datasetFilter === ALL;\n\n const renderBody = () => {\n if (loading) {\n return <LoadingState variant=\"rows\" rows={6} label=\"Loading access grants…\" />;\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={filtered ? 'No grants match these filters' : 'No access grants yet'}\n description={\n filtered\n ? 'Try clearing the dataset or status filter to see more grants.'\n : 'Grant a workspace member scoped access to a restricted or embargoed dataset.'\n }\n action={filtered ? undefined : grantButton}\n />\n );\n }\n\n return (\n <div className=\"overflow-x-auto rounded-card border border-border-default bg-bg-elevated\">\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\">{grant.reason}</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 };\n\n return (\n <PageLayout\n title=\"Data access\"\n description=\"Govern who can reach restricted and embargoed datasets, with scoped, expiring grants.\"\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-w-md\">\n <DialogHeader>\n <DialogTitle>Grant data access</DialogTitle>\n <DialogDescription>\n Give a workspace member scoped access to a dataset. Access is identified by the\n member's User ID.\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"grant-dataset\">Dataset</Label>\n <Select\n value={form.datasetId || undefined}\n onValueChange={(value) => setField('datasetId', value)}\n >\n <SelectTrigger id=\"grant-dataset\" aria-label=\"Dataset\">\n <SelectValue placeholder=\"Select a dataset\" />\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\">Grantee (User ID)</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 </div>\n\n <EntityTagsField\n value={form.scopes}\n onChange={(scopes) => setField('scopes', scopes)}\n label=\"Scopes\"\n placeholder=\"e.g. read, download\"\n />\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"grant-reason\">Reason</Label>\n <Textarea\n id=\"grant-reason\"\n value={form.reason}\n onChange={(event) => setField('reason', event.target.value)}\n rows={2}\n placeholder=\"Why this member needs access.\"\n />\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"grant-expires\">Expires (optional)</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\">Leave blank for an open-ended grant.</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 Cancel\n </Button>\n <Button type=\"button\" onClick={() => void submitGrant()} disabled={granting}>\n <KeyRound className=\"size-4\" />\n {granting ? 'Granting…' : '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';\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 [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('Dataset is required', 'Choose which dataset this grant applies to.');\n return;\n }\n if (!form.granteeId.trim()) {\n notify.error('Grantee is required', 'Enter the workspace User ID to grant access to.');\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('Invalid expiry', 'Enter a valid expiry date or leave it blank.');\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('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('Could not revoke grant', 'The server did not confirm the change.');\n throw new Error('Revoke not confirmed');\n }\n notify.success('Access revoked');\n await refetch();\n };\n\n const grantButton = (\n <Button type=\"button\" onClick={openGrantDialog}>\n <KeyRound className=\"size-4\" />\n Grant access\n </Button>\n );\n\n const showDatasetColumn = datasetFilter === ALL;\n\n const renderBody = () => {\n if (loading) {\n return <LoadingState variant=\"rows\" rows={6} label=\"Loading access grants…\" />;\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={filtered ? 'No grants match these filters' : 'No access grants yet'}\n description={\n filtered\n ? 'Try clearing the dataset or status filter to see more grants.'\n : 'Grant a workspace member scoped access to a restricted or embargoed dataset.'\n }\n action={filtered ? undefined : grantButton}\n />\n );\n }\n\n return (\n <div className=\"overflow-x-auto rounded-card border border-border-default bg-bg-elevated\">\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\">{grant.reason}</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 };\n\n return (\n <PageLayout\n title=\"Data access\"\n description=\"Govern who can reach restricted and embargoed datasets, with scoped, expiring grants.\"\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>Grant data access</DialogTitle>\n <DialogDescription>\n Give a workspace member scoped access to a dataset. Access is identified by the\n member's User ID.\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"grant-dataset\">Dataset</Label>\n <Select\n value={form.datasetId || undefined}\n onValueChange={(value) => setField('datasetId', value)}\n >\n <SelectTrigger id=\"grant-dataset\" aria-label=\"Dataset\">\n <SelectValue placeholder=\"Select a dataset\" />\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\">Grantee (User ID)</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 Paste the workspace member's User ID. You can copy it from the member's\n profile (“Get ID”) or the workspace member directory.\n </p>\n </div>\n\n <EntityTagsField\n value={form.scopes}\n onChange={(scopes) => setField('scopes', scopes)}\n label=\"Scopes\"\n placeholder=\"e.g. read, download\"\n />\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"grant-reason\">Reason</Label>\n <Textarea\n id=\"grant-reason\"\n value={form.reason}\n onChange={(event) => setField('reason', event.target.value)}\n rows={2}\n placeholder=\"Why this member needs access.\"\n />\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"grant-expires\">Expires (optional)</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\">Leave blank for an open-ended grant.</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 Cancel\n </Button>\n <Button type=\"button\" onClick={() => void submitGrant()} disabled={granting}>\n <KeyRound className=\"size-4\" />\n {granting ? 'Granting…' : 'Grant access'}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|