@strapi/content-manager 0.0.0-experimental.745741d19e90275ca6f7c928ca19f9bb0fd9d933 → 0.0.0-experimental.78b47df46708173ab4833373f694257729db4b9e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/{ComponentConfigurationPage-DHNM3YBz.mjs → ComponentConfigurationPage-7-qB29e7.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-DHNM3YBz.mjs.map → ComponentConfigurationPage-7-qB29e7.mjs.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-BvHtG7uH.js → ComponentConfigurationPage-DP7AC0UU.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-BvHtG7uH.js.map → ComponentConfigurationPage-DP7AC0UU.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-Cp6HAEzN.mjs → EditConfigurationPage-CI4XoymK.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-Cp6HAEzN.mjs.map → EditConfigurationPage-CI4XoymK.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-DOmfCEMo.js → EditConfigurationPage-DITVliEI.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-DOmfCEMo.js.map → EditConfigurationPage-DITVliEI.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-BqNpC6hO.js → EditViewPage-CUS2EAhB.js} +24 -9
- package/dist/_chunks/EditViewPage-CUS2EAhB.js.map +1 -0
- package/dist/_chunks/{EditViewPage-BtkEx339.mjs → EditViewPage-Dzpno8xI.mjs} +24 -9
- package/dist/_chunks/EditViewPage-Dzpno8xI.mjs.map +1 -0
- package/dist/_chunks/{Field-R5NbffTB.mjs → Field-B_jG_EV9.mjs} +210 -145
- package/dist/_chunks/Field-B_jG_EV9.mjs.map +1 -0
- package/dist/_chunks/{Field-lsPFnAmH.js → Field-CtUU1Fg8.js} +212 -147
- package/dist/_chunks/Field-CtUU1Fg8.js.map +1 -0
- package/dist/_chunks/{Form-BHmXSfyy.mjs → Form-BXHao2mZ.mjs} +35 -16
- package/dist/_chunks/Form-BXHao2mZ.mjs.map +1 -0
- package/dist/_chunks/{Form-CcGboku8.js → Form-DTqO0ymI.js} +35 -16
- package/dist/_chunks/Form-DTqO0ymI.js.map +1 -0
- package/dist/_chunks/{History-ByUPL3T3.mjs → History-2Ah2CQ4T.mjs} +28 -18
- package/dist/_chunks/History-2Ah2CQ4T.mjs.map +1 -0
- package/dist/_chunks/{History-Bsud8jwh.js → History-C_uSGzO5.js} +28 -18
- package/dist/_chunks/History-C_uSGzO5.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-Bm5HACXf.mjs → ListConfigurationPage-BjSJlaoC.mjs} +20 -8
- package/dist/_chunks/ListConfigurationPage-BjSJlaoC.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DiT463qx.js → ListConfigurationPage-nyuP7OSy.js} +20 -8
- package/dist/_chunks/ListConfigurationPage-nyuP7OSy.js.map +1 -0
- package/dist/_chunks/{ListViewPage-JSyNAAYu.mjs → ListViewPage-B75x3nz2.mjs} +47 -38
- package/dist/_chunks/ListViewPage-B75x3nz2.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-CsrC9L_d.js → ListViewPage-DHgHD8Xg.js} +49 -40
- package/dist/_chunks/ListViewPage-DHgHD8Xg.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-Bsvng4II.js → NoContentTypePage-CDUKdZ7d.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-Bsvng4II.js.map → NoContentTypePage-CDUKdZ7d.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-CsrQUpBE.mjs → NoContentTypePage-DUacQSyF.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-CsrQUpBE.mjs.map → NoContentTypePage-DUacQSyF.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-DNmf_pj0.mjs → NoPermissionsPage-SFllMekk.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-DNmf_pj0.mjs.map → NoPermissionsPage-SFllMekk.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-CdHNJtEf.js → NoPermissionsPage-zwIZydDI.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-CdHNJtEf.js.map → NoPermissionsPage-zwIZydDI.js.map} +1 -1
- package/dist/_chunks/{Relations-u8-37jK0.mjs → Relations-D2NRW8fC.mjs} +14 -10
- package/dist/_chunks/Relations-D2NRW8fC.mjs.map +1 -0
- package/dist/_chunks/{Relations-CghaPv2D.js → Relations-NFLaRNPr.js} +14 -10
- package/dist/_chunks/Relations-NFLaRNPr.js.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-C9HxCo5R.mjs} +971 -686
- package/dist/_chunks/index-C9HxCo5R.mjs.map +1 -0
- package/dist/_chunks/{index-BOZx6IMg.js → index-ovJRE1FM.js} +952 -667
- package/dist/_chunks/index-ovJRE1FM.js.map +1 -0
- package/dist/_chunks/{layout-Bx7svTbY.mjs → layout-DaUjDiWQ.mjs} +23 -10
- package/dist/_chunks/layout-DaUjDiWQ.mjs.map +1 -0
- package/dist/_chunks/{layout-Ciz224q5.js → layout-UNWstw_s.js} +22 -9
- package/dist/_chunks/layout-UNWstw_s.js.map +1 -0
- package/dist/_chunks/{relations-Cxc1cEv3.mjs → relations-D8iFAeRu.mjs} +2 -2
- package/dist/_chunks/{relations-Cxc1cEv3.mjs.map → relations-D8iFAeRu.mjs.map} +1 -1
- package/dist/_chunks/{relations-CP8sB2YZ.js → relations-NN3coOG5.js} +2 -2
- package/dist/_chunks/{relations-CP8sB2YZ.js.map → relations-NN3coOG5.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 +32 -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 +11 -11
- package/dist/admin/src/services/api.d.ts +1 -1
- package/dist/admin/src/services/components.d.ts +2 -2
- package/dist/admin/src/services/contentTypes.d.ts +3 -3
- package/dist/admin/src/services/documents.d.ts +19 -17
- package/dist/admin/src/services/init.d.ts +1 -1
- package/dist/admin/src/services/relations.d.ts +2 -2
- package/dist/admin/src/services/uid.d.ts +3 -3
- package/dist/admin/src/utils/validation.d.ts +4 -1
- package/dist/server/index.js +184 -108
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +185 -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": {
|
@@ -550,7 +544,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
550
544
|
} else if (Array.isArray(value)) {
|
551
545
|
return yup__namespace.array().of(
|
552
546
|
yup__namespace.object().shape({
|
553
|
-
id: yup__namespace.
|
547
|
+
id: yup__namespace.number().required()
|
554
548
|
})
|
555
549
|
);
|
556
550
|
} else if (typeof value === "object") {
|
@@ -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,263 @@ 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
|
+
const hasError = !!error;
|
1169
|
+
return {
|
1170
|
+
components,
|
1171
|
+
document: data?.data,
|
1172
|
+
meta: data?.meta,
|
1173
|
+
isLoading,
|
1174
|
+
hasError,
|
1175
|
+
schema,
|
1176
|
+
schemas,
|
1177
|
+
validate
|
1178
|
+
};
|
1179
|
+
};
|
1180
|
+
const useDoc = () => {
|
1181
|
+
const { id, slug, collectionType, origin } = reactRouterDom.useParams();
|
1182
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
1183
|
+
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
1184
|
+
if (!collectionType) {
|
1185
|
+
throw new Error("Could not find collectionType in url params");
|
842
1186
|
}
|
843
1187
|
if (!slug) {
|
844
1188
|
throw new Error("Could not find model in url params");
|
@@ -855,6 +1199,45 @@ const useDoc = () => {
|
|
855
1199
|
)
|
856
1200
|
};
|
857
1201
|
};
|
1202
|
+
const useContentManagerContext = () => {
|
1203
|
+
const {
|
1204
|
+
collectionType,
|
1205
|
+
model,
|
1206
|
+
id,
|
1207
|
+
components,
|
1208
|
+
isLoading: isLoadingDoc,
|
1209
|
+
schema,
|
1210
|
+
schemas
|
1211
|
+
} = useDoc();
|
1212
|
+
const layout = useDocumentLayout(model);
|
1213
|
+
const form = strapiAdmin.useForm("useContentManagerContext", (state) => state);
|
1214
|
+
const isSingleType = collectionType === SINGLE_TYPES;
|
1215
|
+
const slug = model;
|
1216
|
+
const isCreatingEntry = id === "create";
|
1217
|
+
useContentTypeSchema();
|
1218
|
+
const isLoading = isLoadingDoc || layout.isLoading;
|
1219
|
+
const error = layout.error;
|
1220
|
+
return {
|
1221
|
+
error,
|
1222
|
+
isLoading,
|
1223
|
+
// Base metadata
|
1224
|
+
model,
|
1225
|
+
collectionType,
|
1226
|
+
id,
|
1227
|
+
slug,
|
1228
|
+
isCreatingEntry,
|
1229
|
+
isSingleType,
|
1230
|
+
hasDraftAndPublish: schema?.options?.draftAndPublish ?? false,
|
1231
|
+
// All schema infos
|
1232
|
+
components,
|
1233
|
+
contentType: schema,
|
1234
|
+
contentTypes: schemas,
|
1235
|
+
// Form state
|
1236
|
+
form,
|
1237
|
+
// layout infos
|
1238
|
+
layout
|
1239
|
+
};
|
1240
|
+
};
|
858
1241
|
const prefixPluginTranslations = (trad, pluginId) => {
|
859
1242
|
if (!pluginId) {
|
860
1243
|
throw new TypeError("pluginId can't be empty");
|
@@ -874,6 +1257,8 @@ const useDocumentActions = () => {
|
|
874
1257
|
const { formatMessage } = reactIntl.useIntl();
|
875
1258
|
const { trackUsage } = strapiAdmin.useTracking();
|
876
1259
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
1260
|
+
const navigate = reactRouterDom.useNavigate();
|
1261
|
+
const setCurrentStep = strapiAdmin.useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
877
1262
|
const [deleteDocument] = useDeleteDocumentMutation();
|
878
1263
|
const _delete = React__namespace.useCallback(
|
879
1264
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -1188,6 +1573,7 @@ const useDocumentActions = () => {
|
|
1188
1573
|
defaultMessage: "Saved document"
|
1189
1574
|
})
|
1190
1575
|
});
|
1576
|
+
setCurrentStep("contentManager.success");
|
1191
1577
|
return res.data;
|
1192
1578
|
} catch (err) {
|
1193
1579
|
toggleNotification({
|
@@ -1209,7 +1595,6 @@ const useDocumentActions = () => {
|
|
1209
1595
|
sourceId
|
1210
1596
|
});
|
1211
1597
|
if ("error" in res) {
|
1212
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1213
1598
|
return { error: res.error };
|
1214
1599
|
}
|
1215
1600
|
toggleNotification({
|
@@ -1228,7 +1613,7 @@ const useDocumentActions = () => {
|
|
1228
1613
|
throw err;
|
1229
1614
|
}
|
1230
1615
|
},
|
1231
|
-
[autoCloneDocument,
|
1616
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1232
1617
|
);
|
1233
1618
|
const [cloneDocument] = useCloneDocumentMutation();
|
1234
1619
|
const clone = React__namespace.useCallback(
|
@@ -1254,6 +1639,7 @@ const useDocumentActions = () => {
|
|
1254
1639
|
defaultMessage: "Cloned document"
|
1255
1640
|
})
|
1256
1641
|
});
|
1642
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1257
1643
|
return res.data;
|
1258
1644
|
} catch (err) {
|
1259
1645
|
toggleNotification({
|
@@ -1264,7 +1650,7 @@ const useDocumentActions = () => {
|
|
1264
1650
|
throw err;
|
1265
1651
|
}
|
1266
1652
|
},
|
1267
|
-
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
|
1653
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1268
1654
|
);
|
1269
1655
|
const [getDoc] = useLazyGetDocumentQuery();
|
1270
1656
|
const getDocument = React__namespace.useCallback(
|
@@ -1290,7 +1676,7 @@ const useDocumentActions = () => {
|
|
1290
1676
|
};
|
1291
1677
|
};
|
1292
1678
|
const ProtectedHistoryPage = React.lazy(
|
1293
|
-
() => Promise.resolve().then(() => require("./History-
|
1679
|
+
() => Promise.resolve().then(() => require("./History-C_uSGzO5.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1294
1680
|
);
|
1295
1681
|
const routes$1 = [
|
1296
1682
|
{
|
@@ -1303,31 +1689,31 @@ const routes$1 = [
|
|
1303
1689
|
}
|
1304
1690
|
];
|
1305
1691
|
const ProtectedEditViewPage = React.lazy(
|
1306
|
-
() => Promise.resolve().then(() => require("./EditViewPage-
|
1692
|
+
() => Promise.resolve().then(() => require("./EditViewPage-CUS2EAhB.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1307
1693
|
);
|
1308
1694
|
const ProtectedListViewPage = React.lazy(
|
1309
|
-
() => Promise.resolve().then(() => require("./ListViewPage-
|
1695
|
+
() => Promise.resolve().then(() => require("./ListViewPage-DHgHD8Xg.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1310
1696
|
);
|
1311
1697
|
const ProtectedListConfiguration = React.lazy(
|
1312
|
-
() => Promise.resolve().then(() => require("./ListConfigurationPage-
|
1698
|
+
() => Promise.resolve().then(() => require("./ListConfigurationPage-nyuP7OSy.js")).then((mod) => ({
|
1313
1699
|
default: mod.ProtectedListConfiguration
|
1314
1700
|
}))
|
1315
1701
|
);
|
1316
1702
|
const ProtectedEditConfigurationPage = React.lazy(
|
1317
|
-
() => Promise.resolve().then(() => require("./EditConfigurationPage-
|
1703
|
+
() => Promise.resolve().then(() => require("./EditConfigurationPage-DITVliEI.js")).then((mod) => ({
|
1318
1704
|
default: mod.ProtectedEditConfigurationPage
|
1319
1705
|
}))
|
1320
1706
|
);
|
1321
1707
|
const ProtectedComponentConfigurationPage = React.lazy(
|
1322
|
-
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-
|
1708
|
+
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-DP7AC0UU.js")).then((mod) => ({
|
1323
1709
|
default: mod.ProtectedComponentConfigurationPage
|
1324
1710
|
}))
|
1325
1711
|
);
|
1326
1712
|
const NoPermissions = React.lazy(
|
1327
|
-
() => Promise.resolve().then(() => require("./NoPermissionsPage-
|
1713
|
+
() => Promise.resolve().then(() => require("./NoPermissionsPage-zwIZydDI.js")).then((mod) => ({ default: mod.NoPermissions }))
|
1328
1714
|
);
|
1329
1715
|
const NoContentType = React.lazy(
|
1330
|
-
() => Promise.resolve().then(() => require("./NoContentTypePage-
|
1716
|
+
() => Promise.resolve().then(() => require("./NoContentTypePage-CDUKdZ7d.js")).then((mod) => ({ default: mod.NoContentType }))
|
1331
1717
|
);
|
1332
1718
|
const CollectionTypePages = () => {
|
1333
1719
|
const { collectionType } = reactRouterDom.useParams();
|
@@ -1441,12 +1827,14 @@ const DocumentActionButton = (action) => {
|
|
1441
1827
|
/* @__PURE__ */ jsxRuntime.jsx(
|
1442
1828
|
designSystem.Button,
|
1443
1829
|
{
|
1444
|
-
flex:
|
1830
|
+
flex: "auto",
|
1445
1831
|
startIcon: action.icon,
|
1446
1832
|
disabled: action.disabled,
|
1447
1833
|
onClick: handleClick(action),
|
1448
1834
|
justifyContent: "center",
|
1449
1835
|
variant: action.variant || "default",
|
1836
|
+
paddingTop: "7px",
|
1837
|
+
paddingBottom: "7px",
|
1450
1838
|
children: action.label
|
1451
1839
|
}
|
1452
1840
|
),
|
@@ -1454,7 +1842,7 @@ const DocumentActionButton = (action) => {
|
|
1454
1842
|
DocumentActionConfirmDialog,
|
1455
1843
|
{
|
1456
1844
|
...action.dialog,
|
1457
|
-
variant: action.variant,
|
1845
|
+
variant: action.dialog?.variant ?? action.variant,
|
1458
1846
|
isOpen: dialogId === action.id,
|
1459
1847
|
onClose: handleClose
|
1460
1848
|
}
|
@@ -1511,9 +1899,9 @@ const DocumentActionsMenu = ({
|
|
1511
1899
|
disabled: isDisabled,
|
1512
1900
|
size: "S",
|
1513
1901
|
endIcon: null,
|
1514
|
-
paddingTop: "
|
1515
|
-
paddingLeft: "
|
1516
|
-
paddingRight: "
|
1902
|
+
paddingTop: "4px",
|
1903
|
+
paddingLeft: "7px",
|
1904
|
+
paddingRight: "7px",
|
1517
1905
|
variant,
|
1518
1906
|
children: [
|
1519
1907
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.More, { "aria-hidden": true, focusable: false }),
|
@@ -1524,7 +1912,7 @@ const DocumentActionsMenu = ({
|
|
1524
1912
|
]
|
1525
1913
|
}
|
1526
1914
|
),
|
1527
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, {
|
1915
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1528
1916
|
actions2.map((action) => {
|
1529
1917
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
1530
1918
|
designSystem.Menu.Item,
|
@@ -1533,10 +1921,25 @@ const DocumentActionsMenu = ({
|
|
1533
1921
|
onSelect: handleClick(action),
|
1534
1922
|
display: "block",
|
1535
1923
|
children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", gap: 4, children: [
|
1536
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1924
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
1925
|
+
designSystem.Flex,
|
1926
|
+
{
|
1927
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1928
|
+
gap: 2,
|
1929
|
+
tag: "span",
|
1930
|
+
children: [
|
1931
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
1932
|
+
designSystem.Flex,
|
1933
|
+
{
|
1934
|
+
tag: "span",
|
1935
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1936
|
+
children: action.icon
|
1937
|
+
}
|
1938
|
+
),
|
1939
|
+
action.label
|
1940
|
+
]
|
1941
|
+
}
|
1942
|
+
),
|
1540
1943
|
action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsxRuntime.jsx(
|
1541
1944
|
designSystem.Flex,
|
1542
1945
|
{
|
@@ -1633,11 +2036,11 @@ const DocumentActionConfirmDialog = ({
|
|
1633
2036
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
1634
2037
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: content }),
|
1635
2038
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
|
1636
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", children: formatMessage({
|
2039
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", fullWidth: true, children: formatMessage({
|
1637
2040
|
id: "app.components.Button.cancel",
|
1638
2041
|
defaultMessage: "Cancel"
|
1639
2042
|
}) }) }),
|
1640
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, children: formatMessage({
|
2043
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
|
1641
2044
|
id: "app.components.Button.confirm",
|
1642
2045
|
defaultMessage: "Confirm"
|
1643
2046
|
}) })
|
@@ -1660,8 +2063,8 @@ const DocumentActionModal = ({
|
|
1660
2063
|
};
|
1661
2064
|
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Content, { children: [
|
1662
2065
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Title, { children: title }) }),
|
1663
|
-
|
1664
|
-
|
2066
|
+
typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, { children: Content }),
|
2067
|
+
typeof Footer === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Footer, { onClose: handleClose }) : Footer
|
1665
2068
|
] }) });
|
1666
2069
|
};
|
1667
2070
|
const PublishAction$1 = ({
|
@@ -1676,13 +2079,17 @@ const PublishAction$1 = ({
|
|
1676
2079
|
const navigate = reactRouterDom.useNavigate();
|
1677
2080
|
const { toggleNotification } = strapiAdmin.useNotification();
|
1678
2081
|
const { _unstableFormatValidationErrors: formatValidationErrors } = strapiAdmin.useAPIErrorHandler();
|
2082
|
+
const isListView = reactRouterDom.useMatch(LIST_PATH) !== null;
|
1679
2083
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
1680
2084
|
const { formatMessage } = reactIntl.useIntl();
|
1681
|
-
const { canPublish
|
1682
|
-
"PublishAction",
|
1683
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1684
|
-
);
|
2085
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1685
2086
|
const { publish } = useDocumentActions();
|
2087
|
+
const [
|
2088
|
+
countDraftRelations,
|
2089
|
+
{ isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
|
2090
|
+
] = useLazyGetDraftRelationCountQuery();
|
2091
|
+
const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React__namespace.useState(0);
|
2092
|
+
const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React__namespace.useState(0);
|
1686
2093
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1687
2094
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
1688
2095
|
const modified = strapiAdmin.useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
@@ -1691,63 +2098,143 @@ const PublishAction$1 = ({
|
|
1691
2098
|
const validate = strapiAdmin.useForm("PublishAction", (state) => state.validate);
|
1692
2099
|
const setErrors = strapiAdmin.useForm("PublishAction", (state) => state.setErrors);
|
1693
2100
|
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;
|
2101
|
+
React__namespace.useEffect(() => {
|
2102
|
+
if (isErrorDraftRelations) {
|
2103
|
+
toggleNotification({
|
2104
|
+
type: "danger",
|
2105
|
+
message: formatMessage({
|
2106
|
+
id: getTranslation("error.records.fetch-draft-relatons"),
|
2107
|
+
defaultMessage: "An error occurred while fetching draft relations on this document."
|
2108
|
+
})
|
2109
|
+
});
|
2110
|
+
}
|
2111
|
+
}, [isErrorDraftRelations, toggleNotification, formatMessage]);
|
2112
|
+
React__namespace.useEffect(() => {
|
2113
|
+
const localDraftRelations = /* @__PURE__ */ new Set();
|
2114
|
+
const extractDraftRelations = (data) => {
|
2115
|
+
const relations = data.connect || [];
|
2116
|
+
relations.forEach((relation) => {
|
2117
|
+
if (relation.status === "draft") {
|
2118
|
+
localDraftRelations.add(relation.id);
|
1728
2119
|
}
|
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));
|
2120
|
+
});
|
2121
|
+
};
|
2122
|
+
const traverseAndExtract = (data) => {
|
2123
|
+
Object.entries(data).forEach(([key, value]) => {
|
2124
|
+
if (key === "connect" && Array.isArray(value)) {
|
2125
|
+
extractDraftRelations({ connect: value });
|
2126
|
+
} else if (typeof value === "object" && value !== null) {
|
2127
|
+
traverseAndExtract(value);
|
1745
2128
|
}
|
1746
|
-
}
|
1747
|
-
|
2129
|
+
});
|
2130
|
+
};
|
2131
|
+
if (!documentId || modified) {
|
2132
|
+
traverseAndExtract(formValues);
|
2133
|
+
setLocalCountOfDraftRelations(localDraftRelations.size);
|
2134
|
+
}
|
2135
|
+
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
2136
|
+
React__namespace.useEffect(() => {
|
2137
|
+
if (!document || !document.documentId || isListView) {
|
2138
|
+
return;
|
2139
|
+
}
|
2140
|
+
const fetchDraftRelationsCount = async () => {
|
2141
|
+
const { data, error } = await countDraftRelations({
|
2142
|
+
collectionType,
|
2143
|
+
model,
|
2144
|
+
documentId,
|
2145
|
+
params
|
2146
|
+
});
|
2147
|
+
if (error) {
|
2148
|
+
throw error;
|
1748
2149
|
}
|
2150
|
+
if (data) {
|
2151
|
+
setServerCountOfDraftRelations(data.data);
|
2152
|
+
}
|
2153
|
+
};
|
2154
|
+
fetchDraftRelationsCount();
|
2155
|
+
}, [isListView, document, documentId, countDraftRelations, collectionType, model, params]);
|
2156
|
+
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
2157
|
+
if (!schema?.options?.draftAndPublish) {
|
2158
|
+
return null;
|
2159
|
+
}
|
2160
|
+
const performPublish = async () => {
|
2161
|
+
setSubmitting(true);
|
2162
|
+
try {
|
2163
|
+
const { errors } = await validate();
|
2164
|
+
if (errors) {
|
2165
|
+
toggleNotification({
|
2166
|
+
type: "danger",
|
2167
|
+
message: formatMessage({
|
2168
|
+
id: "content-manager.validation.error",
|
2169
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2170
|
+
})
|
2171
|
+
});
|
2172
|
+
return;
|
2173
|
+
}
|
2174
|
+
const res = await publish(
|
2175
|
+
{
|
2176
|
+
collectionType,
|
2177
|
+
model,
|
2178
|
+
documentId,
|
2179
|
+
params
|
2180
|
+
},
|
2181
|
+
formValues
|
2182
|
+
);
|
2183
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
2184
|
+
navigate({
|
2185
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
2186
|
+
search: rawQuery
|
2187
|
+
});
|
2188
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2189
|
+
setErrors(formatValidationErrors(res.error));
|
2190
|
+
}
|
2191
|
+
} finally {
|
2192
|
+
setSubmitting(false);
|
1749
2193
|
}
|
1750
2194
|
};
|
2195
|
+
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
2196
|
+
const enableDraftRelationsCount = false;
|
2197
|
+
const hasDraftRelations = enableDraftRelationsCount;
|
2198
|
+
return {
|
2199
|
+
/**
|
2200
|
+
* Disabled when:
|
2201
|
+
* - currently if you're cloning a document we don't support publish & clone at the same time.
|
2202
|
+
* - the form is submitting
|
2203
|
+
* - the active tab is the published tab
|
2204
|
+
* - the document is already published & not modified
|
2205
|
+
* - the document is being created & not modified
|
2206
|
+
* - the user doesn't have the permission to publish
|
2207
|
+
*/
|
2208
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
2209
|
+
label: formatMessage({
|
2210
|
+
id: "app.utils.publish",
|
2211
|
+
defaultMessage: "Publish"
|
2212
|
+
}),
|
2213
|
+
onClick: async () => {
|
2214
|
+
await performPublish();
|
2215
|
+
},
|
2216
|
+
dialog: hasDraftRelations ? {
|
2217
|
+
type: "dialog",
|
2218
|
+
variant: "danger",
|
2219
|
+
footer: null,
|
2220
|
+
title: formatMessage({
|
2221
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
|
2222
|
+
defaultMessage: "Confirmation"
|
2223
|
+
}),
|
2224
|
+
content: formatMessage(
|
2225
|
+
{
|
2226
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
2227
|
+
defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
|
2228
|
+
},
|
2229
|
+
{
|
2230
|
+
count: totalDraftRelations
|
2231
|
+
}
|
2232
|
+
),
|
2233
|
+
onConfirm: async () => {
|
2234
|
+
await performPublish();
|
2235
|
+
}
|
2236
|
+
} : void 0
|
2237
|
+
};
|
1751
2238
|
};
|
1752
2239
|
PublishAction$1.type = "publish";
|
1753
2240
|
const UpdateAction = ({
|
@@ -1762,10 +2249,6 @@ const UpdateAction = ({
|
|
1762
2249
|
const cloneMatch = reactRouterDom.useMatch(CLONE_PATH);
|
1763
2250
|
const isCloning = cloneMatch !== null;
|
1764
2251
|
const { formatMessage } = reactIntl.useIntl();
|
1765
|
-
const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1766
|
-
canCreate: canCreate2,
|
1767
|
-
canUpdate: canUpdate2
|
1768
|
-
}));
|
1769
2252
|
const { create, update, clone } = useDocumentActions();
|
1770
2253
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1771
2254
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
@@ -1782,10 +2265,8 @@ const UpdateAction = ({
|
|
1782
2265
|
* - the form is submitting
|
1783
2266
|
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
1784
2267
|
* - 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
2268
|
*/
|
1788
|
-
disabled: isSubmitting || !modified && !isCloning || activeTab === "published"
|
2269
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1789
2270
|
label: formatMessage({
|
1790
2271
|
id: "content-manager.containers.Edit.save",
|
1791
2272
|
defaultMessage: "Save"
|
@@ -1793,16 +2274,18 @@ const UpdateAction = ({
|
|
1793
2274
|
onClick: async () => {
|
1794
2275
|
setSubmitting(true);
|
1795
2276
|
try {
|
1796
|
-
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
1800
|
-
|
1801
|
-
|
1802
|
-
|
1803
|
-
|
1804
|
-
|
1805
|
-
|
2277
|
+
if (activeTab !== "draft") {
|
2278
|
+
const { errors } = await validate();
|
2279
|
+
if (errors) {
|
2280
|
+
toggleNotification({
|
2281
|
+
type: "danger",
|
2282
|
+
message: formatMessage({
|
2283
|
+
id: "content-manager.validation.error",
|
2284
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2285
|
+
})
|
2286
|
+
});
|
2287
|
+
return;
|
2288
|
+
}
|
1806
2289
|
}
|
1807
2290
|
if (isCloning) {
|
1808
2291
|
const res = await clone(
|
@@ -1814,10 +2297,13 @@ const UpdateAction = ({
|
|
1814
2297
|
document
|
1815
2298
|
);
|
1816
2299
|
if ("data" in res) {
|
1817
|
-
navigate(
|
1818
|
-
|
1819
|
-
|
1820
|
-
|
2300
|
+
navigate(
|
2301
|
+
{
|
2302
|
+
pathname: `../${res.data.documentId}`,
|
2303
|
+
search: rawQuery
|
2304
|
+
},
|
2305
|
+
{ relative: "path" }
|
2306
|
+
);
|
1821
2307
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1822
2308
|
setErrors(formatValidationErrors(res.error));
|
1823
2309
|
}
|
@@ -1847,10 +2333,10 @@ const UpdateAction = ({
|
|
1847
2333
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1848
2334
|
navigate(
|
1849
2335
|
{
|
1850
|
-
pathname: `../${
|
2336
|
+
pathname: `../${res.data.documentId}`,
|
1851
2337
|
search: rawQuery
|
1852
2338
|
},
|
1853
|
-
{ replace: true }
|
2339
|
+
{ replace: true, relative: "path" }
|
1854
2340
|
);
|
1855
2341
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1856
2342
|
setErrors(formatValidationErrors(res.error));
|
@@ -1895,7 +2381,7 @@ const UnpublishAction$1 = ({
|
|
1895
2381
|
id: "app.utils.unpublish",
|
1896
2382
|
defaultMessage: "Unpublish"
|
1897
2383
|
}),
|
1898
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2384
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Cross, {}),
|
1899
2385
|
onClick: async () => {
|
1900
2386
|
if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
|
1901
2387
|
if (!documentId) {
|
@@ -2007,7 +2493,7 @@ const DiscardAction = ({
|
|
2007
2493
|
id: "content-manager.actions.discard.label",
|
2008
2494
|
defaultMessage: "Discard changes"
|
2009
2495
|
}),
|
2010
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2496
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Cross, {}),
|
2011
2497
|
position: ["panel", "table-row"],
|
2012
2498
|
variant: "danger",
|
2013
2499
|
dialog: {
|
@@ -2035,11 +2521,6 @@ const DiscardAction = ({
|
|
2035
2521
|
};
|
2036
2522
|
};
|
2037
2523
|
DiscardAction.type = "discard";
|
2038
|
-
const StyledCrossCircle = styledComponents.styled(Icons.CrossCircle)`
|
2039
|
-
path {
|
2040
|
-
fill: currentColor;
|
2041
|
-
}
|
2042
|
-
`;
|
2043
2524
|
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2044
2525
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2045
2526
|
const RelativeTime = React__namespace.forwardRef(
|
@@ -2087,7 +2568,7 @@ const getDisplayName = ({
|
|
2087
2568
|
};
|
2088
2569
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2089
2570
|
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2090
|
-
const statusVariant = status === "draft" ? "
|
2571
|
+
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2091
2572
|
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
2573
|
};
|
2093
2574
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
@@ -2097,23 +2578,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
|
2097
2578
|
id: "content-manager.containers.edit.title.new",
|
2098
2579
|
defaultMessage: "Create an entry"
|
2099
2580
|
}) : documentTitle;
|
2100
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop:
|
2581
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2101
2582
|
/* @__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
|
2583
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2584
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
|
2585
|
+
/* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
|
2586
|
+
] }),
|
2587
|
+
status ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 1, children: /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
|
2117
2588
|
] });
|
2118
2589
|
};
|
2119
2590
|
const HeaderToolbar = () => {
|
@@ -2280,25 +2751,77 @@ const Information = ({ activeTab }) => {
|
|
2280
2751
|
);
|
2281
2752
|
};
|
2282
2753
|
const HeaderActions = ({ actions: actions2 }) => {
|
2283
|
-
|
2284
|
-
|
2754
|
+
const [dialogId, setDialogId] = React__namespace.useState(null);
|
2755
|
+
const handleClick = (action) => async (e) => {
|
2756
|
+
if (!("options" in action)) {
|
2757
|
+
const { onClick = () => false, dialog, id } = action;
|
2758
|
+
const muteDialog = await onClick(e);
|
2759
|
+
if (dialog && !muteDialog) {
|
2760
|
+
e.preventDefault();
|
2761
|
+
setDialogId(id);
|
2762
|
+
}
|
2763
|
+
}
|
2764
|
+
};
|
2765
|
+
const handleClose = () => {
|
2766
|
+
setDialogId(null);
|
2767
|
+
};
|
2768
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 1, children: actions2.map((action) => {
|
2769
|
+
if (action.options) {
|
2285
2770
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
2286
2771
|
designSystem.SingleSelect,
|
2287
2772
|
{
|
2288
2773
|
size: "S",
|
2289
|
-
disabled: action.disabled,
|
2290
|
-
"aria-label": action.label,
|
2291
2774
|
onChange: action.onSelect,
|
2292
|
-
|
2775
|
+
"aria-label": action.label,
|
2776
|
+
...action,
|
2293
2777
|
children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { ...option, children: label }, option.value))
|
2294
2778
|
},
|
2295
2779
|
action.id
|
2296
2780
|
);
|
2297
2781
|
} else {
|
2298
|
-
|
2782
|
+
if (action.type === "icon") {
|
2783
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
|
2784
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
2785
|
+
designSystem.IconButton,
|
2786
|
+
{
|
2787
|
+
disabled: action.disabled,
|
2788
|
+
label: action.label,
|
2789
|
+
size: "S",
|
2790
|
+
onClick: handleClick(action),
|
2791
|
+
children: action.icon
|
2792
|
+
}
|
2793
|
+
),
|
2794
|
+
action.dialog ? /* @__PURE__ */ jsxRuntime.jsx(
|
2795
|
+
HeaderActionDialog,
|
2796
|
+
{
|
2797
|
+
...action.dialog,
|
2798
|
+
isOpen: dialogId === action.id,
|
2799
|
+
onClose: handleClose
|
2800
|
+
}
|
2801
|
+
) : null
|
2802
|
+
] }, action.id);
|
2803
|
+
}
|
2299
2804
|
}
|
2300
2805
|
}) });
|
2301
2806
|
};
|
2807
|
+
const HeaderActionDialog = ({
|
2808
|
+
onClose,
|
2809
|
+
onCancel,
|
2810
|
+
title,
|
2811
|
+
content: Content,
|
2812
|
+
isOpen
|
2813
|
+
}) => {
|
2814
|
+
const handleClose = async () => {
|
2815
|
+
if (onCancel) {
|
2816
|
+
await onCancel();
|
2817
|
+
}
|
2818
|
+
onClose();
|
2819
|
+
};
|
2820
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
2821
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
2822
|
+
typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : Content
|
2823
|
+
] }) });
|
2824
|
+
};
|
2302
2825
|
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
2303
2826
|
const navigate = reactRouterDom.useNavigate();
|
2304
2827
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2339,12 +2862,16 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2339
2862
|
const { delete: deleteAction } = useDocumentActions();
|
2340
2863
|
const { toggleNotification } = strapiAdmin.useNotification();
|
2341
2864
|
const setSubmitting = strapiAdmin.useForm("DeleteAction", (state) => state.setSubmitting);
|
2865
|
+
const isLocalized = document?.locale != null;
|
2342
2866
|
return {
|
2343
2867
|
disabled: !canDelete || !document,
|
2344
|
-
label: formatMessage(
|
2345
|
-
|
2346
|
-
|
2347
|
-
|
2868
|
+
label: formatMessage(
|
2869
|
+
{
|
2870
|
+
id: "content-manager.actions.delete.label",
|
2871
|
+
defaultMessage: "Delete entry{isLocalized, select, true { (all locales)} other {}}"
|
2872
|
+
},
|
2873
|
+
{ isLocalized }
|
2874
|
+
),
|
2348
2875
|
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {}),
|
2349
2876
|
dialog: {
|
2350
2877
|
type: "dialog",
|
@@ -2375,428 +2902,126 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2375
2902
|
}),
|
2376
2903
|
type: "danger"
|
2377
2904
|
});
|
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
|
2905
|
+
return;
|
2906
|
+
}
|
2907
|
+
const res = await deleteAction({
|
2908
|
+
documentId,
|
2909
|
+
model,
|
2910
|
+
collectionType,
|
2911
|
+
params: {
|
2912
|
+
locale: "*"
|
2913
|
+
}
|
2914
|
+
});
|
2915
|
+
if (!("error" in res)) {
|
2916
|
+
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
2917
|
+
}
|
2918
|
+
} finally {
|
2919
|
+
if (!listViewPathMatch) {
|
2920
|
+
setSubmitting(false);
|
2921
|
+
}
|
2687
2922
|
}
|
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
|
2923
|
+
}
|
2709
2924
|
},
|
2710
|
-
|
2711
|
-
|
2712
|
-
...schema?.pluginOptions,
|
2713
|
-
...data.contentType.options
|
2714
|
-
}
|
2925
|
+
variant: "danger",
|
2926
|
+
position: ["header", "table-row"]
|
2715
2927
|
};
|
2716
2928
|
};
|
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
|
-
);
|
2929
|
+
DeleteAction$1.type = "delete";
|
2930
|
+
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2931
|
+
const Panels = () => {
|
2932
|
+
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2933
|
+
const [
|
2934
|
+
{
|
2935
|
+
query: { status }
|
2936
|
+
}
|
2937
|
+
] = strapiAdmin.useQueryParams({
|
2938
|
+
status: "draft"
|
2939
|
+
});
|
2940
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
2941
|
+
const plugins = strapiAdmin.useStrapiApp("Panels", (state) => state.plugins);
|
2942
|
+
const props = {
|
2943
|
+
activeTab: status,
|
2944
|
+
model,
|
2945
|
+
documentId: id,
|
2946
|
+
document: isCloning ? void 0 : document,
|
2947
|
+
meta: isCloning ? void 0 : meta,
|
2948
|
+
collectionType
|
2949
|
+
};
|
2950
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
|
2951
|
+
strapiAdmin.DescriptionComponentRenderer,
|
2952
|
+
{
|
2953
|
+
props,
|
2954
|
+
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2955
|
+
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsxRuntime.jsx(Panel, { ...description, children: content }, id2))
|
2956
|
+
}
|
2957
|
+
) });
|
2746
2958
|
};
|
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
|
-
);
|
2959
|
+
const ActionsPanel = () => {
|
2960
|
+
const { formatMessage } = reactIntl.useIntl();
|
2768
2961
|
return {
|
2769
|
-
|
2770
|
-
|
2771
|
-
|
2772
|
-
|
2773
|
-
|
2774
|
-
...schema?.pluginOptions,
|
2775
|
-
...data.contentType.options
|
2776
|
-
}
|
2962
|
+
title: formatMessage({
|
2963
|
+
id: "content-manager.containers.edit.panels.default.title",
|
2964
|
+
defaultMessage: "Entry"
|
2965
|
+
}),
|
2966
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(ActionsPanelContent, {})
|
2777
2967
|
};
|
2778
2968
|
};
|
2779
|
-
|
2780
|
-
|
2781
|
-
|
2782
|
-
|
2783
|
-
|
2969
|
+
ActionsPanel.type = "actions";
|
2970
|
+
const ActionsPanelContent = () => {
|
2971
|
+
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2972
|
+
const [
|
2973
|
+
{
|
2974
|
+
query: { status = "draft" }
|
2784
2975
|
}
|
2785
|
-
|
2786
|
-
|
2787
|
-
|
2788
|
-
|
2789
|
-
|
2790
|
-
|
2791
|
-
|
2792
|
-
|
2793
|
-
|
2794
|
-
|
2795
|
-
|
2796
|
-
|
2797
|
-
|
2798
|
-
|
2976
|
+
] = strapiAdmin.useQueryParams();
|
2977
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
2978
|
+
const plugins = strapiAdmin.useStrapiApp("ActionsPanel", (state) => state.plugins);
|
2979
|
+
const props = {
|
2980
|
+
activeTab: status,
|
2981
|
+
model,
|
2982
|
+
documentId: id,
|
2983
|
+
document: isCloning ? void 0 : document,
|
2984
|
+
meta: isCloning ? void 0 : meta,
|
2985
|
+
collectionType
|
2986
|
+
};
|
2987
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, width: "100%", children: [
|
2988
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
2989
|
+
strapiAdmin.DescriptionComponentRenderer,
|
2990
|
+
{
|
2991
|
+
props,
|
2992
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2993
|
+
children: (actions2) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActions, { actions: actions2 })
|
2994
|
+
}
|
2995
|
+
),
|
2996
|
+
/* @__PURE__ */ jsxRuntime.jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
2997
|
+
] });
|
2799
2998
|
};
|
2999
|
+
const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
3000
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
3001
|
+
designSystem.Flex,
|
3002
|
+
{
|
3003
|
+
ref,
|
3004
|
+
tag: "aside",
|
3005
|
+
"aria-labelledby": "additional-information",
|
3006
|
+
background: "neutral0",
|
3007
|
+
borderColor: "neutral150",
|
3008
|
+
hasRadius: true,
|
3009
|
+
paddingBottom: 4,
|
3010
|
+
paddingLeft: 4,
|
3011
|
+
paddingRight: 4,
|
3012
|
+
paddingTop: 4,
|
3013
|
+
shadow: "tableShadow",
|
3014
|
+
gap: 3,
|
3015
|
+
direction: "column",
|
3016
|
+
justifyContent: "stretch",
|
3017
|
+
alignItems: "flex-start",
|
3018
|
+
children: [
|
3019
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
3020
|
+
children
|
3021
|
+
]
|
3022
|
+
}
|
3023
|
+
);
|
3024
|
+
});
|
2800
3025
|
const ConfirmBulkActionDialog = ({
|
2801
3026
|
onToggleDialog,
|
2802
3027
|
isOpen = false,
|
@@ -2804,7 +3029,7 @@ const ConfirmBulkActionDialog = ({
|
|
2804
3029
|
endAction
|
2805
3030
|
}) => {
|
2806
3031
|
const { formatMessage } = reactIntl.useIntl();
|
2807
|
-
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, {
|
3032
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
2808
3033
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: formatMessage({
|
2809
3034
|
id: "app.components.ConfirmDialog.title",
|
2810
3035
|
defaultMessage: "Confirmation"
|
@@ -2835,6 +3060,7 @@ const ConfirmDialogPublishAll = ({
|
|
2835
3060
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler(getTranslation);
|
2836
3061
|
const { model, schema } = useDoc();
|
2837
3062
|
const [{ query }] = strapiAdmin.useQueryParams();
|
3063
|
+
const enableDraftRelationsCount = false;
|
2838
3064
|
const {
|
2839
3065
|
data: countDraftRelations = 0,
|
2840
3066
|
isLoading,
|
@@ -2846,7 +3072,7 @@ const ConfirmDialogPublishAll = ({
|
|
2846
3072
|
locale: query?.plugins?.i18n?.locale
|
2847
3073
|
},
|
2848
3074
|
{
|
2849
|
-
skip:
|
3075
|
+
skip: !enableDraftRelationsCount
|
2850
3076
|
}
|
2851
3077
|
);
|
2852
3078
|
React__namespace.useEffect(() => {
|
@@ -3031,7 +3257,7 @@ const SelectedEntriesTableContent = ({
|
|
3031
3257
|
status: row.status
|
3032
3258
|
}
|
3033
3259
|
) }),
|
3034
|
-
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
3260
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
3035
3261
|
designSystem.IconButton,
|
3036
3262
|
{
|
3037
3263
|
tag: reactRouterDom.Link,
|
@@ -3054,9 +3280,10 @@ const SelectedEntriesTableContent = ({
|
|
3054
3280
|
),
|
3055
3281
|
target: "_blank",
|
3056
3282
|
marginLeft: "auto",
|
3057
|
-
|
3283
|
+
variant: "ghost",
|
3284
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, { width: "1.6rem", height: "1.6rem" })
|
3058
3285
|
}
|
3059
|
-
) })
|
3286
|
+
) }) })
|
3060
3287
|
] }, row.id)) })
|
3061
3288
|
] });
|
3062
3289
|
};
|
@@ -3093,7 +3320,13 @@ const SelectedEntriesModalContent = ({
|
|
3093
3320
|
);
|
3094
3321
|
const { rows, validationErrors } = React__namespace.useMemo(() => {
|
3095
3322
|
if (data.length > 0 && schema) {
|
3096
|
-
const validate = createYupSchema(
|
3323
|
+
const validate = createYupSchema(
|
3324
|
+
schema.attributes,
|
3325
|
+
components,
|
3326
|
+
// Since this is the "Publish" action, the validation
|
3327
|
+
// schema must enforce the rules for published entities
|
3328
|
+
{ status: "published" }
|
3329
|
+
);
|
3097
3330
|
const validationErrors2 = {};
|
3098
3331
|
const rows2 = data.map((entry) => {
|
3099
3332
|
try {
|
@@ -3443,7 +3676,7 @@ const TableActions = ({ document }) => {
|
|
3443
3676
|
strapiAdmin.DescriptionComponentRenderer,
|
3444
3677
|
{
|
3445
3678
|
props,
|
3446
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3679
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
3447
3680
|
children: (actions2) => {
|
3448
3681
|
const tableRowActions = actions2.filter((action) => {
|
3449
3682
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3554,7 +3787,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3554
3787
|
}),
|
3555
3788
|
content: /* @__PURE__ */ jsxRuntime.jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
3556
3789
|
footer: ({ onClose }) => {
|
3557
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.
|
3790
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
3558
3791
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
3559
3792
|
id: "cancel",
|
3560
3793
|
defaultMessage: "Cancel"
|
@@ -3595,8 +3828,7 @@ class ContentManagerPlugin {
|
|
3595
3828
|
documentActions = [
|
3596
3829
|
...DEFAULT_ACTIONS,
|
3597
3830
|
...DEFAULT_TABLE_ROW_ACTIONS,
|
3598
|
-
...DEFAULT_HEADER_ACTIONS
|
3599
|
-
HistoryAction
|
3831
|
+
...DEFAULT_HEADER_ACTIONS
|
3600
3832
|
];
|
3601
3833
|
editViewSidePanels = [ActionsPanel];
|
3602
3834
|
headerActions = [];
|
@@ -3685,6 +3917,52 @@ const getPrintableType = (value) => {
|
|
3685
3917
|
}
|
3686
3918
|
return nativeType;
|
3687
3919
|
};
|
3920
|
+
const HistoryAction = ({ model, document }) => {
|
3921
|
+
const { formatMessage } = reactIntl.useIntl();
|
3922
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3923
|
+
const navigate = reactRouterDom.useNavigate();
|
3924
|
+
const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
|
3925
|
+
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3926
|
+
return null;
|
3927
|
+
}
|
3928
|
+
return {
|
3929
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
|
3930
|
+
label: formatMessage({
|
3931
|
+
id: "content-manager.history.document-action",
|
3932
|
+
defaultMessage: "Content History"
|
3933
|
+
}),
|
3934
|
+
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
3935
|
+
disabled: (
|
3936
|
+
/**
|
3937
|
+
* The user is creating a new document.
|
3938
|
+
* It hasn't been saved yet, so there's no history to go to
|
3939
|
+
*/
|
3940
|
+
!document || /**
|
3941
|
+
* The document has been created but the current dimension has never been saved.
|
3942
|
+
* For example, the user is creating a new locale in an existing document,
|
3943
|
+
* so there's no history for the document in that locale
|
3944
|
+
*/
|
3945
|
+
!document.id || /**
|
3946
|
+
* History is only available for content types created by the user.
|
3947
|
+
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
3948
|
+
* which start with `admin::` or `plugin::`
|
3949
|
+
*/
|
3950
|
+
!model.startsWith("api::")
|
3951
|
+
),
|
3952
|
+
position: "header"
|
3953
|
+
};
|
3954
|
+
};
|
3955
|
+
HistoryAction.type = "history";
|
3956
|
+
const historyAdmin = {
|
3957
|
+
bootstrap(app) {
|
3958
|
+
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
3959
|
+
addDocumentAction((actions2) => {
|
3960
|
+
const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
|
3961
|
+
actions2.splice(indexOfDeleteAction, 0, HistoryAction);
|
3962
|
+
return actions2;
|
3963
|
+
});
|
3964
|
+
}
|
3965
|
+
};
|
3688
3966
|
const initialState = {
|
3689
3967
|
collectionTypeLinks: [],
|
3690
3968
|
components: [],
|
@@ -3740,7 +4018,7 @@ const index = {
|
|
3740
4018
|
app.router.addRoute({
|
3741
4019
|
path: "content-manager/*",
|
3742
4020
|
lazy: async () => {
|
3743
|
-
const { Layout } = await Promise.resolve().then(() => require("./layout-
|
4021
|
+
const { Layout } = await Promise.resolve().then(() => require("./layout-UNWstw_s.js"));
|
3744
4022
|
return {
|
3745
4023
|
Component: Layout
|
3746
4024
|
};
|
@@ -3749,10 +4027,15 @@ const index = {
|
|
3749
4027
|
});
|
3750
4028
|
app.registerPlugin(cm.config);
|
3751
4029
|
},
|
4030
|
+
bootstrap(app) {
|
4031
|
+
if (typeof historyAdmin.bootstrap === "function") {
|
4032
|
+
historyAdmin.bootstrap(app);
|
4033
|
+
}
|
4034
|
+
},
|
3752
4035
|
async registerTrads({ locales }) {
|
3753
4036
|
const importedTrads = await Promise.all(
|
3754
4037
|
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-
|
4038
|
+
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
4039
|
return {
|
3757
4040
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3758
4041
|
locale
|
@@ -3770,6 +4053,7 @@ const index = {
|
|
3770
4053
|
};
|
3771
4054
|
exports.ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD = ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD;
|
3772
4055
|
exports.BulkActionsRenderer = BulkActionsRenderer;
|
4056
|
+
exports.CLONE_PATH = CLONE_PATH;
|
3773
4057
|
exports.COLLECTION_TYPES = COLLECTION_TYPES;
|
3774
4058
|
exports.CREATOR_FIELDS = CREATOR_FIELDS;
|
3775
4059
|
exports.DEFAULT_SETTINGS = DEFAULT_SETTINGS;
|
@@ -3797,6 +4081,7 @@ exports.getMainField = getMainField;
|
|
3797
4081
|
exports.getTranslation = getTranslation;
|
3798
4082
|
exports.index = index;
|
3799
4083
|
exports.setInitialData = setInitialData;
|
4084
|
+
exports.useContentManagerContext = useContentManagerContext;
|
3800
4085
|
exports.useContentTypeSchema = useContentTypeSchema;
|
3801
4086
|
exports.useDoc = useDoc;
|
3802
4087
|
exports.useDocLayout = useDocLayout;
|
@@ -3809,4 +4094,4 @@ exports.useGetAllDocumentsQuery = useGetAllDocumentsQuery;
|
|
3809
4094
|
exports.useGetContentTypeConfigurationQuery = useGetContentTypeConfigurationQuery;
|
3810
4095
|
exports.useGetInitialDataQuery = useGetInitialDataQuery;
|
3811
4096
|
exports.useUpdateContentTypeConfigurationMutation = useUpdateContentTypeConfigurationMutation;
|
3812
|
-
//# sourceMappingURL=index-
|
4097
|
+
//# sourceMappingURL=index-ovJRE1FM.js.map
|