@strapi/i18n 5.0.0-rc.11 → 5.0.0-rc.13

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 (27) hide show
  1. package/dist/_chunks/{SettingsPage-CbEn7zF5.mjs → SettingsPage-BjxjwEOb.mjs} +2 -2
  2. package/dist/_chunks/{SettingsPage-CbEn7zF5.mjs.map → SettingsPage-BjxjwEOb.mjs.map} +1 -1
  3. package/dist/_chunks/{SettingsPage-C0l7c5fn.js → SettingsPage-CfTmCkup.js} +2 -2
  4. package/dist/_chunks/{SettingsPage-C0l7c5fn.js.map → SettingsPage-CfTmCkup.js.map} +1 -1
  5. package/dist/_chunks/{en-CM6Pjfyv.mjs → en-2xztdZE1.mjs} +7 -1
  6. package/dist/_chunks/en-2xztdZE1.mjs.map +1 -0
  7. package/dist/_chunks/{en-BsOU9o5z.js → en-DWpfm8h5.js} +7 -1
  8. package/dist/_chunks/en-DWpfm8h5.js.map +1 -0
  9. package/dist/_chunks/{index-C0i3v7QQ.js → index-5XLZwzwx.js} +312 -115
  10. package/dist/_chunks/index-5XLZwzwx.js.map +1 -0
  11. package/dist/_chunks/{index-CkrCiZyq.mjs → index-D-qx3tz4.mjs} +319 -122
  12. package/dist/_chunks/index-D-qx3tz4.mjs.map +1 -0
  13. package/dist/admin/index.js +1 -1
  14. package/dist/admin/index.mjs +1 -1
  15. package/dist/admin/src/components/BulkLocaleActionModal.d.ts +2 -1
  16. package/dist/admin/src/components/CMHeaderActions.d.ts +27 -3
  17. package/dist/admin/src/utils/clean.d.ts +4 -0
  18. package/dist/server/index.js +1 -1
  19. package/dist/server/index.js.map +1 -1
  20. package/dist/server/index.mjs +1 -1
  21. package/dist/server/index.mjs.map +1 -1
  22. package/dist/server/src/bootstrap.d.ts.map +1 -1
  23. package/package.json +9 -9
  24. package/dist/_chunks/en-BsOU9o5z.js.map +0 -1
  25. package/dist/_chunks/en-CM6Pjfyv.mjs.map +0 -1
  26. package/dist/_chunks/index-C0i3v7QQ.js.map +0 -1
  27. package/dist/_chunks/index-CkrCiZyq.mjs.map +0 -1
@@ -241,10 +241,93 @@ const relationsApi = i18nApi.injectEndpoints({
241
241
  })
242
242
  });
243
243
  const { useGetManyDraftRelationCountQuery } = relationsApi;
244
+ const cleanData = (data, schema, components) => {
245
+ const cleanedData = removeFields(data, [
246
+ "createdAt",
247
+ "createdBy",
248
+ "updatedAt",
249
+ "updatedBy",
250
+ "id",
251
+ "documentId",
252
+ "publishedAt",
253
+ "strapi_stage",
254
+ "strapi_assignee",
255
+ "locale"
256
+ ]);
257
+ const cleanedDataWithoutPasswordAndRelation = recursiveRemoveFieldTypes(
258
+ cleanedData,
259
+ schema,
260
+ components,
261
+ ["relation", "password"]
262
+ );
263
+ return cleanedDataWithoutPasswordAndRelation;
264
+ };
265
+ const removeFields = (data, fields) => {
266
+ return Object.keys(data).reduce((acc, current) => {
267
+ if (fields.includes(current)) {
268
+ return acc;
269
+ }
270
+ acc[current] = data[current];
271
+ return acc;
272
+ }, {});
273
+ };
274
+ const recursiveRemoveFieldTypes = (data, schema, components, fields) => {
275
+ return Object.keys(data).reduce((acc, current) => {
276
+ const attribute = schema.attributes[current] ?? { type: void 0 };
277
+ if (fields.includes(attribute.type)) {
278
+ return acc;
279
+ }
280
+ if (attribute.type === "dynamiczone") {
281
+ acc[current] = data[current].map((componentValue, index2) => {
282
+ const { id: _, ...rest } = recursiveRemoveFieldTypes(
283
+ componentValue,
284
+ components[componentValue.__component],
285
+ components,
286
+ fields
287
+ );
288
+ return {
289
+ ...rest,
290
+ __temp_key__: index2 + 1
291
+ };
292
+ });
293
+ } else if (attribute.type === "component") {
294
+ const { repeatable, component } = attribute;
295
+ if (repeatable) {
296
+ acc[current] = (data[current] ?? []).map((compoData, index2) => {
297
+ const { id: _, ...rest } = recursiveRemoveFieldTypes(
298
+ compoData,
299
+ components[component],
300
+ components,
301
+ fields
302
+ );
303
+ return {
304
+ ...rest,
305
+ __temp_key__: index2 + 1
306
+ };
307
+ });
308
+ } else {
309
+ const { id: _, ...rest } = recursiveRemoveFieldTypes(
310
+ data[current] ?? {},
311
+ components[component],
312
+ components,
313
+ fields
314
+ );
315
+ acc[current] = rest;
316
+ }
317
+ } else {
318
+ acc[current] = data[current];
319
+ }
320
+ return acc;
321
+ }, {});
322
+ };
244
323
  const isErrorMessageDescriptor = (object) => {
245
324
  return typeof object === "object" && object !== null && "id" in object && "defaultMessage" in object;
246
325
  };
