@strapi/i18n 0.0.0-experimental.826f263c58b6886b849d3f03b81f7a530bc51c91 → 0.0.0-experimental.93181c8b900e97a04bf10785b368657101ec98d8

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 (40) hide show
  1. package/LICENSE +18 -3
  2. package/dist/_chunks/{SettingsPage-DnLLGeBa.js → SettingsPage-C-1h_H38.js} +91 -104
  3. package/dist/_chunks/SettingsPage-C-1h_H38.js.map +1 -0
  4. package/dist/_chunks/{SettingsPage-0FFSTUW2.mjs → SettingsPage-CPNFX0bZ.mjs} +93 -106
  5. package/dist/_chunks/SettingsPage-CPNFX0bZ.mjs.map +1 -0
  6. package/dist/_chunks/{en-18tWw4P6.mjs → en-CtekP_47.mjs} +4 -1
  7. package/dist/_chunks/en-CtekP_47.mjs.map +1 -0
  8. package/dist/_chunks/{en-Kv6y9zPQ.js → en-CwI88-PP.js} +4 -1
  9. package/dist/_chunks/en-CwI88-PP.js.map +1 -0
  10. package/dist/_chunks/{index-BddUXwss.mjs → index-CgjpU2bY.mjs} +191 -188
  11. package/dist/_chunks/index-CgjpU2bY.mjs.map +1 -0
  12. package/dist/_chunks/{index-DtEKsPcR.js → index-jpk39Rxo.js} +201 -198
  13. package/dist/_chunks/index-jpk39Rxo.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 +2 -1
  18. package/dist/admin/src/components/EditLocale.d.ts +5 -4
  19. package/dist/admin/src/contentReleasesHooks/releaseDetailsView.d.ts +9 -5
  20. package/dist/admin/src/utils/schemas.d.ts +1 -0
  21. package/dist/server/index.js +37 -8
  22. package/dist/server/index.js.map +1 -1
  23. package/dist/server/index.mjs +38 -9
  24. package/dist/server/index.mjs.map +1 -1
  25. package/dist/server/src/index.d.ts +14 -2
  26. package/dist/server/src/index.d.ts.map +1 -1
  27. package/dist/server/src/services/index.d.ts +14 -2
  28. package/dist/server/src/services/index.d.ts.map +1 -1
  29. package/dist/server/src/services/permissions/actions.d.ts +14 -2
  30. package/dist/server/src/services/permissions/actions.d.ts.map +1 -1
  31. package/dist/server/src/services/permissions.d.ts +14 -2
  32. package/dist/server/src/services/permissions.d.ts.map +1 -1
  33. package/package.json +9 -9
  34. package/dist/_chunks/SettingsPage-0FFSTUW2.mjs.map +0 -1
  35. package/dist/_chunks/SettingsPage-DnLLGeBa.js.map +0 -1
  36. package/dist/_chunks/en-18tWw4P6.mjs.map +0 -1
  37. package/dist/_chunks/en-Kv6y9zPQ.js.map +0 -1
  38. package/dist/_chunks/index-BddUXwss.mjs.map +0 -1
  39. package/dist/_chunks/index-DtEKsPcR.js.map +0 -1
  40. package/dist/admin/src/components/Initializer.d.ts +0 -5
@@ -7,6 +7,7 @@ const designSystem = require("@strapi/design-system");
7
7
  const icons = require("@strapi/icons");
8
8
  const reactIntl = require("react-intl");
9
9
  const styledComponents = require("styled-components");
10
+ const query = require("@reduxjs/toolkit/query");
10
11
  const strapiAdmin = require("@strapi/admin/strapi-admin");
11
12
  const strapiAdmin$1 = require("@strapi/content-manager/strapi-admin");
12
13
  const reactRouterDom = require("react-router-dom");
