@strapi/i18n 0.0.0-experimental.3c73a4c6f6073abdf1608121a200c3d4d87b1aa8 → 0.0.0-experimental.44c735643fa8b4286750c2dca43f185bb30b7760

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 (42) hide show
  1. package/LICENSE +18 -3
  2. package/dist/_chunks/{SettingsPage-0FFSTUW2.mjs → SettingsPage-BjxjwEOb.mjs} +93 -106
  3. package/dist/_chunks/SettingsPage-BjxjwEOb.mjs.map +1 -0
  4. package/dist/_chunks/{SettingsPage-DnLLGeBa.js → SettingsPage-CfTmCkup.js} +91 -104
  5. package/dist/_chunks/SettingsPage-CfTmCkup.js.map +1 -0
  6. package/dist/_chunks/{en-18tWw4P6.mjs → en-2xztdZE1.mjs} +9 -1
  7. package/dist/_chunks/en-2xztdZE1.mjs.map +1 -0
  8. package/dist/_chunks/{en-Kv6y9zPQ.js → en-DWpfm8h5.js} +9 -1
  9. package/dist/_chunks/en-DWpfm8h5.js.map +1 -0
  10. package/dist/_chunks/{index-DtEKsPcR.js → index-5XLZwzwx.js} +380 -204
  11. package/dist/_chunks/index-5XLZwzwx.js.map +1 -0
  12. package/dist/_chunks/{index-BddUXwss.mjs → index-D-qx3tz4.mjs} +374 -198
  13. package/dist/_chunks/index-D-qx3tz4.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 +27 -3
  18. package/dist/admin/src/components/EditLocale.d.ts +5 -4
  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 +38 -9
  23. package/dist/server/index.js.map +1 -1
  24. package/dist/server/index.mjs +39 -10
  25. package/dist/server/index.mjs.map +1 -1
  26. package/dist/server/src/bootstrap.d.ts.map +1 -1
  27. package/dist/server/src/index.d.ts +14 -2
  28. package/dist/server/src/index.d.ts.map +1 -1
  29. package/dist/server/src/services/index.d.ts +14 -2
  30. package/dist/server/src/services/index.d.ts.map +1 -1
  31. package/dist/server/src/services/permissions/actions.d.ts +14 -2
  32. package/dist/server/src/services/permissions/actions.d.ts.map +1 -1
  33. package/dist/server/src/services/permissions.d.ts +14 -2
  34. package/dist/server/src/services/permissions.d.ts.map +1 -1
  35. package/package.json +9 -9
  36. package/dist/_chunks/SettingsPage-0FFSTUW2.mjs.map +0 -1
  37. package/dist/_chunks/SettingsPage-DnLLGeBa.js.map +0 -1
  38. package/dist/_chunks/en-18tWw4P6.mjs.map +0 -1
  39. package/dist/_chunks/en-Kv6y9zPQ.js.map +0 -1
  40. package/dist/_chunks/index-BddUXwss.mjs.map +0 -1
  41. package/dist/_chunks/index-DtEKsPcR.js.map +0 -1
  42. package/dist/admin/src/components/Initializer.d.ts +0 -5
@@ -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");
@@ -71,9 +72,7 @@ const CheckboxConfirmation = ({
71
72
  };
72
73
  const handleConfirm = () => {
73
74
  onChange({ target: { name, value: false, type: "checkbox" } });
74
- setIsOpen(false);
75
75
  };
76
- const handleToggle = () => setIsOpen((prev) => !prev);
77
76
  const label = intlLabel.id ? formatMessage(
78
77
  { id: intlLabel.id, defaultMessage: intlLabel.defaultMessage },
79
78
  { ...intlLabel.values }
@@ -82,35 +81,36 @@ const CheckboxConfirmation = ({
82
81
  { id: description.id, defaultMessage: description.defaultMessage },
83
82
  { ...description.values }
84
83
  ) : "";
85
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
84
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Root, { open: isOpen, onOpenChange: setIsOpen, children: [
86
85
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { hint, name, children: [
87
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Checkbox, { onValueChange: handleChange, value, type: "checkbox", children: label }),
86
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Checkbox, { onCheckedChange: handleChange, checked: value, children: label }),
88
87
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {})
89
88
  ] }),
90
- isOpen && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog, { onClose: handleToggle, title: "Confirmation", isOpen, children: [
91
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.DialogBody, { icon: /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, {}), children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
92
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(TextAlignTypography, { id: "confirm-description", children: formatMessage({
89
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
90
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: formatMessage({
91
+ id: getTranslation("CheckboxConfirmation.Modal.title"),
92
+ defaultMessage: "Disable localization"
93
+ }) }),
94
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { icon: /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, {}), children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
95
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(TextAlignTypography, { children: formatMessage({
93
96
  id: getTranslation("CheckboxConfirmation.Modal.content"),
94
97
  defaultMessage: "Disabling localization will engender the deletion of all your content but the one associated to your default locale (if existing)."
95
98
  }) }) }),
96
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", id: "confirm-description", children: formatMessage({
99
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", children: formatMessage({
97
100
  id: getTranslation("CheckboxConfirmation.Modal.body"),
98
101
  defaultMessage: "Do you want to disable it?"
99
102
  }) }) })
100
103
  ] }) }),
