fix(web): name preview close controls

This commit is contained in:
yyh
2026-05-10 22:52:24 +08:00
parent ef152db4a6
commit 35c78f4aa5
10 changed files with 75 additions and 53 deletions

View File

@ -103,6 +103,22 @@ describe('VersionInfoModal', () => {
expect(handleClose).toHaveBeenCalledTimes(1)
})
it('should close when the close button is clicked', () => {
const handleClose = vi.fn()
render(
<VersionInfoModal
isOpen
onClose={handleClose}
onPublish={vi.fn()}
/>,
)
fireEvent.click(screen.getByRole('button', { name: 'operation.close' }))
expect(handleClose).toHaveBeenCalledTimes(1)
})
it('should validate release note length and clear previous errors before publishing', () => {
const handlePublish = vi.fn()
const handleClose = vi.fn()

View File

@ -79,9 +79,14 @@ const VersionInfoModal: FC<VersionInfoModalProps> = ({
<div className="title-2xl-semi-bold text-text-primary first-letter:capitalize">
{versionInfo?.marked_name ? t('versionHistory.editVersionInfo', { ns: 'workflow' }) : t('versionHistory.nameThisVersion', { ns: 'workflow' })}
</div>
<div className="absolute top-5 right-5 flex h-8 w-8 cursor-pointer items-center justify-center p-1.5" onClick={onClose}>
<RiCloseLine className="h-[18px] w-[18px] text-text-tertiary" />
</div>
<button
type="button"
className="absolute top-5 right-5 flex h-8 w-8 cursor-pointer items-center justify-center border-none bg-transparent p-1.5 focus-visible:ring-1 focus-visible:ring-components-input-border-active focus-visible:outline-hidden"
aria-label={t('operation.close', { ns: 'common' })}
onClick={onClose}
>
<RiCloseLine className="h-[18px] w-[18px] text-text-tertiary" aria-hidden="true" />
</button>
</div>
<div className="flex flex-col gap-y-4 px-6 py-3">
<div className="flex flex-col gap-y-1">

View File

@ -73,9 +73,9 @@ describe('FilePreview', () => {
})
it('should render close button with XMarkIcon', async () => {
const { container } = renderFilePreview()
renderFilePreview()
const closeButton = container.querySelector('.cursor-pointer')
const closeButton = screen.getByRole('button', { name: /operation\.close$/ })
expect(closeButton)!.toBeInTheDocument()
const xMarkIcon = closeButton?.querySelector('svg')
expect(xMarkIcon)!.toBeInTheDocument()
@ -269,20 +269,18 @@ describe('FilePreview', () => {
describe('User Interactions', () => {
it('should call hidePreview when close button is clicked', async () => {
const hidePreview = vi.fn()
const { container } = renderFilePreview({ hidePreview })
renderFilePreview({ hidePreview })
const closeButton = container.querySelector('.cursor-pointer') as HTMLElement
fireEvent.click(closeButton)
fireEvent.click(screen.getByRole('button', { name: /operation\.close$/ }))
expect(hidePreview).toHaveBeenCalledTimes(1)
})
it('should call hidePreview with event object when clicked', async () => {
const hidePreview = vi.fn()
const { container } = renderFilePreview({ hidePreview })
renderFilePreview({ hidePreview })
const closeButton = container.querySelector('.cursor-pointer') as HTMLElement
fireEvent.click(closeButton)
fireEvent.click(screen.getByRole('button', { name: /operation\.close$/ }))
// Assert - onClick receives the event object
expect(hidePreview).toHaveBeenCalled()
@ -291,9 +289,9 @@ describe('FilePreview', () => {
it('should handle multiple clicks on close button', async () => {
const hidePreview = vi.fn()
const { container } = renderFilePreview({ hidePreview })
renderFilePreview({ hidePreview })
const closeButton = container.querySelector('.cursor-pointer') as HTMLElement
const closeButton = screen.getByRole('button', { name: /operation\.close$/ })
fireEvent.click(closeButton)
fireEvent.click(closeButton)
fireEvent.click(closeButton)

View File

@ -50,9 +50,14 @@ const FilePreview = ({
<div className={cn(s.previewHeader)}>
<div className={cn(s.title, 'title-md-semi-bold')}>
<span>{t('stepOne.filePreview', { ns: 'datasetCreation' })}</span>
<div className="flex h-6 w-6 cursor-pointer items-center justify-center" onClick={hidePreview}>
<XMarkIcon className="h-4 w-4"></XMarkIcon>
</div>
<button
type="button"
className="flex h-6 w-6 cursor-pointer items-center justify-center border-none bg-transparent p-0 focus-visible:ring-1 focus-visible:ring-components-input-border-active focus-visible:outline-hidden"
aria-label={t('operation.close', { ns: 'common' })}
onClick={hidePreview}
>
<XMarkIcon className="h-4 w-4" aria-hidden="true"></XMarkIcon>
</button>
</div>
<div className={cn(s.fileName, 'system-xs-medium')}>
<span>{getFileName(file)}</span>

View File

@ -118,9 +118,9 @@ describe('NotionPagePreview', () => {
})
it('should render close button with XMarkIcon', async () => {
const { container } = await renderNotionPagePreview()
await renderNotionPagePreview()
const closeButton = container.querySelector('.cursor-pointer')
const closeButton = screen.getByRole('button', { name: /operation\.close$/ })
expect(closeButton).toBeInTheDocument()
const xMarkIcon = closeButton?.querySelector('svg')
expect(xMarkIcon).toBeInTheDocument()
@ -348,19 +348,18 @@ describe('NotionPagePreview', () => {
describe('User Interactions', () => {
it('should call hidePreview when close button is clicked', async () => {
const hidePreview = vi.fn()
const { container } = await renderNotionPagePreview({ hidePreview })
await renderNotionPagePreview({ hidePreview })
const closeButton = container.querySelector('.cursor-pointer') as HTMLElement
fireEvent.click(closeButton)
fireEvent.click(screen.getByRole('button', { name: /operation\.close$/ }))
expect(hidePreview).toHaveBeenCalledTimes(1)
})
it('should handle multiple clicks on close button', async () => {
const hidePreview = vi.fn()
const { container } = await renderNotionPagePreview({ hidePreview })
await renderNotionPagePreview({ hidePreview })
const closeButton = container.querySelector('.cursor-pointer') as HTMLElement
const closeButton = screen.getByRole('button', { name: /operation\.close$/ })
fireEvent.click(closeButton)
fireEvent.click(closeButton)
fireEvent.click(closeButton)

View File

@ -52,9 +52,14 @@ const NotionPagePreview = ({
<div className={cn(s.previewHeader)}>
<div className={cn(s.title, 'title-md-semi-bold')}>
<span>{t('stepOne.pagePreview', { ns: 'datasetCreation' })}</span>
<div className="flex h-6 w-6 cursor-pointer items-center justify-center" onClick={hidePreview}>
<XMarkIcon className="h-4 w-4"></XMarkIcon>
</div>
<button
type="button"
className="flex h-6 w-6 cursor-pointer items-center justify-center border-none bg-transparent p-0 focus-visible:ring-1 focus-visible:ring-components-input-border-active focus-visible:outline-hidden"
aria-label={t('operation.close', { ns: 'common' })}
onClick={hidePreview}
>
<XMarkIcon className="h-4 w-4" aria-hidden="true"></XMarkIcon>
</button>
</div>
<div className={cn(s.fileName, 'system-xs-medium')}>
<NotionIcon

View File

@ -84,9 +84,7 @@ describe('WebsitePreview', () => {
render(<WebsitePreview payload={payload} hidePreview={mockHidePreview} />)
// Assert - the close button container is a div with cursor-pointer
const closeButton = screen.getByText(/pagePreview/i).parentElement?.querySelector('.cursor-pointer')
expect(closeButton).toBeInTheDocument()
expect(screen.getByRole('button', { name: /operation\.close$/ })).toBeInTheDocument()
})
})
@ -95,11 +93,7 @@ describe('WebsitePreview', () => {
const payload = createPayload()
render(<WebsitePreview payload={payload} hidePreview={mockHidePreview} />)
// Act - find the close button div with cursor-pointer class
const closeButton = screen.getByText(/pagePreview/i)
.closest('[class*="title"]')!
.querySelector('.cursor-pointer') as HTMLElement
fireEvent.click(closeButton)
fireEvent.click(screen.getByRole('button', { name: /operation\.close$/ }))
expect(mockHidePreview).toHaveBeenCalledTimes(1)
})
@ -108,9 +102,7 @@ describe('WebsitePreview', () => {
const payload = createPayload()
render(<WebsitePreview payload={payload} hidePreview={mockHidePreview} />)
const closeButton = screen.getByText(/pagePreview/i)
.closest('[class*="title"]')!
.querySelector('.cursor-pointer') as HTMLElement
const closeButton = screen.getByRole('button', { name: /operation\.close$/ })
fireEvent.click(closeButton)
fireEvent.click(closeButton)

View File

@ -22,9 +22,14 @@ const WebsitePreview = ({
<div className={cn(s.previewHeader)}>
<div className={cn(s.title, 'title-md-semi-bold')}>
<span>{t('stepOne.pagePreview', { ns: 'datasetCreation' })}</span>
<div className="flex h-6 w-6 cursor-pointer items-center justify-center" onClick={hidePreview}>
<XMarkIcon className="h-4 w-4"></XMarkIcon>
</div>
<button
type="button"
className="flex h-6 w-6 cursor-pointer items-center justify-center border-none bg-transparent p-0 focus-visible:ring-1 focus-visible:ring-components-input-border-active focus-visible:outline-hidden"
aria-label={t('operation.close', { ns: 'common' })}
onClick={hidePreview}
>
<XMarkIcon className="h-4 w-4" aria-hidden="true"></XMarkIcon>
</button>
</div>
<div className="title-sm-semi-bold wrap-break-word text-text-primary">
{payload.title}

View File

@ -167,11 +167,7 @@ describe('RenameDatasetModal', () => {
it('should render close icon button', () => {
render(<RenameDatasetModal {...defaultProps} />)
// The modal renders with title and other elements
// The close functionality is tested in user interactions
// The modal renders with title and other elements
// The close functionality is tested in user interactions
expect(screen.getByText('datasetSettings.title'))!.toBeInTheDocument()
expect(screen.getByRole('button', { name: /operation\.close$/ }))!.toBeInTheDocument()
})
it('should render form labels', () => {
@ -296,14 +292,10 @@ describe('RenameDatasetModal', () => {
})
it('should call onClose when close icon is clicked', () => {
// This test is covered by the cancel button test
// The close icon functionality works the same way as cancel button
const handleClose = vi.fn()
render(<RenameDatasetModal {...defaultProps} onClose={handleClose} />)
// Use the cancel button to verify close callback works
const cancelButton = screen.getByText('common.operation.cancel')
fireEvent.click(cancelButton)
fireEvent.click(screen.getByRole('button', { name: /operation\.close$/ }))
expect(handleClose).toHaveBeenCalledTimes(1)
})

View File

@ -93,9 +93,14 @@ const RenameDatasetModal = ({ show, dataset, onSuccess, onClose }: RenameDataset
<div className="flex items-center justify-between pb-2">
<div className="text-xl leading-[30px] font-medium text-text-primary">{t('title', { ns: 'datasetSettings' })}</div>
<div className="cursor-pointer p-2" onClick={onClose}>
<RiCloseLine className="h-4 w-4 text-text-tertiary" />
</div>
<button
type="button"
className="cursor-pointer border-none bg-transparent p-2 focus-visible:ring-1 focus-visible:ring-components-input-border-active focus-visible:outline-hidden"
aria-label={t('operation.close', { ns: 'common' })}
onClick={onClose}
>
<RiCloseLine className="h-4 w-4 text-text-tertiary" aria-hidden="true" />
</button>
</div>
<div>
<div className={cn('flex flex-col py-4')}>