@strapi/content-manager 0.0.0-experimental.25e22c6cc9bc6b35392bb55d09f641a0a65e7403 → 0.0.0-experimental.2cfaca2410c03f1dee31ca18c06aedfb313e0fb4
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/{ComponentConfigurationPage-WRPUXGd6.js → ComponentConfigurationPage-DnnZJc1F.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-WRPUXGd6.js.map → ComponentConfigurationPage-DnnZJc1F.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-gdUj_t-O.mjs → ComponentConfigurationPage-hLMNf7KI.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-gdUj_t-O.mjs.map → ComponentConfigurationPage-hLMNf7KI.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-C1vjMBgy.js → EditConfigurationPage-CpLj5gYZ.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-C1vjMBgy.js.map → EditConfigurationPage-CpLj5gYZ.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-BwuIPOJG.mjs → EditConfigurationPage-Dh6sq-G4.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-BwuIPOJG.mjs.map → EditConfigurationPage-Dh6sq-G4.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-0MiFkXa8.mjs → EditViewPage-BU1ugeVi.mjs} +19 -8
- package/dist/_chunks/EditViewPage-BU1ugeVi.mjs.map +1 -0
- package/dist/_chunks/{EditViewPage-DbcGfyqK.js → EditViewPage-D2QVRr_2.js} +19 -8
- package/dist/_chunks/EditViewPage-D2QVRr_2.js.map +1 -0
- package/dist/_chunks/{Field-BG1xu38N.js → Field-BEDX9i_V.js} +465 -145
- package/dist/_chunks/Field-BEDX9i_V.js.map +1 -0
- package/dist/_chunks/{Field-BDMSCcy5.mjs → Field-VSPY6uzs.mjs} +463 -143
- package/dist/_chunks/Field-VSPY6uzs.mjs.map +1 -0
- package/dist/_chunks/{Form-CPVWavB8.mjs → Form-05Oaes1N.mjs} +39 -17
- package/dist/_chunks/Form-05Oaes1N.mjs.map +1 -0
- package/dist/_chunks/{Form-9BnFyUjy.js → Form-DCaY8xBX.js} +39 -17
- package/dist/_chunks/Form-DCaY8xBX.js.map +1 -0
- package/dist/_chunks/{History-BVpd8LP3.mjs → History-BqO2G3MV.mjs} +44 -19
- package/dist/_chunks/History-BqO2G3MV.mjs.map +1 -0
- package/dist/_chunks/{History-BWWxLt2Z.js → History-BrJ1tUvt.js} +44 -19
- package/dist/_chunks/History-BrJ1tUvt.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DozVMKcR.mjs → ListConfigurationPage-C6rsFlme.mjs} +20 -8
- package/dist/_chunks/ListConfigurationPage-C6rsFlme.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-6swzjdAZ.js → ListConfigurationPage-Eane5LKE.js} +20 -8
- package/dist/_chunks/ListConfigurationPage-Eane5LKE.js.map +1 -0
- package/dist/_chunks/{ListViewPage-BlzfjS2Q.js → ListViewPage-Coj-RPsx.js} +61 -43
- package/dist/_chunks/ListViewPage-Coj-RPsx.js.map +1 -0
- package/dist/_chunks/{ListViewPage-Ds0ulgfG.mjs → ListViewPage-yE_zYhcI.mjs} +59 -41
- package/dist/_chunks/ListViewPage-yE_zYhcI.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-D2nCCWEl.js → NoContentTypePage-BDJ0dshy.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-D2nCCWEl.js.map → NoContentTypePage-BDJ0dshy.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-BH11kaKt.mjs → NoContentTypePage-NW_FSVdY.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-BH11kaKt.mjs.map → NoContentTypePage-NW_FSVdY.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-DN_JlsU2.js → NoPermissionsPage-BOtb5FTM.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-DN_JlsU2.js.map → NoPermissionsPage-BOtb5FTM.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-BT2Tn0D_.mjs → NoPermissionsPage-h0I3ImsX.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-BT2Tn0D_.mjs.map → NoPermissionsPage-h0I3ImsX.mjs.map} +1 -1
- package/dist/_chunks/{Relations-CcgFTcWo.js → Relations-CVh0DOKv.js} +4 -4
- package/dist/_chunks/Relations-CVh0DOKv.js.map +1 -0
- package/dist/_chunks/{Relations-Dnag3fhV.mjs → Relations-FP0uWpBz.mjs} +4 -4
- package/dist/_chunks/Relations-FP0uWpBz.mjs.map +1 -0
- package/dist/_chunks/{en-fbKQxLGn.js → en-BlhnxQfj.js} +11 -9
- package/dist/_chunks/{en-fbKQxLGn.js.map → en-BlhnxQfj.js.map} +1 -1
- package/dist/_chunks/{en-Ux26r5pl.mjs → en-C8YBvRrK.mjs} +11 -9
- package/dist/_chunks/{en-Ux26r5pl.mjs.map → en-C8YBvRrK.mjs.map} +1 -1
- package/dist/_chunks/{index-JNNNKUHs.mjs → index-CPCHQ3X_.mjs} +976 -658
- package/dist/_chunks/index-CPCHQ3X_.mjs.map +1 -0
- package/dist/_chunks/{index-CWpLBSt0.js → index-DTKVhcla.js} +968 -650
- package/dist/_chunks/index-DTKVhcla.js.map +1 -0
- package/dist/_chunks/{layout-DC503LnF.mjs → layout-B4UhJ8MJ.mjs} +27 -14
- package/dist/_chunks/layout-B4UhJ8MJ.mjs.map +1 -0
- package/dist/_chunks/{layout--iHdZzRk.js → layout-CWgZzMYf.js} +25 -12
- package/dist/_chunks/layout-CWgZzMYf.js.map +1 -0
- package/dist/_chunks/{relations-CTje5t-a.mjs → relations-B83Ge9a7.mjs} +2 -2
- package/dist/_chunks/{relations-CTje5t-a.mjs.map → relations-B83Ge9a7.mjs.map} +1 -1
- package/dist/_chunks/{relations-BbHizA5K.js → relations-D81a_2zw.js} +2 -2
- package/dist/_chunks/{relations-BbHizA5K.js.map → relations-D81a_2zw.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 +3 -2
- package/dist/admin/src/exports.d.ts +1 -1
- package/dist/admin/src/history/index.d.ts +3 -0
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +30 -1
- package/dist/admin/src/index.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +4 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +20 -0
- 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 +10 -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 +185 -113
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +186 -114
- 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-0MiFkXa8.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-DbcGfyqK.js.map +0 -1
- package/dist/_chunks/Field-BDMSCcy5.mjs.map +0 -1
- package/dist/_chunks/Field-BG1xu38N.js.map +0 -1
- package/dist/_chunks/Form-9BnFyUjy.js.map +0 -1
- package/dist/_chunks/Form-CPVWavB8.mjs.map +0 -1
- package/dist/_chunks/History-BVpd8LP3.mjs.map +0 -1
- package/dist/_chunks/History-BWWxLt2Z.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-6swzjdAZ.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DozVMKcR.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-BlzfjS2Q.js.map +0 -1
- package/dist/_chunks/ListViewPage-Ds0ulgfG.mjs.map +0 -1
- package/dist/_chunks/Relations-CcgFTcWo.js.map +0 -1
- package/dist/_chunks/Relations-Dnag3fhV.mjs.map +0 -1
- package/dist/_chunks/index-CWpLBSt0.js.map +0 -1
- package/dist/_chunks/index-JNNNKUHs.mjs.map +0 -1
- package/dist/_chunks/layout--iHdZzRk.js.map +0 -1
- package/dist/_chunks/layout-DC503LnF.mjs.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
@@ -2,15 +2,15 @@
|
|
2
2
|
const Icons = require("@strapi/icons");
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
4
4
|
const strapiAdmin = require("@strapi/admin/strapi-admin");
|
5
|
-
const qs = require("qs");
|
6
|
-
const reactIntl = require("react-intl");
|
7
|
-
const reactRouterDom = require("react-router-dom");
|
8
5
|
const React = require("react");
|
9
6
|
const designSystem = require("@strapi/design-system");
|
10
|
-
const
|
7
|
+
const reactIntl = require("react-intl");
|
8
|
+
const reactRouterDom = require("react-router-dom");
|
11
9
|
const yup = require("yup");
|
12
10
|
const pipe = require("lodash/fp/pipe");
|
13
11
|
const dateFns = require("date-fns");
|
12
|
+
const styledComponents = require("styled-components");
|
13
|
+
const qs = require("qs");
|
14
14
|
const toolkit = require("@reduxjs/toolkit");
|
15
15
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
16
16
|
function _interopNamespace(e) {
|
@@ -70,42 +70,6 @@ const useInjectionZone = (area) => {
|
|
70
70
|
const [page, position] = area.split(".");
|
71
71
|
return contentManagerPlugin.getInjectedComponents(page, position);
|
72
72
|
};
|
73
|
-
const HistoryAction = ({ model, document }) => {
|
74
|
-
const { formatMessage } = reactIntl.useIntl();
|
75
|
-
const [{ query }] = strapiAdmin.useQueryParams();
|
76
|
-
const navigate = reactRouterDom.useNavigate();
|
77
|
-
const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
|
78
|
-
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
79
|
-
return null;
|
80
|
-
}
|
81
|
-
return {
|
82
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
|
83
|
-
label: formatMessage({
|
84
|
-
id: "content-manager.history.document-action",
|
85
|
-
defaultMessage: "Content History"
|
86
|
-
}),
|
87
|
-
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
88
|
-
disabled: (
|
89
|
-
/**
|
90
|
-
* The user is creating a new document.
|
91
|
-
* It hasn't been saved yet, so there's no history to go to
|
92
|
-
*/
|
93
|
-
!document || /**
|
94
|
-
* The document has been created but the current dimension has never been saved.
|
95
|
-
* For example, the user is creating a new locale in an existing document,
|
96
|
-
* so there's no history for the document in that locale
|
97
|
-
*/
|
98
|
-
!document.id || /**
|
99
|
-
* History is only available for content types created by the user.
|
100
|
-
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
101
|
-
* which start with `admin::` or `plugin::`
|
102
|
-
*/
|
103
|
-
!model.startsWith("api::")
|
104
|
-
),
|
105
|
-
position: "header"
|
106
|
-
};
|
107
|
-
};
|
108
|
-
HistoryAction.type = "history";
|
109
73
|
const ID = "id";
|
110
74
|
const CREATED_BY_ATTRIBUTE_NAME = "createdBy";
|
111
75
|
const UPDATED_BY_ATTRIBUTE_NAME = "updatedBy";
|
@@ -215,10 +179,12 @@ const contentManagerApi = strapiAdmin.adminApi.enhanceEndpoints({
|
|
215
179
|
"Document",
|
216
180
|
"InitialData",
|
217
181
|
"HistoryVersion",
|
218
|
-
"Relations"
|
182
|
+
"Relations",
|
183
|
+
"UidAvailability"
|
219
184
|
]
|
220
185
|
});
|
221
186
|
const documentApi = contentManagerApi.injectEndpoints({
|
187
|
+
overrideExisting: true,
|
222
188
|
endpoints: (builder) => ({
|
223
189
|
autoCloneDocument: builder.mutation({
|
224
190
|
query: ({ model, sourceId, query }) => ({
|
@@ -228,7 +194,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
228
194
|
params: query
|
229
195
|
}
|
230
196
|
}),
|
231
|
-
invalidatesTags: (_result,
|
197
|
+
invalidatesTags: (_result, error, { model }) => {
|
198
|
+
if (error) {
|
199
|
+
return [];
|
200
|
+
}
|
201
|
+
return [{ type: "Document", id: `${model}_LIST` }];
|
202
|
+
}
|
232
203
|
}),
|
233
204
|
cloneDocument: builder.mutation({
|
234
205
|
query: ({ model, sourceId, data, params }) => ({
|
@@ -239,7 +210,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
239
210
|
params
|
240
211
|
}
|
241
212
|
}),
|
242
|
-
invalidatesTags: (_result, _error, { model }) => [
|
213
|
+
invalidatesTags: (_result, _error, { model }) => [
|
214
|
+
{ type: "Document", id: `${model}_LIST` },
|
215
|
+
{ type: "UidAvailability", id: model }
|
216
|
+
]
|
243
217
|
}),
|
244
218
|
/**
|
245
219
|
* Creates a new collection-type document. This should ONLY be used for collection-types.
|
@@ -256,7 +230,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
256
230
|
}),
|
257
231
|
invalidatesTags: (result, _error, { model }) => [
|
258
232
|
{ type: "Document", id: `${model}_LIST` },
|
259
|
-
"Relations"
|
233
|
+
"Relations",
|
234
|
+
{ type: "UidAvailability", id: model }
|
260
235
|
]
|
261
236
|
}),
|
262
237
|
deleteDocument: builder.mutation({
|
@@ -297,7 +272,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
297
272
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
298
273
|
},
|
299
274
|
{ type: "Document", id: `${model}_LIST` },
|
300
|
-
"Relations"
|
275
|
+
"Relations",
|
276
|
+
{ type: "UidAvailability", id: model }
|
301
277
|
];
|
302
278
|
}
|
303
279
|
}),
|
@@ -315,6 +291,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
315
291
|
}),
|
316
292
|
providesTags: (result, _error, arg) => {
|
317
293
|
return [
|
294
|
+
{ type: "Document", id: `ALL_LIST` },
|
318
295
|
{ type: "Document", id: `${arg.model}_LIST` },
|
319
296
|
...result?.results.map(({ documentId }) => ({
|
320
297
|
type: "Document",
|
@@ -353,6 +330,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
353
330
|
{
|
354
331
|
type: "Document",
|
355
332
|
id: collectionType !== SINGLE_TYPES ? `${model}_${result && "documentId" in result ? result.documentId : documentId}` : model
|
333
|
+
},
|
334
|
+
// Make it easy to invalidate all individual documents queries for a model
|
335
|
+
{
|
336
|
+
type: "Document",
|
337
|
+
id: `${model}_ALL_ITEMS`
|
356
338
|
}
|
357
339
|
];
|
358
340
|
}
|
@@ -416,8 +398,21 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
416
398
|
type: "Document",
|
417
399
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
418
400
|
},
|
419
|
-
"Relations"
|
401
|
+
"Relations",
|
402
|
+
{ type: "UidAvailability", id: model }
|
420
403
|
];
|
404
|
+
},
|
405
|
+
async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
|
406
|
+
const patchResult = dispatch(
|
407
|
+
documentApi.util.updateQueryData("getDocument", patch, (draft) => {
|
408
|
+
Object.assign(draft.data, data);
|
409
|
+
})
|
410
|
+
);
|
411
|
+
try {
|
412
|
+
await queryFulfilled;
|
413
|
+
} catch {
|
414
|
+
patchResult.undo();
|
415
|
+
}
|
421
416
|
}
|
422
417
|
}),
|
423
418
|
unpublishDocument: builder.mutation({
|
@@ -487,7 +482,7 @@ const buildValidParams = (query) => {
|
|
487
482
|
const isBaseQueryError = (error) => {
|
488
483
|
return error.name !== void 0;
|
489
484
|
};
|
490
|
-
const createYupSchema = (attributes = {}, components = {}) => {
|
485
|
+
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
491
486
|
const createModelSchema = (attributes2) => yup__namespace.object().shape(
|
492
487
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
493
488
|
if (DOCUMENT_META_FIELDS.includes(name)) {
|
@@ -500,7 +495,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
500
495
|
addMinValidation,
|
501
496
|
addMaxValidation,
|
502
497
|
addRegexValidation
|
503
|
-
].map((fn) => fn(attribute));
|
498
|
+
].map((fn) => fn(attribute, options));
|
504
499
|
const transformSchema = pipe__default.default(...validations);
|
505
500
|
switch (attribute.type) {
|
506
501
|
case "component": {
|
@@ -601,6 +596,14 @@ const createAttributeSchema = (attribute) => {
|
|
601
596
|
if (!value || typeof value === "string" && value.length === 0) {
|
602
597
|
return true;
|
603
598
|
}
|
599
|
+
if (typeof value === "object") {
|
600
|
+
try {
|
601
|
+
JSON.stringify(value);
|
602
|
+
return true;
|
603
|
+
} catch (err) {
|
604
|
+
return false;
|
605
|
+
}
|
606
|
+
}
|
604
607
|
try {
|
605
608
|
JSON.parse(value);
|
606
609
|
return true;
|
@@ -619,13 +622,7 @@ const createAttributeSchema = (attribute) => {
|
|
619
622
|
return yup__namespace.mixed();
|
620
623
|
}
|
621
624
|
};
|
622
|
-
const
|
623
|
-
if (attribute.required) {
|
624
|
-
return schema.required({
|
625
|
-
id: strapiAdmin.translatedErrors.required.id,
|
626
|
-
defaultMessage: "This field is required."
|
627
|
-
});
|
628
|
-
}
|
625
|
+
const nullableSchema = (schema) => {
|
629
626
|
return schema?.nullable ? schema.nullable() : (
|
630
627
|
// In some cases '.nullable' will not be available on the schema.
|
631
628
|
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
@@ -633,7 +630,22 @@ const addRequiredValidation = (attribute) => (schema) => {
|
|
633
630
|
schema
|
634
631
|
);
|
635
632
|
};
|
636
|
-
const
|
633
|
+
const addRequiredValidation = (attribute, options) => (schema) => {
|
634
|
+
if (options.status === "draft") {
|
635
|
+
return nullableSchema(schema);
|
636
|
+
}
|
637
|
+
if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
|
638
|
+
return schema.min(1, strapiAdmin.translatedErrors.required);
|
639
|
+
}
|
640
|
+
if (attribute.required && attribute.type !== "relation") {
|
641
|
+
return schema.required(strapiAdmin.translatedErrors.required);
|
642
|
+
}
|
643
|
+
return nullableSchema(schema);
|
644
|
+
};
|
645
|
+
const addMinLengthValidation = (attribute, options) => (schema) => {
|
646
|
+
if (options.status === "draft") {
|
647
|
+
return schema;
|
648
|
+
}
|
637
649
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
638
650
|
return schema.min(attribute.minLength, {
|
639
651
|
...strapiAdmin.translatedErrors.minLength,
|
@@ -655,9 +667,31 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
655
667
|
}
|
656
668
|
return schema;
|
657
669
|
};
|
658
|
-
const addMinValidation = (attribute) => (schema) => {
|
670
|
+
const addMinValidation = (attribute, options) => (schema) => {
|
659
671
|
if ("min" in attribute) {
|
660
672
|
const min = toInteger(attribute.min);
|
673
|
+
if (attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") {
|
674
|
+
if (options.status !== "draft" && !attribute.required && "test" in schema && min) {
|
675
|
+
return schema.test(
|
676
|
+
"custom-min",
|
677
|
+
{
|
678
|
+
...strapiAdmin.translatedErrors.min,
|
679
|
+
values: {
|
680
|
+
min: attribute.min
|
681
|
+
}
|
682
|
+
},
|
683
|
+
(value) => {
|
684
|
+
if (!value) {
|
685
|
+
return true;
|
686
|
+
}
|
687
|
+
if (Array.isArray(value) && value.length === 0) {
|
688
|
+
return true;
|
689
|
+
}
|
690
|
+
return value.length >= min;
|
691
|
+
}
|
692
|
+
);
|
693
|
+
}
|
694
|
+
}
|
661
695
|
if ("min" in schema && min) {
|
662
696
|
return schema.min(min, {
|
663
697
|
...strapiAdmin.translatedErrors.min,
|
@@ -776,16 +810,115 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
|
|
776
810
|
}, {});
|
777
811
|
return componentsByKey;
|
778
812
|
};
|
779
|
-
const
|
813
|
+
const HOOKS = {
|
814
|
+
/**
|
815
|
+
* Hook that allows to mutate the displayed headers of the list view table
|
816
|
+
* @constant
|
817
|
+
* @type {string}
|
818
|
+
*/
|
819
|
+
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
820
|
+
/**
|
821
|
+
* Hook that allows to mutate the CM's collection types links pre-set filters
|
822
|
+
* @constant
|
823
|
+
* @type {string}
|
824
|
+
*/
|
825
|
+
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
826
|
+
/**
|
827
|
+
* Hook that allows to mutate the CM's edit view layout
|
828
|
+
* @constant
|
829
|
+
* @type {string}
|
830
|
+
*/
|
831
|
+
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
832
|
+
/**
|
833
|
+
* Hook that allows to mutate the CM's single types links pre-set filters
|
834
|
+
* @constant
|
835
|
+
* @type {string}
|
836
|
+
*/
|
837
|
+
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
838
|
+
};
|
839
|
+
const contentTypesApi = contentManagerApi.injectEndpoints({
|
840
|
+
endpoints: (builder) => ({
|
841
|
+
getContentTypeConfiguration: builder.query({
|
842
|
+
query: (uid) => ({
|
843
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
844
|
+
method: "GET"
|
845
|
+
}),
|
846
|
+
transformResponse: (response) => response.data,
|
847
|
+
providesTags: (_result, _error, uid) => [
|
848
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
849
|
+
{ type: "ContentTypeSettings", id: "LIST" }
|
850
|
+
]
|
851
|
+
}),
|
852
|
+
getAllContentTypeSettings: builder.query({
|
853
|
+
query: () => "/content-manager/content-types-settings",
|
854
|
+
transformResponse: (response) => response.data,
|
855
|
+
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
856
|
+
}),
|
857
|
+
updateContentTypeConfiguration: builder.mutation({
|
858
|
+
query: ({ uid, ...body }) => ({
|
859
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
860
|
+
method: "PUT",
|
861
|
+
data: body
|
862
|
+
}),
|
863
|
+
transformResponse: (response) => response.data,
|
864
|
+
invalidatesTags: (_result, _error, { uid }) => [
|
865
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
866
|
+
{ type: "ContentTypeSettings", id: "LIST" },
|
867
|
+
// Is this necessary?
|
868
|
+
{ type: "InitialData" }
|
869
|
+
]
|
870
|
+
})
|
871
|
+
})
|
872
|
+
});
|
873
|
+
const {
|
874
|
+
useGetContentTypeConfigurationQuery,
|
875
|
+
useGetAllContentTypeSettingsQuery,
|
876
|
+
useUpdateContentTypeConfigurationMutation
|
877
|
+
} = contentTypesApi;
|
878
|
+
const checkIfAttributeIsDisplayable = (attribute) => {
|
879
|
+
const { type } = attribute;
|
880
|
+
if (type === "relation") {
|
881
|
+
return !attribute.relation.toLowerCase().includes("morph");
|
882
|
+
}
|
883
|
+
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
884
|
+
};
|
885
|
+
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
886
|
+
if (!mainFieldName) {
|
887
|
+
return void 0;
|
888
|
+
}
|
889
|
+
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
890
|
+
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
891
|
+
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
892
|
+
);
|
893
|
+
return {
|
894
|
+
name: mainFieldName,
|
895
|
+
type: mainFieldType ?? "string"
|
896
|
+
};
|
897
|
+
};
|
898
|
+
const DEFAULT_SETTINGS = {
|
899
|
+
bulkable: false,
|
900
|
+
filterable: false,
|
901
|
+
searchable: false,
|
902
|
+
pagination: false,
|
903
|
+
defaultSortBy: "",
|
904
|
+
defaultSortOrder: "asc",
|
905
|
+
mainField: "id",
|
906
|
+
pageSize: 10
|
907
|
+
};
|
908
|
+
const useDocumentLayout = (model) => {
|
909
|
+
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
910
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
911
|
+
const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
780
912
|
const { toggleNotification } = strapiAdmin.useNotification();
|
781
913
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
914
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
782
915
|
const {
|
783
|
-
|
784
|
-
isLoading:
|
785
|
-
|
786
|
-
|
787
|
-
} =
|
788
|
-
const
|
916
|
+
data,
|
917
|
+
isLoading: isLoadingConfigs,
|
918
|
+
error,
|
919
|
+
isFetching: isFetchingConfigs
|
920
|
+
} = useGetContentTypeConfigurationQuery(model);
|
921
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
789
922
|
React__namespace.useEffect(() => {
|
790
923
|
if (error) {
|
791
924
|
toggleNotification({
|
@@ -793,54 +926,267 @@ const useDocument = (args, opts) => {
|
|
793
926
|
message: formatAPIError(error)
|
794
927
|
});
|
795
928
|
}
|
796
|
-
}, [
|
797
|
-
const
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
(document) => {
|
805
|
-
if (!validationSchema) {
|
806
|
-
throw new Error(
|
807
|
-
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
808
|
-
);
|
809
|
-
}
|
810
|
-
try {
|
811
|
-
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
812
|
-
return null;
|
813
|
-
} catch (error2) {
|
814
|
-
if (error2 instanceof yup.ValidationError) {
|
815
|
-
return strapiAdmin.getYupValidationErrors(error2);
|
816
|
-
}
|
817
|
-
throw error2;
|
818
|
-
}
|
929
|
+
}, [error, formatAPIError, toggleNotification]);
|
930
|
+
const editLayout = React__namespace.useMemo(
|
931
|
+
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
932
|
+
layout: [],
|
933
|
+
components: {},
|
934
|
+
metadatas: {},
|
935
|
+
options: {},
|
936
|
+
settings: DEFAULT_SETTINGS
|
819
937
|
},
|
820
|
-
[
|
938
|
+
[data, isLoading, schemas, schema, components]
|
939
|
+
);
|
940
|
+
const listLayout = React__namespace.useMemo(() => {
|
941
|
+
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
942
|
+
layout: [],
|
943
|
+
metadatas: {},
|
944
|
+
options: {},
|
945
|
+
settings: DEFAULT_SETTINGS
|
946
|
+
};
|
947
|
+
}, [data, isLoading, schemas, schema, components]);
|
948
|
+
const { layout: edit } = React__namespace.useMemo(
|
949
|
+
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
950
|
+
layout: editLayout,
|
951
|
+
query
|
952
|
+
}),
|
953
|
+
[editLayout, query, runHookWaterfall]
|
821
954
|
);
|
822
|
-
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
823
955
|
return {
|
824
|
-
|
825
|
-
document: data?.data,
|
826
|
-
meta: data?.meta,
|
956
|
+
error,
|
827
957
|
isLoading,
|
828
|
-
|
829
|
-
|
958
|
+
edit,
|
959
|
+
list: listLayout
|
830
960
|
};
|
831
961
|
};
|
832
|
-
const
|
833
|
-
const {
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
962
|
+
const useDocLayout = () => {
|
963
|
+
const { model } = useDoc();
|
964
|
+
return useDocumentLayout(model);
|
965
|
+
};
|
966
|
+
const formatEditLayout = (data, {
|
967
|
+
schemas,
|
968
|
+
schema,
|
969
|
+
components
|
970
|
+
}) => {
|
971
|
+
let currentPanelIndex = 0;
|
972
|
+
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
973
|
+
data.contentType.layouts.edit,
|
974
|
+
schema?.attributes,
|
975
|
+
data.contentType.metadatas,
|
976
|
+
{ configurations: data.components, schemas: components },
|
977
|
+
schemas
|
978
|
+
).reduce((panels, row) => {
|
979
|
+
if (row.some((field) => field.type === "dynamiczone")) {
|
980
|
+
panels.push([row]);
|
981
|
+
currentPanelIndex += 2;
|
982
|
+
} else {
|
983
|
+
if (!panels[currentPanelIndex]) {
|
984
|
+
panels.push([]);
|
985
|
+
}
|
986
|
+
panels[currentPanelIndex].push(row);
|
987
|
+
}
|
988
|
+
return panels;
|
989
|
+
}, []);
|
990
|
+
const componentEditAttributes = Object.entries(data.components).reduce(
|
991
|
+
(acc, [uid, configuration]) => {
|
992
|
+
acc[uid] = {
|
993
|
+
layout: convertEditLayoutToFieldLayouts(
|
994
|
+
configuration.layouts.edit,
|
995
|
+
components[uid].attributes,
|
996
|
+
configuration.metadatas,
|
997
|
+
{ configurations: data.components, schemas: components }
|
998
|
+
),
|
999
|
+
settings: {
|
1000
|
+
...configuration.settings,
|
1001
|
+
icon: components[uid].info.icon,
|
1002
|
+
displayName: components[uid].info.displayName
|
1003
|
+
}
|
1004
|
+
};
|
1005
|
+
return acc;
|
1006
|
+
},
|
1007
|
+
{}
|
1008
|
+
);
|
1009
|
+
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1010
|
+
(acc, [attribute, metadata]) => {
|
1011
|
+
return {
|
1012
|
+
...acc,
|
1013
|
+
[attribute]: metadata.edit
|
1014
|
+
};
|
1015
|
+
},
|
1016
|
+
{}
|
1017
|
+
);
|
1018
|
+
return {
|
1019
|
+
layout: panelledEditAttributes,
|
1020
|
+
components: componentEditAttributes,
|
1021
|
+
metadatas: editMetadatas,
|
1022
|
+
settings: {
|
1023
|
+
...data.contentType.settings,
|
1024
|
+
displayName: schema?.info.displayName
|
1025
|
+
},
|
1026
|
+
options: {
|
1027
|
+
...schema?.options,
|
1028
|
+
...schema?.pluginOptions,
|
1029
|
+
...data.contentType.options
|
1030
|
+
}
|
1031
|
+
};
|
1032
|
+
};
|
1033
|
+
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
1034
|
+
return rows.map(
|
1035
|
+
(row) => row.map((field) => {
|
1036
|
+
const attribute = attributes[field.name];
|
1037
|
+
if (!attribute) {
|
1038
|
+
return null;
|
1039
|
+
}
|
1040
|
+
const { edit: metadata } = metadatas[field.name];
|
1041
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1042
|
+
return {
|
1043
|
+
attribute,
|
1044
|
+
disabled: !metadata.editable,
|
1045
|
+
hint: metadata.description,
|
1046
|
+
label: metadata.label ?? "",
|
1047
|
+
name: field.name,
|
1048
|
+
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
1049
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1050
|
+
schemas,
|
1051
|
+
components: components?.schemas ?? {}
|
1052
|
+
}),
|
1053
|
+
placeholder: metadata.placeholder ?? "",
|
1054
|
+
required: attribute.required ?? false,
|
1055
|
+
size: field.size,
|
1056
|
+
unique: "unique" in attribute ? attribute.unique : false,
|
1057
|
+
visible: metadata.visible ?? true,
|
1058
|
+
type: attribute.type
|
1059
|
+
};
|
1060
|
+
}).filter((field) => field !== null)
|
1061
|
+
);
|
1062
|
+
};
|
1063
|
+
const formatListLayout = (data, {
|
1064
|
+
schemas,
|
1065
|
+
schema,
|
1066
|
+
components
|
1067
|
+
}) => {
|
1068
|
+
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1069
|
+
(acc, [attribute, metadata]) => {
|
1070
|
+
return {
|
1071
|
+
...acc,
|
1072
|
+
[attribute]: metadata.list
|
1073
|
+
};
|
1074
|
+
},
|
1075
|
+
{}
|
1076
|
+
);
|
1077
|
+
const listAttributes = convertListLayoutToFieldLayouts(
|
1078
|
+
data.contentType.layouts.list,
|
1079
|
+
schema?.attributes,
|
1080
|
+
listMetadatas,
|
1081
|
+
{ configurations: data.components, schemas: components },
|
1082
|
+
schemas
|
1083
|
+
);
|
1084
|
+
return {
|
1085
|
+
layout: listAttributes,
|
1086
|
+
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
1087
|
+
metadatas: listMetadatas,
|
1088
|
+
options: {
|
1089
|
+
...schema?.options,
|
1090
|
+
...schema?.pluginOptions,
|
1091
|
+
...data.contentType.options
|
1092
|
+
}
|
1093
|
+
};
|
1094
|
+
};
|
1095
|
+
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
1096
|
+
return columns.map((name) => {
|
1097
|
+
const attribute = attributes[name];
|
1098
|
+
if (!attribute) {
|
1099
|
+
return null;
|
1100
|
+
}
|
1101
|
+
const metadata = metadatas[name];
|
1102
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1103
|
+
return {
|
1104
|
+
attribute,
|
1105
|
+
label: metadata.label ?? "",
|
1106
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1107
|
+
schemas,
|
1108
|
+
components: components?.schemas ?? {}
|
1109
|
+
}),
|
1110
|
+
name,
|
1111
|
+
searchable: metadata.searchable ?? true,
|
1112
|
+
sortable: metadata.sortable ?? true
|
1113
|
+
};
|
1114
|
+
}).filter((field) => field !== null);
|
1115
|
+
};
|
1116
|
+
const useDocument = (args, opts) => {
|
1117
|
+
const { toggleNotification } = strapiAdmin.useNotification();
|
1118
|
+
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
1119
|
+
const {
|
1120
|
+
currentData: data,
|
1121
|
+
isLoading: isLoadingDocument,
|
1122
|
+
isFetching: isFetchingDocument,
|
1123
|
+
error
|
1124
|
+
} = useGetDocumentQuery(args, {
|
1125
|
+
...opts,
|
1126
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
1127
|
+
});
|
1128
|
+
const {
|
1129
|
+
components,
|
1130
|
+
schema,
|
1131
|
+
schemas,
|
1132
|
+
isLoading: isLoadingSchema
|
1133
|
+
} = useContentTypeSchema(args.model);
|
1134
|
+
React__namespace.useEffect(() => {
|
1135
|
+
if (error) {
|
1136
|
+
toggleNotification({
|
1137
|
+
type: "danger",
|
1138
|
+
message: formatAPIError(error)
|
1139
|
+
});
|
1140
|
+
}
|
1141
|
+
}, [toggleNotification, error, formatAPIError, args.collectionType]);
|
1142
|
+
const validationSchema = React__namespace.useMemo(() => {
|
1143
|
+
if (!schema) {
|
1144
|
+
return null;
|
1145
|
+
}
|
1146
|
+
return createYupSchema(schema.attributes, components);
|
1147
|
+
}, [schema, components]);
|
1148
|
+
const validate = React__namespace.useCallback(
|
1149
|
+
(document) => {
|
1150
|
+
if (!validationSchema) {
|
1151
|
+
throw new Error(
|
1152
|
+
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
1153
|
+
);
|
1154
|
+
}
|
1155
|
+
try {
|
1156
|
+
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
1157
|
+
return null;
|
1158
|
+
} catch (error2) {
|
1159
|
+
if (error2 instanceof yup.ValidationError) {
|
1160
|
+
return strapiAdmin.getYupValidationErrors(error2);
|
1161
|
+
}
|
1162
|
+
throw error2;
|
1163
|
+
}
|
1164
|
+
},
|
1165
|
+
[validationSchema]
|
1166
|
+
);
|
1167
|
+
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
1168
|
+
return {
|
1169
|
+
components,
|
1170
|
+
document: data?.data,
|
1171
|
+
meta: data?.meta,
|
1172
|
+
isLoading,
|
1173
|
+
schema,
|
1174
|
+
schemas,
|
1175
|
+
validate
|
1176
|
+
};
|
1177
|
+
};
|
1178
|
+
const useDoc = () => {
|
1179
|
+
const { id, slug, collectionType, origin } = reactRouterDom.useParams();
|
1180
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
1181
|
+
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
1182
|
+
if (!collectionType) {
|
1183
|
+
throw new Error("Could not find collectionType in url params");
|
1184
|
+
}
|
1185
|
+
if (!slug) {
|
1186
|
+
throw new Error("Could not find model in url params");
|
1187
|
+
}
|
1188
|
+
return {
|
1189
|
+
collectionType,
|
844
1190
|
model: slug,
|
845
1191
|
id: origin || id === "create" ? void 0 : id,
|
846
1192
|
...useDocument(
|
@@ -851,6 +1197,45 @@ const useDoc = () => {
|
|
851
1197
|
)
|
852
1198
|
};
|
853
1199
|
};
|
1200
|
+
const useContentManagerContext = () => {
|
1201
|
+
const {
|
1202
|
+
collectionType,
|
1203
|
+
model,
|
1204
|
+
id,
|
1205
|
+
components,
|
1206
|
+
isLoading: isLoadingDoc,
|
1207
|
+
schema,
|
1208
|
+
schemas
|
1209
|
+
} = useDoc();
|
1210
|
+
const layout = useDocumentLayout(model);
|
1211
|
+
const form = strapiAdmin.useForm("useContentManagerContext", (state) => state);
|
1212
|
+
const isSingleType = collectionType === SINGLE_TYPES;
|
1213
|
+
const slug = model;
|
1214
|
+
const isCreatingEntry = id === "create";
|
1215
|
+
useContentTypeSchema();
|
1216
|
+
const isLoading = isLoadingDoc || layout.isLoading;
|
1217
|
+
const error = layout.error;
|
1218
|
+
return {
|
1219
|
+
error,
|
1220
|
+
isLoading,
|
1221
|
+
// Base metadata
|
1222
|
+
model,
|
1223
|
+
collectionType,
|
1224
|
+
id,
|
1225
|
+
slug,
|
1226
|
+
isCreatingEntry,
|
1227
|
+
isSingleType,
|
1228
|
+
hasDraftAndPublish: schema?.options?.draftAndPublish ?? false,
|
1229
|
+
// All schema infos
|
1230
|
+
components,
|
1231
|
+
contentType: schema,
|
1232
|
+
contentTypes: schemas,
|
1233
|
+
// Form state
|
1234
|
+
form,
|
1235
|
+
// layout infos
|
1236
|
+
layout
|
1237
|
+
};
|
1238
|
+
};
|
854
1239
|
const prefixPluginTranslations = (trad, pluginId) => {
|
855
1240
|
if (!pluginId) {
|
856
1241
|
throw new TypeError("pluginId can't be empty");
|
@@ -870,6 +1255,8 @@ const useDocumentActions = () => {
|
|
870
1255
|
const { formatMessage } = reactIntl.useIntl();
|
871
1256
|
const { trackUsage } = strapiAdmin.useTracking();
|
872
1257
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
1258
|
+
const navigate = reactRouterDom.useNavigate();
|
1259
|
+
const setCurrentStep = strapiAdmin.useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
873
1260
|
const [deleteDocument] = useDeleteDocumentMutation();
|
874
1261
|
const _delete = React__namespace.useCallback(
|
875
1262
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -1184,6 +1571,7 @@ const useDocumentActions = () => {
|
|
1184
1571
|
defaultMessage: "Saved document"
|
1185
1572
|
})
|
1186
1573
|
});
|
1574
|
+
setCurrentStep("contentManager.success");
|
1187
1575
|
return res.data;
|
1188
1576
|
} catch (err) {
|
1189
1577
|
toggleNotification({
|
@@ -1205,7 +1593,6 @@ const useDocumentActions = () => {
|
|
1205
1593
|
sourceId
|
1206
1594
|
});
|
1207
1595
|
if ("error" in res) {
|
1208
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1209
1596
|
return { error: res.error };
|
1210
1597
|
}
|
1211
1598
|
toggleNotification({
|
@@ -1224,7 +1611,7 @@ const useDocumentActions = () => {
|
|
1224
1611
|
throw err;
|
1225
1612
|
}
|
1226
1613
|
},
|
1227
|
-
[autoCloneDocument,
|
1614
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1228
1615
|
);
|
1229
1616
|
const [cloneDocument] = useCloneDocumentMutation();
|
1230
1617
|
const clone = React__namespace.useCallback(
|
@@ -1250,6 +1637,7 @@ const useDocumentActions = () => {
|
|
1250
1637
|
defaultMessage: "Cloned document"
|
1251
1638
|
})
|
1252
1639
|
});
|
1640
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1253
1641
|
return res.data;
|
1254
1642
|
} catch (err) {
|
1255
1643
|
toggleNotification({
|
@@ -1260,7 +1648,7 @@ const useDocumentActions = () => {
|
|
1260
1648
|
throw err;
|
1261
1649
|
}
|
1262
1650
|
},
|
1263
|
-
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
|
1651
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1264
1652
|
);
|
1265
1653
|
const [getDoc] = useLazyGetDocumentQuery();
|
1266
1654
|
const getDocument = React__namespace.useCallback(
|
@@ -1286,7 +1674,7 @@ const useDocumentActions = () => {
|
|
1286
1674
|
};
|
1287
1675
|
};
|
1288
1676
|
const ProtectedHistoryPage = React.lazy(
|
1289
|
-
() => Promise.resolve().then(() => require("./History-
|
1677
|
+
() => Promise.resolve().then(() => require("./History-BrJ1tUvt.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1290
1678
|
);
|
1291
1679
|
const routes$1 = [
|
1292
1680
|
{
|
@@ -1299,31 +1687,31 @@ const routes$1 = [
|
|
1299
1687
|
}
|
1300
1688
|
];
|
1301
1689
|
const ProtectedEditViewPage = React.lazy(
|
1302
|
-
() => Promise.resolve().then(() => require("./EditViewPage-
|
1690
|
+
() => Promise.resolve().then(() => require("./EditViewPage-D2QVRr_2.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1303
1691
|
);
|
1304
1692
|
const ProtectedListViewPage = React.lazy(
|
1305
|
-
() => Promise.resolve().then(() => require("./ListViewPage-
|
1693
|
+
() => Promise.resolve().then(() => require("./ListViewPage-Coj-RPsx.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1306
1694
|
);
|
1307
1695
|
const ProtectedListConfiguration = React.lazy(
|
1308
|
-
() => Promise.resolve().then(() => require("./ListConfigurationPage-
|
1696
|
+
() => Promise.resolve().then(() => require("./ListConfigurationPage-Eane5LKE.js")).then((mod) => ({
|
1309
1697
|
default: mod.ProtectedListConfiguration
|
1310
1698
|
}))
|
1311
1699
|
);
|
1312
1700
|
const ProtectedEditConfigurationPage = React.lazy(
|
1313
|
-
() => Promise.resolve().then(() => require("./EditConfigurationPage-
|
1701
|
+
() => Promise.resolve().then(() => require("./EditConfigurationPage-CpLj5gYZ.js")).then((mod) => ({
|
1314
1702
|
default: mod.ProtectedEditConfigurationPage
|
1315
1703
|
}))
|
1316
1704
|
);
|
1317
1705
|
const ProtectedComponentConfigurationPage = React.lazy(
|
1318
|
-
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-
|
1706
|
+
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-DnnZJc1F.js")).then((mod) => ({
|
1319
1707
|
default: mod.ProtectedComponentConfigurationPage
|
1320
1708
|
}))
|
1321
1709
|
);
|
1322
1710
|
const NoPermissions = React.lazy(
|
1323
|
-
() => Promise.resolve().then(() => require("./NoPermissionsPage-
|
1711
|
+
() => Promise.resolve().then(() => require("./NoPermissionsPage-BOtb5FTM.js")).then((mod) => ({ default: mod.NoPermissions }))
|
1324
1712
|
);
|
1325
1713
|
const NoContentType = React.lazy(
|
1326
|
-
() => Promise.resolve().then(() => require("./NoContentTypePage-
|
1714
|
+
() => Promise.resolve().then(() => require("./NoContentTypePage-BDJ0dshy.js")).then((mod) => ({ default: mod.NoContentType }))
|
1327
1715
|
);
|
1328
1716
|
const CollectionTypePages = () => {
|
1329
1717
|
const { collectionType } = reactRouterDom.useParams();
|
@@ -1437,12 +1825,14 @@ const DocumentActionButton = (action) => {
|
|
1437
1825
|
/* @__PURE__ */ jsxRuntime.jsx(
|
1438
1826
|
designSystem.Button,
|
1439
1827
|
{
|
1440
|
-
flex:
|
1828
|
+
flex: "auto",
|
1441
1829
|
startIcon: action.icon,
|
1442
1830
|
disabled: action.disabled,
|
1443
1831
|
onClick: handleClick(action),
|
1444
1832
|
justifyContent: "center",
|
1445
1833
|
variant: action.variant || "default",
|
1834
|
+
paddingTop: "7px",
|
1835
|
+
paddingBottom: "7px",
|
1446
1836
|
children: action.label
|
1447
1837
|
}
|
1448
1838
|
),
|
@@ -1450,7 +1840,7 @@ const DocumentActionButton = (action) => {
|
|
1450
1840
|
DocumentActionConfirmDialog,
|
1451
1841
|
{
|
1452
1842
|
...action.dialog,
|
1453
|
-
variant: action.variant,
|
1843
|
+
variant: action.dialog?.variant ?? action.variant,
|
1454
1844
|
isOpen: dialogId === action.id,
|
1455
1845
|
onClose: handleClose
|
1456
1846
|
}
|
@@ -1507,9 +1897,9 @@ const DocumentActionsMenu = ({
|
|
1507
1897
|
disabled: isDisabled,
|
1508
1898
|
size: "S",
|
1509
1899
|
endIcon: null,
|
1510
|
-
paddingTop: "
|
1511
|
-
paddingLeft: "
|
1512
|
-
paddingRight: "
|
1900
|
+
paddingTop: "4px",
|
1901
|
+
paddingLeft: "7px",
|
1902
|
+
paddingRight: "7px",
|
1513
1903
|
variant,
|
1514
1904
|
children: [
|
1515
1905
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.More, { "aria-hidden": true, focusable: false }),
|
@@ -1520,7 +1910,7 @@ const DocumentActionsMenu = ({
|
|
1520
1910
|
]
|
1521
1911
|
}
|
1522
1912
|
),
|
1523
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, {
|
1913
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1524
1914
|
actions2.map((action) => {
|
1525
1915
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
1526
1916
|
designSystem.Menu.Item,
|
@@ -1529,10 +1919,25 @@ const DocumentActionsMenu = ({
|
|
1529
1919
|
onSelect: handleClick(action),
|
1530
1920
|
display: "block",
|
1531
1921
|
children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", gap: 4, children: [
|
1532
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1922
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
1923
|
+
designSystem.Flex,
|
1924
|
+
{
|
1925
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1926
|
+
gap: 2,
|
1927
|
+
tag: "span",
|
1928
|
+
children: [
|
1929
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
1930
|
+
designSystem.Flex,
|
1931
|
+
{
|
1932
|
+
tag: "span",
|
1933
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1934
|
+
children: action.icon
|
1935
|
+
}
|
1936
|
+
),
|
1937
|
+
action.label
|
1938
|
+
]
|
1939
|
+
}
|
1940
|
+
),
|
1536
1941
|
action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsxRuntime.jsx(
|
1537
1942
|
designSystem.Flex,
|
1538
1943
|
{
|
@@ -1591,6 +1996,18 @@ const convertActionVariantToColor = (variant = "secondary") => {
|
|
1591
1996
|
return "primary600";
|
1592
1997
|
}
|
1593
1998
|
};
|
1999
|
+
const convertActionVariantToIconColor = (variant = "secondary") => {
|
2000
|
+
switch (variant) {
|
2001
|
+
case "danger":
|
2002
|
+
return "danger600";
|
2003
|
+
case "secondary":
|
2004
|
+
return "neutral500";
|
2005
|
+
case "success":
|
2006
|
+
return "success600";
|
2007
|
+
default:
|
2008
|
+
return "primary600";
|
2009
|
+
}
|
2010
|
+
};
|
1594
2011
|
const DocumentActionConfirmDialog = ({
|
1595
2012
|
onClose,
|
1596
2013
|
onCancel,
|
@@ -1617,11 +2034,11 @@ const DocumentActionConfirmDialog = ({
|
|
1617
2034
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
1618
2035
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: content }),
|
1619
2036
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
|
1620
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", children: formatMessage({
|
2037
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", fullWidth: true, children: formatMessage({
|
1621
2038
|
id: "app.components.Button.cancel",
|
1622
2039
|
defaultMessage: "Cancel"
|
1623
2040
|
}) }) }),
|
1624
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, children: formatMessage({
|
2041
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
|
1625
2042
|
id: "app.components.Button.confirm",
|
1626
2043
|
defaultMessage: "Confirm"
|
1627
2044
|
}) })
|
@@ -1660,13 +2077,17 @@ const PublishAction$1 = ({
|
|
1660
2077
|
const navigate = reactRouterDom.useNavigate();
|
1661
2078
|
const { toggleNotification } = strapiAdmin.useNotification();
|
1662
2079
|
const { _unstableFormatValidationErrors: formatValidationErrors } = strapiAdmin.useAPIErrorHandler();
|
2080
|
+
const isListView = reactRouterDom.useMatch(LIST_PATH) !== null;
|
1663
2081
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
1664
2082
|
const { formatMessage } = reactIntl.useIntl();
|
1665
|
-
const { canPublish
|
1666
|
-
"PublishAction",
|
1667
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1668
|
-
);
|
2083
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1669
2084
|
const { publish } = useDocumentActions();
|
2085
|
+
const [
|
2086
|
+
countDraftRelations,
|
2087
|
+
{ isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
|
2088
|
+
] = useLazyGetDraftRelationCountQuery();
|
2089
|
+
const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React__namespace.useState(0);
|
2090
|
+
const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React__namespace.useState(0);
|
1670
2091
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1671
2092
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
1672
2093
|
const modified = strapiAdmin.useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
@@ -1675,10 +2096,103 @@ const PublishAction$1 = ({
|
|
1675
2096
|
const validate = strapiAdmin.useForm("PublishAction", (state) => state.validate);
|
1676
2097
|
const setErrors = strapiAdmin.useForm("PublishAction", (state) => state.setErrors);
|
1677
2098
|
const formValues = strapiAdmin.useForm("PublishAction", ({ values }) => values);
|
1678
|
-
|
1679
|
-
|
1680
|
-
|
1681
|
-
|
2099
|
+
React__namespace.useEffect(() => {
|
2100
|
+
if (isErrorDraftRelations) {
|
2101
|
+
toggleNotification({
|
2102
|
+
type: "danger",
|
2103
|
+
message: formatMessage({
|
2104
|
+
id: getTranslation("error.records.fetch-draft-relatons"),
|
2105
|
+
defaultMessage: "An error occurred while fetching draft relations on this document."
|
2106
|
+
})
|
2107
|
+
});
|
2108
|
+
}
|
2109
|
+
}, [isErrorDraftRelations, toggleNotification, formatMessage]);
|
2110
|
+
React__namespace.useEffect(() => {
|
2111
|
+
const localDraftRelations = /* @__PURE__ */ new Set();
|
2112
|
+
const extractDraftRelations = (data) => {
|
2113
|
+
const relations = data.connect || [];
|
2114
|
+
relations.forEach((relation) => {
|
2115
|
+
if (relation.status === "draft") {
|
2116
|
+
localDraftRelations.add(relation.id);
|
2117
|
+
}
|
2118
|
+
});
|
2119
|
+
};
|
2120
|
+
const traverseAndExtract = (data) => {
|
2121
|
+
Object.entries(data).forEach(([key, value]) => {
|
2122
|
+
if (key === "connect" && Array.isArray(value)) {
|
2123
|
+
extractDraftRelations({ connect: value });
|
2124
|
+
} else if (typeof value === "object" && value !== null) {
|
2125
|
+
traverseAndExtract(value);
|
2126
|
+
}
|
2127
|
+
});
|
2128
|
+
};
|
2129
|
+
if (!documentId || modified) {
|
2130
|
+
traverseAndExtract(formValues);
|
2131
|
+
setLocalCountOfDraftRelations(localDraftRelations.size);
|
2132
|
+
}
|
2133
|
+
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
2134
|
+
React__namespace.useEffect(() => {
|
2135
|
+
if (!document || !document.documentId || isListView) {
|
2136
|
+
return;
|
2137
|
+
}
|
2138
|
+
const fetchDraftRelationsCount = async () => {
|
2139
|
+
const { data, error } = await countDraftRelations({
|
2140
|
+
collectionType,
|
2141
|
+
model,
|
2142
|
+
documentId,
|
2143
|
+
params
|
2144
|
+
});
|
2145
|
+
if (error) {
|
2146
|
+
throw error;
|
2147
|
+
}
|
2148
|
+
if (data) {
|
2149
|
+
setServerCountOfDraftRelations(data.data);
|
2150
|
+
}
|
2151
|
+
};
|
2152
|
+
fetchDraftRelationsCount();
|
2153
|
+
}, [isListView, document, documentId, countDraftRelations, collectionType, model, params]);
|
2154
|
+
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
2155
|
+
if (!schema?.options?.draftAndPublish) {
|
2156
|
+
return null;
|
2157
|
+
}
|
2158
|
+
const performPublish = async () => {
|
2159
|
+
setSubmitting(true);
|
2160
|
+
try {
|
2161
|
+
const { errors } = await validate();
|
2162
|
+
if (errors) {
|
2163
|
+
toggleNotification({
|
2164
|
+
type: "danger",
|
2165
|
+
message: formatMessage({
|
2166
|
+
id: "content-manager.validation.error",
|
2167
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2168
|
+
})
|
2169
|
+
});
|
2170
|
+
return;
|
2171
|
+
}
|
2172
|
+
const res = await publish(
|
2173
|
+
{
|
2174
|
+
collectionType,
|
2175
|
+
model,
|
2176
|
+
documentId,
|
2177
|
+
params
|
2178
|
+
},
|
2179
|
+
formValues
|
2180
|
+
);
|
2181
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
2182
|
+
navigate({
|
2183
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
2184
|
+
search: rawQuery
|
2185
|
+
});
|
2186
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2187
|
+
setErrors(formatValidationErrors(res.error));
|
2188
|
+
}
|
2189
|
+
} finally {
|
2190
|
+
setSubmitting(false);
|
2191
|
+
}
|
2192
|
+
};
|
2193
|
+
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
2194
|
+
const enableDraftRelationsCount = false;
|
2195
|
+
const hasDraftRelations = enableDraftRelationsCount;
|
1682
2196
|
return {
|
1683
2197
|
/**
|
1684
2198
|
* Disabled when:
|
@@ -1688,49 +2202,36 @@ const PublishAction$1 = ({
|
|
1688
2202
|
* - the document is already published & not modified
|
1689
2203
|
* - the document is being created & not modified
|
1690
2204
|
* - the user doesn't have the permission to publish
|
1691
|
-
* - the user doesn't have the permission to create a new document
|
1692
|
-
* - the user doesn't have the permission to update the document
|
1693
2205
|
*/
|
1694
|
-
disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish
|
2206
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
1695
2207
|
label: formatMessage({
|
1696
2208
|
id: "app.utils.publish",
|
1697
2209
|
defaultMessage: "Publish"
|
1698
2210
|
}),
|
1699
2211
|
onClick: async () => {
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
|
1713
|
-
|
1714
|
-
|
1715
|
-
|
1716
|
-
|
1717
|
-
documentId,
|
1718
|
-
params
|
1719
|
-
},
|
1720
|
-
formValues
|
1721
|
-
);
|
1722
|
-
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1723
|
-
navigate({
|
1724
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1725
|
-
search: rawQuery
|
1726
|
-
});
|
1727
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1728
|
-
setErrors(formatValidationErrors(res.error));
|
2212
|
+
await performPublish();
|
2213
|
+
},
|
2214
|
+
dialog: hasDraftRelations ? {
|
2215
|
+
type: "dialog",
|
2216
|
+
variant: "danger",
|
2217
|
+
footer: null,
|
2218
|
+
title: formatMessage({
|
2219
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
|
2220
|
+
defaultMessage: "Confirmation"
|
2221
|
+
}),
|
2222
|
+
content: formatMessage(
|
2223
|
+
{
|
2224
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
2225
|
+
defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
|
2226
|
+
},
|
2227
|
+
{
|
2228
|
+
count: totalDraftRelations
|
1729
2229
|
}
|
1730
|
-
|
1731
|
-
|
2230
|
+
),
|
2231
|
+
onConfirm: async () => {
|
2232
|
+
await performPublish();
|
1732
2233
|
}
|
1733
|
-
}
|
2234
|
+
} : void 0
|
1734
2235
|
};
|
1735
2236
|
};
|
1736
2237
|
PublishAction$1.type = "publish";
|
@@ -1746,10 +2247,6 @@ const UpdateAction = ({
|
|
1746
2247
|
const cloneMatch = reactRouterDom.useMatch(CLONE_PATH);
|
1747
2248
|
const isCloning = cloneMatch !== null;
|
1748
2249
|
const { formatMessage } = reactIntl.useIntl();
|
1749
|
-
const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1750
|
-
canCreate: canCreate2,
|
1751
|
-
canUpdate: canUpdate2
|
1752
|
-
}));
|
1753
2250
|
const { create, update, clone } = useDocumentActions();
|
1754
2251
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1755
2252
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
@@ -1766,10 +2263,8 @@ const UpdateAction = ({
|
|
1766
2263
|
* - the form is submitting
|
1767
2264
|
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
1768
2265
|
* - the active tab is the published tab
|
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
2266
|
*/
|
1772
|
-
disabled: isSubmitting || !modified && !isCloning || activeTab === "published"
|
2267
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1773
2268
|
label: formatMessage({
|
1774
2269
|
id: "content-manager.containers.Edit.save",
|
1775
2270
|
defaultMessage: "Save"
|
@@ -1777,16 +2272,18 @@ const UpdateAction = ({
|
|
1777
2272
|
onClick: async () => {
|
1778
2273
|
setSubmitting(true);
|
1779
2274
|
try {
|
1780
|
-
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
-
|
1785
|
-
|
1786
|
-
|
1787
|
-
|
1788
|
-
|
1789
|
-
|
2275
|
+
if (activeTab !== "draft") {
|
2276
|
+
const { errors } = await validate();
|
2277
|
+
if (errors) {
|
2278
|
+
toggleNotification({
|
2279
|
+
type: "danger",
|
2280
|
+
message: formatMessage({
|
2281
|
+
id: "content-manager.validation.error",
|
2282
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2283
|
+
})
|
2284
|
+
});
|
2285
|
+
return;
|
2286
|
+
}
|
1790
2287
|
}
|
1791
2288
|
if (isCloning) {
|
1792
2289
|
const res = await clone(
|
@@ -1798,10 +2295,13 @@ const UpdateAction = ({
|
|
1798
2295
|
document
|
1799
2296
|
);
|
1800
2297
|
if ("data" in res) {
|
1801
|
-
navigate(
|
1802
|
-
|
1803
|
-
|
1804
|
-
|
2298
|
+
navigate(
|
2299
|
+
{
|
2300
|
+
pathname: `../${res.data.documentId}`,
|
2301
|
+
search: rawQuery
|
2302
|
+
},
|
2303
|
+
{ relative: "path" }
|
2304
|
+
);
|
1805
2305
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1806
2306
|
setErrors(formatValidationErrors(res.error));
|
1807
2307
|
}
|
@@ -1829,10 +2329,13 @@ const UpdateAction = ({
|
|
1829
2329
|
document
|
1830
2330
|
);
|
1831
2331
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1832
|
-
navigate(
|
1833
|
-
|
1834
|
-
|
1835
|
-
|
2332
|
+
navigate(
|
2333
|
+
{
|
2334
|
+
pathname: `../${res.data.documentId}`,
|
2335
|
+
search: rawQuery
|
2336
|
+
},
|
2337
|
+
{ replace: true, relative: "path" }
|
2338
|
+
);
|
1836
2339
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1837
2340
|
setErrors(formatValidationErrors(res.error));
|
1838
2341
|
}
|
@@ -1876,7 +2379,7 @@ const UnpublishAction$1 = ({
|
|
1876
2379
|
id: "app.utils.unpublish",
|
1877
2380
|
defaultMessage: "Unpublish"
|
1878
2381
|
}),
|
1879
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2382
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Cross, {}),
|
1880
2383
|
onClick: async () => {
|
1881
2384
|
if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
|
1882
2385
|
if (!documentId) {
|
@@ -1988,7 +2491,7 @@ const DiscardAction = ({
|
|
1988
2491
|
id: "content-manager.actions.discard.label",
|
1989
2492
|
defaultMessage: "Discard changes"
|
1990
2493
|
}),
|
1991
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2494
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Cross, {}),
|
1992
2495
|
position: ["panel", "table-row"],
|
1993
2496
|
variant: "danger",
|
1994
2497
|
dialog: {
|
@@ -2016,11 +2519,6 @@ const DiscardAction = ({
|
|
2016
2519
|
};
|
2017
2520
|
};
|
2018
2521
|
DiscardAction.type = "discard";
|
2019
|
-
const StyledCrossCircle = styledComponents.styled(Icons.CrossCircle)`
|
2020
|
-
path {
|
2021
|
-
fill: currentColor;
|
2022
|
-
}
|
2023
|
-
`;
|
2024
2522
|
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2025
2523
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2026
2524
|
const RelativeTime = React__namespace.forwardRef(
|
@@ -2068,7 +2566,7 @@ const getDisplayName = ({
|
|
2068
2566
|
};
|
2069
2567
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2070
2568
|
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2071
|
-
const statusVariant = status === "draft" ? "
|
2569
|
+
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2072
2570
|
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: capitalise(status) }) });
|
2073
2571
|
};
|
2074
2572
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
@@ -2078,23 +2576,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
|
2078
2576
|
id: "content-manager.containers.edit.title.new",
|
2079
2577
|
defaultMessage: "Create an entry"
|
2080
2578
|
}) : documentTitle;
|
2081
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop:
|
2579
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2082
2580
|
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.BackButton, {}),
|
2083
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
2084
|
-
designSystem.
|
2085
|
-
{
|
2086
|
-
|
2087
|
-
|
2088
|
-
paddingTop: 1,
|
2089
|
-
gap: "80px",
|
2090
|
-
alignItems: "flex-start",
|
2091
|
-
children: [
|
2092
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
|
2093
|
-
/* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
|
2094
|
-
]
|
2095
|
-
}
|
2096
|
-
),
|
2097
|
-
status ? /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: isCloning ? "draft" : status }) : null
|
2581
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2582
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
|
2583
|
+
/* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
|
2584
|
+
] }),
|
2585
|
+
status ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 1, children: /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
|
2098
2586
|
] });
|
2099
2587
|
};
|
2100
2588
|
const HeaderToolbar = () => {
|
@@ -2261,8 +2749,22 @@ const Information = ({ activeTab }) => {
|
|
2261
2749
|
);
|
2262
2750
|
};
|
2263
2751
|
const HeaderActions = ({ actions: actions2 }) => {
|
2264
|
-
|
2265
|
-
|
2752
|
+
const [dialogId, setDialogId] = React__namespace.useState(null);
|
2753
|
+
const handleClick = (action) => async (e) => {
|
2754
|
+
if (!("options" in action)) {
|
2755
|
+
const { onClick = () => false, dialog, id } = action;
|
2756
|
+
const muteDialog = await onClick(e);
|
2757
|
+
if (dialog && !muteDialog) {
|
2758
|
+
e.preventDefault();
|
2759
|
+
setDialogId(id);
|
2760
|
+
}
|
2761
|
+
}
|
2762
|
+
};
|
2763
|
+
const handleClose = () => {
|
2764
|
+
setDialogId(null);
|
2765
|
+
};
|
2766
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 1, children: actions2.map((action) => {
|
2767
|
+
if (action.options) {
|
2266
2768
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
2267
2769
|
designSystem.SingleSelect,
|
2268
2770
|
{
|
@@ -2276,10 +2778,49 @@ const HeaderActions = ({ actions: actions2 }) => {
|
|
2276
2778
|
action.id
|
2277
2779
|
);
|
2278
2780
|
} else {
|
2279
|
-
|
2781
|
+
if (action.type === "icon") {
|
2782
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
|
2783
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
2784
|
+
designSystem.IconButton,
|
2785
|
+
{
|
2786
|
+
disabled: action.disabled,
|
2787
|
+
label: action.label,
|
2788
|
+
size: "S",
|
2789
|
+
onClick: handleClick(action),
|
2790
|
+
children: action.icon
|
2791
|
+
}
|
2792
|
+
),
|
2793
|
+
action.dialog ? /* @__PURE__ */ jsxRuntime.jsx(
|
2794
|
+
HeaderActionDialog,
|
2795
|
+
{
|
2796
|
+
...action.dialog,
|
2797
|
+
isOpen: dialogId === action.id,
|
2798
|
+
onClose: handleClose
|
2799
|
+
}
|
2800
|
+
) : null
|
2801
|
+
] }, action.id);
|
2802
|
+
}
|
2280
2803
|
}
|
2281
2804
|
}) });
|
2282
2805
|
};
|
2806
|
+
const HeaderActionDialog = ({
|
2807
|
+
onClose,
|
2808
|
+
onCancel,
|
2809
|
+
title,
|
2810
|
+
content: Content,
|
2811
|
+
isOpen
|
2812
|
+
}) => {
|
2813
|
+
const handleClose = async () => {
|
2814
|
+
if (onCancel) {
|
2815
|
+
await onCancel();
|
2816
|
+
}
|
2817
|
+
onClose();
|
2818
|
+
};
|
2819
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
2820
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
2821
|
+
typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : Content
|
2822
|
+
] }) });
|
2823
|
+
};
|
2283
2824
|
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
2284
2825
|
const navigate = reactRouterDom.useNavigate();
|
2285
2826
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2320,12 +2861,16 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2320
2861
|
const { delete: deleteAction } = useDocumentActions();
|
2321
2862
|
const { toggleNotification } = strapiAdmin.useNotification();
|
2322
2863
|
const setSubmitting = strapiAdmin.useForm("DeleteAction", (state) => state.setSubmitting);
|
2864
|
+
const isLocalized = document?.locale != null;
|
2323
2865
|
return {
|
2324
2866
|
disabled: !canDelete || !document,
|
2325
|
-
label: formatMessage(
|
2326
|
-
|
2327
|
-
|
2328
|
-
|
2867
|
+
label: formatMessage(
|
2868
|
+
{
|
2869
|
+
id: "content-manager.actions.delete.label",
|
2870
|
+
defaultMessage: "Delete entry{isLocalized, select, true { (all locales)} other {}}"
|
2871
|
+
},
|
2872
|
+
{ isLocalized }
|
2873
|
+
),
|
2329
2874
|
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {}),
|
2330
2875
|
dialog: {
|
2331
2876
|
type: "dialog",
|
@@ -2361,423 +2906,121 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2361
2906
|
const res = await deleteAction({
|
2362
2907
|
documentId,
|
2363
2908
|
model,
|
2364
|
-
collectionType,
|
2365
|
-
params: {
|
2366
|
-
locale: "*"
|
2367
|
-
}
|
2368
|
-
});
|
2369
|
-
if (!("error" in res)) {
|
2370
|
-
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
2371
|
-
}
|
2372
|
-
} finally {
|
2373
|
-
if (!listViewPathMatch) {
|
2374
|
-
setSubmitting(false);
|
2375
|
-
}
|
2376
|
-
}
|
2377
|
-
}
|
2378
|
-
},
|
2379
|
-
variant: "danger",
|
2380
|
-
position: ["header", "table-row"]
|
2381
|
-
};
|
2382
|
-
};
|
2383
|
-
DeleteAction$1.type = "delete";
|
2384
|
-
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2385
|
-
const Panels = () => {
|
2386
|
-
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2387
|
-
const [
|
2388
|
-
{
|
2389
|
-
query: { status }
|
2390
|
-
}
|
2391
|
-
] = strapiAdmin.useQueryParams({
|
2392
|
-
status: "draft"
|
2393
|
-
});
|
2394
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2395
|
-
const plugins = strapiAdmin.useStrapiApp("Panels", (state) => state.plugins);
|
2396
|
-
const props = {
|
2397
|
-
activeTab: status,
|
2398
|
-
model,
|
2399
|
-
documentId: id,
|
2400
|
-
document: isCloning ? void 0 : document,
|
2401
|
-
meta: isCloning ? void 0 : meta,
|
2402
|
-
collectionType
|
2403
|
-
};
|
2404
|
-
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
|
2405
|
-
strapiAdmin.DescriptionComponentRenderer,
|
2406
|
-
{
|
2407
|
-
props,
|
2408
|
-
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2409
|
-
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsxRuntime.jsx(Panel, { ...description, children: content }, id2))
|
2410
|
-
}
|
2411
|
-
) });
|
2412
|
-
};
|
2413
|
-
const ActionsPanel = () => {
|
2414
|
-
const { formatMessage } = reactIntl.useIntl();
|
2415
|
-
return {
|
2416
|
-
title: formatMessage({
|
2417
|
-
id: "content-manager.containers.edit.panels.default.title",
|
2418
|
-
defaultMessage: "Document"
|
2419
|
-
}),
|
2420
|
-
content: /* @__PURE__ */ jsxRuntime.jsx(ActionsPanelContent, {})
|
2421
|
-
};
|
2422
|
-
};
|
2423
|
-
ActionsPanel.type = "actions";
|
2424
|
-
const ActionsPanelContent = () => {
|
2425
|
-
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2426
|
-
const [
|
2427
|
-
{
|
2428
|
-
query: { status = "draft" }
|
2429
|
-
}
|
2430
|
-
] = strapiAdmin.useQueryParams();
|
2431
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2432
|
-
const plugins = strapiAdmin.useStrapiApp("ActionsPanel", (state) => state.plugins);
|
2433
|
-
const props = {
|
2434
|
-
activeTab: status,
|
2435
|
-
model,
|
2436
|
-
documentId: id,
|
2437
|
-
document: isCloning ? void 0 : document,
|
2438
|
-
meta: isCloning ? void 0 : meta,
|
2439
|
-
collectionType
|
2440
|
-
};
|
2441
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, width: "100%", children: [
|
2442
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
2443
|
-
strapiAdmin.DescriptionComponentRenderer,
|
2444
|
-
{
|
2445
|
-
props,
|
2446
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2447
|
-
children: (actions2) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActions, { actions: actions2 })
|
2448
|
-
}
|
2449
|
-
),
|
2450
|
-
/* @__PURE__ */ jsxRuntime.jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
2451
|
-
] });
|
2452
|
-
};
|
2453
|
-
const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
2454
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
2455
|
-
designSystem.Flex,
|
2456
|
-
{
|
2457
|
-
ref,
|
2458
|
-
tag: "aside",
|
2459
|
-
"aria-labelledby": "additional-information",
|
2460
|
-
background: "neutral0",
|
2461
|
-
borderColor: "neutral150",
|
2462
|
-
hasRadius: true,
|
2463
|
-
paddingBottom: 4,
|
2464
|
-
paddingLeft: 4,
|
2465
|
-
paddingRight: 4,
|
2466
|
-
paddingTop: 4,
|
2467
|
-
shadow: "tableShadow",
|
2468
|
-
gap: 3,
|
2469
|
-
direction: "column",
|
2470
|
-
justifyContent: "stretch",
|
2471
|
-
alignItems: "flex-start",
|
2472
|
-
children: [
|
2473
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2474
|
-
children
|
2475
|
-
]
|
2476
|
-
}
|
2477
|
-
);
|
2478
|
-
});
|
2479
|
-
const HOOKS = {
|
2480
|
-
/**
|
2481
|
-
* Hook that allows to mutate the displayed headers of the list view table
|
2482
|
-
* @constant
|
2483
|
-
* @type {string}
|
2484
|
-
*/
|
2485
|
-
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2486
|
-
/**
|
2487
|
-
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2488
|
-
* @constant
|
2489
|
-
* @type {string}
|
2490
|
-
*/
|
2491
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2492
|
-
/**
|
2493
|
-
* Hook that allows to mutate the CM's edit view layout
|
2494
|
-
* @constant
|
2495
|
-
* @type {string}
|
2496
|
-
*/
|
2497
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2498
|
-
/**
|
2499
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
2500
|
-
* @constant
|
2501
|
-
* @type {string}
|
2502
|
-
*/
|
2503
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2504
|
-
};
|
2505
|
-
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2506
|
-
endpoints: (builder) => ({
|
2507
|
-
getContentTypeConfiguration: builder.query({
|
2508
|
-
query: (uid) => ({
|
2509
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2510
|
-
method: "GET"
|
2511
|
-
}),
|
2512
|
-
transformResponse: (response) => response.data,
|
2513
|
-
providesTags: (_result, _error, uid) => [
|
2514
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2515
|
-
{ type: "ContentTypeSettings", id: "LIST" }
|
2516
|
-
]
|
2517
|
-
}),
|
2518
|
-
getAllContentTypeSettings: builder.query({
|
2519
|
-
query: () => "/content-manager/content-types-settings",
|
2520
|
-
transformResponse: (response) => response.data,
|
2521
|
-
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2522
|
-
}),
|
2523
|
-
updateContentTypeConfiguration: builder.mutation({
|
2524
|
-
query: ({ uid, ...body }) => ({
|
2525
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2526
|
-
method: "PUT",
|
2527
|
-
data: body
|
2528
|
-
}),
|
2529
|
-
transformResponse: (response) => response.data,
|
2530
|
-
invalidatesTags: (_result, _error, { uid }) => [
|
2531
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2532
|
-
{ type: "ContentTypeSettings", id: "LIST" },
|
2533
|
-
// Is this necessary?
|
2534
|
-
{ type: "InitialData" }
|
2535
|
-
]
|
2536
|
-
})
|
2537
|
-
})
|
2538
|
-
});
|
2539
|
-
const {
|
2540
|
-
useGetContentTypeConfigurationQuery,
|
2541
|
-
useGetAllContentTypeSettingsQuery,
|
2542
|
-
useUpdateContentTypeConfigurationMutation
|
2543
|
-
} = contentTypesApi;
|
2544
|
-
const checkIfAttributeIsDisplayable = (attribute) => {
|
2545
|
-
const { type } = attribute;
|
2546
|
-
if (type === "relation") {
|
2547
|
-
return !attribute.relation.toLowerCase().includes("morph");
|
2548
|
-
}
|
2549
|
-
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2550
|
-
};
|
2551
|
-
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2552
|
-
if (!mainFieldName) {
|
2553
|
-
return void 0;
|
2554
|
-
}
|
2555
|
-
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2556
|
-
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2557
|
-
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2558
|
-
);
|
2559
|
-
return {
|
2560
|
-
name: mainFieldName,
|
2561
|
-
type: mainFieldType ?? "string"
|
2562
|
-
};
|
2563
|
-
};
|
2564
|
-
const DEFAULT_SETTINGS = {
|
2565
|
-
bulkable: false,
|
2566
|
-
filterable: false,
|
2567
|
-
searchable: false,
|
2568
|
-
pagination: false,
|
2569
|
-
defaultSortBy: "",
|
2570
|
-
defaultSortOrder: "asc",
|
2571
|
-
mainField: "id",
|
2572
|
-
pageSize: 10
|
2573
|
-
};
|
2574
|
-
const useDocumentLayout = (model) => {
|
2575
|
-
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2576
|
-
const [{ query }] = strapiAdmin.useQueryParams();
|
2577
|
-
const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2578
|
-
const { toggleNotification } = strapiAdmin.useNotification();
|
2579
|
-
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
2580
|
-
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2581
|
-
const {
|
2582
|
-
data,
|
2583
|
-
isLoading: isLoadingConfigs,
|
2584
|
-
error,
|
2585
|
-
isFetching: isFetchingConfigs
|
2586
|
-
} = useGetContentTypeConfigurationQuery(model);
|
2587
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2588
|
-
React__namespace.useEffect(() => {
|
2589
|
-
if (error) {
|
2590
|
-
toggleNotification({
|
2591
|
-
type: "danger",
|
2592
|
-
message: formatAPIError(error)
|
2593
|
-
});
|
2594
|
-
}
|
2595
|
-
}, [error, formatAPIError, toggleNotification]);
|
2596
|
-
const editLayout = React__namespace.useMemo(
|
2597
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2598
|
-
layout: [],
|
2599
|
-
components: {},
|
2600
|
-
metadatas: {},
|
2601
|
-
options: {},
|
2602
|
-
settings: DEFAULT_SETTINGS
|
2603
|
-
},
|
2604
|
-
[data, isLoading, schemas, schema, components]
|
2605
|
-
);
|
2606
|
-
const listLayout = React__namespace.useMemo(() => {
|
2607
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2608
|
-
layout: [],
|
2609
|
-
metadatas: {},
|
2610
|
-
options: {},
|
2611
|
-
settings: DEFAULT_SETTINGS
|
2612
|
-
};
|
2613
|
-
}, [data, isLoading, schemas, schema, components]);
|
2614
|
-
const { layout: edit } = React__namespace.useMemo(
|
2615
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2616
|
-
layout: editLayout,
|
2617
|
-
query
|
2618
|
-
}),
|
2619
|
-
[editLayout, query, runHookWaterfall]
|
2620
|
-
);
|
2621
|
-
return {
|
2622
|
-
error,
|
2623
|
-
isLoading,
|
2624
|
-
edit,
|
2625
|
-
list: listLayout
|
2626
|
-
};
|
2627
|
-
};
|
2628
|
-
const useDocLayout = () => {
|
2629
|
-
const { model } = useDoc();
|
2630
|
-
return useDocumentLayout(model);
|
2631
|
-
};
|
2632
|
-
const formatEditLayout = (data, {
|
2633
|
-
schemas,
|
2634
|
-
schema,
|
2635
|
-
components
|
2636
|
-
}) => {
|
2637
|
-
let currentPanelIndex = 0;
|
2638
|
-
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2639
|
-
data.contentType.layouts.edit,
|
2640
|
-
schema?.attributes,
|
2641
|
-
data.contentType.metadatas,
|
2642
|
-
{ configurations: data.components, schemas: components },
|
2643
|
-
schemas
|
2644
|
-
).reduce((panels, row) => {
|
2645
|
-
if (row.some((field) => field.type === "dynamiczone")) {
|
2646
|
-
panels.push([row]);
|
2647
|
-
currentPanelIndex += 2;
|
2648
|
-
} else {
|
2649
|
-
if (!panels[currentPanelIndex]) {
|
2650
|
-
panels.push([]);
|
2651
|
-
}
|
2652
|
-
panels[currentPanelIndex].push(row);
|
2653
|
-
}
|
2654
|
-
return panels;
|
2655
|
-
}, []);
|
2656
|
-
const componentEditAttributes = Object.entries(data.components).reduce(
|
2657
|
-
(acc, [uid, configuration]) => {
|
2658
|
-
acc[uid] = {
|
2659
|
-
layout: convertEditLayoutToFieldLayouts(
|
2660
|
-
configuration.layouts.edit,
|
2661
|
-
components[uid].attributes,
|
2662
|
-
configuration.metadatas
|
2663
|
-
),
|
2664
|
-
settings: {
|
2665
|
-
...configuration.settings,
|
2666
|
-
icon: components[uid].info.icon,
|
2667
|
-
displayName: components[uid].info.displayName
|
2909
|
+
collectionType,
|
2910
|
+
params: {
|
2911
|
+
locale: "*"
|
2912
|
+
}
|
2913
|
+
});
|
2914
|
+
if (!("error" in res)) {
|
2915
|
+
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
2916
|
+
}
|
2917
|
+
} finally {
|
2918
|
+
if (!listViewPathMatch) {
|
2919
|
+
setSubmitting(false);
|
2920
|
+
}
|
2668
2921
|
}
|
2669
|
-
}
|
2670
|
-
return acc;
|
2671
|
-
},
|
2672
|
-
{}
|
2673
|
-
);
|
2674
|
-
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2675
|
-
(acc, [attribute, metadata]) => {
|
2676
|
-
return {
|
2677
|
-
...acc,
|
2678
|
-
[attribute]: metadata.edit
|
2679
|
-
};
|
2680
|
-
},
|
2681
|
-
{}
|
2682
|
-
);
|
2683
|
-
return {
|
2684
|
-
layout: panelledEditAttributes,
|
2685
|
-
components: componentEditAttributes,
|
2686
|
-
metadatas: editMetadatas,
|
2687
|
-
settings: {
|
2688
|
-
...data.contentType.settings,
|
2689
|
-
displayName: schema?.info.displayName
|
2922
|
+
}
|
2690
2923
|
},
|
2691
|
-
|
2692
|
-
|
2693
|
-
...schema?.pluginOptions,
|
2694
|
-
...data.contentType.options
|
2695
|
-
}
|
2924
|
+
variant: "danger",
|
2925
|
+
position: ["header", "table-row"]
|
2696
2926
|
};
|
2697
2927
|
};
|
2698
|
-
|
2699
|
-
|
2700
|
-
|
2701
|
-
|
2702
|
-
|
2703
|
-
|
2704
|
-
}
|
2705
|
-
|
2706
|
-
|
2707
|
-
|
2708
|
-
|
2709
|
-
|
2710
|
-
|
2711
|
-
|
2712
|
-
|
2713
|
-
|
2714
|
-
|
2715
|
-
|
2716
|
-
|
2717
|
-
|
2718
|
-
|
2719
|
-
|
2720
|
-
|
2721
|
-
|
2722
|
-
|
2723
|
-
|
2724
|
-
}
|
2725
|
-
}
|
2726
|
-
);
|
2928
|
+
DeleteAction$1.type = "delete";
|
2929
|
+
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2930
|
+
const Panels = () => {
|
2931
|
+
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2932
|
+
const [
|
2933
|
+
{
|
2934
|
+
query: { status }
|
2935
|
+
}
|
2936
|
+
] = strapiAdmin.useQueryParams({
|
2937
|
+
status: "draft"
|
2938
|
+
});
|
2939
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
2940
|
+
const plugins = strapiAdmin.useStrapiApp("Panels", (state) => state.plugins);
|
2941
|
+
const props = {
|
2942
|
+
activeTab: status,
|
2943
|
+
model,
|
2944
|
+
documentId: id,
|
2945
|
+
document: isCloning ? void 0 : document,
|
2946
|
+
meta: isCloning ? void 0 : meta,
|
2947
|
+
collectionType
|
2948
|
+
};
|
2949
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
|
2950
|
+
strapiAdmin.DescriptionComponentRenderer,
|
2951
|
+
{
|
2952
|
+
props,
|
2953
|
+
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2954
|
+
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsxRuntime.jsx(Panel, { ...description, children: content }, id2))
|
2955
|
+
}
|
2956
|
+
) });
|
2727
2957
|
};
|
2728
|
-
const
|
2729
|
-
|
2730
|
-
schema,
|
2731
|
-
components
|
2732
|
-
}) => {
|
2733
|
-
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2734
|
-
(acc, [attribute, metadata]) => {
|
2735
|
-
return {
|
2736
|
-
...acc,
|
2737
|
-
[attribute]: metadata.list
|
2738
|
-
};
|
2739
|
-
},
|
2740
|
-
{}
|
2741
|
-
);
|
2742
|
-
const listAttributes = convertListLayoutToFieldLayouts(
|
2743
|
-
data.contentType.layouts.list,
|
2744
|
-
schema?.attributes,
|
2745
|
-
listMetadatas,
|
2746
|
-
{ configurations: data.components, schemas: components },
|
2747
|
-
schemas
|
2748
|
-
);
|
2958
|
+
const ActionsPanel = () => {
|
2959
|
+
const { formatMessage } = reactIntl.useIntl();
|
2749
2960
|
return {
|
2750
|
-
|
2751
|
-
|
2752
|
-
|
2753
|
-
|
2754
|
-
|
2755
|
-
...schema?.pluginOptions,
|
2756
|
-
...data.contentType.options
|
2757
|
-
}
|
2961
|
+
title: formatMessage({
|
2962
|
+
id: "content-manager.containers.edit.panels.default.title",
|
2963
|
+
defaultMessage: "Entry"
|
2964
|
+
}),
|
2965
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(ActionsPanelContent, {})
|
2758
2966
|
};
|
2759
2967
|
};
|
2760
|
-
|
2761
|
-
|
2762
|
-
|
2763
|
-
|
2764
|
-
|
2968
|
+
ActionsPanel.type = "actions";
|
2969
|
+
const ActionsPanelContent = () => {
|
2970
|
+
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2971
|
+
const [
|
2972
|
+
{
|
2973
|
+
query: { status = "draft" }
|
2765
2974
|
}
|
2766
|
-
|
2767
|
-
|
2768
|
-
|
2769
|
-
|
2770
|
-
|
2771
|
-
|
2772
|
-
|
2773
|
-
|
2774
|
-
|
2775
|
-
|
2776
|
-
|
2777
|
-
|
2778
|
-
|
2779
|
-
|
2975
|
+
] = strapiAdmin.useQueryParams();
|
2976
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
2977
|
+
const plugins = strapiAdmin.useStrapiApp("ActionsPanel", (state) => state.plugins);
|
2978
|
+
const props = {
|
2979
|
+
activeTab: status,
|
2980
|
+
model,
|
2981
|
+
documentId: id,
|
2982
|
+
document: isCloning ? void 0 : document,
|
2983
|
+
meta: isCloning ? void 0 : meta,
|
2984
|
+
collectionType
|
2985
|
+
};
|
2986
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, width: "100%", children: [
|
2987
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
2988
|
+
strapiAdmin.DescriptionComponentRenderer,
|
2989
|
+
{
|
2990
|
+
props,
|
2991
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2992
|
+
children: (actions2) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActions, { actions: actions2 })
|
2993
|
+
}
|
2994
|
+
),
|
2995
|
+
/* @__PURE__ */ jsxRuntime.jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
2996
|
+
] });
|
2780
2997
|
};
|
2998
|
+
const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
2999
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
3000
|
+
designSystem.Flex,
|
3001
|
+
{
|
3002
|
+
ref,
|
3003
|
+
tag: "aside",
|
3004
|
+
"aria-labelledby": "additional-information",
|
3005
|
+
background: "neutral0",
|
3006
|
+
borderColor: "neutral150",
|
3007
|
+
hasRadius: true,
|
3008
|
+
paddingBottom: 4,
|
3009
|
+
paddingLeft: 4,
|
3010
|
+
paddingRight: 4,
|
3011
|
+
paddingTop: 4,
|
3012
|
+
shadow: "tableShadow",
|
3013
|
+
gap: 3,
|
3014
|
+
direction: "column",
|
3015
|
+
justifyContent: "stretch",
|
3016
|
+
alignItems: "flex-start",
|
3017
|
+
children: [
|
3018
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
3019
|
+
children
|
3020
|
+
]
|
3021
|
+
}
|
3022
|
+
);
|
3023
|
+
});
|
2781
3024
|
const ConfirmBulkActionDialog = ({
|
2782
3025
|
onToggleDialog,
|
2783
3026
|
isOpen = false,
|
@@ -2785,7 +3028,7 @@ const ConfirmBulkActionDialog = ({
|
|
2785
3028
|
endAction
|
2786
3029
|
}) => {
|
2787
3030
|
const { formatMessage } = reactIntl.useIntl();
|
2788
|
-
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, {
|
3031
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
2789
3032
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: formatMessage({
|
2790
3033
|
id: "app.components.ConfirmDialog.title",
|
2791
3034
|
defaultMessage: "Confirmation"
|
@@ -2816,6 +3059,7 @@ const ConfirmDialogPublishAll = ({
|
|
2816
3059
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler(getTranslation);
|
2817
3060
|
const { model, schema } = useDoc();
|
2818
3061
|
const [{ query }] = strapiAdmin.useQueryParams();
|
3062
|
+
const enableDraftRelationsCount = false;
|
2819
3063
|
const {
|
2820
3064
|
data: countDraftRelations = 0,
|
2821
3065
|
isLoading,
|
@@ -2827,7 +3071,7 @@ const ConfirmDialogPublishAll = ({
|
|
2827
3071
|
locale: query?.plugins?.i18n?.locale
|
2828
3072
|
},
|
2829
3073
|
{
|
2830
|
-
skip:
|
3074
|
+
skip: !enableDraftRelationsCount
|
2831
3075
|
}
|
2832
3076
|
);
|
2833
3077
|
React__namespace.useEffect(() => {
|
@@ -2906,7 +3150,14 @@ const formatErrorMessages = (errors, parentKey, formatMessage) => {
|
|
2906
3150
|
)
|
2907
3151
|
);
|
2908
3152
|
} else {
|
2909
|
-
messages.push(
|
3153
|
+
messages.push(
|
3154
|
+
...formatErrorMessages(
|
3155
|
+
// @ts-expect-error TODO: check why value is not compatible with FormErrors
|
3156
|
+
value,
|
3157
|
+
currentKey,
|
3158
|
+
formatMessage
|
3159
|
+
)
|
3160
|
+
);
|
2910
3161
|
}
|
2911
3162
|
} else {
|
2912
3163
|
messages.push(
|
@@ -3005,7 +3256,7 @@ const SelectedEntriesTableContent = ({
|
|
3005
3256
|
status: row.status
|
3006
3257
|
}
|
3007
3258
|
) }),
|
3008
|
-
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
3259
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
3009
3260
|
designSystem.IconButton,
|
3010
3261
|
{
|
3011
3262
|
tag: reactRouterDom.Link,
|
@@ -3028,9 +3279,10 @@ const SelectedEntriesTableContent = ({
|
|
3028
3279
|
),
|
3029
3280
|
target: "_blank",
|
3030
3281
|
marginLeft: "auto",
|
3031
|
-
|
3282
|
+
variant: "ghost",
|
3283
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, { width: "1.6rem", height: "1.6rem" })
|
3032
3284
|
}
|
3033
|
-
) })
|
3285
|
+
) }) })
|
3034
3286
|
] }, row.id)) })
|
3035
3287
|
] });
|
3036
3288
|
};
|
@@ -3067,7 +3319,13 @@ const SelectedEntriesModalContent = ({
|
|
3067
3319
|
);
|
3068
3320
|
const { rows, validationErrors } = React__namespace.useMemo(() => {
|
3069
3321
|
if (data.length > 0 && schema) {
|
3070
|
-
const validate = createYupSchema(
|
3322
|
+
const validate = createYupSchema(
|
3323
|
+
schema.attributes,
|
3324
|
+
components,
|
3325
|
+
// Since this is the "Publish" action, the validation
|
3326
|
+
// schema must enforce the rules for published entities
|
3327
|
+
{ status: "published" }
|
3328
|
+
);
|
3071
3329
|
const validationErrors2 = {};
|
3072
3330
|
const rows2 = data.map((entry) => {
|
3073
3331
|
try {
|
@@ -3417,7 +3675,7 @@ const TableActions = ({ document }) => {
|
|
3417
3675
|
strapiAdmin.DescriptionComponentRenderer,
|
3418
3676
|
{
|
3419
3677
|
props,
|
3420
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3678
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
3421
3679
|
children: (actions2) => {
|
3422
3680
|
const tableRowActions = actions2.filter((action) => {
|
3423
3681
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3528,7 +3786,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3528
3786
|
}),
|
3529
3787
|
content: /* @__PURE__ */ jsxRuntime.jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
3530
3788
|
footer: ({ onClose }) => {
|
3531
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.
|
3789
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
3532
3790
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
3533
3791
|
id: "cancel",
|
3534
3792
|
defaultMessage: "Cancel"
|
@@ -3569,8 +3827,7 @@ class ContentManagerPlugin {
|
|
3569
3827
|
documentActions = [
|
3570
3828
|
...DEFAULT_ACTIONS,
|
3571
3829
|
...DEFAULT_TABLE_ROW_ACTIONS,
|
3572
|
-
...DEFAULT_HEADER_ACTIONS
|
3573
|
-
HistoryAction
|
3830
|
+
...DEFAULT_HEADER_ACTIONS
|
3574
3831
|
];
|
3575
3832
|
editViewSidePanels = [ActionsPanel];
|
3576
3833
|
headerActions = [];
|
@@ -3659,6 +3916,52 @@ const getPrintableType = (value) => {
|
|
3659
3916
|
}
|
3660
3917
|
return nativeType;
|
3661
3918
|
};
|
3919
|
+
const HistoryAction = ({ model, document }) => {
|
3920
|
+
const { formatMessage } = reactIntl.useIntl();
|
3921
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3922
|
+
const navigate = reactRouterDom.useNavigate();
|
3923
|
+
const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
|
3924
|
+
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3925
|
+
return null;
|
3926
|
+
}
|
3927
|
+
return {
|
3928
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
|
3929
|
+
label: formatMessage({
|
3930
|
+
id: "content-manager.history.document-action",
|
3931
|
+
defaultMessage: "Content History"
|
3932
|
+
}),
|
3933
|
+
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
3934
|
+
disabled: (
|
3935
|
+
/**
|
3936
|
+
* The user is creating a new document.
|
3937
|
+
* It hasn't been saved yet, so there's no history to go to
|
3938
|
+
*/
|
3939
|
+
!document || /**
|
3940
|
+
* The document has been created but the current dimension has never been saved.
|
3941
|
+
* For example, the user is creating a new locale in an existing document,
|
3942
|
+
* so there's no history for the document in that locale
|
3943
|
+
*/
|
3944
|
+
!document.id || /**
|
3945
|
+
* History is only available for content types created by the user.
|
3946
|
+
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
3947
|
+
* which start with `admin::` or `plugin::`
|
3948
|
+
*/
|
3949
|
+
!model.startsWith("api::")
|
3950
|
+
),
|
3951
|
+
position: "header"
|
3952
|
+
};
|
3953
|
+
};
|
3954
|
+
HistoryAction.type = "history";
|
3955
|
+
const historyAdmin = {
|
3956
|
+
bootstrap(app) {
|
3957
|
+
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
3958
|
+
addDocumentAction((actions2) => {
|
3959
|
+
const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
|
3960
|
+
actions2.splice(indexOfDeleteAction, 0, HistoryAction);
|
3961
|
+
return actions2;
|
3962
|
+
});
|
3963
|
+
}
|
3964
|
+
};
|
3662
3965
|
const initialState = {
|
3663
3966
|
collectionTypeLinks: [],
|
3664
3967
|
components: [],
|
@@ -3709,15 +4012,29 @@ const index = {
|
|
3709
4012
|
defaultMessage: "Content Manager"
|
3710
4013
|
},
|
3711
4014
|
permissions: [],
|
3712
|
-
Component: () => Promise.resolve().then(() => require("./layout--iHdZzRk.js")).then((mod) => ({ default: mod.Layout })),
|
3713
4015
|
position: 1
|
3714
4016
|
});
|
4017
|
+
app.router.addRoute({
|
4018
|
+
path: "content-manager/*",
|
4019
|
+
lazy: async () => {
|
4020
|
+
const { Layout } = await Promise.resolve().then(() => require("./layout-CWgZzMYf.js"));
|
4021
|
+
return {
|
4022
|
+
Component: Layout
|
4023
|
+
};
|
4024
|
+
},
|
4025
|
+
children: routes
|
4026
|
+
});
|
3715
4027
|
app.registerPlugin(cm.config);
|
3716
4028
|
},
|
4029
|
+
bootstrap(app) {
|
4030
|
+
if (typeof historyAdmin.bootstrap === "function") {
|
4031
|
+
historyAdmin.bootstrap(app);
|
4032
|
+
}
|
4033
|
+
},
|
3717
4034
|
async registerTrads({ locales }) {
|
3718
4035
|
const importedTrads = await Promise.all(
|
3719
4036
|
locales.map((locale) => {
|
3720
|
-
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => Promise.resolve().then(() => require("./ar-BUUWXIYu.js")), "./translations/ca.json": () => Promise.resolve().then(() => require("./ca-Cmk45QO6.js")), "./translations/cs.json": () => Promise.resolve().then(() => require("./cs-CkJy6B2v.js")), "./translations/de.json": () => Promise.resolve().then(() => require("./de-CCEmbAah.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-
|
4037
|
+
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => Promise.resolve().then(() => require("./ar-BUUWXIYu.js")), "./translations/ca.json": () => Promise.resolve().then(() => require("./ca-Cmk45QO6.js")), "./translations/cs.json": () => Promise.resolve().then(() => require("./cs-CkJy6B2v.js")), "./translations/de.json": () => Promise.resolve().then(() => require("./de-CCEmbAah.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-BlhnxQfj.js")), "./translations/es.json": () => Promise.resolve().then(() => require("./es-EUonQTon.js")), "./translations/eu.json": () => Promise.resolve().then(() => require("./eu-VDH-3ovk.js")), "./translations/fr.json": () => Promise.resolve().then(() => require("./fr-B7kGGg3E.js")), "./translations/gu.json": () => Promise.resolve().then(() => require("./gu-BRmF601H.js")), "./translations/hi.json": () => Promise.resolve().then(() => require("./hi-CCJBptSq.js")), "./translations/hu.json": () => Promise.resolve().then(() => require("./hu-sNV_yLYy.js")), "./translations/id.json": () => Promise.resolve().then(() => require("./id-B5Ser98A.js")), "./translations/it.json": () => Promise.resolve().then(() => require("./it-DkBIs7vD.js")), "./translations/ja.json": () => Promise.resolve().then(() => require("./ja-CcFe8diO.js")), "./translations/ko.json": () => Promise.resolve().then(() => require("./ko-woFZPmLk.js")), "./translations/ml.json": () => Promise.resolve().then(() => require("./ml-C2W8N8k1.js")), "./translations/ms.json": () => Promise.resolve().then(() => require("./ms-BuFotyP_.js")), "./translations/nl.json": () => Promise.resolve().then(() => require("./nl-bbEOHChV.js")), "./translations/pl.json": () => Promise.resolve().then(() => require("./pl-uzwG-hk7.js")), "./translations/pt-BR.json": () => Promise.resolve().then(() => require("./pt-BR-BiOz37D9.js")), "./translations/pt.json": () => Promise.resolve().then(() => require("./pt-CeXQuq50.js")), "./translations/ru.json": () => Promise.resolve().then(() => require("./ru-BT3ybNny.js")), "./translations/sa.json": () => Promise.resolve().then(() => require("./sa-CcvkYInH.js")), "./translations/sk.json": () => Promise.resolve().then(() => require("./sk-CvY09Xjv.js")), "./translations/sv.json": () => Promise.resolve().then(() => require("./sv-MYDuzgvT.js")), "./translations/th.json": () => Promise.resolve().then(() => require("./th-D9_GfAjc.js")), "./translations/tr.json": () => Promise.resolve().then(() => require("./tr-D9UH-O_R.js")), "./translations/uk.json": () => Promise.resolve().then(() => require("./uk-C8EiqJY7.js")), "./translations/vi.json": () => Promise.resolve().then(() => require("./vi-CJlYDheJ.js")), "./translations/zh-Hans.json": () => Promise.resolve().then(() => require("./zh-Hans-9kOncHGw.js")), "./translations/zh.json": () => Promise.resolve().then(() => require("./zh-CQQfszqR.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
|
3721
4038
|
return {
|
3722
4039
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3723
4040
|
locale
|
@@ -3735,6 +4052,7 @@ const index = {
|
|
3735
4052
|
};
|
3736
4053
|
exports.ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD = ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD;
|
3737
4054
|
exports.BulkActionsRenderer = BulkActionsRenderer;
|
4055
|
+
exports.CLONE_PATH = CLONE_PATH;
|
3738
4056
|
exports.COLLECTION_TYPES = COLLECTION_TYPES;
|
3739
4057
|
exports.CREATOR_FIELDS = CREATOR_FIELDS;
|
3740
4058
|
exports.DEFAULT_SETTINGS = DEFAULT_SETTINGS;
|
@@ -3761,8 +4079,8 @@ exports.getDisplayName = getDisplayName;
|
|
3761
4079
|
exports.getMainField = getMainField;
|
3762
4080
|
exports.getTranslation = getTranslation;
|
3763
4081
|
exports.index = index;
|
3764
|
-
exports.routes = routes;
|
3765
4082
|
exports.setInitialData = setInitialData;
|
4083
|
+
exports.useContentManagerContext = useContentManagerContext;
|
3766
4084
|
exports.useContentTypeSchema = useContentTypeSchema;
|
3767
4085
|
exports.useDoc = useDoc;
|
3768
4086
|
exports.useDocLayout = useDocLayout;
|
@@ -3775,4 +4093,4 @@ exports.useGetAllDocumentsQuery = useGetAllDocumentsQuery;
|
|
3775
4093
|
exports.useGetContentTypeConfigurationQuery = useGetContentTypeConfigurationQuery;
|
3776
4094
|
exports.useGetInitialDataQuery = useGetInitialDataQuery;
|
3777
4095
|
exports.useUpdateContentTypeConfigurationMutation = useUpdateContentTypeConfigurationMutation;
|
3778
|
-
//# sourceMappingURL=index-
|
4096
|
+
//# sourceMappingURL=index-DTKVhcla.js.map
|