247
- const EntryValidationText = ({ status = "draft", validationErrors }) => {
326
+ const EntryValidationText = ({
327
+ status = "draft",
328
+ validationErrors,
329
+ action
330
+ }) => {
248
331
  const { formatMessage } = reactIntl.useIntl();
249
332
  const getErrorStr = (key, value) => {
250
333
  if (typeof value === "string") {
@@ -278,30 +361,63 @@ const EntryValidationText = ({ status = "draft", validationErrors }) => {
278
361
  ) })
279
362
  ] });
280
363
  }
281
- if (status === "published") {
282
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
283
- /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
284
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
285
- id: "content-manager.bulk-publish.already-published",
286
- defaultMessage: "Already Published"
287
- }) })
288
- ] });
289
- }
290
- if (status === "modified") {
291
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
292
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowsCounterClockwise, { fill: "alternative600" }),
293
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
294
- id: "app.utils.ready-to-publish-changes",
295
- defaultMessage: "Ready to publish changes"
296
- }) })
297
- ] });
298
- }
364
+ const getStatusMessage = () => {
365
+ if (action === "bulk-publish") {
366
+ if (status === "published") {
367
+ return {
368
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
369
+ text: formatMessage({
370
+ id: "content-manager.bulk-publish.already-published",
371
+ defaultMessage: "Already Published"
372
+ }),
373
+ textColor: "success600",
374
+ fontWeight: "bold"
375
+ };
376
+ } else if (status === "modified") {
377
+ return {
378
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowsCounterClockwise, { fill: "alternative600" }),
379
+ text: formatMessage({
380
+ id: "app.utils.ready-to-publish-changes",
381
+ defaultMessage: "Ready to publish changes"
382
+ })
383
+ };
384
+ } else {
385
+ return {
386
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
387
+ text: formatMessage({
388
+ id: "app.utils.ready-to-publish",
389
+ defaultMessage: "Ready to publish"
390
+ })
391
+ };
392
+ }
393
+ } else {
394
+ if (status === "draft") {
395
+ return {
396
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
397
+ text: formatMessage({
398
+ id: "content-manager.bulk-unpublish.already-unpublished",
399
+ defaultMessage: "Already Unpublished"
400
+ }),
401
+ textColor: "success600",
402
+ fontWeight: "bold"
403
+ };
404
+ } else {
405
+ return {
406
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
407
+ text: formatMessage({
408
+ id: "app.utils.ready-to-unpublish-changes",
409
+ defaultMessage: "Ready to unpublish"
410
+ }),
411
+ textColor: "success600",
412
+ fontWeight: "bold"
413
+ };
414
+ }
415
+ }
416
+ };
417
+ const { icon, text, textColor = "success600", fontWeight = "normal" } = getStatusMessage();
299
418
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
300
- /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
301
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
302
- id: "app.utils.ready-to-publish",
303
- defaultMessage: "Ready to publish"
304
- }) })
419
+ icon,
420
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor, fontWeight, children: text })
305
421
  ] });
