@strapi/i18n 0.0.0-experimental.17b4116f461a49b8ce5386f7c8d79c511d40fb3b → 0.0.0-experimental.25e22c6cc9bc6b35392bb55d09f641a0a65e7403

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 (29) hide show
  1. package/dist/_chunks/{SettingsPage-CeqfDjsb.mjs → SettingsPage-Dsi2qGtq.mjs} +109 -125
  2. package/dist/_chunks/SettingsPage-Dsi2qGtq.mjs.map +1 -0
  3. package/dist/_chunks/{SettingsPage-Djqsdrzs.js → SettingsPage-VN7sTzkb.js} +109 -125
  4. package/dist/_chunks/SettingsPage-VN7sTzkb.js.map +1 -0
  5. package/dist/_chunks/{en-CnrTsjWS.mjs → en-18tWw4P6.mjs} +4 -1
  6. package/dist/_chunks/en-18tWw4P6.mjs.map +1 -0
  7. package/dist/_chunks/{en-BuBc6LKZ.js → en-Kv6y9zPQ.js} +4 -1
  8. package/dist/_chunks/en-Kv6y9zPQ.js.map +1 -0
  9. package/dist/_chunks/{index-BDU1w_fd.mjs → index-DhtjJYrx.mjs} +445 -131
  10. package/dist/_chunks/index-DhtjJYrx.mjs.map +1 -0
  11. package/dist/_chunks/{index-DMXJeGjN.js → index-kedPlCo6.js} +439 -127
  12. package/dist/_chunks/index-kedPlCo6.js.map +1 -0
  13. package/dist/admin/index.js +1 -1
  14. package/dist/admin/index.mjs +2 -2
  15. package/dist/admin/src/components/BulkLocaleActionModal.d.ts +15 -0
  16. package/dist/admin/src/components/CMHeaderActions.d.ts +7 -1
  17. package/dist/admin/src/components/EditLocale.d.ts +5 -4
  18. package/dist/admin/src/services/api.d.ts +2 -3
  19. package/dist/admin/src/services/locales.d.ts +1 -1
  20. package/dist/admin/src/services/relations.d.ts +7 -0
  21. package/dist/admin/src/utils/baseQuery.d.ts +4 -19
  22. package/dist/shared/contracts/content-manager.d.ts +20 -1
  23. package/package.json +15 -16
  24. package/dist/_chunks/SettingsPage-CeqfDjsb.mjs.map +0 -1
  25. package/dist/_chunks/SettingsPage-Djqsdrzs.js.map +0 -1
  26. package/dist/_chunks/en-BuBc6LKZ.js.map +0 -1
  27. package/dist/_chunks/en-CnrTsjWS.mjs.map +0 -1
  28. package/dist/_chunks/index-BDU1w_fd.mjs.map +0 -1
  29. package/dist/_chunks/index-DMXJeGjN.js.map +0 -1
@@ -6,12 +6,10 @@ 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
10
  const strapiAdmin = require("@strapi/admin/strapi-admin");
11
11
  const strapiAdmin$1 = require("@strapi/content-manager/strapi-admin");
12
12
  const reactRouterDom = require("react-router-dom");
13
- const react = require("@reduxjs/toolkit/query/react");
14
- const axios = require("axios");
15
13
  const qs = require("qs");
16
14
  const omit = require("lodash/omit");
