@strapi/content-manager 0.0.0-experimental.2a7cb5ff33df35e8ccde5ef918f9f9a4a3ee9a08 → 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-BvHtG7uH.js → ComponentConfigurationPage-DnnZJc1F.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-BvHtG7uH.js.map → ComponentConfigurationPage-DnnZJc1F.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-DHNM3YBz.mjs → ComponentConfigurationPage-hLMNf7KI.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-DHNM3YBz.mjs.map → ComponentConfigurationPage-hLMNf7KI.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-DOmfCEMo.js → EditConfigurationPage-CpLj5gYZ.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-DOmfCEMo.js.map → EditConfigurationPage-CpLj5gYZ.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-Cp6HAEzN.mjs → EditConfigurationPage-Dh6sq-G4.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-Cp6HAEzN.mjs.map → EditConfigurationPage-Dh6sq-G4.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-BtkEx339.mjs → EditViewPage-BU1ugeVi.mjs} +19 -8
- package/dist/_chunks/EditViewPage-BU1ugeVi.mjs.map +1 -0
- package/dist/_chunks/{EditViewPage-BqNpC6hO.js → EditViewPage-D2QVRr_2.js} +19 -8
- package/dist/_chunks/EditViewPage-D2QVRr_2.js.map +1 -0
- package/dist/_chunks/{Field-lsPFnAmH.js → Field-BEDX9i_V.js} +196 -143
- package/dist/_chunks/Field-BEDX9i_V.js.map +1 -0
- package/dist/_chunks/{Field-R5NbffTB.mjs → Field-VSPY6uzs.mjs} +194 -141
- package/dist/_chunks/Field-VSPY6uzs.mjs.map +1 -0
- package/dist/_chunks/{Form-BHmXSfyy.mjs → Form-05Oaes1N.mjs} +35 -16
- package/dist/_chunks/Form-05Oaes1N.mjs.map +1 -0
- package/dist/_chunks/{Form-CcGboku8.js → Form-DCaY8xBX.js} +35 -16
- package/dist/_chunks/Form-DCaY8xBX.js.map +1 -0
- package/dist/_chunks/{History-ByUPL3T3.mjs → History-BqO2G3MV.mjs} +28 -18
- package/dist/_chunks/History-BqO2G3MV.mjs.map +1 -0
- package/dist/_chunks/{History-Bsud8jwh.js → History-BrJ1tUvt.js} +28 -18
- package/dist/_chunks/History-BrJ1tUvt.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-Bm5HACXf.mjs → ListConfigurationPage-C6rsFlme.mjs} +20 -8
- package/dist/_chunks/ListConfigurationPage-C6rsFlme.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DiT463qx.js → ListConfigurationPage-Eane5LKE.js} +20 -8
- package/dist/_chunks/ListConfigurationPage-Eane5LKE.js.map +1 -0
- package/dist/_chunks/{ListViewPage-CsrC9L_d.js → ListViewPage-Coj-RPsx.js} +49 -40
- package/dist/_chunks/ListViewPage-Coj-RPsx.js.map +1 -0
- package/dist/_chunks/{ListViewPage-JSyNAAYu.mjs → ListViewPage-yE_zYhcI.mjs} +47 -38
- package/dist/_chunks/ListViewPage-yE_zYhcI.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-Bsvng4II.js → NoContentTypePage-BDJ0dshy.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-Bsvng4II.js.map → NoContentTypePage-BDJ0dshy.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-CsrQUpBE.mjs → NoContentTypePage-NW_FSVdY.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-CsrQUpBE.mjs.map → NoContentTypePage-NW_FSVdY.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-CdHNJtEf.js → NoPermissionsPage-BOtb5FTM.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-CdHNJtEf.js.map → NoPermissionsPage-BOtb5FTM.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-DNmf_pj0.mjs → NoPermissionsPage-h0I3ImsX.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-DNmf_pj0.mjs.map → NoPermissionsPage-h0I3ImsX.mjs.map} +1 -1
- package/dist/_chunks/{Relations-CghaPv2D.js → Relations-CVh0DOKv.js} +4 -4
- package/dist/_chunks/Relations-CVh0DOKv.js.map +1 -0
- package/dist/_chunks/{Relations-u8-37jK0.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-CaE6NG4a.mjs → index-CPCHQ3X_.mjs} +966 -682
- package/dist/_chunks/index-CPCHQ3X_.mjs.map +1 -0
- package/dist/_chunks/{index-BOZx6IMg.js → index-DTKVhcla.js} +947 -663
- package/dist/_chunks/index-DTKVhcla.js.map +1 -0
- package/dist/_chunks/{layout-Bx7svTbY.mjs → layout-B4UhJ8MJ.mjs} +23 -10
- package/dist/_chunks/layout-B4UhJ8MJ.mjs.map +1 -0
- package/dist/_chunks/{layout-Ciz224q5.js → layout-CWgZzMYf.js} +22 -9
- package/dist/_chunks/layout-CWgZzMYf.js.map +1 -0
- package/dist/_chunks/{relations-Cxc1cEv3.mjs → relations-B83Ge9a7.mjs} +2 -2
- package/dist/_chunks/{relations-Cxc1cEv3.mjs.map → relations-B83Ge9a7.mjs.map} +1 -1
- package/dist/_chunks/{relations-CP8sB2YZ.js → relations-D81a_2zw.js} +2 -2
- package/dist/_chunks/{relations-CP8sB2YZ.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 +5 -4
- 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/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 +178 -108
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +179 -109
- 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-BqNpC6hO.js.map +0 -1
- package/dist/_chunks/EditViewPage-BtkEx339.mjs.map +0 -1
- package/dist/_chunks/Field-R5NbffTB.mjs.map +0 -1
- package/dist/_chunks/Field-lsPFnAmH.js.map +0 -1
- package/dist/_chunks/Form-BHmXSfyy.mjs.map +0 -1
- package/dist/_chunks/Form-CcGboku8.js.map +0 -1
- package/dist/_chunks/History-Bsud8jwh.js.map +0 -1
- package/dist/_chunks/History-ByUPL3T3.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-Bm5HACXf.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DiT463qx.js.map +0 -1
- package/dist/_chunks/ListViewPage-CsrC9L_d.js.map +0 -1
- package/dist/_chunks/ListViewPage-JSyNAAYu.mjs.map +0 -1
- package/dist/_chunks/Relations-CghaPv2D.js.map +0 -1
- package/dist/_chunks/Relations-u8-37jK0.mjs.map +0 -1
- package/dist/_chunks/index-BOZx6IMg.js.map +0 -1
- package/dist/_chunks/index-CaE6NG4a.mjs.map +0 -1
- package/dist/_chunks/layout-Bx7svTbY.mjs.map +0 -1
- package/dist/_chunks/layout-Ciz224q5.js.map +0 -1
- package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
- package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
- package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
- package/strapi-server.js +0 -3
@@ -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,7 +179,8 @@ 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({
|
@@ -229,7 +194,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
229
194
|
params: query
|
230
195
|
}
|
231
196
|
}),
|
232
|
-
invalidatesTags: (_result,
|
197
|
+
invalidatesTags: (_result, error, { model }) => {
|
198
|
+
if (error) {
|
199
|
+
return [];
|
200
|
+
}
|
201
|
+
return [{ type: "Document", id: `${model}_LIST` }];
|
202
|
+
}
|
233
203
|
}),
|
234
204
|
cloneDocument: builder.mutation({
|
235
205
|
query: ({ model, sourceId, data, params }) => ({
|
@@ -240,7 +210,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
240
210
|
params
|
241
211
|
}
|
242
212
|
}),
|
243
|
-
invalidatesTags: (_result, _error, { model }) => [
|
213
|
+
invalidatesTags: (_result, _error, { model }) => [
|
214
|
+
{ type: "Document", id: `${model}_LIST` },
|
215
|
+
{ type: "UidAvailability", id: model }
|
216
|
+
]
|
244
217
|
}),
|
245
218
|
/**
|
246
219
|
* Creates a new collection-type document. This should ONLY be used for collection-types.
|
@@ -257,7 +230,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
257
230
|
}),
|
258
231
|
invalidatesTags: (result, _error, { model }) => [
|
259
232
|
{ type: "Document", id: `${model}_LIST` },
|
260
|
-
"Relations"
|
233
|
+
"Relations",
|
234
|
+
{ type: "UidAvailability", id: model }
|
261
235
|
]
|
262
236
|
}),
|
263
237
|
deleteDocument: builder.mutation({
|
@@ -298,7 +272,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
298
272
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
299
273
|
},
|
300
274
|
{ type: "Document", id: `${model}_LIST` },
|
301
|
-
"Relations"
|
275
|
+
"Relations",
|
276
|
+
{ type: "UidAvailability", id: model }
|
302
277
|
];
|
303
278
|
}
|
304
279
|
}),
|
@@ -316,6 +291,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
316
291
|
}),
|
317
292
|
providesTags: (result, _error, arg) => {
|
318
293
|
return [
|
294
|
+
{ type: "Document", id: `ALL_LIST` },
|
319
295
|
{ type: "Document", id: `${arg.model}_LIST` },
|
320
296
|
...result?.results.map(({ documentId }) => ({
|
321
297
|
type: "Document",
|
@@ -354,6 +330,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
354
330
|
{
|
355
331
|
type: "Document",
|
356
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`
|
357
338
|
}
|
358
339
|
];
|
359
340
|
}
|
@@ -417,8 +398,21 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
417
398
|
type: "Document",
|
418
399
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
419
400
|
},
|
420
|
-
"Relations"
|
401
|
+
"Relations",
|
402
|
+
{ type: "UidAvailability", id: model }
|
421
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
|
+
}
|
422
416
|
}
|
423
417
|
}),
|
424
418
|
unpublishDocument: builder.mutation({
|
@@ -488,7 +482,7 @@ const buildValidParams = (query) => {
|
|
488
482
|
const isBaseQueryError = (error) => {
|
489
483
|
return error.name !== void 0;
|
490
484
|
};
|
491
|
-
const createYupSchema = (attributes = {}, components = {}) => {
|
485
|
+
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
492
486
|
const createModelSchema = (attributes2) => yup__namespace.object().shape(
|
493
487
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
494
488
|
if (DOCUMENT_META_FIELDS.includes(name)) {
|
@@ -501,7 +495,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
501
495
|
addMinValidation,
|
502
496
|
addMaxValidation,
|
503
497
|
addRegexValidation
|
504
|
-
].map((fn) => fn(attribute));
|
498
|
+
].map((fn) => fn(attribute, options));
|
505
499
|
const transformSchema = pipe__default.default(...validations);
|
506
500
|
switch (attribute.type) {
|
507
501
|
case "component": {
|
@@ -602,6 +596,14 @@ const createAttributeSchema = (attribute) => {
|
|
602
596
|
if (!value || typeof value === "string" && value.length === 0) {
|
603
597
|
return true;
|
604
598
|
}
|
599
|
+
if (typeof value === "object") {
|
600
|
+
try {
|
601
|
+
JSON.stringify(value);
|
602
|
+
return true;
|
603
|
+
} catch (err) {
|
604
|
+
return false;
|
605
|
+
}
|
606
|
+
}
|
605
607
|
try {
|
606
608
|
JSON.parse(value);
|
607
609
|
return true;
|
@@ -620,13 +622,7 @@ const createAttributeSchema = (attribute) => {
|
|
620
622
|
return yup__namespace.mixed();
|
621
623
|
}
|
622
624
|
};
|
623
|
-
const
|
624
|
-
if (attribute.required && attribute.type !== "relation") {
|
625
|
-
return schema.required({
|
626
|
-
id: strapiAdmin.translatedErrors.required.id,
|
627
|
-
defaultMessage: "This field is required."
|
628
|
-
});
|
629
|
-
}
|
625
|
+
const nullableSchema = (schema) => {
|
630
626
|
return schema?.nullable ? schema.nullable() : (
|
631
627
|
// In some cases '.nullable' will not be available on the schema.
|
632
628
|
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
@@ -634,7 +630,22 @@ const addRequiredValidation = (attribute) => (schema) => {
|
|
634
630
|
schema
|
635
631
|
);
|
636
632
|
};
|
637
|
-
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
|
+
}
|
638
649
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
639
650
|
return schema.min(attribute.minLength, {
|
640
651
|
...strapiAdmin.translatedErrors.minLength,
|
@@ -656,9 +667,31 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
656
667
|
}
|
657
668
|
return schema;
|
658
669
|
};
|
659
|
-
const addMinValidation = (attribute) => (schema) => {
|
670
|
+
const addMinValidation = (attribute, options) => (schema) => {
|
660
671
|
if ("min" in attribute) {
|
661
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
|
+
}
|
662
695
|
if ("min" in schema && min) {
|
663
696
|
return schema.min(min, {
|
664
697
|
...strapiAdmin.translatedErrors.min,
|
@@ -777,19 +810,115 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
|
|
777
810
|
}, {});
|
778
811
|
return componentsByKey;
|
779
812
|
};
|
780
|
-
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);
|
781
912
|
const { toggleNotification } = strapiAdmin.useNotification();
|
782
913
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
914
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
783
915
|
const {
|
784
|
-
|
785
|
-
isLoading:
|
786
|
-
|
787
|
-
|
788
|
-
} =
|
789
|
-
|
790
|
-
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
791
|
-
});
|
792
|
-
const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
|
916
|
+
data,
|
917
|
+
isLoading: isLoadingConfigs,
|
918
|
+
error,
|
919
|
+
isFetching: isFetchingConfigs
|
920
|
+
} = useGetContentTypeConfigurationQuery(model);
|
921
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
793
922
|
React__namespace.useEffect(() => {
|
794
923
|
if (error) {
|
795
924
|
toggleNotification({
|
@@ -797,48 +926,261 @@ const useDocument = (args, opts) => {
|
|
797
926
|
message: formatAPIError(error)
|
798
927
|
});
|
799
928
|
}
|
800
|
-
}, [
|
801
|
-
const
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
(document) => {
|
809
|
-
if (!validationSchema) {
|
810
|
-
throw new Error(
|
811
|
-
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
812
|
-
);
|
813
|
-
}
|
814
|
-
try {
|
815
|
-
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
816
|
-
return null;
|
817
|
-
} catch (error2) {
|
818
|
-
if (error2 instanceof yup.ValidationError) {
|
819
|
-
return strapiAdmin.getYupValidationErrors(error2);
|
820
|
-
}
|
821
|
-
throw error2;
|
822
|
-
}
|
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
|
823
937
|
},
|
824
|
-
[
|
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]
|
825
954
|
);
|
826
|
-
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
827
955
|
return {
|
828
|
-
|
829
|
-
document: data?.data,
|
830
|
-
meta: data?.meta,
|
956
|
+
error,
|
831
957
|
isLoading,
|
832
|
-
|
833
|
-
|
958
|
+
edit,
|
959
|
+
list: listLayout
|
834
960
|
};
|
835
961
|
};
|
836
|
-
const
|
837
|
-
const {
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
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");
|
842
1184
|
}
|
843
1185
|
if (!slug) {
|
844
1186
|
throw new Error("Could not find model in url params");
|
@@ -855,6 +1197,45 @@ const useDoc = () => {
|
|
855
1197
|
)
|
856
1198
|
};
|
857
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
|
+
};
|
858
1239
|
const prefixPluginTranslations = (trad, pluginId) => {
|
859
1240
|
if (!pluginId) {
|
860
1241
|
throw new TypeError("pluginId can't be empty");
|
@@ -874,6 +1255,8 @@ const useDocumentActions = () => {
|
|
874
1255
|
const { formatMessage } = reactIntl.useIntl();
|
875
1256
|
const { trackUsage } = strapiAdmin.useTracking();
|
876
1257
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
1258
|
+
const navigate = reactRouterDom.useNavigate();
|
1259
|
+
const setCurrentStep = strapiAdmin.useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
877
1260
|
const [deleteDocument] = useDeleteDocumentMutation();
|
878
1261
|
const _delete = React__namespace.useCallback(
|
879
1262
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -1188,6 +1571,7 @@ const useDocumentActions = () => {
|
|
1188
1571
|
defaultMessage: "Saved document"
|
1189
1572
|
})
|
1190
1573
|
});
|
1574
|
+
setCurrentStep("contentManager.success");
|
1191
1575
|
return res.data;
|
1192
1576
|
} catch (err) {
|
1193
1577
|
toggleNotification({
|
@@ -1209,7 +1593,6 @@ const useDocumentActions = () => {
|
|
1209
1593
|
sourceId
|
1210
1594
|
});
|
1211
1595
|
if ("error" in res) {
|
1212
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1213
1596
|
return { error: res.error };
|
1214
1597
|
}
|
1215
1598
|
toggleNotification({
|
@@ -1228,7 +1611,7 @@ const useDocumentActions = () => {
|
|
1228
1611
|
throw err;
|
1229
1612
|
}
|
1230
1613
|
},
|
1231
|
-
[autoCloneDocument,
|
1614
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1232
1615
|
);
|
1233
1616
|
const [cloneDocument] = useCloneDocumentMutation();
|
1234
1617
|
const clone = React__namespace.useCallback(
|
@@ -1254,6 +1637,7 @@ const useDocumentActions = () => {
|
|
1254
1637
|
defaultMessage: "Cloned document"
|
1255
1638
|
})
|
1256
1639
|
});
|
1640
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1257
1641
|
return res.data;
|
1258
1642
|
} catch (err) {
|
1259
1643
|
toggleNotification({
|
@@ -1264,7 +1648,7 @@ const useDocumentActions = () => {
|
|
1264
1648
|
throw err;
|
1265
1649
|
}
|
1266
1650
|
},
|
1267
|
-
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
|
1651
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1268
1652
|
);
|
1269
1653
|
const [getDoc] = useLazyGetDocumentQuery();
|
1270
1654
|
const getDocument = React__namespace.useCallback(
|
@@ -1290,7 +1674,7 @@ const useDocumentActions = () => {
|
|
1290
1674
|
};
|
1291
1675
|
};
|
1292
1676
|
const ProtectedHistoryPage = React.lazy(
|
1293
|
-
() => Promise.resolve().then(() => require("./History-
|
1677
|
+
() => Promise.resolve().then(() => require("./History-BrJ1tUvt.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1294
1678
|
);
|
1295
1679
|
const routes$1 = [
|
1296
1680
|
{
|
@@ -1303,31 +1687,31 @@ const routes$1 = [
|
|
1303
1687
|
}
|
1304
1688
|
];
|
1305
1689
|
const ProtectedEditViewPage = React.lazy(
|
1306
|
-
() => Promise.resolve().then(() => require("./EditViewPage-
|
1690
|
+
() => Promise.resolve().then(() => require("./EditViewPage-D2QVRr_2.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1307
1691
|
);
|
1308
1692
|
const ProtectedListViewPage = React.lazy(
|
1309
|
-
() => Promise.resolve().then(() => require("./ListViewPage-
|
1693
|
+
() => Promise.resolve().then(() => require("./ListViewPage-Coj-RPsx.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1310
1694
|
);
|
1311
1695
|
const ProtectedListConfiguration = React.lazy(
|
1312
|
-
() => Promise.resolve().then(() => require("./ListConfigurationPage-
|
1696
|
+
() => Promise.resolve().then(() => require("./ListConfigurationPage-Eane5LKE.js")).then((mod) => ({
|
1313
1697
|
default: mod.ProtectedListConfiguration
|
1314
1698
|
}))
|
1315
1699
|
);
|
1316
1700
|
const ProtectedEditConfigurationPage = React.lazy(
|
1317
|
-
() => Promise.resolve().then(() => require("./EditConfigurationPage-
|
1701
|
+
() => Promise.resolve().then(() => require("./EditConfigurationPage-CpLj5gYZ.js")).then((mod) => ({
|
1318
1702
|
default: mod.ProtectedEditConfigurationPage
|
1319
1703
|
}))
|
1320
1704
|
);
|
1321
1705
|
const ProtectedComponentConfigurationPage = React.lazy(
|
1322
|
-
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-
|
1706
|
+
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-DnnZJc1F.js")).then((mod) => ({
|
1323
1707
|
default: mod.ProtectedComponentConfigurationPage
|
1324
1708
|
}))
|
1325
1709
|
);
|
1326
1710
|
const NoPermissions = React.lazy(
|
1327
|
-
() => Promise.resolve().then(() => require("./NoPermissionsPage-
|
1711
|
+
() => Promise.resolve().then(() => require("./NoPermissionsPage-BOtb5FTM.js")).then((mod) => ({ default: mod.NoPermissions }))
|
1328
1712
|
);
|
1329
1713
|
const NoContentType = React.lazy(
|
1330
|
-
() => Promise.resolve().then(() => require("./NoContentTypePage-
|
1714
|
+
() => Promise.resolve().then(() => require("./NoContentTypePage-BDJ0dshy.js")).then((mod) => ({ default: mod.NoContentType }))
|
1331
1715
|
);
|
1332
1716
|
const CollectionTypePages = () => {
|
1333
1717
|
const { collectionType } = reactRouterDom.useParams();
|
@@ -1441,12 +1825,14 @@ const DocumentActionButton = (action) => {
|
|
1441
1825
|
/* @__PURE__ */ jsxRuntime.jsx(
|
1442
1826
|
designSystem.Button,
|
1443
1827
|
{
|
1444
|
-
flex:
|
1828
|
+
flex: "auto",
|
1445
1829
|
startIcon: action.icon,
|
1446
1830
|
disabled: action.disabled,
|
1447
1831
|
onClick: handleClick(action),
|
1448
1832
|
justifyContent: "center",
|
1449
1833
|
variant: action.variant || "default",
|
1834
|
+
paddingTop: "7px",
|
1835
|
+
paddingBottom: "7px",
|
1450
1836
|
children: action.label
|
1451
1837
|
}
|
1452
1838
|
),
|
@@ -1454,7 +1840,7 @@ const DocumentActionButton = (action) => {
|
|
1454
1840
|
DocumentActionConfirmDialog,
|
1455
1841
|
{
|
1456
1842
|
...action.dialog,
|
1457
|
-
variant: action.variant,
|
1843
|
+
variant: action.dialog?.variant ?? action.variant,
|
1458
1844
|
isOpen: dialogId === action.id,
|
1459
1845
|
onClose: handleClose
|
1460
1846
|
}
|
@@ -1511,9 +1897,9 @@ const DocumentActionsMenu = ({
|
|
1511
1897
|
disabled: isDisabled,
|
1512
1898
|
size: "S",
|
1513
1899
|
endIcon: null,
|
1514
|
-
paddingTop: "
|
1515
|
-
paddingLeft: "
|
1516
|
-
paddingRight: "
|
1900
|
+
paddingTop: "4px",
|
1901
|
+
paddingLeft: "7px",
|
1902
|
+
paddingRight: "7px",
|
1517
1903
|
variant,
|
1518
1904
|
children: [
|
1519
1905
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.More, { "aria-hidden": true, focusable: false }),
|
@@ -1524,7 +1910,7 @@ const DocumentActionsMenu = ({
|
|
1524
1910
|
]
|
1525
1911
|
}
|
1526
1912
|
),
|
1527
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, {
|
1913
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1528
1914
|
actions2.map((action) => {
|
1529
1915
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
1530
1916
|
designSystem.Menu.Item,
|
@@ -1533,10 +1919,25 @@ const DocumentActionsMenu = ({
|
|
1533
1919
|
onSelect: handleClick(action),
|
1534
1920
|
display: "block",
|
1535
1921
|
children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", gap: 4, children: [
|
1536
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
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
|
+
),
|
1540
1941
|
action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsxRuntime.jsx(
|
1541
1942
|
designSystem.Flex,
|
1542
1943
|
{
|
@@ -1633,11 +2034,11 @@ const DocumentActionConfirmDialog = ({
|
|
1633
2034
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
1634
2035
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: content }),
|
1635
2036
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
|
1636
|
-
/* @__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({
|
1637
2038
|
id: "app.components.Button.cancel",
|
1638
2039
|
defaultMessage: "Cancel"
|
1639
2040
|
}) }) }),
|
1640
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, children: formatMessage({
|
2041
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
|
1641
2042
|
id: "app.components.Button.confirm",
|
1642
2043
|
defaultMessage: "Confirm"
|
1643
2044
|
}) })
|
@@ -1660,8 +2061,8 @@ const DocumentActionModal = ({
|
|
1660
2061
|
};
|
1661
2062
|
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Content, { children: [
|
1662
2063
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Title, { children: title }) }),
|
1663
|
-
|
1664
|
-
|
2064
|
+
typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, { children: Content }),
|
2065
|
+
typeof Footer === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Footer, { onClose: handleClose }) : Footer
|
1665
2066
|
] }) });
|
1666
2067
|
};
|
1667
2068
|
const PublishAction$1 = ({
|
@@ -1676,13 +2077,17 @@ const PublishAction$1 = ({
|
|
1676
2077
|
const navigate = reactRouterDom.useNavigate();
|
1677
2078
|
const { toggleNotification } = strapiAdmin.useNotification();
|
1678
2079
|
const { _unstableFormatValidationErrors: formatValidationErrors } = strapiAdmin.useAPIErrorHandler();
|
2080
|
+
const isListView = reactRouterDom.useMatch(LIST_PATH) !== null;
|
1679
2081
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
1680
2082
|
const { formatMessage } = reactIntl.useIntl();
|
1681
|
-
const { canPublish
|
1682
|
-
"PublishAction",
|
1683
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1684
|
-
);
|
2083
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1685
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);
|
1686
2091
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1687
2092
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
1688
2093
|
const modified = strapiAdmin.useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
@@ -1691,63 +2096,143 @@ const PublishAction$1 = ({
|
|
1691
2096
|
const validate = strapiAdmin.useForm("PublishAction", (state) => state.validate);
|
1692
2097
|
const setErrors = strapiAdmin.useForm("PublishAction", (state) => state.setErrors);
|
1693
2098
|
const formValues = strapiAdmin.useForm("PublishAction", ({ values }) => values);
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
id: "app.utils.publish",
|
1713
|
-
defaultMessage: "Publish"
|
1714
|
-
}),
|
1715
|
-
onClick: async () => {
|
1716
|
-
setSubmitting(true);
|
1717
|
-
try {
|
1718
|
-
const { errors } = await validate();
|
1719
|
-
if (errors) {
|
1720
|
-
toggleNotification({
|
1721
|
-
type: "danger",
|
1722
|
-
message: formatMessage({
|
1723
|
-
id: "content-manager.validation.error",
|
1724
|
-
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
1725
|
-
})
|
1726
|
-
});
|
1727
|
-
return;
|
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);
|
1728
2117
|
}
|
1729
|
-
|
1730
|
-
|
1731
|
-
|
1732
|
-
|
1733
|
-
|
1734
|
-
|
1735
|
-
|
1736
|
-
|
1737
|
-
);
|
1738
|
-
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1739
|
-
navigate({
|
1740
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1741
|
-
search: rawQuery
|
1742
|
-
});
|
1743
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1744
|
-
setErrors(formatValidationErrors(res.error));
|
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);
|
1745
2126
|
}
|
1746
|
-
}
|
1747
|
-
|
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;
|
1748
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);
|
1749
2191
|
}
|
1750
2192
|
};
|
2193
|
+
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
2194
|
+
const enableDraftRelationsCount = false;
|
2195
|
+
const hasDraftRelations = enableDraftRelationsCount;
|
2196
|
+
return {
|
2197
|
+
/**
|
2198
|
+
* Disabled when:
|
2199
|
+
* - currently if you're cloning a document we don't support publish & clone at the same time.
|
2200
|
+
* - the form is submitting
|
2201
|
+
* - the active tab is the published tab
|
2202
|
+
* - the document is already published & not modified
|
2203
|
+
* - the document is being created & not modified
|
2204
|
+
* - the user doesn't have the permission to publish
|
2205
|
+
*/
|
2206
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
2207
|
+
label: formatMessage({
|
2208
|
+
id: "app.utils.publish",
|
2209
|
+
defaultMessage: "Publish"
|
2210
|
+
}),
|
2211
|
+
onClick: async () => {
|
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
|
2229
|
+
}
|
2230
|
+
),
|
2231
|
+
onConfirm: async () => {
|
2232
|
+
await performPublish();
|
2233
|
+
}
|
2234
|
+
} : void 0
|
2235
|
+
};
|
1751
2236
|
};
|
1752
2237
|
PublishAction$1.type = "publish";
|
1753
2238
|
const UpdateAction = ({
|
@@ -1762,10 +2247,6 @@ const UpdateAction = ({
|
|
1762
2247
|
const cloneMatch = reactRouterDom.useMatch(CLONE_PATH);
|
1763
2248
|
const isCloning = cloneMatch !== null;
|
1764
2249
|
const { formatMessage } = reactIntl.useIntl();
|
1765
|
-
const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1766
|
-
canCreate: canCreate2,
|
1767
|
-
canUpdate: canUpdate2
|
1768
|
-
}));
|
1769
2250
|
const { create, update, clone } = useDocumentActions();
|
1770
2251
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1771
2252
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
@@ -1782,10 +2263,8 @@ const UpdateAction = ({
|
|
1782
2263
|
* - the form is submitting
|
1783
2264
|
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
1784
2265
|
* - the active tab is the published tab
|
1785
|
-
* - the user doesn't have the permission to create a new document
|
1786
|
-
* - the user doesn't have the permission to update the document
|
1787
2266
|
*/
|
1788
|
-
disabled: isSubmitting || !modified && !isCloning || activeTab === "published"
|
2267
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1789
2268
|
label: formatMessage({
|
1790
2269
|
id: "content-manager.containers.Edit.save",
|
1791
2270
|
defaultMessage: "Save"
|
@@ -1793,16 +2272,18 @@ const UpdateAction = ({
|
|
1793
2272
|
onClick: async () => {
|
1794
2273
|
setSubmitting(true);
|
1795
2274
|
try {
|
1796
|
-
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
1800
|
-
|
1801
|
-
|
1802
|
-
|
1803
|
-
|
1804
|
-
|
1805
|
-
|
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
|
+
}
|
1806
2287
|
}
|
1807
2288
|
if (isCloning) {
|
1808
2289
|
const res = await clone(
|
@@ -1814,10 +2295,13 @@ const UpdateAction = ({
|
|
1814
2295
|
document
|
1815
2296
|
);
|
1816
2297
|
if ("data" in res) {
|
1817
|
-
navigate(
|
1818
|
-
|
1819
|
-
|
1820
|
-
|
2298
|
+
navigate(
|
2299
|
+
{
|
2300
|
+
pathname: `../${res.data.documentId}`,
|
2301
|
+
search: rawQuery
|
2302
|
+
},
|
2303
|
+
{ relative: "path" }
|
2304
|
+
);
|
1821
2305
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1822
2306
|
setErrors(formatValidationErrors(res.error));
|
1823
2307
|
}
|
@@ -1847,10 +2331,10 @@ const UpdateAction = ({
|
|
1847
2331
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1848
2332
|
navigate(
|
1849
2333
|
{
|
1850
|
-
pathname: `../${
|
2334
|
+
pathname: `../${res.data.documentId}`,
|
1851
2335
|
search: rawQuery
|
1852
2336
|
},
|
1853
|
-
{ replace: true }
|
2337
|
+
{ replace: true, relative: "path" }
|
1854
2338
|
);
|
1855
2339
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1856
2340
|
setErrors(formatValidationErrors(res.error));
|
@@ -1895,7 +2379,7 @@ const UnpublishAction$1 = ({
|
|
1895
2379
|
id: "app.utils.unpublish",
|
1896
2380
|
defaultMessage: "Unpublish"
|
1897
2381
|
}),
|
1898
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2382
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Cross, {}),
|
1899
2383
|
onClick: async () => {
|
1900
2384
|
if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
|
1901
2385
|
if (!documentId) {
|
@@ -2007,7 +2491,7 @@ const DiscardAction = ({
|
|
2007
2491
|
id: "content-manager.actions.discard.label",
|
2008
2492
|
defaultMessage: "Discard changes"
|
2009
2493
|
}),
|
2010
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2494
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Cross, {}),
|
2011
2495
|
position: ["panel", "table-row"],
|
2012
2496
|
variant: "danger",
|
2013
2497
|
dialog: {
|
@@ -2035,11 +2519,6 @@ const DiscardAction = ({
|
|
2035
2519
|
};
|
2036
2520
|
};
|
2037
2521
|
DiscardAction.type = "discard";
|
2038
|
-
const StyledCrossCircle = styledComponents.styled(Icons.CrossCircle)`
|
2039
|
-
path {
|
2040
|
-
fill: currentColor;
|
2041
|
-
}
|
2042
|
-
`;
|
2043
2522
|
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2044
2523
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2045
2524
|
const RelativeTime = React__namespace.forwardRef(
|
@@ -2087,7 +2566,7 @@ const getDisplayName = ({
|
|
2087
2566
|
};
|
2088
2567
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2089
2568
|
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2090
|
-
const statusVariant = status === "draft" ? "
|
2569
|
+
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2091
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) }) });
|
2092
2571
|
};
|
2093
2572
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
@@ -2097,23 +2576,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
|
2097
2576
|
id: "content-manager.containers.edit.title.new",
|
2098
2577
|
defaultMessage: "Create an entry"
|
2099
2578
|
}) : documentTitle;
|
2100
|
-
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: [
|
2101
2580
|
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.BackButton, {}),
|
2102
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
2103
|
-
designSystem.
|
2104
|
-
{
|
2105
|
-
|
2106
|
-
|
2107
|
-
paddingTop: 1,
|
2108
|
-
gap: "80px",
|
2109
|
-
alignItems: "flex-start",
|
2110
|
-
children: [
|
2111
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
|
2112
|
-
/* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
|
2113
|
-
]
|
2114
|
-
}
|
2115
|
-
),
|
2116
|
-
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
|
2117
2586
|
] });
|
2118
2587
|
};
|
2119
2588
|
const HeaderToolbar = () => {
|
@@ -2280,8 +2749,22 @@ const Information = ({ activeTab }) => {
|
|
2280
2749
|
);
|
2281
2750
|
};
|
2282
2751
|
const HeaderActions = ({ actions: actions2 }) => {
|
2283
|
-
|
2284
|
-
|
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) {
|
2285
2768
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
2286
2769
|
designSystem.SingleSelect,
|
2287
2770
|
{
|
@@ -2295,10 +2778,49 @@ const HeaderActions = ({ actions: actions2 }) => {
|
|
2295
2778
|
action.id
|
2296
2779
|
);
|
2297
2780
|
} else {
|
2298
|
-
|
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
|
+
}
|
2299
2803
|
}
|
2300
2804
|
}) });
|
2301
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
|
+
};
|
2302
2824
|
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
2303
2825
|
const navigate = reactRouterDom.useNavigate();
|
2304
2826
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2339,12 +2861,16 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2339
2861
|
const { delete: deleteAction } = useDocumentActions();
|
2340
2862
|
const { toggleNotification } = strapiAdmin.useNotification();
|
2341
2863
|
const setSubmitting = strapiAdmin.useForm("DeleteAction", (state) => state.setSubmitting);
|
2864
|
+
const isLocalized = document?.locale != null;
|
2342
2865
|
return {
|
2343
2866
|
disabled: !canDelete || !document,
|
2344
|
-
label: formatMessage(
|
2345
|
-
|
2346
|
-
|
2347
|
-
|
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
|
+
),
|
2348
2874
|
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {}),
|
2349
2875
|
dialog: {
|
2350
2876
|
type: "dialog",
|
@@ -2375,428 +2901,126 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2375
2901
|
}),
|
2376
2902
|
type: "danger"
|
2377
2903
|
});
|
2378
|
-
return;
|
2379
|
-
}
|
2380
|
-
const res = await deleteAction({
|
2381
|
-
documentId,
|
2382
|
-
model,
|
2383
|
-
collectionType,
|
2384
|
-
params: {
|
2385
|
-
locale: "*"
|
2386
|
-
}
|
2387
|
-
});
|
2388
|
-
if (!("error" in res)) {
|
2389
|
-
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
2390
|
-
}
|
2391
|
-
} finally {
|
2392
|
-
if (!listViewPathMatch) {
|
2393
|
-
setSubmitting(false);
|
2394
|
-
}
|
2395
|
-
}
|
2396
|
-
}
|
2397
|
-
},
|
2398
|
-
variant: "danger",
|
2399
|
-
position: ["header", "table-row"]
|
2400
|
-
};
|
2401
|
-
};
|
2402
|
-
DeleteAction$1.type = "delete";
|
2403
|
-
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2404
|
-
const Panels = () => {
|
2405
|
-
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2406
|
-
const [
|
2407
|
-
{
|
2408
|
-
query: { status }
|
2409
|
-
}
|
2410
|
-
] = strapiAdmin.useQueryParams({
|
2411
|
-
status: "draft"
|
2412
|
-
});
|
2413
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2414
|
-
const plugins = strapiAdmin.useStrapiApp("Panels", (state) => state.plugins);
|
2415
|
-
const props = {
|
2416
|
-
activeTab: status,
|
2417
|
-
model,
|
2418
|
-
documentId: id,
|
2419
|
-
document: isCloning ? void 0 : document,
|
2420
|
-
meta: isCloning ? void 0 : meta,
|
2421
|
-
collectionType
|
2422
|
-
};
|
2423
|
-
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
|
2424
|
-
strapiAdmin.DescriptionComponentRenderer,
|
2425
|
-
{
|
2426
|
-
props,
|
2427
|
-
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2428
|
-
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsxRuntime.jsx(Panel, { ...description, children: content }, id2))
|
2429
|
-
}
|
2430
|
-
) });
|
2431
|
-
};
|
2432
|
-
const ActionsPanel = () => {
|
2433
|
-
const { formatMessage } = reactIntl.useIntl();
|
2434
|
-
return {
|
2435
|
-
title: formatMessage({
|
2436
|
-
id: "content-manager.containers.edit.panels.default.title",
|
2437
|
-
defaultMessage: "Document"
|
2438
|
-
}),
|
2439
|
-
content: /* @__PURE__ */ jsxRuntime.jsx(ActionsPanelContent, {})
|
2440
|
-
};
|
2441
|
-
};
|
2442
|
-
ActionsPanel.type = "actions";
|
2443
|
-
const ActionsPanelContent = () => {
|
2444
|
-
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2445
|
-
const [
|
2446
|
-
{
|
2447
|
-
query: { status = "draft" }
|
2448
|
-
}
|
2449
|
-
] = strapiAdmin.useQueryParams();
|
2450
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2451
|
-
const plugins = strapiAdmin.useStrapiApp("ActionsPanel", (state) => state.plugins);
|
2452
|
-
const props = {
|
2453
|
-
activeTab: status,
|
2454
|
-
model,
|
2455
|
-
documentId: id,
|
2456
|
-
document: isCloning ? void 0 : document,
|
2457
|
-
meta: isCloning ? void 0 : meta,
|
2458
|
-
collectionType
|
2459
|
-
};
|
2460
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, width: "100%", children: [
|
2461
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
2462
|
-
strapiAdmin.DescriptionComponentRenderer,
|
2463
|
-
{
|
2464
|
-
props,
|
2465
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2466
|
-
children: (actions2) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActions, { actions: actions2 })
|
2467
|
-
}
|
2468
|
-
),
|
2469
|
-
/* @__PURE__ */ jsxRuntime.jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
2470
|
-
] });
|
2471
|
-
};
|
2472
|
-
const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
2473
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
2474
|
-
designSystem.Flex,
|
2475
|
-
{
|
2476
|
-
ref,
|
2477
|
-
tag: "aside",
|
2478
|
-
"aria-labelledby": "additional-information",
|
2479
|
-
background: "neutral0",
|
2480
|
-
borderColor: "neutral150",
|
2481
|
-
hasRadius: true,
|
2482
|
-
paddingBottom: 4,
|
2483
|
-
paddingLeft: 4,
|
2484
|
-
paddingRight: 4,
|
2485
|
-
paddingTop: 4,
|
2486
|
-
shadow: "tableShadow",
|
2487
|
-
gap: 3,
|
2488
|
-
direction: "column",
|
2489
|
-
justifyContent: "stretch",
|
2490
|
-
alignItems: "flex-start",
|
2491
|
-
children: [
|
2492
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2493
|
-
children
|
2494
|
-
]
|
2495
|
-
}
|
2496
|
-
);
|
2497
|
-
});
|
2498
|
-
const HOOKS = {
|
2499
|
-
/**
|
2500
|
-
* Hook that allows to mutate the displayed headers of the list view table
|
2501
|
-
* @constant
|
2502
|
-
* @type {string}
|
2503
|
-
*/
|
2504
|
-
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2505
|
-
/**
|
2506
|
-
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2507
|
-
* @constant
|
2508
|
-
* @type {string}
|
2509
|
-
*/
|
2510
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2511
|
-
/**
|
2512
|
-
* Hook that allows to mutate the CM's edit view layout
|
2513
|
-
* @constant
|
2514
|
-
* @type {string}
|
2515
|
-
*/
|
2516
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2517
|
-
/**
|
2518
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
2519
|
-
* @constant
|
2520
|
-
* @type {string}
|
2521
|
-
*/
|
2522
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2523
|
-
};
|
2524
|
-
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2525
|
-
endpoints: (builder) => ({
|
2526
|
-
getContentTypeConfiguration: builder.query({
|
2527
|
-
query: (uid) => ({
|
2528
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2529
|
-
method: "GET"
|
2530
|
-
}),
|
2531
|
-
transformResponse: (response) => response.data,
|
2532
|
-
providesTags: (_result, _error, uid) => [
|
2533
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2534
|
-
{ type: "ContentTypeSettings", id: "LIST" }
|
2535
|
-
]
|
2536
|
-
}),
|
2537
|
-
getAllContentTypeSettings: builder.query({
|
2538
|
-
query: () => "/content-manager/content-types-settings",
|
2539
|
-
transformResponse: (response) => response.data,
|
2540
|
-
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2541
|
-
}),
|
2542
|
-
updateContentTypeConfiguration: builder.mutation({
|
2543
|
-
query: ({ uid, ...body }) => ({
|
2544
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2545
|
-
method: "PUT",
|
2546
|
-
data: body
|
2547
|
-
}),
|
2548
|
-
transformResponse: (response) => response.data,
|
2549
|
-
invalidatesTags: (_result, _error, { uid }) => [
|
2550
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2551
|
-
{ type: "ContentTypeSettings", id: "LIST" },
|
2552
|
-
// Is this necessary?
|
2553
|
-
{ type: "InitialData" }
|
2554
|
-
]
|
2555
|
-
})
|
2556
|
-
})
|
2557
|
-
});
|
2558
|
-
const {
|
2559
|
-
useGetContentTypeConfigurationQuery,
|
2560
|
-
useGetAllContentTypeSettingsQuery,
|
2561
|
-
useUpdateContentTypeConfigurationMutation
|
2562
|
-
} = contentTypesApi;
|
2563
|
-
const checkIfAttributeIsDisplayable = (attribute) => {
|
2564
|
-
const { type } = attribute;
|
2565
|
-
if (type === "relation") {
|
2566
|
-
return !attribute.relation.toLowerCase().includes("morph");
|
2567
|
-
}
|
2568
|
-
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2569
|
-
};
|
2570
|
-
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2571
|
-
if (!mainFieldName) {
|
2572
|
-
return void 0;
|
2573
|
-
}
|
2574
|
-
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2575
|
-
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2576
|
-
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2577
|
-
);
|
2578
|
-
return {
|
2579
|
-
name: mainFieldName,
|
2580
|
-
type: mainFieldType ?? "string"
|
2581
|
-
};
|
2582
|
-
};
|
2583
|
-
const DEFAULT_SETTINGS = {
|
2584
|
-
bulkable: false,
|
2585
|
-
filterable: false,
|
2586
|
-
searchable: false,
|
2587
|
-
pagination: false,
|
2588
|
-
defaultSortBy: "",
|
2589
|
-
defaultSortOrder: "asc",
|
2590
|
-
mainField: "id",
|
2591
|
-
pageSize: 10
|
2592
|
-
};
|
2593
|
-
const useDocumentLayout = (model) => {
|
2594
|
-
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2595
|
-
const [{ query }] = strapiAdmin.useQueryParams();
|
2596
|
-
const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2597
|
-
const { toggleNotification } = strapiAdmin.useNotification();
|
2598
|
-
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
2599
|
-
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2600
|
-
const {
|
2601
|
-
data,
|
2602
|
-
isLoading: isLoadingConfigs,
|
2603
|
-
error,
|
2604
|
-
isFetching: isFetchingConfigs
|
2605
|
-
} = useGetContentTypeConfigurationQuery(model);
|
2606
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2607
|
-
React__namespace.useEffect(() => {
|
2608
|
-
if (error) {
|
2609
|
-
toggleNotification({
|
2610
|
-
type: "danger",
|
2611
|
-
message: formatAPIError(error)
|
2612
|
-
});
|
2613
|
-
}
|
2614
|
-
}, [error, formatAPIError, toggleNotification]);
|
2615
|
-
const editLayout = React__namespace.useMemo(
|
2616
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2617
|
-
layout: [],
|
2618
|
-
components: {},
|
2619
|
-
metadatas: {},
|
2620
|
-
options: {},
|
2621
|
-
settings: DEFAULT_SETTINGS
|
2622
|
-
},
|
2623
|
-
[data, isLoading, schemas, schema, components]
|
2624
|
-
);
|
2625
|
-
const listLayout = React__namespace.useMemo(() => {
|
2626
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2627
|
-
layout: [],
|
2628
|
-
metadatas: {},
|
2629
|
-
options: {},
|
2630
|
-
settings: DEFAULT_SETTINGS
|
2631
|
-
};
|
2632
|
-
}, [data, isLoading, schemas, schema, components]);
|
2633
|
-
const { layout: edit } = React__namespace.useMemo(
|
2634
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2635
|
-
layout: editLayout,
|
2636
|
-
query
|
2637
|
-
}),
|
2638
|
-
[editLayout, query, runHookWaterfall]
|
2639
|
-
);
|
2640
|
-
return {
|
2641
|
-
error,
|
2642
|
-
isLoading,
|
2643
|
-
edit,
|
2644
|
-
list: listLayout
|
2645
|
-
};
|
2646
|
-
};
|
2647
|
-
const useDocLayout = () => {
|
2648
|
-
const { model } = useDoc();
|
2649
|
-
return useDocumentLayout(model);
|
2650
|
-
};
|
2651
|
-
const formatEditLayout = (data, {
|
2652
|
-
schemas,
|
2653
|
-
schema,
|
2654
|
-
components
|
2655
|
-
}) => {
|
2656
|
-
let currentPanelIndex = 0;
|
2657
|
-
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2658
|
-
data.contentType.layouts.edit,
|
2659
|
-
schema?.attributes,
|
2660
|
-
data.contentType.metadatas,
|
2661
|
-
{ configurations: data.components, schemas: components },
|
2662
|
-
schemas
|
2663
|
-
).reduce((panels, row) => {
|
2664
|
-
if (row.some((field) => field.type === "dynamiczone")) {
|
2665
|
-
panels.push([row]);
|
2666
|
-
currentPanelIndex += 2;
|
2667
|
-
} else {
|
2668
|
-
if (!panels[currentPanelIndex]) {
|
2669
|
-
panels.push([]);
|
2670
|
-
}
|
2671
|
-
panels[currentPanelIndex].push(row);
|
2672
|
-
}
|
2673
|
-
return panels;
|
2674
|
-
}, []);
|
2675
|
-
const componentEditAttributes = Object.entries(data.components).reduce(
|
2676
|
-
(acc, [uid, configuration]) => {
|
2677
|
-
acc[uid] = {
|
2678
|
-
layout: convertEditLayoutToFieldLayouts(
|
2679
|
-
configuration.layouts.edit,
|
2680
|
-
components[uid].attributes,
|
2681
|
-
configuration.metadatas
|
2682
|
-
),
|
2683
|
-
settings: {
|
2684
|
-
...configuration.settings,
|
2685
|
-
icon: components[uid].info.icon,
|
2686
|
-
displayName: components[uid].info.displayName
|
2904
|
+
return;
|
2905
|
+
}
|
2906
|
+
const res = await deleteAction({
|
2907
|
+
documentId,
|
2908
|
+
model,
|
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
|
+
}
|
2687
2921
|
}
|
2688
|
-
}
|
2689
|
-
return acc;
|
2690
|
-
},
|
2691
|
-
{}
|
2692
|
-
);
|
2693
|
-
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2694
|
-
(acc, [attribute, metadata]) => {
|
2695
|
-
return {
|
2696
|
-
...acc,
|
2697
|
-
[attribute]: metadata.edit
|
2698
|
-
};
|
2699
|
-
},
|
2700
|
-
{}
|
2701
|
-
);
|
2702
|
-
return {
|
2703
|
-
layout: panelledEditAttributes,
|
2704
|
-
components: componentEditAttributes,
|
2705
|
-
metadatas: editMetadatas,
|
2706
|
-
settings: {
|
2707
|
-
...data.contentType.settings,
|
2708
|
-
displayName: schema?.info.displayName
|
2922
|
+
}
|
2709
2923
|
},
|
2710
|
-
|
2711
|
-
|
2712
|
-
...schema?.pluginOptions,
|
2713
|
-
...data.contentType.options
|
2714
|
-
}
|
2924
|
+
variant: "danger",
|
2925
|
+
position: ["header", "table-row"]
|
2715
2926
|
};
|
2716
2927
|
};
|
2717
|
-
|
2718
|
-
|
2719
|
-
|
2720
|
-
|
2721
|
-
|
2722
|
-
|
2723
|
-
}
|
2724
|
-
|
2725
|
-
|
2726
|
-
|
2727
|
-
|
2728
|
-
|
2729
|
-
|
2730
|
-
|
2731
|
-
|
2732
|
-
|
2733
|
-
|
2734
|
-
|
2735
|
-
|
2736
|
-
|
2737
|
-
|
2738
|
-
|
2739
|
-
|
2740
|
-
|
2741
|
-
|
2742
|
-
|
2743
|
-
}
|
2744
|
-
}
|
2745
|
-
);
|
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
|
+
) });
|
2746
2957
|
};
|
2747
|
-
const
|
2748
|
-
|
2749
|
-
schema,
|
2750
|
-
components
|
2751
|
-
}) => {
|
2752
|
-
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2753
|
-
(acc, [attribute, metadata]) => {
|
2754
|
-
return {
|
2755
|
-
...acc,
|
2756
|
-
[attribute]: metadata.list
|
2757
|
-
};
|
2758
|
-
},
|
2759
|
-
{}
|
2760
|
-
);
|
2761
|
-
const listAttributes = convertListLayoutToFieldLayouts(
|
2762
|
-
data.contentType.layouts.list,
|
2763
|
-
schema?.attributes,
|
2764
|
-
listMetadatas,
|
2765
|
-
{ configurations: data.components, schemas: components },
|
2766
|
-
schemas
|
2767
|
-
);
|
2958
|
+
const ActionsPanel = () => {
|
2959
|
+
const { formatMessage } = reactIntl.useIntl();
|
2768
2960
|
return {
|
2769
|
-
|
2770
|
-
|
2771
|
-
|
2772
|
-
|
2773
|
-
|
2774
|
-
...schema?.pluginOptions,
|
2775
|
-
...data.contentType.options
|
2776
|
-
}
|
2961
|
+
title: formatMessage({
|
2962
|
+
id: "content-manager.containers.edit.panels.default.title",
|
2963
|
+
defaultMessage: "Entry"
|
2964
|
+
}),
|
2965
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(ActionsPanelContent, {})
|
2777
2966
|
};
|
2778
2967
|
};
|
2779
|
-
|
2780
|
-
|
2781
|
-
|
2782
|
-
|
2783
|
-
|
2968
|
+
ActionsPanel.type = "actions";
|
2969
|
+
const ActionsPanelContent = () => {
|
2970
|
+
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2971
|
+
const [
|
2972
|
+
{
|
2973
|
+
query: { status = "draft" }
|
2784
2974
|
}
|
2785
|
-
|
2786
|
-
|
2787
|
-
|
2788
|
-
|
2789
|
-
|
2790
|
-
|
2791
|
-
|
2792
|
-
|
2793
|
-
|
2794
|
-
|
2795
|
-
|
2796
|
-
|
2797
|
-
|
2798
|
-
|
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
|
+
] });
|
2799
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
|
+
});
|
2800
3024
|
const ConfirmBulkActionDialog = ({
|
2801
3025
|
onToggleDialog,
|
2802
3026
|
isOpen = false,
|
@@ -2804,7 +3028,7 @@ const ConfirmBulkActionDialog = ({
|
|
2804
3028
|
endAction
|
2805
3029
|
}) => {
|
2806
3030
|
const { formatMessage } = reactIntl.useIntl();
|
2807
|
-
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: [
|
2808
3032
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: formatMessage({
|
2809
3033
|
id: "app.components.ConfirmDialog.title",
|
2810
3034
|
defaultMessage: "Confirmation"
|
@@ -2835,6 +3059,7 @@ const ConfirmDialogPublishAll = ({
|
|
2835
3059
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler(getTranslation);
|
2836
3060
|
const { model, schema } = useDoc();
|
2837
3061
|
const [{ query }] = strapiAdmin.useQueryParams();
|
3062
|
+
const enableDraftRelationsCount = false;
|
2838
3063
|
const {
|
2839
3064
|
data: countDraftRelations = 0,
|
2840
3065
|
isLoading,
|
@@ -2846,7 +3071,7 @@ const ConfirmDialogPublishAll = ({
|
|
2846
3071
|
locale: query?.plugins?.i18n?.locale
|
2847
3072
|
},
|
2848
3073
|
{
|
2849
|
-
skip:
|
3074
|
+
skip: !enableDraftRelationsCount
|
2850
3075
|
}
|
2851
3076
|
);
|
2852
3077
|
React__namespace.useEffect(() => {
|
@@ -3031,7 +3256,7 @@ const SelectedEntriesTableContent = ({
|
|
3031
3256
|
status: row.status
|
3032
3257
|
}
|
3033
3258
|
) }),
|
3034
|
-
/* @__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(
|
3035
3260
|
designSystem.IconButton,
|
3036
3261
|
{
|
3037
3262
|
tag: reactRouterDom.Link,
|
@@ -3054,9 +3279,10 @@ const SelectedEntriesTableContent = ({
|
|
3054
3279
|
),
|
3055
3280
|
target: "_blank",
|
3056
3281
|
marginLeft: "auto",
|
3057
|
-
|
3282
|
+
variant: "ghost",
|
3283
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, { width: "1.6rem", height: "1.6rem" })
|
3058
3284
|
}
|
3059
|
-
) })
|
3285
|
+
) }) })
|
3060
3286
|
] }, row.id)) })
|
3061
3287
|
] });
|
3062
3288
|
};
|
@@ -3093,7 +3319,13 @@ const SelectedEntriesModalContent = ({
|
|
3093
3319
|
);
|
3094
3320
|
const { rows, validationErrors } = React__namespace.useMemo(() => {
|
3095
3321
|
if (data.length > 0 && schema) {
|
3096
|
-
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
|
+
);
|
3097
3329
|
const validationErrors2 = {};
|
3098
3330
|
const rows2 = data.map((entry) => {
|
3099
3331
|
try {
|
@@ -3443,7 +3675,7 @@ const TableActions = ({ document }) => {
|
|
3443
3675
|
strapiAdmin.DescriptionComponentRenderer,
|
3444
3676
|
{
|
3445
3677
|
props,
|
3446
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3678
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
3447
3679
|
children: (actions2) => {
|
3448
3680
|
const tableRowActions = actions2.filter((action) => {
|
3449
3681
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3554,7 +3786,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3554
3786
|
}),
|
3555
3787
|
content: /* @__PURE__ */ jsxRuntime.jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
3556
3788
|
footer: ({ onClose }) => {
|
3557
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.
|
3789
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
3558
3790
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
3559
3791
|
id: "cancel",
|
3560
3792
|
defaultMessage: "Cancel"
|
@@ -3595,8 +3827,7 @@ class ContentManagerPlugin {
|
|
3595
3827
|
documentActions = [
|
3596
3828
|
...DEFAULT_ACTIONS,
|
3597
3829
|
...DEFAULT_TABLE_ROW_ACTIONS,
|
3598
|
-
...DEFAULT_HEADER_ACTIONS
|
3599
|
-
HistoryAction
|
3830
|
+
...DEFAULT_HEADER_ACTIONS
|
3600
3831
|
];
|
3601
3832
|
editViewSidePanels = [ActionsPanel];
|
3602
3833
|
headerActions = [];
|
@@ -3685,6 +3916,52 @@ const getPrintableType = (value) => {
|
|
3685
3916
|
}
|
3686
3917
|
return nativeType;
|
3687
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
|
+
};
|
3688
3965
|
const initialState = {
|
3689
3966
|
collectionTypeLinks: [],
|
3690
3967
|
components: [],
|
@@ -3740,7 +4017,7 @@ const index = {
|
|
3740
4017
|
app.router.addRoute({
|
3741
4018
|
path: "content-manager/*",
|
3742
4019
|
lazy: async () => {
|
3743
|
-
const { Layout } = await Promise.resolve().then(() => require("./layout-
|
4020
|
+
const { Layout } = await Promise.resolve().then(() => require("./layout-CWgZzMYf.js"));
|
3744
4021
|
return {
|
3745
4022
|
Component: Layout
|
3746
4023
|
};
|
@@ -3749,10 +4026,15 @@ const index = {
|
|
3749
4026
|
});
|
3750
4027
|
app.registerPlugin(cm.config);
|
3751
4028
|
},
|
4029
|
+
bootstrap(app) {
|
4030
|
+
if (typeof historyAdmin.bootstrap === "function") {
|
4031
|
+
historyAdmin.bootstrap(app);
|
4032
|
+
}
|
4033
|
+
},
|
3752
4034
|
async registerTrads({ locales }) {
|
3753
4035
|
const importedTrads = await Promise.all(
|
3754
4036
|
locales.map((locale) => {
|
3755
|
-
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 }) => {
|
3756
4038
|
return {
|
3757
4039
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3758
4040
|
locale
|
@@ -3770,6 +4052,7 @@ const index = {
|
|
3770
4052
|
};
|
3771
4053
|
exports.ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD = ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD;
|
3772
4054
|
exports.BulkActionsRenderer = BulkActionsRenderer;
|
4055
|
+
exports.CLONE_PATH = CLONE_PATH;
|
3773
4056
|
exports.COLLECTION_TYPES = COLLECTION_TYPES;
|
3774
4057
|
exports.CREATOR_FIELDS = CREATOR_FIELDS;
|
3775
4058
|
exports.DEFAULT_SETTINGS = DEFAULT_SETTINGS;
|
@@ -3797,6 +4080,7 @@ exports.getMainField = getMainField;
|
|
3797
4080
|
exports.getTranslation = getTranslation;
|
3798
4081
|
exports.index = index;
|
3799
4082
|
exports.setInitialData = setInitialData;
|
4083
|
+
exports.useContentManagerContext = useContentManagerContext;
|
3800
4084
|
exports.useContentTypeSchema = useContentTypeSchema;
|
3801
4085
|
exports.useDoc = useDoc;
|
3802
4086
|
exports.useDocLayout = useDocLayout;
|
@@ -3809,4 +4093,4 @@ exports.useGetAllDocumentsQuery = useGetAllDocumentsQuery;
|
|
3809
4093
|
exports.useGetContentTypeConfigurationQuery = useGetContentTypeConfigurationQuery;
|
3810
4094
|
exports.useGetInitialDataQuery = useGetInitialDataQuery;
|
3811
4095
|
exports.useUpdateContentTypeConfigurationMutation = useUpdateContentTypeConfigurationMutation;
|
3812
|
-
//# sourceMappingURL=index-
|
4096
|
+
//# sourceMappingURL=index-DTKVhcla.js.map
|