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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/LICENSE +18 -3
  2. package/dist/_chunks/{SettingsPage-0FFSTUW2.mjs → SettingsPage-DbRFoF_H.mjs} +95 -108
  3. package/dist/_chunks/SettingsPage-DbRFoF_H.mjs.map +1 -0
  4. package/dist/_chunks/{SettingsPage-DnLLGeBa.js → SettingsPage-uGJv15wR.js} +93 -106
  5. package/dist/_chunks/SettingsPage-uGJv15wR.js.map +1 -0
  6. package/dist/_chunks/{en-18tWw4P6.mjs → en-BYRZFDBV.mjs} +11 -2
  7. package/dist/_chunks/en-BYRZFDBV.mjs.map +1 -0
  8. package/dist/_chunks/{en-Kv6y9zPQ.js → en-Dk9At9_Z.js} +11 -2
  9. package/dist/_chunks/en-Dk9At9_Z.js.map +1 -0
  10. package/dist/_chunks/{index-BddUXwss.mjs → index-7_EUScSl.mjs} +445 -219
  11. package/dist/_chunks/index-7_EUScSl.mjs.map +1 -0
  12. package/dist/_chunks/{index-DtEKsPcR.js → index-BGtXLYX-.js} +451 -225
  13. package/dist/_chunks/index-BGtXLYX-.js.map +1 -0
  14. package/dist/admin/index.js +1 -1
  15. package/dist/admin/index.mjs +1 -1
  16. package/dist/admin/src/components/BulkLocaleActionModal.d.ts +2 -1
  17. package/dist/admin/src/components/CMHeaderActions.d.ts +29 -3
  18. package/dist/admin/src/components/CreateLocale.d.ts +6 -6
  19. package/dist/admin/src/components/EditLocale.d.ts +5 -4
  20. package/dist/admin/src/contentReleasesHooks/releaseDetailsView.d.ts +9 -5
  21. package/dist/admin/src/utils/clean.d.ts +4 -0
  22. package/dist/admin/src/utils/schemas.d.ts +1 -0
  23. package/dist/server/index.js +397 -487
  24. package/dist/server/index.js.map +1 -1
  25. package/dist/server/index.mjs +398 -488
  26. package/dist/server/index.mjs.map +1 -1
  27. package/dist/server/src/bootstrap.d.ts +1 -4
  28. package/dist/server/src/bootstrap.d.ts.map +1 -1
  29. package/dist/server/src/index.d.ts +15 -13
  30. package/dist/server/src/index.d.ts.map +1 -1
  31. package/dist/server/src/register.d.ts.map +1 -1
  32. package/dist/server/src/services/index.d.ts +14 -10
  33. package/dist/server/src/services/index.d.ts.map +1 -1
  34. package/dist/server/src/services/permissions/actions.d.ts +14 -2
  35. package/dist/server/src/services/permissions/actions.d.ts.map +1 -1
  36. package/dist/server/src/services/permissions.d.ts +14 -2
  37. package/dist/server/src/services/permissions.d.ts.map +1 -1
  38. package/dist/server/src/utils/index.d.ts +0 -2
  39. package/dist/server/src/utils/index.d.ts.map +1 -1
  40. package/package.json +9 -9
  41. package/dist/_chunks/SettingsPage-0FFSTUW2.mjs.map +0 -1
  42. package/dist/_chunks/SettingsPage-DnLLGeBa.js.map +0 -1
  43. package/dist/_chunks/en-18tWw4P6.mjs.map +0 -1
  44. package/dist/_chunks/en-Kv6y9zPQ.js.map +0 -1
  45. package/dist/_chunks/index-BddUXwss.mjs.map +0 -1
  46. package/dist/_chunks/index-DtEKsPcR.js.map +0 -1
  47. package/dist/admin/src/components/Initializer.d.ts +0 -5
  48. package/dist/server/src/migrations/content-type/disable/index.d.ts +0 -3
  49. package/dist/server/src/migrations/content-type/disable/index.d.ts.map +0 -1
  50. package/dist/server/src/migrations/content-type/enable/index.d.ts +0 -3
  51. package/dist/server/src/migrations/content-type/enable/index.d.ts.map +0 -1
  52. package/dist/server/src/services/entity-service-decorator.d.ts +0 -29
  53. package/dist/server/src/services/entity-service-decorator.d.ts.map +0 -1
  54. package/strapi-server.js +0 -3
@@ -1,12 +1,13 @@
1
1
  import get from "lodash/get";
2
2
  import * as yup from "yup";
3
- import { jsxs, Fragment, jsx } from "react/jsx-runtime";
3
+ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
4
4
  import * as React from "react";
5
- import { Typography, Field, Checkbox, Dialog, DialogBody, Flex, DialogFooter, Button as Button$1, Box, Status, IconButton, Tooltip, SingleSelect, SingleSelectOption, VisuallyHidden, useCollator, Popover } from "@strapi/design-system";
6
- import { WarningCircle, Pencil, CrossCircle, CheckCircle, ArrowsCounterClockwise, Trash, ListPlus, Earth, EarthStriked, CaretDown } from "@strapi/icons";
5
+ import { Typography, Dialog, Field, Checkbox, Flex, Button, Modal, Box, Status, IconButton, Tooltip, SingleSelect, SingleSelectOption, VisuallyHidden, useCollator, Popover } from "@strapi/design-system";
6
+ import { WarningCircle, Pencil, CrossCircle, CheckCircle, ArrowsCounterClockwise, Trash, Plus, Download, ListPlus, Cross, Earth, EarthStriked, CaretDown } from "@strapi/icons";
7
7
  import { useIntl } from "react-intl";
8
8
  import { styled } from "styled-components";
9
- import { useAuth, adminApi, useTable, Table, useQueryParams, useNotification, useAPIErrorHandler } from "@strapi/admin/strapi-admin";
9
+ import { skipToken } from "@reduxjs/toolkit/query";
10
+ import { useAuth, adminApi, useTable, Table, useQueryParams, useForm, useNotification, useAPIErrorHandler } from "@strapi/admin/strapi-admin";
10
11
  import { unstable_useDocument, unstable_useDocumentActions, buildValidParams } from "@strapi/content-manager/strapi-admin";
11
12
  import { useParams, Link, useNavigate, matchPath } from "react-router-dom";
12
13
  import * as qs from "qs";