17
15
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
@@ -36,7 +34,6 @@ function _interopNamespace(e) {
36
34
  const get__default = /* @__PURE__ */ _interopDefault(get);
37
35
  const yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
38
36
  const React__namespace = /* @__PURE__ */ _interopNamespace(React);
39
- const styled__default = /* @__PURE__ */ _interopDefault(styled);
40
37
  const qs__namespace = /* @__PURE__ */ _interopNamespace(qs);
41
38
  const omit__default = /* @__PURE__ */ _interopDefault(omit);
42
39
  const __variableDynamicImportRuntimeHelper = (glob, path) => {
@@ -50,7 +47,7 @@ const __variableDynamicImportRuntimeHelper = (glob, path) => {
50
47
  };
51
48
  const pluginId = "i18n";
52
49
  const getTranslation = (id) => `${pluginId}.${id}`;
53
- const TextAlignTypography = styled__default.default(designSystem.Typography)`
50
+ const TextAlignTypography = styledComponents.styled(designSystem.Typography)`
54
51
  text-align: center;
55
52
  `;
56
53
  const CheckboxConfirmation = ({
@@ -74,9 +71,7 @@ const CheckboxConfirmation = ({
74
71
  };
75
72
  const handleConfirm = () => {
76
73
  onChange({ target: { name, value: false, type: "checkbox" } });
77
- setIsOpen(false);
78
74
  };
79
- const handleToggle = () => setIsOpen((prev) => !prev);
80
75
  const label = intlLabel.id ? formatMessage(
81
76
  { id: intlLabel.id, defaultMessage: intlLabel.defaultMessage },
82
77
  { ...intlLabel.values }
@@ -85,43 +80,36 @@ const CheckboxConfirmation = ({
85
80
  { id: description.id, defaultMessage: description.defaultMessage },
86
81
  { ...description.values }
87
82
  ) : "";
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({
83
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Root, { open: isOpen, onOpenChange: setIsOpen, children: [
84
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { hint, name, children: [
85
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Checkbox, { onCheckedChange: handleChange, checked: value, children: label }),
86
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {})
87
+ ] }),
88
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
89
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: formatMessage({
90
+ id: getTranslation("CheckboxConfirmation.Modal.title"),
91
+ defaultMessage: "Disable localization"
92
+ }) }),
93
+ /* @__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: [
94
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(TextAlignTypography, { children: formatMessage({
104
95
  id: getTranslation("CheckboxConfirmation.Modal.content"),
105
96
  defaultMessage: "Disabling localization will engender the deletion of all your content but the one associated to your default locale (if existing)."
106
97
  }) }) }),
107
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", id: "confirm-description", children: formatMessage({
98
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", children: formatMessage({
108
99
  id: getTranslation("CheckboxConfirmation.Modal.body"),
109
100
  defaultMessage: "Do you want to disable it?"
110
101
  }) }) })
111
102
  ] }) }),
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
- )
103
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
104
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", children: formatMessage({
105
+ id: "components.popUpWarning.button.cancel",
106
+ defaultMessage: "No, cancel"
107
+ }) }) }),
108
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Action, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "danger-light", onClick: handleConfirm, children: formatMessage({
109
+ id: getTranslation("CheckboxConfirmation.Modal.button-confirm"),
110
+ defaultMessage: "Yes, disable"
111
+ }) }) })
112
+ ] })
125
113
  ] })
126
114
  ] });
127
115
  };
@@ -186,64 +174,8 @@ const useI18n = () => {
186
174
  ...actions
187
175
  };
188
176
  };
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: () => ({})
177
+ const i18nApi = strapiAdmin.adminApi.enhanceEndpoints({
178
+ addTagTypes: ["Locale"]
247
179
  });
248
180
  const localesApi = i18nApi.injectEndpoints({
249
181
  endpoints: (builder) => ({
@@ -292,6 +224,176 @@ const {
292
224
  useGetDefaultLocalesQuery,
293
225
  useUpdateLocaleMutation
294
226
  } = localesApi;
227
+ const relationsApi = i18nApi.injectEndpoints({
228
+ overrideExisting: true,
229
+ endpoints: (builder) => ({
230
+ getManyDraftRelationCount: builder.query({
231
+ query: ({ model, ...params }) => ({
232
+ url: `/content-manager/collection-types/${model}/actions/countManyEntriesDraftRelations`,
233
+ method: "GET",
234
+ config: {
235
+ params
236
+ }
237
+ }),
238
+ transformResponse: (response) => response.data
239
+ })
240
+ })
241
+ });
242
+ const { useGetManyDraftRelationCountQuery } = relationsApi;
243
+ const isErrorMessageDescriptor = (object) => {
244
+ return typeof object === "object" && object !== null && "id" in object && "defaultMessage" in object;
245
+ };
246
+ const EntryValidationText = ({ status = "draft", validationErrors }) => {
247
+ const { formatMessage } = reactIntl.useIntl();
248
+ const getErrorStr = (key, value) => {
249
+ if (typeof value === "string") {
250
+ return `${key}: ${value}`;
251
+ } else if (isErrorMessageDescriptor(value)) {
252
+ return `${key}: ${formatMessage(value)}`;
253
+ } else if (Array.isArray(value)) {
254
+ return value.map((v) => getErrorStr(key, v)).join(" ");
255
+ } else if (typeof value === "object" && !Array.isArray(value)) {
256
+ return Object.entries(value).map(([k, v]) => getErrorStr(k, v)).join(" ");
257
+ } else {
258
+ return "";
259
+ }
260
+ };
261
+ if (validationErrors) {
262
+ const validationErrorsMessages = Object.entries(validationErrors).map(([key, value]) => {
263
+ return getErrorStr(key, value);
264
+ }).join(" ");
265
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
266
+ /* @__PURE__ */ jsxRuntime.jsx(icons.CrossCircle, { fill: "danger600" }),
267
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { label: validationErrorsMessages, children: /* @__PURE__ */ jsxRuntime.jsx(
268
+ designSystem.Typography,
269
+ {
270
+ maxWidth: "30rem",
271
+ textColor: "danger600",
272
+ variant: "omega",
273
+ fontWeight: "semiBold",
274
+ ellipsis: true,
275
+ children: validationErrorsMessages
276
+ }
277
+ ) })
278
+ ] });
279
+ }
280
+ if (status === "published") {
281
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
282
+ /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
283
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
284
+ id: "content-manager.bulk-publish.already-published",
285
+ defaultMessage: "Already Published"
286
+ }) })
287
+ ] });
288
+ }
289
+ if (status === "modified") {
290
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
291
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowsCounterClockwise, { fill: "alternative600" }),
292
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
293
+ id: "app.utils.ready-to-publish-changes",
294
+ defaultMessage: "Ready to publish changes"
295
+ }) })
296
+ ] });
297
+ }
298
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
299
+ /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
300
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
301
+ id: "app.utils.ready-to-publish",
302
+ defaultMessage: "Ready to publish"
303
+ }) })
304
+ ] });
305
+ };
306
+ const BoldChunk = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
307
+ const BulkLocaleActionModal = ({
308
+ headers,
309
+ rows,
310
+ localesMetadata,
311
+ validationErrors = {}
312
+ }) => {
313
+ const { formatMessage } = reactIntl.useIntl();
314
+ const selectedRows = strapiAdmin.useTable(
315
+ "BulkLocaleActionModal",
316
+ (state) => state.selectedRows
317
+ );
318
+ const getFormattedCountMessage = () => {
319
+ const currentStatusByLocale = rows.reduce((acc, { locale, status }) => {
320
+ acc[locale] = status;
321
+ return acc;
322
+ }, {});
323
+ const localesWithErrors = Object.keys(validationErrors);
324
+ const alreadyPublishedCount = selectedRows.filter(
325
+ ({ locale }) => currentStatusByLocale[locale] === "published"
326
+ ).length;
327
+ const readyToPublishCount = selectedRows.filter(
328
+ ({ locale }) => (currentStatusByLocale[locale] === "draft" || currentStatusByLocale[locale] === "modified") && !localesWithErrors.includes(locale)
329
+ ).length;
330
+ const withErrorsCount = localesWithErrors.length;
331
+ return formatMessage(
332
+ {
333
+ id: "content-manager.containers.list.selectedEntriesModal.selectedCount",
334
+ 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."
335
+ },
336
+ {
337
+ withErrorsCount,
338
+ readyToPublishCount,
339
+ alreadyPublishedCount,
340
+ b: BoldChunk
341
+ }
342
+ );
343
+ };
344
+ return /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
345
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: getFormattedCountMessage() }),
346
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 5, children: /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Content, { children: [
347
+ /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Head, { children: [
348
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.HeaderCheckboxCell, {}),
349
+ headers.map((head) => /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.HeaderCell, { ...head }, head.name))
350
+ ] }),
351
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Body, { children: rows.map(({ locale, status }, index2) => {
352
+ const error = validationErrors?.[locale] ?? null;
353
+ const statusVariant = status === "draft" ? "primary" : status === "published" ? "success" : "alternative";
354
+ return /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Row, { children: [
355
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.CheckboxCell, { id: locale, "aria-label": `Select ${locale}` }),
356
+ /* @__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 }) }),
357
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { display: "flex", children: /* @__PURE__ */ jsxRuntime.jsx(
358
+ designSystem.Status,
359
+ {
360
+ display: "flex",
361
+ paddingLeft: "6px",
362
+ paddingRight: "6px",
363
+ paddingTop: "2px",
364
+ paddingBottom: "2px",
365
+ showBullet: false,
366
+ size: "S",
367
+ variant: statusVariant,
368
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
369
+ }
370
+ ) }) }),
371
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(EntryValidationText, { validationErrors: error, status }) }),
372
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(
373
+ designSystem.IconButton,
374
+ {
375
+ tag: reactRouterDom.Link,
376
+ to: {
377
+ search: qs.stringify({ plugins: { i18n: { locale } } })
378
+ },
379
+ label: formatMessage(
380
+ {
381
+ id: getTranslation("Settings.list.actions.edit"),
382
+ defaultMessage: "Edit {name} locale"
383
+ },
384
+ {
385
+ name: locale
386
+ }
387
+ ),
388
+ borderWidth: 0,
389
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.Pencil, {})
390
+ }
391
+ ) })
392
+ ] }, index2);
393
+ }) })
394
+ ] }) })
395
+ ] });
396
+ };
295
397
  const LocalePickerAction = ({
296
398
  document,
297
399
  meta,
@@ -363,7 +465,7 @@ const LocalePickerAction = ({
363
465
  showBullet: false,
364
466
  size: "S",
365
467
  variant: statusVariant,
366
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { as: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
468
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
367
469
  }
368
470
  ) : null
369
471
  };
@@ -414,7 +516,7 @@ const DeleteLocaleAction = ({
414
516
  }),
415
517
  content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, children: [
416
518
  /* @__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({
519
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
418
520
  id: getTranslation("actions.delete.dialog.body"),
419
521
  defaultMessage: "Are you sure?"
420
522
  }) })
@@ -446,7 +548,229 @@ const DeleteLocaleAction = ({
446
548
  }
447
549
  };
448
550
  };
449
- const StyledTrash = styled__default.default(icons.Trash)`
551
+ const BulkLocalePublishAction = ({
552
+ document: baseDocument,
553
+ documentId,
554
+ model,
555
+ collectionType
556
+ }) => {
557
+ const baseLocale = baseDocument?.locale ?? null;
558
+ const [{ query }] = strapiAdmin.useQueryParams();
559
+ const params = React__namespace.useMemo(() => strapiAdmin$1.buildValidParams(query), [query]);
560
+ const isPublishedTab = query.status === "published";
561
+ const { formatMessage } = reactIntl.useIntl();
562
+ const { hasI18n, canPublish } = useI18n();
563
+ const { toggleNotification } = strapiAdmin.useNotification();
564
+ const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
565
+ const [selectedRows, setSelectedRows] = React__namespace.useState([]);
566
+ const [isConfirmationOpen, setIsConfirmationOpen] = React__namespace.useState(false);
567
+ const { publishMany: publishManyAction } = strapiAdmin$1.unstable_useDocumentActions();
568
+ const {
569
+ document,
570
+ meta: documentMeta,
571
+ schema,
572
+ validate
573
+ } = strapiAdmin$1.unstable_useDocument({
574
+ model,
575
+ collectionType,
576
+ documentId,
577
+ params: {
578
+ locale: baseLocale
579
+ }
580
+ });
581
+ const { data: localesMetadata = [] } = useGetLocalesQuery();
582
+ const headers = [
583
+ {
584
+ label: formatMessage({
585
+ id: "global.name",
586
+ defaultMessage: "Name"
587
+ }),
588
+ name: "name"
589
+ },
590
+ {
591
+ label: formatMessage({
592
+ id: getTranslation("CMEditViewBulkLocale.status"),
593
+ defaultMessage: "Status"
594
+ }),
595
+ name: "status"
596
+ },
597
+ {
598
+ label: formatMessage({
599
+ id: getTranslation("CMEditViewBulkLocale.publication-status"),
600
+ defaultMessage: "Publication Status"
601
+ }),
602
+ name: "publication-status"
603
+ }
604
+ ];
605
+ const [rows, validationErrors] = React__namespace.useMemo(() => {
606
+ if (!document || !documentMeta?.availableLocales) {
607
+ return [[], {}];
608
+ }
609
+ const rowsFromMeta = documentMeta?.availableLocales.map((doc) => {
610
+ const { locale, status } = doc;
611
+ return { locale, status };
612
+ });
613
+ rowsFromMeta.unshift({
614
+ locale: document.locale,
615
+ status: document.status
616
+ });
617
+ const allDocuments = [document, ...documentMeta?.availableLocales ?? []];
618
+ const errors = allDocuments.reduce((errs, document2) => {
619
+ if (!document2) {
620
+ return errs;
621
+ }
622
+ const validation = validate(document2);
623
+ if (validation !== null) {
624
+ errs[document2.locale] = validation;
625
+ }
626
+ return errs;
627
+ }, {});
628
+ return [rowsFromMeta, errors];
629
+ }, [document, documentMeta?.availableLocales, validate]);
630
+ const localesToPublish = selectedRows.reduce((acc, selectedRow) => {
631
+ if (selectedRow.status !== "published" && !Object.keys(validationErrors).includes(selectedRow.locale)) {
632
+ acc.push(selectedRow.locale);
633
+ }
634
+ return acc;
635
+ }, []);
636
+ const {
637
+ data: draftRelationsCount = 0,
638
+ isLoading: isDraftRelationsLoading,
639
+ error: isDraftRelationsError
640
+ } = useGetManyDraftRelationCountQuery(
641
+ {
642
+ model,
643
+ documentIds: [documentId],
644
+ locale: localesToPublish
645
+ },
646
+ {
647
+ skip: !documentId || localesToPublish.length === 0
648
+ }
649
+ );
650
+ React__namespace.useEffect(() => {
651
+ if (isDraftRelationsError) {
652
+ toggleNotification({
653
+ type: "danger",
654
+ message: formatAPIError(isDraftRelationsError)
655
+ });
656
+ }
657
+ }, [isDraftRelationsError, toggleNotification, formatAPIError]);
658
+ if (!schema?.options?.draftAndPublish) {
659
+ return null;
660
+ }
661
+ if (!hasI18n) {
662
+ return null;
663
+ }
664
+ if (!documentId) {
665
+ return null;
666
+ }
667
+ const publish = async () => {
668
+ await publishManyAction({
669
+ model,
670
+ documentIds: [documentId],
671
+ params: {
672
+ ...params,
673
+ locale: localesToPublish
674
+ }
675
+ });
676
+ setSelectedRows([]);
677
+ };
678
+ const handleAction = async () => {
679
+ if (draftRelationsCount > 0) {
680
+ setIsConfirmationOpen(true);
681
+ } else {
682
+ await publish();
683
+ }
684
+ };
685
+ const isUnpublish = document?.status === "published";
686
+ if (isUnpublish) {
687
+ console.warn(["I18N"], "Bulk locale unpublish modal not implemented");
688
+ }
689
+ if (isConfirmationOpen) {
690
+ return {
691
+ label: formatMessage({
692
+ id: "app.components.ConfirmDialog.title",
693
+ defaultMessage: "Confirmation"
694
+ }),
695
+ variant: "danger",
696
+ dialog: {
697
+ onCancel: () => {
698
+ setIsConfirmationOpen(false);
699
+ },
700
+ onConfirm: async () => {
701
+ await publish();
702
+ setIsConfirmationOpen(false);
703
+ },
704
+ type: "dialog",
705
+ title: formatMessage({
706
+ id: getTranslation("actions.publish.dialog.title"),
707
+ defaultMessage: "Confirmation"
708
+ }),
709
+ content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "center", gap: 2, children: [
710
+ /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, { width: "2.4rem", height: "2.4rem", fill: "danger600" }),
711
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", children: formatMessage({
712
+ id: "content-manager.actions.discard.dialog.body",
713
+ defaultMessage: "Are you sure you want to discard the changes? This action is irreversible."
714
+ }) })
715
+ ] })
716
+ }
717
+ };
718
+ }
719
+ return {
720
+ label: formatMessage({
721
+ id: getTranslation("CMEditViewBulkLocale.publish-title"),
722
+ defaultMessage: "Publish Multiple Locales"
723
+ }),
724
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ListPlus, {}),
725
+ disabled: isPublishedTab || !canPublish,
726
+ position: ["panel"],
727
+ variant: "secondary",
728
+ dialog: {
729
+ type: "modal",
730
+ title: formatMessage({
731
+ id: getTranslation("CMEditViewBulkLocale.publish-title"),
732
+ defaultMessage: "Publish Multiple Locales"
733
+ }),
734
+ content: () => {
735
+ return /* @__PURE__ */ jsxRuntime.jsx(
736
+ strapiAdmin.Table.Root,
737
+ {
738
+ headers,
739
+ rows: rows.map((row) => ({
740
+ ...row,
741
+ id: row.locale
742
+ })),
743
+ selectedRows,
744
+ onSelectedRowsChange: (tableSelectedRows) => setSelectedRows(tableSelectedRows),
745
+ children: /* @__PURE__ */ jsxRuntime.jsx(
746
+ BulkLocaleActionModal,
747
+ {
748
+ validationErrors,
749
+ headers,
750
+ rows,
751
+ localesMetadata
752
+ }
753
+ )
754
+ }
755
+ );
756
+ },
757
+ footer: () => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxRuntime.jsx(
758
+ designSystem.Button,
759
+ {
760
+ loading: isDraftRelationsLoading,
761
+ disabled: localesToPublish.length === 0,
762
+ variant: "default",
763
+ onClick: handleAction,
764
+ children: formatMessage({
765
+ id: "app.utils.publish",
766
+ defaultMessage: "Publish"
767
+ })
768
+ }
769
+ ) })
770
+ }
771
+ };
772
+ };
773
+ const StyledTrash = styledComponents.styled(icons.Trash)`
450
774
  path {
451
775
  fill: currentColor;
452
776
  }
@@ -568,7 +892,7 @@ const PERMISSIONS = {
568
892
  read: [{ action: "plugin::i18n.locale.read", subject: null }]
569
893
  };
570
894
  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) {
895
+ if (!("i18n" in layout.options) || typeof layout.options.i18n === "object" && layout.options.i18n !== null && "localized" in layout.options.i18n && !layout.options.i18n.localized) {
572
896
  return { layout };
573
897
  }
574
898
  const components = Object.entries(layout.components).reduce(
@@ -613,8 +937,8 @@ const doesFieldHaveI18nPluginOpt = (pluginOpts) => {
613
937
  };
614
938
  const LabelAction = ({ title, icon }) => {
615
939
  const { formatMessage } = reactIntl.useIntl();
616
- return /* @__PURE__ */ jsxRuntime.jsxs(Span, { as: "span", children: [
617
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { as: "span", children: `(${formatMessage(title)})` }),
940
+ return /* @__PURE__ */ jsxRuntime.jsxs(Span, { tag: "span", children: [
941
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { tag: "span", children: formatMessage(title) }),
618
942
  React__namespace.cloneElement(icon, {
619
943
  "aria-hidden": true,
620
944
  focusable: false
@@ -622,7 +946,7 @@ const LabelAction = ({ title, icon }) => {
622
946
  })
623
947
  ] });
624
948
  };
625
- const Span = styled__default.default(designSystem.Flex)`
949
+ const Span = styledComponents.styled(designSystem.Flex)`
626
950
  svg {
627
951
  width: 12px;
628
952
  height: 12px;
@@ -649,13 +973,7 @@ const LocaleListCell = ({
649
973
  }
650
974
  });
651
975
  const { locale: language } = reactIntl.useIntl();
652
- const [visible, setVisible] = React__namespace.useState(false);
653
- const buttonRef = React__namespace.useRef(null);
654
976
  const { data: locales = [] } = useGetLocalesQuery();
655
- const handleTogglePopover = (e) => {
656
- e.stopPropagation();
657
- setVisible((prev) => !prev);
658
- };
659
977
  const formatter = designSystem.useCollator(language, {
660
978
  sensitivity: "base"
661
979
  });
@@ -677,8 +995,8 @@ const LocaleListCell = ({
677
995
  }
678
996
  return locale.name;
679
997
  }).toSorted((a, b) => formatter.compare(a, b));
680
- return /* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", onClick: handleTogglePopover, ref: buttonRef, children: [
681
- /* @__PURE__ */ jsxRuntime.jsxs(
998
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Popover.Root, { children: [
999
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Popover.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsxs(
682
1000
  ActionWrapper,
683
1001
  {
684
1002
  minWidth: "100%",
@@ -691,20 +1009,11 @@ const LocaleListCell = ({
691
1009
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(icons.CaretDown, {}) })
692
1010
  ]
693
1011
  }
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
- )
1012
+ ) }) }),
1013
+ /* @__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
1014
  ] });
706
1015
  };
707
- const Button = styled__default.default.button`
1016
+ const Button = styledComponents.styled.button`
708
1017
  width: 100%;
709
1018
 
710
1019
  svg {
@@ -730,7 +1039,7 @@ const Button = styled__default.default.button`
730
1039
  }
