@strapi/i18n 0.0.0-experimental.f75e3c6d67cc47c64ab37479efdbb7b43be50b78 → 0.0.0-next.ce84fada19d58a7dfbdd553035e6558f8befcba4

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 (54) hide show
  1. package/LICENSE +18 -3
  2. package/dist/_chunks/{SettingsPage-0FFSTUW2.mjs → SettingsPage-DbRFoF_H.mjs} +95 -108
  3. package/dist/_chunks/SettingsPage-DbRFoF_H.mjs.map +1 -0
  4. package/dist/_chunks/{SettingsPage-DnLLGeBa.js → SettingsPage-uGJv15wR.js} +93 -106
  5. package/dist/_chunks/SettingsPage-uGJv15wR.js.map +1 -0
  6. package/dist/_chunks/{en-18tWw4P6.mjs → en-BYRZFDBV.mjs} +11 -2
  7. package/dist/_chunks/en-BYRZFDBV.mjs.map +1 -0
  8. package/dist/_chunks/{en-Kv6y9zPQ.js → en-Dk9At9_Z.js} +11 -2
  9. package/dist/_chunks/en-Dk9At9_Z.js.map +1 -0
  10. package/dist/_chunks/{index-BddUXwss.mjs → index-7_EUScSl.mjs} +445 -219
  11. package/dist/_chunks/index-7_EUScSl.mjs.map +1 -0
  12. package/dist/_chunks/{index-DtEKsPcR.js → index-BGtXLYX-.js} +451 -225
  13. package/dist/_chunks/index-BGtXLYX-.js.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/components/EditLocale.d.ts +5 -4
  20. package/dist/admin/src/contentReleasesHooks/releaseDetailsView.d.ts +9 -5
  21. package/dist/admin/src/utils/clean.d.ts +4 -0
  22. package/dist/admin/src/utils/schemas.d.ts +1 -0
  23. package/dist/server/index.js +397 -487
  24. package/dist/server/index.js.map +1 -1
  25. package/dist/server/index.mjs +398 -488
  26. package/dist/server/index.mjs.map +1 -1
  27. package/dist/server/src/bootstrap.d.ts +1 -4
  28. package/dist/server/src/bootstrap.d.ts.map +1 -1
  29. package/dist/server/src/index.d.ts +15 -13
  30. package/dist/server/src/index.d.ts.map +1 -1
  31. package/dist/server/src/register.d.ts.map +1 -1
  32. package/dist/server/src/services/index.d.ts +14 -10
  33. package/dist/server/src/services/index.d.ts.map +1 -1
  34. package/dist/server/src/services/permissions/actions.d.ts +14 -2
  35. package/dist/server/src/services/permissions/actions.d.ts.map +1 -1
  36. package/dist/server/src/services/permissions.d.ts +14 -2
  37. package/dist/server/src/services/permissions.d.ts.map +1 -1
  38. package/dist/server/src/utils/index.d.ts +0 -2
  39. package/dist/server/src/utils/index.d.ts.map +1 -1
  40. package/package.json +9 -9
  41. package/dist/_chunks/SettingsPage-0FFSTUW2.mjs.map +0 -1
  42. package/dist/_chunks/SettingsPage-DnLLGeBa.js.map +0 -1
  43. package/dist/_chunks/en-18tWw4P6.mjs.map +0 -1
  44. package/dist/_chunks/en-Kv6y9zPQ.js.map +0 -1
  45. package/dist/_chunks/index-BddUXwss.mjs.map +0 -1
  46. package/dist/_chunks/index-DtEKsPcR.js.map +0 -1
  47. package/dist/admin/src/components/Initializer.d.ts +0 -5
  48. package/dist/server/src/migrations/content-type/disable/index.d.ts +0 -3
  49. package/dist/server/src/migrations/content-type/disable/index.d.ts.map +0 -1
  50. package/dist/server/src/migrations/content-type/enable/index.d.ts +0 -3
  51. package/dist/server/src/migrations/content-type/enable/index.d.ts.map +0 -1
  52. package/dist/server/src/services/entity-service-decorator.d.ts +0 -29
  53. package/dist/server/src/services/entity-service-decorator.d.ts.map +0 -1
  54. 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");
@@ -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,94 @@ 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
+ "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
+ };
244
324
  const isErrorMessageDescriptor = (object) => {
245
325
  return typeof object === "object" && object !== null && "id" in object && "defaultMessage" in object;
246
326
  };