101
- /* @__PURE__ */ jsxRuntime.jsx(
102
- designSystem.DialogFooter,
103
- {
104
- startAction: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleToggle, variant: "tertiary", children: formatMessage({
105
- id: "components.popUpWarning.button.cancel",
106
- defaultMessage: "No, cancel"
107
- }) }),
108
- endAction: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "danger-light", onClick: handleConfirm, children: formatMessage({
109
- id: getTranslation("CheckboxConfirmation.Modal.button-confirm"),
110
- defaultMessage: "Yes, disable"
111
- }) })
112
- }
113
- )
104
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
105
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", children: formatMessage({
106
+ id: "components.popUpWarning.button.cancel",
107
+ defaultMessage: "No, cancel"
108
+ }) }) }),
109
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Action, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "danger-light", onClick: handleConfirm, children: formatMessage({
110
+ id: getTranslation("CheckboxConfirmation.Modal.button-confirm"),
111
+ defaultMessage: "Yes, disable"
112
+ }) }) })
113
+ ] })
114
114
  ] })
115
115
  ] });
116
116
  };
@@ -161,7 +161,7 @@ const useI18n = () => {
161
161
  model: params.slug
162
162
  },
163
163
  {
164
- skip: !params.slug || !params.collectionType
164
+ skip: true
165
165
  }
166
166
  );
167
167
  if (doesPluginOptionsHaveI18nLocalized(schema?.pluginOptions)) {
@@ -241,10 +241,93 @@ const relationsApi = i18nApi.injectEndpoints({
241
241
  })
242
242
  });
243
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
+ ]);
257
+ const cleanedDataWithoutPasswordAndRelation = recursiveRemoveFieldTypes(
258
+ cleanedData,
259
+ schema,
260
+ components,
261
+ ["relation", "password"]
262
+ );
263
+ return cleanedDataWithoutPasswordAndRelation;
264
+ };
265
+ const removeFields = (data, fields) => {
266
+ return Object.keys(data).reduce((acc, current) => {
267
+ if (fields.includes(current)) {
268
+ return acc;
269
+ }
270
+ acc[current] = data[current];
271
+ return acc;
272
+ }, {});
273
+ };
274
+ const recursiveRemoveFieldTypes = (data, schema, components, fields) => {
275
+ return Object.keys(data).reduce((acc, current) => {
276
+ const attribute = schema.attributes[current] ?? { type: void 0 };
277
+ if (fields.includes(attribute.type)) {
278
+ return acc;
279
+ }
280
+ if (attribute.type === "dynamiczone") {
281
+ acc[current] = data[current].map((componentValue, index2) => {
282
+ const { id: _, ...rest } = recursiveRemoveFieldTypes(
283
+ componentValue,
284
+ components[componentValue.__component],
285
+ components,
286
+ fields
287
+ );
288
+ return {
289
+ ...rest,
290
+ __temp_key__: index2 + 1
291
+ };
292
+ });
293
+ } else if (attribute.type === "component") {
294
+ const { repeatable, component } = attribute;
295
+ if (repeatable) {
296
+ acc[current] = (data[current] ?? []).map((compoData, index2) => {
297
+ const { id: _, ...rest } = recursiveRemoveFieldTypes(
298
+ compoData,
299
+ components[component],
300
+ components,
301
+ fields
302
+ );
303
+ return {
304
+ ...rest,
305
+ __temp_key__: index2 + 1
306
+ };
307
+ });
308
+ } else {
309
+ const { id: _, ...rest } = recursiveRemoveFieldTypes(
310
+ data[current] ?? {},
311
+ components[component],
312
+ components,
313
+ fields
314
+ );
315
+ acc[current] = rest;
316
+ }
317
+ } else {
318
+ acc[current] = data[current];
319
+ }
320
+ return acc;
321
+ }, {});
322
+ };
244
323
  const isErrorMessageDescriptor = (object) => {
245
324
  return typeof object === "object" && object !== null && "id" in object && "defaultMessage" in object;
246
325
  };
247
- const EntryValidationText = ({ status = "draft", validationErrors }) => {
326
+ const EntryValidationText = ({
327
+ status = "draft",
328
+ validationErrors,
329
+ action
330
+ }) => {
248
331
  const { formatMessage } = reactIntl.useIntl();
249
332
  const getErrorStr = (key, value) => {
250
333
  if (typeof value === "string") {
@@ -278,30 +361,63 @@ const EntryValidationText = ({ status = "draft", validationErrors }) => {
278
361
  ) })
279
362
  ] });
280
363
  }
