@strapi/i18n 0.0.0-experimental.3c73a4c6f6073abdf1608121a200c3d4d87b1aa8 → 0.0.0-experimental.3d5794391d4c2d9eddf7bd162c02f4bb836eb7a6

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 (56) hide show
  1. package/LICENSE +18 -3
  2. package/dist/_chunks/{SettingsPage-DnLLGeBa.js → SettingsPage-D0hqaut-.js} +93 -106
  3. package/dist/_chunks/SettingsPage-D0hqaut-.js.map +1 -0
  4. package/dist/_chunks/{SettingsPage-0FFSTUW2.mjs → SettingsPage-D67CaQAB.mjs} +95 -108
  5. package/dist/_chunks/SettingsPage-D67CaQAB.mjs.map +1 -0
  6. package/dist/_chunks/{en-Kv6y9zPQ.js → en-BKBz3tro.js} +12 -3
  7. package/dist/_chunks/en-BKBz3tro.js.map +1 -0
  8. package/dist/_chunks/{en-18tWw4P6.mjs → en-DlXfy6Gy.mjs} +12 -3
  9. package/dist/_chunks/en-DlXfy6Gy.mjs.map +1 -0
  10. package/dist/_chunks/{index-DtEKsPcR.js → index-46DNtLCn.js} +454 -229
  11. package/dist/_chunks/index-46DNtLCn.js.map +1 -0
  12. package/dist/_chunks/{index-BddUXwss.mjs → index-CNR8i3KM.mjs} +448 -223
  13. package/dist/_chunks/index-CNR8i3KM.mjs.map +1 -0
  14. package/dist/admin/index.js +1 -1
  15. package/dist/admin/index.mjs +1 -1
  16. package/dist/admin/src/components/BulkLocaleActionModal.d.ts +2 -1
  17. package/dist/admin/src/components/CMHeaderActions.d.ts +29 -3
  18. package/dist/admin/src/components/CreateLocale.d.ts +6 -6
  19. package/dist/admin/src/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 +413 -480
  24. package/dist/server/index.js.map +1 -1
  25. package/dist/server/index.mjs +415 -482
  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 +21 -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 +20 -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/services/sanitize/index.d.ts +11 -0
  39. package/dist/server/src/services/sanitize/index.d.ts.map +1 -0
  40. package/dist/server/src/utils/index.d.ts +2 -2
  41. package/dist/server/src/utils/index.d.ts.map +1 -1
  42. package/package.json +12 -12
  43. package/dist/_chunks/SettingsPage-0FFSTUW2.mjs.map +0 -1
  44. package/dist/_chunks/SettingsPage-DnLLGeBa.js.map +0 -1
  45. package/dist/_chunks/en-18tWw4P6.mjs.map +0 -1
  46. package/dist/_chunks/en-Kv6y9zPQ.js.map +0 -1
  47. package/dist/_chunks/index-BddUXwss.mjs.map +0 -1
  48. package/dist/_chunks/index-DtEKsPcR.js.map +0 -1
  49. package/dist/admin/src/components/Initializer.d.ts +0 -5
  50. package/dist/server/src/migrations/content-type/disable/index.d.ts +0 -3
  51. package/dist/server/src/migrations/content-type/disable/index.d.ts.map +0 -1
  52. package/dist/server/src/migrations/content-type/enable/index.d.ts +0 -3
  53. package/dist/server/src/migrations/content-type/enable/index.d.ts.map +0 -1
  54. package/dist/server/src/services/entity-service-decorator.d.ts +0 -29
  55. package/dist/server/src/services/entity-service-decorator.d.ts.map +0 -1
  56. 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: [
@@ -363,13 +483,12 @@ const BulkLocaleActionModal = ({
363
483
  paddingRight: "6px",
364
484
  paddingTop: "2px",
365
485
  paddingBottom: "2px",
366
- showBullet: false,
367
486
  size: "S",
368
487
  variant: statusVariant,
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
  ) })
@@ -395,6 +514,47 @@ const BulkLocaleActionModal = ({
395
514
  ] }) })
396
515
  ] });
397
516
  };