247
- const EntryValidationText = ({ status = "draft", validationErrors }) => {
327
+ const EntryValidationText = ({
328
+ status = "draft",
329
+ validationErrors,
330
+ action
331
+ }) => {
248
332
  const { formatMessage } = reactIntl.useIntl();
249
333
  const getErrorStr = (key, value) => {
250
334
  if (typeof value === "string") {
@@ -278,30 +362,63 @@ const EntryValidationText = ({ status = "draft", validationErrors }) => {
278
362
  ) })
279
363
  ] });
280
364
  }
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
- }
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();
299
419
  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
- }) })
420
+ icon,
421
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor, fontWeight, children: text })
305
422
  ] });
306
423
  };
307
424
  const BoldChunk = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
@@ -309,7 +426,8 @@ const BulkLocaleActionModal = ({
309
426
  headers,
310
427
  rows,
311
428
  localesMetadata,
312
- validationErrors = {}
429
+ validationErrors = {},
430
+ action
313
431
  }) => {
314
432
  const { formatMessage } = reactIntl.useIntl();
315
433
  const selectedRows = strapiAdmin.useTable(
@@ -322,27 +440,29 @@ const BulkLocaleActionModal = ({
322
440
  return acc;
323
441
  }, {});
324
442
  const localesWithErrors = Object.keys(validationErrors);
325
- const alreadyPublishedCount = selectedRows.filter(
443
+ const publishedCount = selectedRows.filter(
326
444
  ({ locale }) => currentStatusByLocale[locale] === "published"
327
445
  ).length;
328
- const readyToPublishCount = selectedRows.filter(
446
+ const draftCount = selectedRows.filter(
329
447
  ({ locale }) => (currentStatusByLocale[locale] === "draft" || currentStatusByLocale[locale] === "modified") && !localesWithErrors.includes(locale)
330
448
  ).length;
331
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.";
332
452
  return formatMessage(
333
453
  {
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."
454
+ id: messageId,
455
+ defaultMessage
336
456
  },
337
457
  {
338
458
  withErrorsCount,
339
- readyToPublishCount,
340
- alreadyPublishedCount,
459
+ draftCount,
460
+ publishedCount,
341
461
  b: BoldChunk
342
462
  }
343
463
  );
344
464
  };
345
- return /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
465
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Body, { children: [
346
466
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: getFormattedCountMessage() }),
347
467
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 5, children: /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Content, { children: [
348
468
  /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Head, { children: [
@@ -369,7 +489,7 @@ const BulkLocaleActionModal = ({
369
489
  children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
370
490
  }
371
491
  ) }) }),
372
- /* @__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 }) }),
373
493
  /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(
374
494
  designSystem.IconButton,
375
495
  {
@@ -386,7 +506,7 @@ const BulkLocaleActionModal = ({
386
506
  name: locale
387
507
  }
388
508
  ),
389
- borderWidth: 0,
509
+ variant: "ghost",
390
510
  children: /* @__PURE__ */ jsxRuntime.jsx(icons.Pencil, {})
391
511
  }
392
512
  ) })
@@ -395,6 +515,48 @@ const BulkLocaleActionModal = ({
395
515
  ] }) })
396
516
  ] });
