@strapi/i18n 0.0.0-experimental.d954d57341a6623992a0d211daaec8e245c3517d → 0.0.0-experimental.dd1d47ef78ef6cfec4ed62576108500bd9f13740

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.
Files changed (55) hide show
  1. package/LICENSE +18 -3
  2. package/dist/_chunks/{SettingsPage-Dsi2qGtq.mjs → SettingsPage-BHvunuIF.mjs} +17 -12
  3. package/dist/_chunks/SettingsPage-BHvunuIF.mjs.map +1 -0
  4. package/dist/_chunks/{SettingsPage-VN7sTzkb.js → SettingsPage-Bcj7380u.js} +17 -12
  5. package/dist/_chunks/SettingsPage-Bcj7380u.js.map +1 -0
  6. package/dist/_chunks/{en-Kv6y9zPQ.js → en-BKBz3tro.js} +12 -3
  7. package/dist/_chunks/en-BKBz3tro.js.map +1 -0
  8. package/dist/_chunks/{en-18tWw4P6.mjs → en-DlXfy6Gy.mjs} +12 -3
  9. package/dist/_chunks/en-DlXfy6Gy.mjs.map +1 -0
  10. package/dist/_chunks/{index-kedPlCo6.js → index-BKZbxhpm.js} +431 -188
  11. package/dist/_chunks/index-BKZbxhpm.js.map +1 -0
  12. package/dist/_chunks/{index-DhtjJYrx.mjs → index-DUdrr5PR.mjs} +427 -184
  13. package/dist/_chunks/index-DUdrr5PR.mjs.map +1 -0
  14. package/dist/admin/index.js +1 -1
  15. package/dist/admin/index.mjs +1 -1
  16. package/dist/admin/src/components/BulkLocaleActionModal.d.ts +2 -1
  17. package/dist/admin/src/components/CMHeaderActions.d.ts +29 -3
  18. package/dist/admin/src/components/CreateLocale.d.ts +6 -6
  19. package/dist/admin/src/contentReleasesHooks/releaseDetailsView.d.ts +9 -5
  20. package/dist/admin/src/utils/clean.d.ts +4 -0
  21. package/dist/admin/src/utils/schemas.d.ts +1 -0
  22. package/dist/server/index.js +413 -480
  23. package/dist/server/index.js.map +1 -1
  24. package/dist/server/index.mjs +415 -482
  25. package/dist/server/index.mjs.map +1 -1
  26. package/dist/server/src/bootstrap.d.ts +1 -4
  27. package/dist/server/src/bootstrap.d.ts.map +1 -1
  28. package/dist/server/src/index.d.ts +21 -13
  29. package/dist/server/src/index.d.ts.map +1 -1
  30. package/dist/server/src/register.d.ts.map +1 -1
  31. package/dist/server/src/services/index.d.ts +20 -10
  32. package/dist/server/src/services/index.d.ts.map +1 -1
  33. package/dist/server/src/services/permissions/actions.d.ts +14 -2
  34. package/dist/server/src/services/permissions/actions.d.ts.map +1 -1
  35. package/dist/server/src/services/permissions.d.ts +14 -2
  36. package/dist/server/src/services/permissions.d.ts.map +1 -1
  37. package/dist/server/src/services/sanitize/index.d.ts +11 -0
  38. package/dist/server/src/services/sanitize/index.d.ts.map +1 -0
  39. package/dist/server/src/utils/index.d.ts +2 -2
  40. package/dist/server/src/utils/index.d.ts.map +1 -1
  41. package/package.json +10 -10
  42. package/dist/_chunks/SettingsPage-Dsi2qGtq.mjs.map +0 -1
  43. package/dist/_chunks/SettingsPage-VN7sTzkb.js.map +0 -1
  44. package/dist/_chunks/en-18tWw4P6.mjs.map +0 -1
  45. package/dist/_chunks/en-Kv6y9zPQ.js.map +0 -1
  46. package/dist/_chunks/index-DhtjJYrx.mjs.map +0 -1
  47. package/dist/_chunks/index-kedPlCo6.js.map +0 -1
  48. package/dist/admin/src/components/Initializer.d.ts +0 -5
  49. package/dist/server/src/migrations/content-type/disable/index.d.ts +0 -3
  50. package/dist/server/src/migrations/content-type/disable/index.d.ts.map +0 -1
  51. package/dist/server/src/migrations/content-type/enable/index.d.ts +0 -3
  52. package/dist/server/src/migrations/content-type/enable/index.d.ts.map +0 -1
  53. package/dist/server/src/services/entity-service-decorator.d.ts +0 -29
  54. package/dist/server/src/services/entity-service-decorator.d.ts.map +0 -1
  55. package/strapi-server.js +0 -3
@@ -7,6 +7,7 @@ const designSystem = require("@strapi/design-system");
7
7
  const icons = require("@strapi/icons");
8
8
  const reactIntl = require("react-intl");
9
9
  const styledComponents = require("styled-components");
10
+ const query = require("@reduxjs/toolkit/query");
10
11
  const strapiAdmin = require("@strapi/admin/strapi-admin");
11
12
  const strapiAdmin$1 = require("@strapi/content-manager/strapi-admin");
12
13
  const reactRouterDom = require("react-router-dom");
@@ -160,7 +161,7 @@ const useI18n = () => {
160
161
  model: params.slug
161
162
  },
162
163
  {
163
- skip: !params.slug || !params.collectionType
164
+ skip: true
164
165
  }
165
166
  );
166
167
  if (doesPluginOptionsHaveI18nLocalized(schema?.pluginOptions)) {
@@ -240,10 +241,94 @@ const relationsApi = i18nApi.injectEndpoints({
240
241
  })
241
242
  });
242
243
  const { useGetManyDraftRelationCountQuery } = relationsApi;