281
- if (status === "published") {
282
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
283
- /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
284
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
285
- id: "content-manager.bulk-publish.already-published",
286
- defaultMessage: "Already Published"
287
- }) })
288
- ] });
289
- }
290
- if (status === "modified") {
291
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
292
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowsCounterClockwise, { fill: "alternative600" }),
293
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
294
- id: "app.utils.ready-to-publish-changes",
295
- defaultMessage: "Ready to publish changes"
296
- }) })
297
- ] });
298
- }
364
+ const getStatusMessage = () => {
365
+ if (action === "bulk-publish") {
366
+ if (status === "published") {
367
+ return {
368
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
369
+ text: formatMessage({
370
+ id: "content-manager.bulk-publish.already-published",
371
+ defaultMessage: "Already Published"
372
+ }),
373
+ textColor: "success600",
374
+ fontWeight: "bold"
375
+ };
376
+ } else if (status === "modified") {
377
+ return {
378
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowsCounterClockwise, { fill: "alternative600" }),
379
+ text: formatMessage({
380
+ id: "app.utils.ready-to-publish-changes",
381
+ defaultMessage: "Ready to publish changes"
382
+ })
383
+ };
384
+ } else {
385
+ return {
386
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
387
+ text: formatMessage({
388
+ id: "app.utils.ready-to-publish",
389
+ defaultMessage: "Ready to publish"
390
+ })
391
+ };
392
+ }
393
+ } else {
394
+ if (status === "draft") {
395
+ return {
396
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
397
+ text: formatMessage({
398
+ id: "content-manager.bulk-unpublish.already-unpublished",
399
+ defaultMessage: "Already Unpublished"
400
+ }),
401
+ textColor: "success600",
402
+ fontWeight: "bold"
403
+ };
404
+ } else {
405
+ return {
406
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
407
+ text: formatMessage({
408
+ id: "app.utils.ready-to-unpublish-changes",
409
+ defaultMessage: "Ready to unpublish"
410
+ }),
411
+ textColor: "success600",
412
+ fontWeight: "bold"
413
+ };
414
+ }
415
+ }
416
+ };
417
+ const { icon, text, textColor = "success600", fontWeight = "normal" } = getStatusMessage();
299
418
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
300
- /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
301
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
302
- id: "app.utils.ready-to-publish",
303
- defaultMessage: "Ready to publish"
304
- }) })
419
+ icon,
420
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor, fontWeight, children: text })
305
421
  ] });
306
422
  };
307
423
  const BoldChunk = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
@@ -309,7 +425,8 @@ const BulkLocaleActionModal = ({
309
425
  headers,
310
426
  rows,
311
427
  localesMetadata,
312
- validationErrors = {}
428
+ validationErrors = {},
429
+ action
313
430
  }) => {
314
431
  const { formatMessage } = reactIntl.useIntl();
315
432
  const selectedRows = strapiAdmin.useTable(
@@ -322,27 +439,29 @@ const BulkLocaleActionModal = ({
322
439
  return acc;
323
440
  }, {});
324
441
  const localesWithErrors = Object.keys(validationErrors);
325
- const alreadyPublishedCount = selectedRows.filter(
442
+ const publishedCount = selectedRows.filter(
326
443
  ({ locale }) => currentStatusByLocale[locale] === "published"
327
444
  ).length;
328
- const readyToPublishCount = selectedRows.filter(
445
+ const draftCount = selectedRows.filter(
329
446
  ({ locale }) => (currentStatusByLocale[locale] === "draft" || currentStatusByLocale[locale] === "modified") && !localesWithErrors.includes(locale)
330
447
  ).length;
331
448
  const withErrorsCount = localesWithErrors.length;
449
+ const messageId = action === "bulk-publish" ? "content-manager.containers.list.selectedEntriesModal.selectedCount.publish" : "content-manager.containers.list.selectedEntriesModal.selectedCount.unpublish";
450
+ 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.";
332
451
  return formatMessage(
333
452
  {
334
- id: "content-manager.containers.list.selectedEntriesModal.selectedCount",
335
- 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."
453
+ id: messageId,
454
+ defaultMessage
336
455
  },
337
456
  {
338
457
  withErrorsCount,
339
- readyToPublishCount,
340
- alreadyPublishedCount,
458
+ draftCount,
459
+ publishedCount,
341
460
  b: BoldChunk
342
461
  }
343
462
  );
344
463
  };
345
- return /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
464
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Body, { children: [
346
465
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: getFormattedCountMessage() }),
347
466
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 5, children: /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Content, { children: [
348
467
  /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Head, { children: [
@@ -369,7 +488,7 @@ const BulkLocaleActionModal = ({
369
488
  children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
370
489
  }
371
490
  ) }) }),
372
- /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(EntryValidationText, { validationErrors: error, status }) }),
491
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(EntryValidationText, { validationErrors: error, status, action }) }),
373
492
  /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(
374
493
  designSystem.IconButton,
375
494
  {
@@ -386,7 +505,7 @@ const BulkLocaleActionModal = ({
386
505
  name: locale
387
506
  }
388
507
  ),
389
- borderWidth: 0,
508
+ variant: "ghost",
390
509
  children: /* @__PURE__ */ jsxRuntime.jsx(icons.Pencil, {})
391
510
  }
392
511
  ) })
@@ -403,42 +522,47 @@ const LocalePickerAction = ({
403
522
  documentId
404
523
  }) => {
405
524
  const { formatMessage } = reactIntl.useIntl();
406
- const [{ query }, setQuery] = strapiAdmin.useQueryParams();
525
+ const [{ query: query2 }, setQuery] = strapiAdmin.useQueryParams();
407
526
  const { hasI18n, canCreate, canRead } = useI18n();
408
527
  const { data: locales = [] } = useGetLocalesQuery();
409
- const { schema } = strapiAdmin$1.unstable_useDocument({ model, collectionType, documentId });
528
+ const currentDesiredLocale = query2.plugins?.i18n?.locale;
529
+ const { schema } = strapiAdmin$1.unstable_useDocument({
530
+ model,
531
+ collectionType,
532
+ documentId,
533
+ params: { locale: currentDesiredLocale }
534
+ });
410
535
  const handleSelect = React__namespace.useCallback(
411
536
  (value) => {
412
537
  setQuery({
413
538
  plugins: {
414
- ...query.plugins,
539
+ ...query2.plugins,
415
540
  i18n: {
416
541
  locale: value
417
542
  }
418
543
  }
419
544
  });
420
545
  },
421
- [query.plugins, setQuery]
546
+ [query2.plugins, setQuery]
422
547
  );
423
548
  React__namespace.useEffect(() => {
424
549
  if (!Array.isArray(locales) || !hasI18n) {
425
550
  return;
426
551
  }
427
- const currentDesiredLocale = query.plugins?.i18n?.locale;
428
552
  const doesLocaleExist = locales.find((loc) => loc.code === currentDesiredLocale);
429
553
  const defaultLocale = locales.find((locale) => locale.isDefault);
430
554
  if (!doesLocaleExist && defaultLocale?.code) {
431
555
  handleSelect(defaultLocale.code);
432
556
  }
433
- }, [handleSelect, hasI18n, locales, query.plugins?.i18n?.locale]);
434
- if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
435
- return null;
436
- }
437
- const currentLocale = query.plugins?.i18n?.locale || locales.find((loc) => loc.isDefault)?.code;
557
+ }, [handleSelect, hasI18n, locales, currentDesiredLocale]);
558
+ const currentLocale = Array.isArray(locales) ? locales.find((locale) => locale.code === currentDesiredLocale)?.code : void 0;
438
559
  const allCurrentLocales = [
439
560
  { status: getDocumentStatus(document, meta), locale: currentLocale },
440
561
  ...meta?.availableLocales ?? []
441
562
  ];