@@ -71,9 +72,7 @@ const CheckboxConfirmation = ({
71
72
  };
72
73
  const handleConfirm = () => {
73
74
  onChange({ target: { name, value: false, type: "checkbox" } });
74
- setIsOpen(false);
75
75
  };
76
- const handleToggle = () => setIsOpen((prev) => !prev);
77
76
  const label = intlLabel.id ? formatMessage(
78
77
  { id: intlLabel.id, defaultMessage: intlLabel.defaultMessage },
79
78
  { ...intlLabel.values }
@@ -82,35 +81,36 @@ const CheckboxConfirmation = ({
82
81
  { id: description.id, defaultMessage: description.defaultMessage },
83
82
  { ...description.values }
84
83
  ) : "";
85
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
84
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Root, { open: isOpen, onOpenChange: setIsOpen, children: [
86
85
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { hint, name, children: [
87
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Checkbox, { onValueChange: handleChange, value, type: "checkbox", children: label }),
86
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Checkbox, { onCheckedChange: handleChange, checked: value, children: label }),
88
87
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {})
89
88
  ] }),
90
- isOpen && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog, { onClose: handleToggle, title: "Confirmation", isOpen, children: [
91
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.DialogBody, { icon: /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, {}), children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
92
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(TextAlignTypography, { id: "confirm-description", children: formatMessage({
89
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
90
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: formatMessage({
91
+ id: getTranslation("CheckboxConfirmation.Modal.title"),
92
+ defaultMessage: "Disable localization"
93
+ }) }),
94
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { icon: /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, {}), children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
95
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(TextAlignTypography, { children: formatMessage({
93
96
  id: getTranslation("CheckboxConfirmation.Modal.content"),
94
97
  defaultMessage: "Disabling localization will engender the deletion of all your content but the one associated to your default locale (if existing)."
95
98
  }) }) }),
96
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", id: "confirm-description", children: formatMessage({
99
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", children: formatMessage({
97
100
  id: getTranslation("CheckboxConfirmation.Modal.body"),
98
101
  defaultMessage: "Do you want to disable it?"
99
102
  }) }) })
100
103
  ] }) }),
101
- /* @__PURE__ */ jsxRuntime.jsx(
102
- designSystem.DialogFooter,
103
- {
104
- startAction: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleToggle, variant: "tertiary", children: formatMessage({
105
- id: "components.popUpWarning.button.cancel",
106
- defaultMessage: "No, cancel"
107
- }) }),
108
- endAction: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "danger-light", onClick: handleConfirm, children: formatMessage({
109
- id: getTranslation("CheckboxConfirmation.Modal.button-confirm"),
110
- defaultMessage: "Yes, disable"
111
- }) })
112
- }
113
- )
104
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
105
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", children: formatMessage({
106
+ id: "components.popUpWarning.button.cancel",
107
+ defaultMessage: "No, cancel"
108
+ }) }) }),
109
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Action, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "danger-light", onClick: handleConfirm, children: formatMessage({
110
+ id: getTranslation("CheckboxConfirmation.Modal.button-confirm"),
111
+ defaultMessage: "Yes, disable"
112
+ }) }) })
113
+ ] })
114
114
  ] })
115
115
  ] });
116
116
  };
@@ -161,7 +161,7 @@ const useI18n = () => {
161
161
  model: params.slug
162
162
  },
163
163
  {
164
- skip: !params.slug || !params.collectionType
164
+ skip: true
165
165
  }
166
166
  );
167
167
  if (doesPluginOptionsHaveI18nLocalized(schema?.pluginOptions)) {
@@ -244,7 +244,11 @@ const { useGetManyDraftRelationCountQuery } = relationsApi;
244
244
  const isErrorMessageDescriptor = (object) => {
245
245
  return typeof object === "object" && object !== null && "id" in object && "defaultMessage" in object;
246
246
  };
247
- const EntryValidationText = ({ status = "draft", validationErrors }) => {
247
+ const EntryValidationText = ({
248
+ status = "draft",
249
+ validationErrors,
250
+ action
251
+ }) => {
248
252
  const { formatMessage } = reactIntl.useIntl();
249
253
  const getErrorStr = (key, value) => {
250
254
  if (typeof value === "string") {
@@ -278,30 +282,63 @@ const EntryValidationText = ({ status = "draft", validationErrors }) => {
278
282
  ) })
279
283
  ] });