@@ -47,9 +48,7 @@ const CheckboxConfirmation = ({
47
48
  };
48
49
  const handleConfirm = () => {
49
50
  onChange({ target: { name, value: false, type: "checkbox" } });
50
- setIsOpen(false);
51
51
  };
52
- const handleToggle = () => setIsOpen((prev) => !prev);
53
52
  const label = intlLabel.id ? formatMessage(
54
53
  { id: intlLabel.id, defaultMessage: intlLabel.defaultMessage },
55
54
  { ...intlLabel.values }
@@ -58,35 +57,36 @@ const CheckboxConfirmation = ({
58
57
  { id: description.id, defaultMessage: description.defaultMessage },
59
58
  { ...description.values }
60
59
  ) : "";
61
- return /* @__PURE__ */ jsxs(Fragment, { children: [
60
+ return /* @__PURE__ */ jsxs(Dialog.Root, { open: isOpen, onOpenChange: setIsOpen, children: [
62
61
  /* @__PURE__ */ jsxs(Field.Root, { hint, name, children: [
63
- /* @__PURE__ */ jsx(Checkbox, { onValueChange: handleChange, value, type: "checkbox", children: label }),
62
+ /* @__PURE__ */ jsx(Checkbox, { onCheckedChange: handleChange, checked: value, children: label }),
64
63
  /* @__PURE__ */ jsx(Field.Hint, {})
65
64
  ] }),
66
- isOpen && /* @__PURE__ */ jsxs(Dialog, { onClose: handleToggle, title: "Confirmation", isOpen, children: [
67
- /* @__PURE__ */ jsx(DialogBody, { icon: /* @__PURE__ */ jsx(WarningCircle, {}), children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
68
- /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(TextAlignTypography, { id: "confirm-description", children: formatMessage({
65
+ /* @__PURE__ */ jsxs(Dialog.Content, { children: [
66
+ /* @__PURE__ */ jsx(Dialog.Header, { children: formatMessage({
67
+ id: getTranslation("CheckboxConfirmation.Modal.title"),
68
+ defaultMessage: "Disable localization"
69
+ }) }),
70
+ /* @__PURE__ */ jsx(Dialog.Body, { icon: /* @__PURE__ */ jsx(WarningCircle, {}), children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
71
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(TextAlignTypography, { children: formatMessage({
69
72
  id: getTranslation("CheckboxConfirmation.Modal.content"),
70
73
  defaultMessage: "Disabling localization will engender the deletion of all your content but the one associated to your default locale (if existing)."
71
74
  }) }) }),
72
- /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold", id: "confirm-description", children: formatMessage({
75
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold", children: formatMessage({
73
76
  id: getTranslation("CheckboxConfirmation.Modal.body"),
74
77
  defaultMessage: "Do you want to disable it?"
75
78
  }) }) })
76
79
  ] }) }),
77
- /* @__PURE__ */ jsx(
78
- DialogFooter,
79
- {
80
- startAction: /* @__PURE__ */ jsx(Button$1, { onClick: handleToggle, variant: "tertiary", children: formatMessage({
81
- id: "components.popUpWarning.button.cancel",
82
- defaultMessage: "No, cancel"
83
- }) }),
84
- endAction: /* @__PURE__ */ jsx(Button$1, { variant: "danger-light", onClick: handleConfirm, children: formatMessage({
85
- id: getTranslation("CheckboxConfirmation.Modal.button-confirm"),
86
- defaultMessage: "Yes, disable"
87
- }) })
88
- }
89
- )
80
+ /* @__PURE__ */ jsxs(Dialog.Footer, { children: [
81
+ /* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", children: formatMessage({
82
+ id: "components.popUpWarning.button.cancel",
83
+ defaultMessage: "No, cancel"
84
+ }) }) }),
85
+ /* @__PURE__ */ jsx(Dialog.Action, { children: /* @__PURE__ */ jsx(Button, { variant: "danger-light", onClick: handleConfirm, children: formatMessage({
86
+ id: getTranslation("CheckboxConfirmation.Modal.button-confirm"),
87
+ defaultMessage: "Yes, disable"
88
+ }) }) })
89
+ ] })
90
90
  ] })
91
91
  ] });
92
92
  };
@@ -137,7 +137,7 @@ const useI18n = () => {
137
137
  model: params.slug
138
138
  },
139
139
  {
140
- skip: !params.slug || !params.collectionType
140
+ skip: true
141
141
  }
142
142
  );
143
143
  if (doesPluginOptionsHaveI18nLocalized(schema?.pluginOptions)) {
@@ -217,10 +217,94 @@ const relationsApi = i18nApi.injectEndpoints({
217
217
  })
218
218
  });
219
219
  const { useGetManyDraftRelationCountQuery } = relationsApi;
220
+ const cleanData = (data, schema, components) => {
221
+ const cleanedData = removeFields(data, [
222
+ "createdAt",
223
+ "createdBy",
224
+ "updatedAt",
225
+ "updatedBy",
226
+ "id",
227
+ "documentId",
228
+ "publishedAt",
229
+ "strapi_stage",
230
+ "strapi_assignee",
231
+ "locale",
232
+ "status"
233
+ ]);
234
+ const cleanedDataWithoutPasswordAndRelation = recursiveRemoveFieldTypes(
235
+ cleanedData,
236
+ schema,
237
+ components,
238
+ ["relation", "password"]
239
+ );
240
+ return cleanedDataWithoutPasswordAndRelation;
241
+ };
242
+ const removeFields = (data, fields) => {
243
+ return Object.keys(data).reduce((acc, current) => {
244
+ if (fields.includes(current)) {
245
+ return acc;
246
+ }
247
+ acc[current] = data[current];
248
+ return acc;
249
+ }, {});
250
+ };
251
+ const recursiveRemoveFieldTypes = (data, schema, components, fields) => {
252
+ return Object.keys(data).reduce((acc, current) => {
253
+ const attribute = schema.attributes[current] ?? { type: void 0 };
254
+ if (fields.includes(attribute.type)) {
255
+ return acc;
256
+ }
257
+ if (attribute.type === "dynamiczone") {
258
+ acc[current] = data[current].map((componentValue, index2) => {
259
+ const { id: _, ...rest } = recursiveRemoveFieldTypes(
260
+ componentValue,
261
+ components[componentValue.__component],
262
+ components,
263
+ fields
264
+ );
265
+ return {
266
+ ...rest,
267
+ __temp_key__: index2 + 1
268
+ };
269
+ });
270
+ } else if (attribute.type === "component") {
271
+ const { repeatable, component } = attribute;
272
+ if (repeatable) {
273
+ acc[current] = (data[current] ?? []).map((compoData, index2) => {
274
+ const { id: _, ...rest } = recursiveRemoveFieldTypes(
275
+ compoData,
276
+ components[component],
277
+ components,
278
+ fields
279
+ );
280
+ return {
281
+ ...rest,
282
+ __temp_key__: index2 + 1
283
+ };
284
+ });
285
+ } else {
286
+ const { id: _, ...rest } = recursiveRemoveFieldTypes(
287
+ data[current] ?? {},
288
+ components[component],
289
+ components,
290
+ fields
291
+ );
292
+ acc[current] = rest;
293
+ }
294
+ } else {
295
+ acc[current] = data[current];
296
+ }
297
+ return acc;
298
+ }, {});
299
+ };
220
300
  const isErrorMessageDescriptor = (object) => {
221
301
  return typeof object === "object" && object !== null && "id" in object && "defaultMessage" in object;
222
302
  };
223
- const EntryValidationText = ({ status = "draft", validationErrors }) => {
303
+ const EntryValidationText = ({
304
+ status = "draft",
305
+ validationErrors,
306
+ action
307
+ }) => {
224
308
  const { formatMessage } = useIntl();
225
309
  const getErrorStr = (key, value) => {
226
310
  if (typeof value === "string") {
@@ -254,30 +338,63 @@ const EntryValidationText = ({ status = "draft", validationErrors }) => {
254
338
  ) })
255
339
  ] });
