-
Notifications
You must be signed in to change notification settings - Fork 417
[Website] Add error notices and delete confirmation modal to site management #3454
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
d8530d4
3fd14d9
ad1937c
0b0a92a
f7c675e
a7a8cd6
e3ebe12
6dd8960
96fd729
a5e67b3
b0890f9
7684980
0d5a4bf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| import { useState } from 'react'; | ||
| import { Notice, __experimentalText as Text } from '@wordpress/components'; | ||
| import { useAppDispatch, useAppSelector } from '../../lib/state/redux/store'; | ||
| import { | ||
| setActiveModal, | ||
| setSiteSlugToDelete, | ||
| } from '../../lib/state/redux/slice-ui'; | ||
| import { useSitesAPI } from '../../lib/state/redux/site-management-api-middleware'; | ||
| import { Modal } from '../modal'; | ||
| import ModalButtons from '../modal/modal-buttons'; | ||
| import css from '../modal/style.module.css'; | ||
|
|
||
| export function DeleteSiteModal() { | ||
| const dispatch = useAppDispatch(); | ||
| const sitesAPI = useSitesAPI(); | ||
| const siteSlugToDelete = useAppSelector( | ||
| (state) => state.ui.siteSlugToDelete | ||
| ); | ||
| const site = useAppSelector((state) => | ||
| siteSlugToDelete ? state.sites.entities[siteSlugToDelete] : undefined | ||
| ); | ||
|
|
||
| const [isSubmitting, setIsSubmitting] = useState(false); | ||
| const [error, setError] = useState<string | null>(null); | ||
|
|
||
| if (!site || site.metadata.storage === 'none') { | ||
| return null; | ||
| } | ||
|
|
||
| const closeModal = () => { | ||
| dispatch(setActiveModal(null)); | ||
| dispatch(setSiteSlugToDelete(undefined)); | ||
| }; | ||
|
|
||
| const handleSubmit = async () => { | ||
| try { | ||
| setIsSubmitting(true); | ||
| setError(null); | ||
| await sitesAPI.delete(site.slug); | ||
| closeModal(); | ||
| } catch (e) { | ||
| setError( | ||
| e instanceof Error | ||
| ? e.message | ||
| : 'Deleting failed. Please try again.' | ||
| ); | ||
| } finally { | ||
| setIsSubmitting(false); | ||
| } | ||
| }; | ||
|
|
||
| return ( | ||
| <Modal | ||
| title="Delete Playground" | ||
| contentLabel='This is a dialog window which overlays the main content of the page. The modal begins with a heading 2 called "Delete Playground". Pressing the Close button will close the modal and bring you back to where you were on the page.' | ||
| onRequestClose={closeModal} | ||
| small | ||
| > | ||
| <form | ||
| className={css.modalForm} | ||
| onSubmit={(e) => { | ||
| e.preventDefault(); | ||
| handleSubmit(); | ||
| }} | ||
| > | ||
| <Text> | ||
| Are you sure you want to delete the site “ | ||
| {site.metadata.name}”? This action cannot be undone. | ||
| </Text> | ||
| {error ? ( | ||
| <Notice status="error" isDismissible={false}> | ||
| {error} | ||
| </Notice> | ||
| ) : null} | ||
| <ModalButtons | ||
| submitText="Delete" | ||
| areBusy={isSubmitting} | ||
| onCancel={closeModal} | ||
| /> | ||
| </form> | ||
| </Modal> | ||
| ); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,6 +31,7 @@ import { | |
| setSiteManagerOpen, | ||
| setSiteManagerSection, | ||
| setSiteSlugToRename, | ||
| setSiteSlugToDelete, | ||
| } from '../../lib/state/redux/slice-ui'; | ||
| import { useSitesAPI } from '../../lib/state/redux/site-management-api-middleware'; | ||
| import { WordPressIcon } from '@wp-playground/components'; | ||
|
|
@@ -247,14 +248,10 @@ export function SavedPlaygroundsOverlay({ | |
| return `data:${logo.mime};base64,${logo.data}`; | ||
| }; | ||
|
|
||
| const handleDeleteSite = async (site: SiteInfo, closeMenu: () => void) => { | ||
| const proceed = window.confirm( | ||
| `Are you sure you want to delete the site '${site.metadata.name}'?` | ||
| ); | ||
| if (proceed) { | ||
| await sitesAPI.delete(site.slug); | ||
| closeMenu(); | ||
| } | ||
| const handleDeleteSite = (site: SiteInfo, closeMenu: () => void) => { | ||
| dispatch(setSiteSlugToDelete(site.slug)); | ||
| modalDispatch(setActiveModal(modalSlugs.DELETE_SITE)); | ||
| closeMenu(); | ||
| }; | ||
|
Comment on lines
+251
to
255
|
||
|
|
||
| const handleRenameSite = (site: SiteInfo, closeMenu: () => void) => { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When
activeModalisDELETE_SITEbut the selected site is missing (e.g., stale slug, deleted elsewhere, or store mismatch), returningnullrenders no modal while leaving the modal route/state active. This can strand users withmodal=delete-sitein the URL and no visible way to close it. Instead of returningnull, proactively close/reset the modal state (e.g., via an effect) or render a minimal modal that explains the issue and offers a close button.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bgrgicak This one too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add useEffect to handle unexisting site deletion modal state