397
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
+ };
398
560
  const LocalePickerAction = ({
399
561
  document,
400
562
  meta,
@@ -403,74 +565,74 @@ const LocalePickerAction = ({
403
565
  documentId
404
566
  }) => {
405
567
  const { formatMessage } = reactIntl.useIntl();
406
- const [{ query }, setQuery] = strapiAdmin.useQueryParams();
568
+ const [{ query: query2 }, setQuery] = strapiAdmin.useQueryParams();
407
569
  const { hasI18n, canCreate, canRead } = useI18n();
408
570
  const { data: locales = [] } = useGetLocalesQuery();
409
- 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
+ });
410
578
  const handleSelect = React__namespace.useCallback(
411
579
  (value) => {
412
580
  setQuery({
413
581
  plugins: {
414
- ...query.plugins,
582
+ ...query2.plugins,
415
583
  i18n: {
416
584
  locale: value
417
585
  }
418
586
  }
419
587
  });
420
588
  },
421
- [query.plugins, setQuery]
589
+ [query2.plugins, setQuery]
422
590
  );
423
591
  React__namespace.useEffect(() => {
424
592
  if (!Array.isArray(locales) || !hasI18n) {
425
593
  return;
426
594
  }
427
- const currentDesiredLocale = query.plugins?.i18n?.locale;
428
595
  const doesLocaleExist = locales.find((loc) => loc.code === currentDesiredLocale);
429
596
  const defaultLocale = locales.find((locale) => locale.isDefault);
430
597
  if (!doesLocaleExist && defaultLocale?.code) {
431
598
  handleSelect(defaultLocale.code);
432
599
  }
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;
600
+ }, [handleSelect, hasI18n, locales, currentDesiredLocale]);
601
+ const currentLocale = Array.isArray(locales) ? locales.find((locale) => locale.code === currentDesiredLocale) : void 0;
438
602
  const allCurrentLocales = [
439
- { status: getDocumentStatus(document, meta), locale: currentLocale },
603
+ { status: getDocumentStatus(document, meta), locale: currentLocale?.code },
440
604
  ...meta?.availableLocales ?? []
441
605
  ];
606
+ if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
607
+ return null;
608
+ }
442
609
  return {
443
610
  label: formatMessage({
444
611
  id: getTranslation("Settings.locales.modal.locales.label"),
445
612
  defaultMessage: "Locales"
446
613
  }),
447
614
  options: locales.map((locale) => {
615
+ const entryWithLocaleExists = allCurrentLocales.some((doc) => doc.locale === locale.code);
448
616
  const currentLocaleDoc = allCurrentLocales.find(
449
617
  (doc) => "locale" in doc ? doc.locale === locale.code : false
450
618
  );
451
- const status = currentLocaleDoc?.status ?? "draft";
452
- const permissionsToCheck = currentLocaleDoc ? canCreate : canRead;
453
- const statusVariant = status === "draft" ? "primary" : status === "published" ? "success" : "alternative";
619
+ const permissionsToCheck = currentLocaleDoc ? canRead : canCreate;
454
620
  return {
455
621
  disabled: !permissionsToCheck.includes(locale.code),
456
622
  value: locale.code,
457
- label: locale.name,
458
- startIcon: schema?.options?.draftAndPublish ? /* @__PURE__ */ jsxRuntime.jsx(
459
- designSystem.Status,
623
+ label: /* @__PURE__ */ jsxRuntime.jsx(
624
+ LocaleOption,
460
625
  {
461
- display: "flex",
462
- paddingLeft: "6px",
463
- paddingRight: "6px",
464
- paddingTop: "2px",
465
- paddingBottom: "2px",
466
- showBullet: false,
467
- size: "S",
468
- variant: statusVariant,
469
- 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
470
630
  }
471
- ) : null
631
+ ),
632
+ startIcon: !entryWithLocaleExists ? /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}) : null
472
633
  };
473
634
  }),
635
+ customizeContent: () => currentLocale?.name,
474
636
  onSelect: handleSelect,
475
637
  value: currentLocale
476
638
  };
@@ -486,6 +648,95 @@ const getDocumentStatus = (document, meta) => {
486
648
  }
487
649
  return docStatus;