306
422
  };
307
423
  const BoldChunk = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
@@ -309,7 +425,8 @@ const BulkLocaleActionModal = ({
309
425
  headers,
310
426
  rows,
311
427
  localesMetadata,
312
- validationErrors = {}
428
+ validationErrors = {},
429
+ action
313
430
  }) => {
314
431
  const { formatMessage } = reactIntl.useIntl();
315
432
  const selectedRows = strapiAdmin.useTable(
@@ -322,22 +439,24 @@ const BulkLocaleActionModal = ({
322
439
  return acc;
323
440
  }, {});
324
441
  const localesWithErrors = Object.keys(validationErrors);
325
- const alreadyPublishedCount = selectedRows.filter(
442
+ const publishedCount = selectedRows.filter(
326
443
  ({ locale }) => currentStatusByLocale[locale] === "published"
327
444
  ).length;
328
- const readyToPublishCount = selectedRows.filter(
445
+ const draftCount = selectedRows.filter(
329
446
  ({ locale }) => (currentStatusByLocale[locale] === "draft" || currentStatusByLocale[locale] === "modified") && !localesWithErrors.includes(locale)
330
447
  ).length;
331
448
  const withErrorsCount = localesWithErrors.length;
449
+ const messageId = action === "bulk-publish" ? "content-manager.containers.list.selectedEntriesModal.selectedCount.publish" : "content-manager.containers.list.selectedEntriesModal.selectedCount.unpublish";
450
+ const defaultMessage = action === "bulk-publish" ? "<b>{publishedCount}</b> {publishedCount, plural, =0 {entries} one {entry} other {entries}} already published. <b>{draftCount}</b> {draftCount, plural, =0 {entries} one {entry} other {entries}} ready to publish. <b>{withErrorsCount}</b> {withErrorsCount, plural, =0 {entries} one {entry} other {entries}} waiting for action." : "<b>{draftCount}</b> {draftCount, plural, =0 {entries} one {entry} other {entries}} already unpublished. <b>{publishedCount}</b> {publishedCount, plural, =0 {entries} one {entry} other {entries}} ready to unpublish.";
332
451
  return formatMessage(
333
452
  {
334
- id: "content-manager.containers.list.selectedEntriesModal.selectedCount",
335
- defaultMessage: "<b>{alreadyPublishedCount}</b> {alreadyPublishedCount, plural, =0 {entries} one {entry} other {entries}} already published. <b>{readyToPublishCount}</b> {readyToPublishCount, plural, =0 {entries} one {entry} other {entries}} ready to publish. <b>{withErrorsCount}</b> {withErrorsCount, plural, =0 {entries} one {entry} other {entries}} waiting for action."
453
+ id: messageId,
454
+ defaultMessage
336
455
  },
337
456
  {
338
457
  withErrorsCount,
339
- readyToPublishCount,
340
- alreadyPublishedCount,
458
+ draftCount,
459
+ publishedCount,
341
460
  b: BoldChunk
342
461
  }
343
462
  );
@@ -369,7 +488,7 @@ const BulkLocaleActionModal = ({
369
488
  children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
370
489
  }
371
490
  ) }) }),
