mirror of
https://github.com/langgenius/dify.git
synced 2026-05-28 04:43:33 +08:00
fix(web): name preview close controls
This commit is contained in:
@ -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()
|
||||
|
||||
@ -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">
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -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}
|
||||
|
||||
@ -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)
|
||||
})
|
||||
|
||||
@ -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')}>
|
||||
|
||||
Reference in New Issue
Block a user