244
+ const cleanData = (data, schema, components) => {
245
+ const cleanedData = removeFields(data, [
246
+ "createdAt",
247
+ "createdBy",
248
+ "updatedAt",
249
+ "updatedBy",
250
+ "id",
251
+ "documentId",
252
+ "publishedAt",
253
+ "strapi_stage",
254
+ "strapi_assignee",
255
+ "locale",
256
+ "status"
257
+ ]);
258
+ const cleanedDataWithoutPasswordAndRelation = recursiveRemoveFieldTypes(
259
+ cleanedData,
260
+ schema,
261
+ components,
262
+ ["relation", "password"]
263
+ );
264
+ return cleanedDataWithoutPasswordAndRelation;
265
+ };
266
+ const removeFields = (data, fields) => {
267
+ return Object.keys(data).reduce((acc, current) => {
268
+ if (fields.includes(current)) {
269
+ return acc;
270
+ }
271
+ acc[current] = data[current];
272
+ return acc;
273
+ }, {});
274
+ };
275
+ const recursiveRemoveFieldTypes = (data, schema, components, fields) => {
276
+ return Object.keys(data).reduce((acc, current) => {
277
+ const attribute = schema.attributes[current] ?? { type: void 0 };
278
+ if (fields.includes(attribute.type)) {
279
+ return acc;
280
+ }
281
+ if (attribute.type === "dynamiczone") {
282
+ acc[current] = data[current].map((componentValue, index2) => {
283
+ const { id: _, ...rest } = recursiveRemoveFieldTypes(
284
+ componentValue,
285
+ components[componentValue.__component],
286
+ components,
287
+ fields
288
+ );
289
+ return {
290
+ ...rest,
291
+ __temp_key__: index2 + 1
292
+ };
293
+ });
294
+ } else if (attribute.type === "component") {
295
+ const { repeatable, component } = attribute;
296
+ if (repeatable) {
297
+ acc[current] = (data[current] ?? []).map((compoData, index2) => {
298
+ const { id: _, ...rest } = recursiveRemoveFieldTypes(
299
+ compoData,
300
+ components[component],
301
+ components,
302
+ fields
303
+ );
304
+ return {
305
+ ...rest,
306
+ __temp_key__: index2 + 1
307
+ };
308
+ });
309
+ } else {
310
+ const { id: _, ...rest } = recursiveRemoveFieldTypes(
311
+ data[current] ?? {},
312
+ components[component],
313
+ components,
314
+ fields
315
+ );
316
+ acc[current] = rest;
317
+ }
318
+ } else {
319
+ acc[current] = data[current];
320
+ }
321
+ return acc;
322
+ }, {});
323
+ };
243
324
  const isErrorMessageDescriptor = (object) => {
244
325
  return typeof object === "object" && object !== null && "id" in object && "defaultMessage" in object;
245
326
  };
246
- const EntryValidationText = ({ status = "draft", validationErrors }) => {
327
+ const EntryValidationText = ({
328
+ status = "draft",
329
+ validationErrors,
330
+ action
331
+ }) => {
247
332
  const { formatMessage } = reactIntl.useIntl();
248
333
  const getErrorStr = (key, value) => {
249
334
  if (typeof value === "string") {
@@ -277,30 +362,63 @@ const EntryValidationText = ({ status = "draft", validationErrors }) => {
277
362
  ) })
278
363
  ] });
279
364
  }
280
- if (status === "published") {
281
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
282
- /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
283
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
284
- id: "content-manager.bulk-publish.already-published",
285
- defaultMessage: "Already Published"
286
- }) })
287
- ] });
288
- }
289
- if (status === "modified") {
290
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
291
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowsCounterClockwise, { fill: "alternative600" }),
292
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
293
- id: "app.utils.ready-to-publish-changes",
294
- defaultMessage: "Ready to publish changes"
295
- }) })
296
- ] });
297
- }
365
+ const getStatusMessage = () => {
366
+ if (action === "bulk-publish") {
367
+ if (status === "published") {
368
+ return {
369
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
370
+ text: formatMessage({
371
+ id: "content-manager.bulk-publish.already-published",
372
+ defaultMessage: "Already Published"
373
+ }),
374
+ textColor: "success600",
375
+ fontWeight: "bold"
376
+ };
377
+ } else if (status === "modified") {
378
+ return {
379
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowsCounterClockwise, { fill: "alternative600" }),
380
+ text: formatMessage({
381
+ id: "app.utils.ready-to-publish-changes",
382
+ defaultMessage: "Ready to publish changes"
383
+ })
384
+ };
385
+ } else {
386
+ return {
387
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
388
+ text: formatMessage({
389
+ id: "app.utils.ready-to-publish",
390
+ defaultMessage: "Ready to publish"
391
+ })
392
+ };
393
+ }
394
+ } else {
395
+ if (status === "draft") {
396
+ return {
397
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
398
+ text: formatMessage({
399
+ id: "content-manager.bulk-unpublish.already-unpublished",
400
+ defaultMessage: "Already Unpublished"
401
+ }),
402
+ textColor: "success600",
403
+ fontWeight: "bold"
404
+ };
405
+ } else {
406
+ return {
407
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
408
+ text: formatMessage({
409
+ id: "app.utils.ready-to-unpublish-changes",
410
+ defaultMessage: "Ready to unpublish"
411
+ }),
412
+ textColor: "success600",
413
+ fontWeight: "bold"
414
+ };
415
+ }
416
+ }
417
+ };
418
+ const { icon, text, textColor = "success600", fontWeight = "normal" } = getStatusMessage();
298
419
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
299
- /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
300
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
301
- id: "app.utils.ready-to-publish",
302
- defaultMessage: "Ready to publish"
303
- }) })
420
+ icon,
421
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor, fontWeight, children: text })
304
422
  ] });
305
423
  };
306
424
  const BoldChunk = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
