feat(ui): confirmation modal (#11271)
There are nearly a dozen independent implementations of the same modal
spread throughout the admin panel and various plugins. These modals are
used to confirm or cancel an action, such as deleting a document, bulk
publishing, etc. Each of these instances is nearly identical, leading to
unnecessary development efforts when creating them, inconsistent UI, and
duplicative stylesheets.
Everything is now standardized behind a new `ConfirmationModal`
component. This modal comes with a standard API that is flexible enough
to replace nearly every instance. This component has also been exported
for reuse.
Here is a basic example of how to use it:
```tsx
'use client'
import { ConfirmationModal, useModal } from '@payloadcms/ui'
import React, { Fragment } from 'react'
const modalSlug = 'my-confirmation-modal'
export function MyComponent() {
const { openModal } = useModal()
return (
<Fragment>
<button
onClick={() => {
openModal(modalSlug)
}}
type="button"
>
Do something
</button>
<ConfirmationModal
heading="Are you sure?"
body="Confirm or cancel before proceeding."
modalSlug={modalSlug}
onConfirm={({ closeConfirmationModal, setConfirming }) => {
// do something
setConfirming(false)
closeConfirmationModal()
}}
/>
</Fragment>
)
}
```
This commit is contained in:
@@ -704,7 +704,7 @@ describe('General', () => {
|
||||
await page.goto(postsUrl.edit(id))
|
||||
await openDocControls(page)
|
||||
await page.locator('#action-delete').click()
|
||||
await page.locator('#confirm-delete').click()
|
||||
await page.locator(`[id=delete-${id}] #confirm-action`).click()
|
||||
await expect(page.locator(`text=Post "${title}" successfully deleted.`)).toBeVisible()
|
||||
expect(page.url()).toContain(postsUrl.list)
|
||||
})
|
||||
@@ -715,7 +715,7 @@ describe('General', () => {
|
||||
await page.goto(postsUrl.list)
|
||||
await page.locator('input#select-all').check()
|
||||
await page.locator('.delete-documents__toggle').click()
|
||||
await page.locator('#confirm-delete').click()
|
||||
await page.locator('#delete-posts #confirm-action').click()
|
||||
|
||||
await expect(page.locator('.payload-toast-container .toast-success')).toHaveText(
|
||||
'Deleted 3 Posts successfully.',
|
||||
@@ -733,7 +733,7 @@ describe('General', () => {
|
||||
await page.locator('input#select-all').check()
|
||||
await page.locator('button.list-selection__button').click()
|
||||
await page.locator('.delete-documents__toggle').click()
|
||||
await page.locator('#confirm-delete').click()
|
||||
await page.locator('#delete-posts #confirm-action').click()
|
||||
|
||||
await expect(page.locator('.payload-toast-container .toast-success')).toHaveText(
|
||||
'Deleted 1 Post successfully.',
|
||||
@@ -917,7 +917,9 @@ describe('General', () => {
|
||||
await expect(modalContainer).toBeVisible()
|
||||
|
||||
// Click the "Leave anyway" button
|
||||
await page.locator('.leave-without-saving__controls .btn--style-primary').click()
|
||||
await page
|
||||
.locator('#leave-without-saving .confirmation-modal__controls .btn--style-primary')
|
||||
.click()
|
||||
|
||||
// Assert that the class on the modal container changes to 'payload__modal-container--exitDone'
|
||||
await expect(modalContainer).toHaveClass(/payload__modal-container--exitDone/)
|
||||
|
||||
@@ -1006,19 +1006,18 @@ describe('List View', () => {
|
||||
|
||||
test('should delete many', async () => {
|
||||
await page.goto(postsUrl.list)
|
||||
await page.waitForURL(new RegExp(postsUrl.list))
|
||||
// delete should not appear without selection
|
||||
await expect(page.locator('#confirm-delete')).toHaveCount(0)
|
||||
await expect(page.locator('#delete-posts #confirm-action')).toHaveCount(0)
|
||||
// select one row
|
||||
await page.locator('.row-1 .cell-_select input').check()
|
||||
|
||||
// delete button should be present
|
||||
await expect(page.locator('#confirm-delete')).toHaveCount(1)
|
||||
await expect(page.locator('#delete-posts #confirm-action')).toHaveCount(1)
|
||||
|
||||
await page.locator('.row-2 .cell-_select input').check()
|
||||
|
||||
await page.locator('.delete-documents__toggle').click()
|
||||
await page.locator('#confirm-delete').click()
|
||||
await page.locator('#delete-posts #confirm-action').click()
|
||||
await expect(page.locator('.cell-_select')).toHaveCount(1)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -64,6 +64,7 @@ export interface Config {
|
||||
auth: {
|
||||
users: UserAuthOperations;
|
||||
};
|
||||
blocks: {};
|
||||
collections: {
|
||||
uploads: Upload;
|
||||
posts: Post;
|
||||
|
||||
Reference in New Issue
Block a user