517
+ const statusVariants = {
518
+ draft: "secondary",
519
+ published: "success",
520
+ modified: "alternative"
521
+ };
522
+ const LocaleOption = ({
523
+ isDraftAndPublishEnabled,
524
+ locale,
525
+ status,
526
+ entryExists
527
+ }) => {
528
+ const { formatMessage } = reactIntl.useIntl();
529
+ if (!entryExists) {
530
+ return formatMessage(
531
+ {
532
+ id: getTranslation("CMEditViewLocalePicker.locale.create"),
533
+ defaultMessage: "Create <bold>{locale}</bold> locale"
534
+ },
535
+ {
536
+ bold: (locale2) => /* @__PURE__ */ jsxRuntime.jsx("b", { children: locale2 }),
537
+ locale: locale.name
538
+ }
539
+ );
540
+ }
541
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", gap: 1, justifyContent: "space-between", children: [
542
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: locale.name }),
543
+ isDraftAndPublishEnabled ? /* @__PURE__ */ jsxRuntime.jsx(
544
+ designSystem.Status,
545
+ {
546
+ display: "flex",
547
+ paddingLeft: "6px",
548
+ paddingRight: "6px",
549
+ paddingTop: "2px",
550
+ paddingBottom: "2px",
551
+ size: "S",
552
+ variant: statusVariants[status],
553
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
554
+ }
555
+ ) : null
556
+ ] });
557
+ };
398
558
  const LocalePickerAction = ({
399
559
  document,
400
560
  meta,
@@ -403,74 +563,74 @@ const LocalePickerAction = ({
403
563
  documentId
404
564
  }) => {
405
565
  const { formatMessage } = reactIntl.useIntl();
406
- const [{ query }, setQuery] = strapiAdmin.useQueryParams();
566
+ const [{ query: query2 }, setQuery] = strapiAdmin.useQueryParams();
407
567
  const { hasI18n, canCreate, canRead } = useI18n();
408
568
  const { data: locales = [] } = useGetLocalesQuery();
409
- const { schema } = strapiAdmin$1.unstable_useDocument({ model, collectionType, documentId });
569
+ const currentDesiredLocale = query2.plugins?.i18n?.locale;
570
+ const { schema } = strapiAdmin$1.unstable_useDocument({
571
+ model,
572
+ collectionType,
573
+ documentId,
574
+ params: { locale: currentDesiredLocale }
575
+ });
410
576
  const handleSelect = React__namespace.useCallback(
411
577
  (value) => {
412
578
  setQuery({
413
579
  plugins: {
414
- ...query.plugins,
580
+ ...query2.plugins,
415
581
  i18n: {
416
582
  locale: value
417
583
  }
418
584
  }
419
585
  });
420
586
  },
421
- [query.plugins, setQuery]
587
+ [query2.plugins, setQuery]
422
588
  );
423
589
  React__namespace.useEffect(() => {
424
590
  if (!Array.isArray(locales) || !hasI18n) {
425
591
  return;
426
592
  }
427
- const currentDesiredLocale = query.plugins?.i18n?.locale;
428
593
  const doesLocaleExist = locales.find((loc) => loc.code === currentDesiredLocale);
429
594
  const defaultLocale = locales.find((locale) => locale.isDefault);
430
595
  if (!doesLocaleExist && defaultLocale?.code) {
431
596
  handleSelect(defaultLocale.code);
432
597
  }
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;
598
+ }, [handleSelect, hasI18n, locales, currentDesiredLocale]);
599
+ const currentLocale = Array.isArray(locales) ? locales.find((locale) => locale.code === currentDesiredLocale) : void 0;
438
600
  const allCurrentLocales = [
439
- { status: getDocumentStatus(document, meta), locale: currentLocale },
601
+ { status: getDocumentStatus(document, meta), locale: currentLocale?.code },
440
602
  ...meta?.availableLocales ?? []
441
603
  ];
604
+ if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
605
+ return null;
606
+ }
442
607
  return {
443
608
  label: formatMessage({
444
609
  id: getTranslation("Settings.locales.modal.locales.label"),
445
610
  defaultMessage: "Locales"
446
611
  }),
447
612
  options: locales.map((locale) => {
613
+ const entryWithLocaleExists = allCurrentLocales.some((doc) => doc.locale === locale.code);
448
614
  const currentLocaleDoc = allCurrentLocales.find(
449
615
  (doc) => "locale" in doc ? doc.locale === locale.code : false
450
616
  );
451
- const status = currentLocaleDoc?.status ?? "draft";
452
- const permissionsToCheck = currentLocaleDoc ? canCreate : canRead;
453
- const statusVariant = status === "draft" ? "primary" : status === "published" ? "success" : "alternative";
617
+ const permissionsToCheck = currentLocaleDoc ? canRead : canCreate;
454
618
  return {
455
619
  disabled: !permissionsToCheck.includes(locale.code),
456
620
  value: locale.code,
457
- label: locale.name,
458
- startIcon: schema?.options?.draftAndPublish ? /* @__PURE__ */ jsxRuntime.jsx(
459
- designSystem.Status,
621
+ label: /* @__PURE__ */ jsxRuntime.jsx(
622
+ LocaleOption,
460
623
  {
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) })
624
+ isDraftAndPublishEnabled: !!schema?.options?.draftAndPublish,
625
+ locale,
626
+ status: currentLocaleDoc?.status,
627
+ entryExists: entryWithLocaleExists
470
628
  }
471
- ) : null
629
+ ),
630
+ startIcon: !entryWithLocaleExists ? /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}) : null
472
631
  };