@@ -308,7 +426,8 @@ const BulkLocaleActionModal = ({
308
426
  headers,
309
427
  rows,
310
428
  localesMetadata,
311
- validationErrors = {}
429
+ validationErrors = {},
430
+ action
312
431
  }) => {
313
432
  const { formatMessage } = reactIntl.useIntl();
314
433
  const selectedRows = strapiAdmin.useTable(
@@ -321,27 +440,29 @@ const BulkLocaleActionModal = ({
321
440
  return acc;
322
441
  }, {});
323
442
  const localesWithErrors = Object.keys(validationErrors);
324
- const alreadyPublishedCount = selectedRows.filter(
443
+ const publishedCount = selectedRows.filter(
325
444
  ({ locale }) => currentStatusByLocale[locale] === "published"
326
445
  ).length;
327
- const readyToPublishCount = selectedRows.filter(
446
+ const draftCount = selectedRows.filter(
328
447
  ({ locale }) => (currentStatusByLocale[locale] === "draft" || currentStatusByLocale[locale] === "modified") && !localesWithErrors.includes(locale)
329
448
  ).length;
330
449
  const withErrorsCount = localesWithErrors.length;
450
+ const messageId = action === "bulk-publish" ? "content-manager.containers.list.selectedEntriesModal.selectedCount.publish" : "content-manager.containers.list.selectedEntriesModal.selectedCount.unpublish";
451
+ 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.";
331
452
  return formatMessage(
332
453
  {
333
- id: "content-manager.containers.list.selectedEntriesModal.selectedCount",
334
- 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."
454
+ id: messageId,
455
+ defaultMessage
335
456
  },
336
457
  {
337
458
  withErrorsCount,
338
- readyToPublishCount,
339
- alreadyPublishedCount,
459
+ draftCount,
460
+ publishedCount,
340
461
  b: BoldChunk
341
462
  }
342
463
  );
343
464
  };
344
- return /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
465
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Body, { children: [
345
466
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: getFormattedCountMessage() }),
346
467
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 5, children: /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Content, { children: [
347
468
  /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Head, { children: [
@@ -368,7 +489,7 @@ const BulkLocaleActionModal = ({
368
489
  children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
369
490
  }
370
491
  ) }) }),
371
- /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(EntryValidationText, { validationErrors: error, status }) }),
492
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(EntryValidationText, { validationErrors: error, status, action }) }),
372
493
  /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(
373
494
  designSystem.IconButton,
374
495
  {
@@ -385,7 +506,7 @@ const BulkLocaleActionModal = ({
385
506
  name: locale
386
507
  }
387
508
  ),
388
- borderWidth: 0,
509
+ variant: "ghost",
389
510
  children: /* @__PURE__ */ jsxRuntime.jsx(icons.Pencil, {})
390
511
  }
391
512
  ) })
@@ -394,6 +515,48 @@ const BulkLocaleActionModal = ({
394
515
  ] }) })
395
516
  ] });
396
517
  };
518
+ const statusVariants = {
519
+ draft: "secondary",
520
+ published: "success",
521
+ modified: "alternative"
522
+ };
523
+ const LocaleOption = ({
524
+ isDraftAndPublishEnabled,
525
+ locale,
526
+ status,
527
+ entryExists
528
+ }) => {
529
+ const { formatMessage } = reactIntl.useIntl();
530
+ if (!entryExists) {
531
+ return formatMessage(
532
+ {
533
+ id: getTranslation("CMEditViewLocalePicker.locale.create"),
534
+ defaultMessage: "Create <bold>{locale}</bold> locale"
535
+ },
536
+ {
537
+ bold: (locale2) => /* @__PURE__ */ jsxRuntime.jsx("b", { children: locale2 }),
538
+ locale: locale.name
539
+ }
540
+ );
541
+ }
542
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", gap: 1, justifyContent: "space-between", children: [
543
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: locale.name }),
544
+ isDraftAndPublishEnabled ? /* @__PURE__ */ jsxRuntime.jsx(
545
+ designSystem.Status,
546
+ {
547
+ display: "flex",
548
+ paddingLeft: "6px",
549
+ paddingRight: "6px",
550
+ paddingTop: "2px",
551
+ paddingBottom: "2px",
552
+ showBullet: false,
553
+ size: "S",
554
+ variant: statusVariants[status],
555
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
556
+ }
557
+ ) : null
558
+ ] });
559
+ };
397
560
  const LocalePickerAction = ({
398
561
  document,
399
562
  meta,
@@ -402,74 +565,74 @@ const LocalePickerAction = ({
402
565
  documentId
403
566
  }) => {
404
567
  const { formatMessage } = reactIntl.useIntl();
405
- const [{ query }, setQuery] = strapiAdmin.useQueryParams();
568
+ const [{ query: query2 }, setQuery] = strapiAdmin.useQueryParams();
406
569
  const { hasI18n, canCreate, canRead } = useI18n();
407
570
  const { data: locales = [] } = useGetLocalesQuery();
408
- const { schema } = strapiAdmin$1.unstable_useDocument({ model, collectionType, documentId });
571
+ const currentDesiredLocale = query2.plugins?.i18n?.locale;
572
+ const { schema } = strapiAdmin$1.unstable_useDocument({
573
+ model,
574
+ collectionType,
575
+ documentId,
576
+ params: { locale: currentDesiredLocale }
577
+ });
409
578
  const handleSelect = React__namespace.useCallback(
410
579
  (value) => {
411
580
  setQuery({
412
581
  plugins: {
413
- ...query.plugins,
582
+ ...query2.plugins,
414
583
  i18n: {
415
584
  locale: value
416
585
  }
417
586
  }
418
587
  });
419
588
  },
420
- [query.plugins, setQuery]
589
+ [query2.plugins, setQuery]
421
590
  );
422
591
  React__namespace.useEffect(() => {
423
592
  if (!Array.isArray(locales) || !hasI18n) {
424
593
  return;
425
594
  }
426
- const currentDesiredLocale = query.plugins?.i18n?.locale;
427
595
  const doesLocaleExist = locales.find((loc) => loc.code === currentDesiredLocale);
428
596
  const defaultLocale = locales.find((locale) => locale.isDefault);
429
597
  if (!doesLocaleExist && defaultLocale?.code) {
430
598
  handleSelect(defaultLocale.code);
431
599
  }
432
- }, [handleSelect, hasI18n, locales, query.plugins?.i18n?.locale]);
433
- if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
434
- return null;
435
- }
436
- const currentLocale = query.plugins?.i18n?.locale || locales.find((loc) => loc.isDefault)?.code;
600
+ }, [handleSelect, hasI18n, locales, currentDesiredLocale]);
601
+ const currentLocale = Array.isArray(locales) ? locales.find((locale) => locale.code === currentDesiredLocale) : void 0;
437
602
  const allCurrentLocales = [
438
- { status: getDocumentStatus(document, meta), locale: currentLocale },
603
+ { status: getDocumentStatus(document, meta), locale: currentLocale?.code },
439
604
  ...meta?.availableLocales ?? []
440
605
  ];