372
- /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(EntryValidationText, { validationErrors: error, status }) }),
491
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(EntryValidationText, { validationErrors: error, status, action }) }),
373
492
  /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(
374
493
  designSystem.IconButton,
375
494
  {
@@ -406,7 +525,13 @@ const LocalePickerAction = ({
406
525
  const [{ query: query2 }, setQuery] = strapiAdmin.useQueryParams();
407
526
  const { hasI18n, canCreate, canRead } = useI18n();
408
527
  const { data: locales = [] } = useGetLocalesQuery();
409
- const { schema } = strapiAdmin$1.unstable_useDocument({ model, collectionType, documentId });
528
+ const currentDesiredLocale = query2.plugins?.i18n?.locale;
529
+ const { schema } = strapiAdmin$1.unstable_useDocument({
530
+ model,
531
+ collectionType,
532
+ documentId,
533
+ params: { locale: currentDesiredLocale }
534
+ });
410
535
  const handleSelect = React__namespace.useCallback(
411
536
  (value) => {
412
537
  setQuery({
@@ -424,21 +549,20 @@ const LocalePickerAction = ({
424
549
  if (!Array.isArray(locales) || !hasI18n) {
425
550
  return;
426
551
  }
427
- const currentDesiredLocale = query2.plugins?.i18n?.locale;
428
552
  const doesLocaleExist = locales.find((loc) => loc.code === currentDesiredLocale);
429
553
  const defaultLocale = locales.find((locale) => locale.isDefault);
430
554
  if (!doesLocaleExist && defaultLocale?.code) {
431
555
  handleSelect(defaultLocale.code);
432
556
  }
433
- }, [handleSelect, hasI18n, locales, query2.plugins?.i18n?.locale]);
434
- if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
435
- return null;
436
- }
437
- const currentLocale = query2.plugins?.i18n?.locale || locales.find((loc) => loc.isDefault)?.code;
557
+ }, [handleSelect, hasI18n, locales, currentDesiredLocale]);
558
+ const currentLocale = Array.isArray(locales) ? locales.find((locale) => locale.code === currentDesiredLocale)?.code : void 0;
438
559
  const allCurrentLocales = [
439
560
  { status: getDocumentStatus(document, meta), locale: currentLocale },
440
561
  ...meta?.availableLocales ?? []
441
562
  ];
563
+ if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
564
+ return null;
565
+ }
442
566
  return {
443
567
  label: formatMessage({
444
568
  id: getTranslation("Settings.locales.modal.locales.label"),
@@ -450,7 +574,7 @@ const LocalePickerAction = ({
450
574
  );
451
575
  const status = currentLocaleDoc?.status ?? "draft";
452
576
  const permissionsToCheck = currentLocaleDoc ? canCreate : canRead;
453
- const statusVariant = status === "draft" ? "primary" : status === "published" ? "success" : "alternative";
577
+ const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
454
578
  return {
455
579
  disabled: !permissionsToCheck.includes(locale.code),
456
580
  value: locale.code,
@@ -486,6 +610,95 @@ const getDocumentStatus = (document, meta) => {
486
610
  }
487
611
  return docStatus;
488
612
  };
613
+ const FillFromAnotherLocaleAction = ({
614
+ documentId,
615
+ meta,
616
+ model,
617
+ collectionType
618
+ }) => {
619
+ const { formatMessage } = reactIntl.useIntl();
620
+ const [{ query: query2 }] = strapiAdmin.useQueryParams();
621
+ const currentDesiredLocale = query2.plugins?.i18n?.locale;
622
+ const [localeSelected, setLocaleSelected] = React__namespace.useState(null);
623
+ const setValues = strapiAdmin.useForm("FillFromAnotherLocale", (state) => state.setValues);
624
+ const { getDocument } = strapiAdmin$1.unstable_useDocumentActions();
625
+ const { schema, components } = strapiAdmin$1.unstable_useDocument({
626
+ model,
627
+ documentId,
628
+ collectionType,
629
+ params: { locale: currentDesiredLocale }
630
+ });
631
+ const { data: locales = [] } = useGetLocalesQuery();
632
+ const availableLocales = Array.isArray(locales) ? locales.filter((locale) => meta?.availableLocales.some((l) => l.locale === locale.code)) : [];
633
+ const fillFromLocale = (onClose) => async () => {
634
+ const response = await getDocument({
635
+ collectionType,
636
+ model,
637
+ documentId,
638
+ params: { locale: localeSelected }
639
+ });
640
+ if (!response || !schema) {
641
+ return;
642
+ }
643
+ const { data } = response;
644
+ const cleanedData = cleanData(data, schema, components);
645
+ setValues(cleanedData);
646
+ onClose();
647
+ };
648
+ return {
649
+ type: "icon",
650
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Download, {}),
651
+ disabled: availableLocales.length === 0,
652
+ label: formatMessage({
653
+ id: getTranslation("CMEditViewCopyLocale.copy-text"),
654
+ defaultMessage: "Fill in from another locale"
655
+ }),
656
+ dialog: {
657
+ type: "dialog",
658
+ title: formatMessage({
659
+ id: getTranslation("CMEditViewCopyLocale.dialog.title"),
660
+ defaultMessage: "Confirmation"
661
+ }),
662
+ content: ({ onClose }) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
663
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 3, children: [
664
+ /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
665
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", children: formatMessage({
666
+ id: getTranslation("CMEditViewCopyLocale.dialog.body"),
667
+ defaultMessage: "Your current content will be erased and filled by the content of the selected locale:"
668
+ }) }),
669
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { width: "100%", children: [
670
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
671
+ id: getTranslation("CMEditViewCopyLocale.dialog.field.label"),
672
+ defaultMessage: "Locale"
673
+ }) }),
674
+ /* @__PURE__ */ jsxRuntime.jsx(
675
+ designSystem.SingleSelect,
676
+ {
677
+ value: localeSelected,
678
+ placeholder: formatMessage({
679
+ id: getTranslation("CMEditViewCopyLocale.dialog.field.placeholder"),
680
+ defaultMessage: "Select one locale..."
681
+ }),
682
+ onChange: (value) => setLocaleSelected(value),
683
+ children: availableLocales.map((locale) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: locale.code, children: locale.name }, locale.code))
684
+ }
685
+ )
686
+ ] })
687
+ ] }) }),
688
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, width: "100%", children: [
689
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { flex: "auto", variant: "tertiary", onClick: onClose, children: formatMessage({
690
+ id: getTranslation("CMEditViewCopyLocale.cancel-text"),
691
+ defaultMessage: "No, cancel"
692
+ }) }),
693
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { flex: "auto", variant: "success", onClick: fillFromLocale(onClose), children: formatMessage({
694
+ id: getTranslation("CMEditViewCopyLocale.submit-text"),
695
+ defaultMessage: "Yes, fill in"
696
+ }) })
697
+ ] }) })
698
+ ] })
699
+ }
700
+ };
701
+ };
489
702
  const DeleteLocaleAction = ({
490
703
  document,
491
704
  documentId,
@@ -549,23 +762,24 @@ const DeleteLocaleAction = ({
549
762
  }
550
763
  };
551
764
  };
552
- const BulkLocalePublishAction = ({
765
+ const BulkLocaleAction = ({
553
766
  document: baseDocument,
554
767
  documentId,
555
768
  model,
556
- collectionType
769
+ collectionType,
770
+ action
557
771
  }) => {
558
772
  const baseLocale = baseDocument?.locale ?? null;
559
773
  const [{ query: query$1 }] = strapiAdmin.useQueryParams();
560
774
  const params = React__namespace.useMemo(() => strapiAdmin$1.buildValidParams(query$1), [query$1]);
561
- const isPublishedTab = query$1.status === "published";
775
+ const isOnPublishedTab = query$1.status === "published";
562
776
  const { formatMessage } = reactIntl.useIntl();
563
777
  const { hasI18n, canPublish } = useI18n();
564
778
  const { toggleNotification } = strapiAdmin.useNotification();
565
779
  const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
566
780
  const [selectedRows, setSelectedRows] = React__namespace.useState([]);
567
781
  const [isDraftRelationConfirmationOpen, setIsDraftRelationConfirmationOpen] = React__namespace.useState(false);
568
- const { publishMany: publishManyAction } = strapiAdmin$1.unstable_useDocumentActions();
782
+ const { publishMany: publishManyAction, unpublishMany: unpublishManyAction } = strapiAdmin$1.unstable_useDocumentActions();
569
783
  const {
570
784
  document,
571
785
  meta: documentMeta,
@@ -581,7 +795,7 @@ const BulkLocalePublishAction = ({
581
795
  }
582
796
  },
583
797
  {
584
- skip: !hasI18n
798
+ skip: !hasI18n || !baseLocale
585
799
  }
586
800
  );
587
801
  const { data: localesMetadata = [] } = useGetLocalesQuery(hasI18n ? void 0 : query.skipToken);
@@ -633,12 +847,19 @@ const BulkLocalePublishAction = ({
633
847
  }, {});
634
848
  return [rowsFromMeta, errors];
635
849
  }, [document, documentMeta?.availableLocales, validate]);
636
- const localesToPublish = selectedRows.reduce((acc, selectedRow) => {
637
- if (selectedRow.status !== "published" && !Object.keys(validationErrors).includes(selectedRow.locale)) {
850
+ const isBulkPublish = action === "bulk-publish";
851
+ const localesForAction = selectedRows.reduce((acc, selectedRow) => {
852
+ const isValidLocale = (
853
+ // Validation errors are irrelevant if we are trying to unpublish
854
+ !isBulkPublish || !Object.keys(validationErrors).includes(selectedRow.locale)
855
+ );
856
+ const shouldAddLocale = isBulkPublish ? selectedRow.status !== "published" && isValidLocale : selectedRow.status !== "draft" && isValidLocale;
857
+ if (shouldAddLocale) {
638
858
  acc.push(selectedRow.locale);
639
859
  }
640
860
  return acc;
641
861
  }, []);
862
+ const enableDraftRelationsCount = false;
642
863
  const {
643
864
  data: draftRelationsCount = 0,
644
865
  isLoading: isDraftRelationsLoading,
@@ -647,10 +868,10 @@ const BulkLocalePublishAction = ({
647
868
  {
648
869
  model,
649
870
  documentIds: [documentId],
650
- locale: localesToPublish
871
+ locale: localesForAction
651
872
  },
652
873
  {
653
- skip: !documentId || localesToPublish.length === 0
874
+ skip: !enableDraftRelationsCount
654
875
  }
655
876
  );
656
877
  React__namespace.useEffect(() => {
@@ -676,7 +897,18 @@ const BulkLocalePublishAction = ({
676
897
  documentIds: [documentId],
677
898
  params: {
678
899
  ...params,
679
- locale: localesToPublish
900
+ locale: localesForAction
901
+ }
902
+ });
903
+ setSelectedRows([]);
904
+ };
905
+ const unpublish = async () => {
906
+ await unpublishManyAction({
907
+ model,
908
+ documentIds: [documentId],
909
+ params: {
910
+ ...params,
911
+ locale: localesForAction
680
912
  }
681
913
  });
682
914
  setSelectedRows([]);
@@ -684,14 +916,12 @@ const BulkLocalePublishAction = ({
684
916
  const handleAction = async () => {
685
917
  if (draftRelationsCount > 0) {
686
918
  setIsDraftRelationConfirmationOpen(true);
687
- } else {
919
+ } else if (isBulkPublish) {
688
920
  await publish();
921
+ } else {
922
+ await unpublish();
689
923
  }
690
924
  };
691
- const isUnpublish = document?.status === "published";
692
- if (isUnpublish) {
693
- console.warn(["I18N"], "Bulk locale unpublish modal not implemented");
694
- }
695
925
  if (isDraftRelationConfirmationOpen) {
696
926
  return {
697
927
  label: formatMessage({
@@ -729,18 +959,18 @@ const BulkLocalePublishAction = ({
729
959
  const hasPermission = selectedRows.map(({ locale }) => locale).every((locale) => canPublish.includes(locale));
730
960
  return {
731
961
  label: formatMessage({
732
- id: getTranslation("CMEditViewBulkLocale.publish-title"),
733
- defaultMessage: "Publish Multiple Locales"
962
+ id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
963
+ defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
734
964
  }),
735
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ListPlus, {}),
736
- disabled: isPublishedTab || canPublish.length === 0,
965
+ variant: isBulkPublish ? "secondary" : "danger",
966
+ icon: isBulkPublish ? /* @__PURE__ */ jsxRuntime.jsx(icons.ListPlus, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.Cross, {}),
967
+ disabled: isOnPublishedTab || canPublish.length === 0,
737
968
  position: ["panel"],
738
- variant: "secondary",
739
969
  dialog: {
740
970
  type: "modal",
741
971
  title: formatMessage({
742
- id: getTranslation("CMEditViewBulkLocale.publish-title"),
743
- defaultMessage: "Publish Multiple Locales"
972
+ id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
973
+ defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
744
974
  }),
745
975
  content: () => {
746
976
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -759,7 +989,8 @@ const BulkLocalePublishAction = ({
759
989
  validationErrors,
760
990
  headers,
761
991
  rows,
762
- localesMetadata
992
+ localesMetadata,
993
+ action: action ?? "bulk-publish"
763
994
  }
764
995
  )
765
996
  }
@@ -769,18 +1000,24 @@ const BulkLocalePublishAction = ({
769
1000
  designSystem.Button,
770
1001
  {
771
1002
  loading: isDraftRelationsLoading,
772
- disabled: !hasPermission || localesToPublish.length === 0,
1003
+ disabled: !hasPermission || localesForAction.length === 0,
773
1004
  variant: "default",
774
1005
  onClick: handleAction,
775
1006
  children: formatMessage({
776
- id: "app.utils.publish",
777
- defaultMessage: "Publish"
1007
+ id: isBulkPublish ? "app.utils.publish" : "app.utils.unpublish",
1008
+ defaultMessage: isBulkPublish ? "Publish" : "Unpublish"
778
1009
  })
779
1010
  }
780
1011
  ) })
781
1012
  }
782
1013
  };
783
1014
  };
1015
+ const BulkLocalePublishAction = (props) => {
1016
+ return BulkLocaleAction({ action: "bulk-publish", ...props });
1017
+ };
1018
+ const BulkLocaleUnpublishAction = (props) => {
1019
+ return BulkLocaleAction({ action: "bulk-unpublish", ...props });
1020
+ };
784
1021
  const StyledTrash = styledComponents.styled(icons.Trash)`
785
1022
  path {
786
1023
  fill: currentColor;
@@ -1000,54 +1237,13 @@ const LocaleListCell = ({
1000
1237
  return locale.name;
1001
1238
  }).toSorted((a, b) => formatter.compare(a, b));
1002
1239
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Popover.Root, { children: [
1003
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Popover.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsxs(
1004
- ActionWrapper,
1005
- {
1006
- minWidth: "100%",
1007
- alignItems: "center",
1008
- justifyContent: "center",
1009
- height: "3.2rem",
1010
- width: "3.2rem",
1011
- children: [
1012
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", ellipsis: true, children: localesForDocument.join(", ") }),
1013
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(icons.CaretDown, {}) })
1014
- ]
1015
- }
1016
- ) }) }),
1240
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Popover.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "ghost", type: "button", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { minWidth: "100%", alignItems: "center", justifyContent: "center", fontWeight: "regular", children: [
1241
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", ellipsis: true, marginRight: 2, children: localesForDocument.join(", ") }),
1242
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(icons.CaretDown, { width: "1.2rem", height: "1.2rem" }) })
1243
+ ] }) }) }),
1017
1244
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Popover.Content, { sideOffset: 16, children: /* @__PURE__ */ jsxRuntime.jsx("ul", { children: localesForDocument.map((name) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 3, tag: "li", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: name }) }, name)) }) })
1018
1245
  ] });
1019
1246
  };
1020
- const Button = styledComponents.styled.button`
1021
- width: 100%;
1022
-
1023
- svg {
1024
- > g,
1025
- path {
1026
- fill: ${({ theme }) => theme.colors.neutral500};
1027
- }
1028
- }
1029
- &:hover {
1030
- svg {
1031
- > g,
1032
- path {
1033
- fill: ${({ theme }) => theme.colors.neutral600};
1034
- }
1035
- }
1036
- }
1037
- &:active {
1038
- svg {
1039
- > g,
1040
- path {
1041
- fill: ${({ theme }) => theme.colors.neutral400};
1042
- }
1043
- }
1044
- }
1045
- `;
1046
- const ActionWrapper = styledComponents.styled(designSystem.Flex)`
1047
- svg {
1048
- height: 0.4rem;
1049
- }
1050
- `;
1051
1247
  const addColumnToTableHook = ({ displayedHeaders, layout }) => {
1052
1248
  const { options } = layout;
1053
1249
  const isFieldLocalized = doesPluginOptionsHaveI18nLocalized(options) ? options.i18n.localized : false;
@@ -1245,11 +1441,11 @@ const index = {
1245
1441
  },
1246
1442
  id: "internationalization",
1247
1443
  to: "internationalization",
1248
- Component: () => Promise.resolve().then(() => require("./SettingsPage-C0l7c5fn.js")).then((mod) => ({ default: mod.ProtectedSettingsPage })),
1444
+ Component: () => Promise.resolve().then(() => require("./SettingsPage-CfTmCkup.js")).then((mod) => ({ default: mod.ProtectedSettingsPage })),
1249
1445
  permissions: PERMISSIONS.accessMain
1250
1446
  });
1251
1447
  const contentManager = app.getPlugin("content-manager");
1252
- contentManager.apis.addDocumentHeaderAction([LocalePickerAction]);
1448
+ contentManager.apis.addDocumentHeaderAction([LocalePickerAction, FillFromAnotherLocaleAction]);
1253
1449
  contentManager.apis.addDocumentAction((actions) => {
1254
1450
  const indexOfDeleteAction = actions.findIndex((action) => action.type === "delete");
1255
1451
  actions.splice(indexOfDeleteAction, 0, DeleteLocaleAction);
@@ -1257,6 +1453,7 @@ const index = {
1257
1453
  });
1258
1454
  contentManager.apis.addDocumentAction((actions) => {
1259
1455
  actions.splice(2, 0, BulkLocalePublishAction);
1456
+ actions.splice(5, 0, BulkLocaleUnpublishAction);
1260
1457
  return actions;
1261
1458
  });
1262
1459
  contentManager.injectComponent("listView", "actions", {
@@ -1362,7 +1559,7 @@ const index = {
1362
1559
  async registerTrads({ locales }) {
1363
1560
  const importedTrads = await Promise.all(
1364
1561
  locales.map((locale) => {
1365
- 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-BsOU9o5z.js")), "./translations/es.json": () => Promise.resolve().then(() => require("./es-DS-XFGSw.js")), "./translations/fr.json": () => Promise.resolve().then(() => require("./fr-BTjekDpq.js")), "./translations/ko.json": () => Promise.resolve().then(() => require("./ko-DmcGUBQ3.js")), "./translations/pl.json": () => Promise.resolve().then(() => require("./pl-Cn5RYonZ.js")), "./translations/ru.json": () => Promise.resolve().then(() => require("./ru-BMBgVL3s.js")), "./translations/tr.json": () => Promise.resolve().then(() => require("./tr-CarUU76c.js")), "./translations/zh-Hans.json": () => Promise.resolve().then(() => require("./zh-Hans-DSHIXAa3.js")), "./translations/zh.json": () => Promise.resolve().then(() => require("./zh-CukOviB0.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
1562
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/de.json": () => Promise.resolve().then(() => require("./de-DtWiGdHl.js")), "./translations/dk.json": () => Promise.resolve().then(() => require("./dk-D8C-casx.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-DWpfm8h5.js")), "./translations/es.json": () => Promise.resolve().then(() => require("./es-DS-XFGSw.js")), "./translations/fr.json": () => Promise.resolve().then(() => require("./fr-BTjekDpq.js")), "./translations/ko.json": () => Promise.resolve().then(() => require("./ko-DmcGUBQ3.js")), "./translations/pl.json": () => Promise.resolve().then(() => require("./pl-Cn5RYonZ.js")), "./translations/ru.json": () => Promise.resolve().then(() => require("./ru-BMBgVL3s.js")), "./translations/tr.json": () => Promise.resolve().then(() => require("./tr-CarUU76c.js")), "./translations/zh-Hans.json": () => Promise.resolve().then(() => require("./zh-Hans-DSHIXAa3.js")), "./translations/zh.json": () => Promise.resolve().then(() => require("./zh-CukOviB0.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
1366
1563
  return {
1367
1564
  data: prefixPluginTranslations(data, pluginId),
1368
1565
  locale
@@ -1386,4 +1583,4 @@ exports.useDeleteLocaleMutation = useDeleteLocaleMutation;
1386
1583
  exports.useGetDefaultLocalesQuery = useGetDefaultLocalesQuery;
1387
1584
  exports.useGetLocalesQuery = useGetLocalesQuery;
1388
1585
  exports.useUpdateLocaleMutation = useUpdateLocaleMutation;
1389
- //# sourceMappingURL=index-C0i3v7QQ.js.map
1586
+ //# sourceMappingURL=index-5XLZwzwx.js.map