473
632
  }),
633
+ customizeContent: () => currentLocale?.name,
474
634
  onSelect: handleSelect,
475
635
  value: currentLocale
476
636
  };
@@ -486,6 +646,99 @@ const getDocumentStatus = (document, meta) => {
486
646
  }
487
647
  return docStatus;
488
648
  };
649
+ const FillFromAnotherLocaleAction = ({
650
+ documentId,
651
+ meta,
652
+ model,
653
+ collectionType
654
+ }) => {
655
+ const { formatMessage } = reactIntl.useIntl();
656
+ const [{ query: query2 }] = strapiAdmin.useQueryParams();
657
+ const { hasI18n } = useI18n();
658
+ const currentDesiredLocale = query2.plugins?.i18n?.locale;
659
+ const [localeSelected, setLocaleSelected] = React__namespace.useState(null);
660
+ const setValues = strapiAdmin.useForm("FillFromAnotherLocale", (state) => state.setValues);
661
+ const { getDocument } = strapiAdmin$1.unstable_useDocumentActions();
662
+ const { schema, components } = strapiAdmin$1.unstable_useDocument({
663
+ model,
664
+ documentId,
665
+ collectionType,
666
+ params: { locale: currentDesiredLocale }
667
+ });
668
+ const { data: locales = [] } = useGetLocalesQuery();
669
+ const availableLocales = Array.isArray(locales) ? locales.filter((locale) => meta?.availableLocales.some((l) => l.locale === locale.code)) : [];
670
+ const fillFromLocale = (onClose) => async () => {
671
+ const response = await getDocument({
672
+ collectionType,
673
+ model,
674
+ documentId,
675
+ params: { locale: localeSelected }
676
+ });
677
+ if (!response || !schema) {
678
+ return;
679
+ }
680
+ const { data } = response;
681
+ const cleanedData = cleanData(data, schema, components);
682
+ setValues(cleanedData);
683
+ onClose();
684
+ };
685
+ if (!hasI18n) {
686
+ return null;
687
+ }
688
+ return {
689
+ type: "icon",
690
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Download, {}),
691
+ disabled: availableLocales.length === 0,
692
+ label: formatMessage({
693
+ id: getTranslation("CMEditViewCopyLocale.copy-text"),
694
+ defaultMessage: "Fill in from another locale"
695
+ }),
696
+ dialog: {
697
+ type: "dialog",
698
+ title: formatMessage({
699
+ id: getTranslation("CMEditViewCopyLocale.dialog.title"),
700
+ defaultMessage: "Confirmation"
701
+ }),
702
+ content: ({ onClose }) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
703
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 3, children: [
704
+ /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
705
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", children: formatMessage({
706
+ id: getTranslation("CMEditViewCopyLocale.dialog.body"),
707
+ defaultMessage: "Your current content will be erased and filled by the content of the selected locale:"
708
+ }) }),
709
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { width: "100%", children: [
710
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
711
+ id: getTranslation("CMEditViewCopyLocale.dialog.field.label"),
712
+ defaultMessage: "Locale"
713
+ }) }),
714
+ /* @__PURE__ */ jsxRuntime.jsx(
715
+ designSystem.SingleSelect,
716
+ {
717
+ value: localeSelected,
718
+ placeholder: formatMessage({
719
+ id: getTranslation("CMEditViewCopyLocale.dialog.field.placeholder"),
720
+ defaultMessage: "Select one locale..."
721
+ }),
722
+ onChange: (value) => setLocaleSelected(value),
723
+ children: availableLocales.map((locale) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: locale.code, children: locale.name }, locale.code))
724
+ }
725
+ )
726
+ ] })
727
+ ] }) }),
728
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, width: "100%", children: [
729
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { flex: "auto", variant: "tertiary", onClick: onClose, children: formatMessage({
730
+ id: getTranslation("CMEditViewCopyLocale.cancel-text"),
731
+ defaultMessage: "No, cancel"
732
+ }) }),
733
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { flex: "auto", variant: "success", onClick: fillFromLocale(onClose), children: formatMessage({
734
+ id: getTranslation("CMEditViewCopyLocale.submit-text"),
735
+ defaultMessage: "Yes, fill in"
736
+ }) })
737
+ ] }) })
738
+ ] })
739
+ }
740
+ };
741
+ };
489
742
  const DeleteLocaleAction = ({
490
743
  document,
491
744
  documentId,
@@ -497,16 +750,23 @@ const DeleteLocaleAction = ({
497
750
  const { toggleNotification } = strapiAdmin.useNotification();
498
751
  const { delete: deleteAction } = strapiAdmin$1.unstable_useDocumentActions();
499
752
  const { hasI18n, canDelete } = useI18n();
753
+ const [{ query: query2 }] = strapiAdmin.useQueryParams();
754
+ const { data: locales = [] } = useGetLocalesQuery();
755
+ const currentDesiredLocale = query2.plugins?.i18n?.locale;
756
+ const locale = !("error" in locales) && locales.find((loc) => loc.code === currentDesiredLocale);
500
757
  if (!hasI18n) {
501
758
  return null;
502
759
  }
503
760
  return {
504
761
  disabled: document?.locale && !canDelete.includes(document.locale) || !document || !document.id,
505
762
  position: ["header", "table-row"],
506
- label: formatMessage({
507
- id: getTranslation("actions.delete.label"),
508
- defaultMessage: "Delete locale"
509
- }),
763
+ label: formatMessage(
764
+ {
765
+ id: getTranslation("actions.delete.label"),
766
+ defaultMessage: "Delete entry ({locale})"
767
+ },
768
+ { locale: locale && locale.name }
769
+ ),
510
770
  icon: /* @__PURE__ */ jsxRuntime.jsx(StyledTrash, {}),
511
771
  variant: "danger",
512
772
  dialog: {
@@ -523,7 +783,12 @@ const DeleteLocaleAction = ({
523
783
  }) })
524
784
  ] }),
525
785
  onConfirm: async () => {
526
- if (!documentId || !document?.locale) {
786
+ const unableToDelete = (
787
+ // We are unable to delete a collection type without a document ID
788
+ // & unable to delete generally if there is no document locale
789
+ collectionType !== "single-types" && !documentId || !document?.locale
790
+ );
791
+ if (unableToDelete) {
527
792
  console.error(
528
793
  "You're trying to delete a document without an id or locale, this is likely a bug with Strapi. Please open an issue."
529
794
  );
@@ -549,37 +814,43 @@ const DeleteLocaleAction = ({
549
814
  }
550
815
  };
551
816
  };
552
- const BulkLocalePublishAction = ({
817
+ const BulkLocaleAction = ({
553
818
  document: baseDocument,
554
819
  documentId,
555
820
  model,
556
- collectionType
821
+ collectionType,
822
+ action
557
823
  }) => {
558
824
  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";
825
+ const [{ query: query$1 }] = strapiAdmin.useQueryParams();
826
+ const params = React__namespace.useMemo(() => strapiAdmin$1.buildValidParams(query$1), [query$1]);
827
+ const isOnPublishedTab = query$1.status === "published";
562
828
  const { formatMessage } = reactIntl.useIntl();
563
829
  const { hasI18n, canPublish } = useI18n();
564
830
  const { toggleNotification } = strapiAdmin.useNotification();
565
831
  const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
566
832
  const [selectedRows, setSelectedRows] = React__namespace.useState([]);
567
- const [isConfirmationOpen, setIsConfirmationOpen] = React__namespace.useState(false);
568
- const { publishMany: publishManyAction } = strapiAdmin$1.unstable_useDocumentActions();
833
+ const [isDraftRelationConfirmationOpen, setIsDraftRelationConfirmationOpen] = React__namespace.useState(false);
834
+ const { publishMany: publishManyAction, unpublishMany: unpublishManyAction } = strapiAdmin$1.unstable_useDocumentActions();
569
835
  const {
570
836
  document,
571
837
  meta: documentMeta,
572
838
  schema,
573
839
  validate
574
- } = strapiAdmin$1.unstable_useDocument({
575
- model,
576
- collectionType,
577
- documentId,
578
- params: {
579
- locale: baseLocale
840
+ } = strapiAdmin$1.unstable_useDocument(
841
+ {
842
+ model,
843
+ collectionType,
844
+ documentId,
845
+ params: {
846
+ locale: baseLocale
847
+ }
848
+ },
849
+ {
850
+ skip: !hasI18n || !baseLocale
580
851
  }
581
- });
582
- const { data: localesMetadata = [] } = useGetLocalesQuery();
852
+ );
853
+ const { data: localesMetadata = [] } = useGetLocalesQuery(hasI18n ? void 0 : query.skipToken);
583
854
  const headers = [
584
855
  {
585
856
  label: formatMessage({
@@ -628,12 +899,19 @@ const BulkLocalePublishAction = ({
628
899
  }, {});
629
900
  return [rowsFromMeta, errors];
630
901
  }, [document, documentMeta?.availableLocales, validate]);
631
- const localesToPublish = selectedRows.reduce((acc, selectedRow) => {
632
- if (selectedRow.status !== "published" && !Object.keys(validationErrors).includes(selectedRow.locale)) {
902
+ const isBulkPublish = action === "bulk-publish";
903
+ const localesForAction = selectedRows.reduce((acc, selectedRow) => {
904
+ const isValidLocale = (
905
+ // Validation errors are irrelevant if we are trying to unpublish
906
+ !isBulkPublish || !Object.keys(validationErrors).includes(selectedRow.locale)
907
+ );
908
+ const shouldAddLocale = isBulkPublish ? selectedRow.status !== "published" && isValidLocale : selectedRow.status !== "draft" && isValidLocale;
909
+ if (shouldAddLocale) {
633
910
  acc.push(selectedRow.locale);
634
911
  }
635
912
  return acc;
636
913
  }, []);
914
+ const enableDraftRelationsCount = false;
637
915
  const {
638
916
  data: draftRelationsCount = 0,
639
917
  isLoading: isDraftRelationsLoading,
@@ -642,10 +920,10 @@ const BulkLocalePublishAction = ({
642
920
  {
643
921
  model,
644
922
  documentIds: [documentId],
645
- locale: localesToPublish
923
+ locale: localesForAction
646
924
  },
647
925
  {
648
- skip: !documentId || localesToPublish.length === 0
926
+ skip: !enableDraftRelationsCount
649
927
  }
650
928
  );
651
929
  React__namespace.useEffect(() => {
@@ -671,23 +949,32 @@ const BulkLocalePublishAction = ({
671
949
  documentIds: [documentId],
672
950
  params: {
673
951
  ...params,
674
- locale: localesToPublish
952
+ locale: localesForAction
953
+ }
954
+ });
955
+ setSelectedRows([]);
956
+ };
957
+ const unpublish = async () => {
958
+ await unpublishManyAction({
959
+ model,
960
+ documentIds: [documentId],
961
+ params: {
962
+ ...params,
963
+ locale: localesForAction
675
964
  }
676
965
  });
677
966
  setSelectedRows([]);
678
967
  };
679
968
  const handleAction = async () => {
680
969
  if (draftRelationsCount > 0) {
681
- setIsConfirmationOpen(true);
682
- } else {
970
+ setIsDraftRelationConfirmationOpen(true);
971
+ } else if (isBulkPublish) {
683
972
  await publish();
973
+ } else {
974
+ await unpublish();
684
975
  }
685
976
  };
686
- const isUnpublish = document?.status === "published";
687
- if (isUnpublish) {
688
- console.warn(["I18N"], "Bulk locale unpublish modal not implemented");
689
- }
690
- if (isConfirmationOpen) {
977
+ if (isDraftRelationConfirmationOpen) {
691
978
  return {
692
979
  label: formatMessage({
693
980
  id: "app.components.ConfirmDialog.title",
@@ -696,11 +983,11 @@ const BulkLocalePublishAction = ({
696
983
  variant: "danger",
697
984
  dialog: {
698
985
  onCancel: () => {
699
- setIsConfirmationOpen(false);
986
+ setIsDraftRelationConfirmationOpen(false);
700
987
  },
701
988
  onConfirm: async () => {
702
989
  await publish();
703
- setIsConfirmationOpen(false);
990
+ setIsDraftRelationConfirmationOpen(false);
704
991
  },
705
992
  type: "dialog",
706
993
  title: formatMessage({
@@ -710,27 +997,32 @@ const BulkLocalePublishAction = ({
710
997
  content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "center", gap: 2, children: [
711
998
  /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, { width: "2.4rem", height: "2.4rem", fill: "danger600" }),
712
999
  /* @__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."
1000
+ id: getTranslation("CMEditViewBulkLocale.draft-relation-warning"),
1001
+ defaultMessage: "Some locales are related to draft entries. Publishing them could leave broken links in your app."
1002
+ }) }),
1003
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", children: formatMessage({
1004
+ id: getTranslation("CMEditViewBulkLocale.continue-confirmation"),
1005
+ defaultMessage: "Are you sure you want to continue?"
715
1006
  }) })
716
1007
  ] })
717
1008
  }
718
1009
  };
719
1010
  }
1011
+ const hasPermission = selectedRows.map(({ locale }) => locale).every((locale) => canPublish.includes(locale));
720
1012
  return {
721
1013
  label: formatMessage({
722
- id: getTranslation("CMEditViewBulkLocale.publish-title"),
723
- defaultMessage: "Publish Multiple Locales"
1014
+ id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
1015
+ defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
724
1016
  }),
725
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ListPlus, {}),
726
- disabled: isPublishedTab || !canPublish,
1017
+ variant: isBulkPublish ? "secondary" : "danger",
1018
+ icon: isBulkPublish ? /* @__PURE__ */ jsxRuntime.jsx(icons.ListPlus, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.Cross, {}),
1019
+ disabled: isOnPublishedTab || canPublish.length === 0,
727
1020
  position: ["panel"],
728
- variant: "secondary",
729
1021
  dialog: {
730
1022
  type: "modal",
731
1023
  title: formatMessage({
732
- id: getTranslation("CMEditViewBulkLocale.publish-title"),
733
- defaultMessage: "Publish Multiple Locales"
1024
+ id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
1025
+ defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
734
1026
  }),
735
1027
  content: () => {
736
1028
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -749,28 +1041,35 @@ const BulkLocalePublishAction = ({
749
1041
  validationErrors,
750
1042
  headers,
751
1043
  rows,
752
- localesMetadata
1044
+ localesMetadata,
1045
+ action: action ?? "bulk-publish"
753
1046
  }
754
1047
  )
755
1048
  }
756
1049
  );
757
1050
  },
758
- footer: () => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxRuntime.jsx(
1051
+ footer: () => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Footer, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxRuntime.jsx(
759
1052
  designSystem.Button,
760
1053
  {
761
1054
  loading: isDraftRelationsLoading,
762
- disabled: localesToPublish.length === 0,
1055
+ disabled: !hasPermission || localesForAction.length === 0,
763
1056
  variant: "default",
764
1057
  onClick: handleAction,
765
1058
  children: formatMessage({
766
- id: "app.utils.publish",
767
- defaultMessage: "Publish"
1059
+ id: isBulkPublish ? "app.utils.publish" : "app.utils.unpublish",
1060
+ defaultMessage: isBulkPublish ? "Publish" : "Unpublish"
768
1061
  })
769
1062
  }
770
1063
  ) })
771
1064
  }
772
1065
  };
773
1066
  };
1067
+ const BulkLocalePublishAction = (props) => {
1068
+ return BulkLocaleAction({ action: "bulk-publish", ...props });
1069
+ };
1070
+ const BulkLocaleUnpublishAction = (props) => {
1071
+ return BulkLocaleAction({ action: "bulk-unpublish", ...props });
1072
+ };
774
1073
  const StyledTrash = styledComponents.styled(icons.Trash)`
775
1074
  path {
776
1075
  fill: currentColor;
@@ -827,16 +1126,9 @@ const UnpublishModalAdditionalInfo = () => {
827
1126
  }
828
1127
  ) });
829
1128
  };
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
1129
  const LocalePicker = () => {
838
1130
  const { formatMessage } = reactIntl.useIntl();
839
- const [{ query }, setQuery] = strapiAdmin.useQueryParams();
1131
+ const [{ query: query2 }, setQuery] = strapiAdmin.useQueryParams();
840
1132
  const { hasI18n, canRead, canCreate } = useI18n();
841
1133
  const { data: locales = [] } = useGetLocalesQuery(void 0, {
842
1134
  skip: !hasI18n
@@ -846,25 +1138,25 @@ const LocalePicker = () => {
846
1138
  setQuery(
847
1139
  {
848
1140
  page: 1,
849
- plugins: { ...query.plugins, i18n: { locale: code } }
1141
+ plugins: { ...query2.plugins, i18n: { locale: code } }
850
1142
  },
851
1143
  "push",
852
1144
  replace
853
1145
  );
854
1146
  },
855
- [query.plugins, setQuery]
1147
+ [query2.plugins, setQuery]
856
1148
  );
857
1149
  React__namespace.useEffect(() => {
858
1150
  if (!Array.isArray(locales) || !hasI18n) {
859
1151
  return;
860
1152
  }
861
- const currentDesiredLocale = query.plugins?.i18n?.locale;
1153
+ const currentDesiredLocale = query2.plugins?.i18n?.locale;
862
1154
  const doesLocaleExist = locales.find((loc) => loc.code === currentDesiredLocale);
863
1155
  const defaultLocale = locales.find((locale) => locale.isDefault);
864
1156
  if (!doesLocaleExist && defaultLocale?.code) {
865
1157
  handleChange(defaultLocale.code, true);
866
1158
  }
867
- }, [hasI18n, handleChange, locales, query.plugins?.i18n?.locale]);
1159
+ }, [hasI18n, handleChange, locales, query2.plugins?.i18n?.locale]);
868
1160
  if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
869
1161
  return null;
870
1162
  }
@@ -879,7 +1171,7 @@ const LocalePicker = () => {
879
1171
  id: getTranslation("actions.select-locale"),
880
1172
  defaultMessage: "Select locale"
881
1173
  }),
882
- value: query.plugins?.i18n?.locale || locales.find((locale) => locale.isDefault)?.code,
1174
+ value: query2.plugins?.i18n?.locale || locales.find((locale) => locale.isDefault)?.code,
883
1175
  onChange: handleChange,
884
1176
  children: displayedLocales.map((locale) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: locale.code, children: locale.name }, locale.id))
885
1177
  }
@@ -893,7 +1185,7 @@ const PERMISSIONS = {
893
1185
  read: [{ action: "plugin::i18n.locale.read", subject: null }]
894
1186
  };
895
1187
  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) {
1188
+ if (!("i18n" in layout.options) || typeof layout.options.i18n === "object" && layout.options.i18n !== null && "localized" in layout.options.i18n && !layout.options.i18n.localized) {
897
1189
  return { layout };
898
1190
  }
899
1191
  const components = Object.entries(layout.components).reduce(
@@ -939,7 +1231,7 @@ const doesFieldHaveI18nPluginOpt = (pluginOpts) => {
939
1231
  const LabelAction = ({ title, icon }) => {
940
1232
  const { formatMessage } = reactIntl.useIntl();
941
1233
  return /* @__PURE__ */ jsxRuntime.jsxs(Span, { tag: "span", children: [
942
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { tag: "span", children: `(${formatMessage(title)})` }),
1234
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { tag: "span", children: formatMessage(title) }),
943
1235
  React__namespace.cloneElement(icon, {
944
1236
  "aria-hidden": true,
945
1237
  focusable: false
@@ -974,13 +1266,7 @@ const LocaleListCell = ({
974
1266
  }
975
1267
  });
976
1268
  const { locale: language } = reactIntl.useIntl();
977
- const [visible, setVisible] = React__namespace.useState(false);
978
- const buttonRef = React__namespace.useRef(null);
979
1269
  const { data: locales = [] } = useGetLocalesQuery();
980
- const handleTogglePopover = (e) => {
981
- e.stopPropagation();
982
- setVisible((prev) => !prev);
983
- };
984
1270
  const formatter = designSystem.useCollator(language, {
985
1271
  sensitivity: "base"
986
1272
  });
@@ -1002,64 +1288,14 @@ const LocaleListCell = ({
1002
1288
  }
1003
1289
  return locale.name;
1004
1290
  }).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
- )
1291
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Popover.Root, { children: [
1292
+ /* @__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: [
1293
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", ellipsis: true, marginRight: 2, children: localesForDocument.join(", ") }),
1294
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(icons.CaretDown, { width: "1.2rem", height: "1.2rem" }) })
1295
+ ] }) }) }),
1296
+ /* @__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
1297
  ] });
1031
1298
  };
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
1299
  const addColumnToTableHook = ({ displayedHeaders, layout }) => {
1064
1300
  const { options } = layout;
1065
1301
  const isFieldLocalized = doesPluginOptionsHaveI18nLocalized(options) ? options.i18n.localized : false;
@@ -1088,18 +1324,11 @@ const addColumnToTableHook = ({ displayedHeaders, layout }) => {
1088
1324
  const addLocaleToReleasesHook = ({ displayedHeaders = [] }) => {
1089
1325
  return {
1090
1326
  displayedHeaders: [
1091
- // TODO: Fix when migrating to v5
1092
- // ...displayedHeaders,
1327
+ ...displayedHeaders,
1093
1328
  {
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
1329
+ label: {
1330
+ id: "content-releases.page.ReleaseDetails.table.header.label.locale",
1331
+ defaultMessage: "locale"
1103
1332
  },
1104
1333
  name: "locale"
1105
1334
  }
@@ -1192,9 +1421,6 @@ const localeMiddleware = (ctx) => (next) => (permissions) => {
1192
1421
  return next(revisedPermissions);
1193
1422
  };
1194
1423
  const prefixPluginTranslations = (trad, pluginId2) => {
1195
- if (!pluginId2) {
1196
- throw new TypeError("pluginId can't be empty");
1197
- }
1198
1424
  return Object.keys(trad).reduce((acc, current) => {
1199
1425
  acc[`${pluginId2}.${current}`] = trad[current];
1200
1426
  return acc;
@@ -1247,8 +1473,6 @@ const index = {
1247
1473
  app.addRBACMiddleware([localeMiddleware]);
1248
1474
  app.registerPlugin({
1249
1475
  id: pluginId,
1250
- initializer: Initializer,
1251
- isReady: false,
1252
1476
  name: pluginId
1253
1477
  });
1254
1478
  },
@@ -1266,11 +1490,11 @@ const index = {
1266
1490
  },
1267
1491
  id: "internationalization",
1268
1492
  to: "internationalization",
1269
- Component: () => Promise.resolve().then(() => require("./SettingsPage-DnLLGeBa.js")).then((mod) => ({ default: mod.ProtectedSettingsPage })),
1493
+ Component: () => Promise.resolve().then(() => require("./SettingsPage-D0hqaut-.js")).then((mod) => ({ default: mod.ProtectedSettingsPage })),
1270
1494
  permissions: PERMISSIONS.accessMain
1271
1495
  });
1272
1496
  const contentManager = app.getPlugin("content-manager");
1273
- contentManager.apis.addDocumentHeaderAction([LocalePickerAction]);
1497
+ contentManager.apis.addDocumentHeaderAction([LocalePickerAction, FillFromAnotherLocaleAction]);
1274
1498
  contentManager.apis.addDocumentAction((actions) => {
1275
1499
  const indexOfDeleteAction = actions.findIndex((action) => action.type === "delete");
1276
1500
  actions.splice(indexOfDeleteAction, 0, DeleteLocaleAction);
@@ -1278,6 +1502,7 @@ const index = {
1278
1502
  });
1279
1503
  contentManager.apis.addDocumentAction((actions) => {
1280
1504
  actions.splice(2, 0, BulkLocalePublishAction);
1505
+ actions.splice(5, 0, BulkLocaleUnpublishAction);
1281
1506
  return actions;
1282
1507
  });
1283
1508
  contentManager.injectComponent("listView", "actions", {
@@ -1383,7 +1608,7 @@ const index = {
1383
1608
  async registerTrads({ locales }) {
1384
1609
  const importedTrads = await Promise.all(
1385
1610
  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 }) => {
1611
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/de.json": () => Promise.resolve().then(() => require("./de-DtWiGdHl.js")), "./translations/dk.json": () => Promise.resolve().then(() => require("./dk-D8C-casx.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-BKBz3tro.js")), "./translations/es.json": () => Promise.resolve().then(() => require("./es-DS-XFGSw.js")), "./translations/fr.json": () => Promise.resolve().then(() => require("./fr-BTjekDpq.js")), "./translations/ko.json": () => Promise.resolve().then(() => require("./ko-DmcGUBQ3.js")), "./translations/pl.json": () => Promise.resolve().then(() => require("./pl-Cn5RYonZ.js")), "./translations/ru.json": () => Promise.resolve().then(() => require("./ru-BMBgVL3s.js")), "./translations/tr.json": () => Promise.resolve().then(() => require("./tr-CarUU76c.js")), "./translations/zh-Hans.json": () => Promise.resolve().then(() => require("./zh-Hans-DSHIXAa3.js")), "./translations/zh.json": () => Promise.resolve().then(() => require("./zh-CukOviB0.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
1387
1612
  return {
1388
1613
  data: prefixPluginTranslations(data, pluginId),
1389
1614
  locale
@@ -1407,4 +1632,4 @@ exports.useDeleteLocaleMutation = useDeleteLocaleMutation;
1407
1632
  exports.useGetDefaultLocalesQuery = useGetDefaultLocalesQuery;
1408
1633
  exports.useGetLocalesQuery = useGetLocalesQuery;
1409
1634
  exports.useUpdateLocaleMutation = useUpdateLocaleMutation;
1410
- //# sourceMappingURL=index-DtEKsPcR.js.map
1635
+ //# sourceMappingURL=index-46DNtLCn.js.map