feat: show confirmation dialog before discarding library changes [FC-0062] (#1428)
* feat: show confirmation dialog before discarding library changes
This commit is contained in:
@@ -18,11 +18,15 @@ const DeleteModal = ({
|
||||
description,
|
||||
variant,
|
||||
btnState,
|
||||
btnDefaultLabel,
|
||||
btnPendingLabel,
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
|
||||
const modalTitle = title || intl.formatMessage(messages.title, { category });
|
||||
const modalDescription = description || intl.formatMessage(messages.description, { category });
|
||||
const defaultBtnLabel = btnDefaultLabel || intl.formatMessage(messages.deleteButton);
|
||||
const pendingBtnLabel = btnPendingLabel || intl.formatMessage(messages.pendingDeleteButton);
|
||||
|
||||
return (
|
||||
<AlertModal
|
||||
@@ -51,8 +55,8 @@ const DeleteModal = ({
|
||||
onDeleteSubmit();
|
||||
}}
|
||||
labels={{
|
||||
default: intl.formatMessage(messages.deleteButton),
|
||||
pending: intl.formatMessage(messages.pendingDeleteButton),
|
||||
default: defaultBtnLabel,
|
||||
pending: pendingBtnLabel,
|
||||
}}
|
||||
/>
|
||||
</ActionRow>
|
||||
@@ -69,6 +73,8 @@ DeleteModal.defaultProps = {
|
||||
description: '',
|
||||
variant: 'default',
|
||||
btnState: 'default',
|
||||
btnDefaultLabel: '',
|
||||
btnPendingLabel: '',
|
||||
};
|
||||
|
||||
DeleteModal.propTypes = {
|
||||
@@ -80,6 +86,8 @@ DeleteModal.propTypes = {
|
||||
description: PropTypes.string,
|
||||
variant: PropTypes.string,
|
||||
btnState: PropTypes.string,
|
||||
btnDefaultLabel: PropTypes.string,
|
||||
btnPendingLabel: PropTypes.string,
|
||||
};
|
||||
|
||||
export default DeleteModal;
|
||||
|
||||
@@ -486,7 +486,7 @@ describe('<LibraryAuthoringPage />', () => {
|
||||
await renderLibraryPage();
|
||||
|
||||
// Open menu
|
||||
fireEvent.click(screen.getAllByTestId('component-card-menu-toggle')[0]);
|
||||
fireEvent.click((await screen.findAllByTestId('component-card-menu-toggle'))[0]);
|
||||
// Click add to collection
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Add to collection' }));
|
||||
|
||||
|
||||
@@ -161,6 +161,8 @@ describe('<LibraryInfo />', () => {
|
||||
|
||||
const discardButton = screen.getByRole('button', { name: /discard changes/i });
|
||||
fireEvent.click(discardButton);
|
||||
const confirmBtn = screen.getByRole('button', { name: /discard/i });
|
||||
fireEvent.click(confirmBtn);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(axiosMock.history.delete[0].url).toEqual(url);
|
||||
@@ -177,6 +179,8 @@ describe('<LibraryInfo />', () => {
|
||||
|
||||
const discardButton = screen.getByRole('button', { name: /discard changes/i });
|
||||
fireEvent.click(discardButton);
|
||||
const confirmBtn = screen.getByRole('button', { name: /discard/i });
|
||||
fireEvent.click(confirmBtn);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(axiosMock.history.delete[0].url).toEqual(url);
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
import { useCallback, useContext } from 'react';
|
||||
import { useCallback, useContext, useState } from 'react';
|
||||
import { useIntl } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import { useToggle } from '@openedx/paragon';
|
||||
import { ToastContext } from '../../generic/toast-context';
|
||||
import { useLibraryContext } from '../common/context';
|
||||
import { useCommitLibraryChanges, useRevertLibraryChanges } from '../data/apiHooks';
|
||||
import StatusWidget from '../generic/status-widget';
|
||||
import messages from './messages';
|
||||
import DeleteModal from '../../generic/delete-modal/DeleteModal';
|
||||
|
||||
const LibraryPublishStatus = () => {
|
||||
const intl = useIntl();
|
||||
const { libraryData, readOnly } = useLibraryContext();
|
||||
const [isConfirmModalOpen, openConfirmModal, closeConfirmModal] = useToggle(false);
|
||||
const [confirmBtnState, setConfirmBtnState] = useState('default');
|
||||
|
||||
const commitLibraryChanges = useCommitLibraryChanges();
|
||||
const revertLibraryChanges = useRevertLibraryChanges();
|
||||
@@ -28,11 +32,15 @@ const LibraryPublishStatus = () => {
|
||||
|
||||
const revert = useCallback(() => {
|
||||
if (libraryData) {
|
||||
setConfirmBtnState('pending');
|
||||
revertLibraryChanges.mutateAsync(libraryData.id)
|
||||
.then(() => {
|
||||
showToast(intl.formatMessage(messages.revertSuccessMsg));
|
||||
}).catch(() => {
|
||||
showToast(intl.formatMessage(messages.revertErrorMsg));
|
||||
}).finally(() => {
|
||||
setConfirmBtnState('default');
|
||||
closeConfirmModal();
|
||||
});
|
||||
}
|
||||
}, [libraryData]);
|
||||
@@ -42,11 +50,24 @@ const LibraryPublishStatus = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<StatusWidget
|
||||
{...libraryData}
|
||||
onCommit={!readOnly ? commit : undefined}
|
||||
onRevert={!readOnly ? revert : undefined}
|
||||
/>
|
||||
<>
|
||||
<StatusWidget
|
||||
{...libraryData}
|
||||
onCommit={!readOnly ? commit : undefined}
|
||||
onRevert={!readOnly ? openConfirmModal : undefined}
|
||||
/>
|
||||
<DeleteModal
|
||||
isOpen={isConfirmModalOpen}
|
||||
close={closeConfirmModal}
|
||||
variant="warning"
|
||||
title={intl.formatMessage(messages.discardChangesTitle)}
|
||||
description={intl.formatMessage(messages.discardChangesDescription)}
|
||||
onDeleteSubmit={revert}
|
||||
btnState={confirmBtnState}
|
||||
btnDefaultLabel={intl.formatMessage(messages.discardChangesDefaultBtnLabel)}
|
||||
btnPendingLabel={intl.formatMessage(messages.discardChangesDefaultBtnLabel)}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -61,6 +61,21 @@ const messages = defineMessages({
|
||||
defaultMessage: 'There was an error updating the library',
|
||||
description: 'Message when there is an error when updating the library',
|
||||
},
|
||||
discardChangesTitle: {
|
||||
id: 'course-authoring.library-authoring.library.discardChangesTitle',
|
||||
defaultMessage: 'Discard changes',
|
||||
description: 'Title text for confirmation modal shown before discard library changes',
|
||||
},
|
||||
discardChangesDescription: {
|
||||
id: 'course-authoring.library-authoring.library.discardChangesDescription',
|
||||
defaultMessage: 'Are you sure you want to discard all unpublished changes in this library? This will include changes made by other users',
|
||||
description: 'Description text for confirmation modal shown before discard library changes',
|
||||
},
|
||||
discardChangesDefaultBtnLabel: {
|
||||
id: 'course-authoring.library-authoring.library.discardChangesDefaultBtnLabel',
|
||||
defaultMessage: 'Discard',
|
||||
description: 'Button text for confirmation modal shown before discard library changes',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
|
||||
Reference in New Issue
Block a user