280
284
  }
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
- }
285
+ const getStatusMessage = () => {
286
+ if (action === "bulk-publish") {
287
+ if (status === "published") {
288
+ return {
289
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
290
+ text: formatMessage({
291
+ id: "content-manager.bulk-publish.already-published",
292
+ defaultMessage: "Already Published"
293
+ }),
294
+ textColor: "success600",
295
+ fontWeight: "bold"
296
+ };
297
+ } else if (status === "modified") {
298
+ return {
299
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowsCounterClockwise, { fill: "alternative600" }),
300
+ text: formatMessage({
301
+ id: "app.utils.ready-to-publish-changes",
302
+ defaultMessage: "Ready to publish changes"
303
+ })
304
+ };
305
+ } else {
306
+ return {
307
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
308
+ text: formatMessage({
309
+ id: "app.utils.ready-to-publish",
310
+ defaultMessage: "Ready to publish"
311
+ })
312
+ };
313
+ }
314
+ } else {
315
+ if (status === "draft") {
316
+ return {
317
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
318
+ text: formatMessage({
319
+ id: "content-manager.bulk-unpublish.already-unpublished",
320
+ defaultMessage: "Already Unpublished"
321
+ }),
322
+ textColor: "success600",
323
+ fontWeight: "bold"
324
+ };
325
+ } else {
326
+ return {
327
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
328
+ text: formatMessage({
329
+ id: "app.utils.ready-to-unpublish-changes",
330
+ defaultMessage: "Ready to unpublish"
331
+ }),
332
+ textColor: "success600",
333
+ fontWeight: "bold"
334
+ };
335
+ }
336
+ }
337
+ };
338
+ const { icon, text, textColor = "success600", fontWeight = "normal" } = getStatusMessage();
299
339
  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
- }) })
340
+ icon,
341
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor, fontWeight, children: text })
305
342
  ] });
306
343
  };
307
344
  const BoldChunk = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
@@ -309,7 +346,8 @@ const BulkLocaleActionModal = ({
309
346
  headers,
310
347
  rows,
311
348
  localesMetadata,
312
- validationErrors = {}
349
+ validationErrors = {},
350
+ action
313
351
  }) => {
314
352
  const { formatMessage } = reactIntl.useIntl();
315
353
  const selectedRows = strapiAdmin.useTable(
@@ -322,27 +360,29 @@ const BulkLocaleActionModal = ({
322
360
  return acc;
323
361
  }, {});
324
362
  const localesWithErrors = Object.keys(validationErrors);
325
- const alreadyPublishedCount = selectedRows.filter(
363
+ const publishedCount = selectedRows.filter(
326
364
  ({ locale }) => currentStatusByLocale[locale] === "published"
327
365
  ).length;
328
- const readyToPublishCount = selectedRows.filter(
366
+ const draftCount = selectedRows.filter(
329
367
  ({ locale }) => (currentStatusByLocale[locale] === "draft" || currentStatusByLocale[locale] === "modified") && !localesWithErrors.includes(locale)
330
368
  ).length;
331
369
  const withErrorsCount = localesWithErrors.length;
370
+ const messageId = action === "bulk-publish" ? "content-manager.containers.list.selectedEntriesModal.selectedCount.publish" : "content-manager.containers.list.selectedEntriesModal.selectedCount.unpublish";
371
+ 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
372
  return formatMessage(
333
373
  {
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."
374
+ id: messageId,
375
+ defaultMessage
336
376
  },
337
377
  {
338
378
  withErrorsCount,
339
- readyToPublishCount,
340
- alreadyPublishedCount,
379
+ draftCount,
380
+ publishedCount,
341
381
  b: BoldChunk
342
382
  }
343
383
  );
344
384
  };
345
- return /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
385
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Body, { children: [
346
386
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: getFormattedCountMessage() }),
347
387
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 5, children: /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Content, { children: [
348
388
  /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Head, { children: [
@@ -369,7 +409,7 @@ const BulkLocaleActionModal = ({
369
409
  children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
370
410
  }
371
411
  ) }) }),
372
- /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(EntryValidationText, { validationErrors: error, status }) }),
412
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(EntryValidationText, { validationErrors: error, status, action }) }),
373
413
  /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(
374
414
  designSystem.IconButton,
375
415
  {
@@ -386,7 +426,7 @@ const BulkLocaleActionModal = ({
386
426
  name: locale
387
427
  }
388
428
  ),
389
- borderWidth: 0,
429
+ variant: "ghost",
390
430
  children: /* @__PURE__ */ jsxRuntime.jsx(icons.Pencil, {})
391
431
  }
392
432
  ) })
