fix: discard button [FC-0062] (#1214)
* fix: discard changes * refactor: disable discard btn for new libs Enable it if components are added. * refactor: invalidate library related content queries * chore: add comment about content search query invalidation
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import {
|
||||
useQuery, useMutation, useQueryClient, Query,
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
import {
|
||||
type GetLibrariesV2CustomParams,
|
||||
@@ -122,6 +124,22 @@ export const useRevertLibraryChanges = () => {
|
||||
mutationFn: revertLibraryChanges,
|
||||
onSettled: (_data, _error, libraryId) => {
|
||||
queryClient.invalidateQueries({ queryKey: libraryAuthoringQueryKeys.contentLibrary(libraryId) });
|
||||
queryClient.invalidateQueries({
|
||||
// Invalidate all content queries related to this library.
|
||||
// If we allow searching "all courses and libraries" in the future,
|
||||
// then we'd have to invalidate all `["content_search", "results"]`
|
||||
// queries, and not just the ones for this library, because items from
|
||||
// this library could be included in an "all courses and libraries"
|
||||
// search. For now we only allow searching individual libraries.
|
||||
predicate: /* istanbul ignore next */ (query: Query): boolean => {
|
||||
// extraFilter contains library id
|
||||
const extraFilter = query.queryKey[5];
|
||||
if (!(Array.isArray(extraFilter) || typeof extraFilter === 'string')) {
|
||||
return false;
|
||||
}
|
||||
return query.queryKey[0] === 'content_search' && extraFilter?.includes(`context_key = "${libraryId}"`);
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -204,4 +204,44 @@ describe('<LibraryInfo />', () => {
|
||||
|
||||
await waitFor(() => expect(axiosMock.history.post[0].url).toEqual(url));
|
||||
});
|
||||
|
||||
it('should discard changes', async () => {
|
||||
const url = getCommitLibraryChangesUrl(libraryData.id);
|
||||
axiosMock.onDelete(url).reply(200);
|
||||
|
||||
render(<RootWrapper data={libraryData} />);
|
||||
const discardButton = screen.getByRole('button', { name: /discard changes/i });
|
||||
fireEvent.click(discardButton);
|
||||
|
||||
expect(await screen.findByText('Library changes reverted successfully')).toBeInTheDocument();
|
||||
|
||||
await waitFor(() => expect(axiosMock.history.delete[0].url).toEqual(url));
|
||||
});
|
||||
|
||||
it('should show error on discard changes', async () => {
|
||||
const url = getCommitLibraryChangesUrl(libraryData.id);
|
||||
axiosMock.onDelete(url).reply(500);
|
||||
|
||||
render(<RootWrapper data={libraryData} />);
|
||||
const discardButton = screen.getByRole('button', { name: /discard changes/i });
|
||||
fireEvent.click(discardButton);
|
||||
|
||||
expect(await screen.findByText('There was an error reverting changes in the library.')).toBeInTheDocument();
|
||||
|
||||
await waitFor(() => expect(axiosMock.history.delete[0].url).toEqual(url));
|
||||
});
|
||||
|
||||
it('discard changes btn should be disabled for new libraries', async () => {
|
||||
render(<RootWrapper data={{ ...libraryData, lastPublished: null, numBlocks: 0 }} />);
|
||||
const discardButton = screen.getByRole('button', { name: /discard changes/i });
|
||||
|
||||
expect(discardButton).toBeDisabled();
|
||||
});
|
||||
|
||||
it('discard changes btn should be enabled for new libraries if components are added', async () => {
|
||||
render(<RootWrapper data={{ ...libraryData, lastPublished: null, numBlocks: 2 }} />);
|
||||
const discardButton = screen.getByRole('button', { name: /discard changes/i });
|
||||
|
||||
expect(discardButton).not.toBeDisabled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { useCallback, useContext, useMemo } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { Button, Container, Stack } from '@openedx/paragon';
|
||||
import { FormattedDate, FormattedTime, useIntl } from '@edx/frontend-platform/i18n';
|
||||
import { useCommitLibraryChanges } from '../data/apiHooks';
|
||||
import { useCommitLibraryChanges, useRevertLibraryChanges } from '../data/apiHooks';
|
||||
import { ContentLibrary } from '../data/api';
|
||||
import { ToastContext } from '../../generic/toast-context';
|
||||
import messages from './messages';
|
||||
@@ -14,6 +14,7 @@ type LibraryPublishStatusProps = {
|
||||
const LibraryPublishStatus = ({ library } : LibraryPublishStatusProps) => {
|
||||
const intl = useIntl();
|
||||
const commitLibraryChanges = useCommitLibraryChanges();
|
||||
const revertLibraryChanges = useRevertLibraryChanges();
|
||||
const { showToast } = useContext(ToastContext);
|
||||
|
||||
const commit = useCallback(() => {
|
||||
@@ -25,9 +26,6 @@ const LibraryPublishStatus = ({ library } : LibraryPublishStatusProps) => {
|
||||
});
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* TODO, the discard changes breaks the library.
|
||||
* Discomment this when discard changes is fixed.
|
||||
const revert = useCallback(() => {
|
||||
revertLibraryChanges.mutateAsync(library.id)
|
||||
.then(() => {
|
||||
@@ -36,15 +34,16 @@ const LibraryPublishStatus = ({ library } : LibraryPublishStatusProps) => {
|
||||
showToast(intl.formatMessage(messages.revertErrorMsg));
|
||||
});
|
||||
}, []);
|
||||
*/
|
||||
|
||||
const {
|
||||
isPublished,
|
||||
isNew,
|
||||
statusMessage,
|
||||
extraStatusMessage,
|
||||
bodyMessage,
|
||||
} = useMemo(() => {
|
||||
let isPublishedResult: boolean;
|
||||
let isNewResult = false;
|
||||
let statusMessageResult : string;
|
||||
let extraStatusMessageResult : string | undefined;
|
||||
let bodyMessageResult : string | undefined;
|
||||
@@ -94,6 +93,7 @@ const LibraryPublishStatus = ({ library } : LibraryPublishStatusProps) => {
|
||||
|
||||
if (!library.lastPublished) {
|
||||
// Library is never published (new)
|
||||
isNewResult = library.numBlocks === 0; // allow discarding if components are added
|
||||
isPublishedResult = false;
|
||||
statusMessageResult = intl.formatMessage(messages.draftStatusLabel);
|
||||
extraStatusMessageResult = intl.formatMessage(messages.neverPublishedLabel);
|
||||
@@ -123,6 +123,7 @@ const LibraryPublishStatus = ({ library } : LibraryPublishStatusProps) => {
|
||||
}
|
||||
return {
|
||||
isPublished: isPublishedResult,
|
||||
isNew: isNewResult,
|
||||
statusMessage: statusMessageResult,
|
||||
extraStatusMessage: extraStatusMessageResult,
|
||||
bodyMessage: bodyMessageResult,
|
||||
@@ -153,15 +154,11 @@ const LibraryPublishStatus = ({ library } : LibraryPublishStatusProps) => {
|
||||
<Button disabled={isPublished} onClick={commit}>
|
||||
{intl.formatMessage(messages.publishButtonLabel)}
|
||||
</Button>
|
||||
{ /*
|
||||
* TODO, the discard changes breaks the library.
|
||||
* Discomment this when discard changes is fixed.
|
||||
<div className="d-flex justify-content-end">
|
||||
<Button disabled={isPublished} variant="link" onClick={revert}>
|
||||
{intl.formatMessage(messages.discardChangesButtonLabel)}
|
||||
</Button>
|
||||
</div>
|
||||
*/ }
|
||||
<div className="d-flex justify-content-end">
|
||||
<Button disabled={isPublished || isNew} variant="link" onClick={revert}>
|
||||
{intl.formatMessage(messages.discardChangesButtonLabel)}
|
||||
</Button>
|
||||
</div>
|
||||
</Stack>
|
||||
</Container>
|
||||
</Stack>
|
||||
|
||||
Reference in New Issue
Block a user