@strapi/i18n 0.0.0-experimental.6d27139261823fc4b18da9f3c10b271d5010dbf0 → 0.0.0-experimental.71ed910bd859c7e558bd1c1042eaadb7d26fd22a
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-a96ZyFLy.js → SettingsPage-CJOMVQv5.js} +2 -2
- package/dist/_chunks/{SettingsPage-a96ZyFLy.js.map → SettingsPage-CJOMVQv5.js.map} +1 -1
- package/dist/_chunks/{SettingsPage-DW0GwDcD.mjs → SettingsPage-CnBFTsrq.mjs} +2 -2
- package/dist/_chunks/{SettingsPage-DW0GwDcD.mjs.map → SettingsPage-CnBFTsrq.mjs.map} +1 -1
- package/dist/_chunks/{en-CM6Pjfyv.mjs → en-BYRZFDBV.mjs} +9 -2
- package/dist/_chunks/en-BYRZFDBV.mjs.map +1 -0
- package/dist/_chunks/{en-BsOU9o5z.js → en-Dk9At9_Z.js} +9 -2
- package/dist/_chunks/en-Dk9At9_Z.js.map +1 -0
- package/dist/_chunks/{index-4KJn181Q.mjs → index-BFk3nfTb.mjs} +375 -92
- package/dist/_chunks/index-BFk3nfTb.mjs.map +1 -0
- package/dist/_chunks/{index-sfNkjx75.js → index-C5SImSYG.js} +372 -89
- package/dist/_chunks/index-C5SImSYG.js.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 +29 -3
- package/dist/admin/src/utils/clean.d.ts +4 -0
- package/dist/server/index.js +367 -486
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +368 -487
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/bootstrap.d.ts +1 -4
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +1 -11
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +0 -8
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/utils/index.d.ts +0 -2
- package/dist/server/src/utils/index.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-4KJn181Q.mjs.map +0 -1
- package/dist/_chunks/index-sfNkjx75.js.map +0 -1
- package/dist/server/src/migrations/content-type/disable/index.d.ts +0 -3
- package/dist/server/src/migrations/content-type/disable/index.d.ts.map +0 -1
- package/dist/server/src/migrations/content-type/enable/index.d.ts +0 -3
- package/dist/server/src/migrations/content-type/enable/index.d.ts.map +0 -1
- package/dist/server/src/services/entity-service-decorator.d.ts +0 -29
- package/dist/server/src/services/entity-service-decorator.d.ts.map +0 -1
- package/strapi-server.js +0 -3
@@ -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
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, ListPlus, Earth, EarthStriked, CaretDown } from "@strapi/icons";
|
6
|
+
import { WarningCircle, Pencil, CrossCircle, CheckCircle, ArrowsCounterClockwise, Trash, Plus, 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";
|
@@ -217,10 +217,94 @@ 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
|
+
"status"
|
233
|
+
]);
|
234
|
+
const cleanedDataWithoutPasswordAndRelation = recursiveRemoveFieldTypes(
|
235
|
+
cleanedData,
|
236
|
+
schema,
|
237
|
+
components,
|
238
|
+
["relation", "password"]
|
239
|
+
);
|
240
|
+
return cleanedDataWithoutPasswordAndRelation;
|
241
|
+
};
|
242
|
+
const removeFields = (data, fields) => {
|
243
|
+
return Object.keys(data).reduce((acc, current) => {
|
244
|
+
if (fields.includes(current)) {
|
245
|
+
return acc;
|
246
|
+
}
|
247
|
+
acc[current] = data[current];
|
248
|
+
return acc;
|
249
|
+
}, {});
|
250
|
+
};
|
251
|
+
const recursiveRemoveFieldTypes = (data, schema, components, fields) => {
|
252
|
+
return Object.keys(data).reduce((acc, current) => {
|
253
|
+
const attribute = schema.attributes[current] ?? { type: void 0 };
|
254
|
+
if (fields.includes(attribute.type)) {
|
255
|
+
return acc;
|
256
|
+
}
|
257
|
+
if (attribute.type === "dynamiczone") {
|
258
|
+
acc[current] = data[current].map((componentValue, index2) => {
|
259
|
+
const { id: _, ...rest } = recursiveRemoveFieldTypes(
|
260
|
+
componentValue,
|
261
|
+
components[componentValue.__component],
|
262
|
+
components,
|
263
|
+
fields
|
264
|
+
);
|
265
|
+
return {
|
266
|
+
...rest,
|
267
|
+
__temp_key__: index2 + 1
|
268
|
+
};
|
269
|
+
});
|
270
|
+
} else if (attribute.type === "component") {
|
271
|
+
const { repeatable, component } = attribute;
|
272
|
+
if (repeatable) {
|
273
|
+
acc[current] = (data[current] ?? []).map((compoData, index2) => {
|
274
|
+
const { id: _, ...rest } = recursiveRemoveFieldTypes(
|
275
|
+
compoData,
|
276
|
+
components[component],
|
277
|
+
components,
|
278
|
+
fields
|
279
|
+
);
|
280
|
+
return {
|
281
|
+
...rest,
|
282
|
+
__temp_key__: index2 + 1
|
283
|
+
};
|
284
|
+
});
|
285
|
+
} else {
|
286
|
+
const { id: _, ...rest } = recursiveRemoveFieldTypes(
|
287
|
+
data[current] ?? {},
|
288
|
+
components[component],
|
289
|
+
components,
|
290
|
+
fields
|
291
|
+
);
|
292
|
+
acc[current] = rest;
|
293
|
+
}
|
294
|
+
} else {
|
295
|
+
acc[current] = data[current];
|
296
|
+
}
|
297
|
+
return acc;
|
298
|
+
}, {});
|
299
|
+
};
|
220
300
|
const isErrorMessageDescriptor = (object) => {
|
221
301
|
return typeof object === "object" && object !== null && "id" in object && "defaultMessage" in object;
|
222
302
|
};
|
223
|
-
const EntryValidationText = ({
|
303
|
+
const EntryValidationText = ({
|
304
|
+
status = "draft",
|
305
|
+
validationErrors,
|
306
|
+
action
|
307
|
+
}) => {
|
224
308
|
const { formatMessage } = useIntl();
|
225
309
|
const getErrorStr = (key, value) => {
|
226
310
|
if (typeof value === "string") {
|
@@ -254,30 +338,63 @@ const EntryValidationText = ({ status = "draft", validationErrors }) => {
|
|
254
338
|
) })
|
255
339
|
] });
|
256
340
|
}
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
341
|
+
const getStatusMessage = () => {
|
342
|
+
if (action === "bulk-publish") {
|
343
|
+
if (status === "published") {
|
344
|
+
return {
|
345
|
+
icon: /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
346
|
+
text: formatMessage({
|
347
|
+
id: "content-manager.bulk-publish.already-published",
|
348
|
+
defaultMessage: "Already Published"
|
349
|
+
}),
|
350
|
+
textColor: "success600",
|
351
|
+
fontWeight: "bold"
|
352
|
+
};
|
353
|
+
} else if (status === "modified") {
|
354
|
+
return {
|
355
|
+
icon: /* @__PURE__ */ jsx(ArrowsCounterClockwise, { fill: "alternative600" }),
|
356
|
+
text: formatMessage({
|
357
|
+
id: "app.utils.ready-to-publish-changes",
|
358
|
+
defaultMessage: "Ready to publish changes"
|
359
|
+
})
|
360
|
+
};
|
361
|
+
} else {
|
362
|
+
return {
|
363
|
+
icon: /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
364
|
+
text: formatMessage({
|
365
|
+
id: "app.utils.ready-to-publish",
|
366
|
+
defaultMessage: "Ready to publish"
|
367
|
+
})
|
368
|
+
};
|
369
|
+
}
|
370
|
+
} else {
|
371
|
+
if (status === "draft") {
|
372
|
+
return {
|
373
|
+
icon: /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
374
|
+
text: formatMessage({
|
375
|
+
id: "content-manager.bulk-unpublish.already-unpublished",
|
376
|
+
defaultMessage: "Already Unpublished"
|
377
|
+
}),
|
378
|
+
textColor: "success600",
|
379
|
+
fontWeight: "bold"
|
380
|
+
};
|
381
|
+
} else {
|
382
|
+
return {
|
383
|
+
icon: /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
384
|
+
text: formatMessage({
|
385
|
+
id: "app.utils.ready-to-unpublish-changes",
|
386
|
+
defaultMessage: "Ready to unpublish"
|
387
|
+
}),
|
388
|
+
textColor: "success600",
|
389
|
+
fontWeight: "bold"
|
390
|
+
};
|
391
|
+
}
|
392
|
+
}
|
393
|
+
};
|
394
|
+
const { icon, text, textColor = "success600", fontWeight = "normal" } = getStatusMessage();
|
275
395
|
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
|
-
}) })
|
396
|
+
icon,
|
397
|
+
/* @__PURE__ */ jsx(Typography, { textColor, fontWeight, children: text })
|
281
398
|
] });
|
282
399
|
};
|
283
400
|
const BoldChunk = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
|
@@ -285,7 +402,8 @@ const BulkLocaleActionModal = ({
|
|
285
402
|
headers,
|
286
403
|
rows,
|
287
404
|
localesMetadata,
|
288
|
-
validationErrors = {}
|
405
|
+
validationErrors = {},
|
406
|
+
action
|
289
407
|
}) => {
|
290
408
|
const { formatMessage } = useIntl();
|
291
409
|
const selectedRows = useTable(
|
@@ -298,22 +416,24 @@ const BulkLocaleActionModal = ({
|
|
298
416
|
return acc;
|
299
417
|
}, {});
|
300
418
|
const localesWithErrors = Object.keys(validationErrors);
|
301
|
-
const
|
419
|
+
const publishedCount = selectedRows.filter(
|
302
420
|
({ locale }) => currentStatusByLocale[locale] === "published"
|
303
421
|
).length;
|
304
|
-
const
|
422
|
+
const draftCount = selectedRows.filter(
|
305
423
|
({ locale }) => (currentStatusByLocale[locale] === "draft" || currentStatusByLocale[locale] === "modified") && !localesWithErrors.includes(locale)
|
306
424
|
).length;
|
307
425
|
const withErrorsCount = localesWithErrors.length;
|
426
|
+
const messageId = action === "bulk-publish" ? "content-manager.containers.list.selectedEntriesModal.selectedCount.publish" : "content-manager.containers.list.selectedEntriesModal.selectedCount.unpublish";
|
427
|
+
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
428
|
return formatMessage(
|
309
429
|
{
|
310
|
-
id:
|
311
|
-
defaultMessage
|
430
|
+
id: messageId,
|
431
|
+
defaultMessage
|
312
432
|
},
|
313
433
|
{
|
314
434
|
withErrorsCount,
|
315
|
-
|
316
|
-
|
435
|
+
draftCount,
|
436
|
+
publishedCount,
|
317
437
|
b: BoldChunk
|
318
438
|
}
|
319
439
|
);
|
@@ -345,7 +465,7 @@ const BulkLocaleActionModal = ({
|
|
345
465
|
children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
|
346
466
|
}
|
347
467
|
) }) }),
|
348
|
-
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(EntryValidationText, { validationErrors: error, status }) }),
|
468
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(EntryValidationText, { validationErrors: error, status, action }) }),
|
349
469
|
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(
|
350
470
|
IconButton,
|
351
471
|
{
|
@@ -371,6 +491,48 @@ const BulkLocaleActionModal = ({
|
|
371
491
|
] }) })
|
372
492
|
] });
|
373
493
|
};
|
494
|
+
const statusVariants = {
|
495
|
+
draft: "secondary",
|
496
|
+
published: "success",
|
497
|
+
modified: "alternative"
|
498
|
+
};
|
499
|
+
const LocaleOption = ({
|
500
|
+
isDraftAndPublishEnabled,
|
501
|
+
locale,
|
502
|
+
status,
|
503
|
+
entryExists
|
504
|
+
}) => {
|
505
|
+
const { formatMessage } = useIntl();
|
506
|
+
if (!entryExists) {
|
507
|
+
return formatMessage(
|
508
|
+
{
|
509
|
+
id: getTranslation("CMEditViewLocalePicker.locale.create"),
|
510
|
+
defaultMessage: "Create <bold>{locale}</bold> locale"
|
511
|
+
},
|
512
|
+
{
|
513
|
+
bold: (locale2) => /* @__PURE__ */ jsx("b", { children: locale2 }),
|
514
|
+
locale: locale.name
|
515
|
+
}
|
516
|
+
);
|
517
|
+
}
|
518
|
+
return /* @__PURE__ */ jsxs(Flex, { width: "100%", gap: 1, justifyContent: "space-between", children: [
|
519
|
+
/* @__PURE__ */ jsx(Typography, { children: locale.name }),
|
520
|
+
isDraftAndPublishEnabled ? /* @__PURE__ */ jsx(
|
521
|
+
Status,
|
522
|
+
{
|
523
|
+
display: "flex",
|
524
|
+
paddingLeft: "6px",
|
525
|
+
paddingRight: "6px",
|
526
|
+
paddingTop: "2px",
|
527
|
+
paddingBottom: "2px",
|
528
|
+
showBullet: false,
|
529
|
+
size: "S",
|
530
|
+
variant: statusVariants[status],
|
531
|
+
children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
|
532
|
+
}
|
533
|
+
) : null
|
534
|
+
] });
|
535
|
+
};
|
374
536
|
const LocalePickerAction = ({
|
375
537
|
document,
|
376
538
|
meta,
|
@@ -382,7 +544,13 @@ const LocalePickerAction = ({
|
|
382
544
|
const [{ query }, setQuery] = useQueryParams();
|
383
545
|
const { hasI18n, canCreate, canRead } = useI18n();
|
384
546
|
const { data: locales = [] } = useGetLocalesQuery();
|
385
|
-
const
|
547
|
+
const currentDesiredLocale = query.plugins?.i18n?.locale;
|
548
|
+
const { schema } = unstable_useDocument({
|
549
|
+
model,
|
550
|
+
collectionType,
|
551
|
+
documentId,
|
552
|
+
params: { locale: currentDesiredLocale }
|
553
|
+
});
|
386
554
|
const handleSelect = React.useCallback(
|
387
555
|
(value) => {
|
388
556
|
setQuery({
|
@@ -400,53 +568,47 @@ const LocalePickerAction = ({
|
|
400
568
|
if (!Array.isArray(locales) || !hasI18n) {
|
401
569
|
return;
|
402
570
|
}
|
403
|
-
const currentDesiredLocale = query.plugins?.i18n?.locale;
|
404
571
|
const doesLocaleExist = locales.find((loc) => loc.code === currentDesiredLocale);
|
405
572
|
const defaultLocale = locales.find((locale) => locale.isDefault);
|
406
573
|
if (!doesLocaleExist && defaultLocale?.code) {
|
407
574
|
handleSelect(defaultLocale.code);
|
408
575
|
}
|
409
|
-
}, [handleSelect, hasI18n, locales,
|
410
|
-
|
411
|
-
return null;
|
412
|
-
}
|
413
|
-
const currentLocale = query.plugins?.i18n?.locale || locales.find((loc) => loc.isDefault)?.code;
|
576
|
+
}, [handleSelect, hasI18n, locales, currentDesiredLocale]);
|
577
|
+
const currentLocale = Array.isArray(locales) ? locales.find((locale) => locale.code === currentDesiredLocale) : void 0;
|
414
578
|
const allCurrentLocales = [
|
415
|
-
{ status: getDocumentStatus(document, meta), locale: currentLocale },
|
579
|
+
{ status: getDocumentStatus(document, meta), locale: currentLocale?.code },
|
416
580
|
...meta?.availableLocales ?? []
|
417
581
|
];
|
582
|
+
if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
|
583
|
+
return null;
|
584
|
+
}
|
418
585
|
return {
|
419
586
|
label: formatMessage({
|
420
587
|
id: getTranslation("Settings.locales.modal.locales.label"),
|
421
588
|
defaultMessage: "Locales"
|
422
589
|
}),
|
423
590
|
options: locales.map((locale) => {
|
591
|
+
const entryWithLocaleExists = allCurrentLocales.some((doc) => doc.locale === locale.code);
|
424
592
|
const currentLocaleDoc = allCurrentLocales.find(
|
425
593
|
(doc) => "locale" in doc ? doc.locale === locale.code : false
|
426
594
|
);
|
427
|
-
const status = currentLocaleDoc?.status ?? "draft";
|
428
595
|
const permissionsToCheck = currentLocaleDoc ? canCreate : canRead;
|
429
|
-
const statusVariant = status === "draft" ? "primary" : status === "published" ? "success" : "alternative";
|
430
596
|
return {
|
431
597
|
disabled: !permissionsToCheck.includes(locale.code),
|
432
598
|
value: locale.code,
|
433
|
-
label:
|
434
|
-
|
435
|
-
Status,
|
599
|
+
label: /* @__PURE__ */ jsx(
|
600
|
+
LocaleOption,
|
436
601
|
{
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
paddingBottom: "2px",
|
442
|
-
showBullet: false,
|
443
|
-
size: "S",
|
444
|
-
variant: statusVariant,
|
445
|
-
children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
|
602
|
+
isDraftAndPublishEnabled: !!schema?.options?.draftAndPublish,
|
603
|
+
locale,
|
604
|
+
status: currentLocaleDoc?.status,
|
605
|
+
entryExists: entryWithLocaleExists
|
446
606
|
}
|
447
|
-
)
|
607
|
+
),
|
608
|
+
startIcon: !entryWithLocaleExists ? /* @__PURE__ */ jsx(Plus, {}) : null
|
448
609
|
};
|
449
610
|
}),
|
611
|
+
customizeContent: () => currentLocale?.name,
|
450
612
|
onSelect: handleSelect,
|
451
613
|
value: currentLocale
|
452
614
|
};
|
@@ -462,6 +624,95 @@ const getDocumentStatus = (document, meta) => {
|
|
462
624
|
}
|
463
625
|
return docStatus;
|
464
626
|
};
|
627
|
+
const FillFromAnotherLocaleAction = ({
|
628
|
+
documentId,
|
629
|
+
meta,
|
630
|
+
model,
|
631
|
+
collectionType
|
632
|
+
}) => {
|
633
|
+
const { formatMessage } = useIntl();
|
634
|
+
const [{ query }] = useQueryParams();
|
635
|
+
const currentDesiredLocale = query.plugins?.i18n?.locale;
|
636
|
+
const [localeSelected, setLocaleSelected] = React.useState(null);
|
637
|
+
const setValues = useForm("FillFromAnotherLocale", (state) => state.setValues);
|
638
|
+
const { getDocument } = unstable_useDocumentActions();
|
639
|
+
const { schema, components } = unstable_useDocument({
|
640
|
+
model,
|
641
|
+
documentId,
|
642
|
+
collectionType,
|
643
|
+
params: { locale: currentDesiredLocale }
|
644
|
+
});
|
645
|
+
const { data: locales = [] } = useGetLocalesQuery();
|
646
|
+
const availableLocales = Array.isArray(locales) ? locales.filter((locale) => meta?.availableLocales.some((l) => l.locale === locale.code)) : [];
|
647
|
+
const fillFromLocale = (onClose) => async () => {
|
648
|
+
const response = await getDocument({
|
649
|
+
collectionType,
|
650
|
+
model,
|
651
|
+
documentId,
|
652
|
+
params: { locale: localeSelected }
|
653
|
+
});
|
654
|
+
if (!response || !schema) {
|
655
|
+
return;
|
656
|
+
}
|
657
|
+
const { data } = response;
|
658
|
+
const cleanedData = cleanData(data, schema, components);
|
659
|
+
setValues(cleanedData);
|
660
|
+
onClose();
|
661
|
+
};
|
662
|
+
return {
|
663
|
+
type: "icon",
|
664
|
+
icon: /* @__PURE__ */ jsx(Download, {}),
|
665
|
+
disabled: availableLocales.length === 0,
|
666
|
+
label: formatMessage({
|
667
|
+
id: getTranslation("CMEditViewCopyLocale.copy-text"),
|
668
|
+
defaultMessage: "Fill in from another locale"
|
669
|
+
}),
|
670
|
+
dialog: {
|
671
|
+
type: "dialog",
|
672
|
+
title: formatMessage({
|
673
|
+
id: getTranslation("CMEditViewCopyLocale.dialog.title"),
|
674
|
+
defaultMessage: "Confirmation"
|
675
|
+
}),
|
676
|
+
content: ({ onClose }) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
677
|
+
/* @__PURE__ */ jsx(Dialog.Body, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 3, children: [
|
678
|
+
/* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
679
|
+
/* @__PURE__ */ jsx(Typography, { textAlign: "center", children: formatMessage({
|
680
|
+
id: getTranslation("CMEditViewCopyLocale.dialog.body"),
|
681
|
+
defaultMessage: "Your current content will be erased and filled by the content of the selected locale:"
|
682
|
+
}) }),
|
683
|
+
/* @__PURE__ */ jsxs(Field.Root, { width: "100%", children: [
|
684
|
+
/* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
|
685
|
+
id: getTranslation("CMEditViewCopyLocale.dialog.field.label"),
|
686
|
+
defaultMessage: "Locale"
|
687
|
+
}) }),
|
688
|
+
/* @__PURE__ */ jsx(
|
689
|
+
SingleSelect,
|
690
|
+
{
|
691
|
+
value: localeSelected,
|
692
|
+
placeholder: formatMessage({
|
693
|
+
id: getTranslation("CMEditViewCopyLocale.dialog.field.placeholder"),
|
694
|
+
defaultMessage: "Select one locale..."
|
695
|
+
}),
|
696
|
+
onChange: (value) => setLocaleSelected(value),
|
697
|
+
children: availableLocales.map((locale) => /* @__PURE__ */ jsx(SingleSelectOption, { value: locale.code, children: locale.name }, locale.code))
|
698
|
+
}
|
699
|
+
)
|
700
|
+
] })
|
701
|
+
] }) }),
|
702
|
+
/* @__PURE__ */ jsx(Dialog.Footer, { children: /* @__PURE__ */ jsxs(Flex, { gap: 2, width: "100%", children: [
|
703
|
+
/* @__PURE__ */ jsx(Button, { flex: "auto", variant: "tertiary", onClick: onClose, children: formatMessage({
|
704
|
+
id: getTranslation("CMEditViewCopyLocale.cancel-text"),
|
705
|
+
defaultMessage: "No, cancel"
|
706
|
+
}) }),
|
707
|
+
/* @__PURE__ */ jsx(Button, { flex: "auto", variant: "success", onClick: fillFromLocale(onClose), children: formatMessage({
|
708
|
+
id: getTranslation("CMEditViewCopyLocale.submit-text"),
|
709
|
+
defaultMessage: "Yes, fill in"
|
710
|
+
}) })
|
711
|
+
] }) })
|
712
|
+
] })
|
713
|
+
}
|
714
|
+
};
|
715
|
+
};
|
465
716
|
const DeleteLocaleAction = ({
|
466
717
|
document,
|
467
718
|
documentId,
|
@@ -473,16 +724,23 @@ const DeleteLocaleAction = ({
|
|
473
724
|
const { toggleNotification } = useNotification();
|
474
725
|
const { delete: deleteAction } = unstable_useDocumentActions();
|
475
726
|
const { hasI18n, canDelete } = useI18n();
|
727
|
+
const [{ query }] = useQueryParams();
|
728
|
+
const { data: locales = [] } = useGetLocalesQuery();
|
729
|
+
const currentDesiredLocale = query.plugins?.i18n?.locale;
|
730
|
+
const locale = !("error" in locales) && locales.find((loc) => loc.code === currentDesiredLocale);
|
476
731
|
if (!hasI18n) {
|
477
732
|
return null;
|
478
733
|
}
|
479
734
|
return {
|
480
735
|
disabled: document?.locale && !canDelete.includes(document.locale) || !document || !document.id,
|
481
736
|
position: ["header", "table-row"],
|
482
|
-
label: formatMessage(
|
483
|
-
|
484
|
-
|
485
|
-
|
737
|
+
label: formatMessage(
|
738
|
+
{
|
739
|
+
id: getTranslation("actions.delete.label"),
|
740
|
+
defaultMessage: "Delete entry ({locale})"
|
741
|
+
},
|
742
|
+
{ locale: locale && locale.name }
|
743
|
+
),
|
486
744
|
icon: /* @__PURE__ */ jsx(StyledTrash, {}),
|
487
745
|
variant: "danger",
|
488
746
|
dialog: {
|
@@ -525,23 +783,24 @@ const DeleteLocaleAction = ({
|
|
525
783
|
}
|
526
784
|
};
|
527
785
|
};
|
528
|
-
const
|
786
|
+
const BulkLocaleAction = ({
|
529
787
|
document: baseDocument,
|
530
788
|
documentId,
|
531
789
|
model,
|
532
|
-
collectionType
|
790
|
+
collectionType,
|
791
|
+
action
|
533
792
|
}) => {
|
534
793
|
const baseLocale = baseDocument?.locale ?? null;
|
535
794
|
const [{ query }] = useQueryParams();
|
536
795
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
537
|
-
const
|
796
|
+
const isOnPublishedTab = query.status === "published";
|
538
797
|
const { formatMessage } = useIntl();
|
539
798
|
const { hasI18n, canPublish } = useI18n();
|
540
799
|
const { toggleNotification } = useNotification();
|
541
800
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
542
801
|
const [selectedRows, setSelectedRows] = React.useState([]);
|
543
802
|
const [isDraftRelationConfirmationOpen, setIsDraftRelationConfirmationOpen] = React.useState(false);
|
544
|
-
const { publishMany: publishManyAction } = unstable_useDocumentActions();
|
803
|
+
const { publishMany: publishManyAction, unpublishMany: unpublishManyAction } = unstable_useDocumentActions();
|
545
804
|
const {
|
546
805
|
document,
|
547
806
|
meta: documentMeta,
|
@@ -557,7 +816,7 @@ const BulkLocalePublishAction = ({
|
|
557
816
|
}
|
558
817
|
},
|
559
818
|
{
|
560
|
-
skip: !hasI18n
|
819
|
+
skip: !hasI18n || !baseLocale
|
561
820
|
}
|
562
821
|
);
|
563
822
|
const { data: localesMetadata = [] } = useGetLocalesQuery(hasI18n ? void 0 : skipToken);
|
@@ -609,12 +868,19 @@ const BulkLocalePublishAction = ({
|
|
609
868
|
}, {});
|
610
869
|
return [rowsFromMeta, errors];
|
611
870
|
}, [document, documentMeta?.availableLocales, validate]);
|
612
|
-
const
|
613
|
-
|
871
|
+
const isBulkPublish = action === "bulk-publish";
|
872
|
+
const localesForAction = selectedRows.reduce((acc, selectedRow) => {
|
873
|
+
const isValidLocale = (
|
874
|
+
// Validation errors are irrelevant if we are trying to unpublish
|
875
|
+
!isBulkPublish || !Object.keys(validationErrors).includes(selectedRow.locale)
|
876
|
+
);
|
877
|
+
const shouldAddLocale = isBulkPublish ? selectedRow.status !== "published" && isValidLocale : selectedRow.status !== "draft" && isValidLocale;
|
878
|
+
if (shouldAddLocale) {
|
614
879
|
acc.push(selectedRow.locale);
|
615
880
|
}
|
616
881
|
return acc;
|
617
882
|
}, []);
|
883
|
+
const enableDraftRelationsCount = false;
|
618
884
|
const {
|
619
885
|
data: draftRelationsCount = 0,
|
620
886
|
isLoading: isDraftRelationsLoading,
|
@@ -623,10 +889,10 @@ const BulkLocalePublishAction = ({
|
|
623
889
|
{
|
624
890
|
model,
|
625
891
|
documentIds: [documentId],
|
626
|
-
locale:
|
892
|
+
locale: localesForAction
|
627
893
|
},
|
628
894
|
{
|
629
|
-
skip: !
|
895
|
+
skip: !enableDraftRelationsCount
|
630
896
|
}
|
631
897
|
);
|
632
898
|
React.useEffect(() => {
|
@@ -652,7 +918,18 @@ const BulkLocalePublishAction = ({
|
|
652
918
|
documentIds: [documentId],
|
653
919
|
params: {
|
654
920
|
...params,
|
655
|
-
locale:
|
921
|
+
locale: localesForAction
|
922
|
+
}
|
923
|
+
});
|
924
|
+
setSelectedRows([]);
|
925
|
+
};
|
926
|
+
const unpublish = async () => {
|
927
|
+
await unpublishManyAction({
|
928
|
+
model,
|
929
|
+
documentIds: [documentId],
|
930
|
+
params: {
|
931
|
+
...params,
|
932
|
+
locale: localesForAction
|
656
933
|
}
|
657
934
|
});
|
658
935
|
setSelectedRows([]);
|
@@ -660,14 +937,12 @@ const BulkLocalePublishAction = ({
|
|
660
937
|
const handleAction = async () => {
|
661
938
|
if (draftRelationsCount > 0) {
|
662
939
|
setIsDraftRelationConfirmationOpen(true);
|
663
|
-
} else {
|
940
|
+
} else if (isBulkPublish) {
|
664
941
|
await publish();
|
942
|
+
} else {
|
943
|
+
await unpublish();
|
665
944
|
}
|
666
945
|
};
|
667
|
-
const isUnpublish = document?.status === "published";
|
668
|
-
if (isUnpublish) {
|
669
|
-
console.warn(["I18N"], "Bulk locale unpublish modal not implemented");
|
670
|
-
}
|
671
946
|
if (isDraftRelationConfirmationOpen) {
|
672
947
|
return {
|
673
948
|
label: formatMessage({
|
@@ -705,18 +980,18 @@ const BulkLocalePublishAction = ({
|
|
705
980
|
const hasPermission = selectedRows.map(({ locale }) => locale).every((locale) => canPublish.includes(locale));
|
706
981
|
return {
|
707
982
|
label: formatMessage({
|
708
|
-
id: getTranslation("
|
709
|
-
defaultMessage: "Publish Multiple Locales
|
983
|
+
id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
|
984
|
+
defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
|
710
985
|
}),
|
711
|
-
|
712
|
-
|
986
|
+
variant: isBulkPublish ? "secondary" : "danger",
|
987
|
+
icon: isBulkPublish ? /* @__PURE__ */ jsx(ListPlus, {}) : /* @__PURE__ */ jsx(Cross, {}),
|
988
|
+
disabled: isOnPublishedTab || canPublish.length === 0,
|
713
989
|
position: ["panel"],
|
714
|
-
variant: "secondary",
|
715
990
|
dialog: {
|
716
991
|
type: "modal",
|
717
992
|
title: formatMessage({
|
718
|
-
id: getTranslation("
|
719
|
-
defaultMessage: "Publish Multiple Locales
|
993
|
+
id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
|
994
|
+
defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
|
720
995
|
}),
|
721
996
|
content: () => {
|
722
997
|
return /* @__PURE__ */ jsx(
|
@@ -735,7 +1010,8 @@ const BulkLocalePublishAction = ({
|
|
735
1010
|
validationErrors,
|
736
1011
|
headers,
|
737
1012
|
rows,
|
738
|
-
localesMetadata
|
1013
|
+
localesMetadata,
|
1014
|
+
action: action ?? "bulk-publish"
|
739
1015
|
}
|
740
1016
|
)
|
741
1017
|
}
|
@@ -745,18 +1021,24 @@ const BulkLocalePublishAction = ({
|
|
745
1021
|
Button,
|
746
1022
|
{
|
747
1023
|
loading: isDraftRelationsLoading,
|
748
|
-
disabled: !hasPermission ||
|
1024
|
+
disabled: !hasPermission || localesForAction.length === 0,
|
749
1025
|
variant: "default",
|
750
1026
|
onClick: handleAction,
|
751
1027
|
children: formatMessage({
|
752
|
-
id: "app.utils.publish",
|
753
|
-
defaultMessage: "Publish"
|
1028
|
+
id: isBulkPublish ? "app.utils.publish" : "app.utils.unpublish",
|
1029
|
+
defaultMessage: isBulkPublish ? "Publish" : "Unpublish"
|
754
1030
|
})
|
755
1031
|
}
|
756
1032
|
) })
|
757
1033
|
}
|
758
1034
|
};
|
759
1035
|
};
|
1036
|
+
const BulkLocalePublishAction = (props) => {
|
1037
|
+
return BulkLocaleAction({ action: "bulk-publish", ...props });
|
1038
|
+
};
|
1039
|
+
const BulkLocaleUnpublishAction = (props) => {
|
1040
|
+
return BulkLocaleAction({ action: "bulk-unpublish", ...props });
|
1041
|
+
};
|
760
1042
|
const StyledTrash = styled(Trash)`
|
761
1043
|
path {
|
762
1044
|
fill: currentColor;
|
@@ -1180,11 +1462,11 @@ const index = {
|
|
1180
1462
|
},
|
1181
1463
|
id: "internationalization",
|
1182
1464
|
to: "internationalization",
|
1183
|
-
Component: () => import("./SettingsPage-
|
1465
|
+
Component: () => import("./SettingsPage-CnBFTsrq.mjs").then((mod) => ({ default: mod.ProtectedSettingsPage })),
|
1184
1466
|
permissions: PERMISSIONS.accessMain
|
1185
1467
|
});
|
1186
1468
|
const contentManager = app.getPlugin("content-manager");
|
1187
|
-
contentManager.apis.addDocumentHeaderAction([LocalePickerAction]);
|
1469
|
+
contentManager.apis.addDocumentHeaderAction([LocalePickerAction, FillFromAnotherLocaleAction]);
|
1188
1470
|
contentManager.apis.addDocumentAction((actions) => {
|
1189
1471
|
const indexOfDeleteAction = actions.findIndex((action) => action.type === "delete");
|
1190
1472
|
actions.splice(indexOfDeleteAction, 0, DeleteLocaleAction);
|
@@ -1192,6 +1474,7 @@ const index = {
|
|
1192
1474
|
});
|
1193
1475
|
contentManager.apis.addDocumentAction((actions) => {
|
1194
1476
|
actions.splice(2, 0, BulkLocalePublishAction);
|
1477
|
+
actions.splice(5, 0, BulkLocaleUnpublishAction);
|
1195
1478
|
return actions;
|
1196
1479
|
});
|
1197
1480
|
contentManager.injectComponent("listView", "actions", {
|
@@ -1297,7 +1580,7 @@ const index = {
|
|
1297
1580
|
async registerTrads({ locales }) {
|
1298
1581
|
const importedTrads = await Promise.all(
|
1299
1582
|
locales.map((locale) => {
|
1300
|
-
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-
|
1583
|
+
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-BYRZFDBV.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 }) => {
|
1301
1584
|
return {
|
1302
1585
|
data: prefixPluginTranslations(data, pluginId),
|
1303
1586
|
locale
|
@@ -1323,4 +1606,4 @@ export {
|
|
1323
1606
|
index as i,
|
1324
1607
|
useCreateLocaleMutation as u
|
1325
1608
|
};
|
1326
|
-
//# sourceMappingURL=index-
|
1609
|
+
//# sourceMappingURL=index-BFk3nfTb.mjs.map
|