diff --git a/packages/core/admin/admin/src/content-manager/components/DynamicTable/BulkActionsBar/index.js b/packages/core/admin/admin/src/content-manager/components/DynamicTable/BulkActionsBar/index.js
index 6f77009f1a..7ffe9c9336 100644
--- a/packages/core/admin/admin/src/content-manager/components/DynamicTable/BulkActionsBar/index.js
+++ b/packages/core/admin/admin/src/content-manager/components/DynamicTable/BulkActionsBar/index.js
@@ -3,9 +3,11 @@ import PropTypes from 'prop-types';
import { Button, Dialog, DialogBody, DialogFooter, Flex, Typography } from '@strapi/design-system';
import { Check, ExclamationMarkCircle, Trash } from '@strapi/icons';
import { useIntl } from 'react-intl';
+import { useSelector } from 'react-redux';
import { useTracking } from '@strapi/helper-plugin';
import { getTrad } from '../../../utils';
import InjectionZoneList from '../../InjectionZoneList';
+import { listViewDomain } from '../../../pages/ListView/selectors';
const ConfirmBulkActionDialog = ({ onToggleDialog, isOpen, dialogBody, endAction }) => {
const { formatMessage } = useIntl();
@@ -183,9 +185,18 @@ const BulkActionsBar = ({
}) => {
const { formatMessage } = useIntl();
const { trackUsage } = useTracking();
+ const { data } = useSelector(listViewDomain());
+
const [isConfirmButtonLoading, setIsConfirmButtonLoading] = useState(false);
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 = () => {
if (dialogToOpen === 'delete') {
setDialogToOpen(null);
@@ -232,20 +243,24 @@ const BulkActionsBar = ({
return (
<>
- {showPublish && (
+ {publishButtonIsShown && (
<>
-
+ >
+ )}
+ {unpublishButtonIsShown && (
+ <>
+
({
}),
}));
+jest.mock('react-redux', () => ({
+ useSelector: () => ({
+ data: [
+ { id: 1, publishedAt: null },
+ { id: 2, publishedAt: '2023-01-01T10:10:10.408Z' },
+ ],
+ }),
+}));
+
jest.mock('../../../../../shared/hooks', () => ({
...jest.requireActual('../../../../../shared/hooks'),
useInjectionZone: () => [],
@@ -21,7 +30,7 @@ const user = userEvent.setup();
describe('BulkActionsBar', () => {
const requiredProps = {
- selectedEntries: [],
+ selectedEntries: [1, 2],
clearSelectedEntries: jest.fn(),
};
@@ -82,7 +91,19 @@ describe('BulkActionsBar', () => {
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 () => {
@@ -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 () => {
@@ -110,6 +131,6 @@ describe('BulkActionsBar', () => {
);
});
- expect(onConfirmUnpublishAll).toHaveBeenCalledWith([]);
+ expect(onConfirmUnpublishAll).toHaveBeenCalledWith([1, 2]);
});
});