@strapi/content-manager 0.0.0-experimental.545ccead2ee1717bbc7ab950455dbb0ddb9924a3 → 0.0.0-experimental.5788c38836be65c0321a2dcadbdf44f04b798e8a
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/dist/_chunks/{ComponentConfigurationPage-Bqgx7Mes.js → ComponentConfigurationPage-B42mQr1K.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-Bqgx7Mes.js.map → ComponentConfigurationPage-B42mQr1K.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-B1bIXVuX.mjs → ComponentConfigurationPage-D1YuKq8j.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-B1bIXVuX.mjs.map → ComponentConfigurationPage-D1YuKq8j.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-ZO0vOO8q.mjs → EditConfigurationPage-C9yiwgI_.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-ZO0vOO8q.mjs.map → EditConfigurationPage-C9yiwgI_.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-BFEwvdMW.js → EditConfigurationPage-NC89F29V.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-BFEwvdMW.js.map → EditConfigurationPage-NC89F29V.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-DA95Ha6J.js → EditViewPage-DYDpe5Wi.js} +30 -9
- package/dist/_chunks/EditViewPage-DYDpe5Wi.js.map +1 -0
- package/dist/_chunks/{EditViewPage-DlLEyUL6.mjs → EditViewPage-k8UcfVwt.mjs} +30 -9
- package/dist/_chunks/EditViewPage-k8UcfVwt.mjs.map +1 -0
- package/dist/_chunks/{Field-Dq7bDnuh.mjs → Field-BLL5lknV.mjs} +170 -102
- package/dist/_chunks/Field-BLL5lknV.mjs.map +1 -0
- package/dist/_chunks/{Field-CnK8dO8N.js → Field-Crhugun2.js} +172 -104
- package/dist/_chunks/Field-Crhugun2.js.map +1 -0
- package/dist/_chunks/{Form-BpiR4piS.js → Form-DUU19g6M.js} +35 -16
- package/dist/_chunks/Form-DUU19g6M.js.map +1 -0
- package/dist/_chunks/{Form-B_JE0dbz.mjs → Form-UHu2eOuG.mjs} +35 -16
- package/dist/_chunks/Form-UHu2eOuG.mjs.map +1 -0
- package/dist/_chunks/{History-CBNGU7a-.mjs → History-CpxkZXS3.mjs} +21 -11
- package/dist/_chunks/History-CpxkZXS3.mjs.map +1 -0
- package/dist/_chunks/{History-DdIstl8b.js → History-CyA8tvJZ.js} +21 -11
- package/dist/_chunks/History-CyA8tvJZ.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-5dr4qpue.mjs → ListConfigurationPage-OUwV8QF1.mjs} +14 -4
- package/dist/_chunks/ListConfigurationPage-OUwV8QF1.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DkKRparB.js → ListConfigurationPage-pJV7aG2V.js} +14 -4
- package/dist/_chunks/ListConfigurationPage-pJV7aG2V.js.map +1 -0
- package/dist/_chunks/{ListViewPage-wE0lXqoD.js → ListViewPage-BIT0M8VG.js} +49 -40
- package/dist/_chunks/ListViewPage-BIT0M8VG.js.map +1 -0
- package/dist/_chunks/{ListViewPage-DecLrYV6.mjs → ListViewPage-BOnhCGkE.mjs} +47 -38
- package/dist/_chunks/ListViewPage-BOnhCGkE.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-CiIcfYsd.mjs → NoContentTypePage-CwjlHGTn.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-CiIcfYsd.mjs.map → NoContentTypePage-CwjlHGTn.mjs.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-DEKR6tf9.js → NoContentTypePage-uIBsBUmH.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-DEKR6tf9.js.map → NoContentTypePage-uIBsBUmH.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-DmNfF2Bb.js → NoPermissionsPage-C8wkEaOF.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-DmNfF2Bb.js.map → NoPermissionsPage-C8wkEaOF.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-CM5UD8ee.mjs → NoPermissionsPage-CcWbyT_z.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-CM5UD8ee.mjs.map → NoPermissionsPage-CcWbyT_z.mjs.map} +1 -1
- package/dist/_chunks/{Relations-L0xYRoSQ.js → Relations-CwRu_eZv.js} +33 -24
- package/dist/_chunks/Relations-CwRu_eZv.js.map +1 -0
- package/dist/_chunks/{Relations-Dqz0C1fz.mjs → Relations-wIdWJnA9.mjs} +33 -24
- package/dist/_chunks/Relations-wIdWJnA9.mjs.map +1 -0
- package/dist/_chunks/{en-uOUIxfcQ.js → en-Bm0D0IWz.js} +13 -12
- package/dist/_chunks/{en-uOUIxfcQ.js.map → en-Bm0D0IWz.js.map} +1 -1
- package/dist/_chunks/{en-BrCTWlZv.mjs → en-DKV44jRb.mjs} +13 -12
- package/dist/_chunks/{en-BrCTWlZv.mjs.map → en-DKV44jRb.mjs.map} +1 -1
- package/dist/_chunks/{index-DyvUPg1a.js → index-BO-T2BdP.js} +693 -524
- package/dist/_chunks/index-BO-T2BdP.js.map +1 -0
- package/dist/_chunks/{index-BSn97i8U.mjs → index-BQ8DxaCa.mjs} +713 -544
- package/dist/_chunks/index-BQ8DxaCa.mjs.map +1 -0
- package/dist/_chunks/{layout-TPqF2oJ5.js → layout-BTB1_M8g.js} +21 -8
- package/dist/_chunks/layout-BTB1_M8g.js.map +1 -0
- package/dist/_chunks/{layout-DPaHUusj.mjs → layout-N63eyE5E.mjs} +22 -9
- package/dist/_chunks/layout-N63eyE5E.mjs.map +1 -0
- package/dist/_chunks/{relations-Ck7-ecDT.mjs → relations-Bh9r0CVE.mjs} +2 -2
- package/dist/_chunks/{relations-Ck7-ecDT.mjs.map → relations-Bh9r0CVE.mjs.map} +1 -1
- package/dist/_chunks/{relations-BWYS9gkn.js → relations-C9AQuM2z.js} +2 -2
- package/dist/_chunks/{relations-BWYS9gkn.js.map → relations-C9AQuM2z.js.map} +1 -1
- package/dist/_chunks/{usePrev-B9w_-eYc.js → useDebounce-CtcjDB3L.js} +14 -1
- package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs +29 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -0
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +5 -4
- package/dist/admin/src/exports.d.ts +1 -1
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +32 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +4 -48
- package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
- package/dist/admin/src/services/api.d.ts +1 -1
- package/dist/admin/src/services/components.d.ts +2 -2
- package/dist/admin/src/services/contentTypes.d.ts +3 -3
- package/dist/admin/src/services/documents.d.ts +19 -17
- package/dist/admin/src/services/init.d.ts +1 -1
- package/dist/admin/src/services/relations.d.ts +2 -2
- package/dist/admin/src/services/uid.d.ts +3 -3
- package/dist/admin/src/utils/validation.d.ts +4 -1
- package/dist/server/index.js +195 -117
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +196 -118
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/controllers/relations.d.ts.map +1 -1
- package/dist/server/src/controllers/uid.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/dimensions.d.ts +4 -2
- package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -1
- package/dist/server/src/history/services/history.d.ts.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
- package/dist/server/src/history/services/utils.d.ts +2 -1
- package/dist/server/src/history/services/utils.d.ts.map +1 -1
- package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/permission-checker.d.ts.map +1 -1
- package/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/dist/shared/contracts/collection-types.d.ts +3 -1
- package/dist/shared/contracts/collection-types.d.ts.map +1 -1
- package/package.json +11 -11
- package/dist/_chunks/EditViewPage-DA95Ha6J.js.map +0 -1
- package/dist/_chunks/EditViewPage-DlLEyUL6.mjs.map +0 -1
- package/dist/_chunks/Field-CnK8dO8N.js.map +0 -1
- package/dist/_chunks/Field-Dq7bDnuh.mjs.map +0 -1
- package/dist/_chunks/Form-B_JE0dbz.mjs.map +0 -1
- package/dist/_chunks/Form-BpiR4piS.js.map +0 -1
- package/dist/_chunks/History-CBNGU7a-.mjs.map +0 -1
- package/dist/_chunks/History-DdIstl8b.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-5dr4qpue.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DkKRparB.js.map +0 -1
- package/dist/_chunks/ListViewPage-DecLrYV6.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-wE0lXqoD.js.map +0 -1
- package/dist/_chunks/Relations-Dqz0C1fz.mjs.map +0 -1
- package/dist/_chunks/Relations-L0xYRoSQ.js.map +0 -1
- package/dist/_chunks/index-BSn97i8U.mjs.map +0 -1
- package/dist/_chunks/index-DyvUPg1a.js.map +0 -1
- package/dist/_chunks/layout-DPaHUusj.mjs.map +0 -1
- package/dist/_chunks/layout-TPqF2oJ5.js.map +0 -1
- package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
- package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
- package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
- package/strapi-server.js +0 -3
@@ -1,16 +1,16 @@
|
|
1
|
-
import {
|
1
|
+
import { More, Cross, WarningCircle, ListPlus, Pencil, Trash, Check, CrossCircle, CheckCircle, ArrowsCounterClockwise, ChevronRight, Duplicate, ClockCounterClockwise, Feather } from "@strapi/icons";
|
2
2
|
import { jsx, Fragment, jsxs } from "react/jsx-runtime";
|
3
|
-
import { useStrapiApp, createContext, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, getYupValidationErrors,
|
3
|
+
import { useStrapiApp, createContext, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, useQueryParams, getYupValidationErrors, useForm, useTracking, useGuidedTour, BackButton, DescriptionComponentRenderer, useTable, Table } from "@strapi/admin/strapi-admin";
|
4
4
|
import * as React from "react";
|
5
5
|
import { lazy } from "react";
|
6
|
-
import { Button, Menu, VisuallyHidden, Flex,
|
6
|
+
import { Button, Menu, VisuallyHidden, Flex, Typography, Dialog, Modal, Radio, Status, Box, SingleSelect, SingleSelectOption, IconButton, Loader, Tooltip, LinkButton } from "@strapi/design-system";
|
7
7
|
import { useIntl } from "react-intl";
|
8
|
-
import { useParams,
|
9
|
-
import { styled } from "styled-components";
|
8
|
+
import { useParams, useNavigate, Navigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
|
10
9
|
import * as yup from "yup";
|
11
10
|
import { ValidationError } from "yup";
|
12
11
|
import pipe from "lodash/fp/pipe";
|
13
12
|
import { intervalToDuration, isPast } from "date-fns";
|
13
|
+
import { styled } from "styled-components";
|
14
14
|
import { stringify } from "qs";
|
15
15
|
import { createSlice, combineReducers } from "@reduxjs/toolkit";
|
16
16
|
const __variableDynamicImportRuntimeHelper = (glob, path) => {
|
@@ -158,7 +158,8 @@ const contentManagerApi = adminApi.enhanceEndpoints({
|
|
158
158
|
"Document",
|
159
159
|
"InitialData",
|
160
160
|
"HistoryVersion",
|
161
|
-
"Relations"
|
161
|
+
"Relations",
|
162
|
+
"UidAvailability"
|
162
163
|
]
|
163
164
|
});
|
164
165
|
const documentApi = contentManagerApi.injectEndpoints({
|
@@ -172,7 +173,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
172
173
|
params: query
|
173
174
|
}
|
174
175
|
}),
|
175
|
-
invalidatesTags: (_result,
|
176
|
+
invalidatesTags: (_result, error, { model }) => {
|
177
|
+
if (error) {
|
178
|
+
return [];
|
179
|
+
}
|
180
|
+
return [{ type: "Document", id: `${model}_LIST` }];
|
181
|
+
}
|
176
182
|
}),
|
177
183
|
cloneDocument: builder.mutation({
|
178
184
|
query: ({ model, sourceId, data, params }) => ({
|
@@ -183,7 +189,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
183
189
|
params
|
184
190
|
}
|
185
191
|
}),
|
186
|
-
invalidatesTags: (_result, _error, { model }) => [
|
192
|
+
invalidatesTags: (_result, _error, { model }) => [
|
193
|
+
{ type: "Document", id: `${model}_LIST` },
|
194
|
+
{ type: "UidAvailability", id: model }
|
195
|
+
]
|
187
196
|
}),
|
188
197
|
/**
|
189
198
|
* Creates a new collection-type document. This should ONLY be used for collection-types.
|
@@ -200,7 +209,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
200
209
|
}),
|
201
210
|
invalidatesTags: (result, _error, { model }) => [
|
202
211
|
{ type: "Document", id: `${model}_LIST` },
|
203
|
-
"Relations"
|
212
|
+
"Relations",
|
213
|
+
{ type: "UidAvailability", id: model }
|
204
214
|
]
|
205
215
|
}),
|
206
216
|
deleteDocument: builder.mutation({
|
@@ -241,7 +251,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
241
251
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
242
252
|
},
|
243
253
|
{ type: "Document", id: `${model}_LIST` },
|
244
|
-
"Relations"
|
254
|
+
"Relations",
|
255
|
+
{ type: "UidAvailability", id: model }
|
245
256
|
];
|
246
257
|
}
|
247
258
|
}),
|
@@ -259,6 +270,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
259
270
|
}),
|
260
271
|
providesTags: (result, _error, arg) => {
|
261
272
|
return [
|
273
|
+
{ type: "Document", id: `ALL_LIST` },
|
262
274
|
{ type: "Document", id: `${arg.model}_LIST` },
|
263
275
|
...result?.results.map(({ documentId }) => ({
|
264
276
|
type: "Document",
|
@@ -297,6 +309,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
297
309
|
{
|
298
310
|
type: "Document",
|
299
311
|
id: collectionType !== SINGLE_TYPES ? `${model}_${result && "documentId" in result ? result.documentId : documentId}` : model
|
312
|
+
},
|
313
|
+
// Make it easy to invalidate all individual documents queries for a model
|
314
|
+
{
|
315
|
+
type: "Document",
|
316
|
+
id: `${model}_ALL_ITEMS`
|
300
317
|
}
|
301
318
|
];
|
302
319
|
}
|
@@ -360,8 +377,21 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
360
377
|
type: "Document",
|
361
378
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
362
379
|
},
|
363
|
-
"Relations"
|
380
|
+
"Relations",
|
381
|
+
{ type: "UidAvailability", id: model }
|
364
382
|
];
|
383
|
+
},
|
384
|
+
async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
|
385
|
+
const patchResult = dispatch(
|
386
|
+
documentApi.util.updateQueryData("getDocument", patch, (draft) => {
|
387
|
+
Object.assign(draft.data, data);
|
388
|
+
})
|
389
|
+
);
|
390
|
+
try {
|
391
|
+
await queryFulfilled;
|
392
|
+
} catch {
|
393
|
+
patchResult.undo();
|
394
|
+
}
|
365
395
|
}
|
366
396
|
}),
|
367
397
|
unpublishDocument: builder.mutation({
|
@@ -431,20 +461,36 @@ const buildValidParams = (query) => {
|
|
431
461
|
const isBaseQueryError = (error) => {
|
432
462
|
return error.name !== void 0;
|
433
463
|
};
|
434
|
-
const
|
464
|
+
const arrayValidator = (options) => ({
|
465
|
+
message: translatedErrors.required,
|
466
|
+
test(value) {
|
467
|
+
if (options.status === "draft") {
|
468
|
+
return true;
|
469
|
+
}
|
470
|
+
if (!value) {
|
471
|
+
return false;
|
472
|
+
}
|
473
|
+
if (Array.isArray(value) && value.length === 0) {
|
474
|
+
return false;
|
475
|
+
}
|
476
|
+
return true;
|
477
|
+
}
|
478
|
+
});
|
479
|
+
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
435
480
|
const createModelSchema = (attributes2) => yup.object().shape(
|
436
481
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
437
482
|
if (DOCUMENT_META_FIELDS.includes(name)) {
|
438
483
|
return acc;
|
439
484
|
}
|
440
485
|
const validations = [
|
486
|
+
addNullableValidation,
|
441
487
|
addRequiredValidation,
|
442
488
|
addMinLengthValidation,
|
443
489
|
addMaxLengthValidation,
|
444
490
|
addMinValidation,
|
445
491
|
addMaxValidation,
|
446
492
|
addRegexValidation
|
447
|
-
].map((fn) => fn(attribute));
|
493
|
+
].map((fn) => fn(attribute, options));
|
448
494
|
const transformSchema = pipe(...validations);
|
449
495
|
switch (attribute.type) {
|
450
496
|
case "component": {
|
@@ -454,12 +500,12 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
454
500
|
...acc,
|
455
501
|
[name]: transformSchema(
|
456
502
|
yup.array().of(createModelSchema(attributes3).nullable(false))
|
457
|
-
)
|
503
|
+
).test(arrayValidator(options))
|
458
504
|
};
|
459
505
|
} else {
|
460
506
|
return {
|
461
507
|
...acc,
|
462
|
-
[name]: transformSchema(createModelSchema(attributes3))
|
508
|
+
[name]: transformSchema(createModelSchema(attributes3).nullable())
|
463
509
|
};
|
464
510
|
}
|
465
511
|
}
|
@@ -481,7 +527,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
481
527
|
}
|
482
528
|
)
|
483
529
|
)
|
484
|
-
)
|
530
|
+
).test(arrayValidator(options))
|
485
531
|
};
|
486
532
|
case "relation":
|
487
533
|
return {
|
@@ -493,7 +539,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
493
539
|
} else if (Array.isArray(value)) {
|
494
540
|
return yup.array().of(
|
495
541
|
yup.object().shape({
|
496
|
-
id: yup.
|
542
|
+
id: yup.number().required()
|
497
543
|
})
|
498
544
|
);
|
499
545
|
} else if (typeof value === "object") {
|
@@ -545,6 +591,14 @@ const createAttributeSchema = (attribute) => {
|
|
545
591
|
if (!value || typeof value === "string" && value.length === 0) {
|
546
592
|
return true;
|
547
593
|
}
|
594
|
+
if (typeof value === "object") {
|
595
|
+
try {
|
596
|
+
JSON.stringify(value);
|
597
|
+
return true;
|
598
|
+
} catch (err) {
|
599
|
+
return false;
|
600
|
+
}
|
601
|
+
}
|
548
602
|
try {
|
549
603
|
JSON.parse(value);
|
550
604
|
return true;
|
@@ -563,13 +617,7 @@ const createAttributeSchema = (attribute) => {
|
|
563
617
|
return yup.mixed();
|
564
618
|
}
|
565
619
|
};
|
566
|
-
const
|
567
|
-
if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
|
568
|
-
return schema.min(1, translatedErrors.required);
|
569
|
-
}
|
570
|
-
if (attribute.required && attribute.type !== "relation") {
|
571
|
-
return schema.required(translatedErrors.required);
|
572
|
-
}
|
620
|
+
const nullableSchema = (schema) => {
|
573
621
|
return schema?.nullable ? schema.nullable() : (
|
574
622
|
// In some cases '.nullable' will not be available on the schema.
|
575
623
|
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
@@ -577,7 +625,22 @@ const addRequiredValidation = (attribute) => (schema) => {
|
|
577
625
|
schema
|
578
626
|
);
|
579
627
|
};
|
580
|
-
const
|
628
|
+
const addNullableValidation = () => (schema) => {
|
629
|
+
return nullableSchema(schema);
|
630
|
+
};
|
631
|
+
const addRequiredValidation = (attribute, options) => (schema) => {
|
632
|
+
if (options.status === "draft" || !attribute.required) {
|
633
|
+
return schema;
|
634
|
+
}
|
635
|
+
if (attribute.required && "required" in schema) {
|
636
|
+
return schema.required(translatedErrors.required);
|
637
|
+
}
|
638
|
+
return schema;
|
639
|
+
};
|
640
|
+
const addMinLengthValidation = (attribute, options) => (schema) => {
|
641
|
+
if (options.status === "draft") {
|
642
|
+
return schema;
|
643
|
+
}
|
581
644
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
582
645
|
return schema.min(attribute.minLength, {
|
583
646
|
...translatedErrors.minLength,
|
@@ -599,32 +662,13 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
599
662
|
}
|
600
663
|
return schema;
|
601
664
|
};
|
602
|
-
const addMinValidation = (attribute) => (schema) => {
|
603
|
-
if ("
|
665
|
+
const addMinValidation = (attribute, options) => (schema) => {
|
666
|
+
if (options.status === "draft") {
|
667
|
+
return schema;
|
668
|
+
}
|
669
|
+
if ("min" in attribute && "min" in schema) {
|
604
670
|
const min = toInteger(attribute.min);
|
605
|
-
if (
|
606
|
-
if (!attribute.required && "test" in schema && min) {
|
607
|
-
return schema.test(
|
608
|
-
"custom-min",
|
609
|
-
{
|
610
|
-
...translatedErrors.min,
|
611
|
-
values: {
|
612
|
-
min: attribute.min
|
613
|
-
}
|
614
|
-
},
|
615
|
-
(value) => {
|
616
|
-
if (!value) {
|
617
|
-
return true;
|
618
|
-
}
|
619
|
-
if (Array.isArray(value) && value.length === 0) {
|
620
|
-
return true;
|
621
|
-
}
|
622
|
-
return value.length >= min;
|
623
|
-
}
|
624
|
-
);
|
625
|
-
}
|
626
|
-
}
|
627
|
-
if ("min" in schema && min) {
|
671
|
+
if (min) {
|
628
672
|
return schema.min(min, {
|
629
673
|
...translatedErrors.min,
|
630
674
|
values: {
|
@@ -742,19 +786,115 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
|
|
742
786
|
}, {});
|
743
787
|
return componentsByKey;
|
744
788
|
};
|
745
|
-
const
|
789
|
+
const HOOKS = {
|
790
|
+
/**
|
791
|
+
* Hook that allows to mutate the displayed headers of the list view table
|
792
|
+
* @constant
|
793
|
+
* @type {string}
|
794
|
+
*/
|
795
|
+
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
796
|
+
/**
|
797
|
+
* Hook that allows to mutate the CM's collection types links pre-set filters
|
798
|
+
* @constant
|
799
|
+
* @type {string}
|
800
|
+
*/
|
801
|
+
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
802
|
+
/**
|
803
|
+
* Hook that allows to mutate the CM's edit view layout
|
804
|
+
* @constant
|
805
|
+
* @type {string}
|
806
|
+
*/
|
807
|
+
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
808
|
+
/**
|
809
|
+
* Hook that allows to mutate the CM's single types links pre-set filters
|
810
|
+
* @constant
|
811
|
+
* @type {string}
|
812
|
+
*/
|
813
|
+
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
814
|
+
};
|
815
|
+
const contentTypesApi = contentManagerApi.injectEndpoints({
|
816
|
+
endpoints: (builder) => ({
|
817
|
+
getContentTypeConfiguration: builder.query({
|
818
|
+
query: (uid) => ({
|
819
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
820
|
+
method: "GET"
|
821
|
+
}),
|
822
|
+
transformResponse: (response) => response.data,
|
823
|
+
providesTags: (_result, _error, uid) => [
|
824
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
825
|
+
{ type: "ContentTypeSettings", id: "LIST" }
|
826
|
+
]
|
827
|
+
}),
|
828
|
+
getAllContentTypeSettings: builder.query({
|
829
|
+
query: () => "/content-manager/content-types-settings",
|
830
|
+
transformResponse: (response) => response.data,
|
831
|
+
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
832
|
+
}),
|
833
|
+
updateContentTypeConfiguration: builder.mutation({
|
834
|
+
query: ({ uid, ...body }) => ({
|
835
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
836
|
+
method: "PUT",
|
837
|
+
data: body
|
838
|
+
}),
|
839
|
+
transformResponse: (response) => response.data,
|
840
|
+
invalidatesTags: (_result, _error, { uid }) => [
|
841
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
842
|
+
{ type: "ContentTypeSettings", id: "LIST" },
|
843
|
+
// Is this necessary?
|
844
|
+
{ type: "InitialData" }
|
845
|
+
]
|
846
|
+
})
|
847
|
+
})
|
848
|
+
});
|
849
|
+
const {
|
850
|
+
useGetContentTypeConfigurationQuery,
|
851
|
+
useGetAllContentTypeSettingsQuery,
|
852
|
+
useUpdateContentTypeConfigurationMutation
|
853
|
+
} = contentTypesApi;
|
854
|
+
const checkIfAttributeIsDisplayable = (attribute) => {
|
855
|
+
const { type } = attribute;
|
856
|
+
if (type === "relation") {
|
857
|
+
return !attribute.relation.toLowerCase().includes("morph");
|
858
|
+
}
|
859
|
+
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
860
|
+
};
|
861
|
+
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
862
|
+
if (!mainFieldName) {
|
863
|
+
return void 0;
|
864
|
+
}
|
865
|
+
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
866
|
+
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
867
|
+
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
868
|
+
);
|
869
|
+
return {
|
870
|
+
name: mainFieldName,
|
871
|
+
type: mainFieldType ?? "string"
|
872
|
+
};
|
873
|
+
};
|
874
|
+
const DEFAULT_SETTINGS = {
|
875
|
+
bulkable: false,
|
876
|
+
filterable: false,
|
877
|
+
searchable: false,
|
878
|
+
pagination: false,
|
879
|
+
defaultSortBy: "",
|
880
|
+
defaultSortOrder: "asc",
|
881
|
+
mainField: "id",
|
882
|
+
pageSize: 10
|
883
|
+
};
|
884
|
+
const useDocumentLayout = (model) => {
|
885
|
+
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
886
|
+
const [{ query }] = useQueryParams();
|
887
|
+
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
746
888
|
const { toggleNotification } = useNotification();
|
747
889
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
890
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
748
891
|
const {
|
749
|
-
|
750
|
-
isLoading:
|
751
|
-
|
752
|
-
|
753
|
-
} =
|
754
|
-
|
755
|
-
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
756
|
-
});
|
757
|
-
const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
|
892
|
+
data,
|
893
|
+
isLoading: isLoadingConfigs,
|
894
|
+
error,
|
895
|
+
isFetching: isFetchingConfigs
|
896
|
+
} = useGetContentTypeConfigurationQuery(model);
|
897
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
758
898
|
React.useEffect(() => {
|
759
899
|
if (error) {
|
760
900
|
toggleNotification({
|
@@ -762,83 +902,339 @@ const useDocument = (args, opts) => {
|
|
762
902
|
message: formatAPIError(error)
|
763
903
|
});
|
764
904
|
}
|
765
|
-
}, [
|
766
|
-
const
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
(document) => {
|
774
|
-
if (!validationSchema) {
|
775
|
-
throw new Error(
|
776
|
-
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
777
|
-
);
|
778
|
-
}
|
779
|
-
try {
|
780
|
-
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
781
|
-
return null;
|
782
|
-
} catch (error2) {
|
783
|
-
if (error2 instanceof ValidationError) {
|
784
|
-
return getYupValidationErrors(error2);
|
785
|
-
}
|
786
|
-
throw error2;
|
787
|
-
}
|
905
|
+
}, [error, formatAPIError, toggleNotification]);
|
906
|
+
const editLayout = React.useMemo(
|
907
|
+
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
908
|
+
layout: [],
|
909
|
+
components: {},
|
910
|
+
metadatas: {},
|
911
|
+
options: {},
|
912
|
+
settings: DEFAULT_SETTINGS
|
788
913
|
},
|
789
|
-
[
|
914
|
+
[data, isLoading, schemas, schema, components]
|
915
|
+
);
|
916
|
+
const listLayout = React.useMemo(() => {
|
917
|
+
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
918
|
+
layout: [],
|
919
|
+
metadatas: {},
|
920
|
+
options: {},
|
921
|
+
settings: DEFAULT_SETTINGS
|
922
|
+
};
|
923
|
+
}, [data, isLoading, schemas, schema, components]);
|
924
|
+
const { layout: edit } = React.useMemo(
|
925
|
+
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
926
|
+
layout: editLayout,
|
927
|
+
query
|
928
|
+
}),
|
929
|
+
[editLayout, query, runHookWaterfall]
|
790
930
|
);
|
791
|
-
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
792
931
|
return {
|
793
|
-
|
794
|
-
document: data?.data,
|
795
|
-
meta: data?.meta,
|
932
|
+
error,
|
796
933
|
isLoading,
|
797
|
-
|
798
|
-
|
799
|
-
};
|
800
|
-
};
|
801
|
-
const useDoc = () => {
|
802
|
-
const { id, slug, collectionType, origin } = useParams();
|
803
|
-
const [{ query }] = useQueryParams();
|
804
|
-
const params = React.useMemo(() => buildValidParams(query), [query]);
|
805
|
-
if (!collectionType) {
|
806
|
-
throw new Error("Could not find collectionType in url params");
|
807
|
-
}
|
808
|
-
if (!slug) {
|
809
|
-
throw new Error("Could not find model in url params");
|
810
|
-
}
|
811
|
-
return {
|
812
|
-
collectionType,
|
813
|
-
model: slug,
|
814
|
-
id: origin || id === "create" ? void 0 : id,
|
815
|
-
...useDocument(
|
816
|
-
{ documentId: origin || id, model: slug, collectionType, params },
|
817
|
-
{
|
818
|
-
skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
|
819
|
-
}
|
820
|
-
)
|
934
|
+
edit,
|
935
|
+
list: listLayout
|
821
936
|
};
|
822
937
|
};
|
823
|
-
const
|
824
|
-
|
825
|
-
|
826
|
-
}
|
827
|
-
return Object.keys(trad).reduce((acc, current) => {
|
828
|
-
acc[`${pluginId}.${current}`] = trad[current];
|
829
|
-
return acc;
|
830
|
-
}, {});
|
938
|
+
const useDocLayout = () => {
|
939
|
+
const { model } = useDoc();
|
940
|
+
return useDocumentLayout(model);
|
831
941
|
};
|
832
|
-
const
|
833
|
-
|
834
|
-
|
835
|
-
|
942
|
+
const formatEditLayout = (data, {
|
943
|
+
schemas,
|
944
|
+
schema,
|
945
|
+
components
|
946
|
+
}) => {
|
947
|
+
let currentPanelIndex = 0;
|
948
|
+
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
949
|
+
data.contentType.layouts.edit,
|
950
|
+
schema?.attributes,
|
951
|
+
data.contentType.metadatas,
|
952
|
+
{ configurations: data.components, schemas: components },
|
953
|
+
schemas
|
954
|
+
).reduce((panels, row) => {
|
955
|
+
if (row.some((field) => field.type === "dynamiczone")) {
|
956
|
+
panels.push([row]);
|
957
|
+
currentPanelIndex += 2;
|
958
|
+
} else {
|
959
|
+
if (!panels[currentPanelIndex]) {
|
960
|
+
panels.push([]);
|
961
|
+
}
|
962
|
+
panels[currentPanelIndex].push(row);
|
963
|
+
}
|
964
|
+
return panels;
|
965
|
+
}, []);
|
966
|
+
const componentEditAttributes = Object.entries(data.components).reduce(
|
967
|
+
(acc, [uid, configuration]) => {
|
968
|
+
acc[uid] = {
|
969
|
+
layout: convertEditLayoutToFieldLayouts(
|
970
|
+
configuration.layouts.edit,
|
971
|
+
components[uid].attributes,
|
972
|
+
configuration.metadatas,
|
973
|
+
{ configurations: data.components, schemas: components }
|
974
|
+
),
|
975
|
+
settings: {
|
976
|
+
...configuration.settings,
|
977
|
+
icon: components[uid].info.icon,
|
978
|
+
displayName: components[uid].info.displayName
|
979
|
+
}
|
980
|
+
};
|
981
|
+
return acc;
|
982
|
+
},
|
983
|
+
{}
|
984
|
+
);
|
985
|
+
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
986
|
+
(acc, [attribute, metadata]) => {
|
987
|
+
return {
|
988
|
+
...acc,
|
989
|
+
[attribute]: metadata.edit
|
990
|
+
};
|
991
|
+
},
|
992
|
+
{}
|
993
|
+
);
|
994
|
+
return {
|
995
|
+
layout: panelledEditAttributes,
|
996
|
+
components: componentEditAttributes,
|
997
|
+
metadatas: editMetadatas,
|
998
|
+
settings: {
|
999
|
+
...data.contentType.settings,
|
1000
|
+
displayName: schema?.info.displayName
|
1001
|
+
},
|
1002
|
+
options: {
|
1003
|
+
...schema?.options,
|
1004
|
+
...schema?.pluginOptions,
|
1005
|
+
...data.contentType.options
|
1006
|
+
}
|
1007
|
+
};
|
1008
|
+
};
|
1009
|
+
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
1010
|
+
return rows.map(
|
1011
|
+
(row) => row.map((field) => {
|
1012
|
+
const attribute = attributes[field.name];
|
1013
|
+
if (!attribute) {
|
1014
|
+
return null;
|
1015
|
+
}
|
1016
|
+
const { edit: metadata } = metadatas[field.name];
|
1017
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1018
|
+
return {
|
1019
|
+
attribute,
|
1020
|
+
disabled: !metadata.editable,
|
1021
|
+
hint: metadata.description,
|
1022
|
+
label: metadata.label ?? "",
|
1023
|
+
name: field.name,
|
1024
|
+
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
1025
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1026
|
+
schemas,
|
1027
|
+
components: components?.schemas ?? {}
|
1028
|
+
}),
|
1029
|
+
placeholder: metadata.placeholder ?? "",
|
1030
|
+
required: attribute.required ?? false,
|
1031
|
+
size: field.size,
|
1032
|
+
unique: "unique" in attribute ? attribute.unique : false,
|
1033
|
+
visible: metadata.visible ?? true,
|
1034
|
+
type: attribute.type
|
1035
|
+
};
|
1036
|
+
}).filter((field) => field !== null)
|
1037
|
+
);
|
1038
|
+
};
|
1039
|
+
const formatListLayout = (data, {
|
1040
|
+
schemas,
|
1041
|
+
schema,
|
1042
|
+
components
|
1043
|
+
}) => {
|
1044
|
+
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1045
|
+
(acc, [attribute, metadata]) => {
|
1046
|
+
return {
|
1047
|
+
...acc,
|
1048
|
+
[attribute]: metadata.list
|
1049
|
+
};
|
1050
|
+
},
|
1051
|
+
{}
|
1052
|
+
);
|
1053
|
+
const listAttributes = convertListLayoutToFieldLayouts(
|
1054
|
+
data.contentType.layouts.list,
|
1055
|
+
schema?.attributes,
|
1056
|
+
listMetadatas,
|
1057
|
+
{ configurations: data.components, schemas: components },
|
1058
|
+
schemas
|
1059
|
+
);
|
1060
|
+
return {
|
1061
|
+
layout: listAttributes,
|
1062
|
+
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
1063
|
+
metadatas: listMetadatas,
|
1064
|
+
options: {
|
1065
|
+
...schema?.options,
|
1066
|
+
...schema?.pluginOptions,
|
1067
|
+
...data.contentType.options
|
1068
|
+
}
|
1069
|
+
};
|
1070
|
+
};
|
1071
|
+
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
1072
|
+
return columns.map((name) => {
|
1073
|
+
const attribute = attributes[name];
|
1074
|
+
if (!attribute) {
|
1075
|
+
return null;
|
1076
|
+
}
|
1077
|
+
const metadata = metadatas[name];
|
1078
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1079
|
+
return {
|
1080
|
+
attribute,
|
1081
|
+
label: metadata.label ?? "",
|
1082
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1083
|
+
schemas,
|
1084
|
+
components: components?.schemas ?? {}
|
1085
|
+
}),
|
1086
|
+
name,
|
1087
|
+
searchable: metadata.searchable ?? true,
|
1088
|
+
sortable: metadata.sortable ?? true
|
1089
|
+
};
|
1090
|
+
}).filter((field) => field !== null);
|
1091
|
+
};
|
1092
|
+
const useDocument = (args, opts) => {
|
1093
|
+
const { toggleNotification } = useNotification();
|
1094
|
+
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1095
|
+
const {
|
1096
|
+
currentData: data,
|
1097
|
+
isLoading: isLoadingDocument,
|
1098
|
+
isFetching: isFetchingDocument,
|
1099
|
+
error
|
1100
|
+
} = useGetDocumentQuery(args, {
|
1101
|
+
...opts,
|
1102
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
1103
|
+
});
|
1104
|
+
const {
|
1105
|
+
components,
|
1106
|
+
schema,
|
1107
|
+
schemas,
|
1108
|
+
isLoading: isLoadingSchema
|
1109
|
+
} = useContentTypeSchema(args.model);
|
1110
|
+
React.useEffect(() => {
|
1111
|
+
if (error) {
|
1112
|
+
toggleNotification({
|
1113
|
+
type: "danger",
|
1114
|
+
message: formatAPIError(error)
|
1115
|
+
});
|
1116
|
+
}
|
1117
|
+
}, [toggleNotification, error, formatAPIError, args.collectionType]);
|
1118
|
+
const validationSchema = React.useMemo(() => {
|
1119
|
+
if (!schema) {
|
1120
|
+
return null;
|
1121
|
+
}
|
1122
|
+
return createYupSchema(schema.attributes, components);
|
1123
|
+
}, [schema, components]);
|
1124
|
+
const validate = React.useCallback(
|
1125
|
+
(document) => {
|
1126
|
+
if (!validationSchema) {
|
1127
|
+
throw new Error(
|
1128
|
+
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
1129
|
+
);
|
1130
|
+
}
|
1131
|
+
try {
|
1132
|
+
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
1133
|
+
return null;
|
1134
|
+
} catch (error2) {
|
1135
|
+
if (error2 instanceof ValidationError) {
|
1136
|
+
return getYupValidationErrors(error2);
|
1137
|
+
}
|
1138
|
+
throw error2;
|
1139
|
+
}
|
1140
|
+
},
|
1141
|
+
[validationSchema]
|
1142
|
+
);
|
1143
|
+
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
1144
|
+
const hasError = !!error;
|
1145
|
+
return {
|
1146
|
+
components,
|
1147
|
+
document: data?.data,
|
1148
|
+
meta: data?.meta,
|
1149
|
+
isLoading,
|
1150
|
+
hasError,
|
1151
|
+
schema,
|
1152
|
+
schemas,
|
1153
|
+
validate
|
1154
|
+
};
|
1155
|
+
};
|
1156
|
+
const useDoc = () => {
|
1157
|
+
const { id, slug, collectionType, origin } = useParams();
|
1158
|
+
const [{ query }] = useQueryParams();
|
1159
|
+
const params = React.useMemo(() => buildValidParams(query), [query]);
|
1160
|
+
if (!collectionType) {
|
1161
|
+
throw new Error("Could not find collectionType in url params");
|
1162
|
+
}
|
1163
|
+
if (!slug) {
|
1164
|
+
throw new Error("Could not find model in url params");
|
1165
|
+
}
|
1166
|
+
return {
|
1167
|
+
collectionType,
|
1168
|
+
model: slug,
|
1169
|
+
id: origin || id === "create" ? void 0 : id,
|
1170
|
+
...useDocument(
|
1171
|
+
{ documentId: origin || id, model: slug, collectionType, params },
|
1172
|
+
{
|
1173
|
+
skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
|
1174
|
+
}
|
1175
|
+
)
|
1176
|
+
};
|
1177
|
+
};
|
1178
|
+
const useContentManagerContext = () => {
|
1179
|
+
const {
|
1180
|
+
collectionType,
|
1181
|
+
model,
|
1182
|
+
id,
|
1183
|
+
components,
|
1184
|
+
isLoading: isLoadingDoc,
|
1185
|
+
schema,
|
1186
|
+
schemas
|
1187
|
+
} = useDoc();
|
1188
|
+
const layout = useDocumentLayout(model);
|
1189
|
+
const form = useForm("useContentManagerContext", (state) => state);
|
1190
|
+
const isSingleType = collectionType === SINGLE_TYPES;
|
1191
|
+
const slug = model;
|
1192
|
+
const isCreatingEntry = id === "create";
|
1193
|
+
useContentTypeSchema();
|
1194
|
+
const isLoading = isLoadingDoc || layout.isLoading;
|
1195
|
+
const error = layout.error;
|
1196
|
+
return {
|
1197
|
+
error,
|
1198
|
+
isLoading,
|
1199
|
+
// Base metadata
|
1200
|
+
model,
|
1201
|
+
collectionType,
|
1202
|
+
id,
|
1203
|
+
slug,
|
1204
|
+
isCreatingEntry,
|
1205
|
+
isSingleType,
|
1206
|
+
hasDraftAndPublish: schema?.options?.draftAndPublish ?? false,
|
1207
|
+
// All schema infos
|
1208
|
+
components,
|
1209
|
+
contentType: schema,
|
1210
|
+
contentTypes: schemas,
|
1211
|
+
// Form state
|
1212
|
+
form,
|
1213
|
+
// layout infos
|
1214
|
+
layout
|
1215
|
+
};
|
1216
|
+
};
|
1217
|
+
const prefixPluginTranslations = (trad, pluginId) => {
|
1218
|
+
if (!pluginId) {
|
1219
|
+
throw new TypeError("pluginId can't be empty");
|
1220
|
+
}
|
1221
|
+
return Object.keys(trad).reduce((acc, current) => {
|
1222
|
+
acc[`${pluginId}.${current}`] = trad[current];
|
1223
|
+
return acc;
|
1224
|
+
}, {});
|
1225
|
+
};
|
1226
|
+
const getTranslation = (id) => `content-manager.${id}`;
|
1227
|
+
const DEFAULT_UNEXPECTED_ERROR_MSG = {
|
1228
|
+
id: "notification.error",
|
1229
|
+
defaultMessage: "An error occurred, please try again"
|
836
1230
|
};
|
837
1231
|
const useDocumentActions = () => {
|
838
1232
|
const { toggleNotification } = useNotification();
|
839
1233
|
const { formatMessage } = useIntl();
|
840
1234
|
const { trackUsage } = useTracking();
|
841
1235
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1236
|
+
const navigate = useNavigate();
|
1237
|
+
const setCurrentStep = useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
842
1238
|
const [deleteDocument] = useDeleteDocumentMutation();
|
843
1239
|
const _delete = React.useCallback(
|
844
1240
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -1153,6 +1549,7 @@ const useDocumentActions = () => {
|
|
1153
1549
|
defaultMessage: "Saved document"
|
1154
1550
|
})
|
1155
1551
|
});
|
1552
|
+
setCurrentStep("contentManager.success");
|
1156
1553
|
return res.data;
|
1157
1554
|
} catch (err) {
|
1158
1555
|
toggleNotification({
|
@@ -1174,7 +1571,6 @@ const useDocumentActions = () => {
|
|
1174
1571
|
sourceId
|
1175
1572
|
});
|
1176
1573
|
if ("error" in res) {
|
1177
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1178
1574
|
return { error: res.error };
|
1179
1575
|
}
|
1180
1576
|
toggleNotification({
|
@@ -1193,7 +1589,7 @@ const useDocumentActions = () => {
|
|
1193
1589
|
throw err;
|
1194
1590
|
}
|
1195
1591
|
},
|
1196
|
-
[autoCloneDocument,
|
1592
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1197
1593
|
);
|
1198
1594
|
const [cloneDocument] = useCloneDocumentMutation();
|
1199
1595
|
const clone = React.useCallback(
|
@@ -1219,6 +1615,7 @@ const useDocumentActions = () => {
|
|
1219
1615
|
defaultMessage: "Cloned document"
|
1220
1616
|
})
|
1221
1617
|
});
|
1618
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1222
1619
|
return res.data;
|
1223
1620
|
} catch (err) {
|
1224
1621
|
toggleNotification({
|
@@ -1229,7 +1626,7 @@ const useDocumentActions = () => {
|
|
1229
1626
|
throw err;
|
1230
1627
|
}
|
1231
1628
|
},
|
1232
|
-
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
|
1629
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1233
1630
|
);
|
1234
1631
|
const [getDoc] = useLazyGetDocumentQuery();
|
1235
1632
|
const getDocument = React.useCallback(
|
@@ -1255,7 +1652,7 @@ const useDocumentActions = () => {
|
|
1255
1652
|
};
|
1256
1653
|
};
|
1257
1654
|
const ProtectedHistoryPage = lazy(
|
1258
|
-
() => import("./History-
|
1655
|
+
() => import("./History-CpxkZXS3.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1259
1656
|
);
|
1260
1657
|
const routes$1 = [
|
1261
1658
|
{
|
@@ -1268,31 +1665,31 @@ const routes$1 = [
|
|
1268
1665
|
}
|
1269
1666
|
];
|
1270
1667
|
const ProtectedEditViewPage = lazy(
|
1271
|
-
() => import("./EditViewPage-
|
1668
|
+
() => import("./EditViewPage-k8UcfVwt.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1272
1669
|
);
|
1273
1670
|
const ProtectedListViewPage = lazy(
|
1274
|
-
() => import("./ListViewPage-
|
1671
|
+
() => import("./ListViewPage-BOnhCGkE.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1275
1672
|
);
|
1276
1673
|
const ProtectedListConfiguration = lazy(
|
1277
|
-
() => import("./ListConfigurationPage-
|
1674
|
+
() => import("./ListConfigurationPage-OUwV8QF1.mjs").then((mod) => ({
|
1278
1675
|
default: mod.ProtectedListConfiguration
|
1279
1676
|
}))
|
1280
1677
|
);
|
1281
1678
|
const ProtectedEditConfigurationPage = lazy(
|
1282
|
-
() => import("./EditConfigurationPage-
|
1679
|
+
() => import("./EditConfigurationPage-C9yiwgI_.mjs").then((mod) => ({
|
1283
1680
|
default: mod.ProtectedEditConfigurationPage
|
1284
1681
|
}))
|
1285
1682
|
);
|
1286
1683
|
const ProtectedComponentConfigurationPage = lazy(
|
1287
|
-
() => import("./ComponentConfigurationPage-
|
1684
|
+
() => import("./ComponentConfigurationPage-D1YuKq8j.mjs").then((mod) => ({
|
1288
1685
|
default: mod.ProtectedComponentConfigurationPage
|
1289
1686
|
}))
|
1290
1687
|
);
|
1291
1688
|
const NoPermissions = lazy(
|
1292
|
-
() => import("./NoPermissionsPage-
|
1689
|
+
() => import("./NoPermissionsPage-CcWbyT_z.mjs").then((mod) => ({ default: mod.NoPermissions }))
|
1293
1690
|
);
|
1294
1691
|
const NoContentType = lazy(
|
1295
|
-
() => import("./NoContentTypePage-
|
1692
|
+
() => import("./NoContentTypePage-CwjlHGTn.mjs").then((mod) => ({ default: mod.NoContentType }))
|
1296
1693
|
);
|
1297
1694
|
const CollectionTypePages = () => {
|
1298
1695
|
const { collectionType } = useParams();
|
@@ -1406,12 +1803,14 @@ const DocumentActionButton = (action) => {
|
|
1406
1803
|
/* @__PURE__ */ jsx(
|
1407
1804
|
Button,
|
1408
1805
|
{
|
1409
|
-
flex:
|
1806
|
+
flex: "auto",
|
1410
1807
|
startIcon: action.icon,
|
1411
1808
|
disabled: action.disabled,
|
1412
1809
|
onClick: handleClick(action),
|
1413
1810
|
justifyContent: "center",
|
1414
1811
|
variant: action.variant || "default",
|
1812
|
+
paddingTop: "7px",
|
1813
|
+
paddingBottom: "7px",
|
1415
1814
|
children: action.label
|
1416
1815
|
}
|
1417
1816
|
),
|
@@ -1476,9 +1875,9 @@ const DocumentActionsMenu = ({
|
|
1476
1875
|
disabled: isDisabled,
|
1477
1876
|
size: "S",
|
1478
1877
|
endIcon: null,
|
1479
|
-
paddingTop: "
|
1480
|
-
paddingLeft: "
|
1481
|
-
paddingRight: "
|
1878
|
+
paddingTop: "4px",
|
1879
|
+
paddingLeft: "7px",
|
1880
|
+
paddingRight: "7px",
|
1482
1881
|
variant,
|
1483
1882
|
children: [
|
1484
1883
|
/* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
|
@@ -1489,7 +1888,7 @@ const DocumentActionsMenu = ({
|
|
1489
1888
|
]
|
1490
1889
|
}
|
1491
1890
|
),
|
1492
|
-
/* @__PURE__ */ jsxs(Menu.Content, {
|
1891
|
+
/* @__PURE__ */ jsxs(Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1493
1892
|
actions2.map((action) => {
|
1494
1893
|
return /* @__PURE__ */ jsx(
|
1495
1894
|
Menu.Item,
|
@@ -1498,10 +1897,25 @@ const DocumentActionsMenu = ({
|
|
1498
1897
|
onSelect: handleClick(action),
|
1499
1898
|
display: "block",
|
1500
1899
|
children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", gap: 4, children: [
|
1501
|
-
/* @__PURE__ */ jsxs(
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1900
|
+
/* @__PURE__ */ jsxs(
|
1901
|
+
Flex,
|
1902
|
+
{
|
1903
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1904
|
+
gap: 2,
|
1905
|
+
tag: "span",
|
1906
|
+
children: [
|
1907
|
+
/* @__PURE__ */ jsx(
|
1908
|
+
Flex,
|
1909
|
+
{
|
1910
|
+
tag: "span",
|
1911
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1912
|
+
children: action.icon
|
1913
|
+
}
|
1914
|
+
),
|
1915
|
+
action.label
|
1916
|
+
]
|
1917
|
+
}
|
1918
|
+
),
|
1505
1919
|
action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsx(
|
1506
1920
|
Flex,
|
1507
1921
|
{
|
@@ -1598,11 +2012,11 @@ const DocumentActionConfirmDialog = ({
|
|
1598
2012
|
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
1599
2013
|
/* @__PURE__ */ jsx(Dialog.Body, { children: content }),
|
1600
2014
|
/* @__PURE__ */ jsxs(Dialog.Footer, { children: [
|
1601
|
-
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", children: formatMessage({
|
2015
|
+
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", fullWidth: true, children: formatMessage({
|
1602
2016
|
id: "app.components.Button.cancel",
|
1603
2017
|
defaultMessage: "Cancel"
|
1604
2018
|
}) }) }),
|
1605
|
-
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, children: formatMessage({
|
2019
|
+
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
|
1606
2020
|
id: "app.components.Button.confirm",
|
1607
2021
|
defaultMessage: "Confirm"
|
1608
2022
|
}) })
|
@@ -1625,8 +2039,8 @@ const DocumentActionModal = ({
|
|
1625
2039
|
};
|
1626
2040
|
return /* @__PURE__ */ jsx(Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
|
1627
2041
|
/* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: title }) }),
|
1628
|
-
|
1629
|
-
|
2042
|
+
typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsx(Modal.Body, { children: Content }),
|
2043
|
+
typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
|
1630
2044
|
] }) });
|
1631
2045
|
};
|
1632
2046
|
const PublishAction$1 = ({
|
@@ -1641,12 +2055,10 @@ const PublishAction$1 = ({
|
|
1641
2055
|
const navigate = useNavigate();
|
1642
2056
|
const { toggleNotification } = useNotification();
|
1643
2057
|
const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
|
2058
|
+
const isListView = useMatch(LIST_PATH) !== null;
|
1644
2059
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
1645
2060
|
const { formatMessage } = useIntl();
|
1646
|
-
const { canPublish
|
1647
|
-
"PublishAction",
|
1648
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1649
|
-
);
|
2061
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1650
2062
|
const { publish } = useDocumentActions();
|
1651
2063
|
const [
|
1652
2064
|
countDraftRelations,
|
@@ -1698,24 +2110,25 @@ const PublishAction$1 = ({
|
|
1698
2110
|
}
|
1699
2111
|
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
1700
2112
|
React.useEffect(() => {
|
1701
|
-
if (documentId) {
|
1702
|
-
|
1703
|
-
const { data, error } = await countDraftRelations({
|
1704
|
-
collectionType,
|
1705
|
-
model,
|
1706
|
-
documentId,
|
1707
|
-
params
|
1708
|
-
});
|
1709
|
-
if (error) {
|
1710
|
-
throw error;
|
1711
|
-
}
|
1712
|
-
if (data) {
|
1713
|
-
setServerCountOfDraftRelations(data.data);
|
1714
|
-
}
|
1715
|
-
};
|
1716
|
-
fetchDraftRelationsCount();
|
2113
|
+
if (!document || !document.documentId || isListView) {
|
2114
|
+
return;
|
1717
2115
|
}
|
1718
|
-
|
2116
|
+
const fetchDraftRelationsCount = async () => {
|
2117
|
+
const { data, error } = await countDraftRelations({
|
2118
|
+
collectionType,
|
2119
|
+
model,
|
2120
|
+
documentId,
|
2121
|
+
params
|
2122
|
+
});
|
2123
|
+
if (error) {
|
2124
|
+
throw error;
|
2125
|
+
}
|
2126
|
+
if (data) {
|
2127
|
+
setServerCountOfDraftRelations(data.data);
|
2128
|
+
}
|
2129
|
+
};
|
2130
|
+
fetchDraftRelationsCount();
|
2131
|
+
}, [isListView, document, documentId, countDraftRelations, collectionType, model, params]);
|
1719
2132
|
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
1720
2133
|
if (!schema?.options?.draftAndPublish) {
|
1721
2134
|
return null;
|
@@ -1723,7 +2136,9 @@ const PublishAction$1 = ({
|
|
1723
2136
|
const performPublish = async () => {
|
1724
2137
|
setSubmitting(true);
|
1725
2138
|
try {
|
1726
|
-
const { errors } = await validate(
|
2139
|
+
const { errors } = await validate(true, {
|
2140
|
+
status: "published"
|
2141
|
+
});
|
1727
2142
|
if (errors) {
|
1728
2143
|
toggleNotification({
|
1729
2144
|
type: "danger",
|
@@ -1756,7 +2171,8 @@ const PublishAction$1 = ({
|
|
1756
2171
|
}
|
1757
2172
|
};
|
1758
2173
|
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
1759
|
-
const
|
2174
|
+
const enableDraftRelationsCount = false;
|
2175
|
+
const hasDraftRelations = enableDraftRelationsCount;
|
1760
2176
|
return {
|
1761
2177
|
/**
|
1762
2178
|
* Disabled when:
|
@@ -1766,18 +2182,13 @@ const PublishAction$1 = ({
|
|
1766
2182
|
* - the document is already published & not modified
|
1767
2183
|
* - the document is being created & not modified
|
1768
2184
|
* - the user doesn't have the permission to publish
|
1769
|
-
* - the user doesn't have the permission to create a new document
|
1770
|
-
* - the user doesn't have the permission to update the document
|
1771
2185
|
*/
|
1772
|
-
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish
|
2186
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
1773
2187
|
label: formatMessage({
|
1774
2188
|
id: "app.utils.publish",
|
1775
2189
|
defaultMessage: "Publish"
|
1776
2190
|
}),
|
1777
2191
|
onClick: async () => {
|
1778
|
-
if (hasDraftRelations) {
|
1779
|
-
return;
|
1780
|
-
}
|
1781
2192
|
await performPublish();
|
1782
2193
|
},
|
1783
2194
|
dialog: hasDraftRelations ? {
|
@@ -1816,10 +2227,6 @@ const UpdateAction = ({
|
|
1816
2227
|
const cloneMatch = useMatch(CLONE_PATH);
|
1817
2228
|
const isCloning = cloneMatch !== null;
|
1818
2229
|
const { formatMessage } = useIntl();
|
1819
|
-
const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1820
|
-
canCreate: canCreate2,
|
1821
|
-
canUpdate: canUpdate2
|
1822
|
-
}));
|
1823
2230
|
const { create, update, clone } = useDocumentActions();
|
1824
2231
|
const [{ query, rawQuery }] = useQueryParams();
|
1825
2232
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
@@ -1836,10 +2243,8 @@ const UpdateAction = ({
|
|
1836
2243
|
* - the form is submitting
|
1837
2244
|
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
1838
2245
|
* - the active tab is the published tab
|
1839
|
-
* - the user doesn't have the permission to create a new document
|
1840
|
-
* - the user doesn't have the permission to update the document
|
1841
2246
|
*/
|
1842
|
-
disabled: isSubmitting || !modified && !isCloning || activeTab === "published"
|
2247
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1843
2248
|
label: formatMessage({
|
1844
2249
|
id: "content-manager.containers.Edit.save",
|
1845
2250
|
defaultMessage: "Save"
|
@@ -1847,7 +2252,9 @@ const UpdateAction = ({
|
|
1847
2252
|
onClick: async () => {
|
1848
2253
|
setSubmitting(true);
|
1849
2254
|
try {
|
1850
|
-
const { errors } = await validate(
|
2255
|
+
const { errors } = await validate(true, {
|
2256
|
+
status: "draft"
|
2257
|
+
});
|
1851
2258
|
if (errors) {
|
1852
2259
|
toggleNotification({
|
1853
2260
|
type: "danger",
|
@@ -1868,10 +2275,13 @@ const UpdateAction = ({
|
|
1868
2275
|
document
|
1869
2276
|
);
|
1870
2277
|
if ("data" in res) {
|
1871
|
-
navigate(
|
1872
|
-
|
1873
|
-
|
1874
|
-
|
2278
|
+
navigate(
|
2279
|
+
{
|
2280
|
+
pathname: `../${res.data.documentId}`,
|
2281
|
+
search: rawQuery
|
2282
|
+
},
|
2283
|
+
{ relative: "path" }
|
2284
|
+
);
|
1875
2285
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1876
2286
|
setErrors(formatValidationErrors(res.error));
|
1877
2287
|
}
|
@@ -1901,10 +2311,10 @@ const UpdateAction = ({
|
|
1901
2311
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1902
2312
|
navigate(
|
1903
2313
|
{
|
1904
|
-
pathname: `../${
|
2314
|
+
pathname: `../${res.data.documentId}`,
|
1905
2315
|
search: rawQuery
|
1906
2316
|
},
|
1907
|
-
{ replace: true }
|
2317
|
+
{ replace: true, relative: "path" }
|
1908
2318
|
);
|
1909
2319
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1910
2320
|
setErrors(formatValidationErrors(res.error));
|
@@ -1949,7 +2359,7 @@ const UnpublishAction$1 = ({
|
|
1949
2359
|
id: "app.utils.unpublish",
|
1950
2360
|
defaultMessage: "Unpublish"
|
1951
2361
|
}),
|
1952
|
-
icon: /* @__PURE__ */ jsx(
|
2362
|
+
icon: /* @__PURE__ */ jsx(Cross, {}),
|
1953
2363
|
onClick: async () => {
|
1954
2364
|
if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
|
1955
2365
|
if (!documentId) {
|
@@ -2061,7 +2471,7 @@ const DiscardAction = ({
|
|
2061
2471
|
id: "content-manager.actions.discard.label",
|
2062
2472
|
defaultMessage: "Discard changes"
|
2063
2473
|
}),
|
2064
|
-
icon: /* @__PURE__ */ jsx(
|
2474
|
+
icon: /* @__PURE__ */ jsx(Cross, {}),
|
2065
2475
|
position: ["panel", "table-row"],
|
2066
2476
|
variant: "danger",
|
2067
2477
|
dialog: {
|
@@ -2089,11 +2499,6 @@ const DiscardAction = ({
|
|
2089
2499
|
};
|
2090
2500
|
};
|
2091
2501
|
DiscardAction.type = "discard";
|
2092
|
-
const StyledCrossCircle = styled(CrossCircle)`
|
2093
|
-
path {
|
2094
|
-
fill: currentColor;
|
2095
|
-
}
|
2096
|
-
`;
|
2097
2502
|
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2098
2503
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2099
2504
|
const RelativeTime = React.forwardRef(
|
@@ -2141,7 +2546,7 @@ const getDisplayName = ({
|
|
2141
2546
|
};
|
2142
2547
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2143
2548
|
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2144
|
-
const statusVariant = status === "draft" ? "
|
2549
|
+
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2145
2550
|
return /* @__PURE__ */ jsx(Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: capitalise(status) }) });
|
2146
2551
|
};
|
2147
2552
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
@@ -2240,12 +2645,12 @@ const Information = ({ activeTab }) => {
|
|
2240
2645
|
isDisplayed: !!publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME],
|
2241
2646
|
label: formatMessage({
|
2242
2647
|
id: "content-manager.containers.edit.information.last-published.label",
|
2243
|
-
defaultMessage: "
|
2648
|
+
defaultMessage: "Published"
|
2244
2649
|
}),
|
2245
2650
|
value: formatMessage(
|
2246
2651
|
{
|
2247
2652
|
id: "content-manager.containers.edit.information.last-published.value",
|
2248
|
-
defaultMessage: `
|
2653
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2249
2654
|
},
|
2250
2655
|
{
|
2251
2656
|
time: /* @__PURE__ */ jsx(RelativeTime, { timestamp: new Date(publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME]) }),
|
@@ -2258,12 +2663,12 @@ const Information = ({ activeTab }) => {
|
|
2258
2663
|
isDisplayed: !!createAndUpdateDocument?.[UPDATED_AT_ATTRIBUTE_NAME],
|
2259
2664
|
label: formatMessage({
|
2260
2665
|
id: "content-manager.containers.edit.information.last-draft.label",
|
2261
|
-
defaultMessage: "
|
2666
|
+
defaultMessage: "Updated"
|
2262
2667
|
}),
|
2263
2668
|
value: formatMessage(
|
2264
2669
|
{
|
2265
2670
|
id: "content-manager.containers.edit.information.last-draft.value",
|
2266
|
-
defaultMessage: `
|
2671
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2267
2672
|
},
|
2268
2673
|
{
|
2269
2674
|
time: /* @__PURE__ */ jsx(
|
@@ -2281,12 +2686,12 @@ const Information = ({ activeTab }) => {
|
|
2281
2686
|
isDisplayed: !!createAndUpdateDocument?.[CREATED_AT_ATTRIBUTE_NAME],
|
2282
2687
|
label: formatMessage({
|
2283
2688
|
id: "content-manager.containers.edit.information.document.label",
|
2284
|
-
defaultMessage: "
|
2689
|
+
defaultMessage: "Created"
|
2285
2690
|
}),
|
2286
2691
|
value: formatMessage(
|
2287
2692
|
{
|
2288
2693
|
id: "content-manager.containers.edit.information.document.value",
|
2289
|
-
defaultMessage: `
|
2694
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2290
2695
|
},
|
2291
2696
|
{
|
2292
2697
|
time: /* @__PURE__ */ jsx(
|
@@ -2324,25 +2729,77 @@ const Information = ({ activeTab }) => {
|
|
2324
2729
|
);
|
2325
2730
|
};
|
2326
2731
|
const HeaderActions = ({ actions: actions2 }) => {
|
2327
|
-
|
2328
|
-
|
2732
|
+
const [dialogId, setDialogId] = React.useState(null);
|
2733
|
+
const handleClick = (action) => async (e) => {
|
2734
|
+
if (!("options" in action)) {
|
2735
|
+
const { onClick = () => false, dialog, id } = action;
|
2736
|
+
const muteDialog = await onClick(e);
|
2737
|
+
if (dialog && !muteDialog) {
|
2738
|
+
e.preventDefault();
|
2739
|
+
setDialogId(id);
|
2740
|
+
}
|
2741
|
+
}
|
2742
|
+
};
|
2743
|
+
const handleClose = () => {
|
2744
|
+
setDialogId(null);
|
2745
|
+
};
|
2746
|
+
return /* @__PURE__ */ jsx(Flex, { gap: 1, children: actions2.map((action) => {
|
2747
|
+
if (action.options) {
|
2329
2748
|
return /* @__PURE__ */ jsx(
|
2330
2749
|
SingleSelect,
|
2331
2750
|
{
|
2332
2751
|
size: "S",
|
2333
|
-
disabled: action.disabled,
|
2334
|
-
"aria-label": action.label,
|
2335
2752
|
onChange: action.onSelect,
|
2336
|
-
|
2753
|
+
"aria-label": action.label,
|
2754
|
+
...action,
|
2337
2755
|
children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsx(SingleSelectOption, { ...option, children: label }, option.value))
|
2338
2756
|
},
|
2339
2757
|
action.id
|
2340
2758
|
);
|
2341
2759
|
} else {
|
2342
|
-
|
2760
|
+
if (action.type === "icon") {
|
2761
|
+
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
2762
|
+
/* @__PURE__ */ jsx(
|
2763
|
+
IconButton,
|
2764
|
+
{
|
2765
|
+
disabled: action.disabled,
|
2766
|
+
label: action.label,
|
2767
|
+
size: "S",
|
2768
|
+
onClick: handleClick(action),
|
2769
|
+
children: action.icon
|
2770
|
+
}
|
2771
|
+
),
|
2772
|
+
action.dialog ? /* @__PURE__ */ jsx(
|
2773
|
+
HeaderActionDialog,
|
2774
|
+
{
|
2775
|
+
...action.dialog,
|
2776
|
+
isOpen: dialogId === action.id,
|
2777
|
+
onClose: handleClose
|
2778
|
+
}
|
2779
|
+
) : null
|
2780
|
+
] }, action.id);
|
2781
|
+
}
|
2343
2782
|
}
|
2344
2783
|
}) });
|
2345
2784
|
};
|
2785
|
+
const HeaderActionDialog = ({
|
2786
|
+
onClose,
|
2787
|
+
onCancel,
|
2788
|
+
title,
|
2789
|
+
content: Content,
|
2790
|
+
isOpen
|
2791
|
+
}) => {
|
2792
|
+
const handleClose = async () => {
|
2793
|
+
if (onCancel) {
|
2794
|
+
await onCancel();
|
2795
|
+
}
|
2796
|
+
onClose();
|
2797
|
+
};
|
2798
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
2799
|
+
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
2800
|
+
typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : Content
|
2801
|
+
] }) });
|
2802
|
+
};
|
2346
2803
|
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
2347
2804
|
const navigate = useNavigate();
|
2348
2805
|
const { formatMessage } = useIntl();
|
@@ -2383,12 +2840,16 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2383
2840
|
const { delete: deleteAction } = useDocumentActions();
|
2384
2841
|
const { toggleNotification } = useNotification();
|
2385
2842
|
const setSubmitting = useForm("DeleteAction", (state) => state.setSubmitting);
|
2843
|
+
const isLocalized = document?.locale != null;
|
2386
2844
|
return {
|
2387
2845
|
disabled: !canDelete || !document,
|
2388
|
-
label: formatMessage(
|
2389
|
-
|
2390
|
-
|
2391
|
-
|
2846
|
+
label: formatMessage(
|
2847
|
+
{
|
2848
|
+
id: "content-manager.actions.delete.label",
|
2849
|
+
defaultMessage: "Delete entry{isLocalized, select, true { (all locales)} other {}}"
|
2850
|
+
},
|
2851
|
+
{ isLocalized }
|
2852
|
+
),
|
2392
2853
|
icon: /* @__PURE__ */ jsx(Trash, {}),
|
2393
2854
|
dialog: {
|
2394
2855
|
type: "dialog",
|
@@ -2478,7 +2939,7 @@ const ActionsPanel = () => {
|
|
2478
2939
|
return {
|
2479
2940
|
title: formatMessage({
|
2480
2941
|
id: "content-manager.containers.edit.panels.default.title",
|
2481
|
-
defaultMessage: "
|
2942
|
+
defaultMessage: "Entry"
|
2482
2943
|
}),
|
2483
2944
|
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2484
2945
|
};
|
@@ -2539,308 +3000,6 @@ const Panel = React.forwardRef(({ children, title }, ref) => {
|
|
2539
3000
|
}
|
2540
3001
|
);
|
2541
3002
|
});
|
2542
|
-
const HOOKS = {
|
2543
|
-
/**
|
2544
|
-
* Hook that allows to mutate the displayed headers of the list view table
|
2545
|
-
* @constant
|
2546
|
-
* @type {string}
|
2547
|
-
*/
|
2548
|
-
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2549
|
-
/**
|
2550
|
-
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2551
|
-
* @constant
|
2552
|
-
* @type {string}
|
2553
|
-
*/
|
2554
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2555
|
-
/**
|
2556
|
-
* Hook that allows to mutate the CM's edit view layout
|
2557
|
-
* @constant
|
2558
|
-
* @type {string}
|
2559
|
-
*/
|
2560
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2561
|
-
/**
|
2562
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
2563
|
-
* @constant
|
2564
|
-
* @type {string}
|
2565
|
-
*/
|
2566
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2567
|
-
};
|
2568
|
-
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2569
|
-
endpoints: (builder) => ({
|
2570
|
-
getContentTypeConfiguration: builder.query({
|
2571
|
-
query: (uid) => ({
|
2572
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2573
|
-
method: "GET"
|
2574
|
-
}),
|
2575
|
-
transformResponse: (response) => response.data,
|
2576
|
-
providesTags: (_result, _error, uid) => [
|
2577
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2578
|
-
{ type: "ContentTypeSettings", id: "LIST" }
|
2579
|
-
]
|
2580
|
-
}),
|
2581
|
-
getAllContentTypeSettings: builder.query({
|
2582
|
-
query: () => "/content-manager/content-types-settings",
|
2583
|
-
transformResponse: (response) => response.data,
|
2584
|
-
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2585
|
-
}),
|
2586
|
-
updateContentTypeConfiguration: builder.mutation({
|
2587
|
-
query: ({ uid, ...body }) => ({
|
2588
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2589
|
-
method: "PUT",
|
2590
|
-
data: body
|
2591
|
-
}),
|
2592
|
-
transformResponse: (response) => response.data,
|
2593
|
-
invalidatesTags: (_result, _error, { uid }) => [
|
2594
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2595
|
-
{ type: "ContentTypeSettings", id: "LIST" },
|
2596
|
-
// Is this necessary?
|
2597
|
-
{ type: "InitialData" }
|
2598
|
-
]
|
2599
|
-
})
|
2600
|
-
})
|
2601
|
-
});
|
2602
|
-
const {
|
2603
|
-
useGetContentTypeConfigurationQuery,
|
2604
|
-
useGetAllContentTypeSettingsQuery,
|
2605
|
-
useUpdateContentTypeConfigurationMutation
|
2606
|
-
} = contentTypesApi;
|
2607
|
-
const checkIfAttributeIsDisplayable = (attribute) => {
|
2608
|
-
const { type } = attribute;
|
2609
|
-
if (type === "relation") {
|
2610
|
-
return !attribute.relation.toLowerCase().includes("morph");
|
2611
|
-
}
|
2612
|
-
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2613
|
-
};
|
2614
|
-
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2615
|
-
if (!mainFieldName) {
|
2616
|
-
return void 0;
|
2617
|
-
}
|
2618
|
-
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2619
|
-
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2620
|
-
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2621
|
-
);
|
2622
|
-
return {
|
2623
|
-
name: mainFieldName,
|
2624
|
-
type: mainFieldType ?? "string"
|
2625
|
-
};
|
2626
|
-
};
|
2627
|
-
const DEFAULT_SETTINGS = {
|
2628
|
-
bulkable: false,
|
2629
|
-
filterable: false,
|
2630
|
-
searchable: false,
|
2631
|
-
pagination: false,
|
2632
|
-
defaultSortBy: "",
|
2633
|
-
defaultSortOrder: "asc",
|
2634
|
-
mainField: "id",
|
2635
|
-
pageSize: 10
|
2636
|
-
};
|
2637
|
-
const useDocumentLayout = (model) => {
|
2638
|
-
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2639
|
-
const [{ query }] = useQueryParams();
|
2640
|
-
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2641
|
-
const { toggleNotification } = useNotification();
|
2642
|
-
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
2643
|
-
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2644
|
-
const {
|
2645
|
-
data,
|
2646
|
-
isLoading: isLoadingConfigs,
|
2647
|
-
error,
|
2648
|
-
isFetching: isFetchingConfigs
|
2649
|
-
} = useGetContentTypeConfigurationQuery(model);
|
2650
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2651
|
-
React.useEffect(() => {
|
2652
|
-
if (error) {
|
2653
|
-
toggleNotification({
|
2654
|
-
type: "danger",
|
2655
|
-
message: formatAPIError(error)
|
2656
|
-
});
|
2657
|
-
}
|
2658
|
-
}, [error, formatAPIError, toggleNotification]);
|
2659
|
-
const editLayout = React.useMemo(
|
2660
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2661
|
-
layout: [],
|
2662
|
-
components: {},
|
2663
|
-
metadatas: {},
|
2664
|
-
options: {},
|
2665
|
-
settings: DEFAULT_SETTINGS
|
2666
|
-
},
|
2667
|
-
[data, isLoading, schemas, schema, components]
|
2668
|
-
);
|
2669
|
-
const listLayout = React.useMemo(() => {
|
2670
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2671
|
-
layout: [],
|
2672
|
-
metadatas: {},
|
2673
|
-
options: {},
|
2674
|
-
settings: DEFAULT_SETTINGS
|
2675
|
-
};
|
2676
|
-
}, [data, isLoading, schemas, schema, components]);
|
2677
|
-
const { layout: edit } = React.useMemo(
|
2678
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2679
|
-
layout: editLayout,
|
2680
|
-
query
|
2681
|
-
}),
|
2682
|
-
[editLayout, query, runHookWaterfall]
|
2683
|
-
);
|
2684
|
-
return {
|
2685
|
-
error,
|
2686
|
-
isLoading,
|
2687
|
-
edit,
|
2688
|
-
list: listLayout
|
2689
|
-
};
|
2690
|
-
};
|
2691
|
-
const useDocLayout = () => {
|
2692
|
-
const { model } = useDoc();
|
2693
|
-
return useDocumentLayout(model);
|
2694
|
-
};
|
2695
|
-
const formatEditLayout = (data, {
|
2696
|
-
schemas,
|
2697
|
-
schema,
|
2698
|
-
components
|
2699
|
-
}) => {
|
2700
|
-
let currentPanelIndex = 0;
|
2701
|
-
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2702
|
-
data.contentType.layouts.edit,
|
2703
|
-
schema?.attributes,
|
2704
|
-
data.contentType.metadatas,
|
2705
|
-
{ configurations: data.components, schemas: components },
|
2706
|
-
schemas
|
2707
|
-
).reduce((panels, row) => {
|
2708
|
-
if (row.some((field) => field.type === "dynamiczone")) {
|
2709
|
-
panels.push([row]);
|
2710
|
-
currentPanelIndex += 2;
|
2711
|
-
} else {
|
2712
|
-
if (!panels[currentPanelIndex]) {
|
2713
|
-
panels.push([]);
|
2714
|
-
}
|
2715
|
-
panels[currentPanelIndex].push(row);
|
2716
|
-
}
|
2717
|
-
return panels;
|
2718
|
-
}, []);
|
2719
|
-
const componentEditAttributes = Object.entries(data.components).reduce(
|
2720
|
-
(acc, [uid, configuration]) => {
|
2721
|
-
acc[uid] = {
|
2722
|
-
layout: convertEditLayoutToFieldLayouts(
|
2723
|
-
configuration.layouts.edit,
|
2724
|
-
components[uid].attributes,
|
2725
|
-
configuration.metadatas
|
2726
|
-
),
|
2727
|
-
settings: {
|
2728
|
-
...configuration.settings,
|
2729
|
-
icon: components[uid].info.icon,
|
2730
|
-
displayName: components[uid].info.displayName
|
2731
|
-
}
|
2732
|
-
};
|
2733
|
-
return acc;
|
2734
|
-
},
|
2735
|
-
{}
|
2736
|
-
);
|
2737
|
-
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2738
|
-
(acc, [attribute, metadata]) => {
|
2739
|
-
return {
|
2740
|
-
...acc,
|
2741
|
-
[attribute]: metadata.edit
|
2742
|
-
};
|
2743
|
-
},
|
2744
|
-
{}
|
2745
|
-
);
|
2746
|
-
return {
|
2747
|
-
layout: panelledEditAttributes,
|
2748
|
-
components: componentEditAttributes,
|
2749
|
-
metadatas: editMetadatas,
|
2750
|
-
settings: {
|
2751
|
-
...data.contentType.settings,
|
2752
|
-
displayName: schema?.info.displayName
|
2753
|
-
},
|
2754
|
-
options: {
|
2755
|
-
...schema?.options,
|
2756
|
-
...schema?.pluginOptions,
|
2757
|
-
...data.contentType.options
|
2758
|
-
}
|
2759
|
-
};
|
2760
|
-
};
|
2761
|
-
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
2762
|
-
return rows.map(
|
2763
|
-
(row) => row.map((field) => {
|
2764
|
-
const attribute = attributes[field.name];
|
2765
|
-
if (!attribute) {
|
2766
|
-
return null;
|
2767
|
-
}
|
2768
|
-
const { edit: metadata } = metadatas[field.name];
|
2769
|
-
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
2770
|
-
return {
|
2771
|
-
attribute,
|
2772
|
-
disabled: !metadata.editable,
|
2773
|
-
hint: metadata.description,
|
2774
|
-
label: metadata.label ?? "",
|
2775
|
-
name: field.name,
|
2776
|
-
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
2777
|
-
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
2778
|
-
schemas,
|
2779
|
-
components: components?.schemas ?? {}
|
2780
|
-
}),
|
2781
|
-
placeholder: metadata.placeholder ?? "",
|
2782
|
-
required: attribute.required ?? false,
|
2783
|
-
size: field.size,
|
2784
|
-
unique: "unique" in attribute ? attribute.unique : false,
|
2785
|
-
visible: metadata.visible ?? true,
|
2786
|
-
type: attribute.type
|
2787
|
-
};
|
2788
|
-
}).filter((field) => field !== null)
|
2789
|
-
);
|
2790
|
-
};
|
2791
|
-
const formatListLayout = (data, {
|
2792
|
-
schemas,
|
2793
|
-
schema,
|
2794
|
-
components
|
2795
|
-
}) => {
|
2796
|
-
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2797
|
-
(acc, [attribute, metadata]) => {
|
2798
|
-
return {
|
2799
|
-
...acc,
|
2800
|
-
[attribute]: metadata.list
|
2801
|
-
};
|
2802
|
-
},
|
2803
|
-
{}
|
2804
|
-
);
|
2805
|
-
const listAttributes = convertListLayoutToFieldLayouts(
|
2806
|
-
data.contentType.layouts.list,
|
2807
|
-
schema?.attributes,
|
2808
|
-
listMetadatas,
|
2809
|
-
{ configurations: data.components, schemas: components },
|
2810
|
-
schemas
|
2811
|
-
);
|
2812
|
-
return {
|
2813
|
-
layout: listAttributes,
|
2814
|
-
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
2815
|
-
metadatas: listMetadatas,
|
2816
|
-
options: {
|
2817
|
-
...schema?.options,
|
2818
|
-
...schema?.pluginOptions,
|
2819
|
-
...data.contentType.options
|
2820
|
-
}
|
2821
|
-
};
|
2822
|
-
};
|
2823
|
-
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
2824
|
-
return columns.map((name) => {
|
2825
|
-
const attribute = attributes[name];
|
2826
|
-
if (!attribute) {
|
2827
|
-
return null;
|
2828
|
-
}
|
2829
|
-
const metadata = metadatas[name];
|
2830
|
-
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
2831
|
-
return {
|
2832
|
-
attribute,
|
2833
|
-
label: metadata.label ?? "",
|
2834
|
-
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
2835
|
-
schemas,
|
2836
|
-
components: components?.schemas ?? {}
|
2837
|
-
}),
|
2838
|
-
name,
|
2839
|
-
searchable: metadata.searchable ?? true,
|
2840
|
-
sortable: metadata.sortable ?? true
|
2841
|
-
};
|
2842
|
-
}).filter((field) => field !== null);
|
2843
|
-
};
|
2844
3003
|
const ConfirmBulkActionDialog = ({
|
2845
3004
|
onToggleDialog,
|
2846
3005
|
isOpen = false,
|
@@ -2879,6 +3038,7 @@ const ConfirmDialogPublishAll = ({
|
|
2879
3038
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(getTranslation);
|
2880
3039
|
const { model, schema } = useDoc();
|
2881
3040
|
const [{ query }] = useQueryParams();
|
3041
|
+
const enableDraftRelationsCount = false;
|
2882
3042
|
const {
|
2883
3043
|
data: countDraftRelations = 0,
|
2884
3044
|
isLoading,
|
@@ -2890,7 +3050,7 @@ const ConfirmDialogPublishAll = ({
|
|
2890
3050
|
locale: query?.plugins?.i18n?.locale
|
2891
3051
|
},
|
2892
3052
|
{
|
2893
|
-
skip:
|
3053
|
+
skip: !enableDraftRelationsCount
|
2894
3054
|
}
|
2895
3055
|
);
|
2896
3056
|
React.useEffect(() => {
|
@@ -3075,7 +3235,7 @@ const SelectedEntriesTableContent = ({
|
|
3075
3235
|
status: row.status
|
3076
3236
|
}
|
3077
3237
|
) }),
|
3078
|
-
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(
|
3238
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
|
3079
3239
|
IconButton,
|
3080
3240
|
{
|
3081
3241
|
tag: Link,
|
@@ -3098,9 +3258,10 @@ const SelectedEntriesTableContent = ({
|
|
3098
3258
|
),
|
3099
3259
|
target: "_blank",
|
3100
3260
|
marginLeft: "auto",
|
3101
|
-
|
3261
|
+
variant: "ghost",
|
3262
|
+
children: /* @__PURE__ */ jsx(Pencil, { width: "1.6rem", height: "1.6rem" })
|
3102
3263
|
}
|
3103
|
-
) })
|
3264
|
+
) }) })
|
3104
3265
|
] }, row.id)) })
|
3105
3266
|
] });
|
3106
3267
|
};
|
@@ -3137,7 +3298,13 @@ const SelectedEntriesModalContent = ({
|
|
3137
3298
|
);
|
3138
3299
|
const { rows, validationErrors } = React.useMemo(() => {
|
3139
3300
|
if (data.length > 0 && schema) {
|
3140
|
-
const validate = createYupSchema(
|
3301
|
+
const validate = createYupSchema(
|
3302
|
+
schema.attributes,
|
3303
|
+
components,
|
3304
|
+
// Since this is the "Publish" action, the validation
|
3305
|
+
// schema must enforce the rules for published entities
|
3306
|
+
{ status: "published" }
|
3307
|
+
);
|
3141
3308
|
const validationErrors2 = {};
|
3142
3309
|
const rows2 = data.map((entry) => {
|
3143
3310
|
try {
|
@@ -3487,7 +3654,7 @@ const TableActions = ({ document }) => {
|
|
3487
3654
|
DescriptionComponentRenderer,
|
3488
3655
|
{
|
3489
3656
|
props,
|
3490
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3657
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
3491
3658
|
children: (actions2) => {
|
3492
3659
|
const tableRowActions = actions2.filter((action) => {
|
3493
3660
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3598,7 +3765,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3598
3765
|
}),
|
3599
3766
|
content: /* @__PURE__ */ jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
3600
3767
|
footer: ({ onClose }) => {
|
3601
|
-
return /* @__PURE__ */ jsxs(
|
3768
|
+
return /* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
3602
3769
|
/* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
3603
3770
|
id: "cancel",
|
3604
3771
|
defaultMessage: "Cancel"
|
@@ -3829,7 +3996,7 @@ const index = {
|
|
3829
3996
|
app.router.addRoute({
|
3830
3997
|
path: "content-manager/*",
|
3831
3998
|
lazy: async () => {
|
3832
|
-
const { Layout } = await import("./layout-
|
3999
|
+
const { Layout } = await import("./layout-N63eyE5E.mjs");
|
3833
4000
|
return {
|
3834
4001
|
Component: Layout
|
3835
4002
|
};
|
@@ -3846,7 +4013,7 @@ const index = {
|
|
3846
4013
|
async registerTrads({ locales }) {
|
3847
4014
|
const importedTrads = await Promise.all(
|
3848
4015
|
locales.map((locale) => {
|
3849
|
-
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-
|
4016
|
+
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-DKV44jRb.mjs"), "./translations/es.json": () => import("./es-CeXiYflN.mjs"), "./translations/eu.json": () => import("./eu-CdALomew.mjs"), "./translations/fr.json": () => import("./fr-CD9VFbPM.mjs"), "./translations/gu.json": () => import("./gu-CNpaMDpH.mjs"), "./translations/hi.json": () => import("./hi-Dwvd04m3.mjs"), "./translations/hu.json": () => import("./hu-CeYvaaO0.mjs"), "./translations/id.json": () => import("./id-BtwA9WJT.mjs"), "./translations/it.json": () => import("./it-BrVPqaf1.mjs"), "./translations/ja.json": () => import("./ja-CtsUxOvk.mjs"), "./translations/ko.json": () => import("./ko-HVQRlfUI.mjs"), "./translations/ml.json": () => import("./ml-BihZwQit.mjs"), "./translations/ms.json": () => import("./ms-m_WjyWx7.mjs"), "./translations/nl.json": () => import("./nl-D4R9gHx5.mjs"), "./translations/pl.json": () => import("./pl-sbx9mSt_.mjs"), "./translations/pt-BR.json": () => import("./pt-BR-C71iDxnh.mjs"), "./translations/pt.json": () => import("./pt-BsaFvS8-.mjs"), "./translations/ru.json": () => import("./ru-BE6A4Exp.mjs"), "./translations/sa.json": () => import("./sa-Dag0k-Z8.mjs"), "./translations/sk.json": () => import("./sk-BFg-R8qJ.mjs"), "./translations/sv.json": () => import("./sv-CUnfWGsh.mjs"), "./translations/th.json": () => import("./th-BqbI8lIT.mjs"), "./translations/tr.json": () => import("./tr-CgeK3wJM.mjs"), "./translations/uk.json": () => import("./uk-CR-zDhAY.mjs"), "./translations/vi.json": () => import("./vi-DUXIk_fw.mjs"), "./translations/zh-Hans.json": () => import("./zh-Hans-BPQcRIyH.mjs"), "./translations/zh.json": () => import("./zh-BWZspA60.mjs") }), `./translations/${locale}.json`).then(({ default: data }) => {
|
3850
4017
|
return {
|
3851
4018
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3852
4019
|
locale
|
@@ -3867,13 +4034,15 @@ export {
|
|
3867
4034
|
BulkActionsRenderer as B,
|
3868
4035
|
COLLECTION_TYPES as C,
|
3869
4036
|
DocumentStatus as D,
|
3870
|
-
|
3871
|
-
|
3872
|
-
|
4037
|
+
extractContentTypeComponents as E,
|
4038
|
+
DEFAULT_SETTINGS as F,
|
4039
|
+
convertEditLayoutToFieldLayouts as G,
|
3873
4040
|
HOOKS as H,
|
3874
4041
|
InjectionZone as I,
|
3875
|
-
|
3876
|
-
|
4042
|
+
useDocument as J,
|
4043
|
+
index as K,
|
4044
|
+
useContentManagerContext as L,
|
4045
|
+
useDocumentActions as M,
|
3877
4046
|
Panels as P,
|
3878
4047
|
RelativeTime as R,
|
3879
4048
|
SINGLE_TYPES as S,
|
@@ -3891,18 +4060,18 @@ export {
|
|
3891
4060
|
PERMISSIONS as k,
|
3892
4061
|
DocumentRBAC as l,
|
3893
4062
|
DOCUMENT_META_FIELDS as m,
|
3894
|
-
|
3895
|
-
|
3896
|
-
|
3897
|
-
|
3898
|
-
|
4063
|
+
CLONE_PATH as n,
|
4064
|
+
useDocLayout as o,
|
4065
|
+
useGetContentTypeConfigurationQuery as p,
|
4066
|
+
CREATOR_FIELDS as q,
|
4067
|
+
getMainField as r,
|
3899
4068
|
setInitialData as s,
|
3900
|
-
|
4069
|
+
getDisplayName as t,
|
3901
4070
|
useContentTypeSchema as u,
|
3902
|
-
|
3903
|
-
|
3904
|
-
|
3905
|
-
|
3906
|
-
|
4071
|
+
checkIfAttributeIsDisplayable as v,
|
4072
|
+
useGetAllDocumentsQuery as w,
|
4073
|
+
convertListLayoutToFieldLayouts as x,
|
4074
|
+
capitalise as y,
|
4075
|
+
useUpdateContentTypeConfigurationMutation as z
|
3907
4076
|
};
|
3908
|
-
//# sourceMappingURL=index-
|
4077
|
+
//# sourceMappingURL=index-BQ8DxaCa.mjs.map
|