488
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 currentDesiredLocale = query2.plugins?.i18n?.locale;
660
+ const [localeSelected, setLocaleSelected] = React__namespace.useState(null);
661
+ const setValues = strapiAdmin.useForm("FillFromAnotherLocale", (state) => state.setValues);
662
+ const { getDocument } = strapiAdmin$1.unstable_useDocumentActions();
663
+ const { schema, components } = strapiAdmin$1.unstable_useDocument({
664
+ model,
665
+ documentId,
666
+ collectionType,
667
+ params: { locale: currentDesiredLocale }
668
+ });
669
+ const { data: locales = [] } = useGetLocalesQuery();
670
+ const availableLocales = Array.isArray(locales) ? locales.filter((locale) => meta?.availableLocales.some((l) => l.locale === locale.code)) : [];
671
+ const fillFromLocale = (onClose) => async () => {
672
+ const response = await getDocument({
673
+ collectionType,
674
+ model,
675
+ documentId,
676
+ params: { locale: localeSelected }
677
+ });
678
+ if (!response || !schema) {
679
+ return;
680
+ }
681
+ const { data } = response;
682
+ const cleanedData = cleanData(data, schema, components);
683
+ setValues(cleanedData);
684
+ onClose();
685
+ };
686
+ return {
687
+ type: "icon",
688
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Download, {}),
689
+ disabled: availableLocales.length === 0,
690
+ label: formatMessage({
691
+ id: getTranslation("CMEditViewCopyLocale.copy-text"),
692
+ defaultMessage: "Fill in from another locale"
693
+ }),
694
+ dialog: {
695
+ type: "dialog",
696
+ title: formatMessage({
697
+ id: getTranslation("CMEditViewCopyLocale.dialog.title"),
698
+ defaultMessage: "Confirmation"
699
+ }),
700
+ content: ({ onClose }) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
701
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 3, children: [
702
+ /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
703
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", children: formatMessage({
704
+ id: getTranslation("CMEditViewCopyLocale.dialog.body"),
705
+ defaultMessage: "Your current content will be erased and filled by the content of the selected locale:"
706
+ }) }),
707
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { width: "100%", children: [
708
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
709
+ id: getTranslation("CMEditViewCopyLocale.dialog.field.label"),
710
+ defaultMessage: "Locale"
711
+ }) }),
712
+ /* @__PURE__ */ jsxRuntime.jsx(
713
+ designSystem.SingleSelect,
714
+ {
715
+ value: localeSelected,
716
+ placeholder: formatMessage({
717
+ id: getTranslation("CMEditViewCopyLocale.dialog.field.placeholder"),
718
+ defaultMessage: "Select one locale..."
719
+ }),
720
+ onChange: (value) => setLocaleSelected(value),
721
+ children: availableLocales.map((locale) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: locale.code, children: locale.name }, locale.code))
722
+ }
723
+ )
724
+ ] })
725
+ ] }) }),
726
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, width: "100%", children: [
727
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { flex: "auto", variant: "tertiary", onClick: onClose, children: formatMessage({
728
+ id: getTranslation("CMEditViewCopyLocale.cancel-text"),
729
+ defaultMessage: "No, cancel"
730
+ }) }),
731
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { flex: "auto", variant: "success", onClick: fillFromLocale(onClose), children: formatMessage({
732
+ id: getTranslation("CMEditViewCopyLocale.submit-text"),
733
+ defaultMessage: "Yes, fill in"
734
+ }) })
735
+ ] }) })
736
+ ] })
737
+ }
738
+ };
739
+ };
489
740
  const DeleteLocaleAction = ({
490
741
  document,
491
742
  documentId,
@@ -497,16 +748,23 @@ const DeleteLocaleAction = ({
497
748
  const { toggleNotification } = strapiAdmin.useNotification();
498
749
  const { delete: deleteAction } = strapiAdmin$1.unstable_useDocumentActions();
499
750
  const { hasI18n, canDelete } = useI18n();
751
+ const [{ query: query2 }] = strapiAdmin.useQueryParams();
752
+ const { data: locales = [] } = useGetLocalesQuery();
753
+ const currentDesiredLocale = query2.plugins?.i18n?.locale;
754
+ const locale = !("error" in locales) && locales.find((loc) => loc.code === currentDesiredLocale);
500
755
  if (!hasI18n) {
501
756
  return null;
502
757
  }
503
758
  return {
504
759
  disabled: document?.locale && !canDelete.includes(document.locale) || !document || !document.id,
505
760
  position: ["header", "table-row"],
506
- label: formatMessage({
507
- id: getTranslation("actions.delete.label"),
508
- defaultMessage: "Delete locale"
509
- }),
761
+ label: formatMessage(
762
+ {
763
+ id: getTranslation("actions.delete.label"),
764
+ defaultMessage: "Delete entry ({locale})"
765
+ },
766
+ { locale: locale && locale.name }
767
+ ),
510
768
  icon: /* @__PURE__ */ jsxRuntime.jsx(StyledTrash, {}),
511
769
  variant: "danger",
512
770
  dialog: {
@@ -523,7 +781,12 @@ const DeleteLocaleAction = ({
523
781
  }) })
524
782
  ] }),
525
783
  onConfirm: async () => {
526
- if (!documentId || !document?.locale) {
784
+ const unableToDelete = (
785
+ // We are unable to delete a collection type without a document ID
786
+ // & unable to delete generally if there is no document locale
787
+ collectionType !== "single-types" && !documentId || !document?.locale
788
+ );
789
+ if (unableToDelete) {
527
790
  console.error(
528
791
  "You're trying to delete a document without an id or locale, this is likely a bug with Strapi. Please open an issue."
529
792
  );
@@ -549,37 +812,43 @@ const DeleteLocaleAction = ({
549
812
  }
550
813
  };
551
814
  };
552
- const BulkLocalePublishAction = ({
815
+ const BulkLocaleAction = ({
553
816
  document: baseDocument,
554
817
  documentId,
555
818
  model,
556
- collectionType
819
+ collectionType,
820
+ action
557
821
  }) => {
558
822
  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";
823
+ const [{ query: query$1 }] = strapiAdmin.useQueryParams();
824
+ const params = React__namespace.useMemo(() => strapiAdmin$1.buildValidParams(query$1), [query$1]);
825
+ const isOnPublishedTab = query$1.status === "published";
562
826
  const { formatMessage } = reactIntl.useIntl();
563
827
  const { hasI18n, canPublish } = useI18n();
564
828
  const { toggleNotification } = strapiAdmin.useNotification();
565
829
  const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
566
830
  const [selectedRows, setSelectedRows] = React__namespace.useState([]);
567
- const [isConfirmationOpen, setIsConfirmationOpen] = React__namespace.useState(false);
568
- const { publishMany: publishManyAction } = strapiAdmin$1.unstable_useDocumentActions();
831
+ const [isDraftRelationConfirmationOpen, setIsDraftRelationConfirmationOpen] = React__namespace.useState(false);
832
+ const { publishMany: publishManyAction, unpublishMany: unpublishManyAction } = strapiAdmin$1.unstable_useDocumentActions();
569
833
  const {
570
834
  document,
571
835
  meta: documentMeta,
572
836
  schema,
573
837
  validate
574
- } = strapiAdmin$1.unstable_useDocument({
575
- model,
576
- collectionType,
577
- documentId,
578
- params: {
579
- locale: baseLocale
838
+ } = strapiAdmin$1.unstable_useDocument(
839
+ {
840
+ model,
841
+ collectionType,
842
+ documentId,
843
+ params: {
844
+ locale: baseLocale
845
+ }
846
+ },
847
+ {
848
+ skip: !hasI18n || !baseLocale
580
849
  }
581
- });
582
- const { data: localesMetadata = [] } = useGetLocalesQuery();
850
+ );
851
+ const { data: localesMetadata = [] } = useGetLocalesQuery(hasI18n ? void 0 : query.skipToken);
583
852
  const headers = [
584
853
  {
585
854
  label: formatMessage({
@@ -628,12 +897,19 @@ const BulkLocalePublishAction = ({
628
897
  }, {});
629
898
  return [rowsFromMeta, errors];
630
899
  }, [document, documentMeta?.availableLocales, validate]);
631
- const localesToPublish = selectedRows.reduce((acc, selectedRow) => {
632
- if (selectedRow.status !== "published" && !Object.keys(validationErrors).includes(selectedRow.locale)) {
900
+ const isBulkPublish = action === "bulk-publish";
901
+ const localesForAction = selectedRows.reduce((acc, selectedRow) => {
902
+ const isValidLocale = (
903
+ // Validation errors are irrelevant if we are trying to unpublish
904
+ !isBulkPublish || !Object.keys(validationErrors).includes(selectedRow.locale)
905
+ );
906
+ const shouldAddLocale = isBulkPublish ? selectedRow.status !== "published" && isValidLocale : selectedRow.status !== "draft" && isValidLocale;
907
+ if (shouldAddLocale) {
633
908
  acc.push(selectedRow.locale);
634
909
  }
635
910
  return acc;
636
911
  }, []);
912
+ const enableDraftRelationsCount = false;
637
913
  const {
638
914
  data: draftRelationsCount = 0,
639
915
  isLoading: isDraftRelationsLoading,
@@ -642,10 +918,10 @@ const BulkLocalePublishAction = ({
642
918
  {
643
919
  model,
644
920
  documentIds: [documentId],
645
- locale: localesToPublish
921
+ locale: localesForAction
646
922
  },
647
923
  {
648
- skip: !documentId || localesToPublish.length === 0
924
+ skip: !enableDraftRelationsCount
649
925
  }
650
926
  );
651
927
  React__namespace.useEffect(() => {
@@ -671,23 +947,32 @@ const BulkLocalePublishAction = ({
671
947
  documentIds: [documentId],
672
948
  params: {
673
949
  ...params,
674
- locale: localesToPublish
950
+ locale: localesForAction
951
+ }
952
+ });
953
+ setSelectedRows([]);
954
+ };
955
+ const unpublish = async () => {
956
+ await unpublishManyAction({
957
+ model,
958
+ documentIds: [documentId],
959
+ params: {
960
+ ...params,
961
+ locale: localesForAction
675
962
  }
676
963
  });
677
964
  setSelectedRows([]);
678
965
  };
679
966
  const handleAction = async () => {
680
967
  if (draftRelationsCount > 0) {
681
- setIsConfirmationOpen(true);
682
- } else {
968
+ setIsDraftRelationConfirmationOpen(true);
969
+ } else if (isBulkPublish) {
683
970
  await publish();
971
+ } else {
972
+ await unpublish();
684
973
  }
685
974
  };
686
- const isUnpublish = document?.status === "published";
687
- if (isUnpublish) {
688
- console.warn(["I18N"], "Bulk locale unpublish modal not implemented");
689
- }
690
- if (isConfirmationOpen) {
975
+ if (isDraftRelationConfirmationOpen) {
691
976
  return {
692
977
  label: formatMessage({
693
978
  id: "app.components.ConfirmDialog.title",
@@ -696,11 +981,11 @@ const BulkLocalePublishAction = ({
696
981
  variant: "danger",
697
982
  dialog: {
698
983
  onCancel: () => {
699
- setIsConfirmationOpen(false);
984
+ setIsDraftRelationConfirmationOpen(false);
700
985
  },
701
986
  onConfirm: async () => {
702
987
  await publish();
703
- setIsConfirmationOpen(false);
988
+ setIsDraftRelationConfirmationOpen(false);
704
989
  },
705
990
  type: "dialog",
706
991
  title: formatMessage({
@@ -710,27 +995,32 @@ const BulkLocalePublishAction = ({
710
995
  content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "center", gap: 2, children: [
711
996
  /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, { width: "2.4rem", height: "2.4rem", fill: "danger600" }),
712
997
  /* @__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."
998
+ id: getTranslation("CMEditViewBulkLocale.draft-relation-warning"),
999
+ defaultMessage: "Some locales are related to draft entries. Publishing them could leave broken links in your app."
1000
+ }) }),
1001
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", children: formatMessage({
1002
+ id: getTranslation("CMEditViewBulkLocale.continue-confirmation"),
1003
+ defaultMessage: "Are you sure you want to continue?"
715
1004
  }) })
716
1005
  ] })
717
1006
  }
718
1007
  };
719
1008
  }
1009
+ const hasPermission = selectedRows.map(({ locale }) => locale).every((locale) => canPublish.includes(locale));
720
1010
  return {
721
1011
  label: formatMessage({
722
- id: getTranslation("CMEditViewBulkLocale.publish-title"),
723
- defaultMessage: "Publish Multiple Locales"
1012
+ id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
1013
+ defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
724
1014
  }),
725
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ListPlus, {}),
726
- disabled: isPublishedTab || !canPublish,
1015
+ variant: isBulkPublish ? "secondary" : "danger",
1016
+ icon: isBulkPublish ? /* @__PURE__ */ jsxRuntime.jsx(icons.ListPlus, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.Cross, {}),
1017
+ disabled: isOnPublishedTab || canPublish.length === 0,
727
1018
  position: ["panel"],
728
- variant: "secondary",
729
1019
  dialog: {
730
1020
  type: "modal",
731
1021
  title: formatMessage({
732
- id: getTranslation("CMEditViewBulkLocale.publish-title"),
733
- defaultMessage: "Publish Multiple Locales"
1022
+ id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
1023
+ defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
734
1024
  }),
735
1025
  content: () => {
736
1026
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -749,28 +1039,35 @@ const BulkLocalePublishAction = ({
749
1039
  validationErrors,
750
1040
  headers,
751
1041
  rows,
752
- localesMetadata
1042
+ localesMetadata,
1043
+ action: action ?? "bulk-publish"
753
1044
  }
754
1045
  )
755
1046
  }
756
1047
  );
757
1048
  },
758
- footer: () => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxRuntime.jsx(
1049
+ footer: () => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Footer, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxRuntime.jsx(
759
1050
  designSystem.Button,
760
1051
  {
761
1052
  loading: isDraftRelationsLoading,
762
- disabled: localesToPublish.length === 0,
1053
+ disabled: !hasPermission || localesForAction.length === 0,
763
1054
  variant: "default",
764
1055
  onClick: handleAction,
765
1056
  children: formatMessage({
766
- id: "app.utils.publish",
767
- defaultMessage: "Publish"
1057
+ id: isBulkPublish ? "app.utils.publish" : "app.utils.unpublish",
1058
+ defaultMessage: isBulkPublish ? "Publish" : "Unpublish"
768
1059
  })
769
1060
  }
770
1061
  ) })
771
1062
  }
772
1063
  };
773
1064
  };
1065
+ const BulkLocalePublishAction = (props) => {
1066
+ return BulkLocaleAction({ action: "bulk-publish", ...props });
1067
+ };
1068
+ const BulkLocaleUnpublishAction = (props) => {
1069
+ return BulkLocaleAction({ action: "bulk-unpublish", ...props });
1070
+ };
774
1071
  const StyledTrash = styledComponents.styled(icons.Trash)`
775
1072
  path {
776
1073
  fill: currentColor;
@@ -827,16 +1124,9 @@ const UnpublishModalAdditionalInfo = () => {
827
1124
  }
828
1125
  ) });
829
1126
  };
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
1127
  const LocalePicker = () => {
838
1128
  const { formatMessage } = reactIntl.useIntl();
839
- const [{ query }, setQuery] = strapiAdmin.useQueryParams();
1129
+ const [{ query: query2 }, setQuery] = strapiAdmin.useQueryParams();
840
1130
  const { hasI18n, canRead, canCreate } = useI18n();
841
1131
  const { data: locales = [] } = useGetLocalesQuery(void 0, {
842
1132
  skip: !hasI18n
@@ -846,25 +1136,25 @@ const LocalePicker = () => {
846
1136
  setQuery(
847
1137
  {
848
1138
  page: 1,
849
- plugins: { ...query.plugins, i18n: { locale: code } }
1139
+ plugins: { ...query2.plugins, i18n: { locale: code } }
850
1140
  },
851
1141
  "push",
852
1142
  replace
853
1143
  );
854
1144
  },
855
- [query.plugins, setQuery]
1145
+ [query2.plugins, setQuery]
856
1146
  );
857
1147
  React__namespace.useEffect(() => {
858
1148
  if (!Array.isArray(locales) || !hasI18n) {
859
1149
  return;
860
1150
  }
861
- const currentDesiredLocale = query.plugins?.i18n?.locale;
1151
+ const currentDesiredLocale = query2.plugins?.i18n?.locale;
862
1152
  const doesLocaleExist = locales.find((loc) => loc.code === currentDesiredLocale);
863
1153
  const defaultLocale = locales.find((locale) => locale.isDefault);
864
1154
  if (!doesLocaleExist && defaultLocale?.code) {
865
1155
  handleChange(defaultLocale.code, true);
866
1156
  }
867
- }, [hasI18n, handleChange, locales, query.plugins?.i18n?.locale]);
1157
+ }, [hasI18n, handleChange, locales, query2.plugins?.i18n?.locale]);
868
1158
  if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
869
1159
  return null;
870
1160
  }
@@ -879,7 +1169,7 @@ const LocalePicker = () => {
879
1169
  id: getTranslation("actions.select-locale"),
880
1170
  defaultMessage: "Select locale"
881
1171
  }),
882
- value: query.plugins?.i18n?.locale || locales.find((locale) => locale.isDefault)?.code,
1172
+ value: query2.plugins?.i18n?.locale || locales.find((locale) => locale.isDefault)?.code,
883
1173
  onChange: handleChange,
884
1174
  children: displayedLocales.map((locale) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: locale.code, children: locale.name }, locale.id))
885
1175
  }
@@ -893,7 +1183,7 @@ const PERMISSIONS = {
893
1183
  read: [{ action: "plugin::i18n.locale.read", subject: null }]
894
1184
  };
895
1185
  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) {
1186
+ if (!("i18n" in layout.options) || typeof layout.options.i18n === "object" && layout.options.i18n !== null && "localized" in layout.options.i18n && !layout.options.i18n.localized) {
897
1187
  return { layout };
898
1188
  }
899
1189
  const components = Object.entries(layout.components).reduce(
@@ -939,7 +1229,7 @@ const doesFieldHaveI18nPluginOpt = (pluginOpts) => {
939
1229
  const LabelAction = ({ title, icon }) => {
940
1230
  const { formatMessage } = reactIntl.useIntl();
941
1231
  return /* @__PURE__ */ jsxRuntime.jsxs(Span, { tag: "span", children: [
942
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { tag: "span", children: `(${formatMessage(title)})` }),
1232
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { tag: "span", children: formatMessage(title) }),
943
1233
  React__namespace.cloneElement(icon, {
944
1234
  "aria-hidden": true,
945
1235
  focusable: false
@@ -974,13 +1264,7 @@ const LocaleListCell = ({
974
1264
  }
975
1265
  });
976
1266
  const { locale: language } = reactIntl.useIntl();
977
- const [visible, setVisible] = React__namespace.useState(false);
978
- const buttonRef = React__namespace.useRef(null);
979
1267
  const { data: locales = [] } = useGetLocalesQuery();
980
- const handleTogglePopover = (e) => {
981
- e.stopPropagation();
982
- setVisible((prev) => !prev);
983
- };
984
1268
  const formatter = designSystem.useCollator(language, {
985
1269
  sensitivity: "base"
986
1270
  });
@@ -1002,64 +1286,14 @@ const LocaleListCell = ({
1002
1286
  }
1003
1287
  return locale.name;
1004
1288
  }).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
- )
1289
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Popover.Root, { children: [
1290
+ /* @__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: [
1291
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", ellipsis: true, marginRight: 2, children: localesForDocument.join(", ") }),
1292
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(icons.CaretDown, { width: "1.2rem", height: "1.2rem" }) })
1293
+ ] }) }) }),
1294
+ /* @__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
1295
  ] });
1031
1296
  };
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
1297
  const addColumnToTableHook = ({ displayedHeaders, layout }) => {
1064
1298
  const { options } = layout;
1065
1299
  const isFieldLocalized = doesPluginOptionsHaveI18nLocalized(options) ? options.i18n.localized : false;
@@ -1088,18 +1322,11 @@ const addColumnToTableHook = ({ displayedHeaders, layout }) => {
1088
1322
  const addLocaleToReleasesHook = ({ displayedHeaders = [] }) => {
1089
1323
  return {
1090
1324
  displayedHeaders: [
1091
- // TODO: Fix when migrating to v5
1092
- // ...displayedHeaders,
1325
+ ...displayedHeaders,
1093
1326
  {
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
1327
+ label: {
1328
+ id: "content-releases.page.ReleaseDetails.table.header.label.locale",
1329
+ defaultMessage: "locale"
1103
1330
  },
1104
1331
  name: "locale"
1105
1332
  }
@@ -1247,8 +1474,6 @@ const index = {
1247
1474
  app.addRBACMiddleware([localeMiddleware]);
1248
1475
  app.registerPlugin({
1249
1476
  id: pluginId,
1250
- initializer: Initializer,
1251
- isReady: false,
1252
1477
  name: pluginId
1253
1478
  });
1254
1479
  },
@@ -1266,11 +1491,11 @@ const index = {
1266
1491
  },
1267
1492
  id: "internationalization",
1268
1493
  to: "internationalization",
1269
- Component: () => Promise.resolve().then(() => require("./SettingsPage-DnLLGeBa.js")).then((mod) => ({ default: mod.ProtectedSettingsPage })),
1494
+ Component: () => Promise.resolve().then(() => require("./SettingsPage-uGJv15wR.js")).then((mod) => ({ default: mod.ProtectedSettingsPage })),
1270
1495
  permissions: PERMISSIONS.accessMain
1271
1496
  });
1272
1497
  const contentManager = app.getPlugin("content-manager");
1273
- contentManager.apis.addDocumentHeaderAction([LocalePickerAction]);
1498
+ contentManager.apis.addDocumentHeaderAction([LocalePickerAction, FillFromAnotherLocaleAction]);
1274
1499
  contentManager.apis.addDocumentAction((actions) => {
1275
1500
  const indexOfDeleteAction = actions.findIndex((action) => action.type === "delete");
1276
1501
  actions.splice(indexOfDeleteAction, 0, DeleteLocaleAction);
@@ -1278,6 +1503,7 @@ const index = {
1278
1503
  });
1279
1504
  contentManager.apis.addDocumentAction((actions) => {
1280
1505
  actions.splice(2, 0, BulkLocalePublishAction);
1506
+ actions.splice(5, 0, BulkLocaleUnpublishAction);
1281
1507
  return actions;
1282
1508
  });
1283
1509
  contentManager.injectComponent("listView", "actions", {
@@ -1383,7 +1609,7 @@ const index = {
1383
1609
  async registerTrads({ locales }) {
1384
1610
  const importedTrads = await Promise.all(
1385
1611
  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 }) => {
1612
+ 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-Dk9At9_Z.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
1613
  return {
1388
1614
  data: prefixPluginTranslations(data, pluginId),
1389
1615
  locale
@@ -1407,4 +1633,4 @@ exports.useDeleteLocaleMutation = useDeleteLocaleMutation;
1407
1633
  exports.useGetDefaultLocalesQuery = useGetDefaultLocalesQuery;
1408
1634
  exports.useGetLocalesQuery = useGetLocalesQuery;
1409
1635
  exports.useUpdateLocaleMutation = useUpdateLocaleMutation;
1410
- //# sourceMappingURL=index-DtEKsPcR.js.map
1636
+ //# sourceMappingURL=index-BGtXLYX-.js.map