256
340
  }
257
- if (status === "published") {
258
- return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
259
- /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
260
- /* @__PURE__ */ jsx(Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
261
- id: "content-manager.bulk-publish.already-published",
262
- defaultMessage: "Already Published"
263
- }) })
264
- ] });
265
- }
266
- if (status === "modified") {
267
- return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
268
- /* @__PURE__ */ jsx(ArrowsCounterClockwise, { fill: "alternative600" }),
269
- /* @__PURE__ */ jsx(Typography, { children: formatMessage({
270
- id: "app.utils.ready-to-publish-changes",
271
- defaultMessage: "Ready to publish changes"
272
- }) })
273
- ] });
274
- }
341
+ const getStatusMessage = () => {
342
+ if (action === "bulk-publish") {
343
+ if (status === "published") {
344
+ return {
345
+ icon: /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
346
+ text: formatMessage({
347
+ id: "content-manager.bulk-publish.already-published",
348
+ defaultMessage: "Already Published"
349
+ }),
350
+ textColor: "success600",
351
+ fontWeight: "bold"
352
+ };
353
+ } else if (status === "modified") {
354
+ return {
355
+ icon: /* @__PURE__ */ jsx(ArrowsCounterClockwise, { fill: "alternative600" }),
356
+ text: formatMessage({
357
+ id: "app.utils.ready-to-publish-changes",
358
+ defaultMessage: "Ready to publish changes"
359
+ })
360
+ };
361
+ } else {
362
+ return {
363
+ icon: /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
364
+ text: formatMessage({
365
+ id: "app.utils.ready-to-publish",
366
+ defaultMessage: "Ready to publish"
367
+ })
368
+ };
369
+ }
370
+ } else {
371
+ if (status === "draft") {
372
+ return {
373
+ icon: /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
374
+ text: formatMessage({
375
+ id: "content-manager.bulk-unpublish.already-unpublished",
376
+ defaultMessage: "Already Unpublished"
377
+ }),
378
+ textColor: "success600",
379
+ fontWeight: "bold"
380
+ };
381
+ } else {
382
+ return {
383
+ icon: /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
384
+ text: formatMessage({
385
+ id: "app.utils.ready-to-unpublish-changes",
386
+ defaultMessage: "Ready to unpublish"
387
+ }),
388
+ textColor: "success600",
389
+ fontWeight: "bold"
390
+ };
391
+ }
392
+ }
393
+ };
394
+ const { icon, text, textColor = "success600", fontWeight = "normal" } = getStatusMessage();
275
395
  return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
276
- /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
277
- /* @__PURE__ */ jsx(Typography, { children: formatMessage({
278
- id: "app.utils.ready-to-publish",
279
- defaultMessage: "Ready to publish"
280
- }) })
396
+ icon,
397
+ /* @__PURE__ */ jsx(Typography, { textColor, fontWeight, children: text })
281
398
  ] });
282
399
  };
283
400
  const BoldChunk = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
@@ -285,7 +402,8 @@ const BulkLocaleActionModal = ({
285
402
  headers,
286
403
  rows,
287
404
  localesMetadata,
288
- validationErrors = {}
405
+ validationErrors = {},
406
+ action
289
407
  }) => {
290
408
  const { formatMessage } = useIntl();
291
409
  const selectedRows = useTable(
@@ -298,27 +416,29 @@ const BulkLocaleActionModal = ({
298
416
  return acc;
299
417
  }, {});
300
418
  const localesWithErrors = Object.keys(validationErrors);
301
- const alreadyPublishedCount = selectedRows.filter(
419
+ const publishedCount = selectedRows.filter(
302
420
  ({ locale }) => currentStatusByLocale[locale] === "published"
303
421
  ).length;
304
- const readyToPublishCount = selectedRows.filter(
422
+ const draftCount = selectedRows.filter(
305
423
  ({ locale }) => (currentStatusByLocale[locale] === "draft" || currentStatusByLocale[locale] === "modified") && !localesWithErrors.includes(locale)
306
424
  ).length;
307
425
  const withErrorsCount = localesWithErrors.length;
426
+ const messageId = action === "bulk-publish" ? "content-manager.containers.list.selectedEntriesModal.selectedCount.publish" : "content-manager.containers.list.selectedEntriesModal.selectedCount.unpublish";
427
+ 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.";
308
428
  return formatMessage(
309
429
  {
310
- id: "content-manager.containers.list.selectedEntriesModal.selectedCount",
311
- 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."
430
+ id: messageId,
431
+ defaultMessage
312
432
  },
313
433
  {
314
434
  withErrorsCount,
315
- readyToPublishCount,
316
- alreadyPublishedCount,
435
+ draftCount,
436
+ publishedCount,
317
437
  b: BoldChunk
318
438
  }
319
439
  );
320
440
  };
321
- return /* @__PURE__ */ jsxs(React.Fragment, { children: [
441
+ return /* @__PURE__ */ jsxs(Modal.Body, { children: [
322
442
  /* @__PURE__ */ jsx(Typography, { children: getFormattedCountMessage() }),
323
443
  /* @__PURE__ */ jsx(Box, { marginTop: 5, children: /* @__PURE__ */ jsxs(Table.Content, { children: [
324
444
  /* @__PURE__ */ jsxs(Table.Head, { children: [
@@ -345,7 +465,7 @@ const BulkLocaleActionModal = ({
345
465
  children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
346
466
  }
347
467
  ) }) }),
348
- /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(EntryValidationText, { validationErrors: error, status }) }),
468
+ /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(EntryValidationText, { validationErrors: error, status, action }) }),
349
469
  /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(
350
470
  IconButton,
351
471
  {
@@ -362,7 +482,7 @@ const BulkLocaleActionModal = ({
362
482
  name: locale
363
483
  }
364
484
  ),
365
- borderWidth: 0,
485
+ variant: "ghost",
366
486
  children: /* @__PURE__ */ jsx(Pencil, {})
367
487
  }
368
488
  ) })
@@ -371,6 +491,48 @@ const BulkLocaleActionModal = ({
371
491
  ] }) })
372
492
  ] });
373
493
  };
