@strapi/i18n 0.0.0-experimental.7afdc9b682bc83a53ce599c4fb7c9e4506b31fff → 0.0.0-experimental.7bc5339b0393e53f9f568301594621e7fb466e2f
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-DNucKxbi.mjs → SettingsPage-BAx9nmep.mjs} +95 -108
- package/dist/_chunks/SettingsPage-BAx9nmep.mjs.map +1 -0
- package/dist/_chunks/{SettingsPage-CG_qq0Tx.js → SettingsPage-BTgjb2KS.js} +94 -108
- package/dist/_chunks/SettingsPage-BTgjb2KS.js.map +1 -0
- package/dist/_chunks/{en-Kv6y9zPQ.js → en-BKBz3tro.js} +12 -3
- package/dist/_chunks/en-BKBz3tro.js.map +1 -0
- package/dist/_chunks/{en-18tWw4P6.mjs → en-DlXfy6Gy.mjs} +12 -3
- package/dist/_chunks/en-DlXfy6Gy.mjs.map +1 -0
- package/dist/_chunks/{index-DWAqdQ--.js → index-3yyF237r.js} +464 -223
- package/dist/_chunks/index-3yyF237r.js.map +1 -0
- package/dist/_chunks/{index-BYDzOiHE.mjs → index-B0NijiBB.mjs} +457 -215
- package/dist/_chunks/index-B0NijiBB.mjs.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/utils/clean.d.ts +4 -0
- package/dist/admin/src/utils/schemas.d.ts +1 -0
- package/dist/server/index.js +414 -482
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +415 -482
- 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 -13
- package/dist/_chunks/SettingsPage-CG_qq0Tx.js.map +0 -1
- package/dist/_chunks/SettingsPage-DNucKxbi.mjs.map +0 -1
- package/dist/_chunks/en-18tWw4P6.mjs.map +0 -1
- package/dist/_chunks/en-Kv6y9zPQ.js.map +0 -1
- package/dist/_chunks/index-BYDzOiHE.mjs.map +0 -1
- package/dist/_chunks/index-DWAqdQ--.js.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,
|
410
|
-
|
411
|
-
return null;
|
412
|
-
}
|
413
|
-
const currentLocale = query.plugins?.i18n?.locale || locales.find((loc) => loc.isDefault)?.code;
|
581
|
+
}, [handleSelect, hasI18n, locales, currentDesiredLocale]);
|
582
|
+
const currentLocale = Array.isArray(locales) ? locales.find((locale) => locale.code === currentDesiredLocale) : void 0;
|
414
583
|
const allCurrentLocales = [
|
415
|
-
{ status: getDocumentStatus(document, meta), locale: currentLocale },
|
584
|
+
{ status: getDocumentStatus(document, meta), locale: currentLocale?.code },
|
416
585
|
...meta?.availableLocales ?? []
|
417
586
|
];
|
587
|
+
if (!hasI18n || !Array.isArray(locales) || locales.length === 0) {
|
588
|
+
return null;
|
589
|
+
}
|
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,43 @@ const DeleteLocaleAction = ({
|
|
525
800
|
}
|
526
801
|
};
|
527
802
|
};
|
528
|
-
const
|
803
|
+
const BulkLocaleAction = ({
|
529
804
|
document: baseDocument,
|
530
805
|
documentId,
|
531
806
|
model,
|
532
|
-
collectionType
|
807
|
+
collectionType,
|
808
|
+
action
|
533
809
|
}) => {
|
534
810
|
const baseLocale = baseDocument?.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();
|
819
|
+
const [isDraftRelationConfirmationOpen, setIsDraftRelationConfirmationOpen] = React.useState(false);
|
820
|
+
const { publishMany: publishManyAction, unpublishMany: unpublishManyAction } = unstable_useDocumentActions();
|
545
821
|
const {
|
546
822
|
document,
|
547
823
|
meta: documentMeta,
|
548
824
|
schema,
|
549
825
|
validate
|
550
|
-
} = unstable_useDocument(
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
826
|
+
} = unstable_useDocument(
|
827
|
+
{
|
828
|
+
model,
|
829
|
+
collectionType,
|
830
|
+
documentId,
|
831
|
+
params: {
|
832
|
+
locale: baseLocale
|
833
|
+
}
|
834
|
+
},
|
835
|
+
{
|
836
|
+
skip: !hasI18n || !baseLocale
|
556
837
|
}
|
557
|
-
|
558
|
-
const { data: localesMetadata = [] } = useGetLocalesQuery();
|
838
|
+
);
|
839
|
+
const { data: localesMetadata = [] } = useGetLocalesQuery(hasI18n ? void 0 : skipToken);
|
559
840
|
const headers = [
|
560
841
|
{
|
561
842
|
label: formatMessage({
|
@@ -604,12 +885,19 @@ const BulkLocalePublishAction = ({
|
|
604
885
|
}, {});
|
605
886
|
return [rowsFromMeta, errors];
|
606
887
|
}, [document, documentMeta?.availableLocales, validate]);
|
607
|
-
const
|
608
|
-
|
888
|
+
const isBulkPublish = action === "bulk-publish";
|
889
|
+
const localesForAction = selectedRows.reduce((acc, selectedRow) => {
|
890
|
+
const isValidLocale = (
|
891
|
+
// Validation errors are irrelevant if we are trying to unpublish
|
892
|
+
!isBulkPublish || !Object.keys(validationErrors).includes(selectedRow.locale)
|
893
|
+
);
|
894
|
+
const shouldAddLocale = isBulkPublish ? selectedRow.status !== "published" && isValidLocale : selectedRow.status !== "draft" && isValidLocale;
|
895
|
+
if (shouldAddLocale) {
|
609
896
|
acc.push(selectedRow.locale);
|
610
897
|
}
|
611
898
|
return acc;
|
612
899
|
}, []);
|
900
|
+
const enableDraftRelationsCount = false;
|
613
901
|
const {
|
614
902
|
data: draftRelationsCount = 0,
|
615
903
|
isLoading: isDraftRelationsLoading,
|
@@ -618,10 +906,10 @@ const BulkLocalePublishAction = ({
|
|
618
906
|
{
|
619
907
|
model,
|
620
908
|
documentIds: [documentId],
|
621
|
-
locale:
|
909
|
+
locale: localesForAction
|
622
910
|
},
|
623
911
|
{
|
624
|
-
skip: !
|
912
|
+
skip: !enableDraftRelationsCount
|
625
913
|
}
|
626
914
|
);
|
627
915
|
React.useEffect(() => {
|
@@ -647,23 +935,32 @@ const BulkLocalePublishAction = ({
|
|
647
935
|
documentIds: [documentId],
|
648
936
|
params: {
|
649
937
|
...params,
|
650
|
-
locale:
|
938
|
+
locale: localesForAction
|
939
|
+
}
|
940
|
+
});
|
941
|
+
setSelectedRows([]);
|
942
|
+
};
|
943
|
+
const unpublish = async () => {
|
944
|
+
await unpublishManyAction({
|
945
|
+
model,
|
946
|
+
documentIds: [documentId],
|
947
|
+
params: {
|
948
|
+
...params,
|
949
|
+
locale: localesForAction
|
651
950
|
}
|
652
951
|
});
|
653
952
|
setSelectedRows([]);
|
654
953
|
};
|
655
954
|
const handleAction = async () => {
|
656
955
|
if (draftRelationsCount > 0) {
|
657
|
-
|
658
|
-
} else {
|
956
|
+
setIsDraftRelationConfirmationOpen(true);
|
957
|
+
} else if (isBulkPublish) {
|
659
958
|
await publish();
|
959
|
+
} else {
|
960
|
+
await unpublish();
|
660
961
|
}
|
661
962
|
};
|
662
|
-
|
663
|
-
if (isUnpublish) {
|
664
|
-
console.warn(["I18N"], "Bulk locale unpublish modal not implemented");
|
665
|
-
}
|
666
|
-
if (isConfirmationOpen) {
|
963
|
+
if (isDraftRelationConfirmationOpen) {
|
667
964
|
return {
|
668
965
|
label: formatMessage({
|
669
966
|
id: "app.components.ConfirmDialog.title",
|
@@ -672,11 +969,11 @@ const BulkLocalePublishAction = ({
|
|
672
969
|
variant: "danger",
|
673
970
|
dialog: {
|
674
971
|
onCancel: () => {
|
675
|
-
|
972
|
+
setIsDraftRelationConfirmationOpen(false);
|
676
973
|
},
|
677
974
|
onConfirm: async () => {
|
678
975
|
await publish();
|
679
|
-
|
976
|
+
setIsDraftRelationConfirmationOpen(false);
|
680
977
|
},
|
681
978
|
type: "dialog",
|
682
979
|
title: formatMessage({
|
@@ -686,27 +983,32 @@ const BulkLocalePublishAction = ({
|
|
686
983
|
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "center", gap: 2, children: [
|
687
984
|
/* @__PURE__ */ jsx(WarningCircle, { width: "2.4rem", height: "2.4rem", fill: "danger600" }),
|
688
985
|
/* @__PURE__ */ jsx(Typography, { textAlign: "center", children: formatMessage({
|
689
|
-
id: "
|
690
|
-
defaultMessage: "
|
986
|
+
id: getTranslation("CMEditViewBulkLocale.draft-relation-warning"),
|
987
|
+
defaultMessage: "Some locales are related to draft entries. Publishing them could leave broken links in your app."
|
988
|
+
}) }),
|
989
|
+
/* @__PURE__ */ jsx(Typography, { textAlign: "center", children: formatMessage({
|
990
|
+
id: getTranslation("CMEditViewBulkLocale.continue-confirmation"),
|
991
|
+
defaultMessage: "Are you sure you want to continue?"
|
691
992
|
}) })
|
692
993
|
] })
|
693
994
|
}
|
694
995
|
};
|
695
996
|
}
|
997
|
+
const hasPermission = selectedRows.map(({ locale }) => locale).every((locale) => canPublish.includes(locale));
|
696
998
|
return {
|
697
999
|
label: formatMessage({
|
698
|
-
id: getTranslation("
|
699
|
-
defaultMessage: "Publish Multiple Locales
|
1000
|
+
id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
|
1001
|
+
defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
|
700
1002
|
}),
|
701
|
-
|
702
|
-
|
1003
|
+
variant: isBulkPublish ? "secondary" : "danger",
|
1004
|
+
icon: isBulkPublish ? /* @__PURE__ */ jsx(ListPlus, {}) : /* @__PURE__ */ jsx(Cross, {}),
|
1005
|
+
disabled: isOnPublishedTab || canPublish.length === 0,
|
703
1006
|
position: ["panel"],
|
704
|
-
variant: "secondary",
|
705
1007
|
dialog: {
|
706
1008
|
type: "modal",
|
707
1009
|
title: formatMessage({
|
708
|
-
id: getTranslation("
|
709
|
-
defaultMessage: "Publish Multiple Locales
|
1010
|
+
id: getTranslation(`CMEditViewBulkLocale.${isBulkPublish ? "publish" : "unpublish"}-title`),
|
1011
|
+
defaultMessage: `${isBulkPublish ? "Publish" : "Unpublish"} Multiple Locales`
|
710
1012
|
}),
|
711
1013
|
content: () => {
|
712
1014
|
return /* @__PURE__ */ jsx(
|
@@ -725,28 +1027,35 @@ const BulkLocalePublishAction = ({
|
|
725
1027
|
validationErrors,
|
726
1028
|
headers,
|
727
1029
|
rows,
|
728
|
-
localesMetadata
|
1030
|
+
localesMetadata,
|
1031
|
+
action: action ?? "bulk-publish"
|
729
1032
|
}
|
730
1033
|
)
|
731
1034
|
}
|
732
1035
|
);
|
733
1036
|
},
|
734
|
-
footer: () => /* @__PURE__ */ jsx(
|
735
|
-
Button
|
1037
|
+
footer: () => /* @__PURE__ */ jsx(Modal.Footer, { justifyContent: "flex-end", children: /* @__PURE__ */ jsx(
|
1038
|
+
Button,
|
736
1039
|
{
|
737
1040
|
loading: isDraftRelationsLoading,
|
738
|
-
disabled:
|
1041
|
+
disabled: !hasPermission || localesForAction.length === 0,
|
739
1042
|
variant: "default",
|
740
1043
|
onClick: handleAction,
|
741
1044
|
children: formatMessage({
|
742
|
-
id: "app.utils.publish",
|
743
|
-
defaultMessage: "Publish"
|
1045
|
+
id: isBulkPublish ? "app.utils.publish" : "app.utils.unpublish",
|
1046
|
+
defaultMessage: isBulkPublish ? "Publish" : "Unpublish"
|
744
1047
|
})
|
745
1048
|
}
|
746
1049
|
) })
|
747
1050
|
}
|
748
1051
|
};
|
749
1052
|
};
|
1053
|
+
const BulkLocalePublishAction = (props) => {
|
1054
|
+
return BulkLocaleAction({ action: "bulk-publish", ...props });
|
1055
|
+
};
|
1056
|
+
const BulkLocaleUnpublishAction = (props) => {
|
1057
|
+
return BulkLocaleAction({ action: "bulk-unpublish", ...props });
|
1058
|
+
};
|
750
1059
|
const StyledTrash = styled(Trash)`
|
751
1060
|
path {
|
752
1061
|
fill: currentColor;
|
@@ -803,13 +1112,6 @@ const UnpublishModalAdditionalInfo = () => {
|
|
803
1112
|
}
|
804
1113
|
) });
|
805
1114
|
};
|
806
|
-
const Initializer = ({ setPlugin }) => {
|
807
|
-
const setPluginRef = React.useRef(setPlugin);
|
808
|
-
React.useEffect(() => {
|
809
|
-
setPluginRef.current(pluginId);
|
810
|
-
}, []);
|
811
|
-
return null;
|
812
|
-
};
|
813
1115
|
const LocalePicker = () => {
|
814
1116
|
const { formatMessage } = useIntl();
|
815
1117
|
const [{ query }, setQuery] = useQueryParams();
|
@@ -869,7 +1171,7 @@ const PERMISSIONS = {
|
|
869
1171
|
read: [{ action: "plugin::i18n.locale.read", subject: null }]
|
870
1172
|
};
|
871
1173
|
const mutateEditViewHook = ({ layout }) => {
|
872
|
-
if ("i18n" in layout.options
|
1174
|
+
if (!("i18n" in layout.options) || typeof layout.options.i18n === "object" && layout.options.i18n !== null && "localized" in layout.options.i18n && !layout.options.i18n.localized) {
|
873
1175
|
return { layout };
|
874
1176
|
}
|
875
1177
|
const components = Object.entries(layout.components).reduce(
|
@@ -915,7 +1217,7 @@ const doesFieldHaveI18nPluginOpt = (pluginOpts) => {
|
|
915
1217
|
const LabelAction = ({ title, icon }) => {
|
916
1218
|
const { formatMessage } = useIntl();
|
917
1219
|
return /* @__PURE__ */ jsxs(Span, { tag: "span", children: [
|
918
|
-
/* @__PURE__ */ jsx(VisuallyHidden, { tag: "span", children:
|
1220
|
+
/* @__PURE__ */ jsx(VisuallyHidden, { tag: "span", children: formatMessage(title) }),
|
919
1221
|
React.cloneElement(icon, {
|
920
1222
|
"aria-hidden": true,
|
921
1223
|
focusable: false
|
@@ -950,13 +1252,7 @@ const LocaleListCell = ({
|
|
950
1252
|
}
|
951
1253
|
});
|
952
1254
|
const { locale: language } = useIntl();
|
953
|
-
const [visible, setVisible] = React.useState(false);
|
954
|
-
const buttonRef = React.useRef(null);
|
955
1255
|
const { data: locales = [] } = useGetLocalesQuery();
|
956
|
-
const handleTogglePopover = (e) => {
|
957
|
-
e.stopPropagation();
|
958
|
-
setVisible((prev) => !prev);
|
959
|
-
};
|
960
1256
|
const formatter = useCollator(language, {
|
961
1257
|
sensitivity: "base"
|
962
1258
|
});
|
@@ -978,64 +1274,14 @@ const LocaleListCell = ({
|
|
978
1274
|
}
|
979
1275
|
return locale.name;
|
980
1276
|
}).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
|
-
)
|
1277
|
+
return /* @__PURE__ */ jsxs(Popover.Root, { children: [
|
1278
|
+
/* @__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: [
|
1279
|
+
/* @__PURE__ */ jsx(Typography, { textColor: "neutral800", ellipsis: true, marginRight: 2, children: localesForDocument.join(", ") }),
|
1280
|
+
/* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(CaretDown, { width: "1.2rem", height: "1.2rem" }) })
|
1281
|
+
] }) }) }),
|
1282
|
+
/* @__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
1283
|
] });
|
1007
1284
|
};
|
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
1285
|
const addColumnToTableHook = ({ displayedHeaders, layout }) => {
|
1040
1286
|
const { options } = layout;
|
1041
1287
|
const isFieldLocalized = doesPluginOptionsHaveI18nLocalized(options) ? options.i18n.localized : false;
|
@@ -1161,9 +1407,6 @@ const localeMiddleware = (ctx) => (next) => (permissions) => {
|
|
1161
1407
|
return next(revisedPermissions);
|
1162
1408
|
};
|
1163
1409
|
const prefixPluginTranslations = (trad, pluginId2) => {
|
1164
|
-
if (!pluginId2) {
|
1165
|
-
throw new TypeError("pluginId can't be empty");
|
1166
|
-
}
|
1167
1410
|
return Object.keys(trad).reduce((acc, current) => {
|
1168
1411
|
acc[`${pluginId2}.${current}`] = trad[current];
|
1169
1412
|
return acc;
|
@@ -1216,8 +1459,6 @@ const index = {
|
|
1216
1459
|
app.addRBACMiddleware([localeMiddleware]);
|
1217
1460
|
app.registerPlugin({
|
1218
1461
|
id: pluginId,
|
1219
|
-
initializer: Initializer,
|
1220
|
-
isReady: false,
|
1221
1462
|
name: pluginId
|
1222
1463
|
});
|
1223
1464
|
},
|
@@ -1235,11 +1476,11 @@ const index = {
|
|
1235
1476
|
},
|
1236
1477
|
id: "internationalization",
|
1237
1478
|
to: "internationalization",
|
1238
|
-
Component: () => import("./SettingsPage-
|
1479
|
+
Component: () => import("./SettingsPage-BAx9nmep.mjs").then((mod) => ({ default: mod.ProtectedSettingsPage })),
|
1239
1480
|
permissions: PERMISSIONS.accessMain
|
1240
1481
|
});
|
1241
1482
|
const contentManager = app.getPlugin("content-manager");
|
1242
|
-
contentManager.apis.addDocumentHeaderAction([LocalePickerAction]);
|
1483
|
+
contentManager.apis.addDocumentHeaderAction([LocalePickerAction, FillFromAnotherLocaleAction]);
|
1243
1484
|
contentManager.apis.addDocumentAction((actions) => {
|
1244
1485
|
const indexOfDeleteAction = actions.findIndex((action) => action.type === "delete");
|
1245
1486
|
actions.splice(indexOfDeleteAction, 0, DeleteLocaleAction);
|
@@ -1247,6 +1488,7 @@ const index = {
|
|
1247
1488
|
});
|
1248
1489
|
contentManager.apis.addDocumentAction((actions) => {
|
1249
1490
|
actions.splice(2, 0, BulkLocalePublishAction);
|
1491
|
+
actions.splice(5, 0, BulkLocaleUnpublishAction);
|
1250
1492
|
return actions;
|
1251
1493
|
});
|
1252
1494
|
contentManager.injectComponent("listView", "actions", {
|
@@ -1352,7 +1594,7 @@ const index = {
|
|
1352
1594
|
async registerTrads({ locales }) {
|
1353
1595
|
const importedTrads = await Promise.all(
|
1354
1596
|
locales.map((locale) => {
|
1355
|
-
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/de.json": () => import("./de-9eCAqqrB.mjs"), "./translations/dk.json": () => import("./dk-2qBjxt-P.mjs"), "./translations/en.json": () => import("./en-
|
1597
|
+
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/de.json": () => import("./de-9eCAqqrB.mjs"), "./translations/dk.json": () => import("./dk-2qBjxt-P.mjs"), "./translations/en.json": () => import("./en-DlXfy6Gy.mjs"), "./translations/es.json": () => import("./es-DlmMVaBG.mjs"), "./translations/fr.json": () => import("./fr-3S6ke71d.mjs"), "./translations/ko.json": () => import("./ko-qTjQ8IMw.mjs"), "./translations/pl.json": () => import("./pl-B67TSHqT.mjs"), "./translations/ru.json": () => import("./ru-hagMa57T.mjs"), "./translations/tr.json": () => import("./tr-Dw_jmkG-.mjs"), "./translations/zh-Hans.json": () => import("./zh-Hans-Dyc-aR-h.mjs"), "./translations/zh.json": () => import("./zh-57YM4amO.mjs") }), `./translations/${locale}.json`, 3).then(({ default: data }) => {
|
1356
1598
|
return {
|
1357
1599
|
data: prefixPluginTranslations(data, pluginId),
|
1358
1600
|
locale
|
@@ -1378,4 +1620,4 @@ export {
|
|
1378
1620
|
index as i,
|
1379
1621
|
useCreateLocaleMutation as u
|
1380
1622
|
};
|
1381
|
-
//# sourceMappingURL=index-
|
1623
|
+
//# sourceMappingURL=index-B0NijiBB.mjs.map
|