731
1040
  }
732
1041
  `;
733
- const ActionWrapper = styled__default.default(designSystem.Flex)`
1042
+ const ActionWrapper = styledComponents.styled(designSystem.Flex)`
734
1043
  svg {
735
1044
  height: 0.4rem;
736
1045
  }
@@ -941,7 +1250,7 @@ const index = {
941
1250
  },
942
1251
  id: "internationalization",
943
1252
  to: "internationalization",
944
- Component: () => Promise.resolve().then(() => require("./SettingsPage-Djqsdrzs.js")).then((mod) => ({ default: mod.ProtectedSettingsPage })),
1253
+ Component: () => Promise.resolve().then(() => require("./SettingsPage-VN7sTzkb.js")).then((mod) => ({ default: mod.ProtectedSettingsPage })),
945
1254
  permissions: PERMISSIONS.accessMain
946
1255
  });
947
1256
  const contentManager = app.getPlugin("content-manager");
@@ -951,6 +1260,10 @@ const index = {
951
1260
  actions.splice(indexOfDeleteAction, 0, DeleteLocaleAction);
952
1261
  return actions;
953
1262
  });
1263
+ contentManager.apis.addDocumentAction((actions) => {
1264
+ actions.splice(2, 0, BulkLocalePublishAction);
1265
+ return actions;
1266
+ });
954
1267
  contentManager.injectComponent("listView", "actions", {
955
1268
  name: "i18n-locale-filter",
956
1269
  Component: LocalePicker
@@ -1054,7 +1367,7 @@ const index = {
1054
1367
  async registerTrads({ locales }) {
1055
1368
  const importedTrads = await Promise.all(
1056
1369
  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 }) => {
1370
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/de.json": () => Promise.resolve().then(() => require("./de-DtWiGdHl.js")), "./translations/dk.json": () => Promise.resolve().then(() => require("./dk-D8C-casx.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-Kv6y9zPQ.js")), "./translations/es.json": () => Promise.resolve().then(() => require("./es-DS-XFGSw.js")), "./translations/fr.json": () => Promise.resolve().then(() => require("./fr-BTjekDpq.js")), "./translations/ko.json": () => Promise.resolve().then(() => require("./ko-DmcGUBQ3.js")), "./translations/pl.json": () => Promise.resolve().then(() => require("./pl-Cn5RYonZ.js")), "./translations/ru.json": () => Promise.resolve().then(() => require("./ru-BMBgVL3s.js")), "./translations/tr.json": () => Promise.resolve().then(() => require("./tr-CarUU76c.js")), "./translations/zh-Hans.json": () => Promise.resolve().then(() => require("./zh-Hans-DSHIXAa3.js")), "./translations/zh.json": () => Promise.resolve().then(() => require("./zh-CukOviB0.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
1058
1371
  return {
1059
1372
  data: prefixPluginTranslations(data, pluginId),
1060
1373
  locale
@@ -1073,10 +1386,9 @@ const index = {
1073
1386
  exports.PERMISSIONS = PERMISSIONS;
1074
1387
  exports.getTranslation = getTranslation;
1075
1388
  exports.index = index;
1076
- exports.isBaseQueryError = isBaseQueryError;
1077
1389
  exports.useCreateLocaleMutation = useCreateLocaleMutation;
1078
1390
  exports.useDeleteLocaleMutation = useDeleteLocaleMutation;
1079
1391
  exports.useGetDefaultLocalesQuery = useGetDefaultLocalesQuery;
1080
1392
  exports.useGetLocalesQuery = useGetLocalesQuery;
1081
1393
  exports.useUpdateLocaleMutation = useUpdateLocaleMutation;
1082
- //# sourceMappingURL=index-DMXJeGjN.js.map
1394
+ //# sourceMappingURL=index-kedPlCo6.js.map