@@ -403,7 +443,7 @@ const LocalePickerAction = ({
403
443
  documentId
404
444
  }) => {
405
445
  const { formatMessage } = reactIntl.useIntl();
406
- const [{ query }, setQuery] = strapiAdmin.useQueryParams();
446
+ const [{ query: query2 }, setQuery] = strapiAdmin.useQueryParams();
407
447
  const { hasI18n, canCreate, canRead } = useI18n();
408
448
  const { data: locales = [] } = useGetLocalesQuery();
409
449
  const { schema } = strapiAdmin$1.unstable_useDocument({ model, collectionType, documentId });
@@ -411,30 +451,30 @@ const LocalePickerAction = ({
411
451
  (value) => {
412
452
  setQuery({
413
453
  plugins: {
414
- ...query.plugins,
454
+ ...query2.plugins,
415
455
  i18n: {
416
456
  locale: value
417
457
  }
418
458
  }
419
459
  });
420
460
  },
421
- [query.plugins, setQuery]
461
+ [query2.plugins, setQuery]
422
462
  );
423
463
  React__namespace.useEffect(() => {
424
464
  if (!Array.isArray(locales) || !hasI18n) {
425
465
  return;
426
466
  }
427
- const currentDesiredLocale = query.plugins?.i18n?.locale;
467
+ const currentDesiredLocale = query2.plugins?.i18n?.locale;
428
468
  const doesLocaleExist = locales.find((loc) => loc.code === currentDesiredLocale);
429
469
  const defaultLocale = locales.find((locale) => locale.isDefault);
430
470
  if (!doesLocaleExist && defaultLocale?.code) {
431
471
  handleSelect(defaultLocale.code);
432
472
  }
433
- }, [handleSelect, hasI18n, locales, query.plugins?.i18n?.locale]);
473
+ }, [handleSelect, hasI18n, locales, query2.plugins?.i18n?.locale]);
434
474
  if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
435
475
  return null;
436
476
  }
437
- const currentLocale = query.plugins?.i18n?.locale || locales.find((loc) => loc.isDefault)?.code;
477
+ const currentLocale = query2.plugins?.i18n?.locale || locales.find((loc) => loc.isDefault)?.code;
438
478
  const allCurrentLocales = [
439
479
  { status: getDocumentStatus(document, meta), locale: currentLocale },
440
480
  ...meta?.availableLocales ?? []
@@ -549,37 +589,43 @@ const DeleteLocaleAction = ({
549
589
  }
550
590
  };
551
591
  };
