@strapi/i18n 0.0.0-experimental.1610404a03d98b65f497f9adda35815021b8fd76 → 0.0.0-experimental.16a6ec52546a0c189b42121e51a744fd04fc0d65

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 (140) hide show
  1. package/dist/admin/chunks/SettingsPage-BOEeBbiM.mjs +797 -0
  2. package/dist/admin/chunks/SettingsPage-BOEeBbiM.mjs.map +1 -0
  3. package/dist/admin/chunks/SettingsPage-Mg2Ygywx.js +820 -0
  4. package/dist/admin/chunks/SettingsPage-Mg2Ygywx.js.map +1 -0
  5. package/dist/admin/chunks/de-Cm8mYdaO.mjs +64 -0
  6. package/dist/admin/chunks/de-Cm8mYdaO.mjs.map +1 -0
  7. package/dist/admin/chunks/de-nEMWvIiY.js +66 -0
  8. package/dist/admin/chunks/de-nEMWvIiY.js.map +1 -0
  9. package/dist/admin/chunks/dk-BeUFOegB.mjs +64 -0
  10. package/dist/admin/chunks/dk-BeUFOegB.mjs.map +1 -0
  11. package/dist/admin/chunks/dk-CYATLPVe.js +66 -0
  12. package/dist/admin/chunks/dk-CYATLPVe.js.map +1 -0
  13. package/dist/admin/chunks/en-CG5cUCbD.js +81 -0
  14. package/dist/admin/chunks/en-CG5cUCbD.js.map +1 -0
  15. package/dist/admin/chunks/en-eWSaCeOb.mjs +79 -0
  16. package/dist/admin/chunks/en-eWSaCeOb.mjs.map +1 -0
  17. package/dist/admin/chunks/es-CWsogTGm.js +66 -0
  18. package/dist/admin/chunks/es-CWsogTGm.js.map +1 -0
  19. package/dist/admin/chunks/es-DqF_IdAc.mjs +64 -0
  20. package/dist/admin/chunks/es-DqF_IdAc.mjs.map +1 -0
  21. package/dist/admin/chunks/fr-CC7UFcYd.js +66 -0
  22. package/dist/admin/chunks/fr-CC7UFcYd.js.map +1 -0
  23. package/dist/admin/chunks/fr-CyARbZ3c.mjs +64 -0
  24. package/dist/admin/chunks/fr-CyARbZ3c.mjs.map +1 -0
  25. package/dist/admin/chunks/index--VTS8j_L.mjs +2008 -0
  26. package/dist/admin/chunks/index--VTS8j_L.mjs.map +1 -0
  27. package/dist/admin/chunks/index-hJ67XV0K.js +2037 -0
  28. package/dist/admin/chunks/index-hJ67XV0K.js.map +1 -0
  29. package/dist/admin/chunks/ko-Ax4NSedM.mjs +63 -0
  30. package/dist/admin/chunks/ko-Ax4NSedM.mjs.map +1 -0
  31. package/dist/admin/chunks/ko-XwGmfhoq.js +65 -0
  32. package/dist/admin/chunks/ko-XwGmfhoq.js.map +1 -0
  33. package/dist/admin/chunks/pl-B-aqvMqL.mjs +64 -0
  34. package/dist/admin/chunks/pl-B-aqvMqL.mjs.map +1 -0
  35. package/dist/admin/chunks/pl-B_vzY_ZB.js +66 -0
  36. package/dist/admin/chunks/pl-B_vzY_ZB.js.map +1 -0
  37. package/dist/admin/chunks/ru-VkPjQ-Sk.mjs +66 -0
  38. package/dist/admin/chunks/ru-VkPjQ-Sk.mjs.map +1 -0
  39. package/dist/admin/chunks/ru-WzHcJV1f.js +68 -0
  40. package/dist/admin/chunks/ru-WzHcJV1f.js.map +1 -0
  41. package/dist/admin/chunks/tr-CcWp6u3w.js +66 -0
  42. package/dist/admin/chunks/tr-CcWp6u3w.js.map +1 -0
  43. package/dist/admin/chunks/tr-DcTR88c9.mjs +64 -0
  44. package/dist/admin/chunks/tr-DcTR88c9.mjs.map +1 -0
  45. package/dist/admin/chunks/uk-CMz6iPag.mjs +80 -0
  46. package/dist/admin/chunks/uk-CMz6iPag.mjs.map +1 -0
  47. package/dist/admin/chunks/uk-CO6JHYRC.js +82 -0
  48. package/dist/admin/chunks/uk-CO6JHYRC.js.map +1 -0
  49. package/dist/admin/chunks/zh-C9So4SGq.js +66 -0
  50. package/dist/admin/chunks/zh-C9So4SGq.js.map +1 -0
  51. package/dist/admin/chunks/zh-Hans-DnU2bhri.js +57 -0
  52. package/dist/admin/chunks/zh-Hans-DnU2bhri.js.map +1 -0
  53. package/dist/admin/chunks/zh-Hans-L3wsRegj.mjs +55 -0
  54. package/dist/admin/chunks/zh-Hans-L3wsRegj.mjs.map +1 -0
  55. package/dist/admin/chunks/zh-RZyMiPIs.mjs +64 -0
  56. package/dist/admin/chunks/zh-RZyMiPIs.mjs.map +1 -0
  57. package/dist/admin/index.js +20 -4
  58. package/dist/admin/index.js.map +1 -1
  59. package/dist/admin/index.mjs +15 -6
  60. package/dist/admin/index.mjs.map +1 -1
  61. package/dist/admin/src/components/CMHeaderActions.d.ts +2 -2
  62. package/dist/admin/src/components/LocaleListCell.d.ts +4 -4
  63. package/dist/admin/src/components/tests/CreateLocale.test.d.ts +1 -0
  64. package/dist/admin/src/components/tests/DeleteLocale.test.d.ts +1 -0
  65. package/dist/admin/src/components/tests/EditLocale.test.d.ts +1 -0
  66. package/dist/admin/src/components/tests/LocaleListCell.test.d.ts +1 -0
  67. package/dist/admin/src/contentReleasesHooks/releaseDetailsView.d.ts +1 -1
  68. package/dist/admin/src/pages/tests/SettingsPage.test.d.ts +1 -0
  69. package/dist/admin/tests/server.d.ts +1 -0
  70. package/dist/admin/tests/utils.d.ts +6 -0
  71. package/dist/server/index.js +3651 -3360
  72. package/dist/server/index.js.map +1 -1
  73. package/dist/server/index.mjs +3633 -3344
  74. package/dist/server/index.mjs.map +1 -1
  75. package/dist/server/src/index.d.ts +6 -0
  76. package/dist/server/src/index.d.ts.map +1 -1
  77. package/dist/server/src/register.d.ts.map +1 -1
  78. package/dist/server/src/services/index.d.ts +6 -0
  79. package/dist/server/src/services/index.d.ts.map +1 -1
  80. package/dist/server/src/services/localizations.d.ts +1 -1
  81. package/dist/server/src/services/localizations.d.ts.map +1 -1
  82. package/dist/server/src/services/sanitize/index.d.ts +11 -0
  83. package/dist/server/src/services/sanitize/index.d.ts.map +1 -0
  84. package/dist/server/src/utils/index.d.ts +2 -0
  85. package/dist/server/src/utils/index.d.ts.map +1 -1
  86. package/dist/shared/contracts/content-manager.d.ts +1 -1
  87. package/dist/shared/contracts/shared.d.ts +1 -1
  88. package/package.json +18 -16
  89. package/dist/_chunks/SettingsPage-BWEhlJzY.mjs +0 -554
  90. package/dist/_chunks/SettingsPage-BWEhlJzY.mjs.map +0 -1
  91. package/dist/_chunks/SettingsPage-DqW7hbxl.js +0 -573
  92. package/dist/_chunks/SettingsPage-DqW7hbxl.js.map +0 -1
  93. package/dist/_chunks/de-9eCAqqrB.mjs +0 -66
  94. package/dist/_chunks/de-9eCAqqrB.mjs.map +0 -1
  95. package/dist/_chunks/de-DtWiGdHl.js +0 -66
  96. package/dist/_chunks/de-DtWiGdHl.js.map +0 -1
  97. package/dist/_chunks/dk-2qBjxt-P.mjs +0 -66
  98. package/dist/_chunks/dk-2qBjxt-P.mjs.map +0 -1
  99. package/dist/_chunks/dk-D8C-casx.js +0 -66
  100. package/dist/_chunks/dk-D8C-casx.js.map +0 -1
  101. package/dist/_chunks/en-BKBz3tro.js +0 -81
  102. package/dist/_chunks/en-BKBz3tro.js.map +0 -1
  103. package/dist/_chunks/en-DlXfy6Gy.mjs +0 -81
  104. package/dist/_chunks/en-DlXfy6Gy.mjs.map +0 -1
  105. package/dist/_chunks/es-DS-XFGSw.js +0 -66
  106. package/dist/_chunks/es-DS-XFGSw.js.map +0 -1
  107. package/dist/_chunks/es-DlmMVaBG.mjs +0 -66
  108. package/dist/_chunks/es-DlmMVaBG.mjs.map +0 -1
  109. package/dist/_chunks/fr-3S6ke71d.mjs +0 -66
  110. package/dist/_chunks/fr-3S6ke71d.mjs.map +0 -1
  111. package/dist/_chunks/fr-BTjekDpq.js +0 -66
  112. package/dist/_chunks/fr-BTjekDpq.js.map +0 -1
  113. package/dist/_chunks/index-93hDLj9o.js +0 -1639
  114. package/dist/_chunks/index-93hDLj9o.js.map +0 -1
  115. package/dist/_chunks/index-C6Fyjx-i.mjs +0 -1618
  116. package/dist/_chunks/index-C6Fyjx-i.mjs.map +0 -1
  117. package/dist/_chunks/ko-DmcGUBQ3.js +0 -65
  118. package/dist/_chunks/ko-DmcGUBQ3.js.map +0 -1
  119. package/dist/_chunks/ko-qTjQ8IMw.mjs +0 -65
  120. package/dist/_chunks/ko-qTjQ8IMw.mjs.map +0 -1
  121. package/dist/_chunks/pl-B67TSHqT.mjs +0 -66
  122. package/dist/_chunks/pl-B67TSHqT.mjs.map +0 -1
  123. package/dist/_chunks/pl-Cn5RYonZ.js +0 -66
  124. package/dist/_chunks/pl-Cn5RYonZ.js.map +0 -1
  125. package/dist/_chunks/ru-BMBgVL3s.js +0 -68
  126. package/dist/_chunks/ru-BMBgVL3s.js.map +0 -1
  127. package/dist/_chunks/ru-hagMa57T.mjs +0 -68
  128. package/dist/_chunks/ru-hagMa57T.mjs.map +0 -1
  129. package/dist/_chunks/tr-CarUU76c.js +0 -66
  130. package/dist/_chunks/tr-CarUU76c.js.map +0 -1
  131. package/dist/_chunks/tr-Dw_jmkG-.mjs +0 -66
  132. package/dist/_chunks/tr-Dw_jmkG-.mjs.map +0 -1
  133. package/dist/_chunks/zh-57YM4amO.mjs +0 -66
  134. package/dist/_chunks/zh-57YM4amO.mjs.map +0 -1
  135. package/dist/_chunks/zh-CukOviB0.js +0 -66
  136. package/dist/_chunks/zh-CukOviB0.js.map +0 -1
  137. package/dist/_chunks/zh-Hans-DSHIXAa3.js +0 -57
  138. package/dist/_chunks/zh-Hans-DSHIXAa3.js.map +0 -1
  139. package/dist/_chunks/zh-Hans-Dyc-aR-h.mjs +0 -57
  140. package/dist/_chunks/zh-Hans-Dyc-aR-h.mjs.map +0 -1