606
+ if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
607
+ return null;
608
+ }
441
609
  return {
442
610
  label: formatMessage({
443
611
  id: getTranslation("Settings.locales.modal.locales.label"),
444
612
  defaultMessage: "Locales"
445
613
  }),
446
614
  options: locales.map((locale) => {
615
+ const entryWithLocaleExists = allCurrentLocales.some((doc) => doc.locale === locale.code);
447
616
  const currentLocaleDoc = allCurrentLocales.find(
448
617
  (doc) => "locale" in doc ? doc.locale === locale.code : false
449
618
  );
450
- const status = currentLocaleDoc?.status ?? "draft";
451
- const permissionsToCheck = currentLocaleDoc ? canCreate : canRead;
452
- const statusVariant = status === "draft" ? "primary" : status === "published" ? "success" : "alternative";
619
+ const permissionsToCheck = currentLocaleDoc ? canRead : canCreate;
453
620
  return {
454
621
  disabled: !permissionsToCheck.includes(locale.code),
455
622
  value: locale.code,
456
- label: locale.name,
457
- startIcon: schema?.options?.draftAndPublish ? /* @__PURE__ */ jsxRuntime.jsx(
458
- designSystem.Status,
623
+ label: /* @__PURE__ */ jsxRuntime.jsx(
624
+ LocaleOption,
459
625
  {
460
- display: "flex",
461
- paddingLeft: "6px",
462
- paddingRight: "6px",
463
- paddingTop: "2px",
464
- paddingBottom: "2px",
465
- showBullet: false,
466
- size: "S",
467
- variant: statusVariant,
468
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
626
+ isDraftAndPublishEnabled: !!schema?.options?.draftAndPublish,
627
+ locale,
628
+ status: currentLocaleDoc?.status,
629
+ entryExists: entryWithLocaleExists
469
630
  }
470
- ) : null
631
+ ),
632
+ startIcon: !entryWithLocaleExists ? /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}) : null
471
633
  };
472
634
  }),
635
+ customizeContent: () => currentLocale?.name,
473
636
  onSelect: handleSelect,
474
637
  value: currentLocale
475
638
  };
@@ -485,6 +648,99 @@ const getDocumentStatus = (document, meta) => {
485
648
  }
486
649
  return docStatus;
487
650
  };
