@strapi/i18n 0.0.0-experimental.17b4116f461a49b8ce5386f7c8d79c511d40fb3b → 0.0.0-experimental.25e22c6cc9bc6b35392bb55d09f641a0a65e7403
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/{SettingsPage-CeqfDjsb.mjs → SettingsPage-Dsi2qGtq.mjs} +109 -125
- package/dist/_chunks/SettingsPage-Dsi2qGtq.mjs.map +1 -0
- package/dist/_chunks/{SettingsPage-Djqsdrzs.js → SettingsPage-VN7sTzkb.js} +109 -125
- package/dist/_chunks/SettingsPage-VN7sTzkb.js.map +1 -0
- package/dist/_chunks/{en-CnrTsjWS.mjs → en-18tWw4P6.mjs} +4 -1
- package/dist/_chunks/en-18tWw4P6.mjs.map +1 -0
- package/dist/_chunks/{en-BuBc6LKZ.js → en-Kv6y9zPQ.js} +4 -1
- package/dist/_chunks/en-Kv6y9zPQ.js.map +1 -0
- package/dist/_chunks/{index-BDU1w_fd.mjs → index-DhtjJYrx.mjs} +445 -131
- package/dist/_chunks/index-DhtjJYrx.mjs.map +1 -0
- package/dist/_chunks/{index-DMXJeGjN.js → index-kedPlCo6.js} +439 -127
- package/dist/_chunks/index-kedPlCo6.js.map +1 -0
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +2 -2
- package/dist/admin/src/components/BulkLocaleActionModal.d.ts +15 -0
- package/dist/admin/src/components/CMHeaderActions.d.ts +7 -1
- package/dist/admin/src/components/EditLocale.d.ts +5 -4
- package/dist/admin/src/services/api.d.ts +2 -3
- package/dist/admin/src/services/locales.d.ts +1 -1
- package/dist/admin/src/services/relations.d.ts +7 -0
- package/dist/admin/src/utils/baseQuery.d.ts +4 -19
- package/dist/shared/contracts/content-manager.d.ts +20 -1
- package/package.json +15 -16
- package/dist/_chunks/SettingsPage-CeqfDjsb.mjs.map +0 -1
- package/dist/_chunks/SettingsPage-Djqsdrzs.js.map +0 -1
- package/dist/_chunks/en-BuBc6LKZ.js.map +0 -1
- package/dist/_chunks/en-CnrTsjWS.mjs.map +0 -1
- package/dist/_chunks/index-BDU1w_fd.mjs.map +0 -1
- package/dist/_chunks/index-DMXJeGjN.js.map +0 -1
@@ -1,17 +1,16 @@
|
|
1
1
|
import get from "lodash/get";
|
2
2
|
import * as yup from "yup";
|
3
|
-
import { jsxs,
|
3
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
4
4
|
import * as React from "react";
|
5
|
-
import { Typography,
|
6
|
-
import { WarningCircle, Trash, Earth, EarthStriked, CaretDown } from "@strapi/icons";
|
5
|
+
import { Typography, Dialog, Field, Checkbox, Flex, Button as Button$1, Box, Status, IconButton, Tooltip, SingleSelect, SingleSelectOption, VisuallyHidden, useCollator, Popover } from "@strapi/design-system";
|
6
|
+
import { WarningCircle, Pencil, CrossCircle, CheckCircle, ArrowsCounterClockwise, Trash, ListPlus, Earth, EarthStriked, CaretDown } from "@strapi/icons";
|
7
7
|
import { useIntl } from "react-intl";
|
8
|
-
import styled from "styled-components";
|
9
|
-
import { useAuth,
|
10
|
-
import { unstable_useDocument, unstable_useDocumentActions } from "@strapi/content-manager/strapi-admin";
|
11
|
-
import { useParams, useNavigate, matchPath } from "react-router-dom";
|
12
|
-
import { createApi } from "@reduxjs/toolkit/query/react";
|
13
|
-
import { isAxiosError } from "axios";
|
8
|
+
import { styled } from "styled-components";
|
9
|
+
import { useAuth, adminApi, useTable, Table, useQueryParams, useNotification, useAPIErrorHandler } from "@strapi/admin/strapi-admin";
|
10
|
+
import { unstable_useDocument, unstable_useDocumentActions, buildValidParams } from "@strapi/content-manager/strapi-admin";
|
11
|
+
import { useParams, Link, useNavigate, matchPath } from "react-router-dom";
|
14
12
|
import * as qs from "qs";
|
13
|
+
import { stringify } from "qs";
|
15
14
|
import omit from "lodash/omit";
|
16
15
|
const __variableDynamicImportRuntimeHelper = (glob, path) => {
|
17
16
|
const v = glob[path];
|
@@ -48,9 +47,7 @@ const CheckboxConfirmation = ({
|
|
48
47
|
};
|
49
48
|
const handleConfirm = () => {
|
50
49
|
onChange({ target: { name, value: false, type: "checkbox" } });
|
51
|
-
setIsOpen(false);
|
52
50
|
};
|
53
|
-
const handleToggle = () => setIsOpen((prev) => !prev);
|
54
51
|
const label = intlLabel.id ? formatMessage(
|
55
52
|
{ id: intlLabel.id, defaultMessage: intlLabel.defaultMessage },
|
56
53
|
{ ...intlLabel.values }
|
@@ -59,43 +56,36 @@ const CheckboxConfirmation = ({
|
|
59
56
|
{ id: description.id, defaultMessage: description.defaultMessage },
|
60
57
|
{ ...description.values }
|
61
58
|
) : "";
|
62
|
-
return /* @__PURE__ */ jsxs(
|
63
|
-
/* @__PURE__ */
|
64
|
-
Checkbox,
|
65
|
-
{
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
),
|
75
|
-
isOpen && /* @__PURE__ */ jsxs(Dialog, { onClose: handleToggle, title: "Confirmation", isOpen, children: [
|
76
|
-
/* @__PURE__ */ jsx(DialogBody, { icon: /* @__PURE__ */ jsx(WarningCircle, {}), children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
77
|
-
/* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(TextAlignTypography, { id: "confirm-description", children: formatMessage({
|
59
|
+
return /* @__PURE__ */ jsxs(Dialog.Root, { open: isOpen, onOpenChange: setIsOpen, children: [
|
60
|
+
/* @__PURE__ */ jsxs(Field.Root, { hint, name, children: [
|
61
|
+
/* @__PURE__ */ jsx(Checkbox, { onCheckedChange: handleChange, checked: value, children: label }),
|
62
|
+
/* @__PURE__ */ jsx(Field.Hint, {})
|
63
|
+
] }),
|
64
|
+
/* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
65
|
+
/* @__PURE__ */ jsx(Dialog.Header, { children: formatMessage({
|
66
|
+
id: getTranslation("CheckboxConfirmation.Modal.title"),
|
67
|
+
defaultMessage: "Disable localization"
|
68
|
+
}) }),
|
69
|
+
/* @__PURE__ */ jsx(Dialog.Body, { icon: /* @__PURE__ */ jsx(WarningCircle, {}), children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
70
|
+
/* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(TextAlignTypography, { children: formatMessage({
|
78
71
|
id: getTranslation("CheckboxConfirmation.Modal.content"),
|
79
72
|
defaultMessage: "Disabling localization will engender the deletion of all your content but the one associated to your default locale (if existing)."
|
80
73
|
}) }) }),
|
81
|
-
/* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold",
|
74
|
+
/* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold", children: formatMessage({
|
82
75
|
id: getTranslation("CheckboxConfirmation.Modal.body"),
|
83
76
|
defaultMessage: "Do you want to disable it?"
|
84
77
|
}) }) })
|
85
78
|
] }) }),
|
86
|
-
/* @__PURE__ */
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
}) })
|
97
|
-
}
|
98
|
-
)
|
79
|
+
/* @__PURE__ */ jsxs(Dialog.Footer, { children: [
|
80
|
+
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button$1, { variant: "tertiary", children: formatMessage({
|
81
|
+
id: "components.popUpWarning.button.cancel",
|
82
|
+
defaultMessage: "No, cancel"
|
83
|
+
}) }) }),
|
84
|
+
/* @__PURE__ */ jsx(Dialog.Action, { children: /* @__PURE__ */ jsx(Button$1, { variant: "danger-light", onClick: handleConfirm, children: formatMessage({
|
85
|
+
id: getTranslation("CheckboxConfirmation.Modal.button-confirm"),
|
86
|
+
defaultMessage: "Yes, disable"
|
87
|
+
}) }) })
|
88
|
+
] })
|
99
89
|
] })
|
100
90
|
] });
|
101
91
|
};
|
@@ -160,64 +150,8 @@ const useI18n = () => {
|
|
160
150
|
...actions
|
161
151
|
};
|
162
152
|
};
|
163
|
-
const
|
164
|
-
|
165
|
-
const { get: get2, post, del, put } = getFetchClient();
|
166
|
-
if (typeof query === "string") {
|
167
|
-
const result = await get2(query, { signal });
|
168
|
-
return { data: result.data };
|
169
|
-
} else {
|
170
|
-
const { url, method = "GET", data, config } = query;
|
171
|
-
if (method === "POST") {
|
172
|
-
const result2 = await post(url, data, { ...config, signal });
|
173
|
-
return { data: result2.data };
|
174
|
-
}
|
175
|
-
if (method === "DELETE") {
|
176
|
-
const result2 = await del(url, { ...config, signal });
|
177
|
-
return { data: result2.data };
|
178
|
-
}
|
179
|
-
if (method === "PUT") {
|
180
|
-
const result2 = await put(url, data, { ...config, signal });
|
181
|
-
return { data: result2.data };
|
182
|
-
}
|
183
|
-
const result = await get2(url, { ...config, signal });
|
184
|
-
return { data: result.data };
|
185
|
-
}
|
186
|
-
} catch (err) {
|
187
|
-
if (isAxiosError(err)) {
|
188
|
-
if (typeof err.response?.data === "object" && err.response?.data !== null && "error" in err.response?.data) {
|
189
|
-
return { data: void 0, error: err.response?.data.error };
|
190
|
-
} else {
|
191
|
-
return {
|
192
|
-
data: void 0,
|
193
|
-
error: {
|
194
|
-
name: "UnknownError",
|
195
|
-
message: "There was an unknown error response from the API",
|
196
|
-
details: err.response?.data,
|
197
|
-
status: err.response?.status
|
198
|
-
}
|
199
|
-
};
|
200
|
-
}
|
201
|
-
}
|
202
|
-
const error = err;
|
203
|
-
return {
|
204
|
-
data: void 0,
|
205
|
-
error: {
|
206
|
-
name: error.name,
|
207
|
-
message: error.message,
|
208
|
-
stack: error.stack
|
209
|
-
}
|
210
|
-
};
|
211
|
-
}
|
212
|
-
};
|
213
|
-
const isBaseQueryError = (error) => {
|
214
|
-
return error.name !== void 0;
|
215
|
-
};
|
216
|
-
const i18nApi = createApi({
|
217
|
-
reducerPath: "i18nApi",
|
218
|
-
baseQuery: axiosBaseQuery(),
|
219
|
-
tagTypes: ["Locale"],
|
220
|
-
endpoints: () => ({})
|
153
|
+
const i18nApi = adminApi.enhanceEndpoints({
|
154
|
+
addTagTypes: ["Locale"]
|
221
155
|
});
|
222
156
|
const localesApi = i18nApi.injectEndpoints({
|
223
157
|
endpoints: (builder) => ({
|
@@ -266,6 +200,176 @@ const {
|
|
266
200
|
useGetDefaultLocalesQuery,
|
267
201
|
useUpdateLocaleMutation
|
268
202
|
} = localesApi;
|
203
|
+
const relationsApi = i18nApi.injectEndpoints({
|
204
|
+
overrideExisting: true,
|
205
|
+
endpoints: (builder) => ({
|
206
|
+
getManyDraftRelationCount: builder.query({
|
207
|
+
query: ({ model, ...params }) => ({
|
208
|
+
url: `/content-manager/collection-types/${model}/actions/countManyEntriesDraftRelations`,
|
209
|
+
method: "GET",
|
210
|
+
config: {
|
211
|
+
params
|
212
|
+
}
|
213
|
+
}),
|
214
|
+
transformResponse: (response) => response.data
|
215
|
+
})
|
216
|
+
})
|
217
|
+
});
|
218
|
+
const { useGetManyDraftRelationCountQuery } = relationsApi;
|
219
|
+
const isErrorMessageDescriptor = (object) => {
|
220
|
+
return typeof object === "object" && object !== null && "id" in object && "defaultMessage" in object;
|
221
|
+
};
|
222
|
+
const EntryValidationText = ({ status = "draft", validationErrors }) => {
|
223
|
+
const { formatMessage } = useIntl();
|
224
|
+
const getErrorStr = (key, value) => {
|
225
|
+
if (typeof value === "string") {
|
226
|
+
return `${key}: ${value}`;
|
227
|
+
} else if (isErrorMessageDescriptor(value)) {
|
228
|
+
return `${key}: ${formatMessage(value)}`;
|
229
|
+
} else if (Array.isArray(value)) {
|
230
|
+
return value.map((v) => getErrorStr(key, v)).join(" ");
|
231
|
+
} else if (typeof value === "object" && !Array.isArray(value)) {
|
232
|
+
return Object.entries(value).map(([k, v]) => getErrorStr(k, v)).join(" ");
|
233
|
+
} else {
|
234
|
+
return "";
|
235
|
+
}
|
236
|
+
};
|
237
|
+
if (validationErrors) {
|
238
|
+
const validationErrorsMessages = Object.entries(validationErrors).map(([key, value]) => {
|
239
|
+
return getErrorStr(key, value);
|
240
|
+
}).join(" ");
|
241
|
+
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
242
|
+
/* @__PURE__ */ jsx(CrossCircle, { fill: "danger600" }),
|
243
|
+
/* @__PURE__ */ jsx(Tooltip, { label: validationErrorsMessages, children: /* @__PURE__ */ jsx(
|
244
|
+
Typography,
|
245
|
+
{
|
246
|
+
maxWidth: "30rem",
|
247
|
+
textColor: "danger600",
|
248
|
+
variant: "omega",
|
249
|
+
fontWeight: "semiBold",
|
250
|
+
ellipsis: true,
|
251
|
+
children: validationErrorsMessages
|
252
|
+
}
|
253
|
+
) })
|
254
|
+
] });
|
255
|
+
}
|
256
|
+
if (status === "published") {
|
257
|
+
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
258
|
+
/* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
259
|
+
/* @__PURE__ */ jsx(Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
|
260
|
+
id: "content-manager.bulk-publish.already-published",
|
261
|
+
defaultMessage: "Already Published"
|
262
|
+
}) })
|
263
|
+
] });
|
264
|
+
}
|
265
|
+
if (status === "modified") {
|
266
|
+
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
267
|
+
/* @__PURE__ */ jsx(ArrowsCounterClockwise, { fill: "alternative600" }),
|
268
|
+
/* @__PURE__ */ jsx(Typography, { children: formatMessage({
|
269
|
+
id: "app.utils.ready-to-publish-changes",
|
270
|
+
defaultMessage: "Ready to publish changes"
|
271
|
+
}) })
|
272
|
+
] });
|
273
|
+
}
|
274
|
+
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
275
|
+
/* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
276
|
+
/* @__PURE__ */ jsx(Typography, { children: formatMessage({
|
277
|
+
id: "app.utils.ready-to-publish",
|
278
|
+
defaultMessage: "Ready to publish"
|
279
|
+
}) })
|
280
|
+
] });
|
281
|
+
};
|
282
|
+
const BoldChunk = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
|
283
|
+
const BulkLocaleActionModal = ({
|
284
|
+
headers,
|
285
|
+
rows,
|
286
|
+
localesMetadata,
|
287
|
+
validationErrors = {}
|
288
|
+
}) => {
|
289
|
+
const { formatMessage } = useIntl();
|
290
|
+
const selectedRows = useTable(
|
291
|
+
"BulkLocaleActionModal",
|
292
|
+
(state) => state.selectedRows
|
293
|
+
);
|
294
|
+
const getFormattedCountMessage = () => {
|
295
|
+
const currentStatusByLocale = rows.reduce((acc, { locale, status }) => {
|
296
|
+
acc[locale] = status;
|
297
|
+
return acc;
|
298
|
+
}, {});
|
299
|
+
const localesWithErrors = Object.keys(validationErrors);
|
300
|
+
const alreadyPublishedCount = selectedRows.filter(
|
301
|
+
({ locale }) => currentStatusByLocale[locale] === "published"
|
302
|
+
).length;
|
303
|
+
const readyToPublishCount = selectedRows.filter(
|
304
|
+
({ locale }) => (currentStatusByLocale[locale] === "draft" || currentStatusByLocale[locale] === "modified") && !localesWithErrors.includes(locale)
|
305
|
+
).length;
|
306
|
+
const withErrorsCount = localesWithErrors.length;
|
307
|
+
return formatMessage(
|
308
|
+
{
|
309
|
+
id: "content-manager.containers.list.selectedEntriesModal.selectedCount",
|
310
|
+
defaultMessage: "<b>{alreadyPublishedCount}</b> {alreadyPublishedCount, plural, =0 {entries} one {entry} other {entries}} already published. <b>{readyToPublishCount}</b> {readyToPublishCount, plural, =0 {entries} one {entry} other {entries}} ready to publish. <b>{withErrorsCount}</b> {withErrorsCount, plural, =0 {entries} one {entry} other {entries}} waiting for action."
|
311
|
+
},
|
312
|
+
{
|
313
|
+
withErrorsCount,
|
314
|
+
readyToPublishCount,
|
315
|
+
alreadyPublishedCount,
|
316
|
+
b: BoldChunk
|
317
|
+
}
|
318
|
+
);
|
319
|
+
};
|
320
|
+
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
321
|
+
/* @__PURE__ */ jsx(Typography, { children: getFormattedCountMessage() }),
|
322
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 5, children: /* @__PURE__ */ jsxs(Table.Content, { children: [
|
323
|
+
/* @__PURE__ */ jsxs(Table.Head, { children: [
|
324
|
+
/* @__PURE__ */ jsx(Table.HeaderCheckboxCell, {}),
|
325
|
+
headers.map((head) => /* @__PURE__ */ jsx(Table.HeaderCell, { ...head }, head.name))
|
326
|
+
] }),
|
327
|
+
/* @__PURE__ */ jsx(Table.Body, { children: rows.map(({ locale, status }, index2) => {
|
328
|
+
const error = validationErrors?.[locale] ?? null;
|
329
|
+
const statusVariant = status === "draft" ? "primary" : status === "published" ? "success" : "alternative";
|
330
|
+
return /* @__PURE__ */ jsxs(Table.Row, { children: [
|
331
|
+
/* @__PURE__ */ jsx(Table.CheckboxCell, { id: locale, "aria-label": `Select ${locale}` }),
|
332
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", children: Array.isArray(localesMetadata) ? localesMetadata.find((localeEntry) => localeEntry.code === locale)?.name : locale }) }),
|
333
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Box, { display: "flex", children: /* @__PURE__ */ jsx(
|
334
|
+
Status,
|
335
|
+
{
|
336
|
+
display: "flex",
|
337
|
+
paddingLeft: "6px",
|
338
|
+
paddingRight: "6px",
|
339
|
+
paddingTop: "2px",
|
340
|
+
paddingBottom: "2px",
|
341
|
+
showBullet: false,
|
342
|
+
size: "S",
|
343
|
+
variant: statusVariant,
|
344
|
+
children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
|
345
|
+
}
|
346
|
+
) }) }),
|
347
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(EntryValidationText, { validationErrors: error, status }) }),
|
348
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(
|
349
|
+
IconButton,
|
350
|
+
{
|
351
|
+
tag: Link,
|
352
|
+
to: {
|
353
|
+
search: stringify({ plugins: { i18n: { locale } } })
|
354
|
+
},
|
355
|
+
label: formatMessage(
|
356
|
+
{
|
357
|
+
id: getTranslation("Settings.list.actions.edit"),
|
358
|
+
defaultMessage: "Edit {name} locale"
|
359
|
+
},
|
360
|
+
{
|
361
|
+
name: locale
|
362
|
+
}
|
363
|
+
),
|
364
|
+
borderWidth: 0,
|
365
|
+
children: /* @__PURE__ */ jsx(Pencil, {})
|
366
|
+
}
|
367
|
+
) })
|
368
|
+
] }, index2);
|
369
|
+
}) })
|
370
|
+
] }) })
|
371
|
+
] });
|
372
|
+
};
|
269
373
|
const LocalePickerAction = ({
|
270
374
|
document,
|
271
375
|
meta,
|
@@ -337,7 +441,7 @@ const LocalePickerAction = ({
|
|
337
441
|
showBullet: false,
|
338
442
|
size: "S",
|
339
443
|
variant: statusVariant,
|
340
|
-
children: /* @__PURE__ */ jsx(Typography, {
|
444
|
+
children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
|
341
445
|
}
|
342
446
|
) : null
|
343
447
|
};
|
@@ -388,7 +492,7 @@ const DeleteLocaleAction = ({
|
|
388
492
|
}),
|
389
493
|
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
|
390
494
|
/* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
391
|
-
/* @__PURE__ */ jsx(Typography, {
|
495
|
+
/* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
392
496
|
id: getTranslation("actions.delete.dialog.body"),
|
393
497
|
defaultMessage: "Are you sure?"
|
394
498
|
}) })
|
@@ -420,6 +524,228 @@ const DeleteLocaleAction = ({
|
|
420
524
|
}
|
421
525
|
};
|
422
526
|
};
|
527
|
+
const BulkLocalePublishAction = ({
|
528
|
+
document: baseDocument,
|
529
|
+
documentId,
|
530
|
+
model,
|
531
|
+
collectionType
|
532
|
+
}) => {
|
533
|
+
const baseLocale = baseDocument?.locale ?? null;
|
534
|
+
const [{ query }] = useQueryParams();
|
535
|
+
const params = React.useMemo(() => buildValidParams(query), [query]);
|
536
|
+
const isPublishedTab = query.status === "published";
|
537
|
+
const { formatMessage } = useIntl();
|
538
|
+
const { hasI18n, canPublish } = useI18n();
|
539
|
+
const { toggleNotification } = useNotification();
|
540
|
+
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
541
|
+
const [selectedRows, setSelectedRows] = React.useState([]);
|
542
|
+
const [isConfirmationOpen, setIsConfirmationOpen] = React.useState(false);
|
543
|
+
const { publishMany: publishManyAction } = unstable_useDocumentActions();
|
544
|
+
const {
|
545
|
+
document,
|
546
|
+
meta: documentMeta,
|
547
|
+
schema,
|
548
|
+
validate
|
549
|
+
} = unstable_useDocument({
|
550
|
+
model,
|
551
|
+
collectionType,
|
552
|
+
documentId,
|
553
|
+
params: {
|
554
|
+
locale: baseLocale
|
555
|
+
}
|
556
|
+
});
|
557
|
+
const { data: localesMetadata = [] } = useGetLocalesQuery();
|
558
|
+
const headers = [
|
559
|
+
{
|
560
|
+
label: formatMessage({
|
561
|
+
id: "global.name",
|
562
|
+
defaultMessage: "Name"
|
563
|
+
}),
|
564
|
+
name: "name"
|
565
|
+
},
|
566
|
+
{
|
567
|
+
label: formatMessage({
|
568
|
+
id: getTranslation("CMEditViewBulkLocale.status"),
|
569
|
+
defaultMessage: "Status"
|
570
|
+
}),
|
571
|
+
name: "status"
|
572
|
+
},
|
573
|
+
{
|
574
|
+
label: formatMessage({
|
575
|
+
id: getTranslation("CMEditViewBulkLocale.publication-status"),
|
576
|
+
defaultMessage: "Publication Status"
|
577
|
+
}),
|
578
|
+
name: "publication-status"
|
579
|
+
}
|
580
|
+
];
|
581
|
+
const [rows, validationErrors] = React.useMemo(() => {
|
582
|
+
if (!document || !documentMeta?.availableLocales) {
|
583
|
+
return [[], {}];
|
584
|
+
}
|
585
|
+
const rowsFromMeta = documentMeta?.availableLocales.map((doc) => {
|
586
|
+
const { locale, status } = doc;
|
587
|
+
return { locale, status };
|
588
|
+
});
|
589
|
+
rowsFromMeta.unshift({
|
590
|
+
locale: document.locale,
|
591
|
+
status: document.status
|
592
|
+
});
|
593
|
+
const allDocuments = [document, ...documentMeta?.availableLocales ?? []];
|
594
|
+
const errors = allDocuments.reduce((errs, document2) => {
|
595
|
+
if (!document2) {
|
596
|
+
return errs;
|
597
|
+
}
|
598
|
+
const validation = validate(document2);
|
599
|
+
if (validation !== null) {
|
600
|
+
errs[document2.locale] = validation;
|
601
|
+
}
|
602
|
+
return errs;
|
603
|
+
}, {});
|
604
|
+
return [rowsFromMeta, errors];
|
605
|
+
}, [document, documentMeta?.availableLocales, validate]);
|
606
|
+
const localesToPublish = selectedRows.reduce((acc, selectedRow) => {
|
607
|
+
if (selectedRow.status !== "published" && !Object.keys(validationErrors).includes(selectedRow.locale)) {
|
608
|
+
acc.push(selectedRow.locale);
|
609
|
+
}
|
610
|
+
return acc;
|
611
|
+
}, []);
|
612
|
+
const {
|
613
|
+
data: draftRelationsCount = 0,
|
614
|
+
isLoading: isDraftRelationsLoading,
|
615
|
+
error: isDraftRelationsError
|
616
|
+
} = useGetManyDraftRelationCountQuery(
|
617
|
+
{
|
618
|
+
model,
|
619
|
+
documentIds: [documentId],
|
620
|
+
locale: localesToPublish
|
621
|
+
},
|
622
|
+
{
|
623
|
+
skip: !documentId || localesToPublish.length === 0
|
624
|
+
}
|
625
|
+
);
|
626
|
+
React.useEffect(() => {
|
627
|
+
if (isDraftRelationsError) {
|
628
|
+
toggleNotification({
|
629
|
+
type: "danger",
|
630
|
+
message: formatAPIError(isDraftRelationsError)
|
631
|
+
});
|
632
|
+
}
|
633
|
+
}, [isDraftRelationsError, toggleNotification, formatAPIError]);
|
634
|
+
if (!schema?.options?.draftAndPublish) {
|
635
|
+
return null;
|
636
|
+
}
|
637
|
+
if (!hasI18n) {
|
638
|
+
return null;
|
639
|
+
}
|
640
|
+
if (!documentId) {
|
641
|
+
return null;
|
642
|
+
}
|
643
|
+
const publish = async () => {
|
644
|
+
await publishManyAction({
|
645
|
+
model,
|
646
|
+
documentIds: [documentId],
|
647
|
+
params: {
|
648
|
+
...params,
|
649
|
+
locale: localesToPublish
|
650
|
+
}
|
651
|
+
});
|
652
|
+
setSelectedRows([]);
|
653
|
+
};
|
654
|
+
const handleAction = async () => {
|
655
|
+
if (draftRelationsCount > 0) {
|
656
|
+
setIsConfirmationOpen(true);
|
657
|
+
} else {
|
658
|
+
await publish();
|
659
|
+
}
|
660
|
+
};
|
661
|
+
const isUnpublish = document?.status === "published";
|
662
|
+
if (isUnpublish) {
|
663
|
+
console.warn(["I18N"], "Bulk locale unpublish modal not implemented");
|
664
|
+
}
|
665
|
+
if (isConfirmationOpen) {
|
666
|
+
return {
|
667
|
+
label: formatMessage({
|
668
|
+
id: "app.components.ConfirmDialog.title",
|
669
|
+
defaultMessage: "Confirmation"
|
670
|
+
}),
|
671
|
+
variant: "danger",
|
672
|
+
dialog: {
|
673
|
+
onCancel: () => {
|
674
|
+
setIsConfirmationOpen(false);
|
675
|
+
},
|
676
|
+
onConfirm: async () => {
|
677
|
+
await publish();
|
678
|
+
setIsConfirmationOpen(false);
|
679
|
+
},
|
680
|
+
type: "dialog",
|
681
|
+
title: formatMessage({
|
682
|
+
id: getTranslation("actions.publish.dialog.title"),
|
683
|
+
defaultMessage: "Confirmation"
|
684
|
+
}),
|
685
|
+
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "center", gap: 2, children: [
|
686
|
+
/* @__PURE__ */ jsx(WarningCircle, { width: "2.4rem", height: "2.4rem", fill: "danger600" }),
|
687
|
+
/* @__PURE__ */ jsx(Typography, { textAlign: "center", children: formatMessage({
|
688
|
+
id: "content-manager.actions.discard.dialog.body",
|
689
|
+
defaultMessage: "Are you sure you want to discard the changes? This action is irreversible."
|
690
|
+
}) })
|
691
|
+
] })
|
692
|
+
}
|
693
|
+
};
|
694
|
+
}
|
695
|
+
return {
|
696
|
+
label: formatMessage({
|
697
|
+
id: getTranslation("CMEditViewBulkLocale.publish-title"),
|
698
|
+
defaultMessage: "Publish Multiple Locales"
|
699
|
+
}),
|
700
|
+
icon: /* @__PURE__ */ jsx(ListPlus, {}),
|
701
|
+
disabled: isPublishedTab || !canPublish,
|
702
|
+
position: ["panel"],
|
703
|
+
variant: "secondary",
|
704
|
+
dialog: {
|
705
|
+
type: "modal",
|
706
|
+
title: formatMessage({
|
707
|
+
id: getTranslation("CMEditViewBulkLocale.publish-title"),
|
708
|
+
defaultMessage: "Publish Multiple Locales"
|
709
|
+
}),
|
710
|
+
content: () => {
|
711
|
+
return /* @__PURE__ */ jsx(
|
712
|
+
Table.Root,
|
713
|
+
{
|
714
|
+
headers,
|
715
|
+
rows: rows.map((row) => ({
|
716
|
+
...row,
|
717
|
+
id: row.locale
|
718
|
+
})),
|
719
|
+
selectedRows,
|
720
|
+
onSelectedRowsChange: (tableSelectedRows) => setSelectedRows(tableSelectedRows),
|
721
|
+
children: /* @__PURE__ */ jsx(
|
722
|
+
BulkLocaleActionModal,
|
723
|
+
{
|
724
|
+
validationErrors,
|
725
|
+
headers,
|
726
|
+
rows,
|
727
|
+
localesMetadata
|
728
|
+
}
|
729
|
+
)
|
730
|
+
}
|
731
|
+
);
|
732
|
+
},
|
733
|
+
footer: () => /* @__PURE__ */ jsx(Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsx(
|
734
|
+
Button$1,
|
735
|
+
{
|
736
|
+
loading: isDraftRelationsLoading,
|
737
|
+
disabled: localesToPublish.length === 0,
|
738
|
+
variant: "default",
|
739
|
+
onClick: handleAction,
|
740
|
+
children: formatMessage({
|
741
|
+
id: "app.utils.publish",
|
742
|
+
defaultMessage: "Publish"
|
743
|
+
})
|
744
|
+
}
|
745
|
+
) })
|
746
|
+
}
|
747
|
+
};
|
748
|
+
};
|
423
749
|
const StyledTrash = styled(Trash)`
|
424
750
|
path {
|
425
751
|
fill: currentColor;
|
@@ -542,7 +868,7 @@ const PERMISSIONS = {
|
|
542
868
|
read: [{ action: "plugin::i18n.locale.read", subject: null }]
|
543
869
|
};
|
544
870
|
const mutateEditViewHook = ({ layout }) => {
|
545
|
-
if ("i18n" in layout.options
|
871
|
+
if (!("i18n" in layout.options) || typeof layout.options.i18n === "object" && layout.options.i18n !== null && "localized" in layout.options.i18n && !layout.options.i18n.localized) {
|
546
872
|
return { layout };
|
547
873
|
}
|
548
874
|
const components = Object.entries(layout.components).reduce(
|
@@ -587,8 +913,8 @@ const doesFieldHaveI18nPluginOpt = (pluginOpts) => {
|
|
587
913
|
};
|
588
914
|
const LabelAction = ({ title, icon }) => {
|
589
915
|
const { formatMessage } = useIntl();
|
590
|
-
return /* @__PURE__ */ jsxs(Span, {
|
591
|
-
/* @__PURE__ */ jsx(VisuallyHidden, {
|
916
|
+
return /* @__PURE__ */ jsxs(Span, { tag: "span", children: [
|
917
|
+
/* @__PURE__ */ jsx(VisuallyHidden, { tag: "span", children: formatMessage(title) }),
|
592
918
|
React.cloneElement(icon, {
|
593
919
|
"aria-hidden": true,
|
594
920
|
focusable: false
|
@@ -623,13 +949,7 @@ const LocaleListCell = ({
|
|
623
949
|
}
|
624
950
|
});
|
625
951
|
const { locale: language } = useIntl();
|
626
|
-
const [visible, setVisible] = React.useState(false);
|
627
|
-
const buttonRef = React.useRef(null);
|
628
952
|
const { data: locales = [] } = useGetLocalesQuery();
|
629
|
-
const handleTogglePopover = (e) => {
|
630
|
-
e.stopPropagation();
|
631
|
-
setVisible((prev) => !prev);
|
632
|
-
};
|
633
953
|
const formatter = useCollator(language, {
|
634
954
|
sensitivity: "base"
|
635
955
|
});
|
@@ -651,8 +971,8 @@ const LocaleListCell = ({
|
|
651
971
|
}
|
652
972
|
return locale.name;
|
653
973
|
}).toSorted((a, b) => formatter.compare(a, b));
|
654
|
-
return /* @__PURE__ */ jsxs(
|
655
|
-
/* @__PURE__ */ jsxs(
|
974
|
+
return /* @__PURE__ */ jsxs(Popover.Root, { children: [
|
975
|
+
/* @__PURE__ */ jsx(Popover.Trigger, { children: /* @__PURE__ */ jsx(Button, { type: "button", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxs(
|
656
976
|
ActionWrapper,
|
657
977
|
{
|
658
978
|
minWidth: "100%",
|
@@ -665,17 +985,8 @@ const LocaleListCell = ({
|
|
665
985
|
/* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(CaretDown, {}) })
|
666
986
|
]
|
667
987
|
}
|
668
|
-
),
|
669
|
-
|
670
|
-
Popover,
|
671
|
-
{
|
672
|
-
onDismiss: () => setVisible(false),
|
673
|
-
source: buttonRef,
|
674
|
-
spacing: 16,
|
675
|
-
centered: true,
|
676
|
-
children: /* @__PURE__ */ jsx("ul", { children: localesForDocument.map((name) => /* @__PURE__ */ jsx(Box, { padding: 3, as: "li", children: /* @__PURE__ */ jsx(Typography, { children: name }) }, name)) })
|
677
|
-
}
|
678
|
-
)
|
988
|
+
) }) }),
|
989
|
+
/* @__PURE__ */ jsx(Popover.Content, { sideOffset: 16, children: /* @__PURE__ */ jsx("ul", { children: localesForDocument.map((name) => /* @__PURE__ */ jsx(Box, { padding: 3, tag: "li", children: /* @__PURE__ */ jsx(Typography, { children: name }) }, name)) }) })
|
679
990
|
] });
|
680
991
|
};
|
681
992
|
const Button = styled.button`
|
@@ -915,7 +1226,7 @@ const index = {
|
|
915
1226
|
},
|
916
1227
|
id: "internationalization",
|
917
1228
|
to: "internationalization",
|
918
|
-
Component: () => import("./SettingsPage-
|
1229
|
+
Component: () => import("./SettingsPage-Dsi2qGtq.mjs").then((mod) => ({ default: mod.ProtectedSettingsPage })),
|
919
1230
|
permissions: PERMISSIONS.accessMain
|
920
1231
|
});
|
921
1232
|
const contentManager = app.getPlugin("content-manager");
|
@@ -925,6 +1236,10 @@ const index = {
|
|
925
1236
|
actions.splice(indexOfDeleteAction, 0, DeleteLocaleAction);
|
926
1237
|
return actions;
|
927
1238
|
});
|
1239
|
+
contentManager.apis.addDocumentAction((actions) => {
|
1240
|
+
actions.splice(2, 0, BulkLocalePublishAction);
|
1241
|
+
return actions;
|
1242
|
+
});
|
928
1243
|
contentManager.injectComponent("listView", "actions", {
|
929
1244
|
name: "i18n-locale-filter",
|
930
1245
|
Component: LocalePicker
|
@@ -1028,7 +1343,7 @@ const index = {
|
|
1028
1343
|
async registerTrads({ locales }) {
|
1029
1344
|
const importedTrads = await Promise.all(
|
1030
1345
|
locales.map((locale) => {
|
1031
|
-
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/de.json": () => import("./de-9eCAqqrB.mjs"), "./translations/dk.json": () => import("./dk-2qBjxt-P.mjs"), "./translations/en.json": () => import("./en-
|
1346
|
+
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/de.json": () => import("./de-9eCAqqrB.mjs"), "./translations/dk.json": () => import("./dk-2qBjxt-P.mjs"), "./translations/en.json": () => import("./en-18tWw4P6.mjs"), "./translations/es.json": () => import("./es-DlmMVaBG.mjs"), "./translations/fr.json": () => import("./fr-3S6ke71d.mjs"), "./translations/ko.json": () => import("./ko-qTjQ8IMw.mjs"), "./translations/pl.json": () => import("./pl-B67TSHqT.mjs"), "./translations/ru.json": () => import("./ru-hagMa57T.mjs"), "./translations/tr.json": () => import("./tr-Dw_jmkG-.mjs"), "./translations/zh-Hans.json": () => import("./zh-Hans-Dyc-aR-h.mjs"), "./translations/zh.json": () => import("./zh-57YM4amO.mjs") }), `./translations/${locale}.json`).then(({ default: data }) => {
|
1032
1347
|
return {
|
1033
1348
|
data: prefixPluginTranslations(data, pluginId),
|
1034
1349
|
locale
|
@@ -1047,12 +1362,11 @@ const index = {
|
|
1047
1362
|
export {
|
1048
1363
|
PERMISSIONS as P,
|
1049
1364
|
useGetDefaultLocalesQuery as a,
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
index as e,
|
1365
|
+
useDeleteLocaleMutation as b,
|
1366
|
+
useUpdateLocaleMutation as c,
|
1367
|
+
useGetLocalesQuery as d,
|
1054
1368
|
getTranslation as g,
|
1055
|
-
|
1369
|
+
index as i,
|
1056
1370
|
useCreateLocaleMutation as u
|
1057
1371
|
};
|
1058
|
-
//# sourceMappingURL=index-
|
1372
|
+
//# sourceMappingURL=index-DhtjJYrx.mjs.map
|