@strapi/i18n 0.0.0-experimental.826f263c58b6886b849d3f03b81f7a530bc51c91 → 0.0.0-experimental.82afe56cecefd0078d534e25909834ecf5fdd404
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.
- package/LICENSE +18 -3
- package/dist/_chunks/{SettingsPage-0FFSTUW2.mjs → SettingsPage-B-KzAqT3.mjs} +95 -108
- package/dist/_chunks/SettingsPage-B-KzAqT3.mjs.map +1 -0
- package/dist/_chunks/{SettingsPage-DnLLGeBa.js → SettingsPage-hyOi94O9.js} +94 -108
- package/dist/_chunks/SettingsPage-hyOi94O9.js.map +1 -0
- package/dist/_chunks/{de-DtWiGdHl.js → de-BOhNX_-5.js} +1 -2
- package/dist/_chunks/de-BOhNX_-5.js.map +1 -0
- package/dist/_chunks/{de-9eCAqqrB.mjs → de-D80IRBP9.mjs} +1 -2
- package/dist/_chunks/de-D80IRBP9.mjs.map +1 -0
- package/dist/_chunks/{dk-2qBjxt-P.mjs → dk-CJ6Zzz78.mjs} +1 -2
- package/dist/_chunks/dk-CJ6Zzz78.mjs.map +1 -0
- package/dist/_chunks/{dk-D8C-casx.js → dk-cjXm0p3m.js} +1 -2
- package/dist/_chunks/dk-cjXm0p3m.js.map +1 -0
- package/dist/_chunks/{en-18tWw4P6.mjs → en-BTyF7WVW.mjs} +12 -4
- package/dist/_chunks/en-BTyF7WVW.mjs.map +1 -0
- package/dist/_chunks/{en-Kv6y9zPQ.js → en-UlC0jh2t.js} +12 -4
- package/dist/_chunks/en-UlC0jh2t.js.map +1 -0
- package/dist/_chunks/{es-DlmMVaBG.mjs → es-V8WnPN7w.mjs} +1 -2
- package/dist/_chunks/es-V8WnPN7w.mjs.map +1 -0
- package/dist/_chunks/{es-DS-XFGSw.js → es-hr9b_HLp.js} +1 -2
- package/dist/_chunks/es-hr9b_HLp.js.map +1 -0
- package/dist/_chunks/{fr-BTjekDpq.js → fr-BFmBbE0H.js} +1 -2
- package/dist/_chunks/fr-BFmBbE0H.js.map +1 -0
- package/dist/_chunks/{fr-3S6ke71d.mjs → fr-F94noFiV.mjs} +1 -2
- package/dist/_chunks/fr-F94noFiV.mjs.map +1 -0
- package/dist/_chunks/{index-BddUXwss.mjs → index-BcYj5jo9.mjs} +476 -275
- package/dist/_chunks/index-BcYj5jo9.mjs.map +1 -0
- package/dist/_chunks/{index-DtEKsPcR.js → index-C8NzsAKp.js} +483 -283
- package/dist/_chunks/index-C8NzsAKp.js.map +1 -0
- package/dist/_chunks/{ko-DmcGUBQ3.js → ko-C40pNQ9b.js} +1 -2
- package/dist/_chunks/ko-C40pNQ9b.js.map +1 -0
- package/dist/_chunks/{ko-qTjQ8IMw.mjs → ko-CF-P3Car.mjs} +1 -2
- package/dist/_chunks/ko-CF-P3Car.mjs.map +1 -0
- package/dist/_chunks/{pl-B67TSHqT.mjs → pl-Dxr9RUmD.mjs} +1 -2
- package/dist/_chunks/pl-Dxr9RUmD.mjs.map +1 -0
- package/dist/_chunks/{pl-Cn5RYonZ.js → pl-JtWBy-JQ.js} +1 -2
- package/dist/_chunks/pl-JtWBy-JQ.js.map +1 -0
- package/dist/_chunks/{ru-hagMa57T.mjs → ru-B-4sVwXN.mjs} +1 -2
- package/dist/_chunks/ru-B-4sVwXN.mjs.map +1 -0
- package/dist/_chunks/{ru-BMBgVL3s.js → ru-COSWt3Nu.js} +1 -2
- package/dist/_chunks/ru-COSWt3Nu.js.map +1 -0
- package/dist/_chunks/{tr-CarUU76c.js → tr-BVj1O5ch.js} +1 -2
- package/dist/_chunks/tr-BVj1O5ch.js.map +1 -0
- package/dist/_chunks/{tr-Dw_jmkG-.mjs → tr-Ccu6Yj11.mjs} +1 -2
- package/dist/_chunks/tr-Ccu6Yj11.mjs.map +1 -0
- package/dist/_chunks/{zh-57YM4amO.mjs → zh-BIz395Ms.mjs} +1 -2
- package/dist/_chunks/zh-BIz395Ms.mjs.map +1 -0
- package/dist/_chunks/{zh-Hans-Dyc-aR-h.mjs → zh-Hans-Bfo6_TCM.mjs} +1 -2
- package/dist/_chunks/zh-Hans-Bfo6_TCM.mjs.map +1 -0
- package/dist/_chunks/{zh-Hans-DSHIXAa3.js → zh-Hans-DIEm_EMC.js} +1 -2
- package/dist/_chunks/zh-Hans-DIEm_EMC.js.map +1 -0
- package/dist/_chunks/{zh-CukOviB0.js → zh-wkBPBkhc.js} +1 -2
- package/dist/_chunks/zh-wkBPBkhc.js.map +1 -0
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/admin/src/components/BulkLocaleActionModal.d.ts +2 -1
- package/dist/admin/src/components/CMHeaderActions.d.ts +29 -3
- package/dist/admin/src/components/CreateLocale.d.ts +6 -6
- package/dist/admin/src/components/EditLocale.d.ts +5 -4
- package/dist/admin/src/components/LocaleListCell.d.ts +4 -4
- package/dist/admin/src/contentReleasesHooks/releaseDetailsView.d.ts +9 -5
- package/dist/admin/src/utils/clean.d.ts +4 -0
- package/dist/admin/src/utils/schemas.d.ts +1 -0
- package/dist/server/index.js +418 -478
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +419 -478
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/bootstrap.d.ts +1 -4
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +21 -13
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +20 -10
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/permissions/actions.d.ts +14 -2
- package/dist/server/src/services/permissions/actions.d.ts.map +1 -1
- package/dist/server/src/services/permissions.d.ts +14 -2
- package/dist/server/src/services/permissions.d.ts.map +1 -1
- package/dist/server/src/services/sanitize/index.d.ts +11 -0
- package/dist/server/src/services/sanitize/index.d.ts.map +1 -0
- package/dist/server/src/utils/index.d.ts +2 -2
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/package.json +13 -14
- package/dist/_chunks/SettingsPage-0FFSTUW2.mjs.map +0 -1
- package/dist/_chunks/SettingsPage-DnLLGeBa.js.map +0 -1
- package/dist/_chunks/de-9eCAqqrB.mjs.map +0 -1
- package/dist/_chunks/de-DtWiGdHl.js.map +0 -1
- package/dist/_chunks/dk-2qBjxt-P.mjs.map +0 -1
- package/dist/_chunks/dk-D8C-casx.js.map +0 -1
- package/dist/_chunks/en-18tWw4P6.mjs.map +0 -1
- package/dist/_chunks/en-Kv6y9zPQ.js.map +0 -1
- package/dist/_chunks/es-DS-XFGSw.js.map +0 -1
- package/dist/_chunks/es-DlmMVaBG.mjs.map +0 -1
- package/dist/_chunks/fr-3S6ke71d.mjs.map +0 -1
- package/dist/_chunks/fr-BTjekDpq.js.map +0 -1
- package/dist/_chunks/index-BddUXwss.mjs.map +0 -1
- package/dist/_chunks/index-DtEKsPcR.js.map +0 -1
- package/dist/_chunks/ko-DmcGUBQ3.js.map +0 -1
- package/dist/_chunks/ko-qTjQ8IMw.mjs.map +0 -1
- package/dist/_chunks/pl-B67TSHqT.mjs.map +0 -1
- package/dist/_chunks/pl-Cn5RYonZ.js.map +0 -1
- package/dist/_chunks/ru-BMBgVL3s.js.map +0 -1
- package/dist/_chunks/ru-hagMa57T.mjs.map +0 -1
- package/dist/_chunks/tr-CarUU76c.js.map +0 -1
- package/dist/_chunks/tr-Dw_jmkG-.mjs.map +0 -1
- package/dist/_chunks/zh-57YM4amO.mjs.map +0 -1
- package/dist/_chunks/zh-CukOviB0.js.map +0 -1
- package/dist/_chunks/zh-Hans-DSHIXAa3.js.map +0 -1
- package/dist/_chunks/zh-Hans-Dyc-aR-h.mjs.map +0 -1
- package/dist/admin/src/components/Initializer.d.ts +0 -5
- package/dist/server/src/migrations/content-type/disable/index.d.ts +0 -3
- package/dist/server/src/migrations/content-type/disable/index.d.ts.map +0 -1
- package/dist/server/src/migrations/content-type/enable/index.d.ts +0 -3
- package/dist/server/src/migrations/content-type/enable/index.d.ts.map +0 -1
- package/dist/server/src/services/entity-service-decorator.d.ts +0 -29
- package/dist/server/src/services/entity-service-decorator.d.ts.map +0 -1
- package/strapi-server.js +0 -3
@@ -1,24 +1,32 @@
|
|
1
1
|
import get from "lodash/get";
|
2
2
|
import * as yup from "yup";
|
3
|
-
import { jsxs,
|
3
|
+
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
4
4
|
import * as React from "react";
|
5
|
-
import { Typography, Field, Checkbox,
|
6
|
-
import { WarningCircle, Pencil, CrossCircle, CheckCircle, ArrowsCounterClockwise, Trash, ListPlus, Earth, EarthStriked, CaretDown } from "@strapi/icons";
|
5
|
+
import { Typography, Dialog, Field, Checkbox, Flex, Button, Modal, Box, Status, IconButton, Tooltip, SingleSelect, SingleSelectOption, VisuallyHidden, useCollator, Popover } from "@strapi/design-system";
|
6
|
+
import { WarningCircle, Pencil, CrossCircle, CheckCircle, ArrowsCounterClockwise, Trash, Plus, Download, ListPlus, Cross, Earth, EarthStriked, CaretDown } from "@strapi/icons";
|
7
7
|
import { useIntl } from "react-intl";
|
8
8
|
import { styled } from "styled-components";
|
9
|
-
import {
|
9
|
+
import { skipToken } from "@reduxjs/toolkit/query";
|
10
|
+
import { useAuth, adminApi, useTable, Table, useQueryParams, useForm, useNotification, useAPIErrorHandler } from "@strapi/admin/strapi-admin";
|
10
11
|
import { unstable_useDocument, unstable_useDocumentActions, buildValidParams } from "@strapi/content-manager/strapi-admin";
|
11
12
|
import { useParams, Link, useNavigate, matchPath } from "react-router-dom";
|
12
13
|
import * as qs from "qs";
|
13
14
|
import { stringify } from "qs";
|
14
15
|
import omit from "lodash/omit";
|
15
|
-
const __variableDynamicImportRuntimeHelper = (glob, path) => {
|
16
|
+
const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
|
16
17
|
const v = glob[path];
|
17
18
|
if (v) {
|
18
19
|
return typeof v === "function" ? v() : Promise.resolve(v);
|
19
20
|
}
|
20
21
|
return new Promise((_, reject) => {
|
21
|
-
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
22
|
+
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
23
|
+
reject.bind(
|
24
|
+
null,
|
25
|
+
new Error(
|
26
|
+
"Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
|
27
|
+
)
|
28
|
+
)
|
29
|
+
);
|
22
30
|
});
|
23
31
|
};
|
24
32
|
const pluginId = "i18n";
|
@@ -47,9 +55,7 @@ const CheckboxConfirmation = ({
|
|
47
55
|
};
|
48
56
|
const handleConfirm = () => {
|
49
57
|
onChange({ target: { name, value: false, type: "checkbox" } });
|
50
|
-
setIsOpen(false);
|
51
58
|
};
|
52
|
-
const handleToggle = () => setIsOpen((prev) => !prev);
|
53
59
|
const label = intlLabel.id ? formatMessage(
|
54
60
|
{ id: intlLabel.id, defaultMessage: intlLabel.defaultMessage },
|
55
61
|
{ ...intlLabel.values }
|
@@ -58,35 +64,36 @@ const CheckboxConfirmation = ({
|
|
58
64
|
{ id: description.id, defaultMessage: description.defaultMessage },
|
59
65
|
{ ...description.values }
|
60
66
|
) : "";
|
61
|
-
return /* @__PURE__ */ jsxs(
|
67
|
+
return /* @__PURE__ */ jsxs(Dialog.Root, { open: isOpen, onOpenChange: setIsOpen, children: [
|
62
68
|
/* @__PURE__ */ jsxs(Field.Root, { hint, name, children: [
|
63
|
-
/* @__PURE__ */ jsx(Checkbox, {
|
69
|
+
/* @__PURE__ */ jsx(Checkbox, { onCheckedChange: handleChange, checked: value, children: label }),
|
64
70
|
/* @__PURE__ */ jsx(Field.Hint, {})
|
65
71
|
] }),
|
66
|
-
|
67
|
-
/* @__PURE__ */ jsx(
|
68
|
-
|
72
|
+
/* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
73
|
+
/* @__PURE__ */ jsx(Dialog.Header, { children: formatMessage({
|
74
|
+
id: getTranslation("CheckboxConfirmation.Modal.title"),
|
75
|
+
defaultMessage: "Disable localization"
|
76
|
+
}) }),
|
77
|
+
/* @__PURE__ */ jsx(Dialog.Body, { icon: /* @__PURE__ */ jsx(WarningCircle, {}), children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
78
|
+
/* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(TextAlignTypography, { children: formatMessage({
|
69
79
|
id: getTranslation("CheckboxConfirmation.Modal.content"),
|
70
80
|
defaultMessage: "Disabling localization will engender the deletion of all your content but the one associated to your default locale (if existing)."
|
71
81
|
}) }) }),
|
72
|
-
/* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold",
|
82
|
+
/* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold", children: formatMessage({
|
73
83
|
id: getTranslation("CheckboxConfirmation.Modal.body"),
|
74
84
|
defaultMessage: "Do you want to disable it?"
|
75
85
|
}) }) })
|
76
86
|
] }) }),
|
77
|
-
/* @__PURE__ */
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
}) })
|
88
|
-
}
|
89
|
-
)
|
87
|
+
/* @__PURE__ */ jsxs(Dialog.Footer, { children: [
|
88
|
+
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", children: formatMessage({
|
89
|
+
id: "components.popUpWarning.button.cancel",
|
90
|
+
defaultMessage: "No, cancel"
|
91
|
+
}) }) }),
|
92
|
+
/* @__PURE__ */ jsx(Dialog.Action, { children: /* @__PURE__ */ jsx(Button, { variant: "danger-light", onClick: handleConfirm, children: formatMessage({
|
93
|
+
id: getTranslation("CheckboxConfirmation.Modal.button-confirm"),
|
94
|
+
defaultMessage: "Yes, disable"
|
95
|
+
}) }) })
|
96
|
+
] })
|
90
97
|
] })
|
91
98
|
] });
|
92
99
|
};
|
@@ -137,7 +144,7 @@ const useI18n = () => {
|
|
137
144
|
model: params.slug
|
138
145
|
},
|
139
146
|
{
|
140
|
-
skip:
|
147
|
+
skip: true
|
141
148
|
}
|
142
149
|
);
|
143
150
|
if (doesPluginOptionsHaveI18nLocalized(schema?.pluginOptions)) {
|
@@ -217,10 +224,94 @@ const relationsApi = i18nApi.injectEndpoints({
|
|
217
224
|
})
|
218
225
|
});
|
219
226
|
const { useGetManyDraftRelationCountQuery } = relationsApi;
|
227
|
+
const cleanData = (data, schema, components) => {
|
228
|
+
const cleanedData = removeFields(data, [
|
229
|
+
"createdAt",
|
230
|
+
"createdBy",
|
231
|
+
"updatedAt",
|
232
|
+
"updatedBy",
|
233
|
+
"id",
|
234
|
+
"documentId",
|
235
|
+
"publishedAt",
|
236
|
+
"strapi_stage",
|
237
|
+
"strapi_assignee",
|
238
|
+
"locale",
|
239
|
+
"status"
|
240
|
+
]);
|
241
|
+
const cleanedDataWithoutPasswordAndRelation = recursiveRemoveFieldTypes(
|
242
|
+
cleanedData,
|
243
|
+
schema,
|
244
|
+
components,
|
245
|
+
["relation", "password"]
|
246
|
+
);
|
247
|
+
return cleanedDataWithoutPasswordAndRelation;
|
248
|
+
};
|
249
|
+
const removeFields = (data, fields) => {
|
250
|
+
return Object.keys(data).reduce((acc, current) => {
|
251
|
+
if (fields.includes(current)) {
|
252
|
+
return acc;
|
253
|
+
}
|
254
|
+
acc[current] = data[current];
|
255
|
+
return acc;
|
256
|
+
}, {});
|
257
|
+
};
|
258
|
+
const recursiveRemoveFieldTypes = (data, schema, components, fields) => {
|
259
|
+
return Object.keys(data).reduce((acc, current) => {
|
260
|
+
const attribute = schema.attributes[current] ?? { type: void 0 };
|
261
|
+
if (fields.includes(attribute.type)) {
|
262
|
+
return acc;
|
263
|
+
}
|
264
|
+
if (attribute.type === "dynamiczone") {
|
265
|
+
acc[current] = data[current].map((componentValue, index2) => {
|
266
|
+
const { id: _, ...rest } = recursiveRemoveFieldTypes(
|
267
|
+
componentValue,
|
268
|
+
components[componentValue.__component],
|
269
|
+
components,
|
270
|
+
fields
|
271
|
+
);
|
272
|
+
return {
|
273
|
+
...rest,
|
274
|
+
__temp_key__: index2 + 1
|
275
|
+
};
|
276
|
+
});
|
277
|
+
} else if (attribute.type === "component") {
|
278
|
+
const { repeatable, component } = attribute;
|
279
|
+
if (repeatable) {
|
280
|
+
acc[current] = (data[current] ?? []).map((compoData, index2) => {
|
281
|
+
const { id: _, ...rest } = recursiveRemoveFieldTypes(
|
282
|
+
compoData,
|
283
|
+
components[component],
|
284
|
+
components,
|
285
|
+
fields
|
286
|
+
);
|
287
|
+
return {
|
288
|
+
...rest,
|
289
|
+
__temp_key__: index2 + 1
|
290
|
+
};
|
291
|
+
});
|
292
|
+
} else {
|
293
|
+
const { id: _, ...rest } = recursiveRemoveFieldTypes(
|
294
|
+
data[current] ?? {},
|
295
|
+
components[component],
|
296
|
+
components,
|
297
|
+
fields
|
298
|
+
);
|
299
|
+
acc[current] = rest;
|
300
|
+
}
|
301
|
+
} else {
|
302
|
+
acc[current] = data[current];
|
303
|
+
}
|
304
|
+
return acc;
|
305
|
+
}, {});
|
306
|
+
};
|
220
307
|
const isErrorMessageDescriptor = (object) => {
|
221
308
|
return typeof object === "object" && object !== null && "id" in object && "defaultMessage" in object;
|
222
309
|
};
|
223
|
-
const EntryValidationText = ({
|
310
|
+
const EntryValidationText = ({
|
311
|
+
status = "draft",
|
312
|
+
validationErrors,
|
313
|
+
action
|
314
|
+
}) => {
|
224
315
|
const { formatMessage } = useIntl();
|
225
316
|
const getErrorStr = (key, value) => {
|
226
317
|
if (typeof value === "string") {
|
@@ -254,30 +345,63 @@ const EntryValidationText = ({ status = "draft", validationErrors }) => {
|
|
254
345
|
) })
|
255
346
|
] });
|
256
347
|
}
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
348
|
+
const getStatusMessage = () => {
|
349
|
+
if (action === "bulk-publish") {
|
350
|
+
if (status === "published") {
|
351
|
+
return {
|
352
|
+
icon: /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
353
|
+
text: formatMessage({
|
354
|
+
id: "content-manager.bulk-publish.already-published",
|
355
|
+
defaultMessage: "Already Published"
|
356
|
+
}),
|
357
|
+
textColor: "success600",
|
358
|
+
fontWeight: "bold"
|
359
|
+
};
|
360
|
+
} else if (status === "modified") {
|
361
|
+
return {
|
362
|
+
icon: /* @__PURE__ */ jsx(ArrowsCounterClockwise, { fill: "alternative600" }),
|
363
|
+
text: formatMessage({
|
364
|
+
id: "app.utils.ready-to-publish-changes",
|
365
|
+
defaultMessage: "Ready to publish changes"
|
366
|
+
})
|
367
|
+
};
|
368
|
+
} else {
|
369
|
+
return {
|
370
|
+
icon: /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
371
|
+
text: formatMessage({
|
372
|
+
id: "app.utils.ready-to-publish",
|
373
|
+
defaultMessage: "Ready to publish"
|
374
|
+
})
|
375
|
+
};
|
376
|
+
}
|
377
|
+
} else {
|
378
|
+
if (status === "draft") {
|
379
|
+
return {
|
380
|
+
icon: /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
381
|
+
text: formatMessage({
|
382
|
+
id: "content-manager.bulk-unpublish.already-unpublished",
|
383
|
+
defaultMessage: "Already Unpublished"
|
384
|
+
}),
|
385
|
+
textColor: "success600",
|
386
|
+
fontWeight: "bold"
|
387
|
+
};
|
388
|
+
} else {
|
389
|
+
return {
|
390
|
+
icon: /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
391
|
+
text: formatMessage({
|
392
|
+
id: "app.utils.ready-to-unpublish-changes",
|
393
|
+
defaultMessage: "Ready to unpublish"
|
394
|
+
}),
|
395
|
+
textColor: "success600",
|
396
|
+
fontWeight: "bold"
|
397
|
+
};
|
398
|
+
}
|
399
|
+
}
|
400
|
+
};
|
401
|
+
const { icon, text, textColor = "success600", fontWeight = "normal" } = getStatusMessage();
|
275
402
|
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
276
|
-
|
277
|
-
/* @__PURE__ */ jsx(Typography, { children:
|
278
|
-
id: "app.utils.ready-to-publish",
|
279
|
-
defaultMessage: "Ready to publish"
|
280
|
-
}) })
|
403
|
+
icon,
|
404
|
+
/* @__PURE__ */ jsx(Typography, { textColor, fontWeight, children: text })
|
281
405
|
] });
|
282
406
|
};
|
283
407
|
const BoldChunk = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
|
@@ -285,7 +409,8 @@ const BulkLocaleActionModal = ({
|
|
285
409
|
headers,
|
286
410
|
rows,
|
287
411
|
localesMetadata,
|
288
|
-
validationErrors = {}
|
412
|
+
validationErrors = {},
|
413
|
+
action
|
289
414
|
}) => {
|
290
415
|
const { formatMessage } = useIntl();
|
291
416
|
const selectedRows = useTable(
|
@@ -298,27 +423,29 @@ const BulkLocaleActionModal = ({
|
|
298
423
|
return acc;
|
299
424
|
}, {});
|
300
425
|
const localesWithErrors = Object.keys(validationErrors);
|
301
|
-
const
|
426
|
+
const publishedCount = selectedRows.filter(
|
302
427
|
({ locale }) => currentStatusByLocale[locale] === "published"
|
303
428
|
).length;
|
304
|
-
const
|
429
|
+
const draftCount = selectedRows.filter(
|
305
430
|
({ locale }) => (currentStatusByLocale[locale] === "draft" || currentStatusByLocale[locale] === "modified") && !localesWithErrors.includes(locale)
|
306
431
|
).length;
|
307
432
|
const withErrorsCount = localesWithErrors.length;
|
433
|
+
const messageId = action === "bulk-publish" ? "content-manager.containers.list.selectedEntriesModal.selectedCount.publish" : "content-manager.containers.list.selectedEntriesModal.selectedCount.unpublish";
|
434
|
+
const defaultMessage = action === "bulk-publish" ? "<b>{publishedCount}</b> {publishedCount, plural, =0 {entries} one {entry} other {entries}} already published. <b>{draftCount}</b> {draftCount, plural, =0 {entries} one {entry} other {entries}} ready to publish. <b>{withErrorsCount}</b> {withErrorsCount, plural, =0 {entries} one {entry} other {entries}} waiting for action." : "<b>{draftCount}</b> {draftCount, plural, =0 {entries} one {entry} other {entries}} already unpublished. <b>{publishedCount}</b> {publishedCount, plural, =0 {entries} one {entry} other {entries}} ready to unpublish.";
|
308
435
|
return formatMessage(
|
309
436
|
{
|
310
|
-
id:
|
311
|
-
defaultMessage
|
437
|
+
id: messageId,
|
438
|
+
defaultMessage
|
312
439
|
},
|
313
440
|
{
|
314
441
|
withErrorsCount,
|
315
|
-
|
316
|
-
|
442
|
+
draftCount,
|
443
|
+
publishedCount,
|
317
444
|
b: BoldChunk
|
318
445
|
}
|
319
446
|
);
|
320
447
|
};
|
321
|
-
return /* @__PURE__ */ jsxs(
|
448
|
+
return /* @__PURE__ */ jsxs(Modal.Body, { children: [
|
322
449
|
/* @__PURE__ */ jsx(Typography, { children: getFormattedCountMessage() }),
|
323
450
|
/* @__PURE__ */ jsx(Box, { marginTop: 5, children: /* @__PURE__ */ jsxs(Table.Content, { children: [
|
324
451
|
/* @__PURE__ */ jsxs(Table.Head, { children: [
|
@@ -339,13 +466,12 @@ const BulkLocaleActionModal = ({
|
|
339
466
|
paddingRight: "6px",
|
340
467
|
paddingTop: "2px",
|
341
468
|
paddingBottom: "2px",
|
342
|
-
showBullet: false,
|
343
469
|
size: "S",
|
344
470
|
variant: statusVariant,
|
345
471
|
children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
|
346
472
|
}
|
347
473
|
) }) }),
|
348
|
-
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(EntryValidationText, { validationErrors: error, status }) }),
|
474
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(EntryValidationText, { validationErrors: error, status, action }) }),
|
349
475
|
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(
|
350
476
|
IconButton,
|
351
477
|
{
|
@@ -362,7 +488,7 @@ const BulkLocaleActionModal = ({
|
|
362
488
|
name: locale
|
363
489
|
}
|
364
490
|
),
|
365
|
-
|
491
|
+
variant: "ghost",
|
366
492
|
children: /* @__PURE__ */ jsx(Pencil, {})
|
367
493
|
}
|
368
494
|
) })
|
@@ -371,6 +497,47 @@ const BulkLocaleActionModal = ({
|
|
371
497
|
] }) })
|
372
498
|
] });
|
373
499
|
};
|
500
|
+
const statusVariants = {
|
501
|
+
draft: "secondary",
|
502
|
+
published: "success",
|
503
|
+
modified: "alternative"
|
504
|
+
};
|
505
|
+
const LocaleOption = ({
|
506
|
+
isDraftAndPublishEnabled,
|
507
|
+
locale,
|
508
|
+
status,
|
509
|
+
entryExists
|
510
|
+
}) => {
|
511
|
+
const { formatMessage } = useIntl();
|
512
|
+
if (!entryExists) {
|
513
|
+
return formatMessage(
|
514
|
+
{
|
515
|
+
id: getTranslation("CMEditViewLocalePicker.locale.create"),
|
516
|
+
defaultMessage: "Create <bold>{locale}</bold> locale"
|
517
|
+
},
|
518
|
+
{
|
519
|
+
bold: (locale2) => /* @__PURE__ */ jsx("b", { children: locale2 }),
|
520
|
+
locale: locale.name
|
521
|
+
}
|
522
|
+
);
|
523
|
+
}
|
524
|
+
return /* @__PURE__ */ jsxs(Flex, { width: "100%", gap: 1, justifyContent: "space-between", children: [
|
525
|
+
/* @__PURE__ */ jsx(Typography, { children: locale.name }),
|
526
|
+
isDraftAndPublishEnabled ? /* @__PURE__ */ jsx(
|
527
|
+
Status,
|
528
|
+
{
|
529
|
+
display: "flex",
|
530
|
+
paddingLeft: "6px",
|
531
|
+
paddingRight: "6px",
|
532
|
+
paddingTop: "2px",
|
533
|
+
paddingBottom: "2px",
|
534
|
+
size: "S",
|
535
|
+
variant: statusVariants[status],
|
536
|
+
children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
|
537
|
+
}
|
538
|
+
) : null
|
539
|
+
] });
|
540
|
+
};
|
374
541
|
const LocalePickerAction = ({
|
375
542
|
document,
|
376
543
|
meta,
|
@@ -382,7 +549,13 @@ const LocalePickerAction = ({
|
|
382
549
|
const [{ query }, setQuery] = useQueryParams();
|
383
550
|
const { hasI18n, canCreate, canRead } = useI18n();
|
384
551
|
const { data: locales = [] } = useGetLocalesQuery();
|
385
|
-
const
|
552
|
+
const currentDesiredLocale = query.plugins?.i18n?.locale;
|
553
|
+
const { schema } = unstable_useDocument({
|
554
|
+
model,
|
555
|
+
collectionType,
|
556
|
+
documentId,
|
557
|
+
params: { locale: currentDesiredLocale }
|
558
|
+
});
|
386
559
|
const handleSelect = React.useCallback(
|
387
560
|
(value) => {
|
388
561
|
setQuery({
|
@@ -400,53 +573,50 @@ const LocalePickerAction = ({
|
|
400
573
|
if (!Array.isArray(locales) || !hasI18n) {
|
401
574
|
return;
|
402
575
|
}
|
403
|
-
const currentDesiredLocale = query.plugins?.i18n?.locale;
|
404
576
|
const doesLocaleExist = locales.find((loc) => loc.code === currentDesiredLocale);
|
405
577
|
const defaultLocale = locales.find((locale) => locale.isDefault);
|
406
578
|
if (!doesLocaleExist && defaultLocale?.code) {
|
407
579
|
handleSelect(defaultLocale.code);
|
408
580
|
}
|
409
|
-
}, [handleSelect, hasI18n, locales,
|
581
|
+
}, [handleSelect, hasI18n, locales, currentDesiredLocale]);
|
582
|
+
const currentLocale = Array.isArray(locales) ? locales.find((locale) => locale.code === currentDesiredLocale) : void 0;
|
583
|
+
const allCurrentLocales = [
|
584
|
+
{ status: getDocumentStatus(document, meta), locale: currentLocale?.code },
|
585
|
+
...document?.localizations ?? []
|
586
|
+
];
|
410
587
|
if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
|
411
588
|
return null;
|
412
589
|
}
|
413
|
-
const
|
414
|
-
|
415
|
-
|
416
|
-
...meta?.availableLocales ?? []
|
417
|
-
];
|
590
|
+
const displayedLocales = locales.filter((locale) => {
|
591
|
+
return canRead.includes(locale.code);
|
592
|
+
});
|
418
593
|
return {
|
419
594
|
label: formatMessage({
|
420
595
|
id: getTranslation("Settings.locales.modal.locales.label"),
|
421
596
|
defaultMessage: "Locales"
|
422
597
|
}),
|
423
|
-
options:
|
598
|
+
options: displayedLocales.map((locale) => {
|
599
|
+
const entryWithLocaleExists = allCurrentLocales.some((doc) => doc.locale === locale.code);
|
424
600
|
const currentLocaleDoc = allCurrentLocales.find(
|
425
601
|
(doc) => "locale" in doc ? doc.locale === locale.code : false
|
426
602
|
);
|
427
|
-
const
|
428
|
-
const permissionsToCheck = currentLocaleDoc ? canCreate : canRead;
|
429
|
-
const statusVariant = status === "draft" ? "primary" : status === "published" ? "success" : "alternative";
|
603
|
+
const permissionsToCheck = currentLocaleDoc ? canRead : canCreate;
|
430
604
|
return {
|
431
605
|
disabled: !permissionsToCheck.includes(locale.code),
|
432
606
|
value: locale.code,
|
433
|
-
label:
|
434
|
-
|
435
|
-
Status,
|
607
|
+
label: /* @__PURE__ */ jsx(
|
608
|
+
LocaleOption,
|
436
609
|
{
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
paddingBottom: "2px",
|
442
|
-
showBullet: false,
|
443
|
-
size: "S",
|
444
|
-
variant: statusVariant,
|
445
|
-
children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "pi", fontWeight: "bold", children: capitalize(status) })
|
610
|
+
isDraftAndPublishEnabled: !!schema?.options?.draftAndPublish,
|
611
|
+
locale,
|
612
|
+
status: currentLocaleDoc?.status,
|
613
|
+
entryExists: entryWithLocaleExists
|
446
614
|
}
|
447
|
-
)
|
615
|
+
),
|
616
|
+
startIcon: !entryWithLocaleExists ? /* @__PURE__ */ jsx(Plus, {}) : null
|
448
617
|
};
|
449
618
|
}),
|
619
|
+
customizeContent: () => currentLocale?.name,
|
450
620
|
onSelect: handleSelect,
|
451
621
|
value: currentLocale
|
452
622
|
};
|
@@ -462,6 +632,99 @@ const getDocumentStatus = (document, meta) => {
|
|
462
632
|
}
|
463
633
|
return docStatus;
|
464
634
|
};
|
635
|
+
const FillFromAnotherLocaleAction = ({
|
636
|
+
documentId,
|
637
|
+
meta,
|
638
|
+
model,
|
639
|
+
collectionType
|
640
|
+
}) => {
|
641
|
+
const { formatMessage } = useIntl();
|
642
|
+
const [{ query }] = useQueryParams();
|
643
|
+
const { hasI18n } = useI18n();
|
644
|
+
const currentDesiredLocale = query.plugins?.i18n?.locale;
|
645
|
+
const [localeSelected, setLocaleSelected] = React.useState(null);
|
646
|
+
const setValues = useForm("FillFromAnotherLocale", (state) => state.setValues);
|
647
|
+
const { getDocument } = unstable_useDocumentActions();
|
648
|
+
const { schema, components } = unstable_useDocument({
|
649
|
+
model,
|
650
|
+
documentId,
|
651
|
+
collectionType,
|
652
|
+
params: { locale: currentDesiredLocale }
|
653
|
+
});
|
654
|
+
const { data: locales = [] } = useGetLocalesQuery();
|
655
|
+
const availableLocales = Array.isArray(locales) ? locales.filter((locale) => meta?.availableLocales.some((l) => l.locale === locale.code)) : [];
|
656
|
+
const fillFromLocale = (onClose) => async () => {
|
657
|
+
const response = await getDocument({
|
658
|
+
collectionType,
|
659
|
+
model,
|
660
|
+
documentId,
|
661
|
+
params: { locale: localeSelected }
|
662
|
+
});
|
663
|
+
if (!response || !schema) {
|
664
|
+
return;
|
665
|
+
}
|
666
|
+
const { data } = response;
|
667
|
+
const cleanedData = cleanData(data, schema, components);
|
668
|
+
setValues(cleanedData);
|
669
|
+
onClose();
|
670
|
+
};
|
671
|
+
if (!hasI18n) {
|
672
|
+
return null;
|
673
|
+
}
|
674
|
+
return {
|
675
|
+
type: "icon",
|
676
|
+
icon: /* @__PURE__ */ jsx(Download, {}),
|
677
|
+
disabled: availableLocales.length === 0,
|
678
|
+
label: formatMessage({
|
679
|
+
id: getTranslation("CMEditViewCopyLocale.copy-text"),
|
680
|
+
defaultMessage: "Fill in from another locale"
|
681
|
+
}),
|
682
|
+
dialog: {
|
683
|
+
type: "dialog",
|
684
|
+
title: formatMessage({
|
685
|
+
id: getTranslation("CMEditViewCopyLocale.dialog.title"),
|
686
|
+
defaultMessage: "Confirmation"
|
687
|
+
}),
|
688
|
+
content: ({ onClose }) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
689
|
+
/* @__PURE__ */ jsx(Dialog.Body, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 3, children: [
|
690
|
+
/* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
691
|
+
/* @__PURE__ */ jsx(Typography, { textAlign: "center", children: formatMessage({
|
692
|
+
id: getTranslation("CMEditViewCopyLocale.dialog.body"),
|
693
|
+
defaultMessage: "Your current content will be erased and filled by the content of the selected locale:"
|
694
|
+
}) }),
|
695
|
+
/* @__PURE__ */ jsxs(Field.Root, { width: "100%", children: [
|
696
|
+
/* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
|
697
|
+
id: getTranslation("CMEditViewCopyLocale.dialog.field.label"),
|
698
|
+
defaultMessage: "Locale"
|
699
|
+
}) }),
|
700
|
+
/* @__PURE__ */ jsx(
|
701
|
+
SingleSelect,
|
702
|
+
{
|
703
|
+
value: localeSelected,
|
704
|
+
placeholder: formatMessage({
|
705
|
+
id: getTranslation("CMEditViewCopyLocale.dialog.field.placeholder"),
|
706
|
+
defaultMessage: "Select one locale..."
|
707
|
+
}),
|
708
|
+
onChange: (value) => setLocaleSelected(value),
|
709
|
+
children: availableLocales.map((locale) => /* @__PURE__ */ jsx(SingleSelectOption, { value: locale.code, children: locale.name }, locale.code))
|
710
|
+
}
|
711
|
+
)
|
712
|
+
] })
|
713
|
+
] }) }),
|
714
|
+
/* @__PURE__ */ jsx(Dialog.Footer, { children: /* @__PURE__ */ jsxs(Flex, { gap: 2, width: "100%", children: [
|
715
|
+
/* @__PURE__ */ jsx(Button, { flex: "auto", variant: "tertiary", onClick: onClose, children: formatMessage({
|
716
|
+
id: getTranslation("CMEditViewCopyLocale.cancel-text"),
|
717
|
+
defaultMessage: "No, cancel"
|
718
|
+
}) }),
|
719
|
+
/* @__PURE__ */ jsx(Button, { flex: "auto", variant: "success", onClick: fillFromLocale(onClose), children: formatMessage({
|
720
|
+
id: getTranslation("CMEditViewCopyLocale.submit-text"),
|
721
|
+
defaultMessage: "Yes, fill in"
|
722
|
+
}) })
|
723
|
+
] }) })
|
724
|
+
] })
|
725
|
+
}
|
726
|
+
};
|
727
|
+
};
|
465
728
|
const DeleteLocaleAction = ({
|
466
729
|
document,
|
467
730
|
documentId,
|
@@ -473,16 +736,23 @@ const DeleteLocaleAction = ({
|
|
473
736
|
const { toggleNotification } = useNotification();
|
474
737
|
const { delete: deleteAction } = unstable_useDocumentActions();
|
475
738
|
const { hasI18n, canDelete } = useI18n();
|
739
|
+
const [{ query }] = useQueryParams();
|
740
|
+
const { data: locales = [] } = useGetLocalesQuery();
|
741
|
+
const currentDesiredLocale = query.plugins?.i18n?.locale;
|
742
|
+
const locale = !("error" in locales) && locales.find((loc) => loc.code === currentDesiredLocale);
|
476
743
|
if (!hasI18n) {
|
477
744
|
return null;
|
478
745
|
}
|
479
746
|
return {
|
480
747
|
disabled: document?.locale && !canDelete.includes(document.locale) || !document || !document.id,
|
481
748
|
position: ["header", "table-row"],
|
482
|
-
label: formatMessage(
|
483
|
-
|
484
|
-
|
485
|
-
|
749
|
+
label: formatMessage(
|
750
|
+
{
|
751
|
+
id: getTranslation("actions.delete.label"),
|
752
|
+
defaultMessage: "Delete entry ({locale})"
|
753
|
+
},
|
754
|
+
{ locale: locale && locale.name }
|
755
|
+
),
|
486
756
|
icon: /* @__PURE__ */ jsx(StyledTrash, {}),
|
487
757
|
variant: "danger",
|
488
758
|
dialog: {
|
@@ -499,7 +769,12 @@ const DeleteLocaleAction = ({
|
|
499
769
|
}) })
|
500
770
|
] }),
|
501
771
|
onConfirm: async () => {
|
502
|
-
|
772
|
+
const unableToDelete = (
|
773
|
+
// We are unable to delete a collection type without a document ID
|
774
|
+
// & unable to delete generally if there is no document locale
|
775
|
+
collectionType !== "single-types" && !documentId || !document?.locale
|
776
|
+
);
|
777
|
+
if (unableToDelete) {
|
503
778
|
console.error(
|
504
779
|
"You're trying to delete a document without an id or locale, this is likely a bug with Strapi. Please open an issue."
|
505
780
|
);
|
@@ -525,37 +800,39 @@ const DeleteLocaleAction = ({
|
|
525
800
|
}
|
526
801
|
};
|
527
802
|
};
|
528
|
-
const
|
529
|
-
document
|
803
|
+
const BulkLocaleAction = ({
|
804
|
+
document,
|
530
805
|
documentId,
|
531
806
|
model,
|
532
|
-
collectionType
|
807
|
+
collectionType,
|
808
|
+
action
|
533
809
|
}) => {
|
534
|
-
const
|
810
|
+
const locale = document?.locale ?? null;
|
535
811
|
const [{ query }] = useQueryParams();
|
536
812
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
537
|
-
const
|
813
|
+
const isOnPublishedTab = query.status === "published";
|
538
814
|
const { formatMessage } = useIntl();
|
539
815
|
const { hasI18n, canPublish } = useI18n();
|
540
816
|
const { toggleNotification } = useNotification();
|
541
817
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
542
818
|
const [selectedRows, setSelectedRows] = React.useState([]);
|
543
|
-
const [
|
544
|
-
const { publishMany: publishManyAction } = unstable_useDocumentActions();
|
545
|
-
const {
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
819
|
+
const [isDraftRelationConfirmationOpen, setIsDraftRelationConfirmationOpen] = React.useState(false);
|
820
|
+
const { publishMany: publishManyAction, unpublishMany: unpublishManyAction } = unstable_useDocumentActions();
|
821
|
+
const { schema, validate } = unstable_useDocument(
|
822
|
+
{
|
823
|
+
model,
|
824
|
+
collectionType,
|
825
|
+
documentId,
|
826
|
+
params: {
|
827
|
+
locale
|
828
|
+
}
|
829
|
+
},
|
830
|
+
{
|
831
|
+
// No need to fetch the document, the data is already available in the `document` prop
|
832
|
+
skip: true
|
556
833
|
}
|
557
|
-
|
558
|
-
const { data: localesMetadata = [] } = useGetLocalesQuery();
|
834
|
+
);
|
835
|
+
const { data: localesMetadata = [] } = useGetLocalesQuery(hasI18n ? void 0 : skipToken);
|
559
836
|
const headers = [
|
560
837
|
{
|
561
838
|
label: formatMessage({
|
@@ -580,18 +857,19 @@ const BulkLocalePublishAction = ({
|
|
580
857
|
}
|
581
858
|
];
|
582
859
|
const [rows, validationErrors] = React.useMemo(() => {
|
583
|
-
if (!document
|
860
|
+
if (!document) {
|
584
861
|
return [[], {}];
|
585
862
|
}
|
586
|
-
const
|
587
|
-
|
588
|
-
|
863
|
+
const localizations = document.localizations ?? [];
|
864
|
+
const locales = localizations.map((doc) => {
|
865
|
+
const { locale: locale2, status } = doc;
|
866
|
+
return { locale: locale2, status };
|
589
867
|
});
|
590
|
-
|
868
|
+
locales.unshift({
|
591
869
|
locale: document.locale,
|
592
870
|
status: document.status
|
593
871
|
});
|
594
|
-
const allDocuments = [document, ...
|
872
|
+
const allDocuments = [document, ...localizations];
|
595
873
|
const errors = allDocuments.reduce((errs, document2) => {
|
596
874
|
if (!document2) {
|
597
875
|
return errs;
|
@@ -602,14 +880,21 @@ const BulkLocalePublishAction = ({
|
|
602
880
|
}
|
603
881
|
return errs;
|
604
882
|
}, {});
|
605
|
-
return [
|
606
|
-
}, [document,
|
607
|
-
const
|
608
|
-
|
883
|
+
return [locales, errors];
|
884
|
+
}, [document, validate]);
|
885
|
+
const isBulkPublish = action === "bulk-publish";
|
886
|
+
const localesForAction = selectedRows.reduce((acc, selectedRow) => {
|
887
|
+
const isValidLocale = (
|
888
|
+
// Validation errors are irrelevant if we are trying to unpublish
|
889
|
+
!isBulkPublish || !Object.keys(validationErrors).includes(selectedRow.locale)
|
890
|
+
);
|
891
|
+
const shouldAddLocale = isBulkPublish ? selectedRow.status !== "published" && isValidLocale : selectedRow.status !== "draft" && isValidLocale;
|
892
|
+
if (shouldAddLocale) {
|
609
893
|
acc.push(selectedRow.locale);
|
610
894
|
}
|
611
895
|
return acc;
|
612
896
|
}, []);
|
897
|
+
const enableDraftRelationsCount = false;
|
613
898
|
const {
|
614
899
|
data: draftRelationsCount = 0,
|
615
900
|
isLoading: isDraftRelationsLoading,
|
@@ -618,10 +903,10 @@ const BulkLocalePublishAction = ({
|
|
618
903
|
{
|
619
904
|
model,
|
620
905
|
documentIds: [documentId],
|
621
|
-
locale:
|
906
|
+
locale: localesForAction
|
622
907
|
},
|
623
908
|
{
|
624
|
-
skip: !
|
909
|
+
skip: !enableDraftRelationsCount
|
625
910
|
}
|
626
911
|
);
|
627
912
|
React.useEffect(() => {
|
@@ -647,23 +932,32 @@ const BulkLocalePublishAction = ({
|
|
647
932
|
documentIds: [documentId],
|
648
933
|
params: {
|
649
934
|
...params,
|
650
|
-
locale:
|
935
|
+
locale: localesForAction
|
936
|
+
}
|
937
|
+
});
|
938
|
+
setSelectedRows([]);
|
939
|
+
};
|
940
|
+
const unpublish = async () => {
|
941
|
+
await unpublishManyAction({
|
942
|
+
model,
|
943
|
+
documentIds: [documentId],
|
944
|
+
params: {
|
945
|
+
...params,
|
946
|
+
locale: localesForAction
|
651
947
|
}
|
652
948
|
});
|
653
949
|
setSelectedRows([]);
|
654
950
|
};
|
655
951
|
const handleAction = async () => {
|
656
952
|
if (draftRelationsCount > 0) {
|
657
|
-
|
658
|
-
} else {
|
953
|
+
setIsDraftRelationConfirmationOpen(true);
|
954
|
+
} else if (isBulkPublish) {
|
659
955
|
await publish();
|
956
|
+
} else {
|
957
|
+
await unpublish();
|
660
958
|
}
|
661
959
|
};
|
662
|
-
|
663
|
-
if (isUnpublish) {
|
664
|
-
console.warn(["I18N"], "Bulk locale unpublish modal not implemented");
|
665
|
-
}
|
666
|
-
if (isConfirmationOpen) {
|
960
|
+
if (isDraftRelationConfirmationOpen) {
|
667
961
|
return {
|
668
962
|
label: formatMessage({
|
669
963
|
id: "app.components.ConfirmDialog.title",
|
@@ -672,11 +966,11 @@ const BulkLocalePublishAction = ({
|
|
672
966
|
variant: "danger",
|
673
967
|
dialog: {
|
674
968
|
onCancel: () => {
|
675
|
-
|
969
|
+
setIsDraftRelationConfirmationOpen(false);
|
676
970
|
},
|
677
971
|
onConfirm: async () => {
|
678
972
|
await publish();
|
679
|
-
|
973
|
+
setIsDraftRelationConfirmationOpen(false);
|
680
974
|
},
|
681
975
|
type: "dialog",
|
682
976
|
title: formatMessage({
|
@@ -686,27 +980,32 @@ const BulkLocalePublishAction = ({
|
|
686
980
|
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "center", gap: 2, children: [
|
687
981
|
/* @__PURE__ */ jsx(WarningCircle, { width: "2.4rem", height: "2.4rem", fill: "danger600" }),
|
688
982
|
/* @__PURE__ */ jsx(Typography, { textAlign: "center", children: formatMessage({
|
689
|
-
id: "
|
690
|
-
defaultMessage: "
|
983
|
+
id: getTranslation("CMEditViewBulkLocale.draft-relation-warning"),
|
984
|
+
defaultMessage: "Some locales are related to draft entries. Publishing them could leave broken links in your app."
|
985
|
+
}) }),
|
986
|
+
/* @__PURE__ */ jsx(Typography, { textAlign: "center", children: formatMessage({
|
987
|
+
id: getTranslation("CMEditViewBulkLocale.continue-confirmation"),
|
988
|
+
defaultMessage: "Are you sure you want to continue?"
|
691
989
|
}) })
|
692
990
|
] })
|
693
991
|
}
|
694
992
|
};
|
695
993
|
}
|
994
|
+
const hasPermission = selectedRows.map(({ locale: locale2 }) => locale2).every((locale2) => canPublish.includes(locale2));
|
696
995
|
return {
|
697
996
|
label: formatMessage({
|
698
|
-
id: getTranslation("
|
699
|
-
defaultMessage: "Publish Multiple Locales
|
997
|
+
id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
|
998
|
+
defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
|
700
999
|
}),
|
701
|
-
|
702
|
-
|
1000
|
+
variant: isBulkPublish ? "secondary" : "danger",
|
1001
|
+
icon: isBulkPublish ? /* @__PURE__ */ jsx(ListPlus, {}) : /* @__PURE__ */ jsx(Cross, {}),
|
1002
|
+
disabled: isOnPublishedTab || canPublish.length === 0,
|
703
1003
|
position: ["panel"],
|
704
|
-
variant: "secondary",
|
705
1004
|
dialog: {
|
706
1005
|
type: "modal",
|
707
1006
|
title: formatMessage({
|
708
|
-
id: getTranslation("
|
709
|
-
defaultMessage: "Publish Multiple Locales
|
1007
|
+
id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
|
1008
|
+
defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
|
710
1009
|
}),
|
711
1010
|
content: () => {
|
712
1011
|
return /* @__PURE__ */ jsx(
|
@@ -725,28 +1024,35 @@ const BulkLocalePublishAction = ({
|
|
725
1024
|
validationErrors,
|
726
1025
|
headers,
|
727
1026
|
rows,
|
728
|
-
localesMetadata
|
1027
|
+
localesMetadata,
|
1028
|
+
action: action ?? "bulk-publish"
|
729
1029
|
}
|
730
1030
|
)
|
731
1031
|
}
|
732
1032
|
);
|
733
1033
|
},
|
734
|
-
footer: () => /* @__PURE__ */ jsx(
|
735
|
-
Button
|
1034
|
+
footer: () => /* @__PURE__ */ jsx(Modal.Footer, { justifyContent: "flex-end", children: /* @__PURE__ */ jsx(
|
1035
|
+
Button,
|
736
1036
|
{
|
737
1037
|
loading: isDraftRelationsLoading,
|
738
|
-
disabled:
|
1038
|
+
disabled: !hasPermission || localesForAction.length === 0,
|
739
1039
|
variant: "default",
|
740
1040
|
onClick: handleAction,
|
741
1041
|
children: formatMessage({
|
742
|
-
id: "app.utils.publish",
|
743
|
-
defaultMessage: "Publish"
|
1042
|
+
id: isBulkPublish ? "app.utils.publish" : "app.utils.unpublish",
|
1043
|
+
defaultMessage: isBulkPublish ? "Publish" : "Unpublish"
|
744
1044
|
})
|
745
1045
|
}
|
746
1046
|
) })
|
747
1047
|
}
|
748
1048
|
};
|
749
1049
|
};
|
1050
|
+
const BulkLocalePublishAction = (props) => {
|
1051
|
+
return BulkLocaleAction({ action: "bulk-publish", ...props });
|
1052
|
+
};
|
1053
|
+
const BulkLocaleUnpublishAction = (props) => {
|
1054
|
+
return BulkLocaleAction({ action: "bulk-unpublish", ...props });
|
1055
|
+
};
|
750
1056
|
const StyledTrash = styled(Trash)`
|
751
1057
|
path {
|
752
1058
|
fill: currentColor;
|
@@ -803,13 +1109,6 @@ const UnpublishModalAdditionalInfo = () => {
|
|
803
1109
|
}
|
804
1110
|
) });
|
805
1111
|
};
|
806
|
-
const Initializer = ({ setPlugin }) => {
|
807
|
-
const setPluginRef = React.useRef(setPlugin);
|
808
|
-
React.useEffect(() => {
|
809
|
-
setPluginRef.current(pluginId);
|
810
|
-
}, []);
|
811
|
-
return null;
|
812
|
-
};
|
813
1112
|
const LocalePicker = () => {
|
814
1113
|
const { formatMessage } = useIntl();
|
815
1114
|
const [{ query }, setQuery] = useQueryParams();
|
@@ -869,7 +1168,7 @@ const PERMISSIONS = {
|
|
869
1168
|
read: [{ action: "plugin::i18n.locale.read", subject: null }]
|
870
1169
|
};
|
871
1170
|
const mutateEditViewHook = ({ layout }) => {
|
872
|
-
if ("i18n" in layout.options
|
1171
|
+
if (!("i18n" in layout.options) || typeof layout.options.i18n === "object" && layout.options.i18n !== null && "localized" in layout.options.i18n && !layout.options.i18n.localized) {
|
873
1172
|
return { layout };
|
874
1173
|
}
|
875
1174
|
const components = Object.entries(layout.components).reduce(
|
@@ -915,7 +1214,7 @@ const doesFieldHaveI18nPluginOpt = (pluginOpts) => {
|
|
915
1214
|
const LabelAction = ({ title, icon }) => {
|
916
1215
|
const { formatMessage } = useIntl();
|
917
1216
|
return /* @__PURE__ */ jsxs(Span, { tag: "span", children: [
|
918
|
-
/* @__PURE__ */ jsx(VisuallyHidden, { tag: "span", children:
|
1217
|
+
/* @__PURE__ */ jsx(VisuallyHidden, { tag: "span", children: formatMessage(title) }),
|
919
1218
|
React.cloneElement(icon, {
|
920
1219
|
"aria-hidden": true,
|
921
1220
|
focusable: false
|
@@ -935,35 +1234,16 @@ const Span = styled(Flex)`
|
|
935
1234
|
}
|
936
1235
|
}
|
937
1236
|
`;
|
938
|
-
const LocaleListCell = ({
|
939
|
-
documentId,
|
940
|
-
locale: currentLocale,
|
941
|
-
collectionType,
|
942
|
-
model
|
943
|
-
}) => {
|
944
|
-
const { meta, isLoading } = unstable_useDocument({
|
945
|
-
documentId,
|
946
|
-
collectionType,
|
947
|
-
model,
|
948
|
-
params: {
|
949
|
-
locale: currentLocale
|
950
|
-
}
|
951
|
-
});
|
1237
|
+
const LocaleListCell = ({ locale: currentLocale, localizations }) => {
|
952
1238
|
const { locale: language } = useIntl();
|
953
|
-
const [visible, setVisible] = React.useState(false);
|
954
|
-
const buttonRef = React.useRef(null);
|
955
1239
|
const { data: locales = [] } = useGetLocalesQuery();
|
956
|
-
const handleTogglePopover = (e) => {
|
957
|
-
e.stopPropagation();
|
958
|
-
setVisible((prev) => !prev);
|
959
|
-
};
|
960
1240
|
const formatter = useCollator(language, {
|
961
1241
|
sensitivity: "base"
|
962
1242
|
});
|
963
|
-
if (!Array.isArray(locales) ||
|
1243
|
+
if (!Array.isArray(locales) || !localizations) {
|
964
1244
|
return null;
|
965
1245
|
}
|
966
|
-
const availableLocales =
|
1246
|
+
const availableLocales = localizations.map((loc) => loc.locale);
|
967
1247
|
const localesForDocument = locales.reduce((acc, locale) => {
|
968
1248
|
const createdLocale = [currentLocale, ...availableLocales].find((loc) => {
|
969
1249
|
return loc === locale.code;
|
@@ -978,64 +1258,14 @@ const LocaleListCell = ({
|
|
978
1258
|
}
|
979
1259
|
return locale.name;
|
980
1260
|
}).toSorted((a, b) => formatter.compare(a, b));
|
981
|
-
return /* @__PURE__ */ jsxs(
|
982
|
-
/* @__PURE__ */ jsxs(
|
983
|
-
|
984
|
-
{
|
985
|
-
|
986
|
-
|
987
|
-
justifyContent: "center",
|
988
|
-
height: "3.2rem",
|
989
|
-
width: "3.2rem",
|
990
|
-
children: [
|
991
|
-
/* @__PURE__ */ jsx(Typography, { textColor: "neutral800", ellipsis: true, children: localesForDocument.join(", ") }),
|
992
|
-
/* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(CaretDown, {}) })
|
993
|
-
]
|
994
|
-
}
|
995
|
-
),
|
996
|
-
visible && /* @__PURE__ */ jsx(
|
997
|
-
Popover,
|
998
|
-
{
|
999
|
-
onDismiss: () => setVisible(false),
|
1000
|
-
source: buttonRef,
|
1001
|
-
spacing: 16,
|
1002
|
-
centered: true,
|
1003
|
-
children: /* @__PURE__ */ jsx("ul", { children: localesForDocument.map((name) => /* @__PURE__ */ jsx(Box, { padding: 3, tag: "li", children: /* @__PURE__ */ jsx(Typography, { children: name }) }, name)) })
|
1004
|
-
}
|
1005
|
-
)
|
1261
|
+
return /* @__PURE__ */ jsxs(Popover.Root, { children: [
|
1262
|
+
/* @__PURE__ */ jsx(Popover.Trigger, { children: /* @__PURE__ */ jsx(Button, { variant: "ghost", type: "button", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxs(Flex, { minWidth: "100%", alignItems: "center", justifyContent: "center", fontWeight: "regular", children: [
|
1263
|
+
/* @__PURE__ */ jsx(Typography, { textColor: "neutral800", ellipsis: true, marginRight: 2, children: localesForDocument.join(", ") }),
|
1264
|
+
/* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(CaretDown, { width: "1.2rem", height: "1.2rem" }) })
|
1265
|
+
] }) }) }),
|
1266
|
+
/* @__PURE__ */ jsx(Popover.Content, { sideOffset: 16, children: /* @__PURE__ */ jsx("ul", { children: localesForDocument.map((name) => /* @__PURE__ */ jsx(Box, { padding: 3, tag: "li", children: /* @__PURE__ */ jsx(Typography, { children: name }) }, name)) }) })
|
1006
1267
|
] });
|
1007
1268
|
};
|
1008
|
-
const Button = styled.button`
|
1009
|
-
width: 100%;
|
1010
|
-
|
1011
|
-
svg {
|
1012
|
-
> g,
|
1013
|
-
path {
|
1014
|
-
fill: ${({ theme }) => theme.colors.neutral500};
|
1015
|
-
}
|
1016
|
-
}
|
1017
|
-
&:hover {
|
1018
|
-
svg {
|
1019
|
-
> g,
|
1020
|
-
path {
|
1021
|
-
fill: ${({ theme }) => theme.colors.neutral600};
|
1022
|
-
}
|
1023
|
-
}
|
1024
|
-
}
|
1025
|
-
&:active {
|
1026
|
-
svg {
|
1027
|
-
> g,
|
1028
|
-
path {
|
1029
|
-
fill: ${({ theme }) => theme.colors.neutral400};
|
1030
|
-
}
|
1031
|
-
}
|
1032
|
-
}
|
1033
|
-
`;
|
1034
|
-
const ActionWrapper = styled(Flex)`
|
1035
|
-
svg {
|
1036
|
-
height: 0.4rem;
|
1037
|
-
}
|
1038
|
-
`;
|
1039
1269
|
const addColumnToTableHook = ({ displayedHeaders, layout }) => {
|
1040
1270
|
const { options } = layout;
|
1041
1271
|
const isFieldLocalized = doesPluginOptionsHaveI18nLocalized(options) ? options.i18n.localized : false;
|
@@ -1064,18 +1294,11 @@ const addColumnToTableHook = ({ displayedHeaders, layout }) => {
|
|
1064
1294
|
const addLocaleToReleasesHook = ({ displayedHeaders = [] }) => {
|
1065
1295
|
return {
|
1066
1296
|
displayedHeaders: [
|
1067
|
-
|
1068
|
-
// ...displayedHeaders,
|
1297
|
+
...displayedHeaders,
|
1069
1298
|
{
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
label: {
|
1074
|
-
id: "content-releases.page.ReleaseDetails.table.header.label.locale",
|
1075
|
-
defaultMessage: "locale"
|
1076
|
-
},
|
1077
|
-
searchable: false,
|
1078
|
-
sortable: false
|
1299
|
+
label: {
|
1300
|
+
id: "content-releases.page.ReleaseDetails.table.header.label.locale",
|
1301
|
+
defaultMessage: "locale"
|
1079
1302
|
},
|
1080
1303
|
name: "locale"
|
1081
1304
|
}
|
@@ -1168,9 +1391,6 @@ const localeMiddleware = (ctx) => (next) => (permissions) => {
|
|
1168
1391
|
return next(revisedPermissions);
|
1169
1392
|
};
|
1170
1393
|
const prefixPluginTranslations = (trad, pluginId2) => {
|
1171
|
-
if (!pluginId2) {
|
1172
|
-
throw new TypeError("pluginId can't be empty");
|
1173
|
-
}
|
1174
1394
|
return Object.keys(trad).reduce((acc, current) => {
|
1175
1395
|
acc[`${pluginId2}.${current}`] = trad[current];
|
1176
1396
|
return acc;
|
@@ -1223,8 +1443,6 @@ const index = {
|
|
1223
1443
|
app.addRBACMiddleware([localeMiddleware]);
|
1224
1444
|
app.registerPlugin({
|
1225
1445
|
id: pluginId,
|
1226
|
-
initializer: Initializer,
|
1227
|
-
isReady: false,
|
1228
1446
|
name: pluginId
|
1229
1447
|
});
|
1230
1448
|
},
|
@@ -1242,11 +1460,11 @@ const index = {
|
|
1242
1460
|
},
|
1243
1461
|
id: "internationalization",
|
1244
1462
|
to: "internationalization",
|
1245
|
-
Component: () => import("./SettingsPage-
|
1463
|
+
Component: () => import("./SettingsPage-B-KzAqT3.mjs").then((mod) => ({ default: mod.ProtectedSettingsPage })),
|
1246
1464
|
permissions: PERMISSIONS.accessMain
|
1247
1465
|
});
|
1248
1466
|
const contentManager = app.getPlugin("content-manager");
|
1249
|
-
contentManager.apis.addDocumentHeaderAction([LocalePickerAction]);
|
1467
|
+
contentManager.apis.addDocumentHeaderAction([LocalePickerAction, FillFromAnotherLocaleAction]);
|
1250
1468
|
contentManager.apis.addDocumentAction((actions) => {
|
1251
1469
|
const indexOfDeleteAction = actions.findIndex((action) => action.type === "delete");
|
1252
1470
|
actions.splice(indexOfDeleteAction, 0, DeleteLocaleAction);
|
@@ -1254,6 +1472,7 @@ const index = {
|
|
1254
1472
|
});
|
1255
1473
|
contentManager.apis.addDocumentAction((actions) => {
|
1256
1474
|
actions.splice(2, 0, BulkLocalePublishAction);
|
1475
|
+
actions.splice(5, 0, BulkLocaleUnpublishAction);
|
1257
1476
|
return actions;
|
1258
1477
|
});
|
1259
1478
|
contentManager.injectComponent("listView", "actions", {
|
@@ -1303,24 +1522,6 @@ const index = {
|
|
1303
1522
|
}
|
1304
1523
|
});
|
1305
1524
|
ctbFormsAPI.extendFields(LOCALIZED_FIELDS, {
|
1306
|
-
validator: (args) => ({
|
1307
|
-
i18n: yup.object().shape({
|
1308
|
-
localized: yup.bool().test({
|
1309
|
-
name: "ensure-unique-localization",
|
1310
|
-
message: getTranslation("plugin.schema.i18n.ensure-unique-localization"),
|
1311
|
-
test(value) {
|
1312
|
-
if (value === void 0 || value) {
|
1313
|
-
return true;
|
1314
|
-
}
|
1315
|
-
const unique = get(args, ["3", "modifiedData", "unique"], null);
|
1316
|
-
if (unique && !value) {
|
1317
|
-
return false;
|
1318
|
-
}
|
1319
|
-
return true;
|
1320
|
-
}
|
1321
|
-
})
|
1322
|
-
})
|
1323
|
-
}),
|
1324
1525
|
form: {
|
1325
1526
|
advanced({ contentTypeSchema, forTarget, type, step }) {
|
1326
1527
|
if (forTarget !== "contentType") {
|
@@ -1359,7 +1560,7 @@ const index = {
|
|
1359
1560
|
async registerTrads({ locales }) {
|
1360
1561
|
const importedTrads = await Promise.all(
|
1361
1562
|
locales.map((locale) => {
|
1362
|
-
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/de.json": () => import("./de-
|
1563
|
+
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/de.json": () => import("./de-D80IRBP9.mjs"), "./translations/dk.json": () => import("./dk-CJ6Zzz78.mjs"), "./translations/en.json": () => import("./en-BTyF7WVW.mjs"), "./translations/es.json": () => import("./es-V8WnPN7w.mjs"), "./translations/fr.json": () => import("./fr-F94noFiV.mjs"), "./translations/ko.json": () => import("./ko-CF-P3Car.mjs"), "./translations/pl.json": () => import("./pl-Dxr9RUmD.mjs"), "./translations/ru.json": () => import("./ru-B-4sVwXN.mjs"), "./translations/tr.json": () => import("./tr-Ccu6Yj11.mjs"), "./translations/zh-Hans.json": () => import("./zh-Hans-Bfo6_TCM.mjs"), "./translations/zh.json": () => import("./zh-BIz395Ms.mjs") }), `./translations/${locale}.json`, 3).then(({ default: data }) => {
|
1363
1564
|
return {
|
1364
1565
|
data: prefixPluginTranslations(data, pluginId),
|
1365
1566
|
locale
|
@@ -1385,4 +1586,4 @@ export {
|
|
1385
1586
|
index as i,
|
1386
1587
|
useCreateLocaleMutation as u
|
1387
1588
|
};
|
1388
|
-
//# sourceMappingURL=index-
|
1589
|
+
//# sourceMappingURL=index-BcYj5jo9.mjs.map
|