@@ -1,1639 +0,0 @@
1
- "use strict";
2
- const get = require("lodash/get");
3
- const yup = require("yup");
4
- const jsxRuntime = require("react/jsx-runtime");
5
- const React = require("react");
6
- const designSystem = require("@strapi/design-system");
7
- const icons = require("@strapi/icons");
8
- const reactIntl = require("react-intl");
9
- const styledComponents = require("styled-components");
10
- const query = require("@reduxjs/toolkit/query");
11
- const strapiAdmin = require("@strapi/admin/strapi-admin");
12
- const strapiAdmin$1 = require("@strapi/content-manager/strapi-admin");
13
- const reactRouterDom = require("react-router-dom");
14
- const qs = require("qs");
15
- const omit = require("lodash/omit");
16
- const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
17
- function _interopNamespace(e) {
18
- if (e && e.__esModule) return e;
19
- const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
20
- if (e) {
21
- for (const k in e) {
22
- if (k !== "default") {
23
- const d = Object.getOwnPropertyDescriptor(e, k);
24
- Object.defineProperty(n, k, d.get ? d : {
25
- enumerable: true,
26
- get: () => e[k]
27
- });
28
- }
29
- }
30
- }
31
- n.default = e;
32
- return Object.freeze(n);
33
- }
34
- const get__default = /* @__PURE__ */ _interopDefault(get);
35
- const yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
36
- const React__namespace = /* @__PURE__ */ _interopNamespace(React);
37
- const qs__namespace = /* @__PURE__ */ _interopNamespace(qs);
38
- const omit__default = /* @__PURE__ */ _interopDefault(omit);
39
- const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
40
- const v = glob[path];
41
- if (v) {
42
- return typeof v === "function" ? v() : Promise.resolve(v);
43
- }
44
- return new Promise((_, reject) => {
45
- (typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
46
- reject.bind(
47
- null,
48
- new Error(
49
- "Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
50
- )
51
- )
52
- );
53
- });
54
- };
55
- const pluginId = "i18n";
56
- const getTranslation = (id) => `${pluginId}.${id}`;
57
- const TextAlignTypography = styledComponents.styled(designSystem.Typography)`
58
- text-align: center;
59
- `;
60
- const CheckboxConfirmation = ({
61
- description,
62
- isCreating = false,
63
- intlLabel,
64
- name,
65
- onChange,
66
- value
67
- }) => {
68
- const { formatMessage } = reactIntl.useIntl();
69
- const [isOpen, setIsOpen] = React__namespace.useState(false);
70
- const handleChange = (value2) => {
71
- if (isCreating || value2) {
72
- return onChange({ target: { name, value: value2, type: "checkbox" } });
73
- }
74
- if (!value2) {
75
- return setIsOpen(true);
76
- }
77
- return null;
78
- };
79
- const handleConfirm = () => {
80
- onChange({ target: { name, value: false, type: "checkbox" } });
81
- };
82
- const label = intlLabel.id ? formatMessage(
83
- { id: intlLabel.id, defaultMessage: intlLabel.defaultMessage },
84
- { ...intlLabel.values }
85
- ) : name;
86
- const hint = description ? formatMessage(
87
- { id: description.id, defaultMessage: description.defaultMessage },
88
- { ...description.values }
89
- ) : "";
90
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Root, { open: isOpen, onOpenChange: setIsOpen, children: [
91
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { hint, name, children: [
92
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Checkbox, { onCheckedChange: handleChange, checked: value, children: label }),
93
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {})
94
- ] }),
95
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
96
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: formatMessage({
97
- id: getTranslation("CheckboxConfirmation.Modal.title"),
98
- defaultMessage: "Disable localization"
99
- }) }),
100
- /* @__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: [
101
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(TextAlignTypography, { children: formatMessage({
102
- id: getTranslation("CheckboxConfirmation.Modal.content"),
103
- defaultMessage: "Disabling localization will engender the deletion of all your content but the one associated to your default locale (if existing)."
104
- }) }) }),
105
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", children: formatMessage({
106
- id: getTranslation("CheckboxConfirmation.Modal.body"),
107
- defaultMessage: "Do you want to disable it?"
108
- }) }) })
109
- ] }) }),
110
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
111
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", children: formatMessage({
112
- id: "components.popUpWarning.button.cancel",
113
- defaultMessage: "No, cancel"
114
- }) }) }),
115
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Action, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "danger-light", onClick: handleConfirm, children: formatMessage({
116
- id: getTranslation("CheckboxConfirmation.Modal.button-confirm"),
117
- defaultMessage: "Yes, disable"
118
- }) }) })
119
- ] })
120
- ] })
121
- ] });
122
- };
123
- const LOCALIZED_FIELDS = [
124
- "biginteger",
125
- "boolean",
126
- "component",
127
- "date",
128
- "datetime",
129
- "decimal",
130
- "dynamiczone",
131
- "email",
132
- "enumeration",
133
- "float",
134
- "integer",
135
- "json",
136
- "media",
137
- "number",
138
- "password",
139
- "richtext",
140
- "blocks",
141
- "string",
142
- "text",
143
- "time"
144
- ];
145
- const doesPluginOptionsHaveI18nLocalized = (opts) => typeof opts === "object" && opts !== null && "i18n" in opts && typeof opts.i18n === "object" && opts.i18n !== null && "localized" in opts.i18n && typeof opts.i18n.localized === "boolean";
146
- const capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1);
147
- const useI18n = () => {
148
- const params = reactRouterDom.useParams();
149
- const userPermissions = strapiAdmin.useAuth("useI18n", (state) => state.permissions);
150
- const actions = React__namespace.useMemo(() => {
151
- const permissions = userPermissions.filter((permission) => permission.subject === params.slug);
152
- return permissions.reduce(
153
- (acc, permission) => {
154
- const [actionShorthand] = permission.action.split(".").slice(-1);
155
- return {
156
- ...acc,
157
- [`can${capitalize(actionShorthand)}`]: permission.properties?.locales ?? []
158
- };
159
- },
160
- { canCreate: [], canRead: [], canUpdate: [], canDelete: [], canPublish: [] }
161
- );
162
- }, [params.slug, userPermissions]);
163
- const { schema } = strapiAdmin$1.unstable_useDocument(
164
- {
165
- // We can non-null assert these because below we skip the query if they are not present
166
- collectionType: params.collectionType,
167
- model: params.slug
168
- },
169
- {
170
- skip: true
171
- }
172
- );
173
- if (doesPluginOptionsHaveI18nLocalized(schema?.pluginOptions)) {
174
- return {
175
- hasI18n: schema.pluginOptions.i18n.localized,
176
- ...actions
177
- };
178
- }
179
- return {
180
- hasI18n: false,
181
- ...actions
182
- };
183
- };
184
- const i18nApi = strapiAdmin.adminApi.enhanceEndpoints({
185
- addTagTypes: ["Locale"]
186
- });
187
- const localesApi = i18nApi.injectEndpoints({
188
- endpoints: (builder) => ({
189
- createLocale: builder.mutation({
190
- query: (data) => ({
191
- url: "/i18n/locales",
192
- method: "POST",
193
- data
194
- }),
195
- invalidatesTags: [{ type: "Locale", id: "LIST" }]
196
- }),
197
- deleteLocale: builder.mutation({
198
- query: (id) => ({
199
- url: `/i18n/locales/${id}`,
200
- method: "DELETE"
201
- }),
202
- invalidatesTags: (result, error, id) => [{ type: "Locale", id }]
203
- }),
204
- getLocales: builder.query({
205
- query: () => "/i18n/locales",
206
- providesTags: (res) => [
207
- { type: "Locale", id: "LIST" },
208
- ...Array.isArray(res) ? res.map((locale) => ({
209
- type: "Locale",
210
- id: locale.id
211
- })) : []
212
- ]
213
- }),
214
- getDefaultLocales: builder.query({
215
- query: () => "/i18n/iso-locales"
216
- }),
217
- updateLocale: builder.mutation({
218
- query: ({ id, ...data }) => ({
219
- url: `/i18n/locales/${id}`,
220
- method: "PUT",
221
- data
222
- }),
223
- invalidatesTags: (result, error, { id }) => [{ type: "Locale", id }]
224
- })
225
- })
226
- });
227
- const {
228
- useCreateLocaleMutation,
229
- useDeleteLocaleMutation,
230
- useGetLocalesQuery,
231
- useGetDefaultLocalesQuery,
232
- useUpdateLocaleMutation
233
- } = localesApi;
234
- const relationsApi = i18nApi.injectEndpoints({
235
- overrideExisting: true,
236
- endpoints: (builder) => ({
237
- getManyDraftRelationCount: builder.query({
238
- query: ({ model, ...params }) => ({
239
- url: `/content-manager/collection-types/${model}/actions/countManyEntriesDraftRelations`,
240
- method: "GET",
241
- config: {
242
- params
243
- }
244
- }),
245
- transformResponse: (response) => response.data
246
- })
247
- })
248
- });
249
- const { useGetManyDraftRelationCountQuery } = relationsApi;
250
- const cleanData = (data, schema, components) => {
251
- const cleanedData = removeFields(data, [
252
- "createdAt",
253
- "createdBy",
254
- "updatedAt",
255
- "updatedBy",
256
- "id",
257
- "documentId",
258
- "publishedAt",
259
- "strapi_stage",
260
- "strapi_assignee",
261
- "locale",
262
- "status"
263
- ]);
264
- const cleanedDataWithoutPasswordAndRelation = recursiveRemoveFieldTypes(
265
- cleanedData,
266
- schema,
267
- components,
268
- ["relation", "password"]
269
- );
270
- return cleanedDataWithoutPasswordAndRelation;
271
- };
272
- const removeFields = (data, fields) => {
273
- return Object.keys(data).reduce((acc, current) => {
274
- if (fields.includes(current)) {
275
- return acc;
276
- }
277
- acc[current] = data[current];
278
- return acc;
279
- }, {});
280
- };
281
- const recursiveRemoveFieldTypes = (data, schema, components, fields) => {
282
- return Object.keys(data).reduce((acc, current) => {
283
- const attribute = schema.attributes[current] ?? { type: void 0 };
284
- if (fields.includes(attribute.type)) {
285
- return acc;
286
- }
287
- if (attribute.type === "dynamiczone") {
288
- acc[current] = data[current].map((componentValue, index2) => {
289
- const { id: _, ...rest } = recursiveRemoveFieldTypes(
290
- componentValue,
291
- components[componentValue.__component],
292
- components,
293
- fields
294
- );
295
- return {
296
- ...rest,
297
- __temp_key__: index2 + 1
298
- };
299
- });
300
- } else if (attribute.type === "component") {
301
- const { repeatable, component } = attribute;
302
- if (repeatable) {
303
- acc[current] = (data[current] ?? []).map((compoData, index2) => {
304
- const { id: _, ...rest } = recursiveRemoveFieldTypes(
305
- compoData,
306
- components[component],
307
- components,
308
- fields
309
- );
310
- return {
311
- ...rest,
312
- __temp_key__: index2 + 1
313
- };
314
- });
315
- } else {
316
- const { id: _, ...rest } = recursiveRemoveFieldTypes(
317
- data[current] ?? {},
318
- components[component],
319
- components,
320
- fields
321
- );
322
- acc[current] = rest;
323
- }
324
- } else {
325
- acc[current] = data[current];
326
- }
327
- return acc;
328
- }, {});
329
- };
330
- const isErrorMessageDescriptor = (object) => {
331
- return typeof object === "object" && object !== null && "id" in object && "defaultMessage" in object;
332
- };
333
- const EntryValidationText = ({
334
- status = "draft",
335
- validationErrors,
336
- action
337
- }) => {
338
- const { formatMessage } = reactIntl.useIntl();
339
- const getErrorStr = (key, value) => {
340
- if (typeof value === "string") {
341
- return `${key}: ${value}`;
342
- } else if (isErrorMessageDescriptor(value)) {
343
- return `${key}: ${formatMessage(value)}`;
344
- } else if (Array.isArray(value)) {
345
- return value.map((v) => getErrorStr(key, v)).join(" ");
346
- } else if (typeof value === "object" && !Array.isArray(value)) {
347
- return Object.entries(value).map(([k, v]) => getErrorStr(k, v)).join(" ");
348
- } else {
349
- return "";
350
- }
351
- };
352
- if (validationErrors) {
353
- const validationErrorsMessages = Object.entries(validationErrors).map(([key, value]) => {
354
- return getErrorStr(key, value);
355
- }).join(" ");
356
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
357
- /* @__PURE__ */ jsxRuntime.jsx(icons.CrossCircle, { fill: "danger600" }),
358
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { label: validationErrorsMessages, children: /* @__PURE__ */ jsxRuntime.jsx(
359
- designSystem.Typography,
360
- {
361
- maxWidth: "30rem",
362
- textColor: "danger600",
363
- variant: "omega",
364
- fontWeight: "semiBold",
365
- ellipsis: true,
366
- children: validationErrorsMessages
367
- }
368
- ) })
369
- ] });
370
- }
371
- const getStatusMessage = () => {
372
- if (action === "bulk-publish") {
373
- if (status === "published") {
374
- return {
375
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
376
- text: formatMessage({
377
- id: "content-manager.bulk-publish.already-published",
378
- defaultMessage: "Already Published"
379
- }),
380
- textColor: "success600",
381
- fontWeight: "bold"
382
- };
383
- } else if (status === "modified") {
384
- return {
385
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowsCounterClockwise, { fill: "alternative600" }),
386
- text: formatMessage({
387
- id: "app.utils.ready-to-publish-changes",
388
- defaultMessage: "Ready to publish changes"
389
- })
390
- };
391
- } else {
392
- return {
393
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
394
- text: formatMessage({
395
- id: "app.utils.ready-to-publish",
396
- defaultMessage: "Ready to publish"
397
- })
398
- };
399
- }
400
- } else {
401
- if (status === "draft") {
402
- return {
403
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
404
- text: formatMessage({
405
- id: "content-manager.bulk-unpublish.already-unpublished",
406
- defaultMessage: "Already Unpublished"
407
- }),
408
- textColor: "success600",
409
- fontWeight: "bold"
410
- };
411
- } else {
412
- return {
413
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { fill: "success600" }),
414
- text: formatMessage({
415
- id: "app.utils.ready-to-unpublish-changes",
416
- defaultMessage: "Ready to unpublish"
417
- }),
418
- textColor: "success600",
419
- fontWeight: "bold"
420
- };
421
- }
422
- }
423
- };
424
- const { icon, text, textColor = "success600", fontWeight = "normal" } = getStatusMessage();
425
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
426
- icon,
427
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor, fontWeight, children: text })
428
- ] });
429
- };
430
- const BoldChunk = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
431
- const BulkLocaleActionModal = ({
432
- headers,
433
- rows,
434
- localesMetadata,
435
- validationErrors = {},
436
- action
437
- }) => {
438
- const { formatMessage } = reactIntl.useIntl();
439
- const selectedRows = strapiAdmin.useTable(
440
- "BulkLocaleActionModal",
441
- (state) => state.selectedRows
442
- );
443
- const getFormattedCountMessage = () => {
444
- const currentStatusByLocale = rows.reduce((acc, { locale, status }) => {
445
- acc[locale] = status;
446
- return acc;
447
- }, {});
448
- const localesWithErrors = Object.keys(validationErrors);
449
- const publishedCount = selectedRows.filter(
450
- ({ locale }) => currentStatusByLocale[locale] === "published"
451
- ).length;
452
- const draftCount = selectedRows.filter(
453
- ({ locale }) => (currentStatusByLocale[locale] === "draft" || currentStatusByLocale[locale] === "modified") && !localesWithErrors.includes(locale)
454
- ).length;
455
- const withErrorsCount = localesWithErrors.length;
456
- const messageId = action === "bulk-publish" ? "content-manager.containers.list.selectedEntriesModal.selectedCount.publish" : "content-manager.containers.list.selectedEntriesModal.selectedCount.unpublish";
457
- 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.";
458
- return formatMessage(
459
- {
460
- id: messageId,
461
- defaultMessage
462
- },
463
- {
464
- withErrorsCount,
465
- draftCount,
466
- publishedCount,
467
- b: BoldChunk
468
- }
469
- );
470
- };
471
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Body, { children: [
472
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: getFormattedCountMessage() }),
473
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 5, children: /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Content, { children: [
474
- /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Head, { children: [
475
- /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.HeaderCheckboxCell, {}),
476
- headers.map((head) => /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.HeaderCell, { ...head }, head.name))
477
- ] }),
478
- /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Body, { children: rows.map(({ locale, status }, index2) => {
479
- const error = validationErrors?.[locale] ?? null;
480
- const statusVariant = status === "draft" ? "primary" : status === "published" ? "success" : "alternative";
481
- return /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Row, { children: [
482
- /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.CheckboxCell, { id: locale, "aria-label": `Select ${locale}` }),
483
- /* @__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 }) }),
484
- /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { display: "flex", children: /* @__PURE__ */ jsxRuntime.jsx(
485
- designSystem.Status,
486
- {
487
- display: "flex",
488
- paddingLeft: "6px",
489
- paddingRight: "6px",
490
- paddingTop: "2px",
491
- paddingBottom: "2px",
492
- showBullet: false,
493
- size: "S",
494
- variant: statusVariant,
495
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
496
- }
497
- ) }) }),
498
- /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(EntryValidationText, { validationErrors: error, status, action }) }),
499
- /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(
500
- designSystem.IconButton,
501
- {
502
- tag: reactRouterDom.Link,
503
- to: {
504
- search: qs.stringify({ plugins: { i18n: { locale } } })
505
- },
506
- label: formatMessage(
507
- {
508
- id: getTranslation("Settings.list.actions.edit"),
509
- defaultMessage: "Edit {name} locale"
510
- },
511
- {
512
- name: locale
513
- }
514
- ),
515
- variant: "ghost",
516
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.Pencil, {})
517
- }
518
- ) })
519
- ] }, index2);
520
- }) })
521
- ] }) })
522
- ] });
523
- };
524
- const statusVariants = {
525
- draft: "secondary",
526
- published: "success",
527
- modified: "alternative"
528
- };
529
- const LocaleOption = ({
530
- isDraftAndPublishEnabled,
531
- locale,
532
- status,
533
- entryExists
534
- }) => {
535
- const { formatMessage } = reactIntl.useIntl();
536
- if (!entryExists) {
537
- return formatMessage(
538
- {
539
- id: getTranslation("CMEditViewLocalePicker.locale.create"),
540
- defaultMessage: "Create <bold>{locale}</bold> locale"
541
- },
542
- {
543
- bold: (locale2) => /* @__PURE__ */ jsxRuntime.jsx("b", { children: locale2 }),
544
- locale: locale.name
545
- }
546
- );
547
- }
548
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", gap: 1, justifyContent: "space-between", children: [
549
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: locale.name }),
550
- isDraftAndPublishEnabled ? /* @__PURE__ */ jsxRuntime.jsx(
551
- designSystem.Status,
552
- {
553
- display: "flex",
554
- paddingLeft: "6px",
555
- paddingRight: "6px",
556
- paddingTop: "2px",
557
- paddingBottom: "2px",
558
- showBullet: false,
559
- size: "S",
560
- variant: statusVariants[status],
561
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
562
- }
563
- ) : null
564
- ] });
565
- };
566
- const LocalePickerAction = ({
567
- document,
568
- meta,
569
- model,
570
- collectionType,
571
- documentId
572
- }) => {
573
- const { formatMessage } = reactIntl.useIntl();
574
- const [{ query: query2 }, setQuery] = strapiAdmin.useQueryParams();
575
- const { hasI18n, canCreate, canRead } = useI18n();
576
- const { data: locales = [] } = useGetLocalesQuery();
577
- const currentDesiredLocale = query2.plugins?.i18n?.locale;
578
- const { schema } = strapiAdmin$1.unstable_useDocument({
579
- model,
580
- collectionType,
581
- documentId,
582
- params: { locale: currentDesiredLocale }
583
- });
584
- const handleSelect = React__namespace.useCallback(
585
- (value) => {
586
- setQuery({
587
- plugins: {
588
- ...query2.plugins,
589
- i18n: {
590
- locale: value
591
- }
592
- }
593
- });
594
- },
595
- [query2.plugins, setQuery]
596
- );
597
- React__namespace.useEffect(() => {
598
- if (!Array.isArray(locales) || !hasI18n) {
599
- return;
600
- }
601
- const doesLocaleExist = locales.find((loc) => loc.code === currentDesiredLocale);
602
- const defaultLocale = locales.find((locale) => locale.isDefault);
603
- if (!doesLocaleExist && defaultLocale?.code) {
604
- handleSelect(defaultLocale.code);
605
- }
606
- }, [handleSelect, hasI18n, locales, currentDesiredLocale]);
607
- const currentLocale = Array.isArray(locales) ? locales.find((locale) => locale.code === currentDesiredLocale) : void 0;
608
- const allCurrentLocales = [
609
- { status: getDocumentStatus(document, meta), locale: currentLocale?.code },
610
- ...meta?.availableLocales ?? []
611
- ];
612
- if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
613
- return null;
614
- }
615
- return {
616
- label: formatMessage({
617
- id: getTranslation("Settings.locales.modal.locales.label"),
618
- defaultMessage: "Locales"
619
- }),
620
- options: locales.map((locale) => {
621
- const entryWithLocaleExists = allCurrentLocales.some((doc) => doc.locale === locale.code);
622
- const currentLocaleDoc = allCurrentLocales.find(
623
- (doc) => "locale" in doc ? doc.locale === locale.code : false
624
- );
625
- const permissionsToCheck = currentLocaleDoc ? canRead : canCreate;
626
- return {
627
- disabled: !permissionsToCheck.includes(locale.code),
628
- value: locale.code,
629
- label: /* @__PURE__ */ jsxRuntime.jsx(
630
- LocaleOption,
631
- {
632
- isDraftAndPublishEnabled: !!schema?.options?.draftAndPublish,
633
- locale,
634
- status: currentLocaleDoc?.status,
635
- entryExists: entryWithLocaleExists
636
- }
637
- ),
638
- startIcon: !entryWithLocaleExists ? /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}) : null
639
- };
640
- }),
641
- customizeContent: () => currentLocale?.name,
642
- onSelect: handleSelect,
643
- value: currentLocale
644
- };
645
- };
646
- const getDocumentStatus = (document, meta) => {
647
- const docStatus = document?.status;
648
- const statuses = meta?.availableStatus ?? [];
649
- if (!docStatus) {
650
- return "draft";
651
- }
652
- if (docStatus === "draft" && statuses.find((doc) => doc.publishedAt !== null)) {
653
- return "published";
654
- }
655
- return docStatus;
656
- };
657
- const FillFromAnotherLocaleAction = ({
658
- documentId,
659
- meta,
660
- model,
661
- collectionType
662
- }) => {
663
- const { formatMessage } = reactIntl.useIntl();
664
- const [{ query: query2 }] = strapiAdmin.useQueryParams();
665
- const currentDesiredLocale = query2.plugins?.i18n?.locale;
666
- const [localeSelected, setLocaleSelected] = React__namespace.useState(null);
667
- const setValues = strapiAdmin.useForm("FillFromAnotherLocale", (state) => state.setValues);
668
- const { getDocument } = strapiAdmin$1.unstable_useDocumentActions();
669
- const { schema, components } = strapiAdmin$1.unstable_useDocument({
670
- model,
671
- documentId,
672
- collectionType,
673
- params: { locale: currentDesiredLocale }
674
- });
675
- const { data: locales = [] } = useGetLocalesQuery();
676
- const availableLocales = Array.isArray(locales) ? locales.filter((locale) => meta?.availableLocales.some((l) => l.locale === locale.code)) : [];
677
- const fillFromLocale = (onClose) => async () => {
678
- const response = await getDocument({
679
- collectionType,
680
- model,
681
- documentId,
682
- params: { locale: localeSelected }
683
- });
684
- if (!response || !schema) {
685
- return;
686
- }
687
- const { data } = response;
688
- const cleanedData = cleanData(data, schema, components);
689
- setValues(cleanedData);
690
- onClose();
691
- };
692
- return {
693
- type: "icon",
694
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Download, {}),
695
- disabled: availableLocales.length === 0,
696
- label: formatMessage({
697
- id: getTranslation("CMEditViewCopyLocale.copy-text"),
698
- defaultMessage: "Fill in from another locale"
699
- }),
700
- dialog: {
701
- type: "dialog",
702
- title: formatMessage({
703
- id: getTranslation("CMEditViewCopyLocale.dialog.title"),
704
- defaultMessage: "Confirmation"
705
- }),
706
- content: ({ onClose }) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
707
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 3, children: [
708
- /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
709
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", children: formatMessage({
710
- id: getTranslation("CMEditViewCopyLocale.dialog.body"),
711
- defaultMessage: "Your current content will be erased and filled by the content of the selected locale:"
712
- }) }),
713
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { width: "100%", children: [
714
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: formatMessage({
715
- id: getTranslation("CMEditViewCopyLocale.dialog.field.label"),
716
- defaultMessage: "Locale"
717
- }) }),
718
- /* @__PURE__ */ jsxRuntime.jsx(
719
- designSystem.SingleSelect,
720
- {
721
- value: localeSelected,
722
- placeholder: formatMessage({
723
- id: getTranslation("CMEditViewCopyLocale.dialog.field.placeholder"),
724
- defaultMessage: "Select one locale..."
725
- }),
726
- onChange: (value) => setLocaleSelected(value),
727
- children: availableLocales.map((locale) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: locale.code, children: locale.name }, locale.code))
728
- }
729
- )
730
- ] })
731
- ] }) }),
732
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, width: "100%", children: [
733
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { flex: "auto", variant: "tertiary", onClick: onClose, children: formatMessage({
734
- id: getTranslation("CMEditViewCopyLocale.cancel-text"),
735
- defaultMessage: "No, cancel"
736
- }) }),
737
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { flex: "auto", variant: "success", onClick: fillFromLocale(onClose), children: formatMessage({
738
- id: getTranslation("CMEditViewCopyLocale.submit-text"),
739
- defaultMessage: "Yes, fill in"
740
- }) })
741
- ] }) })
742
- ] })
743
- }
744
- };
745
- };
746
- const DeleteLocaleAction = ({
747
- document,
748
- documentId,
749
- model,
750
- collectionType
751
- }) => {
752
- const { formatMessage } = reactIntl.useIntl();
753
- const navigate = reactRouterDom.useNavigate();
754
- const { toggleNotification } = strapiAdmin.useNotification();
755
- const { delete: deleteAction } = strapiAdmin$1.unstable_useDocumentActions();
756
- const { hasI18n, canDelete } = useI18n();
757
- const [{ query: query2 }] = strapiAdmin.useQueryParams();
758
- const { data: locales = [] } = useGetLocalesQuery();
759
- const currentDesiredLocale = query2.plugins?.i18n?.locale;
760
- const locale = !("error" in locales) && locales.find((loc) => loc.code === currentDesiredLocale);
761
- if (!hasI18n) {
762
- return null;
763
- }
764
- return {
765
- disabled: document?.locale && !canDelete.includes(document.locale) || !document || !document.id,
766
- position: ["header", "table-row"],
767
- label: formatMessage(
768
- {
769
- id: getTranslation("actions.delete.label"),
770
- defaultMessage: "Delete entry ({locale})"
771
- },
772
- { locale: locale && locale.name }
773
- ),
774
- icon: /* @__PURE__ */ jsxRuntime.jsx(StyledTrash, {}),
775
- variant: "danger",
776
- dialog: {
777
- type: "dialog",
778
- title: formatMessage({
779
- id: getTranslation("actions.delete.dialog.title"),
780
- defaultMessage: "Confirmation"
781
- }),
782
- content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, children: [
783
- /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
784
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
785
- id: getTranslation("actions.delete.dialog.body"),
786
- defaultMessage: "Are you sure?"
787
- }) })
788
- ] }),
789
- onConfirm: async () => {
790
- const unableToDelete = (
791
- // We are unable to delete a collection type without a document ID
792
- // & unable to delete generally if there is no document locale
793
- collectionType !== "single-types" && !documentId || !document?.locale
794
- );
795
- if (unableToDelete) {
796
- console.error(
797
- "You're trying to delete a document without an id or locale, this is likely a bug with Strapi. Please open an issue."
798
- );
799
- toggleNotification({
800
- message: formatMessage({
801
- id: getTranslation("actions.delete.error"),
802
- defaultMessage: "An error occurred while trying to delete the document locale."
803
- }),
804
- type: "danger"
805
- });
806
- return;
807
- }
808
- const res = await deleteAction({
809
- documentId,
810
- model,
811
- collectionType,
812
- params: { locale: document.locale }
813
- });
814
- if (!("error" in res)) {
815
- navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
816
- }
817
- }
818
- }
819
- };
820
- };
821
- const BulkLocaleAction = ({
822
- document: baseDocument,
823
- documentId,
824
- model,
825
- collectionType,
826
- action
827
- }) => {
828
- const baseLocale = baseDocument?.locale ?? null;
829
- const [{ query: query$1 }] = strapiAdmin.useQueryParams();
830
- const params = React__namespace.useMemo(() => strapiAdmin$1.buildValidParams(query$1), [query$1]);
831
- const isOnPublishedTab = query$1.status === "published";
832
- const { formatMessage } = reactIntl.useIntl();
833
- const { hasI18n, canPublish } = useI18n();
834
- const { toggleNotification } = strapiAdmin.useNotification();
835
- const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
836
- const [selectedRows, setSelectedRows] = React__namespace.useState([]);
837
- const [isDraftRelationConfirmationOpen, setIsDraftRelationConfirmationOpen] = React__namespace.useState(false);
838
- const { publishMany: publishManyAction, unpublishMany: unpublishManyAction } = strapiAdmin$1.unstable_useDocumentActions();
839
- const {
840
- document,
841
- meta: documentMeta,
842
- schema,
843
- validate
844
- } = strapiAdmin$1.unstable_useDocument(
845
- {
846
- model,
847
- collectionType,
848
- documentId,
849
- params: {
850
- locale: baseLocale
851
- }
852
- },
853
- {
854
- skip: !hasI18n || !baseLocale
855
- }
856
- );
857
- const { data: localesMetadata = [] } = useGetLocalesQuery(hasI18n ? void 0 : query.skipToken);
858
- const headers = [
859
- {
860
- label: formatMessage({
861
- id: "global.name",
862
- defaultMessage: "Name"
863
- }),
864
- name: "name"
865
- },
866
- {
867
- label: formatMessage({
868
- id: getTranslation("CMEditViewBulkLocale.status"),
869
- defaultMessage: "Status"
870
- }),
871
- name: "status"
872
- },
873
- {
874
- label: formatMessage({
875
- id: getTranslation("CMEditViewBulkLocale.publication-status"),
876
- defaultMessage: "Publication Status"
877
- }),
878
- name: "publication-status"
879
- }
880
- ];
881
- const [rows, validationErrors] = React__namespace.useMemo(() => {
882
- if (!document || !documentMeta?.availableLocales) {
883
- return [[], {}];
884
- }
885
- const rowsFromMeta = documentMeta?.availableLocales.map((doc) => {
886
- const { locale, status } = doc;
887
- return { locale, status };
888
- });
889
- rowsFromMeta.unshift({
890
- locale: document.locale,
891
- status: document.status
892
- });
893
- const allDocuments = [document, ...documentMeta?.availableLocales ?? []];
894
- const errors = allDocuments.reduce((errs, document2) => {
895
- if (!document2) {
896
- return errs;
897
- }
898
- const validation = validate(document2);
899
- if (validation !== null) {
900
- errs[document2.locale] = validation;
901
- }
902
- return errs;
903
- }, {});
904
- return [rowsFromMeta, errors];
905
- }, [document, documentMeta?.availableLocales, validate]);
906
- const isBulkPublish = action === "bulk-publish";
907
- const localesForAction = selectedRows.reduce((acc, selectedRow) => {
908
- const isValidLocale = (
909
- // Validation errors are irrelevant if we are trying to unpublish
910
- !isBulkPublish || !Object.keys(validationErrors).includes(selectedRow.locale)
911
- );
912
- const shouldAddLocale = isBulkPublish ? selectedRow.status !== "published" && isValidLocale : selectedRow.status !== "draft" && isValidLocale;
913
- if (shouldAddLocale) {
914
- acc.push(selectedRow.locale);
915
- }
916
- return acc;
917
- }, []);
918
- const enableDraftRelationsCount = false;
919
- const {
920
- data: draftRelationsCount = 0,
921
- isLoading: isDraftRelationsLoading,
922
- error: isDraftRelationsError
923
- } = useGetManyDraftRelationCountQuery(
924
- {
925
- model,
926
- documentIds: [documentId],
927
- locale: localesForAction
928
- },
929
- {
930
- skip: !enableDraftRelationsCount
931
- }
932
- );
933
- React__namespace.useEffect(() => {
934
- if (isDraftRelationsError) {
935
- toggleNotification({
936
- type: "danger",
937
- message: formatAPIError(isDraftRelationsError)
938
- });
939
- }
940
- }, [isDraftRelationsError, toggleNotification, formatAPIError]);
941
- if (!schema?.options?.draftAndPublish) {
942
- return null;
943
- }
944
- if (!hasI18n) {
945
- return null;
946
- }
947
- if (!documentId) {
948
- return null;
949
- }
950
- const publish = async () => {
951
- await publishManyAction({
952
- model,
953
- documentIds: [documentId],
954
- params: {
955
- ...params,
956
- locale: localesForAction
957
- }
958
- });
959
- setSelectedRows([]);
960
- };
961
- const unpublish = async () => {
962
- await unpublishManyAction({
963
- model,
964
- documentIds: [documentId],
965
- params: {
966
- ...params,
967
- locale: localesForAction
968
- }
969
- });
970
- setSelectedRows([]);
971
- };
972
- const handleAction = async () => {
973
- if (draftRelationsCount > 0) {
974
- setIsDraftRelationConfirmationOpen(true);
975
- } else if (isBulkPublish) {
976
- await publish();
977
- } else {
978
- await unpublish();
979
- }
980
- };
981
- if (isDraftRelationConfirmationOpen) {
982
- return {
983
- label: formatMessage({
984
- id: "app.components.ConfirmDialog.title",
985
- defaultMessage: "Confirmation"
986
- }),
987
- variant: "danger",
988
- dialog: {
989
- onCancel: () => {
990
- setIsDraftRelationConfirmationOpen(false);
991
- },
992
- onConfirm: async () => {
993
- await publish();
994
- setIsDraftRelationConfirmationOpen(false);
995
- },
996
- type: "dialog",
997
- title: formatMessage({
998
- id: getTranslation("actions.publish.dialog.title"),
999
- defaultMessage: "Confirmation"
1000
- }),
1001
- content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "center", gap: 2, children: [
1002
- /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, { width: "2.4rem", height: "2.4rem", fill: "danger600" }),
1003
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", children: formatMessage({
1004
- id: getTranslation("CMEditViewBulkLocale.draft-relation-warning"),
1005
- defaultMessage: "Some locales are related to draft entries. Publishing them could leave broken links in your app."
1006
- }) }),
1007
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", children: formatMessage({
1008
- id: getTranslation("CMEditViewBulkLocale.continue-confirmation"),
1009
- defaultMessage: "Are you sure you want to continue?"
1010
- }) })
1011
- ] })
1012
- }
1013
- };
1014
- }
1015
- const hasPermission = selectedRows.map(({ locale }) => locale).every((locale) => canPublish.includes(locale));
1016
- return {
1017
- label: formatMessage({
1018
- id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
1019
- defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
1020
- }),
1021
- variant: isBulkPublish ? "secondary" : "danger",
1022
- icon: isBulkPublish ? /* @__PURE__ */ jsxRuntime.jsx(icons.ListPlus, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.Cross, {}),
1023
- disabled: isOnPublishedTab || canPublish.length === 0,
1024
- position: ["panel"],
1025
- dialog: {
1026
- type: "modal",
1027
- title: formatMessage({
1028
- id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
1029
- defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
1030
- }),
1031
- content: () => {
1032
- return /* @__PURE__ */ jsxRuntime.jsx(
1033
- strapiAdmin.Table.Root,
1034
- {
1035
- headers,
1036
- rows: rows.map((row) => ({
1037
- ...row,
1038
- id: row.locale
1039
- })),
1040
- selectedRows,
1041
- onSelectedRowsChange: (tableSelectedRows) => setSelectedRows(tableSelectedRows),
1042
- children: /* @__PURE__ */ jsxRuntime.jsx(
1043
- BulkLocaleActionModal,
1044
- {
1045
- validationErrors,
1046
- headers,
1047
- rows,
1048
- localesMetadata,
1049
- action: action ?? "bulk-publish"
1050
- }
1051
- )
1052
- }
1053
- );
1054
- },
1055
- footer: () => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Footer, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxRuntime.jsx(
1056
- designSystem.Button,
1057
- {
1058
- loading: isDraftRelationsLoading,
1059
- disabled: !hasPermission || localesForAction.length === 0,
1060
- variant: "default",
1061
- onClick: handleAction,
1062
- children: formatMessage({
1063
- id: isBulkPublish ? "app.utils.publish" : "app.utils.unpublish",
1064
- defaultMessage: isBulkPublish ? "Publish" : "Unpublish"
1065
- })
1066
- }
1067
- ) })
1068
- }
1069
- };
1070
- };
1071
- const BulkLocalePublishAction = (props) => {
1072
- return BulkLocaleAction({ action: "bulk-publish", ...props });
1073
- };
1074
- const BulkLocaleUnpublishAction = (props) => {
1075
- return BulkLocaleAction({ action: "bulk-unpublish", ...props });
1076
- };
1077
- const StyledTrash = styledComponents.styled(icons.Trash)`
1078
- path {
1079
- fill: currentColor;
1080
- }
1081
- `;
1082
- const Emphasis = (chunks) => {
1083
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", textColor: "danger500", children: chunks });
1084
- };
1085
- const DeleteModalAdditionalInfo = () => {
1086
- const { hasI18n } = useI18n();
1087
- const { formatMessage } = reactIntl.useIntl();
1088
- if (!hasI18n) {
1089
- return null;
1090
- }
1091
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", children: formatMessage(
1092
- {
1093
- id: getTranslation("Settings.list.actions.deleteAdditionalInfos"),
1094
- defaultMessage: "This will delete the active locale versions <em>(from Internationalization)</em>"
1095
- },
1096
- {
1097
- em: Emphasis
1098
- }
1099
- ) });
1100
- };
1101
- const PublishModalAdditionalInfo = () => {
1102
- const { hasI18n } = useI18n();
1103
- const { formatMessage } = reactIntl.useIntl();
1104
- if (!hasI18n) {
1105
- return null;
1106
- }
1107
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", children: formatMessage(
1108
- {
1109
- id: getTranslation("Settings.list.actions.publishAdditionalInfos"),
1110
- defaultMessage: "This will publish the active locale versions <em>(from Internationalization)</em>"
1111
- },
1112
- {
1113
- em: Emphasis
1114
- }
1115
- ) });
1116
- };
1117
- const UnpublishModalAdditionalInfo = () => {
1118
- const { hasI18n } = useI18n();
1119
- const { formatMessage } = reactIntl.useIntl();
1120
- if (!hasI18n) {
1121
- return null;
1122
- }
1123
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", children: formatMessage(
1124
- {
1125
- id: getTranslation("Settings.list.actions.unpublishAdditionalInfos"),
1126
- defaultMessage: "This will unpublish the active locale versions <em>(from Internationalization)</em>"
1127
- },
1128
- {
1129
- em: Emphasis
1130
- }
1131
- ) });
1132
- };
1133
- const LocalePicker = () => {
1134
- const { formatMessage } = reactIntl.useIntl();
1135
- const [{ query: query2 }, setQuery] = strapiAdmin.useQueryParams();
1136
- const { hasI18n, canRead, canCreate } = useI18n();
1137
- const { data: locales = [] } = useGetLocalesQuery(void 0, {
1138
- skip: !hasI18n
1139
- });
1140
- const handleChange = React__namespace.useCallback(
1141
- (code, replace = false) => {
1142
- setQuery(
1143
- {
1144
- page: 1,
1145
- plugins: { ...query2.plugins, i18n: { locale: code } }
1146
- },
1147
- "push",
1148
- replace
1149
- );
1150
- },
1151
- [query2.plugins, setQuery]
1152
- );
1153
- React__namespace.useEffect(() => {
1154
- if (!Array.isArray(locales) || !hasI18n) {
1155
- return;
1156
- }
1157
- const currentDesiredLocale = query2.plugins?.i18n?.locale;
1158
- const doesLocaleExist = locales.find((loc) => loc.code === currentDesiredLocale);
1159
- const defaultLocale = locales.find((locale) => locale.isDefault);
1160
- if (!doesLocaleExist && defaultLocale?.code) {
1161
- handleChange(defaultLocale.code, true);
1162
- }
1163
- }, [hasI18n, handleChange, locales, query2.plugins?.i18n?.locale]);
1164
- if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
1165
- return null;
1166
- }
1167
- const displayedLocales = locales.filter((locale) => {
1168
- return canCreate.includes(locale.code) || canRead.includes(locale.code);
1169
- });
1170
- return /* @__PURE__ */ jsxRuntime.jsx(
1171
- designSystem.SingleSelect,
1172
- {
1173
- size: "S",
1174
- "aria-label": formatMessage({
1175
- id: getTranslation("actions.select-locale"),
1176
- defaultMessage: "Select locale"
1177
- }),
1178
- value: query2.plugins?.i18n?.locale || locales.find((locale) => locale.isDefault)?.code,
1179
- onChange: handleChange,
1180
- children: displayedLocales.map((locale) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: locale.code, children: locale.name }, locale.id))
1181
- }
1182
- );
1183
- };
1184
- const PERMISSIONS = {
1185
- accessMain: [{ action: "plugin::i18n.locale.read", subject: null }],
1186
- create: [{ action: "plugin::i18n.locale.create", subject: null }],
1187
- delete: [{ action: "plugin::i18n.locale.delete", subject: null }],
1188
- update: [{ action: "plugin::i18n.locale.update", subject: null }],
1189
- read: [{ action: "plugin::i18n.locale.read", subject: null }]
1190
- };
1191
- const mutateEditViewHook = ({ layout }) => {
1192
- if (!("i18n" in layout.options) || typeof layout.options.i18n === "object" && layout.options.i18n !== null && "localized" in layout.options.i18n && !layout.options.i18n.localized) {
1193
- return { layout };
1194
- }
1195
- const components = Object.entries(layout.components).reduce(
1196
- (acc, [key, componentLayout]) => {
1197
- return {
1198
- ...acc,
1199
- [key]: {
1200
- ...componentLayout,
1201
- layout: componentLayout.layout.map((row) => row.map(addLabelActionToField))
1202
- }
1203
- };
1204
- },
1205
- {}
1206
- );
1207
- return {
1208
- layout: {
1209
- ...layout,
1210
- components,
1211
- layout: layout.layout.map((panel) => panel.map((row) => row.map(addLabelActionToField)))
1212
- }
1213
- };
1214
- };
1215
- const addLabelActionToField = (field) => {
1216
- const isFieldLocalized = doesFieldHaveI18nPluginOpt(field.attribute.pluginOptions) ? field.attribute.pluginOptions.i18n.localized : true;
1217
- const labelActionProps = {
1218
- title: {
1219
- id: isFieldLocalized ? getTranslation("Field.localized") : getTranslation("Field.not-localized"),
1220
- defaultMessage: isFieldLocalized ? "This value is unique for the selected locale" : "This value is the same across all locales"
1221
- },
1222
- icon: isFieldLocalized ? /* @__PURE__ */ jsxRuntime.jsx(icons.Earth, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.EarthStriked, {})
1223
- };
1224
- return {
1225
- ...field,
1226
- labelAction: /* @__PURE__ */ jsxRuntime.jsx(LabelAction, { ...labelActionProps })
1227
- };
1228
- };
1229
- const doesFieldHaveI18nPluginOpt = (pluginOpts) => {
1230
- if (!pluginOpts) {
1231
- return false;
1232
- }
1233
- return "i18n" in pluginOpts && typeof pluginOpts.i18n === "object" && pluginOpts.i18n !== null && "localized" in pluginOpts.i18n;
1234
- };
1235
- const LabelAction = ({ title, icon }) => {
1236
- const { formatMessage } = reactIntl.useIntl();
1237
- return /* @__PURE__ */ jsxRuntime.jsxs(Span, { tag: "span", children: [
1238
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { tag: "span", children: formatMessage(title) }),
1239
- React__namespace.cloneElement(icon, {
1240
- "aria-hidden": true,
1241
- focusable: false
1242
- // See: https://allyjs.io/tutorials/focusing-in-svg.html#making-svg-elements-focusable
1243
- })
1244
- ] });
1245
- };
1246
- const Span = styledComponents.styled(designSystem.Flex)`
1247
- svg {
1248
- width: 12px;
1249
- height: 12px;
1250
-
1251
- fill: ${({ theme }) => theme.colors.neutral500};
1252
-
1253
- path {
1254
- fill: ${({ theme }) => theme.colors.neutral500};
1255
- }
1256
- }
1257
- `;
1258
- const LocaleListCell = ({
1259
- documentId,
1260
- locale: currentLocale,
1261
- collectionType,
1262
- model
1263
- }) => {
1264
- const { meta, isLoading } = strapiAdmin$1.unstable_useDocument({
1265
- documentId,
1266
- collectionType,
1267
- model,
1268
- params: {
1269
- locale: currentLocale
1270
- }
1271
- });
1272
- const { locale: language } = reactIntl.useIntl();
1273
- const { data: locales = [] } = useGetLocalesQuery();
1274
- const formatter = designSystem.useCollator(language, {
1275
- sensitivity: "base"
1276
- });
1277
- if (!Array.isArray(locales) || isLoading) {
1278
- return null;
1279
- }
1280
- const availableLocales = meta?.availableLocales.map((doc) => doc.locale) ?? [];
1281
- const localesForDocument = locales.reduce((acc, locale) => {
1282
- const createdLocale = [currentLocale, ...availableLocales].find((loc) => {
1283
- return loc === locale.code;
1284
- });
1285
- if (createdLocale) {
1286
- acc.push(locale);
1287
- }
1288
- return acc;
1289
- }, []).map((locale) => {
1290
- if (locale.isDefault) {
1291
- return `${locale.name} (default)`;
1292
- }
1293
- return locale.name;
1294
- }).toSorted((a, b) => formatter.compare(a, b));
1295
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Popover.Root, { children: [
1296
- /* @__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: [
1297
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", ellipsis: true, marginRight: 2, children: localesForDocument.join(", ") }),
1298
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(icons.CaretDown, { width: "1.2rem", height: "1.2rem" }) })
1299
- ] }) }) }),
1300
- /* @__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)) }) })
1301
- ] });
1302
- };
1303
- const addColumnToTableHook = ({ displayedHeaders, layout }) => {
1304
- const { options } = layout;
1305
- const isFieldLocalized = doesPluginOptionsHaveI18nLocalized(options) ? options.i18n.localized : false;
1306
- if (!isFieldLocalized) {
1307
- return { displayedHeaders, layout };
1308
- }
1309
- return {
1310
- displayedHeaders: [
1311
- ...displayedHeaders,
1312
- {
1313
- attribute: { type: "string" },
1314
- label: {
1315
- id: getTranslation("list-view.table.header.label"),
1316
- defaultMessage: "Available in"
1317
- },
1318
- searchable: false,
1319
- sortable: false,
1320
- name: "locales",
1321
- // @ts-expect-error – ID is seen as number | string; this will change when we move the type over.
1322
- cellFormatter: (props, _header, meta) => /* @__PURE__ */ jsxRuntime.jsx(LocaleListCell, { ...props, ...meta })
1323
- }
1324
- ],
1325
- layout
1326
- };
1327
- };
1328
- const addLocaleToReleasesHook = ({ displayedHeaders = [] }) => {
1329
- return {
1330
- displayedHeaders: [
1331
- ...displayedHeaders,
1332
- {
1333
- label: {
1334
- id: "content-releases.page.ReleaseDetails.table.header.label.locale",
1335
- defaultMessage: "locale"
1336
- },
1337
- name: "locale"
1338
- }
1339
- ],
1340
- hasI18nEnabled: true
1341
- };
1342
- };
1343
- const extendCTBAttributeInitialDataMiddleware = () => {
1344
- return ({ getState }) => (next) => (action) => {
1345
- const enhanceAction = () => {
1346
- try {
1347
- const store = getState();
1348
- const hasi18nEnabled = get__default.default(
1349
- store,
1350
- [
1351
- "content-type-builder_dataManagerProvider",
1352
- "modifiedData",
1353
- "contentType",
1354
- "schema",
1355
- "pluginOptions",
1356
- "i18n",
1357
- "localized"
1358
- ],
1359
- false
1360
- );
1361
- if (hasi18nEnabled) {
1362
- const pluginOptions = action.options ? { ...action.options.pluginOptions, i18n: { localized: true } } : { i18n: { localized: true } };
1363
- return next({
1364
- ...action,
1365
- options: {
1366
- pluginOptions
1367
- }
1368
- });
1369
- }
1370
- return next(action);
1371
- } catch (err) {
1372
- return next(action);
1373
- }
1374
- };
1375
- if (action.type === "ContentTypeBuilder/FormModal/SET_ATTRIBUTE_DATA_SCHEMA" && action.forTarget === "contentType" && !["relation", "component"].includes(action.attributeType) && !action.isEditing) {
1376
- return enhanceAction();
1377
- }
1378
- if (action.type === "ContentTypeBuilder/FormModal/SET_CUSTOM_FIELD_DATA_SCHEMA" && action.forTarget === "contentType" && !action.isEditing) {
1379
- return enhanceAction();
1380
- }
1381
- if ((action.type === "ContentTypeBuilder/FormModal/RESET_PROPS_AND_SET_FORM_FOR_ADDING_AN_EXISTING_COMPO" || action.type === "ContentTypeBuilder/FormModal/RESET_PROPS_AND_SAVE_CURRENT_DATA") && action.forTarget === "contentType") {
1382
- return enhanceAction();
1383
- }
1384
- return next(action);
1385
- };
1386
- };
1387
- const extendCTBInitialDataMiddleware = () => {
1388
- return () => (next) => (action) => {
1389
- if (action.type === "ContentTypeBuilder/FormModal/SET_DATA_TO_EDIT" && action.modalType === "contentType") {
1390
- const i18n = { localized: false };
1391
- const pluginOptions = action.data.pluginOptions ? { ...action.data.pluginOptions, i18n } : { i18n };
1392
- const data = { ...action.data, pluginOptions };
1393
- if (action.actionType === "create") {
1394
- return next({ ...action, data });
1395
- }
1396
- if (!action.data.pluginOptions?.i18n?.localized) {
1397
- return next({ ...action, data });
1398
- }
1399
- }
1400
- return next(action);
1401
- };
1402
- };
1403
- const localeMiddleware = (ctx) => (next) => (permissions) => {
1404
- const match = reactRouterDom.matchPath("/content-manager/:collectionType/:model?/:id", ctx.pathname);
1405
- if (!match) {
1406
- return next(permissions);
1407
- }
1408
- const search = qs__namespace.parse(ctx.search);
1409
- if (typeof search !== "object") {
1410
- return next(permissions);
1411
- }
1412
- if (!("plugins" in search && typeof search.plugins === "object")) {
1413
- return next(permissions);
1414
- }
1415
- if (!("i18n" in search.plugins && typeof search.plugins.i18n === "object" && !Array.isArray(search.plugins.i18n))) {
1416
- return next(permissions);
1417
- }
1418
- const { locale } = search.plugins.i18n;
1419
- if (typeof locale !== "string") {
1420
- return next(permissions);
1421
- }
1422
- const revisedPermissions = permissions.filter(
1423
- (permission) => !permission.properties?.locales || permission.properties.locales.includes(locale)
1424
- );
1425
- return next(revisedPermissions);
1426
- };
1427
- const prefixPluginTranslations = (trad, pluginId2) => {
1428
- return Object.keys(trad).reduce((acc, current) => {
1429
- acc[`${pluginId2}.${current}`] = trad[current];
1430
- return acc;
1431
- }, {});
1432
- };
1433
- const mutateCTBContentTypeSchema = (nextSchema, prevSchema) => {
1434
- if (!doesPluginOptionsHaveI18nLocalized(nextSchema.pluginOptions)) {
1435
- return nextSchema;
1436
- }
1437
- const isNextSchemaLocalized = nextSchema.pluginOptions.i18n.localized;
1438
- const isPrevSchemaLocalized = doesPluginOptionsHaveI18nLocalized(
1439
- prevSchema?.schema?.pluginOptions
1440
- ) ? prevSchema?.schema?.pluginOptions.i18n.localized : false;
1441
- if (isNextSchemaLocalized && isPrevSchemaLocalized) {
1442
- return nextSchema;
1443
- }
1444
- if (isNextSchemaLocalized) {
1445
- const attributes = addLocalisationToFields(nextSchema.attributes);
1446
- return { ...nextSchema, attributes };
1447
- }
1448
- if (!isNextSchemaLocalized) {
1449
- const pluginOptions = omit__default.default(nextSchema.pluginOptions, "i18n");
1450
- const attributes = disableAttributesLocalisation(nextSchema.attributes);
1451
- return { ...nextSchema, pluginOptions, attributes };
1452
- }
1453
- return nextSchema;
1454
- };
1455
- const addLocalisationToFields = (attributes) => Object.keys(attributes).reduce((acc, current) => {
1456
- const currentAttribute = attributes[current];
1457
- if (LOCALIZED_FIELDS.includes(currentAttribute.type)) {
1458
- const i18n = { localized: true };
1459
- const pluginOptions = currentAttribute.pluginOptions ? { ...currentAttribute.pluginOptions, i18n } : { i18n };
1460
- acc[current] = { ...currentAttribute, pluginOptions };
1461
- return acc;
1462
- }
1463
- acc[current] = currentAttribute;
1464
- return acc;
1465
- }, {});
1466
- const disableAttributesLocalisation = (attributes) => Object.keys(attributes).reduce((acc, current) => {
1467
- acc[current] = omit__default.default(attributes[current], "pluginOptions.i18n");
1468
- return acc;
1469
- }, {});
1470
- const index = {
1471
- register(app) {
1472
- app.addMiddlewares([extendCTBAttributeInitialDataMiddleware, extendCTBInitialDataMiddleware]);
1473
- app.addMiddlewares([() => i18nApi.middleware]);
1474
- app.addReducers({
1475
- [i18nApi.reducerPath]: i18nApi.reducer
1476
- });
1477
- app.addRBACMiddleware([localeMiddleware]);
1478
- app.registerPlugin({
1479
- id: pluginId,
1480
- name: pluginId
1481
- });
1482
- },
1483
- bootstrap(app) {
1484
- app.registerHook("Admin/CM/pages/ListView/inject-column-in-table", addColumnToTableHook);
1485
- app.registerHook("Admin/CM/pages/EditView/mutate-edit-view-layout", mutateEditViewHook);
1486
- app.registerHook(
1487
- "ContentReleases/pages/ReleaseDetails/add-locale-in-releases",
1488
- addLocaleToReleasesHook
1489
- );
1490
- app.addSettingsLink("global", {
1491
- intlLabel: {
1492
- id: getTranslation("plugin.name"),
1493
- defaultMessage: "Internationalization"
1494
- },
1495
- id: "internationalization",
1496
- to: "internationalization",
1497
- Component: () => Promise.resolve().then(() => require("./SettingsPage-DqW7hbxl.js")).then((mod) => ({ default: mod.ProtectedSettingsPage })),
1498
- permissions: PERMISSIONS.accessMain
1499
- });
1500
- const contentManager = app.getPlugin("content-manager");
1501
- contentManager.apis.addDocumentHeaderAction([LocalePickerAction, FillFromAnotherLocaleAction]);
1502
- contentManager.apis.addDocumentAction((actions) => {
1503
- const indexOfDeleteAction = actions.findIndex((action) => action.type === "delete");
1504
- actions.splice(indexOfDeleteAction, 0, DeleteLocaleAction);
1505
- return actions;
1506
- });
1507
- contentManager.apis.addDocumentAction((actions) => {
1508
- actions.splice(2, 0, BulkLocalePublishAction);
1509
- actions.splice(5, 0, BulkLocaleUnpublishAction);
1510
- return actions;
1511
- });
1512
- contentManager.injectComponent("listView", "actions", {
1513
- name: "i18n-locale-filter",
1514
- Component: LocalePicker
1515
- });
1516
- contentManager.injectComponent("listView", "publishModalAdditionalInfos", {
1517
- name: "i18n-publish-bullets-in-modal",
1518
- Component: PublishModalAdditionalInfo
1519
- });
1520
- contentManager.injectComponent("listView", "unpublishModalAdditionalInfos", {
1521
- name: "i18n-unpublish-bullets-in-modal",
1522
- Component: UnpublishModalAdditionalInfo
1523
- });
1524
- contentManager.injectComponent("listView", "deleteModalAdditionalInfos", {
1525
- name: "i18n-delete-bullets-in-modal",
1526
- Component: DeleteModalAdditionalInfo
1527
- });
1528
- const ctbPlugin = app.getPlugin("content-type-builder");
1529
- if (ctbPlugin) {
1530
- const ctbFormsAPI = ctbPlugin.apis.forms;
1531
- ctbFormsAPI.addContentTypeSchemaMutation(mutateCTBContentTypeSchema);
1532
- ctbFormsAPI.components.add({ id: "checkboxConfirmation", component: CheckboxConfirmation });
1533
- ctbFormsAPI.extendContentType({
1534
- validator: () => ({
1535
- i18n: yup__namespace.object().shape({
1536
- localized: yup__namespace.bool()
1537
- })
1538
- }),
1539
- form: {
1540
- advanced() {
1541
- return [
1542
- {
1543
- name: "pluginOptions.i18n.localized",
1544
- description: {
1545
- id: getTranslation("plugin.schema.i18n.localized.description-content-type"),
1546
- defaultMessage: "Allows translating an entry into different languages"
1547
- },
1548
- type: "checkboxConfirmation",
1549
- intlLabel: {
1550
- id: getTranslation("plugin.schema.i18n.localized.label-content-type"),
1551
- defaultMessage: "Localization"
1552
- }
1553
- }
1554
- ];
1555
- }
1556
- }
1557
- });
1558
- ctbFormsAPI.extendFields(LOCALIZED_FIELDS, {
1559
- validator: (args) => ({
1560
- i18n: yup__namespace.object().shape({
1561
- localized: yup__namespace.bool().test({
1562
- name: "ensure-unique-localization",
1563
- message: getTranslation("plugin.schema.i18n.ensure-unique-localization"),
1564
- test(value) {
1565
- if (value === void 0 || value) {
1566
- return true;
1567
- }
1568
- const unique = get__default.default(args, ["3", "modifiedData", "unique"], null);
1569
- if (unique && !value) {
1570
- return false;
1571
- }
1572
- return true;
1573
- }
1574
- })
1575
- })
1576
- }),
1577
- form: {
1578
- advanced({ contentTypeSchema, forTarget, type, step }) {
1579
- if (forTarget !== "contentType") {
1580
- return [];
1581
- }
1582
- const hasI18nEnabled = get__default.default(
1583
- contentTypeSchema,
1584
- ["schema", "pluginOptions", "i18n", "localized"],
1585
- false
1586
- );
1587
- if (!hasI18nEnabled) {
1588
- return [];
1589
- }
1590
- if (type === "component" && step === "1") {
1591
- return [];
1592
- }
1593
- return [
1594
- {
1595
- name: "pluginOptions.i18n.localized",
1596
- description: {
1597
- id: getTranslation("plugin.schema.i18n.localized.description-field"),
1598
- defaultMessage: "The field can have different values in each locale"
1599
- },
1600
- type: "checkbox",
1601
- intlLabel: {
1602
- id: getTranslation("plugin.schema.i18n.localized.label-field"),
1603
- defaultMessage: "Enable localization for this field"
1604
- }
1605
- }
1606
- ];
1607
- }
1608
- }
1609
- });
1610
- }
1611
- },
1612
- async registerTrads({ locales }) {
1613
- const importedTrads = await Promise.all(
1614
- locales.map((locale) => {
1615
- 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-BKBz3tro.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`, 3).then(({ default: data }) => {
1616
- return {
1617
- data: prefixPluginTranslations(data, pluginId),
1618
- locale
1619
- };
1620
- }).catch(() => {
1621
- return {
1622
- data: {},
1623
- locale
1624
- };
1625
- });
1626
- })
1627
- );
1628
- return Promise.resolve(importedTrads);
1629
- }
1630
- };
1631
- exports.PERMISSIONS = PERMISSIONS;
1632
- exports.getTranslation = getTranslation;
1633
- exports.index = index;
1634
- exports.useCreateLocaleMutation = useCreateLocaleMutation;
1635
- exports.useDeleteLocaleMutation = useDeleteLocaleMutation;
1636
- exports.useGetDefaultLocalesQuery = useGetDefaultLocalesQuery;
1637
- exports.useGetLocalesQuery = useGetLocalesQuery;
1638
- exports.useUpdateLocaleMutation = useUpdateLocaleMutation;
1639
- //# sourceMappingURL=index-93hDLj9o.js.map