From 46968fb013e0e83f7594652821f8abbd55fa6be5 Mon Sep 17 00:00:00 2001 From: Sean Teramae Date: Thu, 4 Jun 2026 11:51:29 -0700 Subject: [PATCH 1/2] feat(studio): Edit description on fileset detail route Signed-off-by: Sean Teramae --- .../components/FilesetActionMenu/index.tsx | 108 ++++++++++++++++++ .../FilesetDetailRoute/FilesetCard/index.tsx | 11 +- .../src/routes/FilesetDetailRoute/index.tsx | 34 +++++- 3 files changed, 139 insertions(+), 14 deletions(-) create mode 100644 web/packages/studio/src/components/FilesetActionMenu/index.tsx diff --git a/web/packages/studio/src/components/FilesetActionMenu/index.tsx b/web/packages/studio/src/components/FilesetActionMenu/index.tsx new file mode 100644 index 0000000000..6d70620825 --- /dev/null +++ b/web/packages/studio/src/components/FilesetActionMenu/index.tsx @@ -0,0 +1,108 @@ +// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { getEntityReference } from '@nemo/common/src/namedEntity'; +import { useFilesDeleteFileset } from '@nemo/sdk/generated/platform/api'; +import type { FilesetOutput } from '@nemo/sdk/generated/platform/schema'; +import { + Button, + DropdownContent, + DropdownItem, + DropdownRoot, + DropdownTrigger, +} from '@nvidia/foundations-react-core'; +import { invalidateDatasetCaches } from '@studio/api/datasets/invalidateDatasetCaches'; +import { DatasetCreateModal } from '@studio/components/DatasetCreateModal'; +import { DatasetCreateModalMode } from '@studio/components/DatasetCreateModal/constants'; +import { DeleteConfirmationModal } from '@studio/components/DeleteConfirmationModal'; +import { EllipsisVertical } from 'lucide-react'; +import { type FC, useState } from 'react'; + +export interface FilesetActionMenuProps { + dataset: FilesetOutput; + onNavigateToDetails?: (dataset: FilesetOutput) => void; + onDatasetUpdated?: (dataset: FilesetOutput) => void; + onDatasetDeleted?: (dataset: FilesetOutput) => void; +} + +export const FilesetActionMenu: FC = ({ + dataset, + onNavigateToDetails, + onDatasetUpdated, + onDatasetDeleted, +}) => { + const [modalOpen, setModalOpen] = useState<'edit' | 'delete' | undefined>(undefined); + const { mutateAsync: deleteDataset } = useFilesDeleteFileset({ + mutation: { + onSuccess: (_data, variables) => { + invalidateDatasetCaches(variables.workspace, variables.name, ['list']); + }, + }, + }); + + const handleDeleteDataset = async (): Promise => { + try { + if (!dataset?.workspace || !dataset?.name) { + throw new Error('Dataset workspace or name is undefined'); + } + await deleteDataset({ workspace: dataset.workspace, name: dataset.name }); + onDatasetDeleted?.(dataset); + return true; + } catch (error) { + console.error('Failed to delete dataset:', error); + return false; + } + }; + + const handleModalClose = () => { + setModalOpen(undefined); + }; + + const handleDatasetUpdated = (updatedDataset: FilesetOutput) => { + onDatasetUpdated?.(updatedDataset); + handleModalClose(); + }; + + return ( + <> + + + + + + {onNavigateToDetails && ( + onNavigateToDetails(dataset)}>View + )} + setModalOpen('edit')}>Edit + setModalOpen('delete')} danger> + Delete + + + + + {modalOpen === 'edit' && ( + + )} + + {modalOpen === 'delete' && ( + + )} + + ); +}; diff --git a/web/packages/studio/src/routes/FilesetDetailRoute/FilesetCard/index.tsx b/web/packages/studio/src/routes/FilesetDetailRoute/FilesetCard/index.tsx index 98d2406eeb..f99792c080 100644 --- a/web/packages/studio/src/routes/FilesetDetailRoute/FilesetCard/index.tsx +++ b/web/packages/studio/src/routes/FilesetDetailRoute/FilesetCard/index.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import type { FilesetFileOutput, FilesetOutput } from '@nemo/sdk/generated/platform/schema'; -import { Grid, GridItem, Stack, Text } from '@nvidia/foundations-react-core'; +import { Grid, GridItem, Stack } from '@nvidia/foundations-react-core'; import { useDatasetFileContent } from '@studio/api/datasets/useDatasetFileContent'; import { ReadmeBody } from '@studio/routes/FilesetDetailRoute/FilesetCard/ReadmeBody'; import { FilesetMetadataPanel } from '@studio/routes/FilesetDetailRoute/FilesetMetadataPanel'; @@ -52,19 +52,14 @@ export const FilesetCard: FC = ({ - {fileset.description && ( - - {fileset.description} - - )} { const workspace = useWorkspaceFromPath(); + const navigate = useNavigate(); const { filesetName } = useRequiredPathParams([ROUTE_PARAMS.filesetName]); const filesetId = getEntityReference({ namespace: workspace, name: filesetName }); @@ -105,17 +108,36 @@ export const FilesetDetailRoute: FC = () => { // The source line (HF/NGC origin) is meaningful for model/generic filesets; // datasets don't surface it. const source = isDataset ? undefined : getModelSource(fileset); - const description = source ? ( - - {creatorToIcon(source.creatorSlug, { className: 'w-4 h-4 flex-shrink-0' })} - {source.path} - + const descriptionText = {fileset.description}; + const description = isDataset ? ( + descriptionText + ) : source ? ( + + + {creatorToIcon(source.creatorSlug, { className: 'w-4 h-4 flex-shrink-0' })} + {source.path} + + {descriptionText} + ) : undefined; return ( - + + + {filesetName} + navigate(getWorkspaceFilesetsRoute(workspace))} + /> + + + } + slotDescription={description} + /> Date: Thu, 4 Jun 2026 15:37:34 -0700 Subject: [PATCH 2/2] fix terminology Signed-off-by: Sean Teramae --- .../components/FilesetActionMenu/index.tsx | 48 +++++++++---------- .../src/routes/FilesetDetailRoute/index.tsx | 4 +- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/web/packages/studio/src/components/FilesetActionMenu/index.tsx b/web/packages/studio/src/components/FilesetActionMenu/index.tsx index 6d70620825..b82b60bea9 100644 --- a/web/packages/studio/src/components/FilesetActionMenu/index.tsx +++ b/web/packages/studio/src/components/FilesetActionMenu/index.tsx @@ -19,20 +19,20 @@ import { EllipsisVertical } from 'lucide-react'; import { type FC, useState } from 'react'; export interface FilesetActionMenuProps { - dataset: FilesetOutput; - onNavigateToDetails?: (dataset: FilesetOutput) => void; - onDatasetUpdated?: (dataset: FilesetOutput) => void; - onDatasetDeleted?: (dataset: FilesetOutput) => void; + fileset: FilesetOutput; + onNavigateToDetails?: (fileset: FilesetOutput) => void; + onFilesetUpdated?: (fileset: FilesetOutput) => void; + onFilesetDeleted?: (fileset: FilesetOutput) => void; } export const FilesetActionMenu: FC = ({ - dataset, + fileset, onNavigateToDetails, - onDatasetUpdated, - onDatasetDeleted, + onFilesetUpdated, + onFilesetDeleted, }) => { const [modalOpen, setModalOpen] = useState<'edit' | 'delete' | undefined>(undefined); - const { mutateAsync: deleteDataset } = useFilesDeleteFileset({ + const { mutateAsync: deleteFileset } = useFilesDeleteFileset({ mutation: { onSuccess: (_data, variables) => { invalidateDatasetCaches(variables.workspace, variables.name, ['list']); @@ -40,16 +40,16 @@ export const FilesetActionMenu: FC = ({ }, }); - const handleDeleteDataset = async (): Promise => { + const handleDeleteFileset = async (): Promise => { try { - if (!dataset?.workspace || !dataset?.name) { - throw new Error('Dataset workspace or name is undefined'); + if (!fileset?.workspace || !fileset?.name) { + throw new Error('Fileset workspace or name is undefined'); } - await deleteDataset({ workspace: dataset.workspace, name: dataset.name }); - onDatasetDeleted?.(dataset); + await deleteFileset({ workspace: fileset.workspace, name: fileset.name }); + onFilesetDeleted?.(fileset); return true; } catch (error) { - console.error('Failed to delete dataset:', error); + console.error('Failed to delete fileset:', error); return false; } }; @@ -58,8 +58,8 @@ export const FilesetActionMenu: FC = ({ setModalOpen(undefined); }; - const handleDatasetUpdated = (updatedDataset: FilesetOutput) => { - onDatasetUpdated?.(updatedDataset); + const handleFilesetUpdated = (updatedFileset: FilesetOutput) => { + onFilesetUpdated?.(updatedFileset); handleModalClose(); }; @@ -67,13 +67,13 @@ export const FilesetActionMenu: FC = ({ <> - {onNavigateToDetails && ( - onNavigateToDetails(dataset)}>View + onNavigateToDetails(fileset)}>View )} setModalOpen('edit')}>Edit setModalOpen('delete')} danger> @@ -84,10 +84,10 @@ export const FilesetActionMenu: FC = ({ {modalOpen === 'edit' && ( )} @@ -96,11 +96,11 @@ export const FilesetActionMenu: FC = ({ )} diff --git a/web/packages/studio/src/routes/FilesetDetailRoute/index.tsx b/web/packages/studio/src/routes/FilesetDetailRoute/index.tsx index 3a8b969453..711c3685e8 100644 --- a/web/packages/studio/src/routes/FilesetDetailRoute/index.tsx +++ b/web/packages/studio/src/routes/FilesetDetailRoute/index.tsx @@ -130,8 +130,8 @@ export const FilesetDetailRoute: FC = () => { {filesetName} navigate(getWorkspaceFilesetsRoute(workspace))} + fileset={fileset} + onFilesetDeleted={() => navigate(getWorkspaceFilesetsRoute(workspace))} />