@strapi/i18n 0.0.0-experimental.e60ec1829240dae21c1e1d29076681c322288813 → 0.0.0-experimental.e9122b401c96877b6707775c4f893660eab93ae3

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 (47) hide show
  1. package/LICENSE +18 -3
  2. package/dist/_chunks/{SettingsPage-CeqfDjsb.mjs → SettingsPage-BjxjwEOb.mjs} +115 -126
  3. package/dist/_chunks/SettingsPage-BjxjwEOb.mjs.map +1 -0
  4. package/dist/_chunks/{SettingsPage-Djqsdrzs.js → SettingsPage-CfTmCkup.js} +115 -126
  5. package/dist/_chunks/SettingsPage-CfTmCkup.js.map +1 -0
  6. package/dist/_chunks/{en-CnrTsjWS.mjs → en-2xztdZE1.mjs} +12 -1
  7. package/dist/_chunks/en-2xztdZE1.mjs.map +1 -0
  8. package/dist/_chunks/{en-BuBc6LKZ.js → en-DWpfm8h5.js} +12 -1
  9. package/dist/_chunks/en-DWpfm8h5.js.map +1 -0
  10. package/dist/_chunks/{index-DMXJeGjN.js → index-5XLZwzwx.js} +711 -207
  11. package/dist/_chunks/index-5XLZwzwx.js.map +1 -0
  12. package/dist/_chunks/{index-BDU1w_fd.mjs → index-D-qx3tz4.mjs} +710 -204
  13. package/dist/_chunks/index-D-qx3tz4.mjs.map +1 -0
  14. package/dist/admin/index.js +1 -1
  15. package/dist/admin/index.mjs +2 -2
  16. package/dist/admin/src/components/BulkLocaleActionModal.d.ts +16 -0
  17. package/dist/admin/src/components/CMHeaderActions.d.ts +33 -3
  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/services/api.d.ts +2 -3
  21. package/dist/admin/src/services/locales.d.ts +1 -1
  22. package/dist/admin/src/services/relations.d.ts +7 -0
  23. package/dist/admin/src/utils/baseQuery.d.ts +4 -19
  24. package/dist/admin/src/utils/clean.d.ts +4 -0
  25. package/dist/admin/src/utils/schemas.d.ts +1 -0
  26. package/dist/server/index.js +38 -9
  27. package/dist/server/index.js.map +1 -1
  28. package/dist/server/index.mjs +39 -10
  29. package/dist/server/index.mjs.map +1 -1
  30. package/dist/server/src/bootstrap.d.ts.map +1 -1
  31. package/dist/server/src/index.d.ts +14 -2
  32. package/dist/server/src/index.d.ts.map +1 -1
  33. package/dist/server/src/services/index.d.ts +14 -2
  34. package/dist/server/src/services/index.d.ts.map +1 -1
  35. package/dist/server/src/services/permissions/actions.d.ts +14 -2
  36. package/dist/server/src/services/permissions/actions.d.ts.map +1 -1
  37. package/dist/server/src/services/permissions.d.ts +14 -2
  38. package/dist/server/src/services/permissions.d.ts.map +1 -1
  39. package/dist/shared/contracts/content-manager.d.ts +20 -1
  40. package/package.json +15 -16
  41. package/dist/_chunks/SettingsPage-CeqfDjsb.mjs.map +0 -1
  42. package/dist/_chunks/SettingsPage-Djqsdrzs.js.map +0 -1
  43. package/dist/_chunks/en-BuBc6LKZ.js.map +0 -1
  44. package/dist/_chunks/en-CnrTsjWS.mjs.map +0 -1
  45. package/dist/_chunks/index-BDU1w_fd.mjs.map +0 -1
  46. package/dist/_chunks/index-DMXJeGjN.js.map +0 -1
  47. package/dist/admin/src/components/Initializer.d.ts +0 -5
@@ -6,12 +6,11 @@ const React = require("react");
6
6
  const designSystem = require("@strapi/design-system");
7
7
  const icons = require("@strapi/icons");
8
8
  const reactIntl = require("react-intl");
9
- const styled = require("styled-components");
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");
13
- const react = require("@reduxjs/toolkit/query/react");
14
- const axios = require("axios");
15
14
  const qs = require("qs");
16
15
  const omit = require("lodash/omit");