563
+ if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
564
+ return null;
565
+ }
442
566
  return {
443
567
  label: formatMessage({
444
568
  id: getTranslation("Settings.locales.modal.locales.label"),
@@ -450,7 +574,7 @@ const LocalePickerAction = ({
450
574
  );
451
575
  const status = currentLocaleDoc?.status ?? "draft";
452
576
  const permissionsToCheck = currentLocaleDoc ? canCreate : canRead;
453
- const statusVariant = status === "draft" ? "primary" : status === "published" ? "success" : "alternative";
577
+ const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
454
578
  return {
455
579
  disabled: !permissionsToCheck.includes(locale.code),
456
580
  value: locale.code,
@@ -486,6 +610,95 @@ const getDocumentStatus = (document, meta) => {
486
610
  }
487
611
  return docStatus;
488
612
  };
613
+ const FillFromAnotherLocaleAction = ({
614
+ documentId,
615
+ meta,
616
+ model,
617
+ collectionType
618
+ }) => {
619
+ const { formatMessage } = reactIntl.useIntl();
620
+ const [{ query: query2 }] = strapiAdmin.useQueryParams();
621
+ const currentDesiredLocale = query2.plugins?.i18n?.locale;
622
+ const [localeSelected, setLocaleSelected] = React__namespace.useState(null);
623
+ const setValues = strapiAdmin.useForm("FillFromAnotherLocale", (state) => state.setValues);
624
+ const { getDocument } = strapiAdmin$1.unstable_useDocumentActions();
625
+ const { schema, components } = strapiAdmin$1.unstable_useDocument({
626
+ model,
627
+ documentId,
628
+ collectionType,
629
+ params: { locale: currentDesiredLocale }
630
+ });
631
+ const { data: locales = [] } = useGetLocalesQuery();
632
+ const availableLocales = Array.isArray(locales) ? locales.filter((locale) => meta?.availableLocales.some((l) => l.locale === locale.code)) : [];
633
+ const fillFromLocale = (onClose) => async () => {
634
+ const response = await getDocument({
635
+ collectionType,
636
+ model,
637
+ documentId,
638
+ params: { locale: localeSelected }
639
+ });
640
+ if (!response || !schema) {
641
+ return;
642
+ }
643
+ const { data } = response;
644
+ const cleanedData = cleanData(data, schema, components);
645
+ setValues(cleanedData);
646
+ onClose();
647
+ };
648
+ return {
649
+ type: "icon",
650
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Download, {}),
651
+ disabled: availableLocales.length === 0,
652
+ label: formatMessage({
653
+ id: getTranslation("CMEditViewCopyLocale.copy-text"),
654
+ defaultMessage: "Fill in from another locale"
655
+ }),
656
+ dialog: {
657
+ type: "dialog",
658
+ title: formatMessage({
659
+ id: getTranslation("CMEditViewCopyLocale.dialog.title"),
660
+ defaultMessage: "Confirmation"
661
+ }),
662
+ content: ({ onClose }) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
663
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 3, children: [
664
+ /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
665
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", children: formatMessage({
666
+ id: getTranslation("CMEditViewCopyLocale.dialog.body"),
667
+ defaultMessage: "Your current content will be erased and filled by the content of the selected locale:"
668
+ }) }),
669
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { width: "100%", children: [
670
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
671
+ id: getTranslation("CMEditViewCopyLocale.dialog.field.label"),
672
+ defaultMessage: "Locale"
673
+ }) }),
674
+ /* @__PURE__ */ jsxRuntime.jsx(
675
+ designSystem.SingleSelect,
676
+ {
677
+ value: localeSelected,
678
+ placeholder: formatMessage({
679
+ id: getTranslation("CMEditViewCopyLocale.dialog.field.placeholder"),
680
+ defaultMessage: "Select one locale..."
681
+ }),
682
+ onChange: (value) => setLocaleSelected(value),
683
+ children: availableLocales.map((locale) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: locale.code, children: locale.name }, locale.code))
684
+ }
685
+ )
686
+ ] })
687
+ ] }) }),
688
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, width: "100%", children: [
689
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { flex: "auto", variant: "tertiary", onClick: onClose, children: formatMessage({
690
+ id: getTranslation("CMEditViewCopyLocale.cancel-text"),
691
+ defaultMessage: "No, cancel"
692
+ }) }),
693
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { flex: "auto", variant: "success", onClick: fillFromLocale(onClose), children: formatMessage({
694
+ id: getTranslation("CMEditViewCopyLocale.submit-text"),
695
+ defaultMessage: "Yes, fill in"
696
+ }) })
697
+ ] }) })
698
+ ] })
699
+ }
700
+ };
701
+ };
489
702
  const DeleteLocaleAction = ({
490
703
  document,
491
704
  documentId,
@@ -549,37 +762,43 @@ const DeleteLocaleAction = ({
549
762
  }
550
763
  };
551
764
  };
552
- const BulkLocalePublishAction = ({
765
+ const BulkLocaleAction = ({
553
766
  document: baseDocument,
554
767
  documentId,
555
768
  model,
556
- collectionType
769
+ collectionType,
770
+ action
557
771
  }) => {
558
772
  const baseLocale = baseDocument?.locale ?? null;
559
- const [{ query }] = strapiAdmin.useQueryParams();
560
- const params = React__namespace.useMemo(() => strapiAdmin$1.buildValidParams(query), [query]);
561
- const isPublishedTab = query.status === "published";
773
+ const [{ query: query$1 }] = strapiAdmin.useQueryParams();
774
+ const params = React__namespace.useMemo(() => strapiAdmin$1.buildValidParams(query$1), [query$1]);
775
+ const isOnPublishedTab = query$1.status === "published";
562
776
  const { formatMessage } = reactIntl.useIntl();
563
777
  const { hasI18n, canPublish } = useI18n();
564
778
  const { toggleNotification } = strapiAdmin.useNotification();
565
779
  const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
566
780
  const [selectedRows, setSelectedRows] = React__namespace.useState([]);
567
- const [isConfirmationOpen, setIsConfirmationOpen] = React__namespace.useState(false);
568
- const { publishMany: publishManyAction } = strapiAdmin$1.unstable_useDocumentActions();
781
+ const [isDraftRelationConfirmationOpen, setIsDraftRelationConfirmationOpen] = React__namespace.useState(false);
782
+ const { publishMany: publishManyAction, unpublishMany: unpublishManyAction } = strapiAdmin$1.unstable_useDocumentActions();
569
783
  const {
570
784
  document,
571
785
  meta: documentMeta,
572
786
  schema,
573
787
  validate
574
- } = strapiAdmin$1.unstable_useDocument({
575
- model,
576
- collectionType,
577
- documentId,
578
- params: {
579
- locale: baseLocale
788
+ } = strapiAdmin$1.unstable_useDocument(
789
+ {
790
+ model,
791
+ collectionType,
792
+ documentId,
793
+ params: {
794
+ locale: baseLocale
795
+ }
796
+ },
797
+ {
798
+ skip: !hasI18n || !baseLocale
580
799
  }
581
- });
582
- const { data: localesMetadata = [] } = useGetLocalesQuery();
800
+ );
801
+ const { data: localesMetadata = [] } = useGetLocalesQuery(hasI18n ? void 0 : query.skipToken);
583
802
  const headers = [
584
803
  {
585
804
  label: formatMessage({
@@ -628,12 +847,19 @@ const BulkLocalePublishAction = ({
628
847
  }, {});
629
848
  return [rowsFromMeta, errors];
630
849
  }, [document, documentMeta?.availableLocales, validate]);
631
- const localesToPublish = selectedRows.reduce((acc, selectedRow) => {
632
- if (selectedRow.status !== "published" && !Object.keys(validationErrors).includes(selectedRow.locale)) {
850
+ const isBulkPublish = action === "bulk-publish";
851
+ const localesForAction = selectedRows.reduce((acc, selectedRow) => {
852
+ const isValidLocale = (
853
+ // Validation errors are irrelevant if we are trying to unpublish
854
+ !isBulkPublish || !Object.keys(validationErrors).includes(selectedRow.locale)
855
+ );
856
+ const shouldAddLocale = isBulkPublish ? selectedRow.status !== "published" && isValidLocale : selectedRow.status !== "draft" && isValidLocale;
857
+ if (shouldAddLocale) {
633
858
  acc.push(selectedRow.locale);
634
859
  }
635
860
  return acc;
636
861
  }, []);
862
+ const enableDraftRelationsCount = false;
637
863
  const {
638
864
  data: draftRelationsCount = 0,
639
865
  isLoading: isDraftRelationsLoading,
@@ -642,10 +868,10 @@ const BulkLocalePublishAction = ({
642
868
  {
643
869
  model,
644
870
  documentIds: [documentId],
645
- locale: localesToPublish
871
+ locale: localesForAction
646
872
  },
647
873
  {
648
- skip: !documentId || localesToPublish.length === 0
874
+ skip: !enableDraftRelationsCount
649
875
  }
650
876
  );
651
877
  React__namespace.useEffect(() => {
@@ -671,23 +897,32 @@ const BulkLocalePublishAction = ({
671
897
  documentIds: [documentId],
672
898
  params: {
673
899
  ...params,
674
- locale: localesToPublish
900
+ locale: localesForAction
901
+ }
902
+ });
903
+ setSelectedRows([]);
904
+ };
905
+ const unpublish = async () => {
906
+ await unpublishManyAction({
907
+ model,
908
+ documentIds: [documentId],
909
+ params: {
910
+ ...params,
911
+ locale: localesForAction
675
912
  }
676
913
  });
677
914
  setSelectedRows([]);
678
915
  };
679
916
  const handleAction = async () => {
680
917
  if (draftRelationsCount > 0) {
681
- setIsConfirmationOpen(true);
682
- } else {
918
+ setIsDraftRelationConfirmationOpen(true);
919
+ } else if (isBulkPublish) {
683
920
  await publish();
921
+ } else {
922
+ await unpublish();
684
923
  }
685
924
  };
686
- const isUnpublish = document?.status === "published";
687
- if (isUnpublish) {
688
- console.warn(["I18N"], "Bulk locale unpublish modal not implemented");
689
- }
690
- if (isConfirmationOpen) {
925
+ if (isDraftRelationConfirmationOpen) {
691
926
  return {
692
927
  label: formatMessage({
693
928
  id: "app.components.ConfirmDialog.title",
@@ -696,11 +931,11 @@ const BulkLocalePublishAction = ({
696
931
  variant: "danger",
697
932
  dialog: {
698
933
  onCancel: () => {
699
- setIsConfirmationOpen(false);
934
+ setIsDraftRelationConfirmationOpen(false);
700
935
  },
701
936
  onConfirm: async () => {
702
937
  await publish();
703
- setIsConfirmationOpen(false);
938
+ setIsDraftRelationConfirmationOpen(false);
704
939
  },
705
940
  type: "dialog",
706
941
  title: formatMessage({
@@ -710,27 +945,32 @@ const BulkLocalePublishAction = ({
710
945
  content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "center", gap: 2, children: [
711
946
  /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, { width: "2.4rem", height: "2.4rem", fill: "danger600" }),
712
947
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", children: formatMessage({
713
- id: "content-manager.actions.discard.dialog.body",
714
- defaultMessage: "Are you sure you want to discard the changes? This action is irreversible."
948
+ id: getTranslation("CMEditViewBulkLocale.draft-relation-warning"),
949
+ defaultMessage: "Some locales are related to draft entries. Publishing them could leave broken links in your app."
950
+ }) }),
951
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", children: formatMessage({
952
+ id: getTranslation("CMEditViewBulkLocale.continue-confirmation"),
953
+ defaultMessage: "Are you sure you want to continue?"
715
954
  }) })
716
955
  ] })
717
956
  }
718
957
  };
719
958
  }
959
+ const hasPermission = selectedRows.map(({ locale }) => locale).every((locale) => canPublish.includes(locale));
720
960
  return {
721
961
  label: formatMessage({
722
- id: getTranslation("CMEditViewBulkLocale.publish-title"),
723
- defaultMessage: "Publish Multiple Locales"
962
+ id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
963
+ defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
724
964
  }),
725
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ListPlus, {}),
726
- disabled: isPublishedTab || !canPublish,
965
+ variant: isBulkPublish ? "secondary" : "danger",
966
+ icon: isBulkPublish ? /* @__PURE__ */ jsxRuntime.jsx(icons.ListPlus, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.Cross, {}),
967
+ disabled: isOnPublishedTab || canPublish.length === 0,
727
968
  position: ["panel"],
728
- variant: "secondary",
729
969
  dialog: {
730
970
  type: "modal",
731
971
  title: formatMessage({
732
- id: getTranslation("CMEditViewBulkLocale.publish-title"),
733
- defaultMessage: "Publish Multiple Locales"
972
+ id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
973
+ defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
734
974
  }),
735
975
  content: () => {
736
976
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -749,28 +989,35 @@ const BulkLocalePublishAction = ({
749
989
  validationErrors,
750
990
  headers,
751
991
  rows,
752
- localesMetadata
992
+ localesMetadata,
993
+ action: action ?? "bulk-publish"
753
994
  }
754
995
  )
755
996
  }
756
997
  );
757
998
  },
758
- footer: () => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxRuntime.jsx(
999
+ footer: () => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Footer, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxRuntime.jsx(
759
1000
  designSystem.Button,
760
1001
  {
761
1002
  loading: isDraftRelationsLoading,
762
- disabled: localesToPublish.length === 0,
1003
+ disabled: !hasPermission || localesForAction.length === 0,
763
1004
  variant: "default",
764
1005
  onClick: handleAction,
765
1006
  children: formatMessage({
766
- id: "app.utils.publish",
767
- defaultMessage: "Publish"
1007
+ id: isBulkPublish ? "app.utils.publish" : "app.utils.unpublish",
1008
+ defaultMessage: isBulkPublish ? "Publish" : "Unpublish"
768
1009
  })
769
1010
  }
770
1011
  ) })
771
1012
  }
772
1013
  };
773
1014
  };
1015
+ const BulkLocalePublishAction = (props) => {
1016
+ return BulkLocaleAction({ action: "bulk-publish", ...props });
1017
+ };
1018
+ const BulkLocaleUnpublishAction = (props) => {
1019
+ return BulkLocaleAction({ action: "bulk-unpublish", ...props });
1020
+ };
774
1021
  const StyledTrash = styledComponents.styled(icons.Trash)`
775
1022
  path {
776
1023
  fill: currentColor;
@@ -827,16 +1074,9 @@ const UnpublishModalAdditionalInfo = () => {
827
1074
  }
828
1075
  ) });
829
1076
  };
830
- const Initializer = ({ setPlugin }) => {
831
- const setPluginRef = React__namespace.useRef(setPlugin);
832
- React__namespace.useEffect(() => {
833
- setPluginRef.current(pluginId);
834
- }, []);
835
- return null;
836
- };
837
1077
  const LocalePicker = () => {
838
1078
  const { formatMessage } = reactIntl.useIntl();
839
- const [{ query }, setQuery] = strapiAdmin.useQueryParams();
1079
+ const [{ query: query2 }, setQuery] = strapiAdmin.useQueryParams();
840
1080
  const { hasI18n, canRead, canCreate } = useI18n();
841
1081
  const { data: locales = [] } = useGetLocalesQuery(void 0, {
842
1082
  skip: !hasI18n
@@ -846,25 +1086,25 @@ const LocalePicker = () => {
846
1086
  setQuery(
847
1087
  {
848
1088
  page: 1,
849
- plugins: { ...query.plugins, i18n: { locale: code } }
1089
+ plugins: { ...query2.plugins, i18n: { locale: code } }
850
1090
  },
851
1091
  "push",
852
1092
  replace
853
1093
  );
854
1094
  },
855
- [query.plugins, setQuery]
1095
+ [query2.plugins, setQuery]
856
1096
  );
857
1097
  React__namespace.useEffect(() => {
858
1098
  if (!Array.isArray(locales) || !hasI18n) {
859
1099
  return;
860
1100
  }
861
- const currentDesiredLocale = query.plugins?.i18n?.locale;
1101
+ const currentDesiredLocale = query2.plugins?.i18n?.locale;
862
1102
  const doesLocaleExist = locales.find((loc) => loc.code === currentDesiredLocale);
863
1103
  const defaultLocale = locales.find((locale) => locale.isDefault);
864
1104
  if (!doesLocaleExist && defaultLocale?.code) {
865
1105
  handleChange(defaultLocale.code, true);
866
1106
  }
867
- }, [hasI18n, handleChange, locales, query.plugins?.i18n?.locale]);
1107
+ }, [hasI18n, handleChange, locales, query2.plugins?.i18n?.locale]);
868
1108
  if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
869
1109
  return null;
870
1110
  }
@@ -879,7 +1119,7 @@ const LocalePicker = () => {
879
1119
  id: getTranslation("actions.select-locale"),
880
1120
  defaultMessage: "Select locale"
881
1121
  }),
882
- value: query.plugins?.i18n?.locale || locales.find((locale) => locale.isDefault)?.code,
1122
+ value: query2.plugins?.i18n?.locale || locales.find((locale) => locale.isDefault)?.code,
883
1123
  onChange: handleChange,
884
1124
  children: displayedLocales.map((locale) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: locale.code, children: locale.name }, locale.id))
885
1125
  }
@@ -893,7 +1133,7 @@ const PERMISSIONS = {
893
1133
  read: [{ action: "plugin::i18n.locale.read", subject: null }]
894
1134
  };
895
1135
  const mutateEditViewHook = ({ layout }) => {
896
- if ("i18n" in layout.options && typeof layout.options.i18n === "object" && layout.options.i18n !== null && "localized" in layout.options.i18n && !layout.options.i18n.localized) {
1136
+ if (!("i18n" in layout.options) || typeof layout.options.i18n === "object" && layout.options.i18n !== null && "localized" in layout.options.i18n && !layout.options.i18n.localized) {
897
1137
  return { layout };
898
1138
  }
899
1139
  const components = Object.entries(layout.components).reduce(
@@ -939,7 +1179,7 @@ const doesFieldHaveI18nPluginOpt = (pluginOpts) => {
939
1179
  const LabelAction = ({ title, icon }) => {
940
1180
  const { formatMessage } = reactIntl.useIntl();
941
1181
  return /* @__PURE__ */ jsxRuntime.jsxs(Span, { tag: "span", children: [
942
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { tag: "span", children: `(${formatMessage(title)})` }),
1182
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { tag: "span", children: formatMessage(title) }),
943
1183
  React__namespace.cloneElement(icon, {
944
1184
  "aria-hidden": true,
945
1185
  focusable: false
@@ -974,13 +1214,7 @@ const LocaleListCell = ({
974
1214
  }
975
1215
  });
976
1216
  const { locale: language } = reactIntl.useIntl();
977
- const [visible, setVisible] = React__namespace.useState(false);
978
- const buttonRef = React__namespace.useRef(null);
979
1217
  const { data: locales = [] } = useGetLocalesQuery();
980
- const handleTogglePopover = (e) => {
981
- e.stopPropagation();
982
- setVisible((prev) => !prev);
983
- };
984
1218
  const formatter = designSystem.useCollator(language, {
985
1219
  sensitivity: "base"
986
1220
  });
@@ -1002,64 +1236,14 @@ const LocaleListCell = ({
1002
1236
  }
1003
1237
  return locale.name;
1004
1238
  }).toSorted((a, b) => formatter.compare(a, b));
1005
- return /* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", onClick: handleTogglePopover, ref: buttonRef, children: [
1006
- /* @__PURE__ */ jsxRuntime.jsxs(
1007
- ActionWrapper,
1008
- {
1009
- minWidth: "100%",
1010
- alignItems: "center",
1011
- justifyContent: "center",
1012
- height: "3.2rem",
1013
- width: "3.2rem",
1014
- children: [
1015
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", ellipsis: true, children: localesForDocument.join(", ") }),
1016
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(icons.CaretDown, {}) })
1017
- ]
1018
- }
1019
- ),
1020
- visible && /* @__PURE__ */ jsxRuntime.jsx(
1021
- designSystem.Popover,
1022
- {
1023
- onDismiss: () => setVisible(false),
1024
- source: buttonRef,
1025
- spacing: 16,
1026
- centered: true,
1027
- 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)) })
1028
- }
1029
- )
1239
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Popover.Root, { children: [
1240
+ /* @__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: [
1241
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", ellipsis: true, marginRight: 2, children: localesForDocument.join(", ") }),
1242
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(icons.CaretDown, { width: "1.2rem", height: "1.2rem" }) })
1243
+ ] }) }) }),
1244
+ /* @__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)) }) })
1030
1245
  ] });
1031
1246
  };
1032
- const Button = styledComponents.styled.button`
1033
- width: 100%;
1034
-
1035
- svg {
1036
- > g,
1037
- path {
1038
- fill: ${({ theme }) => theme.colors.neutral500};
1039
- }
1040
- }
1041
- &:hover {
1042
- svg {
1043
- > g,
1044
- path {
1045
- fill: ${({ theme }) => theme.colors.neutral600};
1046
- }
1047
- }
1048
- }
1049
- &:active {
1050
- svg {
1051
- > g,
1052
- path {
1053
- fill: ${({ theme }) => theme.colors.neutral400};
1054
- }
1055
- }
1056
- }
1057
- `;
1058
- const ActionWrapper = styledComponents.styled(designSystem.Flex)`
1059
- svg {
1060
- height: 0.4rem;
1061
- }
1062
- `;
1063
1247
  const addColumnToTableHook = ({ displayedHeaders, layout }) => {
1064
1248
  const { options } = layout;
1065
1249
  const isFieldLocalized = doesPluginOptionsHaveI18nLocalized(options) ? options.i18n.localized : false;
@@ -1088,18 +1272,11 @@ const addColumnToTableHook = ({ displayedHeaders, layout }) => {
1088
1272
  const addLocaleToReleasesHook = ({ displayedHeaders = [] }) => {
1089
1273
  return {
1090
1274
  displayedHeaders: [
1091
- // TODO: Fix when migrating to v5
1092
- // ...displayedHeaders,
1275
+ ...displayedHeaders,
1093
1276
  {
1094
- key: "__locale__",
1095
- fieldSchema: { type: "string" },
1096
- metadatas: {
1097
- label: {
1098
- id: "content-releases.page.ReleaseDetails.table.header.label.locale",
1099
- defaultMessage: "locale"
1100
- },
1101
- searchable: false,
1102
- sortable: false
1277
+ label: {
1278
+ id: "content-releases.page.ReleaseDetails.table.header.label.locale",
1279
+ defaultMessage: "locale"
1103
1280
  },
1104
1281
  name: "locale"
1105
1282
  }
@@ -1247,8 +1424,6 @@ const index = {
1247
1424
  app.addRBACMiddleware([localeMiddleware]);
1248
1425
  app.registerPlugin({
1249
1426
  id: pluginId,
1250
- initializer: Initializer,
1251
- isReady: false,
1252
1427
  name: pluginId
1253
1428
  });
1254
1429
  },
@@ -1266,11 +1441,11 @@ const index = {
1266
1441
  },
1267
1442
  id: "internationalization",
1268
1443
  to: "internationalization",
1269
- Component: () => Promise.resolve().then(() => require("./SettingsPage-DnLLGeBa.js")).then((mod) => ({ default: mod.ProtectedSettingsPage })),
1444
+ Component: () => Promise.resolve().then(() => require("./SettingsPage-CfTmCkup.js")).then((mod) => ({ default: mod.ProtectedSettingsPage })),
1270
1445
  permissions: PERMISSIONS.accessMain
1271
1446
  });
1272
1447
  const contentManager = app.getPlugin("content-manager");
1273
- contentManager.apis.addDocumentHeaderAction([LocalePickerAction]);
1448
+ contentManager.apis.addDocumentHeaderAction([LocalePickerAction, FillFromAnotherLocaleAction]);
1274
1449
  contentManager.apis.addDocumentAction((actions) => {
1275
1450
  const indexOfDeleteAction = actions.findIndex((action) => action.type === "delete");
1276
1451
  actions.splice(indexOfDeleteAction, 0, DeleteLocaleAction);
@@ -1278,6 +1453,7 @@ const index = {
1278
1453
  });
1279
1454
  contentManager.apis.addDocumentAction((actions) => {
1280
1455
  actions.splice(2, 0, BulkLocalePublishAction);
1456
+ actions.splice(5, 0, BulkLocaleUnpublishAction);
1281
1457
  return actions;
1282
1458
  });
1283
1459
  contentManager.injectComponent("listView", "actions", {
@@ -1383,7 +1559,7 @@ const index = {
1383
1559
  async registerTrads({ locales }) {
1384
1560
  const importedTrads = await Promise.all(
1385
1561
  locales.map((locale) => {
1386
- 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 }) => {
1562
+ 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-DWpfm8h5.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 }) => {
1387
1563
  return {
1388
1564
  data: prefixPluginTranslations(data, pluginId),
1389
1565
  locale
@@ -1407,4 +1583,4 @@ exports.useDeleteLocaleMutation = useDeleteLocaleMutation;
1407
1583
  exports.useGetDefaultLocalesQuery = useGetDefaultLocalesQuery;
1408
1584
  exports.useGetLocalesQuery = useGetLocalesQuery;
1409
1585
  exports.useUpdateLocaleMutation = useUpdateLocaleMutation;
1410
- //# sourceMappingURL=index-DtEKsPcR.js.map
1586
+ //# sourceMappingURL=index-5XLZwzwx.js.map