494
+ const statusVariants = {
495
+ draft: "secondary",
496
+ published: "success",
497
+ modified: "alternative"
498
+ };
499
+ const LocaleOption = ({
500
+ isDraftAndPublishEnabled,
501
+ locale,
502
+ status,
503
+ entryExists
504
+ }) => {
505
+ const { formatMessage } = useIntl();
506
+ if (!entryExists) {
507
+ return formatMessage(
508
+ {
509
+ id: getTranslation("CMEditViewLocalePicker.locale.create"),
510
+ defaultMessage: "Create <bold>{locale}</bold> locale"
511
+ },
512
+ {
513
+ bold: (locale2) => /* @__PURE__ */ jsx("b", { children: locale2 }),
514
+ locale: locale.name
515
+ }
516
+ );
517
+ }
518
+ return /* @__PURE__ */ jsxs(Flex, { width: "100%", gap: 1, justifyContent: "space-between", children: [
519
+ /* @__PURE__ */ jsx(Typography, { children: locale.name }),
520
+ isDraftAndPublishEnabled ? /* @__PURE__ */ jsx(
521
+ Status,
522
+ {
523
+ display: "flex",
524
+ paddingLeft: "6px",
525
+ paddingRight: "6px",
526
+ paddingTop: "2px",
527
+ paddingBottom: "2px",
528
+ showBullet: false,
529
+ size: "S",
530
+ variant: statusVariants[status],
531
+ children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
532
+ }
533
+ ) : null
534
+ ] });
535
+ };
374
536
  const LocalePickerAction = ({
375
537
  document,
376
538
  meta,
@@ -382,7 +544,13 @@ const LocalePickerAction = ({
382
544
  const [{ query }, setQuery] = useQueryParams();
383
545
  const { hasI18n, canCreate, canRead } = useI18n();
384
546
  const { data: locales = [] } = useGetLocalesQuery();
385
- const { schema } = unstable_useDocument({ model, collectionType, documentId });
547
+ const currentDesiredLocale = query.plugins?.i18n?.locale;
548
+ const { schema } = unstable_useDocument({
549
+ model,
550
+ collectionType,
551
+ documentId,
552
+ params: { locale: currentDesiredLocale }
553
+ });
386
554
  const handleSelect = React.useCallback(
387
555
  (value) => {
388
556
  setQuery({
@@ -400,53 +568,47 @@ const LocalePickerAction = ({
400
568
  if (!Array.isArray(locales) || !hasI18n) {
401
569
  return;
402
570
  }
403
- const currentDesiredLocale = query.plugins?.i18n?.locale;
404
571
  const doesLocaleExist = locales.find((loc) => loc.code === currentDesiredLocale);
405
572
  const defaultLocale = locales.find((locale) => locale.isDefault);
406
573
  if (!doesLocaleExist && defaultLocale?.code) {
407
574
  handleSelect(defaultLocale.code);
408
575
  }
409
- }, [handleSelect, hasI18n, locales, query.plugins?.i18n?.locale]);
410
- if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
411
- return null;
412
- }
413
- const currentLocale = query.plugins?.i18n?.locale || locales.find((loc) => loc.isDefault)?.code;
576
+ }, [handleSelect, hasI18n, locales, currentDesiredLocale]);
577
+ const currentLocale = Array.isArray(locales) ? locales.find((locale) => locale.code === currentDesiredLocale) : void 0;
414
578
  const allCurrentLocales = [
415
- { status: getDocumentStatus(document, meta), locale: currentLocale },
579
+ { status: getDocumentStatus(document, meta), locale: currentLocale?.code },
416
580
  ...meta?.availableLocales ?? []
417
581
  ];
582
+ if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
583
+ return null;
584
+ }
418
585
  return {
419
586
  label: formatMessage({
420
587
  id: getTranslation("Settings.locales.modal.locales.label"),
421
588
  defaultMessage: "Locales"
422
589
  }),
423
590
  options: locales.map((locale) => {
591
+ const entryWithLocaleExists = allCurrentLocales.some((doc) => doc.locale === locale.code);
424
592
  const currentLocaleDoc = allCurrentLocales.find(
425
593
  (doc) => "locale" in doc ? doc.locale === locale.code : false
426
594
  );
427
- const status = currentLocaleDoc?.status ?? "draft";
428
- const permissionsToCheck = currentLocaleDoc ? canCreate : canRead;
429
- const statusVariant = status === "draft" ? "primary" : status === "published" ? "success" : "alternative";
595
+ const permissionsToCheck = currentLocaleDoc ? canRead : canCreate;
430
596
  return {
431
597
  disabled: !permissionsToCheck.includes(locale.code),
432
598
  value: locale.code,
433
- label: locale.name,
434
- startIcon: schema?.options?.draftAndPublish ? /* @__PURE__ */ jsx(
435
- Status,
599
+ label: /* @__PURE__ */ jsx(
600
+ LocaleOption,
436
601
  {
437
- display: "flex",
438
- paddingLeft: "6px",
439
- paddingRight: "6px",
440
- paddingTop: "2px",
441
- paddingBottom: "2px",
442
- showBullet: false,
443
- size: "S",
444
- variant: statusVariant,
445
- children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
602
+ isDraftAndPublishEnabled: !!schema?.options?.draftAndPublish,
603
+ locale,
604
+ status: currentLocaleDoc?.status,
605
+ entryExists: entryWithLocaleExists
446
606
  }
447
- ) : null
607
+ ),
608
+ startIcon: !entryWithLocaleExists ? /* @__PURE__ */ jsx(Plus, {}) : null
448
609
  };
449
610
  }),
611
+ customizeContent: () => currentLocale?.name,
450
612
  onSelect: handleSelect,
451
613
  value: currentLocale
452
614
  };
@@ -462,6 +624,95 @@ const getDocumentStatus = (document, meta) => {
462
624
  }
463
625
  return docStatus;
464
626
  };
627
+ const FillFromAnotherLocaleAction = ({
628
+ documentId,
629
+ meta,
630
+ model,
631
+ collectionType
632
+ }) => {
633
+ const { formatMessage } = useIntl();
634
+ const [{ query }] = useQueryParams();
635
+ const currentDesiredLocale = query.plugins?.i18n?.locale;
636
+ const [localeSelected, setLocaleSelected] = React.useState(null);
637
+ const setValues = useForm("FillFromAnotherLocale", (state) => state.setValues);
638
+ const { getDocument } = unstable_useDocumentActions();
639
+ const { schema, components } = unstable_useDocument({
640
+ model,
641
+ documentId,
642
+ collectionType,
643
+ params: { locale: currentDesiredLocale }
644
+ });
645
+ const { data: locales = [] } = useGetLocalesQuery();
646
+ const availableLocales = Array.isArray(locales) ? locales.filter((locale) => meta?.availableLocales.some((l) => l.locale === locale.code)) : [];
647
+ const fillFromLocale = (onClose) => async () => {
648
+ const response = await getDocument({
649
+ collectionType,
650
+ model,
651
+ documentId,
652
+ params: { locale: localeSelected }
653
+ });
654
+ if (!response || !schema) {
655
+ return;
656
+ }
657
+ const { data } = response;
658
+ const cleanedData = cleanData(data, schema, components);
659
+ setValues(cleanedData);
660
+ onClose();
661
+ };
662
+ return {
663
+ type: "icon",
664
+ icon: /* @__PURE__ */ jsx(Download, {}),
665
+ disabled: availableLocales.length === 0,
666
+ label: formatMessage({
667
+ id: getTranslation("CMEditViewCopyLocale.copy-text"),
668
+ defaultMessage: "Fill in from another locale"
669
+ }),
670
+ dialog: {
671
+ type: "dialog",
672
+ title: formatMessage({
673
+ id: getTranslation("CMEditViewCopyLocale.dialog.title"),
674
+ defaultMessage: "Confirmation"
675
+ }),
676
+ content: ({ onClose }) => /* @__PURE__ */ jsxs(Fragment, { children: [
677
+ /* @__PURE__ */ jsx(Dialog.Body, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 3, children: [
678
+ /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
679
+ /* @__PURE__ */ jsx(Typography, { textAlign: "center", children: formatMessage({
680
+ id: getTranslation("CMEditViewCopyLocale.dialog.body"),
681
+ defaultMessage: "Your current content will be erased and filled by the content of the selected locale:"
682
+ }) }),
683
+ /* @__PURE__ */ jsxs(Field.Root, { width: "100%", children: [
684
+ /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
685
+ id: getTranslation("CMEditViewCopyLocale.dialog.field.label"),
686
+ defaultMessage: "Locale"
687
+ }) }),
688
+ /* @__PURE__ */ jsx(
689
+ SingleSelect,
690
+ {
691
+ value: localeSelected,
692
+ placeholder: formatMessage({
693
+ id: getTranslation("CMEditViewCopyLocale.dialog.field.placeholder"),
694
+ defaultMessage: "Select one locale..."
695
+ }),
696
+ onChange: (value) => setLocaleSelected(value),
697
+ children: availableLocales.map((locale) => /* @__PURE__ */ jsx(SingleSelectOption, { value: locale.code, children: locale.name }, locale.code))
698
+ }
699
+ )
700
+ ] })
701
+ ] }) }),
702
+ /* @__PURE__ */ jsx(Dialog.Footer, { children: /* @__PURE__ */ jsxs(Flex, { gap: 2, width: "100%", children: [
703
+ /* @__PURE__ */ jsx(Button, { flex: "auto", variant: "tertiary", onClick: onClose, children: formatMessage({
704
+ id: getTranslation("CMEditViewCopyLocale.cancel-text"),
705
+ defaultMessage: "No, cancel"
706
+ }) }),
707
+ /* @__PURE__ */ jsx(Button, { flex: "auto", variant: "success", onClick: fillFromLocale(onClose), children: formatMessage({
708
+ id: getTranslation("CMEditViewCopyLocale.submit-text"),
709
+ defaultMessage: "Yes, fill in"
710
+ }) })
711
+ ] }) })
712
+ ] })
713
+ }
714
+ };
715
+ };
465
716
  const DeleteLocaleAction = ({
466
717
  document,
467
718
  documentId,
@@ -473,16 +724,23 @@ const DeleteLocaleAction = ({
473
724
  const { toggleNotification } = useNotification();
474
725
  const { delete: deleteAction } = unstable_useDocumentActions();
475
726
  const { hasI18n, canDelete } = useI18n();
727
+ const [{ query }] = useQueryParams();
728
+ const { data: locales = [] } = useGetLocalesQuery();
729
+ const currentDesiredLocale = query.plugins?.i18n?.locale;
730
+ const locale = !("error" in locales) && locales.find((loc) => loc.code === currentDesiredLocale);
476
731
  if (!hasI18n) {
477
732
  return null;
478
733
  }
479
734
  return {
480
735
  disabled: document?.locale && !canDelete.includes(document.locale) || !document || !document.id,
481
736
  position: ["header", "table-row"],
482
- label: formatMessage({
483
- id: getTranslation("actions.delete.label"),
484
- defaultMessage: "Delete locale"
485
- }),
737
+ label: formatMessage(
738
+ {
739
+ id: getTranslation("actions.delete.label"),
740
+ defaultMessage: "Delete entry ({locale})"
741
+ },
742
+ { locale: locale && locale.name }
743
+ ),
486
744
  icon: /* @__PURE__ */ jsx(StyledTrash, {}),
487
745
  variant: "danger",
488
746
  dialog: {
@@ -499,7 +757,12 @@ const DeleteLocaleAction = ({
499
757
  }) })
500
758
  ] }),
501
759
  onConfirm: async () => {
502
- if (!documentId || !document?.locale) {
760
+ const unableToDelete = (
761
+ // We are unable to delete a collection type without a document ID
762
+ // & unable to delete generally if there is no document locale
763
+ collectionType !== "single-types" && !documentId || !document?.locale
764
+ );
765
+ if (unableToDelete) {
503
766
  console.error(
504
767
  "You're trying to delete a document without an id or locale, this is likely a bug with Strapi. Please open an issue."
505
768
  );
@@ -525,37 +788,43 @@ const DeleteLocaleAction = ({
525
788
  }
526
789
  };
527
790
  };
528
- const BulkLocalePublishAction = ({
791
+ const BulkLocaleAction = ({
529
792
  document: baseDocument,
530
793
  documentId,
531
794
  model,
532
- collectionType
795
+ collectionType,
796
+ action
533
797
  }) => {
534
798
  const baseLocale = baseDocument?.locale ?? null;
535
799
  const [{ query }] = useQueryParams();
536
800
  const params = React.useMemo(() => buildValidParams(query), [query]);
537
- const isPublishedTab = query.status === "published";
801
+ const isOnPublishedTab = query.status === "published";
538
802
  const { formatMessage } = useIntl();
539
803
  const { hasI18n, canPublish } = useI18n();
540
804
  const { toggleNotification } = useNotification();
541
805
  const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
542
806
  const [selectedRows, setSelectedRows] = React.useState([]);
543
- const [isConfirmationOpen, setIsConfirmationOpen] = React.useState(false);
544
- const { publishMany: publishManyAction } = unstable_useDocumentActions();
807
+ const [isDraftRelationConfirmationOpen, setIsDraftRelationConfirmationOpen] = React.useState(false);
808
+ const { publishMany: publishManyAction, unpublishMany: unpublishManyAction } = unstable_useDocumentActions();
545
809
  const {
546
810
  document,
547
811
  meta: documentMeta,
548
812
  schema,
549
813
  validate
550
- } = unstable_useDocument({
551
- model,
552
- collectionType,
553
- documentId,
554
- params: {
555
- locale: baseLocale
814
+ } = unstable_useDocument(
815
+ {
816
+ model,
817
+ collectionType,
818
+ documentId,
819
+ params: {
820
+ locale: baseLocale
821
+ }
822
+ },
823
+ {
824
+ skip: !hasI18n || !baseLocale
556
825
  }
557
- });
558
- const { data: localesMetadata = [] } = useGetLocalesQuery();
826
+ );
827
+ const { data: localesMetadata = [] } = useGetLocalesQuery(hasI18n ? void 0 : skipToken);
559
828
  const headers = [
560
829
  {
561
830
  label: formatMessage({
@@ -604,12 +873,19 @@ const BulkLocalePublishAction = ({
604
873
  }, {});
605
874
  return [rowsFromMeta, errors];
606
875
  }, [document, documentMeta?.availableLocales, validate]);
607
- const localesToPublish = selectedRows.reduce((acc, selectedRow) => {
608
- if (selectedRow.status !== "published" && !Object.keys(validationErrors).includes(selectedRow.locale)) {
876
+ const isBulkPublish = action === "bulk-publish";
877
+ const localesForAction = selectedRows.reduce((acc, selectedRow) => {
878
+ const isValidLocale = (
879
+ // Validation errors are irrelevant if we are trying to unpublish
880
+ !isBulkPublish || !Object.keys(validationErrors).includes(selectedRow.locale)
881
+ );
882
+ const shouldAddLocale = isBulkPublish ? selectedRow.status !== "published" && isValidLocale : selectedRow.status !== "draft" && isValidLocale;
883
+ if (shouldAddLocale) {
609
884
  acc.push(selectedRow.locale);
610
885
  }
611
886
  return acc;
612
887
  }, []);
888
+ const enableDraftRelationsCount = false;
613
889
  const {
614
890
  data: draftRelationsCount = 0,
615
891
  isLoading: isDraftRelationsLoading,
@@ -618,10 +894,10 @@ const BulkLocalePublishAction = ({
618
894
  {
619
895
  model,
620
896
  documentIds: [documentId],
621
- locale: localesToPublish
897
+ locale: localesForAction
622
898
  },
623
899
  {
624
- skip: !documentId || localesToPublish.length === 0
900
+ skip: !enableDraftRelationsCount
625
901
  }
626
902
  );
627
903
  React.useEffect(() => {
@@ -647,23 +923,32 @@ const BulkLocalePublishAction = ({
647
923
  documentIds: [documentId],
648
924
  params: {
649
925
  ...params,
650
- locale: localesToPublish
926
+ locale: localesForAction
927
+ }
928
+ });
929
+ setSelectedRows([]);
930
+ };
931
+ const unpublish = async () => {
932
+ await unpublishManyAction({
933
+ model,
934
+ documentIds: [documentId],
935
+ params: {
936
+ ...params,
937
+ locale: localesForAction
651
938
  }
652
939
  });
653
940
  setSelectedRows([]);
654
941
  };
655
942
  const handleAction = async () => {
656
943
  if (draftRelationsCount > 0) {
657
- setIsConfirmationOpen(true);
658
- } else {
944
+ setIsDraftRelationConfirmationOpen(true);
945
+ } else if (isBulkPublish) {
659
946
  await publish();
947
+ } else {
948
+ await unpublish();
660
949
  }
661
950
  };
662
- const isUnpublish = document?.status === "published";
663
- if (isUnpublish) {
664
- console.warn(["I18N"], "Bulk locale unpublish modal not implemented");
665
- }
666
- if (isConfirmationOpen) {
951
+ if (isDraftRelationConfirmationOpen) {
667
952
  return {
668
953
  label: formatMessage({
669
954
  id: "app.components.ConfirmDialog.title",
@@ -672,11 +957,11 @@ const BulkLocalePublishAction = ({
672
957
  variant: "danger",
673
958
  dialog: {
674
959
  onCancel: () => {
675
- setIsConfirmationOpen(false);
960
+ setIsDraftRelationConfirmationOpen(false);
676
961
  },
677
962
  onConfirm: async () => {
678
963
  await publish();
679
- setIsConfirmationOpen(false);
964
+ setIsDraftRelationConfirmationOpen(false);
680
965
  },
681
966
  type: "dialog",
682
967
  title: formatMessage({
@@ -686,27 +971,32 @@ const BulkLocalePublishAction = ({
686
971
  content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "center", gap: 2, children: [
687
972
  /* @__PURE__ */ jsx(WarningCircle, { width: "2.4rem", height: "2.4rem", fill: "danger600" }),
688
973
  /* @__PURE__ */ jsx(Typography, { textAlign: "center", children: formatMessage({
689
- id: "content-manager.actions.discard.dialog.body",
690
- defaultMessage: "Are you sure you want to discard the changes? This action is irreversible."
974
+ id: getTranslation("CMEditViewBulkLocale.draft-relation-warning"),
975
+ defaultMessage: "Some locales are related to draft entries. Publishing them could leave broken links in your app."
976
+ }) }),
977
+ /* @__PURE__ */ jsx(Typography, { textAlign: "center", children: formatMessage({
978
+ id: getTranslation("CMEditViewBulkLocale.continue-confirmation"),
979
+ defaultMessage: "Are you sure you want to continue?"
691
980
  }) })
692
981
  ] })
693
982
  }
694
983
  };
695
984
  }
985
+ const hasPermission = selectedRows.map(({ locale }) => locale).every((locale) => canPublish.includes(locale));
696
986
  return {
697
987
  label: formatMessage({
698
- id: getTranslation("CMEditViewBulkLocale.publish-title"),
699
- defaultMessage: "Publish Multiple Locales"
988
+ id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
989
+ defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
700
990
  }),
701
- icon: /* @__PURE__ */ jsx(ListPlus, {}),
702
- disabled: isPublishedTab || !canPublish,
991
+ variant: isBulkPublish ? "secondary" : "danger",
992
+ icon: isBulkPublish ? /* @__PURE__ */ jsx(ListPlus, {}) : /* @__PURE__ */ jsx(Cross, {}),
993
+ disabled: isOnPublishedTab || canPublish.length === 0,
703
994
  position: ["panel"],
704
- variant: "secondary",
705
995
  dialog: {
706
996
  type: "modal",
707
997
  title: formatMessage({
708
- id: getTranslation("CMEditViewBulkLocale.publish-title"),
709
- defaultMessage: "Publish Multiple Locales"
998
+ id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
999
+ defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
710
1000
  }),
711
1001
  content: () => {
712
1002
  return /* @__PURE__ */ jsx(
@@ -725,28 +1015,35 @@ const BulkLocalePublishAction = ({
725
1015
  validationErrors,
726
1016
  headers,
727
1017
  rows,
728
- localesMetadata
1018
+ localesMetadata,
1019
+ action: action ?? "bulk-publish"
729
1020
  }
730
1021
  )
731
1022
  }
732
1023
  );
733
1024
  },
734
- footer: () => /* @__PURE__ */ jsx(Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsx(
735
- Button$1,
1025
+ footer: () => /* @__PURE__ */ jsx(Modal.Footer, { justifyContent: "flex-end", children: /* @__PURE__ */ jsx(
1026
+ Button,
736
1027
  {
737
1028
  loading: isDraftRelationsLoading,
738
- disabled: localesToPublish.length === 0,
1029
+ disabled: !hasPermission || localesForAction.length === 0,
739
1030
  variant: "default",
740
1031
  onClick: handleAction,
741
1032
  children: formatMessage({
742
- id: "app.utils.publish",
743
- defaultMessage: "Publish"
1033
+ id: isBulkPublish ? "app.utils.publish" : "app.utils.unpublish",
1034
+ defaultMessage: isBulkPublish ? "Publish" : "Unpublish"
744
1035
  })
745
1036
  }
746
1037
  ) })
747
1038
  }
748
1039
  };
749
1040
  };
1041
+ const BulkLocalePublishAction = (props) => {
1042
+ return BulkLocaleAction({ action: "bulk-publish", ...props });
1043
+ };
1044
+ const BulkLocaleUnpublishAction = (props) => {
1045
+ return BulkLocaleAction({ action: "bulk-unpublish", ...props });
1046
+ };
750
1047
  const StyledTrash = styled(Trash)`
751
1048
  path {
752
1049
  fill: currentColor;
@@ -803,13 +1100,6 @@ const UnpublishModalAdditionalInfo = () => {
803
1100
  }
804
1101
  ) });
805
1102
  };
806
- const Initializer = ({ setPlugin }) => {
807
- const setPluginRef = React.useRef(setPlugin);
808
- React.useEffect(() => {
809
- setPluginRef.current(pluginId);
810
- }, []);
811
- return null;
812
- };
813
1103
  const LocalePicker = () => {
814
1104
  const { formatMessage } = useIntl();
815
1105
  const [{ query }, setQuery] = useQueryParams();
@@ -869,7 +1159,7 @@ const PERMISSIONS = {
869
1159
  read: [{ action: "plugin::i18n.locale.read", subject: null }]
870
1160
  };
871
1161
  const mutateEditViewHook = ({ layout }) => {
872
- if ("i18n" in layout.options && typeof layout.options.i18n === "object" && layout.options.i18n !== null && "localized" in layout.options.i18n && !layout.options.i18n.localized) {
1162
+ if (!("i18n" in layout.options) || typeof layout.options.i18n === "object" && layout.options.i18n !== null && "localized" in layout.options.i18n && !layout.options.i18n.localized) {
873
1163
  return { layout };
874
1164
  }
875
1165
  const components = Object.entries(layout.components).reduce(
@@ -915,7 +1205,7 @@ const doesFieldHaveI18nPluginOpt = (pluginOpts) => {
915
1205
  const LabelAction = ({ title, icon }) => {
916
1206
  const { formatMessage } = useIntl();
917
1207
  return /* @__PURE__ */ jsxs(Span, { tag: "span", children: [
918
- /* @__PURE__ */ jsx(VisuallyHidden, { tag: "span", children: `(${formatMessage(title)})` }),
1208
+ /* @__PURE__ */ jsx(VisuallyHidden, { tag: "span", children: formatMessage(title) }),
919
1209
  React.cloneElement(icon, {
920
1210
  "aria-hidden": true,
921
1211
  focusable: false
@@ -950,13 +1240,7 @@ const LocaleListCell = ({
950
1240
  }
951
1241
  });
952
1242
  const { locale: language } = useIntl();
953
- const [visible, setVisible] = React.useState(false);
954
- const buttonRef = React.useRef(null);
955
1243
  const { data: locales = [] } = useGetLocalesQuery();
956
- const handleTogglePopover = (e) => {
957
- e.stopPropagation();
958
- setVisible((prev) => !prev);
959
- };
960
1244
  const formatter = useCollator(language, {
961
1245
  sensitivity: "base"
962
1246
  });
@@ -978,64 +1262,14 @@ const LocaleListCell = ({
978
1262
  }
979
1263
  return locale.name;
980
1264
  }).toSorted((a, b) => formatter.compare(a, b));
981
- return /* @__PURE__ */ jsxs(Button, { type: "button", onClick: handleTogglePopover, ref: buttonRef, children: [
982
- /* @__PURE__ */ jsxs(
983
- ActionWrapper,
984
- {
985
- minWidth: "100%",
986
- alignItems: "center",
987
- justifyContent: "center",
988
- height: "3.2rem",
989
- width: "3.2rem",
990
- children: [
991
- /* @__PURE__ */ jsx(Typography, { textColor: "neutral800", ellipsis: true, children: localesForDocument.join(", ") }),
992
- /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(CaretDown, {}) })
993
- ]
994
- }
995
- ),
996
- visible && /* @__PURE__ */ jsx(
997
- Popover,
998
- {
999
- onDismiss: () => setVisible(false),
1000
- source: buttonRef,
1001
- spacing: 16,
1002
- centered: true,
1003
- children: /* @__PURE__ */ jsx("ul", { children: localesForDocument.map((name) => /* @__PURE__ */ jsx(Box, { padding: 3, tag: "li", children: /* @__PURE__ */ jsx(Typography, { children: name }) }, name)) })
1004
- }
1005
- )
1265
+ return /* @__PURE__ */ jsxs(Popover.Root, { children: [
1266
+ /* @__PURE__ */ jsx(Popover.Trigger, { children: /* @__PURE__ */ jsx(Button, { variant: "ghost", type: "button", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxs(Flex, { minWidth: "100%", alignItems: "center", justifyContent: "center", fontWeight: "regular", children: [
1267
+ /* @__PURE__ */ jsx(Typography, { textColor: "neutral800", ellipsis: true, marginRight: 2, children: localesForDocument.join(", ") }),
1268
+ /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(CaretDown, { width: "1.2rem", height: "1.2rem" }) })
1269
+ ] }) }) }),
1270
+ /* @__PURE__ */ jsx(Popover.Content, { sideOffset: 16, children: /* @__PURE__ */ jsx("ul", { children: localesForDocument.map((name) => /* @__PURE__ */ jsx(Box, { padding: 3, tag: "li", children: /* @__PURE__ */ jsx(Typography, { children: name }) }, name)) }) })
1006
1271
  ] });
1007
1272
  };
1008
- const Button = styled.button`
1009
- width: 100%;
1010
-
1011
- svg {
1012
- > g,
1013
- path {
1014
- fill: ${({ theme }) => theme.colors.neutral500};
1015
- }
1016
- }
1017
- &:hover {
1018
- svg {
1019
- > g,
1020
- path {
1021
- fill: ${({ theme }) => theme.colors.neutral600};
1022
- }
1023
- }
1024
- }
1025
- &:active {
1026
- svg {
1027
- > g,
1028
- path {
1029
- fill: ${({ theme }) => theme.colors.neutral400};
1030
- }
1031
- }
1032
- }
1033
- `;
1034
- const ActionWrapper = styled(Flex)`
1035
- svg {
1036
- height: 0.4rem;
1037
- }
1038
- `;
1039
1273
  const addColumnToTableHook = ({ displayedHeaders, layout }) => {
1040
1274
  const { options } = layout;
1041
1275
  const isFieldLocalized = doesPluginOptionsHaveI18nLocalized(options) ? options.i18n.localized : false;
@@ -1064,18 +1298,11 @@ const addColumnToTableHook = ({ displayedHeaders, layout }) => {
1064
1298
  const addLocaleToReleasesHook = ({ displayedHeaders = [] }) => {
1065
1299
  return {
1066
1300
  displayedHeaders: [
1067
- // TODO: Fix when migrating to v5
1068
- // ...displayedHeaders,
1301
+ ...displayedHeaders,
1069
1302
  {
1070
- key: "__locale__",
1071
- fieldSchema: { type: "string" },
1072
- metadatas: {
1073
- label: {
1074
- id: "content-releases.page.ReleaseDetails.table.header.label.locale",
1075
- defaultMessage: "locale"
1076
- },
1077
- searchable: false,
1078
- sortable: false
1303
+ label: {
1304
+ id: "content-releases.page.ReleaseDetails.table.header.label.locale",
1305
+ defaultMessage: "locale"
1079
1306
  },
1080
1307
  name: "locale"
1081
1308
  }
@@ -1223,8 +1450,6 @@ const index = {
1223
1450
  app.addRBACMiddleware([localeMiddleware]);
1224
1451
  app.registerPlugin({
1225
1452
  id: pluginId,
1226
- initializer: Initializer,
1227
- isReady: false,
1228
1453
  name: pluginId
1229
1454
  });
1230
1455
  },
@@ -1242,11 +1467,11 @@ const index = {
1242
1467
  },
1243
1468
  id: "internationalization",
1244
1469
  to: "internationalization",
1245
- Component: () => import("./SettingsPage-0FFSTUW2.mjs").then((mod) => ({ default: mod.ProtectedSettingsPage })),
1470
+ Component: () => import("./SettingsPage-DbRFoF_H.mjs").then((mod) => ({ default: mod.ProtectedSettingsPage })),
1246
1471
  permissions: PERMISSIONS.accessMain
1247
1472
  });
1248
1473
  const contentManager = app.getPlugin("content-manager");
1249
- contentManager.apis.addDocumentHeaderAction([LocalePickerAction]);
1474
+ contentManager.apis.addDocumentHeaderAction([LocalePickerAction, FillFromAnotherLocaleAction]);
1250
1475
  contentManager.apis.addDocumentAction((actions) => {
1251
1476
  const indexOfDeleteAction = actions.findIndex((action) => action.type === "delete");
1252
1477
  actions.splice(indexOfDeleteAction, 0, DeleteLocaleAction);
@@ -1254,6 +1479,7 @@ const index = {
1254
1479
  });
1255
1480
  contentManager.apis.addDocumentAction((actions) => {
1256
1481
  actions.splice(2, 0, BulkLocalePublishAction);
1482
+ actions.splice(5, 0, BulkLocaleUnpublishAction);
1257
1483
  return actions;
1258
1484
  });
1259
1485
  contentManager.injectComponent("listView", "actions", {
@@ -1359,7 +1585,7 @@ const index = {
1359
1585
  async registerTrads({ locales }) {
1360
1586
  const importedTrads = await Promise.all(
1361
1587
  locales.map((locale) => {
1362
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/de.json": () => import("./de-9eCAqqrB.mjs"), "./translations/dk.json": () => import("./dk-2qBjxt-P.mjs"), "./translations/en.json": () => import("./en-18tWw4P6.mjs"), "./translations/es.json": () => import("./es-DlmMVaBG.mjs"), "./translations/fr.json": () => import("./fr-3S6ke71d.mjs"), "./translations/ko.json": () => import("./ko-qTjQ8IMw.mjs"), "./translations/pl.json": () => import("./pl-B67TSHqT.mjs"), "./translations/ru.json": () => import("./ru-hagMa57T.mjs"), "./translations/tr.json": () => import("./tr-Dw_jmkG-.mjs"), "./translations/zh-Hans.json": () => import("./zh-Hans-Dyc-aR-h.mjs"), "./translations/zh.json": () => import("./zh-57YM4amO.mjs") }), `./translations/${locale}.json`).then(({ default: data }) => {
1588
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/de.json": () => import("./de-9eCAqqrB.mjs"), "./translations/dk.json": () => import("./dk-2qBjxt-P.mjs"), "./translations/en.json": () => import("./en-BYRZFDBV.mjs"), "./translations/es.json": () => import("./es-DlmMVaBG.mjs"), "./translations/fr.json": () => import("./fr-3S6ke71d.mjs"), "./translations/ko.json": () => import("./ko-qTjQ8IMw.mjs"), "./translations/pl.json": () => import("./pl-B67TSHqT.mjs"), "./translations/ru.json": () => import("./ru-hagMa57T.mjs"), "./translations/tr.json": () => import("./tr-Dw_jmkG-.mjs"), "./translations/zh-Hans.json": () => import("./zh-Hans-Dyc-aR-h.mjs"), "./translations/zh.json": () => import("./zh-57YM4amO.mjs") }), `./translations/${locale}.json`).then(({ default: data }) => {
1363
1589
  return {
1364
1590
  data: prefixPluginTranslations(data, pluginId),
1365
1591
  locale
@@ -1385,4 +1611,4 @@ export {
1385
1611
  index as i,
1386
1612
  useCreateLocaleMutation as u
1387
1613
  };
1388
- //# sourceMappingURL=index-BddUXwss.mjs.map
1614
+ //# sourceMappingURL=index-7_EUScSl.mjs.map