fix(web): name metadata drawer actions

This commit is contained in:
yyh
2026-05-10 22:29:36 +08:00
parent 2266127b3b
commit 7fbee2c041
2 changed files with 30 additions and 77 deletions

View File

@ -86,6 +86,10 @@ describe('DatasetMetadataDrawer', () => {
vi.clearAllMocks()
})
const clickFirstMetadataAction = (name: string) => {
fireEvent.click(screen.getAllByRole('button', { name })[0]!)
}
describe('Rendering', () => {
it('should render without crashing', async () => {
render(<DatasetMetadataDrawer {...defaultProps} />)
@ -143,7 +147,7 @@ describe('DatasetMetadataDrawer', () => {
expect(screen.getByRole('dialog'))!.toBeInTheDocument()
})
fireEvent.click(screen.getByTestId('close-icon'))
fireEvent.click(screen.getByRole('button', { name: 'common.operation.close' }))
expect(onClose).toHaveBeenCalledTimes(1)
})
@ -247,21 +251,7 @@ describe('DatasetMetadataDrawer', () => {
expect(screen.getByRole('dialog'))!.toBeInTheDocument()
})
// Find user metadata items with group/item class (these have edit/delete icons)
const dialog = screen.getByRole('dialog')
const items = dialog.querySelectorAll('.group\\/item')
expect(items.length).toBe(2) // 2 user metadata items
// Find the hidden container with edit/delete icons
const actionsContainer = items[0]!.querySelector('.hidden.items-center')
expect(actionsContainer).toBeTruthy()
// Find and click the first SVG (edit icon)
if (actionsContainer) {
const svgs = actionsContainer.querySelectorAll('svg')
expect(svgs.length).toBeGreaterThan(0)
fireEvent.click(svgs[0]!)
}
clickFirstMetadataAction('common.operation.edit')
// Wait for rename modal (contains input)
await waitFor(() => {
@ -278,14 +268,7 @@ describe('DatasetMetadataDrawer', () => {
expect(screen.getByRole('dialog'))!.toBeInTheDocument()
})
// Find and click edit icon
const dialog = screen.getByRole('dialog')
const items = dialog.querySelectorAll('.group\\/item')
const actionsContainer = items[0]!.querySelector('.hidden.items-center')
if (actionsContainer) {
const svgs = actionsContainer.querySelectorAll('svg')
fireEvent.click(svgs[0]!)
}
clickFirstMetadataAction('common.operation.edit')
// Change name and save
await waitFor(() => {
@ -319,14 +302,7 @@ describe('DatasetMetadataDrawer', () => {
expect(screen.getByRole('dialog'))!.toBeInTheDocument()
})
// Find and click edit icon
const dialog = screen.getByRole('dialog')
const items = dialog.querySelectorAll('.group\\/item')
const actionsContainer = items[0]!.querySelector('.hidden.items-center')
if (actionsContainer) {
const svgs = actionsContainer.querySelectorAll('svg')
fireEvent.click(svgs[0]!)
}
clickFirstMetadataAction('common.operation.edit')
// Wait for modal and click cancel
await waitFor(() => {
@ -355,14 +331,7 @@ describe('DatasetMetadataDrawer', () => {
expect(screen.getByRole('dialog'))!.toBeInTheDocument()
})
// Find and click edit icon
const dialog = screen.getByRole('dialog')
const items = dialog.querySelectorAll('.group\\/item')
const actionsContainer = items[0]!.querySelector('.hidden.items-center')
if (actionsContainer) {
const svgs = actionsContainer.querySelectorAll('svg')
fireEvent.click(svgs[0]!)
}
clickFirstMetadataAction('common.operation.edit')
// Wait for rename modal
await waitFor(() => {
@ -387,19 +356,7 @@ describe('DatasetMetadataDrawer', () => {
expect(screen.getByRole('dialog'))!.toBeInTheDocument()
})
// Find user metadata items
const dialog = screen.getByRole('dialog')
const items = dialog.querySelectorAll('.group\\/item')
// Find the delete container
const deleteContainer = items[0]!.querySelector('.hover\\:text-text-destructive')
expect(deleteContainer).toBeTruthy()
if (deleteContainer) {
const deleteIcon = deleteContainer.querySelector('svg')
if (deleteIcon)
fireEvent.click(deleteIcon)
}
clickFirstMetadataAction('common.operation.remove')
// Confirm dialog should appear
await waitFor(() => {
@ -419,15 +376,7 @@ describe('DatasetMetadataDrawer', () => {
expect(screen.getByRole('dialog'))!.toBeInTheDocument()
})
// Find and click delete icon
const dialog = screen.getByRole('dialog')
const items = dialog.querySelectorAll('.group\\/item')
const deleteContainer = items[0]!.querySelector('.hover\\:text-text-destructive')
if (deleteContainer) {
const deleteIcon = deleteContainer.querySelector('svg')
if (deleteIcon)
fireEvent.click(deleteIcon)
}
clickFirstMetadataAction('common.operation.remove')
// Wait for confirm dialog
await waitFor(() => {
@ -465,15 +414,7 @@ describe('DatasetMetadataDrawer', () => {
expect(screen.getByRole('dialog'))!.toBeInTheDocument()
})
// Find and click delete icon
const dialog = screen.getByRole('dialog')
const items = dialog.querySelectorAll('.group\\/item')
const deleteContainer = items[0]!.querySelector('.hover\\:text-text-destructive')
if (deleteContainer) {
const deleteIcon = deleteContainer.querySelector('svg')
if (deleteIcon)
fireEvent.click(deleteIcon)
}
clickFirstMetadataAction('common.operation.remove')
// Wait for confirm dialog
await waitFor(() => {

View File

@ -70,7 +70,7 @@ const Item: FC<ItemProps> = ({
onRename?.()
}, [onRename])
const deleteBtnRef = useRef<HTMLDivElement>(null)
const deleteBtnRef = useRef<HTMLButtonElement>(null)
const isDeleteHovering = useHover(deleteBtnRef)
const [isShowDeleteConfirm, {
setTrue: showDeleteConfirm,
@ -107,10 +107,23 @@ const Item: FC<ItemProps> = ({
</div>
)}
<div className="ml-2 hidden items-center space-x-1 text-text-tertiary group-hover/item:flex">
<RiEditLine className="size-4 cursor-pointer" onClick={handleRename} />
<div ref={deleteBtnRef} className="hover:text-text-destructive">
<RiDeleteBinLine className="size-4 cursor-pointer" onClick={showDeleteConfirm} />
</div>
<button
type="button"
aria-label={t('operation.edit', { ns: 'common' })}
className="cursor-pointer rounded-md p-0.5 hover:bg-state-base-hover focus-visible:ring-1 focus-visible:ring-components-input-border-active focus-visible:outline-hidden"
onClick={handleRename}
>
<RiEditLine className="size-4" aria-hidden="true" />
</button>
<button
type="button"
ref={deleteBtnRef}
aria-label={t('operation.remove', { ns: 'common' })}
className="cursor-pointer rounded-md p-0.5 hover:bg-state-destructive-hover hover:text-text-destructive focus-visible:ring-1 focus-visible:ring-state-destructive-border focus-visible:outline-hidden"
onClick={showDeleteConfirm}
>
<RiDeleteBinLine className="size-4" aria-hidden="true" />
</button>
</div>
<AlertDialog open={isShowDeleteConfirm} onOpenChange={open => !open && hideDeleteConfirm()}>
<AlertDialogContent>
@ -205,7 +218,6 @@ const DatasetMetadataDrawer: FC<Props> = ({
<DrawerCloseButton
aria-label={t('operation.close', { ns: 'common' })}
className="h-6 w-6 rounded-md"
data-testid="close-icon"
/>
</div>
<div className="min-h-0 flex-1 overflow-y-auto px-4 pb-6">