Merge pull request #16586 from strapi/bulk-publish/entries-status

[Bulk Publish] Show publish/unpublish button sbased on entries publishedAt status
This commit is contained in:
Fernando Chávez 2023-05-10 10:17:47 +02:00 committed by GitHub
commit af744b9d4e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 8 deletions

View File

@ -3,9 +3,11 @@ import PropTypes from 'prop-types';
import { Button, Dialog, DialogBody, DialogFooter, Flex, Typography } from '@strapi/design-system'; import { Button, Dialog, DialogBody, DialogFooter, Flex, Typography } from '@strapi/design-system';
import { Check, ExclamationMarkCircle, Trash } from '@strapi/icons'; import { Check, ExclamationMarkCircle, Trash } from '@strapi/icons';
import { useIntl } from 'react-intl'; import { useIntl } from 'react-intl';
import { useSelector } from 'react-redux';
import { useTracking } from '@strapi/helper-plugin'; import { useTracking } from '@strapi/helper-plugin';
import { getTrad } from '../../../utils'; import { getTrad } from '../../../utils';
import InjectionZoneList from '../../InjectionZoneList'; import InjectionZoneList from '../../InjectionZoneList';
import { listViewDomain } from '../../../pages/ListView/selectors';
const ConfirmBulkActionDialog = ({ onToggleDialog, isOpen, dialogBody, endAction }) => { const ConfirmBulkActionDialog = ({ onToggleDialog, isOpen, dialogBody, endAction }) => {
const { formatMessage } = useIntl(); const { formatMessage } = useIntl();
@ -183,9 +185,18 @@ const BulkActionsBar = ({
}) => { }) => {
const { formatMessage } = useIntl(); const { formatMessage } = useIntl();
const { trackUsage } = useTracking(); const { trackUsage } = useTracking();
const { data } = useSelector(listViewDomain());
const [isConfirmButtonLoading, setIsConfirmButtonLoading] = useState(false); const [isConfirmButtonLoading, setIsConfirmButtonLoading] = useState(false);
const [dialogToOpen, setDialogToOpen] = useState(null); const [dialogToOpen, setDialogToOpen] = useState(null);
// Filters for Bulk actions
const selectedEntriesObjects = data.filter((entry) => selectedEntries.includes(entry.id));
const publishButtonIsShown =
showPublish && selectedEntriesObjects.some((entry) => !entry.publishedAt);
const unpublishButtonIsShown =
showPublish && selectedEntriesObjects.some((entry) => entry.publishedAt);
const toggleDeleteModal = () => { const toggleDeleteModal = () => {
if (dialogToOpen === 'delete') { if (dialogToOpen === 'delete') {
setDialogToOpen(null); setDialogToOpen(null);
@ -232,20 +243,24 @@ const BulkActionsBar = ({
return ( return (
<> <>
{showPublish && ( {publishButtonIsShown && (
<> <>
<Button variant="tertiary" onClick={togglePublishModal}> <Button variant="tertiary" onClick={togglePublishModal}>
{formatMessage({ id: 'app.utils.publish', defaultMessage: 'Publish' })} {formatMessage({ id: 'app.utils.publish', defaultMessage: 'Publish' })}
</Button> </Button>
<Button variant="tertiary" onClick={toggleUnpublishModal}>
{formatMessage({ id: 'app.utils.unpublish', defaultMessage: 'Unpublish' })}
</Button>
<ConfirmDialogPublishAll <ConfirmDialogPublishAll
isOpen={dialogToOpen === 'publish'} isOpen={dialogToOpen === 'publish'}
onToggleDialog={togglePublishModal} onToggleDialog={togglePublishModal}
isConfirmButtonLoading={isConfirmButtonLoading} isConfirmButtonLoading={isConfirmButtonLoading}
onConfirm={handleBulkPublish} onConfirm={handleBulkPublish}
/> />
</>
)}
{unpublishButtonIsShown && (
<>
<Button variant="tertiary" onClick={toggleUnpublishModal}>
{formatMessage({ id: 'app.utils.unpublish', defaultMessage: 'Unpublish' })}
</Button>
<ConfirmDialogUnpublishAll <ConfirmDialogUnpublishAll
isOpen={dialogToOpen === 'unpublish'} isOpen={dialogToOpen === 'unpublish'}
onToggleDialog={toggleUnpublishModal} onToggleDialog={toggleUnpublishModal}

View File

@ -12,6 +12,15 @@ jest.mock('@strapi/helper-plugin', () => ({
}), }),
})); }));
jest.mock('react-redux', () => ({
useSelector: () => ({
data: [
{ id: 1, publishedAt: null },
{ id: 2, publishedAt: '2023-01-01T10:10:10.408Z' },
],
}),
}));
jest.mock('../../../../../shared/hooks', () => ({ jest.mock('../../../../../shared/hooks', () => ({
...jest.requireActual('../../../../../shared/hooks'), ...jest.requireActual('../../../../../shared/hooks'),
useInjectionZone: () => [], useInjectionZone: () => [],
@ -21,7 +30,7 @@ const user = userEvent.setup();
describe('BulkActionsBar', () => { describe('BulkActionsBar', () => {
const requiredProps = { const requiredProps = {
selectedEntries: [], selectedEntries: [1, 2],
clearSelectedEntries: jest.fn(), clearSelectedEntries: jest.fn(),
}; };
@ -82,7 +91,19 @@ describe('BulkActionsBar', () => {
await user.click(screen.getByRole('button', { name: /confirm/i })); await user.click(screen.getByRole('button', { name: /confirm/i }));
}); });
expect(mockConfirmDeleteAll).toHaveBeenCalledWith([]); expect(mockConfirmDeleteAll).toHaveBeenCalledWith([1, 2]);
});
it('should not show publish button if selected entries are all published', () => {
setup({ showPublish: true, selectedEntries: [2] });
expect(screen.queryByRole('button', { name: /\bPublish\b/ })).not.toBeInTheDocument();
});
it('should not show unpublish button if selected entries are all unpublished', () => {
setup({ showPublish: true, selectedEntries: [1] });
expect(screen.queryByRole('button', { name: /\bUnpublish\b/ })).not.toBeInTheDocument();
}); });
it('should show publish modal if publish button is clicked', async () => { it('should show publish modal if publish button is clicked', async () => {
@ -96,7 +117,7 @@ describe('BulkActionsBar', () => {
); );
}); });
expect(onConfirmPublishAll).toHaveBeenCalledWith([]); expect(onConfirmPublishAll).toHaveBeenCalledWith([1, 2]);
}); });
it('should show unpublish modal if unpublish button is clicked', async () => { it('should show unpublish modal if unpublish button is clicked', async () => {
@ -110,6 +131,6 @@ describe('BulkActionsBar', () => {
); );
}); });
expect(onConfirmUnpublishAll).toHaveBeenCalledWith([]); expect(onConfirmUnpublishAll).toHaveBeenCalledWith([1, 2]);
}); });
}); });