17
16
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
@@ -36,7 +35,6 @@ function _interopNamespace(e) {
36
35
  const get__default = /* @__PURE__ */ _interopDefault(get);
37
36
  const yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
38
37
  const React__namespace = /* @__PURE__ */ _interopNamespace(React);
39
- const styled__default = /* @__PURE__ */ _interopDefault(styled);
40
38
  const qs__namespace = /* @__PURE__ */ _interopNamespace(qs);
41
39
  const omit__default = /* @__PURE__ */ _interopDefault(omit);
42
40
  const __variableDynamicImportRuntimeHelper = (glob, path) => {
@@ -50,7 +48,7 @@ const __variableDynamicImportRuntimeHelper = (glob, path) => {
50
48
  };
51
49
  const pluginId = "i18n";
52
50
  const getTranslation = (id) => `${pluginId}.${id}`;
53
- const TextAlignTypography = styled__default.default(designSystem.Typography)`
51
+ const TextAlignTypography = styledComponents.styled(designSystem.Typography)`
54
52
  text-align: center;
55
53
  `;
56
54
  const CheckboxConfirmation = ({
@@ -74,9 +72,7 @@ const CheckboxConfirmation = ({
74
72
  };
75
73
  const handleConfirm = () => {
76
74
  onChange({ target: { name, value: false, type: "checkbox" } });
77
- setIsOpen(false);
78
75
  };
79
- const handleToggle = () => setIsOpen((prev) => !prev);
80
76
  const label = intlLabel.id ? formatMessage(
81
77
  { id: intlLabel.id, defaultMessage: intlLabel.defaultMessage },
82
78
  { ...intlLabel.values }
@@ -85,43 +81,36 @@ const CheckboxConfirmation = ({
85
81
  { id: description.id, defaultMessage: description.defaultMessage },
86
82
  { ...description.values }
87
83
  ) : "";
88
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
89
- /* @__PURE__ */ jsxRuntime.jsx(
90
- designSystem.Checkbox,
91
- {
92
- hint,
93
- id: name,
94
- name,
95
- onValueChange: handleChange,
96
- value,
97
- type: "checkbox",
98
- children: label
99
- }
100
- ),
101
- isOpen && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog, { onClose: handleToggle, title: "Confirmation", isOpen, children: [
102
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.DialogBody, { icon: /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, {}), children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
103
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(TextAlignTypography, { id: "confirm-description", children: formatMessage({
84
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Root, { open: isOpen, onOpenChange: setIsOpen, children: [
85
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { hint, name, children: [
86
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Checkbox, { onCheckedChange: handleChange, checked: value, children: label }),
87
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {})
88
+ ] }),
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({
104
96
  id: getTranslation("CheckboxConfirmation.Modal.content"),
105
97
  defaultMessage: "Disabling localization will engender the deletion of all your content but the one associated to your default locale (if existing)."
106
98
  }) }) }),
107
- /* @__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({
108
100
  id: getTranslation("CheckboxConfirmation.Modal.body"),
109
101
  defaultMessage: "Do you want to disable it?"
110
102
  }) }) })
111
103
  ] }) }),
112
- /* @__PURE__ */ jsxRuntime.jsx(
113
- designSystem.DialogFooter,
114
- {
115
- startAction: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleToggle, variant: "tertiary", children: formatMessage({
116
- id: "components.popUpWarning.button.cancel",
117
- defaultMessage: "No, cancel"
118
- }) }),
119
- endAction: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "danger-light", onClick: handleConfirm, children: formatMessage({
120
- id: getTranslation("CheckboxConfirmation.Modal.button-confirm"),
121
- defaultMessage: "Yes, disable"
122
- }) })
123
- }
124
- )
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
+ ] })
125
114
  ] })
126
115
  ] });
127
116
  };
@@ -172,7 +161,7 @@ const useI18n = () => {
172
161
  model: params.slug
173
162
  },
174
163
  {
175
- skip: !params.slug || !params.collectionType
164
+ skip: true
176
165
  }
177
166
  );
178
167
  if (doesPluginOptionsHaveI18nLocalized(schema?.pluginOptions)) {
@@ -186,64 +175,8 @@ const useI18n = () => {
186
175
  ...actions
187
176
  };
188
177
  };
189
- const axiosBaseQuery = () => async (query, { signal }) => {
190
- try {
191
- const { get: get2, post, del, put } = strapiAdmin.getFetchClient();
192
- if (typeof query === "string") {
193
- const result = await get2(query, { signal });
194
- return { data: result.data };
195
- } else {
196
- const { url, method = "GET", data, config } = query;
197
- if (method === "POST") {
198
- const result2 = await post(url, data, { ...config, signal });
199
- return { data: result2.data };
200
- }
201
- if (method === "DELETE") {
202
- const result2 = await del(url, { ...config, signal });
203
- return { data: result2.data };
204
- }
205
- if (method === "PUT") {
206
- const result2 = await put(url, data, { ...config, signal });
207
- return { data: result2.data };
208
- }
209
- const result = await get2(url, { ...config, signal });
210
- return { data: result.data };
211
- }
212
- } catch (err) {
213
- if (axios.isAxiosError(err)) {
214
- if (typeof err.response?.data === "object" && err.response?.data !== null && "error" in err.response?.data) {
215
- return { data: void 0, error: err.response?.data.error };
216
- } else {
217
- return {
218
- data: void 0,
219
- error: {
220
- name: "UnknownError",
221
- message: "There was an unknown error response from the API",
222
- details: err.response?.data,
223
- status: err.response?.status
224
- }
225
- };
226
- }
227
- }
228
- const error = err;
229
- return {
230
- data: void 0,
231
- error: {
232
- name: error.name,
233
- message: error.message,
234
- stack: error.stack
235
- }
236
- };
237
- }
238
- };
239
- const isBaseQueryError = (error) => {
240
- return error.name !== void 0;
241
- };
242
- const i18nApi = react.createApi({
243
- reducerPath: "i18nApi",
244
- baseQuery: axiosBaseQuery(),
245
- tagTypes: ["Locale"],
246
- endpoints: () => ({})
178
+ const i18nApi = strapiAdmin.adminApi.enhanceEndpoints({
179
+ addTagTypes: ["Locale"]
247
180
  });
248
181
  const localesApi = i18nApi.injectEndpoints({
249
182
  endpoints: (builder) => ({
@@ -292,6 +225,295 @@ const {
292
225
  useGetDefaultLocalesQuery,
293
226
  useUpdateLocaleMutation
294
227
  } = localesApi;
228
+ const relationsApi = i18nApi.injectEndpoints({
229
+ overrideExisting: true,
230
+ endpoints: (builder) => ({
231
+ getManyDraftRelationCount: builder.query({
232
+ query: ({ model, ...params }) => ({
233
+ url: `/content-manager/collection-types/${model}/actions/countManyEntriesDraftRelations`,
234
+ method: "GET",
235
+ config: {
236
+ params
237
+ }
238
+ }),
239
+ transformResponse: (response) => response.data
240
+ })
241
+ })
242
+ });
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
+ };
323
+ const isErrorMessageDescriptor = (object) => {
324
+ return typeof object === "object" && object !== null && "id" in object && "defaultMessage" in object;
325
+ };
326
+ const EntryValidationText = ({
327
+ status = "draft",
328
+ validationErrors,
329
+ action
330
+ }) => {
331
+ const { formatMessage } = reactIntl.useIntl();
332
+ const getErrorStr = (key, value) => {
333
+ if (typeof value === "string") {
334
+ return `${key}: ${value}`;
335
+ } else if (isErrorMessageDescriptor(value)) {
336
+ return `${key}: ${formatMessage(value)}`;
337
+ } else if (Array.isArray(value)) {
338
+ return value.map((v) => getErrorStr(key, v)).join(" ");
339
+ } else if (typeof value === "object" && !Array.isArray(value)) {
340
+ return Object.entries(value).map(([k, v]) => getErrorStr(k, v)).join(" ");
341
+ } else {
342
+ return "";
343
+ }
344
+ };
345
+ if (validationErrors) {
346
+ const validationErrorsMessages = Object.entries(validationErrors).map(([key, value]) => {
347
+ return getErrorStr(key, value);
348
+ }).join(" ");
349
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
350
+ /* @__PURE__ */ jsxRuntime.jsx(icons.CrossCircle, { fill: "danger600" }),
351
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { label: validationErrorsMessages, children: /* @__PURE__ */ jsxRuntime.jsx(
352
+ designSystem.Typography,
353
+ {
354
+ maxWidth: "30rem",
355
+ textColor: "danger600",
356
+ variant: "omega",
357
+ fontWeight: "semiBold",
358
+ ellipsis: true,
359
+ children: validationErrorsMessages
360
+ }
361
+ ) })
362
+ ] });
363
+ }
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();
418
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
419
+ icon,
420
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor, fontWeight, children: text })
421
+ ] });
422
+ };
423
+ const BoldChunk = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
424
+ const BulkLocaleActionModal = ({
425
+ headers,
426
+ rows,
427
+ localesMetadata,
428
+ validationErrors = {},
429
+ action
430
+ }) => {
431
+ const { formatMessage } = reactIntl.useIntl();
432
+ const selectedRows = strapiAdmin.useTable(
433
+ "BulkLocaleActionModal",
434
+ (state) => state.selectedRows
435
+ );
436
+ const getFormattedCountMessage = () => {
437
+ const currentStatusByLocale = rows.reduce((acc, { locale, status }) => {
438
+ acc[locale] = status;
439
+ return acc;
440
+ }, {});
441
+ const localesWithErrors = Object.keys(validationErrors);
442
+ const publishedCount = selectedRows.filter(
443
+ ({ locale }) => currentStatusByLocale[locale] === "published"
444
+ ).length;
445
+ const draftCount = selectedRows.filter(
446
+ ({ locale }) => (currentStatusByLocale[locale] === "draft" || currentStatusByLocale[locale] === "modified") && !localesWithErrors.includes(locale)
447
+ ).length;
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.";
451
+ return formatMessage(
452
+ {
453
+ id: messageId,
454
+ defaultMessage
455
+ },
456
+ {
457
+ withErrorsCount,
458
+ draftCount,
459
+ publishedCount,
460
+ b: BoldChunk
461
+ }
462
+ );
463
+ };
464
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Body, { children: [
465
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: getFormattedCountMessage() }),
466
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 5, children: /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Content, { children: [
467
+ /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Head, { children: [
468
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.HeaderCheckboxCell, {}),
469
+ headers.map((head) => /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.HeaderCell, { ...head }, head.name))
470
+ ] }),
471
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Body, { children: rows.map(({ locale, status }, index2) => {
472
+ const error = validationErrors?.[locale] ?? null;
473
+ const statusVariant = status === "draft" ? "primary" : status === "published" ? "success" : "alternative";
474
+ return /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Row, { children: [
475
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.CheckboxCell, { id: locale, "aria-label": `Select ${locale}` }),
476
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", textColor: "neutral600", children: Array.isArray(localesMetadata) ? localesMetadata.find((localeEntry) => localeEntry.code === locale)?.name : locale }) }),
477
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { display: "flex", children: /* @__PURE__ */ jsxRuntime.jsx(
478
+ designSystem.Status,
479
+ {
480
+ display: "flex",
481
+ paddingLeft: "6px",
482
+ paddingRight: "6px",
483
+ paddingTop: "2px",
484
+ paddingBottom: "2px",
485
+ showBullet: false,
486
+ size: "S",
487
+ variant: statusVariant,
488
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
489
+ }
490
+ ) }) }),
491
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(EntryValidationText, { validationErrors: error, status, action }) }),
492
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(
493
+ designSystem.IconButton,
494
+ {
495
+ tag: reactRouterDom.Link,
496
+ to: {
497
+ search: qs.stringify({ plugins: { i18n: { locale } } })
498
+ },
499
+ label: formatMessage(
500
+ {
501
+ id: getTranslation("Settings.list.actions.edit"),
502
+ defaultMessage: "Edit {name} locale"
503
+ },
504
+ {
505
+ name: locale
506
+ }
507
+ ),
508
+ variant: "ghost",
509
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.Pencil, {})
510
+ }
511
+ ) })
512
+ ] }, index2);
513
+ }) })
514
+ ] }) })
515
+ ] });
516
+ };
295
517
  const LocalePickerAction = ({
296
518
  document,
297
519
  meta,
@@ -300,42 +522,47 @@ const LocalePickerAction = ({
300
522
  documentId
301
523
  }) => {
302
524
  const { formatMessage } = reactIntl.useIntl();
303
- const [{ query }, setQuery] = strapiAdmin.useQueryParams();
525
+ const [{ query: query2 }, setQuery] = strapiAdmin.useQueryParams();
304
526
  const { hasI18n, canCreate, canRead } = useI18n();
305
527
  const { data: locales = [] } = useGetLocalesQuery();
306
- 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
+ });
307
535
  const handleSelect = React__namespace.useCallback(
308
536
  (value) => {
309
537
  setQuery({
310
538
  plugins: {
311
- ...query.plugins,
539
+ ...query2.plugins,
312
540
  i18n: {
313
541
  locale: value
314
542
  }
315
543
  }
316
544
  });
317
545
  },
318
- [query.plugins, setQuery]
546
+ [query2.plugins, setQuery]
319
547
  );
320
548
  React__namespace.useEffect(() => {
321
549
  if (!Array.isArray(locales) || !hasI18n) {
322
550
  return;
323
551
  }
324
- const currentDesiredLocale = query.plugins?.i18n?.locale;
325
552
  const doesLocaleExist = locales.find((loc) => loc.code === currentDesiredLocale);
326
553
  const defaultLocale = locales.find((locale) => locale.isDefault);
327
554
  if (!doesLocaleExist && defaultLocale?.code) {
328
555
  handleSelect(defaultLocale.code);
329
556
  }
330
- }, [handleSelect, hasI18n, locales, query.plugins?.i18n?.locale]);
331
- if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
332
- return null;
333
- }
334
- const currentLocale = query.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;
335
559
  const allCurrentLocales = [
336
560
  { status: getDocumentStatus(document, meta), locale: currentLocale },
337
561
  ...meta?.availableLocales ?? []
338
562
  ];
563
+ if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
564
+ return null;
565
+ }
339
566
  return {
340
567
  label: formatMessage({
341
568
  id: getTranslation("Settings.locales.modal.locales.label"),
@@ -347,7 +574,7 @@ const LocalePickerAction = ({
347
574
  );
348
575
  const status = currentLocaleDoc?.status ?? "draft";
349
576
  const permissionsToCheck = currentLocaleDoc ? canCreate : canRead;
350
- const statusVariant = status === "draft" ? "primary" : status === "published" ? "success" : "alternative";
577
+ const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
351
578
  return {
352
579
  disabled: !permissionsToCheck.includes(locale.code),
353
580
  value: locale.code,
@@ -363,7 +590,7 @@ const LocalePickerAction = ({
363
590
  showBullet: false,
364
591
  size: "S",
365
592
  variant: statusVariant,
366
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { as: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
593
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
367
594
  }
368
595
  ) : null
369
596
  };
@@ -383,6 +610,95 @@ const getDocumentStatus = (document, meta) => {
383
610
  }
384
611
  return docStatus;
385
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
+ };
386
702
  const DeleteLocaleAction = ({
387
703
  document,
388
704
  documentId,
@@ -414,7 +730,7 @@ const DeleteLocaleAction = ({
414
730
  }),
415
731
  content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, children: [
416
732
  /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
417
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { as: "p", variant: "omega", textAlign: "center", children: formatMessage({
733
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
418
734
  id: getTranslation("actions.delete.dialog.body"),
419
735
  defaultMessage: "Are you sure?"
420
736
  }) })
@@ -446,7 +762,263 @@ const DeleteLocaleAction = ({
446
762
  }
447
763
  };
448
764
  };
449
- const StyledTrash = styled__default.default(icons.Trash)`
765
+ const BulkLocaleAction = ({
766
+ document: baseDocument,
767
+ documentId,
768
+ model,
769
+ collectionType,
770
+ action
771
+ }) => {
772
+ const baseLocale = baseDocument?.locale ?? null;
773
+ const [{ query: query$1 }] = strapiAdmin.useQueryParams();
774
+ const params = React__namespace.useMemo(() => strapiAdmin$1.buildValidParams(query$1), [query$1]);
775
+ const isOnPublishedTab = query$1.status === "published";
776
+ const { formatMessage } = reactIntl.useIntl();
777
+ const { hasI18n, canPublish } = useI18n();
778
+ const { toggleNotification } = strapiAdmin.useNotification();
779
+ const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
780
+ const [selectedRows, setSelectedRows] = React__namespace.useState([]);
781
+ const [isDraftRelationConfirmationOpen, setIsDraftRelationConfirmationOpen] = React__namespace.useState(false);
782
+ const { publishMany: publishManyAction, unpublishMany: unpublishManyAction } = strapiAdmin$1.unstable_useDocumentActions();
783
+ const {
784
+ document,
785
+ meta: documentMeta,
786
+ schema,
787
+ validate
788
+ } = strapiAdmin$1.unstable_useDocument(
789
+ {
790
+ model,
791
+ collectionType,
792
+ documentId,
793
+ params: {
794
+ locale: baseLocale
795
+ }
796
+ },
797
+ {
798
+ skip: !hasI18n || !baseLocale
799
+ }
800
+ );
801
+ const { data: localesMetadata = [] } = useGetLocalesQuery(hasI18n ? void 0 : query.skipToken);
802
+ const headers = [
803
+ {
804
+ label: formatMessage({
805
+ id: "global.name",
806
+ defaultMessage: "Name"
807
+ }),
808
+ name: "name"
809
+ },
810
+ {
811
+ label: formatMessage({
812
+ id: getTranslation("CMEditViewBulkLocale.status"),
813
+ defaultMessage: "Status"
814
+ }),
815
+ name: "status"
816
+ },
817
+ {
818
+ label: formatMessage({
819
+ id: getTranslation("CMEditViewBulkLocale.publication-status"),
820
+ defaultMessage: "Publication Status"
821
+ }),
822
+ name: "publication-status"
823
+ }
824
+ ];
825
+ const [rows, validationErrors] = React__namespace.useMemo(() => {
826
+ if (!document || !documentMeta?.availableLocales) {
827
+ return [[], {}];
828
+ }
829
+ const rowsFromMeta = documentMeta?.availableLocales.map((doc) => {
830
+ const { locale, status } = doc;
831
+ return { locale, status };
832
+ });
833
+ rowsFromMeta.unshift({
834
+ locale: document.locale,
835
+ status: document.status
836
+ });
837
+ const allDocuments = [document, ...documentMeta?.availableLocales ?? []];
838
+ const errors = allDocuments.reduce((errs, document2) => {
839
+ if (!document2) {
840
+ return errs;
841
+ }
842
+ const validation = validate(document2);
843
+ if (validation !== null) {
844
+ errs[document2.locale] = validation;
845
+ }
846
+ return errs;
847
+ }, {});
848
+ return [rowsFromMeta, errors];
849
+ }, [document, documentMeta?.availableLocales, validate]);
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) {
858
+ acc.push(selectedRow.locale);
859
+ }
860
+ return acc;
861
+ }, []);
862
+ const enableDraftRelationsCount = false;
863
+ const {
864
+ data: draftRelationsCount = 0,
865
+ isLoading: isDraftRelationsLoading,
866
+ error: isDraftRelationsError
867
+ } = useGetManyDraftRelationCountQuery(
868
+ {
869
+ model,
870
+ documentIds: [documentId],
871
+ locale: localesForAction
872
+ },
873
+ {
874
+ skip: !enableDraftRelationsCount
875
+ }
876
+ );
877
+ React__namespace.useEffect(() => {
878
+ if (isDraftRelationsError) {
879
+ toggleNotification({
880
+ type: "danger",
881
+ message: formatAPIError(isDraftRelationsError)
882
+ });
883
+ }
884
+ }, [isDraftRelationsError, toggleNotification, formatAPIError]);
885
+ if (!schema?.options?.draftAndPublish) {
886
+ return null;
887
+ }
888
+ if (!hasI18n) {
889
+ return null;
890
+ }
891
+ if (!documentId) {
892
+ return null;
893
+ }
894
+ const publish = async () => {
895
+ await publishManyAction({
896
+ model,
897
+ documentIds: [documentId],
898
+ params: {
899
+ ...params,
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
912
+ }
913
+ });
914
+ setSelectedRows([]);
915
+ };
916
+ const handleAction = async () => {
917
+ if (draftRelationsCount > 0) {
918
+ setIsDraftRelationConfirmationOpen(true);
919
+ } else if (isBulkPublish) {
920
+ await publish();
921
+ } else {
922
+ await unpublish();
923
+ }
924
+ };
925
+ if (isDraftRelationConfirmationOpen) {
926
+ return {
927
+ label: formatMessage({
928
+ id: "app.components.ConfirmDialog.title",
929
+ defaultMessage: "Confirmation"
930
+ }),
931
+ variant: "danger",
932
+ dialog: {
933
+ onCancel: () => {
934
+ setIsDraftRelationConfirmationOpen(false);
935
+ },
936
+ onConfirm: async () => {
937
+ await publish();
938
+ setIsDraftRelationConfirmationOpen(false);
939
+ },
940
+ type: "dialog",
941
+ title: formatMessage({
942
+ id: getTranslation("actions.publish.dialog.title"),
943
+ defaultMessage: "Confirmation"
944
+ }),
945
+ content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "center", gap: 2, children: [
946
+ /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, { width: "2.4rem", height: "2.4rem", fill: "danger600" }),
947
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", children: formatMessage({
948
+ id: getTranslation("CMEditViewBulkLocale.draft-relation-warning"),
949
+ defaultMessage: "Some locales are related to draft entries. Publishing them could leave broken links in your app."
950
+ }) }),
951
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", children: formatMessage({
952
+ id: getTranslation("CMEditViewBulkLocale.continue-confirmation"),
953
+ defaultMessage: "Are you sure you want to continue?"
954
+ }) })
955
+ ] })
956
+ }
957
+ };
958
+ }
959
+ const hasPermission = selectedRows.map(({ locale }) => locale).every((locale) => canPublish.includes(locale));
960
+ return {
961
+ label: formatMessage({
962
+ id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
963
+ defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
964
+ }),
965
+ variant: isBulkPublish ? "secondary" : "danger",
966
+ icon: isBulkPublish ? /* @__PURE__ */ jsxRuntime.jsx(icons.ListPlus, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.Cross, {}),
967
+ disabled: isOnPublishedTab || canPublish.length === 0,
968
+ position: ["panel"],
969
+ dialog: {
970
+ type: "modal",
971
+ title: formatMessage({
972
+ id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
973
+ defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
974
+ }),
975
+ content: () => {
976
+ return /* @__PURE__ */ jsxRuntime.jsx(
977
+ strapiAdmin.Table.Root,
978
+ {
979
+ headers,
980
+ rows: rows.map((row) => ({
981
+ ...row,
982
+ id: row.locale
983
+ })),
984
+ selectedRows,
985
+ onSelectedRowsChange: (tableSelectedRows) => setSelectedRows(tableSelectedRows),
986
+ children: /* @__PURE__ */ jsxRuntime.jsx(
987
+ BulkLocaleActionModal,
988
+ {
989
+ validationErrors,
990
+ headers,
991
+ rows,
992
+ localesMetadata,
993
+ action: action ?? "bulk-publish"
994
+ }
995
+ )
996
+ }
997
+ );
998
+ },
999
+ footer: () => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Footer, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxRuntime.jsx(
1000
+ designSystem.Button,
1001
+ {
1002
+ loading: isDraftRelationsLoading,
1003
+ disabled: !hasPermission || localesForAction.length === 0,
1004
+ variant: "default",
1005
+ onClick: handleAction,
1006
+ children: formatMessage({
1007
+ id: isBulkPublish ? "app.utils.publish" : "app.utils.unpublish",
1008
+ defaultMessage: isBulkPublish ? "Publish" : "Unpublish"
1009
+ })
1010
+ }
1011
+ ) })
1012
+ }
1013
+ };
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
+ };
1021
+ const StyledTrash = styledComponents.styled(icons.Trash)`
450
1022
  path {
451
1023
  fill: currentColor;
452
1024
  }
@@ -502,16 +1074,9 @@ const UnpublishModalAdditionalInfo = () => {
502
1074
  }
503
1075
  ) });
504
1076
  };
505
- const Initializer = ({ setPlugin }) => {
506
- const setPluginRef = React__namespace.useRef(setPlugin);
507
- React__namespace.useEffect(() => {
508
- setPluginRef.current(pluginId);
509
- }, []);
510
- return null;
511
- };
512
1077
  const LocalePicker = () => {
513
1078
  const { formatMessage } = reactIntl.useIntl();
514
- const [{ query }, setQuery] = strapiAdmin.useQueryParams();
1079
+ const [{ query: query2 }, setQuery] = strapiAdmin.useQueryParams();
515
1080
  const { hasI18n, canRead, canCreate } = useI18n();
516
1081
  const { data: locales = [] } = useGetLocalesQuery(void 0, {
517
1082
  skip: !hasI18n
@@ -521,25 +1086,25 @@ const LocalePicker = () => {
521
1086
  setQuery(
522
1087
  {
523
1088
  page: 1,
524
- plugins: { ...query.plugins, i18n: { locale: code } }
1089
+ plugins: { ...query2.plugins, i18n: { locale: code } }
525
1090
  },
526
1091
  "push",
527
1092
  replace
528
1093
  );
529
1094
  },
530
- [query.plugins, setQuery]
1095
+ [query2.plugins, setQuery]
531
1096
  );
532
1097
  React__namespace.useEffect(() => {
533
1098
  if (!Array.isArray(locales) || !hasI18n) {
534
1099
  return;
535
1100
  }
536
- const currentDesiredLocale = query.plugins?.i18n?.locale;
1101
+ const currentDesiredLocale = query2.plugins?.i18n?.locale;
537
1102
  const doesLocaleExist = locales.find((loc) => loc.code === currentDesiredLocale);
538
1103
  const defaultLocale = locales.find((locale) => locale.isDefault);
539
1104
  if (!doesLocaleExist && defaultLocale?.code) {
540
1105
  handleChange(defaultLocale.code, true);
541
1106
  }
542
- }, [hasI18n, handleChange, locales, query.plugins?.i18n?.locale]);
1107
+ }, [hasI18n, handleChange, locales, query2.plugins?.i18n?.locale]);
543
1108
  if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
544
1109
  return null;
545
1110
  }
@@ -554,7 +1119,7 @@ const LocalePicker = () => {
554
1119
  id: getTranslation("actions.select-locale"),
555
1120
  defaultMessage: "Select locale"
556
1121
  }),
557
- value: query.plugins?.i18n?.locale || locales.find((locale) => locale.isDefault)?.code,
1122
+ value: query2.plugins?.i18n?.locale || locales.find((locale) => locale.isDefault)?.code,
558
1123
  onChange: handleChange,
559
1124
  children: displayedLocales.map((locale) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: locale.code, children: locale.name }, locale.id))
560
1125
  }
@@ -568,7 +1133,7 @@ const PERMISSIONS = {
568
1133
  read: [{ action: "plugin::i18n.locale.read", subject: null }]
569
1134
  };
570
1135
  const mutateEditViewHook = ({ layout }) => {
571
- if ("i18n" in layout.options && typeof layout.options.i18n === "object" && layout.options.i18n !== null && "localized" in layout.options.i18n && !layout.options.i18n.localized) {
1136
+ if (!("i18n" in layout.options) || typeof layout.options.i18n === "object" && layout.options.i18n !== null && "localized" in layout.options.i18n && !layout.options.i18n.localized) {
572
1137
  return { layout };
573
1138
  }
574
1139
  const components = Object.entries(layout.components).reduce(
@@ -613,8 +1178,8 @@ const doesFieldHaveI18nPluginOpt = (pluginOpts) => {
613
1178
  };
614
1179
  const LabelAction = ({ title, icon }) => {
615
1180
  const { formatMessage } = reactIntl.useIntl();
616
- return /* @__PURE__ */ jsxRuntime.jsxs(Span, { as: "span", children: [
617
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { as: "span", children: `(${formatMessage(title)})` }),
1181
+ return /* @__PURE__ */ jsxRuntime.jsxs(Span, { tag: "span", children: [
1182
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { tag: "span", children: formatMessage(title) }),
618
1183
  React__namespace.cloneElement(icon, {
619
1184
  "aria-hidden": true,
620
1185
  focusable: false
@@ -622,7 +1187,7 @@ const LabelAction = ({ title, icon }) => {
622
1187
  })
623
1188
  ] });
624
1189
  };
625
- const Span = styled__default.default(designSystem.Flex)`
1190
+ const Span = styledComponents.styled(designSystem.Flex)`
626
1191
  svg {
627
1192
  width: 12px;
628
1193
  height: 12px;
@@ -649,13 +1214,7 @@ const LocaleListCell = ({
649
1214
  }
650
1215
  });
651
1216
  const { locale: language } = reactIntl.useIntl();
652
- const [visible, setVisible] = React__namespace.useState(false);
653
- const buttonRef = React__namespace.useRef(null);
654
1217
  const { data: locales = [] } = useGetLocalesQuery();
655
- const handleTogglePopover = (e) => {
656
- e.stopPropagation();
657
- setVisible((prev) => !prev);
658
- };
659
1218
  const formatter = designSystem.useCollator(language, {
660
1219
  sensitivity: "base"
661
1220
  });
@@ -677,64 +1236,14 @@ const LocaleListCell = ({
677
1236
  }
678
1237
  return locale.name;
679
1238
  }).toSorted((a, b) => formatter.compare(a, b));
680
- return /* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", onClick: handleTogglePopover, ref: buttonRef, children: [
681
- /* @__PURE__ */ jsxRuntime.jsxs(
682
- ActionWrapper,
683
- {
684
- minWidth: "100%",
685
- alignItems: "center",
686
- justifyContent: "center",
687
- height: "3.2rem",
688
- width: "3.2rem",
689
- children: [
690
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", ellipsis: true, children: localesForDocument.join(", ") }),
691
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(icons.CaretDown, {}) })
692
- ]
693
- }
694
- ),
695
- visible && /* @__PURE__ */ jsxRuntime.jsx(
696
- designSystem.Popover,
697
- {
698
- onDismiss: () => setVisible(false),
699
- source: buttonRef,
700
- spacing: 16,
701
- centered: true,
702
- children: /* @__PURE__ */ jsxRuntime.jsx("ul", { children: localesForDocument.map((name) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 3, as: "li", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: name }) }, name)) })
703
- }
704
- )
1239
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Popover.Root, { children: [
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
+ ] }) }) }),
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)) }) })
705
1245
  ] });
706
1246
  };
707
- const Button = styled__default.default.button`
708
- width: 100%;
709
-
710
- svg {
711
- > g,
712
- path {
713
- fill: ${({ theme }) => theme.colors.neutral500};
714
- }
715
- }
716
- &:hover {
717
- svg {
718
- > g,
719
- path {
720
- fill: ${({ theme }) => theme.colors.neutral600};
721
- }
722
- }
723
- }
724
- &:active {
725
- svg {
726
- > g,
727
- path {
728
- fill: ${({ theme }) => theme.colors.neutral400};
729
- }
730
- }
731
- }
732
- `;
733
- const ActionWrapper = styled__default.default(designSystem.Flex)`
734
- svg {
735
- height: 0.4rem;
736
- }
737
- `;
738
1247
  const addColumnToTableHook = ({ displayedHeaders, layout }) => {
739
1248
  const { options } = layout;
740
1249
  const isFieldLocalized = doesPluginOptionsHaveI18nLocalized(options) ? options.i18n.localized : false;
@@ -763,18 +1272,11 @@ const addColumnToTableHook = ({ displayedHeaders, layout }) => {
763
1272
  const addLocaleToReleasesHook = ({ displayedHeaders = [] }) => {
764
1273
  return {
765
1274
  displayedHeaders: [
766
- // TODO: Fix when migrating to v5
767
- // ...displayedHeaders,
1275
+ ...displayedHeaders,
768
1276
  {
769
- key: "__locale__",
770
- fieldSchema: { type: "string" },
771
- metadatas: {
772
- label: {
773
- id: "content-releases.page.ReleaseDetails.table.header.label.locale",
774
- defaultMessage: "locale"
775
- },
776
- searchable: false,
777
- sortable: false
1277
+ label: {
1278
+ id: "content-releases.page.ReleaseDetails.table.header.label.locale",
1279
+ defaultMessage: "locale"
778
1280
  },
779
1281
  name: "locale"
780
1282
  }
@@ -922,8 +1424,6 @@ const index = {
922
1424
  app.addRBACMiddleware([localeMiddleware]);
923
1425
  app.registerPlugin({
924
1426
  id: pluginId,
925
- initializer: Initializer,
926
- isReady: false,
927
1427
  name: pluginId
928
1428
  });
929
1429
  },
@@ -941,16 +1441,21 @@ const index = {
941
1441
  },
942
1442
  id: "internationalization",
943
1443
  to: "internationalization",
944
- Component: () => Promise.resolve().then(() => require("./SettingsPage-Djqsdrzs.js")).then((mod) => ({ default: mod.ProtectedSettingsPage })),
1444
+ Component: () => Promise.resolve().then(() => require("./SettingsPage-CfTmCkup.js")).then((mod) => ({ default: mod.ProtectedSettingsPage })),
945
1445
  permissions: PERMISSIONS.accessMain
946
1446
  });
947
1447
  const contentManager = app.getPlugin("content-manager");
948
- contentManager.apis.addDocumentHeaderAction([LocalePickerAction]);
1448
+ contentManager.apis.addDocumentHeaderAction([LocalePickerAction, FillFromAnotherLocaleAction]);
949
1449
  contentManager.apis.addDocumentAction((actions) => {
950
1450
  const indexOfDeleteAction = actions.findIndex((action) => action.type === "delete");
951
1451
  actions.splice(indexOfDeleteAction, 0, DeleteLocaleAction);
952
1452
  return actions;
953
1453
  });
1454
+ contentManager.apis.addDocumentAction((actions) => {
1455
+ actions.splice(2, 0, BulkLocalePublishAction);
1456
+ actions.splice(5, 0, BulkLocaleUnpublishAction);
1457
+ return actions;
1458
+ });
954
1459
  contentManager.injectComponent("listView", "actions", {
955
1460
  name: "i18n-locale-filter",
956
1461
  Component: LocalePicker
@@ -1054,7 +1559,7 @@ const index = {
1054
1559
  async registerTrads({ locales }) {
1055
1560
  const importedTrads = await Promise.all(
1056
1561
  locales.map((locale) => {
1057
- 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-BuBc6LKZ.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 }) => {
1058
1563
  return {
1059
1564
  data: prefixPluginTranslations(data, pluginId),
1060
1565
  locale
@@ -1073,10 +1578,9 @@ const index = {
1073
1578
  exports.PERMISSIONS = PERMISSIONS;
1074
1579
  exports.getTranslation = getTranslation;
1075
1580
  exports.index = index;
1076
- exports.isBaseQueryError = isBaseQueryError;
1077
1581
  exports.useCreateLocaleMutation = useCreateLocaleMutation;
1078
1582
  exports.useDeleteLocaleMutation = useDeleteLocaleMutation;
1079
1583
  exports.useGetDefaultLocalesQuery = useGetDefaultLocalesQuery;
1080
1584
  exports.useGetLocalesQuery = useGetLocalesQuery;
1081
1585
  exports.useUpdateLocaleMutation = useUpdateLocaleMutation;
1082
- //# sourceMappingURL=index-DMXJeGjN.js.map
1586
+ //# sourceMappingURL=index-5XLZwzwx.js.map