552
- const BulkLocalePublishAction = ({
592
+ const BulkLocaleAction = ({
553
593
  document: baseDocument,
554
594
  documentId,
555
595
  model,
556
- collectionType
596
+ collectionType,
597
+ action
557
598
  }) => {
558
599
  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";
600
+ const [{ query: query$1 }] = strapiAdmin.useQueryParams();
601
+ const params = React__namespace.useMemo(() => strapiAdmin$1.buildValidParams(query$1), [query$1]);
602
+ const isOnPublishedTab = query$1.status === "published";
562
603
  const { formatMessage } = reactIntl.useIntl();
563
604
  const { hasI18n, canPublish } = useI18n();
564
605
  const { toggleNotification } = strapiAdmin.useNotification();
565
606
  const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
566
607
  const [selectedRows, setSelectedRows] = React__namespace.useState([]);
567
- const [isConfirmationOpen, setIsConfirmationOpen] = React__namespace.useState(false);
568
- const { publishMany: publishManyAction } = strapiAdmin$1.unstable_useDocumentActions();
608
+ const [isDraftRelationConfirmationOpen, setIsDraftRelationConfirmationOpen] = React__namespace.useState(false);
609
+ const { publishMany: publishManyAction, unpublishMany: unpublishManyAction } = strapiAdmin$1.unstable_useDocumentActions();
569
610
  const {
570
611
  document,
571
612
  meta: documentMeta,
572
613
  schema,
573
614
  validate
574
- } = strapiAdmin$1.unstable_useDocument({
575
- model,
576
- collectionType,
577
- documentId,
578
- params: {
579
- locale: baseLocale
615
+ } = strapiAdmin$1.unstable_useDocument(
616
+ {
617
+ model,
618
+ collectionType,
619
+ documentId,
620
+ params: {
621
+ locale: baseLocale
622
+ }
623
+ },
624
+ {
625
+ skip: !hasI18n
580
626
  }
581
- });
582
- const { data: localesMetadata = [] } = useGetLocalesQuery();
627
+ );
628
+ const { data: localesMetadata = [] } = useGetLocalesQuery(hasI18n ? void 0 : query.skipToken);
583
629
  const headers = [
584
630
  {
585
631
  label: formatMessage({
@@ -628,12 +674,19 @@ const BulkLocalePublishAction = ({
628
674
  }, {});
629
675
  return [rowsFromMeta, errors];
630
676
  }, [document, documentMeta?.availableLocales, validate]);
631
- const localesToPublish = selectedRows.reduce((acc, selectedRow) => {
632
- if (selectedRow.status !== "published" && !Object.keys(validationErrors).includes(selectedRow.locale)) {
677
+ const isBulkPublish = action === "bulk-publish";
678
+ const localesForAction = selectedRows.reduce((acc, selectedRow) => {
679
+ const isValidLocale = (
680
+ // Validation errors are irrelevant if we are trying to unpublish
681
+ !isBulkPublish || !Object.keys(validationErrors).includes(selectedRow.locale)
682
+ );
683
+ const shouldAddLocale = isBulkPublish ? selectedRow.status !== "published" && isValidLocale : selectedRow.status !== "draft" && isValidLocale;
684
+ if (shouldAddLocale) {
633
685
  acc.push(selectedRow.locale);
634
686
  }
635
687
  return acc;
636
688
  }, []);
689
+ const enableDraftRelationsCount = false;
637
690
  const {
638
691
  data: draftRelationsCount = 0,
639
692
  isLoading: isDraftRelationsLoading,
@@ -642,10 +695,10 @@ const BulkLocalePublishAction = ({
642
695
  {
643
696
  model,
644
697
  documentIds: [documentId],
645
- locale: localesToPublish
698
+ locale: localesForAction
646
699
  },
647
700
  {
648
- skip: !documentId || localesToPublish.length === 0
701
+ skip: !enableDraftRelationsCount
649
702
  }
650
703
  );
651
704
  React__namespace.useEffect(() => {
@@ -671,23 +724,32 @@ const BulkLocalePublishAction = ({
671
724
  documentIds: [documentId],
672
725
  params: {
673
726
  ...params,
674
- locale: localesToPublish
727
+ locale: localesForAction
728
+ }
729
+ });
730
+ setSelectedRows([]);
731
+ };
732
+ const unpublish = async () => {
733
+ await unpublishManyAction({
734
+ model,
735
+ documentIds: [documentId],
736
+ params: {
737
+ ...params,
738
+ locale: localesForAction
675
739
  }
676
740
  });
677
741
  setSelectedRows([]);
678
742
  };
679
743
  const handleAction = async () => {
680
744
  if (draftRelationsCount > 0) {
681
- setIsConfirmationOpen(true);
682
- } else {
745
+ setIsDraftRelationConfirmationOpen(true);
746
+ } else if (isBulkPublish) {
683
747
  await publish();
748
+ } else {
749
+ await unpublish();
684
750
  }
685
751
  };
686
- const isUnpublish = document?.status === "published";
687
- if (isUnpublish) {
688
- console.warn(["I18N"], "Bulk locale unpublish modal not implemented");
689
- }
690
- if (isConfirmationOpen) {
752
+ if (isDraftRelationConfirmationOpen) {
691
753
  return {
692
754
  label: formatMessage({
693
755
  id: "app.components.ConfirmDialog.title",
@@ -696,11 +758,11 @@ const BulkLocalePublishAction = ({
696
758
  variant: "danger",
697
759
  dialog: {
698
760
  onCancel: () => {
699
- setIsConfirmationOpen(false);
761
+ setIsDraftRelationConfirmationOpen(false);
700
762
  },
701
763
  onConfirm: async () => {
702
764
  await publish();
703
- setIsConfirmationOpen(false);
765
+ setIsDraftRelationConfirmationOpen(false);
704
766
  },
705
767
  type: "dialog",
706
768
  title: formatMessage({
@@ -710,27 +772,32 @@ const BulkLocalePublishAction = ({
710
772
  content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "center", gap: 2, children: [
711
773
  /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, { width: "2.4rem", height: "2.4rem", fill: "danger600" }),
712
774
  /* @__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."
775
+ id: getTranslation("CMEditViewBulkLocale.draft-relation-warning"),
776
+ defaultMessage: "Some locales are related to draft entries. Publishing them could leave broken links in your app."
777
+ }) }),
778
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", children: formatMessage({
779
+ id: getTranslation("CMEditViewBulkLocale.continue-confirmation"),
780
+ defaultMessage: "Are you sure you want to continue?"
715
781
  }) })
716
782
  ] })
717
783
  }
718
784
  };
719
785
  }
786
+ const hasPermission = selectedRows.map(({ locale }) => locale).every((locale) => canPublish.includes(locale));
720
787
  return {
721
788
  label: formatMessage({
722
- id: getTranslation("CMEditViewBulkLocale.publish-title"),
723
- defaultMessage: "Publish Multiple Locales"
789
+ id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
790
+ defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
724
791
  }),
725
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ListPlus, {}),
726
- disabled: isPublishedTab || !canPublish,
792
+ variant: isBulkPublish ? "secondary" : "danger",
793
+ icon: isBulkPublish ? /* @__PURE__ */ jsxRuntime.jsx(icons.ListPlus, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.Cross, {}),
794
+ disabled: isOnPublishedTab || canPublish.length === 0,
727
795
  position: ["panel"],
728
- variant: "secondary",
729
796
  dialog: {
730
797
  type: "modal",
731
798
  title: formatMessage({
732
- id: getTranslation("CMEditViewBulkLocale.publish-title"),
733
- defaultMessage: "Publish Multiple Locales"
799
+ id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
800
+ defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
734
801
  }),
735
802
  content: () => {
736
803
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -749,28 +816,35 @@ const BulkLocalePublishAction = ({
749
816
  validationErrors,
750
817
  headers,
751
818
  rows,
752
- localesMetadata
819
+ localesMetadata,
820
+ action: action ?? "bulk-publish"
753
821
  }
754
822
  )
755
823
  }
756
824
  );
757
825
  },
758
- footer: () => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxRuntime.jsx(
826
+ footer: () => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Footer, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxRuntime.jsx(
759
827
  designSystem.Button,
760
828
  {
761
829
  loading: isDraftRelationsLoading,
762
- disabled: localesToPublish.length === 0,
830
+ disabled: !hasPermission || localesForAction.length === 0,
763
831
  variant: "default",
764
832
  onClick: handleAction,
765
833
  children: formatMessage({
766
- id: "app.utils.publish",
767
- defaultMessage: "Publish"
834
+ id: isBulkPublish ? "app.utils.publish" : "app.utils.unpublish",
835
+ defaultMessage: isBulkPublish ? "Publish" : "Unpublish"
768
836
  })
769
837
  }
770
838
  ) })
771
839
  }
772
840
  };
773
841
  };
842
+ const BulkLocalePublishAction = (props) => {
843
+ return BulkLocaleAction({ action: "bulk-publish", ...props });
844
+ };
845
+ const BulkLocaleUnpublishAction = (props) => {
846
+ return BulkLocaleAction({ action: "bulk-unpublish", ...props });
847
+ };
774
848
  const StyledTrash = styledComponents.styled(icons.Trash)`
775
849
  path {
776
850
  fill: currentColor;
@@ -827,16 +901,9 @@ const UnpublishModalAdditionalInfo = () => {
827
901
  }
828
902
  ) });
829
903
  };
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
904
  const LocalePicker = () => {
838
905
  const { formatMessage } = reactIntl.useIntl();
839
- const [{ query }, setQuery] = strapiAdmin.useQueryParams();
906
+ const [{ query: query2 }, setQuery] = strapiAdmin.useQueryParams();
840
907
  const { hasI18n, canRead, canCreate } = useI18n();
841
908
  const { data: locales = [] } = useGetLocalesQuery(void 0, {
842
909
  skip: !hasI18n
@@ -846,25 +913,25 @@ const LocalePicker = () => {
846
913
  setQuery(
847
914
  {
848
915
  page: 1,
849
- plugins: { ...query.plugins, i18n: { locale: code } }
916
+ plugins: { ...query2.plugins, i18n: { locale: code } }
850
917
  },
851
918
  "push",
852
919
  replace
853
920
  );
854
921
  },
855
- [query.plugins, setQuery]
922
+ [query2.plugins, setQuery]
856
923
  );
857
924
  React__namespace.useEffect(() => {
858
925
  if (!Array.isArray(locales) || !hasI18n) {
859
926
  return;
860
927
  }
861
- const currentDesiredLocale = query.plugins?.i18n?.locale;
928
+ const currentDesiredLocale = query2.plugins?.i18n?.locale;
862
929
  const doesLocaleExist = locales.find((loc) => loc.code === currentDesiredLocale);
863
930
  const defaultLocale = locales.find((locale) => locale.isDefault);
864
931
  if (!doesLocaleExist && defaultLocale?.code) {
865
932
  handleChange(defaultLocale.code, true);
866
933
  }
867
- }, [hasI18n, handleChange, locales, query.plugins?.i18n?.locale]);
934
+ }, [hasI18n, handleChange, locales, query2.plugins?.i18n?.locale]);
868
935
  if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
869
936
  return null;
870
937
  }
@@ -879,7 +946,7 @@ const LocalePicker = () => {
879
946
  id: getTranslation("actions.select-locale"),
880
947
  defaultMessage: "Select locale"
881
948
  }),
882
- value: query.plugins?.i18n?.locale || locales.find((locale) => locale.isDefault)?.code,
949
+ value: query2.plugins?.i18n?.locale || locales.find((locale) => locale.isDefault)?.code,
883
950
  onChange: handleChange,
884
951
  children: displayedLocales.map((locale) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: locale.code, children: locale.name }, locale.id))
885
952
  }
@@ -893,7 +960,7 @@ const PERMISSIONS = {
893
960
  read: [{ action: "plugin::i18n.locale.read", subject: null }]
894
961
  };
895
962
  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) {
963
+ if (!("i18n" in layout.options) || typeof layout.options.i18n === "object" && layout.options.i18n !== null && "localized" in layout.options.i18n && !layout.options.i18n.localized) {
897
964
  return { layout };
898
965
  }
899
966
  const components = Object.entries(layout.components).reduce(
@@ -939,7 +1006,7 @@ const doesFieldHaveI18nPluginOpt = (pluginOpts) => {
939
1006
  const LabelAction = ({ title, icon }) => {
940
1007
  const { formatMessage } = reactIntl.useIntl();
941
1008
  return /* @__PURE__ */ jsxRuntime.jsxs(Span, { tag: "span", children: [
942
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { tag: "span", children: `(${formatMessage(title)})` }),
1009
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { tag: "span", children: formatMessage(title) }),
943
1010
  React__namespace.cloneElement(icon, {
944
1011
  "aria-hidden": true,
945
1012
  focusable: false
@@ -974,13 +1041,7 @@ const LocaleListCell = ({
974
1041
  }
975
1042
  });
976
1043
  const { locale: language } = reactIntl.useIntl();
977
- const [visible, setVisible] = React__namespace.useState(false);
978
- const buttonRef = React__namespace.useRef(null);
979
1044
  const { data: locales = [] } = useGetLocalesQuery();
980
- const handleTogglePopover = (e) => {
981
- e.stopPropagation();
982
- setVisible((prev) => !prev);
983
- };
984
1045
  const formatter = designSystem.useCollator(language, {
985
1046
  sensitivity: "base"
986
1047
  });
@@ -1002,64 +1063,14 @@ const LocaleListCell = ({
1002
1063
  }
1003
1064
  return locale.name;
1004
1065
  }).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
- )
1066
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Popover.Root, { children: [
1067
+ /* @__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: [
1068
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", ellipsis: true, marginRight: 2, children: localesForDocument.join(", ") }),
1069
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(icons.CaretDown, { width: "1.2rem", height: "1.2rem" }) })
1070
+ ] }) }) }),
1071
+ /* @__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
1072
  ] });
1031
1073
  };
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
1074
  const addColumnToTableHook = ({ displayedHeaders, layout }) => {
1064
1075
  const { options } = layout;
1065
1076
  const isFieldLocalized = doesPluginOptionsHaveI18nLocalized(options) ? options.i18n.localized : false;
@@ -1088,18 +1099,11 @@ const addColumnToTableHook = ({ displayedHeaders, layout }) => {
1088
1099
  const addLocaleToReleasesHook = ({ displayedHeaders = [] }) => {
1089
1100
  return {
1090
1101
  displayedHeaders: [
1091
- // TODO: Fix when migrating to v5
1092
- // ...displayedHeaders,
1102
+ ...displayedHeaders,
1093
1103
  {
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
1104
+ label: {
1105
+ id: "content-releases.page.ReleaseDetails.table.header.label.locale",
1106
+ defaultMessage: "locale"
1103
1107
  },
1104
1108
  name: "locale"
1105
1109
  }
@@ -1247,8 +1251,6 @@ const index = {
1247
1251
  app.addRBACMiddleware([localeMiddleware]);
1248
1252
  app.registerPlugin({
1249
1253
  id: pluginId,
1250
- initializer: Initializer,
1251
- isReady: false,
1252
1254
  name: pluginId
1253
1255
  });
1254
1256
  },
@@ -1266,7 +1268,7 @@ const index = {
1266
1268
  },
1267
1269
  id: "internationalization",
1268
1270
  to: "internationalization",
1269
- Component: () => Promise.resolve().then(() => require("./SettingsPage-DnLLGeBa.js")).then((mod) => ({ default: mod.ProtectedSettingsPage })),
1271
+ Component: () => Promise.resolve().then(() => require("./SettingsPage-C-1h_H38.js")).then((mod) => ({ default: mod.ProtectedSettingsPage })),
1270
1272
  permissions: PERMISSIONS.accessMain
1271
1273
  });
1272
1274
  const contentManager = app.getPlugin("content-manager");
@@ -1278,6 +1280,7 @@ const index = {
1278
1280
  });
1279
1281
  contentManager.apis.addDocumentAction((actions) => {
1280
1282
  actions.splice(2, 0, BulkLocalePublishAction);
1283
+ actions.splice(5, 0, BulkLocaleUnpublishAction);
1281
1284
  return actions;
1282
1285
  });
1283
1286
  contentManager.injectComponent("listView", "actions", {
@@ -1383,7 +1386,7 @@ const index = {
1383
1386
  async registerTrads({ locales }) {
1384
1387
  const importedTrads = await Promise.all(
1385
1388
  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 }) => {
1389
+ 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-CwI88-PP.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
1390
  return {
1388
1391
  data: prefixPluginTranslations(data, pluginId),
1389
1392
  locale
@@ -1407,4 +1410,4 @@ exports.useDeleteLocaleMutation = useDeleteLocaleMutation;
1407
1410
  exports.useGetDefaultLocalesQuery = useGetDefaultLocalesQuery;
1408
1411
  exports.useGetLocalesQuery = useGetLocalesQuery;
1409
1412
  exports.useUpdateLocaleMutation = useUpdateLocaleMutation;
1410
- //# sourceMappingURL=index-DtEKsPcR.js.map
1413
+ //# sourceMappingURL=index-jpk39Rxo.js.map