651
+ const FillFromAnotherLocaleAction = ({
652
+ documentId,
653
+ meta,
654
+ model,
655
+ collectionType
656
+ }) => {
657
+ const { formatMessage } = reactIntl.useIntl();
658
+ const [{ query: query2 }] = strapiAdmin.useQueryParams();
659
+ const { hasI18n } = useI18n();
660
+ const currentDesiredLocale = query2.plugins?.i18n?.locale;
661
+ const [localeSelected, setLocaleSelected] = React__namespace.useState(null);
662
+ const setValues = strapiAdmin.useForm("FillFromAnotherLocale", (state) => state.setValues);
663
+ const { getDocument } = strapiAdmin$1.unstable_useDocumentActions();
664
+ const { schema, components } = strapiAdmin$1.unstable_useDocument({
665
+ model,
666
+ documentId,
667
+ collectionType,
668
+ params: { locale: currentDesiredLocale }
669
+ });
670
+ const { data: locales = [] } = useGetLocalesQuery();
671
+ const availableLocales = Array.isArray(locales) ? locales.filter((locale) => meta?.availableLocales.some((l) => l.locale === locale.code)) : [];
672
+ const fillFromLocale = (onClose) => async () => {
673
+ const response = await getDocument({
674
+ collectionType,
675
+ model,
676
+ documentId,
677
+ params: { locale: localeSelected }
678
+ });
679
+ if (!response || !schema) {
680
+ return;
681
+ }
682
+ const { data } = response;
683
+ const cleanedData = cleanData(data, schema, components);
684
+ setValues(cleanedData);
685
+ onClose();
686
+ };
687
+ if (!hasI18n) {
688
+ return null;
689
+ }
690
+ return {
691
+ type: "icon",
692
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Download, {}),
693
+ disabled: availableLocales.length === 0,
694
+ label: formatMessage({
695
+ id: getTranslation("CMEditViewCopyLocale.copy-text"),
696
+ defaultMessage: "Fill in from another locale"
697
+ }),
698
+ dialog: {
699
+ type: "dialog",
700
+ title: formatMessage({
701
+ id: getTranslation("CMEditViewCopyLocale.dialog.title"),
702
+ defaultMessage: "Confirmation"
703
+ }),
704
+ content: ({ onClose }) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
705
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 3, children: [
706
+ /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
707
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", children: formatMessage({
708
+ id: getTranslation("CMEditViewCopyLocale.dialog.body"),
709
+ defaultMessage: "Your current content will be erased and filled by the content of the selected locale:"
710
+ }) }),
711
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { width: "100%", children: [
712
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
713
+ id: getTranslation("CMEditViewCopyLocale.dialog.field.label"),
714
+ defaultMessage: "Locale"
715
+ }) }),
716
+ /* @__PURE__ */ jsxRuntime.jsx(
717
+ designSystem.SingleSelect,
718
+ {
719
+ value: localeSelected,
720
+ placeholder: formatMessage({
721
+ id: getTranslation("CMEditViewCopyLocale.dialog.field.placeholder"),
722
+ defaultMessage: "Select one locale..."
723
+ }),
724
+ onChange: (value) => setLocaleSelected(value),
725
+ children: availableLocales.map((locale) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: locale.code, children: locale.name }, locale.code))
726
+ }
727
+ )
728
+ ] })
729
+ ] }) }),
730
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, width: "100%", children: [
731
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { flex: "auto", variant: "tertiary", onClick: onClose, children: formatMessage({
732
+ id: getTranslation("CMEditViewCopyLocale.cancel-text"),
733
+ defaultMessage: "No, cancel"
734
+ }) }),
735
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { flex: "auto", variant: "success", onClick: fillFromLocale(onClose), children: formatMessage({
736
+ id: getTranslation("CMEditViewCopyLocale.submit-text"),
737
+ defaultMessage: "Yes, fill in"
738
+ }) })
739
+ ] }) })
740
+ ] })
741
+ }
742
+ };
743
+ };
488
744
  const DeleteLocaleAction = ({
489
745
  document,
490
746
  documentId,
@@ -496,16 +752,23 @@ const DeleteLocaleAction = ({
496
752
  const { toggleNotification } = strapiAdmin.useNotification();
497
753
  const { delete: deleteAction } = strapiAdmin$1.unstable_useDocumentActions();
498
754
  const { hasI18n, canDelete } = useI18n();
755
+ const [{ query: query2 }] = strapiAdmin.useQueryParams();
756
+ const { data: locales = [] } = useGetLocalesQuery();
757
+ const currentDesiredLocale = query2.plugins?.i18n?.locale;
758
+ const locale = !("error" in locales) && locales.find((loc) => loc.code === currentDesiredLocale);
499
759
  if (!hasI18n) {
500
760
  return null;
501
761
  }
502
762
  return {
503
763
  disabled: document?.locale && !canDelete.includes(document.locale) || !document || !document.id,
504
764
  position: ["header", "table-row"],
505
- label: formatMessage({
506
- id: getTranslation("actions.delete.label"),
507
- defaultMessage: "Delete locale"
508
- }),
765
+ label: formatMessage(
766
+ {
767
+ id: getTranslation("actions.delete.label"),
768
+ defaultMessage: "Delete entry ({locale})"
769
+ },
770
+ { locale: locale && locale.name }
771
+ ),
509
772
  icon: /* @__PURE__ */ jsxRuntime.jsx(StyledTrash, {}),
510
773
  variant: "danger",
511
774
  dialog: {
@@ -522,7 +785,12 @@ const DeleteLocaleAction = ({
522
785
  }) })
523
786
  ] }),
524
787
  onConfirm: async () => {
525
- if (!documentId || !document?.locale) {
788
+ const unableToDelete = (
789
+ // We are unable to delete a collection type without a document ID
790
+ // & unable to delete generally if there is no document locale
791
+ collectionType !== "single-types" && !documentId || !document?.locale
792
+ );
793
+ if (unableToDelete) {
526
794
  console.error(
527
795
  "You're trying to delete a document without an id or locale, this is likely a bug with Strapi. Please open an issue."
528
796
  );
@@ -548,37 +816,43 @@ const DeleteLocaleAction = ({
548
816
  }
549
817
  };
550
818
  };
551
- const BulkLocalePublishAction = ({
819
+ const BulkLocaleAction = ({
552
820
  document: baseDocument,
553
821
  documentId,
554
822
  model,
555
- collectionType
823
+ collectionType,
824
+ action
556
825
  }) => {
557
826
  const baseLocale = baseDocument?.locale ?? null;
558
- const [{ query }] = strapiAdmin.useQueryParams();
559
- const params = React__namespace.useMemo(() => strapiAdmin$1.buildValidParams(query), [query]);
560
- const isPublishedTab = query.status === "published";
827
+ const [{ query: query$1 }] = strapiAdmin.useQueryParams();
828
+ const params = React__namespace.useMemo(() => strapiAdmin$1.buildValidParams(query$1), [query$1]);
829
+ const isOnPublishedTab = query$1.status === "published";
561
830
  const { formatMessage } = reactIntl.useIntl();
562
831
  const { hasI18n, canPublish } = useI18n();
563
832
  const { toggleNotification } = strapiAdmin.useNotification();
564
833
  const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
565
834
  const [selectedRows, setSelectedRows] = React__namespace.useState([]);
566
- const [isConfirmationOpen, setIsConfirmationOpen] = React__namespace.useState(false);
567
- const { publishMany: publishManyAction } = strapiAdmin$1.unstable_useDocumentActions();
835
+ const [isDraftRelationConfirmationOpen, setIsDraftRelationConfirmationOpen] = React__namespace.useState(false);
836
+ const { publishMany: publishManyAction, unpublishMany: unpublishManyAction } = strapiAdmin$1.unstable_useDocumentActions();
568
837
  const {
569
838
  document,
570
839
  meta: documentMeta,
571
840
  schema,
572
841
  validate
573
- } = strapiAdmin$1.unstable_useDocument({
574
- model,
575
- collectionType,
576
- documentId,
577
- params: {
578
- locale: baseLocale
842
+ } = strapiAdmin$1.unstable_useDocument(
843
+ {
844
+ model,
845
+ collectionType,
846
+ documentId,
847
+ params: {
848
+ locale: baseLocale
849
+ }
850
+ },
851
+ {
852
+ skip: !hasI18n || !baseLocale
579
853
  }
580
- });
581
- const { data: localesMetadata = [] } = useGetLocalesQuery();
854
+ );
855
+ const { data: localesMetadata = [] } = useGetLocalesQuery(hasI18n ? void 0 : query.skipToken);
582
856
  const headers = [
583
857
  {
584
858
  label: formatMessage({
@@ -627,12 +901,19 @@ const BulkLocalePublishAction = ({
627
901
  }, {});
628
902
  return [rowsFromMeta, errors];
629
903
  }, [document, documentMeta?.availableLocales, validate]);
630
- const localesToPublish = selectedRows.reduce((acc, selectedRow) => {
631
- if (selectedRow.status !== "published" && !Object.keys(validationErrors).includes(selectedRow.locale)) {
904
+ const isBulkPublish = action === "bulk-publish";
905
+ const localesForAction = selectedRows.reduce((acc, selectedRow) => {
906
+ const isValidLocale = (
907
+ // Validation errors are irrelevant if we are trying to unpublish
908
+ !isBulkPublish || !Object.keys(validationErrors).includes(selectedRow.locale)
909
+ );
910
+ const shouldAddLocale = isBulkPublish ? selectedRow.status !== "published" && isValidLocale : selectedRow.status !== "draft" && isValidLocale;
911
+ if (shouldAddLocale) {
632
912
  acc.push(selectedRow.locale);
633
913
  }
634
914
  return acc;
635
915
  }, []);
916
+ const enableDraftRelationsCount = false;
636
917
  const {
637
918
  data: draftRelationsCount = 0,
638
919
  isLoading: isDraftRelationsLoading,
@@ -641,10 +922,10 @@ const BulkLocalePublishAction = ({
641
922
  {
642
923
  model,
643
924
  documentIds: [documentId],
644
- locale: localesToPublish
925
+ locale: localesForAction
645
926
  },
646
927
  {
647
- skip: !documentId || localesToPublish.length === 0
928
+ skip: !enableDraftRelationsCount
648
929
  }
649
930
  );
650
931
  React__namespace.useEffect(() => {
@@ -670,23 +951,32 @@ const BulkLocalePublishAction = ({
670
951
  documentIds: [documentId],
671
952
  params: {
672
953
  ...params,
673
- locale: localesToPublish
954
+ locale: localesForAction
955
+ }
956
+ });
957
+ setSelectedRows([]);
958
+ };
959
+ const unpublish = async () => {
960
+ await unpublishManyAction({
961
+ model,
962
+ documentIds: [documentId],
963
+ params: {
964
+ ...params,
965
+ locale: localesForAction
674
966
  }
675
967
  });
676
968
  setSelectedRows([]);
677
969
  };
678
970
  const handleAction = async () => {
679
971
  if (draftRelationsCount > 0) {
680
- setIsConfirmationOpen(true);
681
- } else {
972
+ setIsDraftRelationConfirmationOpen(true);
973
+ } else if (isBulkPublish) {
682
974
  await publish();
975
+ } else {
976
+ await unpublish();
683
977
  }
684
978
  };
685
- const isUnpublish = document?.status === "published";
686
- if (isUnpublish) {
687
- console.warn(["I18N"], "Bulk locale unpublish modal not implemented");
688
- }
689
- if (isConfirmationOpen) {
979
+ if (isDraftRelationConfirmationOpen) {
690
980
  return {
691
981
  label: formatMessage({
692
982
  id: "app.components.ConfirmDialog.title",
@@ -695,11 +985,11 @@ const BulkLocalePublishAction = ({
695
985
  variant: "danger",
696
986
  dialog: {
697
987
  onCancel: () => {
698
- setIsConfirmationOpen(false);
988
+ setIsDraftRelationConfirmationOpen(false);
699
989
  },
700
990
  onConfirm: async () => {
701
991
  await publish();
702
- setIsConfirmationOpen(false);
992
+ setIsDraftRelationConfirmationOpen(false);
703
993
  },
704
994
  type: "dialog",
705
995
  title: formatMessage({
@@ -709,27 +999,32 @@ const BulkLocalePublishAction = ({
709
999
  content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "center", gap: 2, children: [
710
1000
  /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, { width: "2.4rem", height: "2.4rem", fill: "danger600" }),
711
1001
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", children: formatMessage({
712
- id: "content-manager.actions.discard.dialog.body",
713
- defaultMessage: "Are you sure you want to discard the changes? This action is irreversible."
1002
+ id: getTranslation("CMEditViewBulkLocale.draft-relation-warning"),
1003
+ defaultMessage: "Some locales are related to draft entries. Publishing them could leave broken links in your app."
1004
+ }) }),
1005
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", children: formatMessage({
1006
+ id: getTranslation("CMEditViewBulkLocale.continue-confirmation"),
1007
+ defaultMessage: "Are you sure you want to continue?"
714
1008
  }) })
715
1009
  ] })
716
1010
  }
717
1011
  };
718
1012
  }
1013
+ const hasPermission = selectedRows.map(({ locale }) => locale).every((locale) => canPublish.includes(locale));
719
1014
  return {
720
1015
  label: formatMessage({
721
- id: getTranslation("CMEditViewBulkLocale.publish-title"),
722
- defaultMessage: "Publish Multiple Locales"
1016
+ id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
1017
+ defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
723
1018
  }),
724
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ListPlus, {}),
725
- disabled: isPublishedTab || !canPublish,
1019
+ variant: isBulkPublish ? "secondary" : "danger",
1020
+ icon: isBulkPublish ? /* @__PURE__ */ jsxRuntime.jsx(icons.ListPlus, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.Cross, {}),
1021
+ disabled: isOnPublishedTab || canPublish.length === 0,
726
1022
  position: ["panel"],
727
- variant: "secondary",
728
1023
  dialog: {
729
1024
  type: "modal",
730
1025
  title: formatMessage({
731
- id: getTranslation("CMEditViewBulkLocale.publish-title"),
732
- defaultMessage: "Publish Multiple Locales"
1026
+ id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
1027
+ defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
733
1028
  }),
734
1029
  content: () => {
735
1030
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -748,28 +1043,35 @@ const BulkLocalePublishAction = ({
748
1043
  validationErrors,
749
1044
  headers,
750
1045
  rows,
751
- localesMetadata
1046
+ localesMetadata,
1047
+ action: action ?? "bulk-publish"
752
1048
  }
753
1049
  )
754
1050
  }
755
1051
  );
756
1052
  },
757
- footer: () => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxRuntime.jsx(
1053
+ footer: () => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Footer, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxRuntime.jsx(
758
1054
  designSystem.Button,
759
1055
  {
760
1056
  loading: isDraftRelationsLoading,
761
- disabled: localesToPublish.length === 0,
1057
+ disabled: !hasPermission || localesForAction.length === 0,
762
1058
  variant: "default",
763
1059
  onClick: handleAction,
764
1060
  children: formatMessage({
765
- id: "app.utils.publish",
766
- defaultMessage: "Publish"
1061
+ id: isBulkPublish ? "app.utils.publish" : "app.utils.unpublish",
1062
+ defaultMessage: isBulkPublish ? "Publish" : "Unpublish"
767
1063
  })
768
1064
  }
769
1065
  ) })
770
1066
  }
771
1067
  };
772
1068
  };
1069
+ const BulkLocalePublishAction = (props) => {
1070
+ return BulkLocaleAction({ action: "bulk-publish", ...props });
1071
+ };
1072
+ const BulkLocaleUnpublishAction = (props) => {
1073
+ return BulkLocaleAction({ action: "bulk-unpublish", ...props });
1074
+ };
773
1075
  const StyledTrash = styledComponents.styled(icons.Trash)`
774
1076
  path {
775
1077
  fill: currentColor;
@@ -826,16 +1128,9 @@ const UnpublishModalAdditionalInfo = () => {
826
1128
  }
827
1129
  ) });
828
1130
  };
829
- const Initializer = ({ setPlugin }) => {
830
- const setPluginRef = React__namespace.useRef(setPlugin);
831
- React__namespace.useEffect(() => {
832
- setPluginRef.current(pluginId);
833
- }, []);
834
- return null;
835
- };
836
1131
  const LocalePicker = () => {
837
1132
  const { formatMessage } = reactIntl.useIntl();
838
- const [{ query }, setQuery] = strapiAdmin.useQueryParams();
1133
+ const [{ query: query2 }, setQuery] = strapiAdmin.useQueryParams();
839
1134
  const { hasI18n, canRead, canCreate } = useI18n();
840
1135
  const { data: locales = [] } = useGetLocalesQuery(void 0, {
841
1136
  skip: !hasI18n
@@ -845,25 +1140,25 @@ const LocalePicker = () => {
845
1140
  setQuery(
846
1141
  {
847
1142
  page: 1,
848
- plugins: { ...query.plugins, i18n: { locale: code } }
1143
+ plugins: { ...query2.plugins, i18n: { locale: code } }
849
1144
  },
850
1145
  "push",
851
1146
  replace
852
1147
  );
853
1148
  },
854
- [query.plugins, setQuery]
1149
+ [query2.plugins, setQuery]
855
1150
  );
856
1151
  React__namespace.useEffect(() => {
857
1152
  if (!Array.isArray(locales) || !hasI18n) {
858
1153
  return;
859
1154
  }
860
- const currentDesiredLocale = query.plugins?.i18n?.locale;
1155
+ const currentDesiredLocale = query2.plugins?.i18n?.locale;
861
1156
  const doesLocaleExist = locales.find((loc) => loc.code === currentDesiredLocale);
862
1157
  const defaultLocale = locales.find((locale) => locale.isDefault);
863
1158
  if (!doesLocaleExist && defaultLocale?.code) {
864
1159
  handleChange(defaultLocale.code, true);
865
1160
  }
866
- }, [hasI18n, handleChange, locales, query.plugins?.i18n?.locale]);
1161
+ }, [hasI18n, handleChange, locales, query2.plugins?.i18n?.locale]);
867
1162
  if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
868
1163
  return null;
869
1164
  }
@@ -878,7 +1173,7 @@ const LocalePicker = () => {
878
1173
  id: getTranslation("actions.select-locale"),
879
1174
  defaultMessage: "Select locale"
880
1175
  }),
881
- value: query.plugins?.i18n?.locale || locales.find((locale) => locale.isDefault)?.code,
1176
+ value: query2.plugins?.i18n?.locale || locales.find((locale) => locale.isDefault)?.code,
882
1177
  onChange: handleChange,
883
1178
  children: displayedLocales.map((locale) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: locale.code, children: locale.name }, locale.id))
884
1179
  }
@@ -996,54 +1291,13 @@ const LocaleListCell = ({
996
1291
  return locale.name;
997
1292
  }).toSorted((a, b) => formatter.compare(a, b));
998
1293
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Popover.Root, { children: [
999
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Popover.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsxs(
1000
- ActionWrapper,
1001
- {
1002
- minWidth: "100%",
1003
- alignItems: "center",
1004
- justifyContent: "center",
1005
- height: "3.2rem",
1006
- width: "3.2rem",
1007
- children: [
1008
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", ellipsis: true, children: localesForDocument.join(", ") }),
1009
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(icons.CaretDown, {}) })
1010
- ]
1011
- }
1012
- ) }) }),
1294
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Popover.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "ghost", type: "button", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { minWidth: "100%", alignItems: "center", justifyContent: "center", fontWeight: "regular", children: [
1295
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", ellipsis: true, marginRight: 2, children: localesForDocument.join(", ") }),
1296
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(icons.CaretDown, { width: "1.2rem", height: "1.2rem" }) })
1297
+ ] }) }) }),
1013
1298
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Popover.Content, { sideOffset: 16, children: /* @__PURE__ */ jsxRuntime.jsx("ul", { children: localesForDocument.map((name) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 3, tag: "li", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: name }) }, name)) }) })
1014
1299
  ] });
1015
1300
  };
1016
- const Button = styledComponents.styled.button`
1017
- width: 100%;
1018
-
1019
- svg {
1020
- > g,
1021
- path {
1022
- fill: ${({ theme }) => theme.colors.neutral500};
1023
- }
1024
- }
1025
- &:hover {
1026
- svg {
1027
- > g,
1028
- path {
1029
- fill: ${({ theme }) => theme.colors.neutral600};
1030
- }
1031
- }
1032
- }
1033
- &:active {
1034
- svg {
1035
- > g,
1036
- path {
1037
- fill: ${({ theme }) => theme.colors.neutral400};
1038
- }
1039
- }
1040
- }
1041
- `;
1042
- const ActionWrapper = styledComponents.styled(designSystem.Flex)`
1043
- svg {
1044
- height: 0.4rem;
1045
- }
1046
- `;
1047
1301
  const addColumnToTableHook = ({ displayedHeaders, layout }) => {
1048
1302
  const { options } = layout;
1049
1303
  const isFieldLocalized = doesPluginOptionsHaveI18nLocalized(options) ? options.i18n.localized : false;
@@ -1072,18 +1326,11 @@ const addColumnToTableHook = ({ displayedHeaders, layout }) => {
1072
1326
  const addLocaleToReleasesHook = ({ displayedHeaders = [] }) => {
1073
1327
  return {
1074
1328
  displayedHeaders: [
1075
- // TODO: Fix when migrating to v5
1076
- // ...displayedHeaders,
1329
+ ...displayedHeaders,
1077
1330
  {
1078
- key: "__locale__",
1079
- fieldSchema: { type: "string" },
1080
- metadatas: {
1081
- label: {
1082
- id: "content-releases.page.ReleaseDetails.table.header.label.locale",
1083
- defaultMessage: "locale"
1084
- },
1085
- searchable: false,
1086
- sortable: false
1331
+ label: {
1332
+ id: "content-releases.page.ReleaseDetails.table.header.label.locale",
1333
+ defaultMessage: "locale"
1087
1334
  },
1088
1335
  name: "locale"
1089
1336
  }
@@ -1176,9 +1423,6 @@ const localeMiddleware = (ctx) => (next) => (permissions) => {
1176
1423
  return next(revisedPermissions);
1177
1424
  };
1178
1425
  const prefixPluginTranslations = (trad, pluginId2) => {
1179
- if (!pluginId2) {
1180
- throw new TypeError("pluginId can't be empty");
1181
- }
1182
1426
  return Object.keys(trad).reduce((acc, current) => {
1183
1427
  acc[`${pluginId2}.${current}`] = trad[current];
1184
1428
  return acc;
@@ -1231,8 +1475,6 @@ const index = {
1231
1475
  app.addRBACMiddleware([localeMiddleware]);
1232
1476
  app.registerPlugin({
1233
1477
  id: pluginId,
1234
- initializer: Initializer,
1235
- isReady: false,
1236
1478
  name: pluginId
1237
1479
  });
1238
1480
  },
@@ -1250,11 +1492,11 @@ const index = {
1250
1492
  },
1251
1493
  id: "internationalization",
1252
1494
  to: "internationalization",
1253
- Component: () => Promise.resolve().then(() => require("./SettingsPage-VN7sTzkb.js")).then((mod) => ({ default: mod.ProtectedSettingsPage })),
1495
+ Component: () => Promise.resolve().then(() => require("./SettingsPage-Bcj7380u.js")).then((mod) => ({ default: mod.ProtectedSettingsPage })),
1254
1496
  permissions: PERMISSIONS.accessMain
1255
1497
  });
1256
1498
  const contentManager = app.getPlugin("content-manager");
1257
- contentManager.apis.addDocumentHeaderAction([LocalePickerAction]);
1499
+ contentManager.apis.addDocumentHeaderAction([LocalePickerAction, FillFromAnotherLocaleAction]);
1258
1500
  contentManager.apis.addDocumentAction((actions) => {
1259
1501
  const indexOfDeleteAction = actions.findIndex((action) => action.type === "delete");
1260
1502
  actions.splice(indexOfDeleteAction, 0, DeleteLocaleAction);
@@ -1262,6 +1504,7 @@ const index = {
1262
1504
  });
1263
1505
  contentManager.apis.addDocumentAction((actions) => {
1264
1506
  actions.splice(2, 0, BulkLocalePublishAction);
1507
+ actions.splice(5, 0, BulkLocaleUnpublishAction);
1265
1508
  return actions;
1266
1509
  });
1267
1510
  contentManager.injectComponent("listView", "actions", {
@@ -1367,7 +1610,7 @@ const index = {
1367
1610
  async registerTrads({ locales }) {
1368
1611
  const importedTrads = await Promise.all(
1369
1612
  locales.map((locale) => {
1370
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/de.json": () => Promise.resolve().then(() => require("./de-DtWiGdHl.js")), "./translations/dk.json": () => Promise.resolve().then(() => require("./dk-D8C-casx.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-Kv6y9zPQ.js")), "./translations/es.json": () => Promise.resolve().then(() => require("./es-DS-XFGSw.js")), "./translations/fr.json": () => Promise.resolve().then(() => require("./fr-BTjekDpq.js")), "./translations/ko.json": () => Promise.resolve().then(() => require("./ko-DmcGUBQ3.js")), "./translations/pl.json": () => Promise.resolve().then(() => require("./pl-Cn5RYonZ.js")), "./translations/ru.json": () => Promise.resolve().then(() => require("./ru-BMBgVL3s.js")), "./translations/tr.json": () => Promise.resolve().then(() => require("./tr-CarUU76c.js")), "./translations/zh-Hans.json": () => Promise.resolve().then(() => require("./zh-Hans-DSHIXAa3.js")), "./translations/zh.json": () => Promise.resolve().then(() => require("./zh-CukOviB0.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
1613
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/de.json": () => Promise.resolve().then(() => require("./de-DtWiGdHl.js")), "./translations/dk.json": () => Promise.resolve().then(() => require("./dk-D8C-casx.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-BKBz3tro.js")), "./translations/es.json": () => Promise.resolve().then(() => require("./es-DS-XFGSw.js")), "./translations/fr.json": () => Promise.resolve().then(() => require("./fr-BTjekDpq.js")), "./translations/ko.json": () => Promise.resolve().then(() => require("./ko-DmcGUBQ3.js")), "./translations/pl.json": () => Promise.resolve().then(() => require("./pl-Cn5RYonZ.js")), "./translations/ru.json": () => Promise.resolve().then(() => require("./ru-BMBgVL3s.js")), "./translations/tr.json": () => Promise.resolve().then(() => require("./tr-CarUU76c.js")), "./translations/zh-Hans.json": () => Promise.resolve().then(() => require("./zh-Hans-DSHIXAa3.js")), "./translations/zh.json": () => Promise.resolve().then(() => require("./zh-CukOviB0.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
1371
1614
  return {
1372
1615
  data: prefixPluginTranslations(data, pluginId),
1373
1616
  locale
@@ -1391,4 +1634,4 @@ exports.useDeleteLocaleMutation = useDeleteLocaleMutation;
1391
1634
  exports.useGetDefaultLocalesQuery = useGetDefaultLocalesQuery;
1392
1635
  exports.useGetLocalesQuery = useGetLocalesQuery;
1393
1636
  exports.useUpdateLocaleMutation = useUpdateLocaleMutation;
1394
- //# sourceMappingURL=index-kedPlCo6.js.map
1637
+ //# sourceMappingURL=index-BKZbxhpm.js.map