[Bugfix] Bulk publish/unpublish for non-default locale entities (#17941)

* pass the locale to the publish and draft relations calls

* fix the problem for entities without internationalization and add unit tests
This commit is contained in:
Simone 2023-09-12 10:40:51 +02:00 committed by GitHub
parent c03a0a4a28
commit e3a5416487
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 86 additions and 7 deletions

View File

@ -6,6 +6,7 @@ import {
useFetchClient,
useNotification,
useAPIErrorHandler,
useQueryParams,
} from '@strapi/helper-plugin';
import { Check, ExclamationMarkCircle } from '@strapi/icons';
import PropTypes from 'prop-types';
@ -82,6 +83,7 @@ const ConfirmDialogPublishAll = ({ isOpen, onToggleDialog, isConfirmButtonLoadin
const {
contentType: { uid: slug },
} = useSelector(listViewDomain());
const [{ query }] = useQueryParams();
const {
data: countDraftRelations,
@ -97,6 +99,7 @@ const ConfirmDialogPublishAll = ({ isOpen, onToggleDialog, isConfirmButtonLoadin
{
params: {
ids: selectedEntries,
locale: query?.plugins?.i18n?.locale,
},
}
);

View File

@ -1,7 +1,7 @@
import React from 'react';
import { lightTheme, ThemeProvider } from '@strapi/design-system';
import { Table } from '@strapi/helper-plugin';
import { Table, useQueryParams } from '@strapi/helper-plugin';
import { render as renderRTL, screen, waitFor, within } from '@testing-library/react';
import { rest } from 'msw';
import { setupServer } from 'msw/node';
@ -34,6 +34,17 @@ jest.mock('@strapi/helper-plugin', () => ({
useNotification: jest.fn(() => {
return toggleNotification;
}),
useQueryParams: jest.fn(() => [
{
query: {
plugins: {
i18n: {
locale: 'en',
},
},
},
},
]),
}));
const handlers = [
@ -215,4 +226,35 @@ describe('ConfirmDialogPublishAll', () => {
);
expect(await screen.getByRole('alert')).toBeInTheDocument();
});
it('should show the warning message with 2 draft relations and 2 entries even if the locale param is not passed', async () => {
useQueryParams.mockImplementation(() => [
{
query: {
page: 1,
pageSize: 10,
sort: 'name:ASC',
},
},
]);
server.use(
rest.get('*/countManyEntriesDraftRelations', (req, res, ctx) => {
return res.once(
ctx.status(200),
ctx.json({
data: 2,
})
);
})
);
render();
await waitFor(() => {
const publishDialog = screen.getByRole('dialog');
expect(publishDialog).toBeInTheDocument();
within(publishDialog).getByText(/2 relations out of 2 entries are/i);
});
});
});

View File

@ -445,7 +445,7 @@ const SelectedEntriesModal = ({ onToggle }) => {
// We want to keep the selected entries order same as the list view
const [
{
query: { sort },
query: { sort, plugins },
},
] = useQueryParams();
@ -458,6 +458,7 @@ const SelectedEntriesModal = ({ onToggle }) => {
$in: entriesToFetch,
},
},
locale: plugins?.i18n?.locale,
};
const { get } = useFetchClient();

View File

@ -1,7 +1,7 @@
import React from 'react';
import { lightTheme, ThemeProvider } from '@strapi/design-system';
import { Table } from '@strapi/helper-plugin';
import { Table, useQueryParams } from '@strapi/helper-plugin';
import {
render as renderRTL,
screen,
@ -31,6 +31,11 @@ jest.mock('@strapi/helper-plugin', () => ({
{
query: {
sort: 'name:DESC',
plugins: {
i18n: {
locale: 'en',
},
},
},
},
]),
@ -159,6 +164,32 @@ describe('Bulk publish selected entries modal', () => {
expect(screen.queryByText('Entry 4')).not.toBeInTheDocument();
});
it('renders the selected items in the modal even if the locale param is not passed', async () => {
useQueryParams.mockImplementation(() => [
{
query: {
page: 1,
pageSize: 10,
sort: 'name:DESC',
},
},
]);
const { queryByText } = render(
<Table.Root defaultSelectedEntries={[1, 2, 3]} colCount={4}>
<SelectedEntriesModal onToggle={jest.fn()} />
</Table.Root>
);
await waitForElementToBeRemoved(() => queryByText('Loading content'));
expect(screen.getByText(/publish entries/i)).toBeInTheDocument();
// Nested table should render the selected items from the parent table
expect(screen.queryByText('Entry 1')).toBeInTheDocument();
expect(screen.queryByText('Entry 4')).not.toBeInTheDocument();
});
it('reacts to selection updates', async () => {
const { queryByText } = render(
<Table.Root defaultSelectedEntries={[1, 2, 3]} colCount={4}>

View File

@ -445,6 +445,7 @@ module.exports = {
async countManyEntriesDraftRelations(ctx) {
const { userAbility } = ctx.state;
const ids = ctx.request.query.ids;
const locale = ctx.request.query.locale;
const { model } = ctx.params;
const entityManager = getService('entity-manager');
@ -454,13 +455,13 @@ module.exports = {
return ctx.forbidden();
}
const entities = await entityManager.find(ids, model);
const entities = await entityManager.find({ ids, locale }, model);
if (!entities) {
return ctx.notFound();
}
const number = await entityManager.countManyEntriesDraftRelations(ids, model);
const number = await entityManager.countManyEntriesDraftRelations(ids, model, locale);
return {
data: number,

View File

@ -11,7 +11,7 @@ interface EntityManager {
publish(): any;
unpublish(): any;
countDraftRelations(id: string, uid: string): number;
countManyEntriesDraftRelations(ids: number[], uid: string): number;
countManyEntriesDraftRelations(ids: number[], uid: string, locale?: string): number;
}
export default function (opts: { strapi: Strapi }): EntityManager;

View File

@ -301,7 +301,7 @@ module.exports = ({ strapi }) => ({
return sumDraftCounts(entity, uid);
},
async countManyEntriesDraftRelations(ids, uid) {
async countManyEntriesDraftRelations(ids, uid, locale = 'en') {
const { populate, hasRelations } = getDeepPopulateDraftCount(uid);
if (!hasRelations) {
@ -311,6 +311,7 @@ module.exports = ({ strapi }) => ({
const entities = await strapi.entityService.findMany(uid, {
populate,
filters: { id: { $in: ids } },
locale,
});
const totalNumberDraftRelations = entities.reduce(