@strapi/i18n 5.0.0-rc.11 → 5.0.0-rc.13
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-CbEn7zF5.mjs → SettingsPage-BjxjwEOb.mjs} +2 -2
- package/dist/_chunks/{SettingsPage-CbEn7zF5.mjs.map → SettingsPage-BjxjwEOb.mjs.map} +1 -1
- package/dist/_chunks/{SettingsPage-C0l7c5fn.js → SettingsPage-CfTmCkup.js} +2 -2
- package/dist/_chunks/{SettingsPage-C0l7c5fn.js.map → SettingsPage-CfTmCkup.js.map} +1 -1
- package/dist/_chunks/{en-CM6Pjfyv.mjs → en-2xztdZE1.mjs} +7 -1
- package/dist/_chunks/en-2xztdZE1.mjs.map +1 -0
- package/dist/_chunks/{en-BsOU9o5z.js → en-DWpfm8h5.js} +7 -1
- package/dist/_chunks/en-DWpfm8h5.js.map +1 -0
- package/dist/_chunks/{index-C0i3v7QQ.js → index-5XLZwzwx.js} +312 -115
- package/dist/_chunks/index-5XLZwzwx.js.map +1 -0
- package/dist/_chunks/{index-CkrCiZyq.mjs → index-D-qx3tz4.mjs} +319 -122
- package/dist/_chunks/index-D-qx3tz4.mjs.map +1 -0
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/admin/src/components/BulkLocaleActionModal.d.ts +2 -1
- package/dist/admin/src/components/CMHeaderActions.d.ts +27 -3
- package/dist/admin/src/utils/clean.d.ts +4 -0
- package/dist/server/index.js +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +1 -1
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/package.json +9 -9
- package/dist/_chunks/en-BsOU9o5z.js.map +0 -1
- package/dist/_chunks/en-CM6Pjfyv.mjs.map +0 -1
- package/dist/_chunks/index-C0i3v7QQ.js.map +0 -1
- package/dist/_chunks/index-CkrCiZyq.mjs.map +0 -1
@@ -1,13 +1,13 @@
|
|
1
1
|
import get from "lodash/get";
|
2
2
|
import * as yup from "yup";
|
3
|
-
import { jsxs, jsx } from "react/jsx-runtime";
|
3
|
+
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
4
4
|
import * as React from "react";
|
5
|
-
import { Typography, Dialog, Field, Checkbox, Flex, Button
|
6
|
-
import { WarningCircle, Pencil, CrossCircle, CheckCircle, ArrowsCounterClockwise, Trash, ListPlus, Earth, EarthStriked, CaretDown } from "@strapi/icons";
|
5
|
+
import { Typography, Dialog, Field, Checkbox, Flex, Button, Modal, Box, Status, IconButton, Tooltip, SingleSelect, SingleSelectOption, VisuallyHidden, useCollator, Popover } from "@strapi/design-system";
|
6
|
+
import { WarningCircle, Pencil, CrossCircle, CheckCircle, ArrowsCounterClockwise, Trash, Download, ListPlus, Cross, Earth, EarthStriked, CaretDown } from "@strapi/icons";
|
7
7
|
import { useIntl } from "react-intl";
|
8
8
|
import { styled } from "styled-components";
|
9
9
|
import { skipToken } from "@reduxjs/toolkit/query";
|
10
|
-
import { useAuth, adminApi, useTable, Table, useQueryParams, useNotification, useAPIErrorHandler } from "@strapi/admin/strapi-admin";
|
10
|
+
import { useAuth, adminApi, useTable, Table, useQueryParams, useForm, useNotification, useAPIErrorHandler } from "@strapi/admin/strapi-admin";
|
11
11
|
import { unstable_useDocument, unstable_useDocumentActions, buildValidParams } from "@strapi/content-manager/strapi-admin";
|
12
12
|
import { useParams, Link, useNavigate, matchPath } from "react-router-dom";
|
13
13
|
import * as qs from "qs";
|
@@ -78,11 +78,11 @@ const CheckboxConfirmation = ({
|
|
78
78
|
}) }) })
|
79
79
|
] }) }),
|
80
80
|
/* @__PURE__ */ jsxs(Dialog.Footer, { children: [
|
81
|
-
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button
|
81
|
+
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", children: formatMessage({
|
82
82
|
id: "components.popUpWarning.button.cancel",
|
83
83
|
defaultMessage: "No, cancel"
|
84
84
|
}) }) }),
|
85
|
-
/* @__PURE__ */ jsx(Dialog.Action, { children: /* @__PURE__ */ jsx(Button
|
85
|
+
/* @__PURE__ */ jsx(Dialog.Action, { children: /* @__PURE__ */ jsx(Button, { variant: "danger-light", onClick: handleConfirm, children: formatMessage({
|
86
86
|
id: getTranslation("CheckboxConfirmation.Modal.button-confirm"),
|
87
87
|
defaultMessage: "Yes, disable"
|
88
88
|
}) }) })
|
@@ -217,10 +217,93 @@ const relationsApi = i18nApi.injectEndpoints({
|
|
217
217
|
})
|
218
218
|
});
|
219
219
|
const { useGetManyDraftRelationCountQuery } = relationsApi;
|
220
|
+
const cleanData = (data, schema, components) => {
|
221
|
+
const cleanedData = removeFields(data, [
|
222
|
+
"createdAt",
|
223
|
+
"createdBy",
|
224
|
+
"updatedAt",
|
225
|
+
"updatedBy",
|
226
|
+
"id",
|
227
|
+
"documentId",
|
228
|
+
"publishedAt",
|
229
|
+
"strapi_stage",
|
230
|
+
"strapi_assignee",
|
231
|
+
"locale"
|
232
|
+
]);
|
233
|
+
const cleanedDataWithoutPasswordAndRelation = recursiveRemoveFieldTypes(
|
234
|
+
cleanedData,
|
235
|
+
schema,
|
236
|
+
components,
|
237
|
+
["relation", "password"]
|
238
|
+
);
|
239
|
+
return cleanedDataWithoutPasswordAndRelation;
|
240
|
+
};
|
241
|
+
const removeFields = (data, fields) => {
|
242
|
+
return Object.keys(data).reduce((acc, current) => {
|
243
|
+
if (fields.includes(current)) {
|
244
|
+
return acc;
|
245
|
+
}
|
246
|
+
acc[current] = data[current];
|
247
|
+
return acc;
|
248
|
+
}, {});
|
249
|
+
};
|
250
|
+
const recursiveRemoveFieldTypes = (data, schema, components, fields) => {
|
251
|
+
return Object.keys(data).reduce((acc, current) => {
|
252
|
+
const attribute = schema.attributes[current] ?? { type: void 0 };
|
253
|
+
if (fields.includes(attribute.type)) {
|
254
|
+
return acc;
|
255
|
+
}
|
256
|
+
if (attribute.type === "dynamiczone") {
|
257
|
+
acc[current] = data[current].map((componentValue, index2) => {
|
258
|
+
const { id: _, ...rest } = recursiveRemoveFieldTypes(
|
259
|
+
componentValue,
|
260
|
+
components[componentValue.__component],
|
261
|
+
components,
|
262
|
+
fields
|
263
|
+
);
|
264
|
+
return {
|
265
|
+
...rest,
|
266
|
+
__temp_key__: index2 + 1
|
267
|
+
};
|
268
|
+
});
|
269
|
+
} else if (attribute.type === "component") {
|
270
|
+
const { repeatable, component } = attribute;
|
271
|
+
if (repeatable) {
|
272
|
+
acc[current] = (data[current] ?? []).map((compoData, index2) => {
|
273
|
+
const { id: _, ...rest } = recursiveRemoveFieldTypes(
|
274
|
+
compoData,
|
275
|
+
components[component],
|
276
|
+
components,
|
277
|
+
fields
|
278
|
+
);
|
279
|
+
return {
|
280
|
+
...rest,
|
281
|
+
__temp_key__: index2 + 1
|
282
|
+
};
|
283
|
+
});
|
284
|
+
} else {
|
285
|
+
const { id: _, ...rest } = recursiveRemoveFieldTypes(
|
286
|
+
data[current] ?? {},
|
287
|
+
components[component],
|
288
|
+
components,
|
289
|
+
fields
|
290
|
+
);
|
291
|
+
acc[current] = rest;
|
292
|
+
}
|
293
|
+
} else {
|
294
|
+
acc[current] = data[current];
|
295
|
+
}
|
296
|
+
return acc;
|
297
|
+
}, {});
|
298
|
+
};
|
220
299
|
const isErrorMessageDescriptor = (object) => {
|
221
300
|
return typeof object === "object" && object !== null && "id" in object && "defaultMessage" in object;
|
222
301
|
};
|
223
|
-
const EntryValidationText = ({
|
302
|
+
const EntryValidationText = ({
|
303
|
+
status = "draft",
|
304
|
+
validationErrors,
|
305
|
+
action
|
306
|
+
}) => {
|
224
307
|
const { formatMessage } = useIntl();
|
225
308
|
const getErrorStr = (key, value) => {
|
226
309
|
if (typeof value === "string") {
|
@@ -254,30 +337,63 @@ const EntryValidationText = ({ status = "draft", validationErrors }) => {
|
|
254
337
|
) })
|
255
338
|
] });
|
256
339
|
}
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
340
|
+
const getStatusMessage = () => {
|
341
|
+
if (action === "bulk-publish") {
|
342
|
+
if (status === "published") {
|
343
|
+
return {
|
344
|
+
icon: /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
345
|
+
text: formatMessage({
|
346
|
+
id: "content-manager.bulk-publish.already-published",
|
347
|
+
defaultMessage: "Already Published"
|
348
|
+
}),
|
349
|
+
textColor: "success600",
|
350
|
+
fontWeight: "bold"
|
351
|
+
};
|
352
|
+
} else if (status === "modified") {
|
353
|
+
return {
|
354
|
+
icon: /* @__PURE__ */ jsx(ArrowsCounterClockwise, { fill: "alternative600" }),
|
355
|
+
text: formatMessage({
|
356
|
+
id: "app.utils.ready-to-publish-changes",
|
357
|
+
defaultMessage: "Ready to publish changes"
|
358
|
+
})
|
359
|
+
};
|
360
|
+
} else {
|
361
|
+
return {
|
362
|
+
icon: /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
363
|
+
text: formatMessage({
|
364
|
+
id: "app.utils.ready-to-publish",
|
365
|
+
defaultMessage: "Ready to publish"
|
366
|
+
})
|
367
|
+
};
|
368
|
+
}
|
369
|
+
} else {
|
370
|
+
if (status === "draft") {
|
371
|
+
return {
|
372
|
+
icon: /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
373
|
+
text: formatMessage({
|
374
|
+
id: "content-manager.bulk-unpublish.already-unpublished",
|
375
|
+
defaultMessage: "Already Unpublished"
|
376
|
+
}),
|
377
|
+
textColor: "success600",
|
378
|
+
fontWeight: "bold"
|
379
|
+
};
|
380
|
+
} else {
|
381
|
+
return {
|
382
|
+
icon: /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
383
|
+
text: formatMessage({
|
384
|
+
id: "app.utils.ready-to-unpublish-changes",
|
385
|
+
defaultMessage: "Ready to unpublish"
|
386
|
+
}),
|
387
|
+
textColor: "success600",
|
388
|
+
fontWeight: "bold"
|
389
|
+
};
|
390
|
+
}
|
391
|
+
}
|
392
|
+
};
|
393
|
+
const { icon, text, textColor = "success600", fontWeight = "normal" } = getStatusMessage();
|
275
394
|
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
276
|
-
|
277
|
-
/* @__PURE__ */ jsx(Typography, { children:
|
278
|
-
id: "app.utils.ready-to-publish",
|
279
|
-
defaultMessage: "Ready to publish"
|
280
|
-
}) })
|
395
|
+
icon,
|
396
|
+
/* @__PURE__ */ jsx(Typography, { textColor, fontWeight, children: text })
|
281
397
|
] });
|
282
398
|
};
|
283
399
|
const BoldChunk = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
|
@@ -285,7 +401,8 @@ const BulkLocaleActionModal = ({
|
|
285
401
|
headers,
|
286
402
|
rows,
|
287
403
|
localesMetadata,
|
288
|
-
validationErrors = {}
|
404
|
+
validationErrors = {},
|
405
|
+
action
|
289
406
|
}) => {
|
290
407
|
const { formatMessage } = useIntl();
|
291
408
|
const selectedRows = useTable(
|
@@ -298,22 +415,24 @@ const BulkLocaleActionModal = ({
|
|
298
415
|
return acc;
|
299
416
|
}, {});
|
300
417
|
const localesWithErrors = Object.keys(validationErrors);
|
301
|
-
const
|
418
|
+
const publishedCount = selectedRows.filter(
|
302
419
|
({ locale }) => currentStatusByLocale[locale] === "published"
|
303
420
|
).length;
|
304
|
-
const
|
421
|
+
const draftCount = selectedRows.filter(
|
305
422
|
({ locale }) => (currentStatusByLocale[locale] === "draft" || currentStatusByLocale[locale] === "modified") && !localesWithErrors.includes(locale)
|
306
423
|
).length;
|
307
424
|
const withErrorsCount = localesWithErrors.length;
|
425
|
+
const messageId = action === "bulk-publish" ? "content-manager.containers.list.selectedEntriesModal.selectedCount.publish" : "content-manager.containers.list.selectedEntriesModal.selectedCount.unpublish";
|
426
|
+
const defaultMessage = action === "bulk-publish" ? "<b>{publishedCount}</b> {publishedCount, plural, =0 {entries} one {entry} other {entries}} already published. <b>{draftCount}</b> {draftCount, plural, =0 {entries} one {entry} other {entries}} ready to publish. <b>{withErrorsCount}</b> {withErrorsCount, plural, =0 {entries} one {entry} other {entries}} waiting for action." : "<b>{draftCount}</b> {draftCount, plural, =0 {entries} one {entry} other {entries}} already unpublished. <b>{publishedCount}</b> {publishedCount, plural, =0 {entries} one {entry} other {entries}} ready to unpublish.";
|
308
427
|
return formatMessage(
|
309
428
|
{
|
310
|
-
id:
|
311
|
-
defaultMessage
|
429
|
+
id: messageId,
|
430
|
+
defaultMessage
|
312
431
|
},
|
313
432
|
{
|
314
433
|
withErrorsCount,
|
315
|
-
|
316
|
-
|
434
|
+
draftCount,
|
435
|
+
publishedCount,
|
317
436
|
b: BoldChunk
|
318
437
|
}
|
319
438
|
);
|
@@ -345,7 +464,7 @@ const BulkLocaleActionModal = ({
|
|
345
464
|
children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
|
346
465
|
}
|
347
466
|
) }) }),
|
348
|
-
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(EntryValidationText, { validationErrors: error, status }) }),
|
467
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(EntryValidationText, { validationErrors: error, status, action }) }),
|
349
468
|
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(
|
350
469
|
IconButton,
|
351
470
|
{
|
@@ -382,7 +501,13 @@ const LocalePickerAction = ({
|
|
382
501
|
const [{ query }, setQuery] = useQueryParams();
|
383
502
|
const { hasI18n, canCreate, canRead } = useI18n();
|
384
503
|
const { data: locales = [] } = useGetLocalesQuery();
|
385
|
-
const
|
504
|
+
const currentDesiredLocale = query.plugins?.i18n?.locale;
|
505
|
+
const { schema } = unstable_useDocument({
|
506
|
+
model,
|
507
|
+
collectionType,
|
508
|
+
documentId,
|
509
|
+
params: { locale: currentDesiredLocale }
|
510
|
+
});
|
386
511
|
const handleSelect = React.useCallback(
|
387
512
|
(value) => {
|
388
513
|
setQuery({
|
@@ -400,21 +525,20 @@ const LocalePickerAction = ({
|
|
400
525
|
if (!Array.isArray(locales) || !hasI18n) {
|
401
526
|
return;
|
402
527
|
}
|
403
|
-
const currentDesiredLocale = query.plugins?.i18n?.locale;
|
404
528
|
const doesLocaleExist = locales.find((loc) => loc.code === currentDesiredLocale);
|
405
529
|
const defaultLocale = locales.find((locale) => locale.isDefault);
|
406
530
|
if (!doesLocaleExist && defaultLocale?.code) {
|
407
531
|
handleSelect(defaultLocale.code);
|
408
532
|
}
|
409
|
-
}, [handleSelect, hasI18n, locales,
|
410
|
-
|
411
|
-
return null;
|
412
|
-
}
|
413
|
-
const currentLocale = query.plugins?.i18n?.locale || locales.find((loc) => loc.isDefault)?.code;
|
533
|
+
}, [handleSelect, hasI18n, locales, currentDesiredLocale]);
|
534
|
+
const currentLocale = Array.isArray(locales) ? locales.find((locale) => locale.code === currentDesiredLocale)?.code : void 0;
|
414
535
|
const allCurrentLocales = [
|
415
536
|
{ status: getDocumentStatus(document, meta), locale: currentLocale },
|
416
537
|
...meta?.availableLocales ?? []
|
417
538
|
];
|
539
|
+
if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
|
540
|
+
return null;
|
541
|
+
}
|
418
542
|
return {
|
419
543
|
label: formatMessage({
|
420
544
|
id: getTranslation("Settings.locales.modal.locales.label"),
|
@@ -426,7 +550,7 @@ const LocalePickerAction = ({
|
|
426
550
|
);
|
427
551
|
const status = currentLocaleDoc?.status ?? "draft";
|
428
552
|
const permissionsToCheck = currentLocaleDoc ? canCreate : canRead;
|
429
|
-
const statusVariant = status === "draft" ? "
|
553
|
+
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
430
554
|
return {
|
431
555
|
disabled: !permissionsToCheck.includes(locale.code),
|
432
556
|
value: locale.code,
|
@@ -462,6 +586,95 @@ const getDocumentStatus = (document, meta) => {
|
|
462
586
|
}
|
463
587
|
return docStatus;
|
464
588
|
};
|
589
|
+
const FillFromAnotherLocaleAction = ({
|
590
|
+
documentId,
|
591
|
+
meta,
|
592
|
+
model,
|
593
|
+
collectionType
|
594
|
+
}) => {
|
595
|
+
const { formatMessage } = useIntl();
|
596
|
+
const [{ query }] = useQueryParams();
|
597
|
+
const currentDesiredLocale = query.plugins?.i18n?.locale;
|
598
|
+
const [localeSelected, setLocaleSelected] = React.useState(null);
|
599
|
+
const setValues = useForm("FillFromAnotherLocale", (state) => state.setValues);
|
600
|
+
const { getDocument } = unstable_useDocumentActions();
|
601
|
+
const { schema, components } = unstable_useDocument({
|
602
|
+
model,
|
603
|
+
documentId,
|
604
|
+
collectionType,
|
605
|
+
params: { locale: currentDesiredLocale }
|
606
|
+
});
|
607
|
+
const { data: locales = [] } = useGetLocalesQuery();
|
608
|
+
const availableLocales = Array.isArray(locales) ? locales.filter((locale) => meta?.availableLocales.some((l) => l.locale === locale.code)) : [];
|
609
|
+
const fillFromLocale = (onClose) => async () => {
|
610
|
+
const response = await getDocument({
|
611
|
+
collectionType,
|
612
|
+
model,
|
613
|
+
documentId,
|
614
|
+
params: { locale: localeSelected }
|
615
|
+
});
|
616
|
+
if (!response || !schema) {
|
617
|
+
return;
|
618
|
+
}
|
619
|
+
const { data } = response;
|
620
|
+
const cleanedData = cleanData(data, schema, components);
|
621
|
+
setValues(cleanedData);
|
622
|
+
onClose();
|
623
|
+
};
|
624
|
+
return {
|
625
|
+
type: "icon",
|
626
|
+
icon: /* @__PURE__ */ jsx(Download, {}),
|
627
|
+
disabled: availableLocales.length === 0,
|
628
|
+
label: formatMessage({
|
629
|
+
id: getTranslation("CMEditViewCopyLocale.copy-text"),
|
630
|
+
defaultMessage: "Fill in from another locale"
|
631
|
+
}),
|
632
|
+
dialog: {
|
633
|
+
type: "dialog",
|
634
|
+
title: formatMessage({
|
635
|
+
id: getTranslation("CMEditViewCopyLocale.dialog.title"),
|
636
|
+
defaultMessage: "Confirmation"
|
637
|
+
}),
|
638
|
+
content: ({ onClose }) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
639
|
+
/* @__PURE__ */ jsx(Dialog.Body, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 3, children: [
|
640
|
+
/* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
641
|
+
/* @__PURE__ */ jsx(Typography, { textAlign: "center", children: formatMessage({
|
642
|
+
id: getTranslation("CMEditViewCopyLocale.dialog.body"),
|
643
|
+
defaultMessage: "Your current content will be erased and filled by the content of the selected locale:"
|
644
|
+
}) }),
|
645
|
+
/* @__PURE__ */ jsxs(Field.Root, { width: "100%", children: [
|
646
|
+
/* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
|
647
|
+
id: getTranslation("CMEditViewCopyLocale.dialog.field.label"),
|
648
|
+
defaultMessage: "Locale"
|
649
|
+
}) }),
|
650
|
+
/* @__PURE__ */ jsx(
|
651
|
+
SingleSelect,
|
652
|
+
{
|
653
|
+
value: localeSelected,
|
654
|
+
placeholder: formatMessage({
|
655
|
+
id: getTranslation("CMEditViewCopyLocale.dialog.field.placeholder"),
|
656
|
+
defaultMessage: "Select one locale..."
|
657
|
+
}),
|
658
|
+
onChange: (value) => setLocaleSelected(value),
|
659
|
+
children: availableLocales.map((locale) => /* @__PURE__ */ jsx(SingleSelectOption, { value: locale.code, children: locale.name }, locale.code))
|
660
|
+
}
|
661
|
+
)
|
662
|
+
] })
|
663
|
+
] }) }),
|
664
|
+
/* @__PURE__ */ jsx(Dialog.Footer, { children: /* @__PURE__ */ jsxs(Flex, { gap: 2, width: "100%", children: [
|
665
|
+
/* @__PURE__ */ jsx(Button, { flex: "auto", variant: "tertiary", onClick: onClose, children: formatMessage({
|
666
|
+
id: getTranslation("CMEditViewCopyLocale.cancel-text"),
|
667
|
+
defaultMessage: "No, cancel"
|
668
|
+
}) }),
|
669
|
+
/* @__PURE__ */ jsx(Button, { flex: "auto", variant: "success", onClick: fillFromLocale(onClose), children: formatMessage({
|
670
|
+
id: getTranslation("CMEditViewCopyLocale.submit-text"),
|
671
|
+
defaultMessage: "Yes, fill in"
|
672
|
+
}) })
|
673
|
+
] }) })
|
674
|
+
] })
|
675
|
+
}
|
676
|
+
};
|
677
|
+
};
|
465
678
|
const DeleteLocaleAction = ({
|
466
679
|
document,
|
467
680
|
documentId,
|
@@ -525,23 +738,24 @@ const DeleteLocaleAction = ({
|
|
525
738
|
}
|
526
739
|
};
|
527
740
|
};
|
528
|
-
const
|
741
|
+
const BulkLocaleAction = ({
|
529
742
|
document: baseDocument,
|
530
743
|
documentId,
|
531
744
|
model,
|
532
|
-
collectionType
|
745
|
+
collectionType,
|
746
|
+
action
|
533
747
|
}) => {
|
534
748
|
const baseLocale = baseDocument?.locale ?? null;
|
535
749
|
const [{ query }] = useQueryParams();
|
536
750
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
537
|
-
const
|
751
|
+
const isOnPublishedTab = query.status === "published";
|
538
752
|
const { formatMessage } = useIntl();
|
539
753
|
const { hasI18n, canPublish } = useI18n();
|
540
754
|
const { toggleNotification } = useNotification();
|
541
755
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
542
756
|
const [selectedRows, setSelectedRows] = React.useState([]);
|
543
757
|
const [isDraftRelationConfirmationOpen, setIsDraftRelationConfirmationOpen] = React.useState(false);
|
544
|
-
const { publishMany: publishManyAction } = unstable_useDocumentActions();
|
758
|
+
const { publishMany: publishManyAction, unpublishMany: unpublishManyAction } = unstable_useDocumentActions();
|
545
759
|
const {
|
546
760
|
document,
|
547
761
|
meta: documentMeta,
|
@@ -557,7 +771,7 @@ const BulkLocalePublishAction = ({
|
|
557
771
|
}
|
558
772
|
},
|
559
773
|
{
|
560
|
-
skip: !hasI18n
|
774
|
+
skip: !hasI18n || !baseLocale
|
561
775
|
}
|
562
776
|
);
|
563
777
|
const { data: localesMetadata = [] } = useGetLocalesQuery(hasI18n ? void 0 : skipToken);
|
@@ -609,12 +823,19 @@ const BulkLocalePublishAction = ({
|
|
609
823
|
}, {});
|
610
824
|
return [rowsFromMeta, errors];
|
611
825
|
}, [document, documentMeta?.availableLocales, validate]);
|
612
|
-
const
|
613
|
-
|
826
|
+
const isBulkPublish = action === "bulk-publish";
|
827
|
+
const localesForAction = selectedRows.reduce((acc, selectedRow) => {
|
828
|
+
const isValidLocale = (
|
829
|
+
// Validation errors are irrelevant if we are trying to unpublish
|
830
|
+
!isBulkPublish || !Object.keys(validationErrors).includes(selectedRow.locale)
|
831
|
+
);
|
832
|
+
const shouldAddLocale = isBulkPublish ? selectedRow.status !== "published" && isValidLocale : selectedRow.status !== "draft" && isValidLocale;
|
833
|
+
if (shouldAddLocale) {
|
614
834
|
acc.push(selectedRow.locale);
|
615
835
|
}
|
616
836
|
return acc;
|
617
837
|
}, []);
|
838
|
+
const enableDraftRelationsCount = false;
|
618
839
|
const {
|
619
840
|
data: draftRelationsCount = 0,
|
620
841
|
isLoading: isDraftRelationsLoading,
|
@@ -623,10 +844,10 @@ const BulkLocalePublishAction = ({
|
|
623
844
|
{
|
624
845
|
model,
|
625
846
|
documentIds: [documentId],
|
626
|
-
locale:
|
847
|
+
locale: localesForAction
|
627
848
|
},
|
628
849
|
{
|
629
|
-
skip: !
|
850
|
+
skip: !enableDraftRelationsCount
|
630
851
|
}
|
631
852
|
);
|
632
853
|
React.useEffect(() => {
|
@@ -652,7 +873,18 @@ const BulkLocalePublishAction = ({
|
|
652
873
|
documentIds: [documentId],
|
653
874
|
params: {
|
654
875
|
...params,
|
655
|
-
locale:
|
876
|
+
locale: localesForAction
|
877
|
+
}
|
878
|
+
});
|
879
|
+
setSelectedRows([]);
|
880
|
+
};
|
881
|
+
const unpublish = async () => {
|
882
|
+
await unpublishManyAction({
|
883
|
+
model,
|
884
|
+
documentIds: [documentId],
|
885
|
+
params: {
|
886
|
+
...params,
|
887
|
+
locale: localesForAction
|
656
888
|
}
|
657
889
|
});
|
658
890
|
setSelectedRows([]);
|
@@ -660,14 +892,12 @@ const BulkLocalePublishAction = ({
|
|
660
892
|
const handleAction = async () => {
|
661
893
|
if (draftRelationsCount > 0) {
|
662
894
|
setIsDraftRelationConfirmationOpen(true);
|
663
|
-
} else {
|
895
|
+
} else if (isBulkPublish) {
|
664
896
|
await publish();
|
897
|
+
} else {
|
898
|
+
await unpublish();
|
665
899
|
}
|
666
900
|
};
|
667
|
-
const isUnpublish = document?.status === "published";
|
668
|
-
if (isUnpublish) {
|
669
|
-
console.warn(["I18N"], "Bulk locale unpublish modal not implemented");
|
670
|
-
}
|
671
901
|
if (isDraftRelationConfirmationOpen) {
|
672
902
|
return {
|
673
903
|
label: formatMessage({
|
@@ -705,18 +935,18 @@ const BulkLocalePublishAction = ({
|
|
705
935
|
const hasPermission = selectedRows.map(({ locale }) => locale).every((locale) => canPublish.includes(locale));
|
706
936
|
return {
|
707
937
|
label: formatMessage({
|
708
|
-
id: getTranslation("
|
709
|
-
defaultMessage: "Publish Multiple Locales
|
938
|
+
id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
|
939
|
+
defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
|
710
940
|
}),
|
711
|
-
|
712
|
-
|
941
|
+
variant: isBulkPublish ? "secondary" : "danger",
|
942
|
+
icon: isBulkPublish ? /* @__PURE__ */ jsx(ListPlus, {}) : /* @__PURE__ */ jsx(Cross, {}),
|
943
|
+
disabled: isOnPublishedTab || canPublish.length === 0,
|
713
944
|
position: ["panel"],
|
714
|
-
variant: "secondary",
|
715
945
|
dialog: {
|
716
946
|
type: "modal",
|
717
947
|
title: formatMessage({
|
718
|
-
id: getTranslation("
|
719
|
-
defaultMessage: "Publish Multiple Locales
|
948
|
+
id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
|
949
|
+
defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
|
720
950
|
}),
|
721
951
|
content: () => {
|
722
952
|
return /* @__PURE__ */ jsx(
|
@@ -735,28 +965,35 @@ const BulkLocalePublishAction = ({
|
|
735
965
|
validationErrors,
|
736
966
|
headers,
|
737
967
|
rows,
|
738
|
-
localesMetadata
|
968
|
+
localesMetadata,
|
969
|
+
action: action ?? "bulk-publish"
|
739
970
|
}
|
740
971
|
)
|
741
972
|
}
|
742
973
|
);
|
743
974
|
},
|
744
975
|
footer: () => /* @__PURE__ */ jsx(Modal.Footer, { justifyContent: "flex-end", children: /* @__PURE__ */ jsx(
|
745
|
-
Button
|
976
|
+
Button,
|
746
977
|
{
|
747
978
|
loading: isDraftRelationsLoading,
|
748
|
-
disabled: !hasPermission ||
|
979
|
+
disabled: !hasPermission || localesForAction.length === 0,
|
749
980
|
variant: "default",
|
750
981
|
onClick: handleAction,
|
751
982
|
children: formatMessage({
|
752
|
-
id: "app.utils.publish",
|
753
|
-
defaultMessage: "Publish"
|
983
|
+
id: isBulkPublish ? "app.utils.publish" : "app.utils.unpublish",
|
984
|
+
defaultMessage: isBulkPublish ? "Publish" : "Unpublish"
|
754
985
|
})
|
755
986
|
}
|
756
987
|
) })
|
757
988
|
}
|
758
989
|
};
|
759
990
|
};
|
991
|
+
const BulkLocalePublishAction = (props) => {
|
992
|
+
return BulkLocaleAction({ action: "bulk-publish", ...props });
|
993
|
+
};
|
994
|
+
const BulkLocaleUnpublishAction = (props) => {
|
995
|
+
return BulkLocaleAction({ action: "bulk-unpublish", ...props });
|
996
|
+
};
|
760
997
|
const StyledTrash = styled(Trash)`
|
761
998
|
path {
|
762
999
|
fill: currentColor;
|
@@ -976,54 +1213,13 @@ const LocaleListCell = ({
|
|
976
1213
|
return locale.name;
|
977
1214
|
}).toSorted((a, b) => formatter.compare(a, b));
|
978
1215
|
return /* @__PURE__ */ jsxs(Popover.Root, { children: [
|
979
|
-
/* @__PURE__ */ jsx(Popover.Trigger, { children: /* @__PURE__ */ jsx(Button, { type: "button", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxs(
|
980
|
-
|
981
|
-
{
|
982
|
-
|
983
|
-
alignItems: "center",
|
984
|
-
justifyContent: "center",
|
985
|
-
height: "3.2rem",
|
986
|
-
width: "3.2rem",
|
987
|
-
children: [
|
988
|
-
/* @__PURE__ */ jsx(Typography, { textColor: "neutral800", ellipsis: true, children: localesForDocument.join(", ") }),
|
989
|
-
/* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(CaretDown, {}) })
|
990
|
-
]
|
991
|
-
}
|
992
|
-
) }) }),
|
1216
|
+
/* @__PURE__ */ jsx(Popover.Trigger, { children: /* @__PURE__ */ jsx(Button, { variant: "ghost", type: "button", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxs(Flex, { minWidth: "100%", alignItems: "center", justifyContent: "center", fontWeight: "regular", children: [
|
1217
|
+
/* @__PURE__ */ jsx(Typography, { textColor: "neutral800", ellipsis: true, marginRight: 2, children: localesForDocument.join(", ") }),
|
1218
|
+
/* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(CaretDown, { width: "1.2rem", height: "1.2rem" }) })
|
1219
|
+
] }) }) }),
|
993
1220
|
/* @__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)) }) })
|
994
1221
|
] });
|
995
1222
|
};
|
996
|
-
const Button = styled.button`
|
997
|
-
width: 100%;
|
998
|
-
|
999
|
-
svg {
|
1000
|
-
> g,
|
1001
|
-
path {
|
1002
|
-
fill: ${({ theme }) => theme.colors.neutral500};
|
1003
|
-
}
|
1004
|
-
}
|
1005
|
-
&:hover {
|
1006
|
-
svg {
|
1007
|
-
> g,
|
1008
|
-
path {
|
1009
|
-
fill: ${({ theme }) => theme.colors.neutral600};
|
1010
|
-
}
|
1011
|
-
}
|
1012
|
-
}
|
1013
|
-
&:active {
|
1014
|
-
svg {
|
1015
|
-
> g,
|
1016
|
-
path {
|
1017
|
-
fill: ${({ theme }) => theme.colors.neutral400};
|
1018
|
-
}
|
1019
|
-
}
|
1020
|
-
}
|
1021
|
-
`;
|
1022
|
-
const ActionWrapper = styled(Flex)`
|
1023
|
-
svg {
|
1024
|
-
height: 0.4rem;
|
1025
|
-
}
|
1026
|
-
`;
|
1027
1223
|
const addColumnToTableHook = ({ displayedHeaders, layout }) => {
|
1028
1224
|
const { options } = layout;
|
1029
1225
|
const isFieldLocalized = doesPluginOptionsHaveI18nLocalized(options) ? options.i18n.localized : false;
|
@@ -1221,11 +1417,11 @@ const index = {
|
|
1221
1417
|
},
|
1222
1418
|
id: "internationalization",
|
1223
1419
|
to: "internationalization",
|
1224
|
-
Component: () => import("./SettingsPage-
|
1420
|
+
Component: () => import("./SettingsPage-BjxjwEOb.mjs").then((mod) => ({ default: mod.ProtectedSettingsPage })),
|
1225
1421
|
permissions: PERMISSIONS.accessMain
|
1226
1422
|
});
|
1227
1423
|
const contentManager = app.getPlugin("content-manager");
|
1228
|
-
contentManager.apis.addDocumentHeaderAction([LocalePickerAction]);
|
1424
|
+
contentManager.apis.addDocumentHeaderAction([LocalePickerAction, FillFromAnotherLocaleAction]);
|
1229
1425
|
contentManager.apis.addDocumentAction((actions) => {
|
1230
1426
|
const indexOfDeleteAction = actions.findIndex((action) => action.type === "delete");
|
1231
1427
|
actions.splice(indexOfDeleteAction, 0, DeleteLocaleAction);
|
@@ -1233,6 +1429,7 @@ const index = {
|
|
1233
1429
|
});
|
1234
1430
|
contentManager.apis.addDocumentAction((actions) => {
|
1235
1431
|
actions.splice(2, 0, BulkLocalePublishAction);
|
1432
|
+
actions.splice(5, 0, BulkLocaleUnpublishAction);
|
1236
1433
|
return actions;
|
1237
1434
|
});
|
1238
1435
|
contentManager.injectComponent("listView", "actions", {
|
@@ -1338,7 +1535,7 @@ const index = {
|
|
1338
1535
|
async registerTrads({ locales }) {
|
1339
1536
|
const importedTrads = await Promise.all(
|
1340
1537
|
locales.map((locale) => {
|
1341
|
-
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-
|
1538
|
+
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-2xztdZE1.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 }) => {
|
1342
1539
|
return {
|
1343
1540
|
data: prefixPluginTranslations(data, pluginId),
|
1344
1541
|
locale
|
@@ -1364,4 +1561,4 @@ export {
|
|
1364
1561
|
index as i,
|
1365
1562
|
useCreateLocaleMutation as u
|
1366
1563
|
};
|
1367
|
-
//# sourceMappingURL=index-
|
1564
|
+
//# sourceMappingURL=index-D-qx3tz4.mjs.map
|