@strapi/content-manager 0.0.0-experimental.145e7d7ddefd1aef71aaf3d9bb86440d013035bf → 0.0.0-experimental.15989d13d8be058bf37afc84b7a8377ef1da3263
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/CardDragPreview-C0QyJgRA.js.map +1 -1
- package/dist/_chunks/CardDragPreview-DOxamsuj.mjs.map +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-D_g11bYV.js → ComponentConfigurationPage-BSEZcJVB.js} +5 -6
- package/dist/_chunks/{ComponentConfigurationPage-D_g11bYV.js.map → ComponentConfigurationPage-BSEZcJVB.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-DJEJ49QD.mjs → ComponentConfigurationPage-BiASGi7x.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-DJEJ49QD.mjs.map → ComponentConfigurationPage-BiASGi7x.mjs.map} +1 -1
- package/dist/_chunks/{ComponentIcon-BXdiCGQp.js → ComponentIcon-CRbtQEUV.js} +2 -3
- package/dist/_chunks/{ComponentIcon-BXdiCGQp.js.map → ComponentIcon-CRbtQEUV.js.map} +1 -1
- package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +1 -1
- package/dist/_chunks/{EditConfigurationPage-CeL712KW.js → EditConfigurationPage-D2rtvneE.js} +5 -6
- package/dist/_chunks/{EditConfigurationPage-CeL712KW.js.map → EditConfigurationPage-D2rtvneE.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-QBZdUYyG.mjs → EditConfigurationPage-vN4zupij.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-QBZdUYyG.mjs.map → EditConfigurationPage-vN4zupij.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-g5TwrgRY.js → EditViewPage-BwisF04Q.js} +50 -11
- package/dist/_chunks/EditViewPage-BwisF04Q.js.map +1 -0
- package/dist/_chunks/{EditViewPage-CvRUUpVh.mjs → EditViewPage-_A31Cl4g.mjs} +50 -10
- package/dist/_chunks/EditViewPage-_A31Cl4g.mjs.map +1 -0
- package/dist/_chunks/{Field-reyvfnop.mjs → Field-CvIunNOj.mjs} +238 -152
- package/dist/_chunks/Field-CvIunNOj.mjs.map +1 -0
- package/dist/_chunks/{Field-ncdInvxS.js → Field-Dsu6-FrM.js} +244 -158
- package/dist/_chunks/Field-Dsu6-FrM.js.map +1 -0
- package/dist/_chunks/FieldTypeIcon-CMlNO8PE.mjs.map +1 -1
- package/dist/_chunks/FieldTypeIcon-Dnwq_IRF.js.map +1 -1
- package/dist/_chunks/{Form-DoMGsYxH.mjs → Form-DK0fG0Gj.mjs} +15 -9
- package/dist/_chunks/Form-DK0fG0Gj.mjs.map +1 -0
- package/dist/_chunks/{Form-BJ7bYiUx.js → Form-DUwWcCmA.js} +17 -12
- package/dist/_chunks/Form-DUwWcCmA.js.map +1 -0
- package/dist/_chunks/{History-pbhkxIrf.js → History-CeCDhoJG.js} +42 -100
- package/dist/_chunks/History-CeCDhoJG.js.map +1 -0
- package/dist/_chunks/{History-BseDJOrj.mjs → History-DP8gmXpm.mjs} +43 -100
- package/dist/_chunks/History-DP8gmXpm.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DWE_fr5B.mjs → ListConfigurationPage-BCkO5iuN.mjs} +7 -6
- package/dist/_chunks/ListConfigurationPage-BCkO5iuN.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-Bna8zfjr.js → ListConfigurationPage-C-bAd44a.js} +7 -7
- package/dist/_chunks/ListConfigurationPage-C-bAd44a.js.map +1 -0
- package/dist/_chunks/{ListViewPage-Dymsvnv6.js → ListViewPage-BKTZFhsM.js} +88 -54
- package/dist/_chunks/ListViewPage-BKTZFhsM.js.map +1 -0
- package/dist/_chunks/{ListViewPage-lQ-VLV2G.mjs → ListViewPage-Cf_DgaFV.mjs} +83 -48
- package/dist/_chunks/ListViewPage-Cf_DgaFV.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-B4t_OsDR.js → NoContentTypePage-D3Cm3v3q.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-B4t_OsDR.js.map → NoContentTypePage-D3Cm3v3q.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-VCQOMwlf.mjs → NoContentTypePage-nHIyvJcB.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-VCQOMwlf.mjs.map → NoContentTypePage-nHIyvJcB.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-TV830k4P.mjs → NoPermissionsPage-BALVSJ7x.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-TV830k4P.mjs.map → NoPermissionsPage-BALVSJ7x.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-BOwB6hki.js → NoPermissionsPage-CChGWBj5.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-BOwB6hki.js.map → NoPermissionsPage-CChGWBj5.js.map} +1 -1
- package/dist/_chunks/Preview-C4NBzKUV.mjs +294 -0
- package/dist/_chunks/Preview-C4NBzKUV.mjs.map +1 -0
- package/dist/_chunks/Preview-CT28Ckpg.js +312 -0
- package/dist/_chunks/Preview-CT28Ckpg.js.map +1 -0
- package/dist/_chunks/{Relations-D6NAlnsl.mjs → Relations-C8uC89cT.mjs} +75 -41
- package/dist/_chunks/Relations-C8uC89cT.mjs.map +1 -0
- package/dist/_chunks/{Relations-DdlstXTu.js → Relations-CvkPCng_.js} +75 -42
- package/dist/_chunks/Relations-CvkPCng_.js.map +1 -0
- package/dist/_chunks/{en-Cf41pH5f.js → en-BK8Xyl5I.js} +24 -12
- package/dist/_chunks/{en-Cf41pH5f.js.map → en-BK8Xyl5I.js.map} +1 -1
- package/dist/_chunks/{en-DCszE74t.mjs → en-Dtk_ot79.mjs} +24 -12
- package/dist/_chunks/{en-DCszE74t.mjs.map → en-Dtk_ot79.mjs.map} +1 -1
- package/dist/_chunks/{es-EUonQTon.js → es-9K52xZIr.js} +2 -2
- package/dist/_chunks/{ja-CcFe8diO.js.map → es-9K52xZIr.js.map} +1 -1
- package/dist/_chunks/{es-CeXiYflN.mjs → es-D34tqjMw.mjs} +2 -2
- package/dist/_chunks/{es-CeXiYflN.mjs.map → es-D34tqjMw.mjs.map} +1 -1
- package/dist/_chunks/{fr-CD9VFbPM.mjs → fr--pg5jUbt.mjs} +13 -3
- package/dist/_chunks/{fr-CD9VFbPM.mjs.map → fr--pg5jUbt.mjs.map} +1 -1
- package/dist/_chunks/{fr-B7kGGg3E.js → fr-B2Kyv8Z9.js} +13 -3
- package/dist/_chunks/{fr-B7kGGg3E.js.map → fr-B2Kyv8Z9.js.map} +1 -1
- package/dist/_chunks/hooks-BAaaKPS_.js.map +1 -1
- package/dist/_chunks/{index-CQos-KS0.js → index-CnX_j5h-.js} +1239 -942
- package/dist/_chunks/index-CnX_j5h-.js.map +1 -0
- package/dist/_chunks/{index-BYSWwHBJ.mjs → index-Dh2aGTGJ.mjs} +1241 -944
- package/dist/_chunks/index-Dh2aGTGJ.mjs.map +1 -0
- package/dist/_chunks/{ja-CcFe8diO.js → ja-7sfIbjxE.js} +2 -2
- package/dist/_chunks/{es-EUonQTon.js.map → ja-7sfIbjxE.js.map} +1 -1
- package/dist/_chunks/{ja-CtsUxOvk.mjs → ja-BHqhDq4V.mjs} +2 -2
- package/dist/_chunks/{ja-CtsUxOvk.mjs.map → ja-BHqhDq4V.mjs.map} +1 -1
- package/dist/_chunks/{layout-0TY7UtKO.mjs → layout-B5qsPihj.mjs} +6 -5
- package/dist/_chunks/{layout-0TY7UtKO.mjs.map → layout-B5qsPihj.mjs.map} +1 -1
- package/dist/_chunks/{layout-B4XAqu1v.js → layout-B_qdWGny.js} +7 -7
- package/dist/_chunks/{layout-B4XAqu1v.js.map → layout-B_qdWGny.js.map} +1 -1
- package/dist/_chunks/{objects-gigeqt7s.js → objects-BcXOv6_9.js} +2 -4
- package/dist/_chunks/{objects-gigeqt7s.js.map → objects-BcXOv6_9.js.map} +1 -1
- package/dist/_chunks/{objects-mKMAmfec.mjs → objects-D6yBsdmx.mjs} +2 -4
- package/dist/_chunks/{objects-mKMAmfec.mjs.map → objects-D6yBsdmx.mjs.map} +1 -1
- package/dist/_chunks/{relations-xZ2tMj1G.js → relations-ChcieiF5.js} +6 -7
- package/dist/_chunks/relations-ChcieiF5.js.map +1 -0
- package/dist/_chunks/{relations-DFDWfa0s.mjs → relations-DMXpNY-e.mjs} +6 -7
- package/dist/_chunks/relations-DMXpNY-e.mjs.map +1 -0
- 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/_chunks/{useDragAndDrop-J0TUUbR6.js → useDragAndDrop-BMtgCYzL.js} +5 -9
- package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js.map → useDragAndDrop-BMtgCYzL.js.map} +1 -1
- package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs → useDragAndDrop-DJ6jqvZN.mjs} +4 -7
- package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs.map → useDragAndDrop-DJ6jqvZN.mjs.map} +1 -1
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +4 -3
- package/dist/admin/src/content-manager.d.ts +3 -2
- package/dist/admin/src/exports.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +32 -1
- package/dist/admin/src/pages/EditView/EditViewPage.d.ts +9 -1
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Code.d.ts +7 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/utils/prismLanguages.d.ts +49 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
- package/dist/admin/src/preview/components/PreviewContent.d.ts +2 -0
- package/dist/admin/src/preview/components/PreviewHeader.d.ts +2 -0
- package/dist/admin/src/preview/components/PreviewSidePanel.d.ts +3 -0
- package/dist/admin/src/preview/index.d.ts +4 -0
- package/dist/admin/src/preview/pages/Preview.d.ts +11 -0
- package/dist/admin/src/preview/routes.d.ts +3 -0
- package/dist/admin/src/preview/services/preview.d.ts +3 -0
- package/dist/admin/src/router.d.ts +1 -1
- package/dist/admin/src/services/documents.d.ts +0 -3
- package/dist/server/index.js +513 -260
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +514 -260
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/controllers/relations.d.ts.map +1 -1
- package/dist/server/src/controllers/utils/metadata.d.ts +16 -1
- package/dist/server/src/controllers/utils/metadata.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 -3
- package/dist/server/src/history/services/utils.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +7 -6
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/preview/controllers/index.d.ts +2 -0
- package/dist/server/src/preview/controllers/index.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/preview.d.ts +13 -0
- package/dist/server/src/preview/controllers/preview.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/validation/preview.d.ts +6 -0
- package/dist/server/src/preview/controllers/validation/preview.d.ts.map +1 -0
- package/dist/server/src/preview/index.d.ts +4 -0
- package/dist/server/src/preview/index.d.ts.map +1 -0
- package/dist/server/src/preview/routes/index.d.ts +8 -0
- package/dist/server/src/preview/routes/index.d.ts.map +1 -0
- package/dist/server/src/preview/routes/preview.d.ts +4 -0
- package/dist/server/src/preview/routes/preview.d.ts.map +1 -0
- package/dist/server/src/preview/services/index.d.ts +16 -0
- package/dist/server/src/preview/services/index.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview-config.d.ts +32 -0
- package/dist/server/src/preview/services/preview-config.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview.d.ts +12 -0
- package/dist/server/src/preview/services/preview.d.ts.map +1 -0
- package/dist/server/src/preview/utils.d.ts +19 -0
- package/dist/server/src/preview/utils.d.ts.map +1 -0
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/routes/index.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 +12 -10
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +7 -6
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/utils/populate.d.ts +2 -2
- package/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/dist/server/src/utils/index.d.ts +2 -0
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/dist/shared/contracts/index.d.ts +1 -0
- package/dist/shared/contracts/index.d.ts.map +1 -1
- package/dist/shared/contracts/preview.d.ts +27 -0
- package/dist/shared/contracts/preview.d.ts.map +1 -0
- package/dist/shared/index.js +4 -0
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs +4 -0
- package/dist/shared/index.mjs.map +1 -1
- package/package.json +17 -15
- package/dist/_chunks/EditViewPage-CvRUUpVh.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-g5TwrgRY.js.map +0 -1
- package/dist/_chunks/Field-ncdInvxS.js.map +0 -1
- package/dist/_chunks/Field-reyvfnop.mjs.map +0 -1
- package/dist/_chunks/Form-BJ7bYiUx.js.map +0 -1
- package/dist/_chunks/Form-DoMGsYxH.mjs.map +0 -1
- package/dist/_chunks/History-BseDJOrj.mjs.map +0 -1
- package/dist/_chunks/History-pbhkxIrf.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-Bna8zfjr.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DWE_fr5B.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-Dymsvnv6.js.map +0 -1
- package/dist/_chunks/ListViewPage-lQ-VLV2G.mjs.map +0 -1
- package/dist/_chunks/Relations-D6NAlnsl.mjs.map +0 -1
- package/dist/_chunks/Relations-DdlstXTu.js.map +0 -1
- package/dist/_chunks/index-BYSWwHBJ.mjs.map +0 -1
- package/dist/_chunks/index-CQos-KS0.js.map +0 -1
- package/dist/_chunks/relations-DFDWfa0s.mjs.map +0 -1
- package/dist/_chunks/relations-xZ2tMj1G.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
@@ -4,18 +4,18 @@ const jsxRuntime = require("react/jsx-runtime");
|
|
4
4
|
const strapiAdmin = require("@strapi/admin/strapi-admin");
|
5
5
|
const React = require("react");
|
6
6
|
const designSystem = require("@strapi/design-system");
|
7
|
+
const mapValues = require("lodash/fp/mapValues");
|
7
8
|
const reactIntl = require("react-intl");
|
8
9
|
const reactRouterDom = require("react-router-dom");
|
10
|
+
const styledComponents = require("styled-components");
|
9
11
|
const yup = require("yup");
|
12
|
+
const qs = require("qs");
|
10
13
|
const pipe = require("lodash/fp/pipe");
|
11
14
|
const dateFns = require("date-fns");
|
12
|
-
const styledComponents = require("styled-components");
|
13
|
-
const qs = require("qs");
|
14
15
|
const toolkit = require("@reduxjs/toolkit");
|
15
16
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
16
17
|
function _interopNamespace(e) {
|
17
|
-
if (e && e.__esModule)
|
18
|
-
return e;
|
18
|
+
if (e && e.__esModule) return e;
|
19
19
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
20
20
|
if (e) {
|
21
21
|
for (const k in e) {
|
@@ -32,15 +32,23 @@ function _interopNamespace(e) {
|
|
32
32
|
return Object.freeze(n);
|
33
33
|
}
|
34
34
|
const React__namespace = /* @__PURE__ */ _interopNamespace(React);
|
35
|
+
const mapValues__default = /* @__PURE__ */ _interopDefault(mapValues);
|
35
36
|
const yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
|
36
37
|
const pipe__default = /* @__PURE__ */ _interopDefault(pipe);
|
37
|
-
const __variableDynamicImportRuntimeHelper = (glob, path) => {
|
38
|
+
const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
|
38
39
|
const v = glob[path];
|
39
40
|
if (v) {
|
40
41
|
return typeof v === "function" ? v() : Promise.resolve(v);
|
41
42
|
}
|
42
43
|
return new Promise((_, reject) => {
|
43
|
-
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
44
|
+
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
45
|
+
reject.bind(
|
46
|
+
null,
|
47
|
+
new Error(
|
48
|
+
"Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
|
49
|
+
)
|
50
|
+
)
|
51
|
+
);
|
44
52
|
});
|
45
53
|
};
|
46
54
|
const PLUGIN_ID = "content-manager";
|
@@ -121,6 +129,7 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
121
129
|
if (!slug) {
|
122
130
|
throw new Error("Cannot find the slug param in the URL");
|
123
131
|
}
|
132
|
+
const [{ rawQuery }] = strapiAdmin.useQueryParams();
|
124
133
|
const userPermissions = strapiAdmin.useAuth("DocumentRBAC", (state) => state.permissions);
|
125
134
|
const contentTypePermissions = React__namespace.useMemo(() => {
|
126
135
|
const contentTypePermissions2 = userPermissions.filter(
|
@@ -131,7 +140,14 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
131
140
|
return { ...acc, [action]: [permission] };
|
132
141
|
}, {});
|
133
142
|
}, [slug, userPermissions]);
|
134
|
-
const { isLoading, allowedActions } = strapiAdmin.useRBAC(
|
143
|
+
const { isLoading, allowedActions } = strapiAdmin.useRBAC(
|
144
|
+
contentTypePermissions,
|
145
|
+
permissions ?? void 0,
|
146
|
+
// TODO: useRBAC context should be typed and built differently
|
147
|
+
// We are passing raw query as context to the hook so that it can
|
148
|
+
// rely on the locale provided from DocumentRBAC for its permission calculations.
|
149
|
+
rawQuery
|
150
|
+
);
|
135
151
|
const canCreateFields = !isLoading && allowedActions.canCreate ? extractAndDedupeFields(contentTypePermissions.create) : [];
|
136
152
|
const canReadFields = !isLoading && allowedActions.canRead ? extractAndDedupeFields(contentTypePermissions.read) : [];
|
137
153
|
const canUpdateFields = !isLoading && allowedActions.canUpdate ? extractAndDedupeFields(contentTypePermissions.update) : [];
|
@@ -232,7 +248,19 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
232
248
|
{ type: "Document", id: `${model}_LIST` },
|
233
249
|
"Relations",
|
234
250
|
{ type: "UidAvailability", id: model }
|
235
|
-
]
|
251
|
+
],
|
252
|
+
transformResponse: (response, meta, arg) => {
|
253
|
+
if (!("data" in response) && arg.model === "plugin::users-permissions.user") {
|
254
|
+
return {
|
255
|
+
data: response,
|
256
|
+
meta: {
|
257
|
+
availableStatus: [],
|
258
|
+
availableLocales: []
|
259
|
+
}
|
260
|
+
};
|
261
|
+
}
|
262
|
+
return response;
|
263
|
+
}
|
236
264
|
}),
|
237
265
|
deleteDocument: builder.mutation({
|
238
266
|
query: ({ collectionType, model, documentId, params }) => ({
|
@@ -286,7 +314,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
286
314
|
url: `/content-manager/collection-types/${model}`,
|
287
315
|
method: "GET",
|
288
316
|
config: {
|
289
|
-
params
|
317
|
+
params: qs.stringify(params, { encode: true })
|
290
318
|
}
|
291
319
|
}),
|
292
320
|
providesTags: (result, _error, arg) => {
|
@@ -465,8 +493,7 @@ const {
|
|
465
493
|
useUnpublishManyDocumentsMutation
|
466
494
|
} = documentApi;
|
467
495
|
const buildValidParams = (query) => {
|
468
|
-
if (!query)
|
469
|
-
return query;
|
496
|
+
if (!query) return query;
|
470
497
|
const { plugins: _, ...validQueryParams } = {
|
471
498
|
...query,
|
472
499
|
...Object.values(query?.plugins ?? {}).reduce(
|
@@ -474,14 +501,29 @@ const buildValidParams = (query) => {
|
|
474
501
|
{}
|
475
502
|
)
|
476
503
|
};
|
477
|
-
if ("_q" in validQueryParams) {
|
478
|
-
validQueryParams._q = encodeURIComponent(validQueryParams._q);
|
479
|
-
}
|
480
504
|
return validQueryParams;
|
481
505
|
};
|
482
506
|
const isBaseQueryError = (error) => {
|
483
507
|
return error.name !== void 0;
|
484
508
|
};
|
509
|
+
const arrayValidator = (attribute, options) => ({
|
510
|
+
message: strapiAdmin.translatedErrors.required,
|
511
|
+
test(value) {
|
512
|
+
if (options.status === "draft") {
|
513
|
+
return true;
|
514
|
+
}
|
515
|
+
if (!attribute.required) {
|
516
|
+
return true;
|
517
|
+
}
|
518
|
+
if (!value) {
|
519
|
+
return false;
|
520
|
+
}
|
521
|
+
if (Array.isArray(value) && value.length === 0) {
|
522
|
+
return false;
|
523
|
+
}
|
524
|
+
return true;
|
525
|
+
}
|
526
|
+
});
|
485
527
|
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
486
528
|
const createModelSchema = (attributes2) => yup__namespace.object().shape(
|
487
529
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
@@ -489,6 +531,7 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
|
|
489
531
|
return acc;
|
490
532
|
}
|
491
533
|
const validations = [
|
534
|
+
addNullableValidation,
|
492
535
|
addRequiredValidation,
|
493
536
|
addMinLengthValidation,
|
494
537
|
addMaxLengthValidation,
|
@@ -505,12 +548,12 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
|
|
505
548
|
...acc,
|
506
549
|
[name]: transformSchema(
|
507
550
|
yup__namespace.array().of(createModelSchema(attributes3).nullable(false))
|
508
|
-
)
|
551
|
+
).test(arrayValidator(attribute, options))
|
509
552
|
};
|
510
553
|
} else {
|
511
554
|
return {
|
512
555
|
...acc,
|
513
|
-
[name]: transformSchema(createModelSchema(attributes3))
|
556
|
+
[name]: transformSchema(createModelSchema(attributes3).nullable())
|
514
557
|
};
|
515
558
|
}
|
516
559
|
}
|
@@ -532,7 +575,7 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
|
|
532
575
|
}
|
533
576
|
)
|
534
577
|
)
|
535
|
-
)
|
578
|
+
).test(arrayValidator(attribute, options))
|
536
579
|
};
|
537
580
|
case "relation":
|
538
581
|
return {
|
@@ -544,7 +587,7 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
|
|
544
587
|
} else if (Array.isArray(value)) {
|
545
588
|
return yup__namespace.array().of(
|
546
589
|
yup__namespace.object().shape({
|
547
|
-
id: yup__namespace.
|
590
|
+
id: yup__namespace.number().required()
|
548
591
|
})
|
549
592
|
);
|
550
593
|
} else if (typeof value === "object") {
|
@@ -630,17 +673,17 @@ const nullableSchema = (schema) => {
|
|
630
673
|
schema
|
631
674
|
);
|
632
675
|
};
|
676
|
+
const addNullableValidation = () => (schema) => {
|
677
|
+
return nullableSchema(schema);
|
678
|
+
};
|
633
679
|
const addRequiredValidation = (attribute, options) => (schema) => {
|
634
|
-
if (options.status === "draft") {
|
635
|
-
return
|
636
|
-
}
|
637
|
-
if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
|
638
|
-
return schema.min(1, strapiAdmin.translatedErrors.required);
|
680
|
+
if (options.status === "draft" || !attribute.required) {
|
681
|
+
return schema;
|
639
682
|
}
|
640
|
-
if (attribute.required &&
|
683
|
+
if (attribute.required && "required" in schema) {
|
641
684
|
return schema.required(strapiAdmin.translatedErrors.required);
|
642
685
|
}
|
643
|
-
return
|
686
|
+
return schema;
|
644
687
|
};
|
645
688
|
const addMinLengthValidation = (attribute, options) => (schema) => {
|
646
689
|
if (options.status === "draft") {
|
@@ -668,31 +711,12 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
668
711
|
return schema;
|
669
712
|
};
|
670
713
|
const addMinValidation = (attribute, options) => (schema) => {
|
671
|
-
if ("
|
714
|
+
if (options.status === "draft") {
|
715
|
+
return schema;
|
716
|
+
}
|
717
|
+
if ("min" in attribute && "min" in schema) {
|
672
718
|
const min = toInteger(attribute.min);
|
673
|
-
if (
|
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
|
-
}
|
695
|
-
if ("min" in schema && min) {
|
719
|
+
if (min) {
|
696
720
|
return schema.min(min, {
|
697
721
|
...strapiAdmin.translatedErrors.min,
|
698
722
|
values: {
|
@@ -810,19 +834,115 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
|
|
810
834
|
}, {});
|
811
835
|
return componentsByKey;
|
812
836
|
};
|
813
|
-
const
|
837
|
+
const HOOKS = {
|
838
|
+
/**
|
839
|
+
* Hook that allows to mutate the displayed headers of the list view table
|
840
|
+
* @constant
|
841
|
+
* @type {string}
|
842
|
+
*/
|
843
|
+
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
844
|
+
/**
|
845
|
+
* Hook that allows to mutate the CM's collection types links pre-set filters
|
846
|
+
* @constant
|
847
|
+
* @type {string}
|
848
|
+
*/
|
849
|
+
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
850
|
+
/**
|
851
|
+
* Hook that allows to mutate the CM's edit view layout
|
852
|
+
* @constant
|
853
|
+
* @type {string}
|
854
|
+
*/
|
855
|
+
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
856
|
+
/**
|
857
|
+
* Hook that allows to mutate the CM's single types links pre-set filters
|
858
|
+
* @constant
|
859
|
+
* @type {string}
|
860
|
+
*/
|
861
|
+
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
862
|
+
};
|
863
|
+
const contentTypesApi = contentManagerApi.injectEndpoints({
|
864
|
+
endpoints: (builder) => ({
|
865
|
+
getContentTypeConfiguration: builder.query({
|
866
|
+
query: (uid) => ({
|
867
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
868
|
+
method: "GET"
|
869
|
+
}),
|
870
|
+
transformResponse: (response) => response.data,
|
871
|
+
providesTags: (_result, _error, uid) => [
|
872
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
873
|
+
{ type: "ContentTypeSettings", id: "LIST" }
|
874
|
+
]
|
875
|
+
}),
|
876
|
+
getAllContentTypeSettings: builder.query({
|
877
|
+
query: () => "/content-manager/content-types-settings",
|
878
|
+
transformResponse: (response) => response.data,
|
879
|
+
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
880
|
+
}),
|
881
|
+
updateContentTypeConfiguration: builder.mutation({
|
882
|
+
query: ({ uid, ...body }) => ({
|
883
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
884
|
+
method: "PUT",
|
885
|
+
data: body
|
886
|
+
}),
|
887
|
+
transformResponse: (response) => response.data,
|
888
|
+
invalidatesTags: (_result, _error, { uid }) => [
|
889
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
890
|
+
{ type: "ContentTypeSettings", id: "LIST" },
|
891
|
+
// Is this necessary?
|
892
|
+
{ type: "InitialData" }
|
893
|
+
]
|
894
|
+
})
|
895
|
+
})
|
896
|
+
});
|
897
|
+
const {
|
898
|
+
useGetContentTypeConfigurationQuery,
|
899
|
+
useGetAllContentTypeSettingsQuery,
|
900
|
+
useUpdateContentTypeConfigurationMutation
|
901
|
+
} = contentTypesApi;
|
902
|
+
const checkIfAttributeIsDisplayable = (attribute) => {
|
903
|
+
const { type } = attribute;
|
904
|
+
if (type === "relation") {
|
905
|
+
return !attribute.relation.toLowerCase().includes("morph");
|
906
|
+
}
|
907
|
+
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
908
|
+
};
|
909
|
+
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
910
|
+
if (!mainFieldName) {
|
911
|
+
return void 0;
|
912
|
+
}
|
913
|
+
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
914
|
+
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
915
|
+
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
916
|
+
);
|
917
|
+
return {
|
918
|
+
name: mainFieldName,
|
919
|
+
type: mainFieldType ?? "string"
|
920
|
+
};
|
921
|
+
};
|
922
|
+
const DEFAULT_SETTINGS = {
|
923
|
+
bulkable: false,
|
924
|
+
filterable: false,
|
925
|
+
searchable: false,
|
926
|
+
pagination: false,
|
927
|
+
defaultSortBy: "",
|
928
|
+
defaultSortOrder: "asc",
|
929
|
+
mainField: "id",
|
930
|
+
pageSize: 10
|
931
|
+
};
|
932
|
+
const useDocumentLayout = (model) => {
|
933
|
+
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
934
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
935
|
+
const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
814
936
|
const { toggleNotification } = strapiAdmin.useNotification();
|
815
937
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
938
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
816
939
|
const {
|
817
|
-
|
818
|
-
isLoading:
|
819
|
-
|
820
|
-
|
821
|
-
} =
|
822
|
-
|
823
|
-
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
824
|
-
});
|
825
|
-
const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
|
940
|
+
data,
|
941
|
+
isLoading: isLoadingConfigs,
|
942
|
+
error,
|
943
|
+
isFetching: isFetchingConfigs
|
944
|
+
} = useGetContentTypeConfigurationQuery(model);
|
945
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
826
946
|
React__namespace.useEffect(() => {
|
827
947
|
if (error) {
|
828
948
|
toggleNotification({
|
@@ -830,363 +950,438 @@ const useDocument = (args, opts) => {
|
|
830
950
|
message: formatAPIError(error)
|
831
951
|
});
|
832
952
|
}
|
833
|
-
}, [
|
834
|
-
const
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
(document) => {
|
842
|
-
if (!validationSchema) {
|
843
|
-
throw new Error(
|
844
|
-
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
845
|
-
);
|
846
|
-
}
|
847
|
-
try {
|
848
|
-
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
849
|
-
return null;
|
850
|
-
} catch (error2) {
|
851
|
-
if (error2 instanceof yup.ValidationError) {
|
852
|
-
return strapiAdmin.getYupValidationErrors(error2);
|
853
|
-
}
|
854
|
-
throw error2;
|
855
|
-
}
|
953
|
+
}, [error, formatAPIError, toggleNotification]);
|
954
|
+
const editLayout = React__namespace.useMemo(
|
955
|
+
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
956
|
+
layout: [],
|
957
|
+
components: {},
|
958
|
+
metadatas: {},
|
959
|
+
options: {},
|
960
|
+
settings: DEFAULT_SETTINGS
|
856
961
|
},
|
857
|
-
[
|
962
|
+
[data, isLoading, schemas, schema, components]
|
963
|
+
);
|
964
|
+
const listLayout = React__namespace.useMemo(() => {
|
965
|
+
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
966
|
+
layout: [],
|
967
|
+
metadatas: {},
|
968
|
+
options: {},
|
969
|
+
settings: DEFAULT_SETTINGS
|
970
|
+
};
|
971
|
+
}, [data, isLoading, schemas, schema, components]);
|
972
|
+
const { layout: edit } = React__namespace.useMemo(
|
973
|
+
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
974
|
+
layout: editLayout,
|
975
|
+
query
|
976
|
+
}),
|
977
|
+
[editLayout, query, runHookWaterfall]
|
858
978
|
);
|
859
|
-
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
860
979
|
return {
|
861
|
-
|
862
|
-
document: data?.data,
|
863
|
-
meta: data?.meta,
|
980
|
+
error,
|
864
981
|
isLoading,
|
865
|
-
|
866
|
-
|
867
|
-
};
|
868
|
-
};
|
869
|
-
const useDoc = () => {
|
870
|
-
const { id, slug, collectionType, origin } = reactRouterDom.useParams();
|
871
|
-
const [{ query }] = strapiAdmin.useQueryParams();
|
872
|
-
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
873
|
-
if (!collectionType) {
|
874
|
-
throw new Error("Could not find collectionType in url params");
|
875
|
-
}
|
876
|
-
if (!slug) {
|
877
|
-
throw new Error("Could not find model in url params");
|
878
|
-
}
|
879
|
-
return {
|
880
|
-
collectionType,
|
881
|
-
model: slug,
|
882
|
-
id: origin || id === "create" ? void 0 : id,
|
883
|
-
...useDocument(
|
884
|
-
{ documentId: origin || id, model: slug, collectionType, params },
|
885
|
-
{
|
886
|
-
skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
|
887
|
-
}
|
888
|
-
)
|
982
|
+
edit,
|
983
|
+
list: listLayout
|
889
984
|
};
|
890
985
|
};
|
891
|
-
const
|
892
|
-
|
893
|
-
|
894
|
-
}
|
895
|
-
return Object.keys(trad).reduce((acc, current) => {
|
896
|
-
acc[`${pluginId}.${current}`] = trad[current];
|
897
|
-
return acc;
|
898
|
-
}, {});
|
899
|
-
};
|
900
|
-
const getTranslation = (id) => `content-manager.${id}`;
|
901
|
-
const DEFAULT_UNEXPECTED_ERROR_MSG = {
|
902
|
-
id: "notification.error",
|
903
|
-
defaultMessage: "An error occurred, please try again"
|
986
|
+
const useDocLayout = () => {
|
987
|
+
const { model } = useDoc();
|
988
|
+
return useDocumentLayout(model);
|
904
989
|
};
|
905
|
-
const
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
const
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
});
|
927
|
-
return { error: res.error };
|
928
|
-
}
|
929
|
-
toggleNotification({
|
930
|
-
type: "success",
|
931
|
-
message: formatMessage({
|
932
|
-
id: getTranslation("success.record.delete"),
|
933
|
-
defaultMessage: "Deleted document"
|
934
|
-
})
|
935
|
-
});
|
936
|
-
trackUsage("didDeleteEntry", trackerProperty);
|
937
|
-
return res.data;
|
938
|
-
} catch (err) {
|
939
|
-
toggleNotification({
|
940
|
-
type: "danger",
|
941
|
-
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
942
|
-
});
|
943
|
-
trackUsage("didNotDeleteEntry", { error: err, ...trackerProperty });
|
944
|
-
throw err;
|
990
|
+
const formatEditLayout = (data, {
|
991
|
+
schemas,
|
992
|
+
schema,
|
993
|
+
components
|
994
|
+
}) => {
|
995
|
+
let currentPanelIndex = 0;
|
996
|
+
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
997
|
+
data.contentType.layouts.edit,
|
998
|
+
schema?.attributes,
|
999
|
+
data.contentType.metadatas,
|
1000
|
+
{ configurations: data.components, schemas: components },
|
1001
|
+
schemas
|
1002
|
+
).reduce((panels, row) => {
|
1003
|
+
if (row.some((field) => field.type === "dynamiczone")) {
|
1004
|
+
panels.push([row]);
|
1005
|
+
currentPanelIndex += 2;
|
1006
|
+
} else {
|
1007
|
+
if (!panels[currentPanelIndex]) {
|
1008
|
+
panels.push([row]);
|
1009
|
+
} else {
|
1010
|
+
panels[currentPanelIndex].push(row);
|
945
1011
|
}
|
946
|
-
}
|
947
|
-
|
948
|
-
);
|
949
|
-
const
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
message: formatAPIError(res.error)
|
963
|
-
});
|
964
|
-
return { error: res.error };
|
1012
|
+
}
|
1013
|
+
return panels;
|
1014
|
+
}, []);
|
1015
|
+
const componentEditAttributes = Object.entries(data.components).reduce(
|
1016
|
+
(acc, [uid, configuration]) => {
|
1017
|
+
acc[uid] = {
|
1018
|
+
layout: convertEditLayoutToFieldLayouts(
|
1019
|
+
configuration.layouts.edit,
|
1020
|
+
components[uid].attributes,
|
1021
|
+
configuration.metadatas,
|
1022
|
+
{ configurations: data.components, schemas: components }
|
1023
|
+
),
|
1024
|
+
settings: {
|
1025
|
+
...configuration.settings,
|
1026
|
+
icon: components[uid].info.icon,
|
1027
|
+
displayName: components[uid].info.displayName
|
965
1028
|
}
|
966
|
-
|
967
|
-
|
968
|
-
title: formatMessage({
|
969
|
-
id: getTranslation("success.records.delete"),
|
970
|
-
defaultMessage: "Successfully deleted."
|
971
|
-
}),
|
972
|
-
message: ""
|
973
|
-
});
|
974
|
-
trackUsage("didBulkDeleteEntries");
|
975
|
-
return res.data;
|
976
|
-
} catch (err) {
|
977
|
-
toggleNotification({
|
978
|
-
type: "danger",
|
979
|
-
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
980
|
-
});
|
981
|
-
trackUsage("didNotBulkDeleteEntries");
|
982
|
-
throw err;
|
983
|
-
}
|
1029
|
+
};
|
1030
|
+
return acc;
|
984
1031
|
},
|
985
|
-
|
1032
|
+
{}
|
986
1033
|
);
|
987
|
-
const
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
model,
|
994
|
-
documentId,
|
995
|
-
params
|
996
|
-
});
|
997
|
-
if ("error" in res) {
|
998
|
-
toggleNotification({
|
999
|
-
type: "danger",
|
1000
|
-
message: formatAPIError(res.error)
|
1001
|
-
});
|
1002
|
-
return { error: res.error };
|
1003
|
-
}
|
1004
|
-
toggleNotification({
|
1005
|
-
type: "success",
|
1006
|
-
message: formatMessage({
|
1007
|
-
id: "content-manager.success.record.discard",
|
1008
|
-
defaultMessage: "Changes discarded"
|
1009
|
-
})
|
1010
|
-
});
|
1011
|
-
return res.data;
|
1012
|
-
} catch (err) {
|
1013
|
-
toggleNotification({
|
1014
|
-
type: "danger",
|
1015
|
-
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1016
|
-
});
|
1017
|
-
throw err;
|
1018
|
-
}
|
1034
|
+
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1035
|
+
(acc, [attribute, metadata]) => {
|
1036
|
+
return {
|
1037
|
+
...acc,
|
1038
|
+
[attribute]: metadata.edit
|
1039
|
+
};
|
1019
1040
|
},
|
1020
|
-
|
1041
|
+
{}
|
1021
1042
|
);
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
defaultMessage: "Published document"
|
1044
|
-
})
|
1045
|
-
});
|
1046
|
-
return res.data;
|
1047
|
-
} catch (err) {
|
1048
|
-
toggleNotification({
|
1049
|
-
type: "danger",
|
1050
|
-
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1051
|
-
});
|
1052
|
-
throw err;
|
1043
|
+
return {
|
1044
|
+
layout: panelledEditAttributes,
|
1045
|
+
components: componentEditAttributes,
|
1046
|
+
metadatas: editMetadatas,
|
1047
|
+
settings: {
|
1048
|
+
...data.contentType.settings,
|
1049
|
+
displayName: schema?.info.displayName
|
1050
|
+
},
|
1051
|
+
options: {
|
1052
|
+
...schema?.options,
|
1053
|
+
...schema?.pluginOptions,
|
1054
|
+
...data.contentType.options
|
1055
|
+
}
|
1056
|
+
};
|
1057
|
+
};
|
1058
|
+
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
1059
|
+
return rows.map(
|
1060
|
+
(row) => row.map((field) => {
|
1061
|
+
const attribute = attributes[field.name];
|
1062
|
+
if (!attribute) {
|
1063
|
+
return null;
|
1053
1064
|
}
|
1065
|
+
const { edit: metadata } = metadatas[field.name];
|
1066
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1067
|
+
return {
|
1068
|
+
attribute,
|
1069
|
+
disabled: !metadata.editable,
|
1070
|
+
hint: metadata.description,
|
1071
|
+
label: metadata.label ?? "",
|
1072
|
+
name: field.name,
|
1073
|
+
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
1074
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1075
|
+
schemas,
|
1076
|
+
components: components?.schemas ?? {}
|
1077
|
+
}),
|
1078
|
+
placeholder: metadata.placeholder ?? "",
|
1079
|
+
required: attribute.required ?? false,
|
1080
|
+
size: field.size,
|
1081
|
+
unique: "unique" in attribute ? attribute.unique : false,
|
1082
|
+
visible: metadata.visible ?? true,
|
1083
|
+
type: attribute.type
|
1084
|
+
};
|
1085
|
+
}).filter((field) => field !== null)
|
1086
|
+
);
|
1087
|
+
};
|
1088
|
+
const formatListLayout = (data, {
|
1089
|
+
schemas,
|
1090
|
+
schema,
|
1091
|
+
components
|
1092
|
+
}) => {
|
1093
|
+
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1094
|
+
(acc, [attribute, metadata]) => {
|
1095
|
+
return {
|
1096
|
+
...acc,
|
1097
|
+
[attribute]: metadata.list
|
1098
|
+
};
|
1054
1099
|
},
|
1055
|
-
|
1100
|
+
{}
|
1056
1101
|
);
|
1057
|
-
const
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1102
|
+
const listAttributes = convertListLayoutToFieldLayouts(
|
1103
|
+
data.contentType.layouts.list,
|
1104
|
+
schema?.attributes,
|
1105
|
+
listMetadatas,
|
1106
|
+
{ configurations: data.components, schemas: components },
|
1107
|
+
schemas
|
1108
|
+
);
|
1109
|
+
return {
|
1110
|
+
layout: listAttributes,
|
1111
|
+
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
1112
|
+
metadatas: listMetadatas,
|
1113
|
+
options: {
|
1114
|
+
...schema?.options,
|
1115
|
+
...schema?.pluginOptions,
|
1116
|
+
...data.contentType.options
|
1117
|
+
}
|
1118
|
+
};
|
1119
|
+
};
|
1120
|
+
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
1121
|
+
return columns.map((name) => {
|
1122
|
+
const attribute = attributes[name];
|
1123
|
+
if (!attribute) {
|
1124
|
+
return null;
|
1125
|
+
}
|
1126
|
+
const metadata = metadatas[name];
|
1127
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1128
|
+
return {
|
1129
|
+
attribute,
|
1130
|
+
label: metadata.label ?? "",
|
1131
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1132
|
+
schemas,
|
1133
|
+
components: components?.schemas ?? {}
|
1134
|
+
}),
|
1135
|
+
name,
|
1136
|
+
searchable: metadata.searchable ?? true,
|
1137
|
+
sortable: metadata.sortable ?? true
|
1138
|
+
};
|
1139
|
+
}).filter((field) => field !== null);
|
1140
|
+
};
|
1141
|
+
const useDocument = (args, opts) => {
|
1142
|
+
const { toggleNotification } = strapiAdmin.useNotification();
|
1143
|
+
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
1144
|
+
const {
|
1145
|
+
currentData: data,
|
1146
|
+
isLoading: isLoadingDocument,
|
1147
|
+
isFetching: isFetchingDocument,
|
1148
|
+
error
|
1149
|
+
} = useGetDocumentQuery(args, {
|
1150
|
+
...opts,
|
1151
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
1152
|
+
});
|
1153
|
+
const {
|
1154
|
+
components,
|
1155
|
+
schema,
|
1156
|
+
schemas,
|
1157
|
+
isLoading: isLoadingSchema
|
1158
|
+
} = useContentTypeSchema(args.model);
|
1159
|
+
React__namespace.useEffect(() => {
|
1160
|
+
if (error) {
|
1161
|
+
toggleNotification({
|
1162
|
+
type: "danger",
|
1163
|
+
message: formatAPIError(error)
|
1164
|
+
});
|
1165
|
+
}
|
1166
|
+
}, [toggleNotification, error, formatAPIError, args.collectionType]);
|
1167
|
+
const validationSchema = React__namespace.useMemo(() => {
|
1168
|
+
if (!schema) {
|
1169
|
+
return null;
|
1170
|
+
}
|
1171
|
+
return createYupSchema(schema.attributes, components);
|
1172
|
+
}, [schema, components]);
|
1173
|
+
const validate = React__namespace.useCallback(
|
1174
|
+
(document) => {
|
1175
|
+
if (!validationSchema) {
|
1176
|
+
throw new Error(
|
1177
|
+
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
1178
|
+
);
|
1179
|
+
}
|
1180
|
+
try {
|
1181
|
+
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
1182
|
+
return null;
|
1183
|
+
} catch (error2) {
|
1184
|
+
if (error2 instanceof yup.ValidationError) {
|
1185
|
+
return strapiAdmin.getYupValidationErrors(error2);
|
1186
|
+
}
|
1187
|
+
throw error2;
|
1084
1188
|
}
|
1085
1189
|
},
|
1086
|
-
[
|
1087
|
-
// trackUsage,
|
1088
|
-
publishManyDocuments,
|
1089
|
-
toggleNotification,
|
1090
|
-
formatMessage,
|
1091
|
-
formatAPIError
|
1092
|
-
]
|
1190
|
+
[validationSchema]
|
1093
1191
|
);
|
1094
|
-
const
|
1095
|
-
const
|
1096
|
-
|
1192
|
+
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
1193
|
+
const hasError = !!error;
|
1194
|
+
return {
|
1195
|
+
components,
|
1196
|
+
document: data?.data,
|
1197
|
+
meta: data?.meta,
|
1198
|
+
isLoading,
|
1199
|
+
hasError,
|
1200
|
+
schema,
|
1201
|
+
schemas,
|
1202
|
+
validate
|
1203
|
+
};
|
1204
|
+
};
|
1205
|
+
const useDoc = () => {
|
1206
|
+
const { id, slug, collectionType, origin } = reactRouterDom.useParams();
|
1207
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
1208
|
+
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
1209
|
+
if (!collectionType) {
|
1210
|
+
throw new Error("Could not find collectionType in url params");
|
1211
|
+
}
|
1212
|
+
if (!slug) {
|
1213
|
+
throw new Error("Could not find model in url params");
|
1214
|
+
}
|
1215
|
+
const document = useDocument(
|
1216
|
+
{ documentId: origin || id, model: slug, collectionType, params },
|
1217
|
+
{
|
1218
|
+
skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
|
1219
|
+
}
|
1220
|
+
);
|
1221
|
+
const returnId = origin || id === "create" ? void 0 : id;
|
1222
|
+
return {
|
1223
|
+
collectionType,
|
1224
|
+
model: slug,
|
1225
|
+
id: returnId,
|
1226
|
+
...document
|
1227
|
+
};
|
1228
|
+
};
|
1229
|
+
const useContentManagerContext = () => {
|
1230
|
+
const {
|
1231
|
+
collectionType,
|
1232
|
+
model,
|
1233
|
+
id,
|
1234
|
+
components,
|
1235
|
+
isLoading: isLoadingDoc,
|
1236
|
+
schema,
|
1237
|
+
schemas
|
1238
|
+
} = useDoc();
|
1239
|
+
const layout = useDocumentLayout(model);
|
1240
|
+
const form = strapiAdmin.useForm("useContentManagerContext", (state) => state);
|
1241
|
+
const isSingleType = collectionType === SINGLE_TYPES;
|
1242
|
+
const slug = model;
|
1243
|
+
const isCreatingEntry = id === "create";
|
1244
|
+
useContentTypeSchema();
|
1245
|
+
const isLoading = isLoadingDoc || layout.isLoading;
|
1246
|
+
const error = layout.error;
|
1247
|
+
return {
|
1248
|
+
error,
|
1249
|
+
isLoading,
|
1250
|
+
// Base metadata
|
1251
|
+
model,
|
1252
|
+
collectionType,
|
1253
|
+
id,
|
1254
|
+
slug,
|
1255
|
+
isCreatingEntry,
|
1256
|
+
isSingleType,
|
1257
|
+
hasDraftAndPublish: schema?.options?.draftAndPublish ?? false,
|
1258
|
+
// All schema infos
|
1259
|
+
components,
|
1260
|
+
contentType: schema,
|
1261
|
+
contentTypes: schemas,
|
1262
|
+
// Form state
|
1263
|
+
form,
|
1264
|
+
// layout infos
|
1265
|
+
layout
|
1266
|
+
};
|
1267
|
+
};
|
1268
|
+
const prefixPluginTranslations = (trad, pluginId) => {
|
1269
|
+
return Object.keys(trad).reduce((acc, current) => {
|
1270
|
+
acc[`${pluginId}.${current}`] = trad[current];
|
1271
|
+
return acc;
|
1272
|
+
}, {});
|
1273
|
+
};
|
1274
|
+
const getTranslation = (id) => `content-manager.${id}`;
|
1275
|
+
const DEFAULT_UNEXPECTED_ERROR_MSG = {
|
1276
|
+
id: "notification.error",
|
1277
|
+
defaultMessage: "An error occurred, please try again"
|
1278
|
+
};
|
1279
|
+
const useDocumentActions = () => {
|
1280
|
+
const { toggleNotification } = strapiAdmin.useNotification();
|
1281
|
+
const { formatMessage } = reactIntl.useIntl();
|
1282
|
+
const { trackUsage } = strapiAdmin.useTracking();
|
1283
|
+
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
1284
|
+
const navigate = reactRouterDom.useNavigate();
|
1285
|
+
const setCurrentStep = strapiAdmin.useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
1286
|
+
const [deleteDocument] = useDeleteDocumentMutation();
|
1287
|
+
const _delete = React__namespace.useCallback(
|
1288
|
+
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
1097
1289
|
try {
|
1098
|
-
trackUsage("
|
1099
|
-
const res = await
|
1290
|
+
trackUsage("willDeleteEntry", trackerProperty);
|
1291
|
+
const res = await deleteDocument({
|
1100
1292
|
collectionType,
|
1101
1293
|
model,
|
1102
1294
|
documentId,
|
1103
|
-
data,
|
1104
1295
|
params
|
1105
1296
|
});
|
1106
1297
|
if ("error" in res) {
|
1107
|
-
toggleNotification({
|
1108
|
-
|
1298
|
+
toggleNotification({
|
1299
|
+
type: "danger",
|
1300
|
+
message: formatAPIError(res.error)
|
1301
|
+
});
|
1109
1302
|
return { error: res.error };
|
1110
1303
|
}
|
1111
|
-
trackUsage("didEditEntry", trackerProperty);
|
1112
1304
|
toggleNotification({
|
1113
1305
|
type: "success",
|
1114
1306
|
message: formatMessage({
|
1115
|
-
id: getTranslation("success.record.
|
1116
|
-
defaultMessage: "
|
1307
|
+
id: getTranslation("success.record.delete"),
|
1308
|
+
defaultMessage: "Deleted document"
|
1117
1309
|
})
|
1118
1310
|
});
|
1311
|
+
trackUsage("didDeleteEntry", trackerProperty);
|
1119
1312
|
return res.data;
|
1120
1313
|
} catch (err) {
|
1121
|
-
trackUsage("didNotEditEntry", { error: err, ...trackerProperty });
|
1122
1314
|
toggleNotification({
|
1123
1315
|
type: "danger",
|
1124
1316
|
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1125
1317
|
});
|
1318
|
+
trackUsage("didNotDeleteEntry", { error: err, ...trackerProperty });
|
1126
1319
|
throw err;
|
1127
1320
|
}
|
1128
1321
|
},
|
1129
|
-
[trackUsage,
|
1322
|
+
[trackUsage, deleteDocument, toggleNotification, formatMessage, formatAPIError]
|
1130
1323
|
);
|
1131
|
-
const [
|
1132
|
-
const
|
1133
|
-
async ({
|
1324
|
+
const [deleteManyDocuments] = useDeleteManyDocumentsMutation();
|
1325
|
+
const deleteMany = React__namespace.useCallback(
|
1326
|
+
async ({ model, documentIds, params }) => {
|
1134
1327
|
try {
|
1135
|
-
trackUsage("
|
1136
|
-
const res = await
|
1137
|
-
collectionType,
|
1328
|
+
trackUsage("willBulkDeleteEntries");
|
1329
|
+
const res = await deleteManyDocuments({
|
1138
1330
|
model,
|
1139
|
-
|
1140
|
-
params
|
1141
|
-
data: {
|
1142
|
-
discardDraft
|
1143
|
-
}
|
1331
|
+
documentIds,
|
1332
|
+
params
|
1144
1333
|
});
|
1145
1334
|
if ("error" in res) {
|
1146
|
-
toggleNotification({
|
1335
|
+
toggleNotification({
|
1336
|
+
type: "danger",
|
1337
|
+
message: formatAPIError(res.error)
|
1338
|
+
});
|
1147
1339
|
return { error: res.error };
|
1148
1340
|
}
|
1149
|
-
trackUsage("didUnpublishEntry");
|
1150
1341
|
toggleNotification({
|
1151
1342
|
type: "success",
|
1152
|
-
|
1153
|
-
id: getTranslation("success.
|
1154
|
-
defaultMessage: "
|
1155
|
-
})
|
1343
|
+
title: formatMessage({
|
1344
|
+
id: getTranslation("success.records.delete"),
|
1345
|
+
defaultMessage: "Successfully deleted."
|
1346
|
+
}),
|
1347
|
+
message: ""
|
1156
1348
|
});
|
1349
|
+
trackUsage("didBulkDeleteEntries");
|
1157
1350
|
return res.data;
|
1158
1351
|
} catch (err) {
|
1159
1352
|
toggleNotification({
|
1160
1353
|
type: "danger",
|
1161
1354
|
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1162
1355
|
});
|
1356
|
+
trackUsage("didNotBulkDeleteEntries");
|
1163
1357
|
throw err;
|
1164
1358
|
}
|
1165
1359
|
},
|
1166
|
-
[trackUsage,
|
1360
|
+
[trackUsage, deleteManyDocuments, toggleNotification, formatMessage, formatAPIError]
|
1167
1361
|
);
|
1168
|
-
const [
|
1169
|
-
const
|
1170
|
-
async ({ model,
|
1362
|
+
const [discardDocument] = useDiscardDocumentMutation();
|
1363
|
+
const discard = React__namespace.useCallback(
|
1364
|
+
async ({ collectionType, model, documentId, params }) => {
|
1171
1365
|
try {
|
1172
|
-
|
1173
|
-
|
1366
|
+
const res = await discardDocument({
|
1367
|
+
collectionType,
|
1174
1368
|
model,
|
1175
|
-
|
1369
|
+
documentId,
|
1176
1370
|
params
|
1177
1371
|
});
|
1178
1372
|
if ("error" in res) {
|
1179
|
-
toggleNotification({
|
1373
|
+
toggleNotification({
|
1374
|
+
type: "danger",
|
1375
|
+
message: formatAPIError(res.error)
|
1376
|
+
});
|
1180
1377
|
return { error: res.error };
|
1181
1378
|
}
|
1182
|
-
trackUsage("didBulkUnpublishEntries");
|
1183
1379
|
toggleNotification({
|
1184
1380
|
type: "success",
|
1185
|
-
|
1186
|
-
id:
|
1187
|
-
defaultMessage: "
|
1188
|
-
})
|
1189
|
-
message: ""
|
1381
|
+
message: formatMessage({
|
1382
|
+
id: "content-manager.success.record.discard",
|
1383
|
+
defaultMessage: "Changes discarded"
|
1384
|
+
})
|
1190
1385
|
});
|
1191
1386
|
return res.data;
|
1192
1387
|
} catch (err) {
|
@@ -1194,16 +1389,196 @@ const useDocumentActions = () => {
|
|
1194
1389
|
type: "danger",
|
1195
1390
|
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1196
1391
|
});
|
1197
|
-
trackUsage("didNotBulkUnpublishEntries");
|
1198
1392
|
throw err;
|
1199
1393
|
}
|
1200
1394
|
},
|
1201
|
-
[
|
1395
|
+
[discardDocument, formatAPIError, formatMessage, toggleNotification]
|
1202
1396
|
);
|
1203
|
-
const [
|
1204
|
-
const
|
1205
|
-
async ({ model, params }, data
|
1206
|
-
try {
|
1397
|
+
const [publishDocument] = usePublishDocumentMutation();
|
1398
|
+
const publish = React__namespace.useCallback(
|
1399
|
+
async ({ collectionType, model, documentId, params }, data) => {
|
1400
|
+
try {
|
1401
|
+
trackUsage("willPublishEntry");
|
1402
|
+
const res = await publishDocument({
|
1403
|
+
collectionType,
|
1404
|
+
model,
|
1405
|
+
documentId,
|
1406
|
+
data,
|
1407
|
+
params
|
1408
|
+
});
|
1409
|
+
if ("error" in res) {
|
1410
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1411
|
+
return { error: res.error };
|
1412
|
+
}
|
1413
|
+
trackUsage("didPublishEntry");
|
1414
|
+
toggleNotification({
|
1415
|
+
type: "success",
|
1416
|
+
message: formatMessage({
|
1417
|
+
id: getTranslation("success.record.publish"),
|
1418
|
+
defaultMessage: "Published document"
|
1419
|
+
})
|
1420
|
+
});
|
1421
|
+
return res.data;
|
1422
|
+
} catch (err) {
|
1423
|
+
toggleNotification({
|
1424
|
+
type: "danger",
|
1425
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1426
|
+
});
|
1427
|
+
throw err;
|
1428
|
+
}
|
1429
|
+
},
|
1430
|
+
[trackUsage, publishDocument, toggleNotification, formatMessage, formatAPIError]
|
1431
|
+
);
|
1432
|
+
const [publishManyDocuments] = usePublishManyDocumentsMutation();
|
1433
|
+
const publishMany = React__namespace.useCallback(
|
1434
|
+
async ({ model, documentIds, params }) => {
|
1435
|
+
try {
|
1436
|
+
const res = await publishManyDocuments({
|
1437
|
+
model,
|
1438
|
+
documentIds,
|
1439
|
+
params
|
1440
|
+
});
|
1441
|
+
if ("error" in res) {
|
1442
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1443
|
+
return { error: res.error };
|
1444
|
+
}
|
1445
|
+
toggleNotification({
|
1446
|
+
type: "success",
|
1447
|
+
message: formatMessage({
|
1448
|
+
id: getTranslation("success.record.publish"),
|
1449
|
+
defaultMessage: "Published document"
|
1450
|
+
})
|
1451
|
+
});
|
1452
|
+
return res.data;
|
1453
|
+
} catch (err) {
|
1454
|
+
toggleNotification({
|
1455
|
+
type: "danger",
|
1456
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1457
|
+
});
|
1458
|
+
throw err;
|
1459
|
+
}
|
1460
|
+
},
|
1461
|
+
[
|
1462
|
+
// trackUsage,
|
1463
|
+
publishManyDocuments,
|
1464
|
+
toggleNotification,
|
1465
|
+
formatMessage,
|
1466
|
+
formatAPIError
|
1467
|
+
]
|
1468
|
+
);
|
1469
|
+
const [updateDocument] = useUpdateDocumentMutation();
|
1470
|
+
const update = React__namespace.useCallback(
|
1471
|
+
async ({ collectionType, model, documentId, params }, data, trackerProperty) => {
|
1472
|
+
try {
|
1473
|
+
trackUsage("willEditEntry", trackerProperty);
|
1474
|
+
const res = await updateDocument({
|
1475
|
+
collectionType,
|
1476
|
+
model,
|
1477
|
+
documentId,
|
1478
|
+
data,
|
1479
|
+
params
|
1480
|
+
});
|
1481
|
+
if ("error" in res) {
|
1482
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1483
|
+
trackUsage("didNotEditEntry", { error: res.error, ...trackerProperty });
|
1484
|
+
return { error: res.error };
|
1485
|
+
}
|
1486
|
+
trackUsage("didEditEntry", trackerProperty);
|
1487
|
+
toggleNotification({
|
1488
|
+
type: "success",
|
1489
|
+
message: formatMessage({
|
1490
|
+
id: getTranslation("success.record.save"),
|
1491
|
+
defaultMessage: "Saved document"
|
1492
|
+
})
|
1493
|
+
});
|
1494
|
+
return res.data;
|
1495
|
+
} catch (err) {
|
1496
|
+
trackUsage("didNotEditEntry", { error: err, ...trackerProperty });
|
1497
|
+
toggleNotification({
|
1498
|
+
type: "danger",
|
1499
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1500
|
+
});
|
1501
|
+
throw err;
|
1502
|
+
}
|
1503
|
+
},
|
1504
|
+
[trackUsage, updateDocument, toggleNotification, formatMessage, formatAPIError]
|
1505
|
+
);
|
1506
|
+
const [unpublishDocument] = useUnpublishDocumentMutation();
|
1507
|
+
const unpublish = React__namespace.useCallback(
|
1508
|
+
async ({ collectionType, model, documentId, params }, discardDraft = false) => {
|
1509
|
+
try {
|
1510
|
+
trackUsage("willUnpublishEntry");
|
1511
|
+
const res = await unpublishDocument({
|
1512
|
+
collectionType,
|
1513
|
+
model,
|
1514
|
+
documentId,
|
1515
|
+
params,
|
1516
|
+
data: {
|
1517
|
+
discardDraft
|
1518
|
+
}
|
1519
|
+
});
|
1520
|
+
if ("error" in res) {
|
1521
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1522
|
+
return { error: res.error };
|
1523
|
+
}
|
1524
|
+
trackUsage("didUnpublishEntry");
|
1525
|
+
toggleNotification({
|
1526
|
+
type: "success",
|
1527
|
+
message: formatMessage({
|
1528
|
+
id: getTranslation("success.record.unpublish"),
|
1529
|
+
defaultMessage: "Unpublished document"
|
1530
|
+
})
|
1531
|
+
});
|
1532
|
+
return res.data;
|
1533
|
+
} catch (err) {
|
1534
|
+
toggleNotification({
|
1535
|
+
type: "danger",
|
1536
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1537
|
+
});
|
1538
|
+
throw err;
|
1539
|
+
}
|
1540
|
+
},
|
1541
|
+
[trackUsage, unpublishDocument, toggleNotification, formatMessage, formatAPIError]
|
1542
|
+
);
|
1543
|
+
const [unpublishManyDocuments] = useUnpublishManyDocumentsMutation();
|
1544
|
+
const unpublishMany = React__namespace.useCallback(
|
1545
|
+
async ({ model, documentIds, params }) => {
|
1546
|
+
try {
|
1547
|
+
trackUsage("willBulkUnpublishEntries");
|
1548
|
+
const res = await unpublishManyDocuments({
|
1549
|
+
model,
|
1550
|
+
documentIds,
|
1551
|
+
params
|
1552
|
+
});
|
1553
|
+
if ("error" in res) {
|
1554
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1555
|
+
return { error: res.error };
|
1556
|
+
}
|
1557
|
+
trackUsage("didBulkUnpublishEntries");
|
1558
|
+
toggleNotification({
|
1559
|
+
type: "success",
|
1560
|
+
title: formatMessage({
|
1561
|
+
id: getTranslation("success.records.unpublish"),
|
1562
|
+
defaultMessage: "Successfully unpublished."
|
1563
|
+
}),
|
1564
|
+
message: ""
|
1565
|
+
});
|
1566
|
+
return res.data;
|
1567
|
+
} catch (err) {
|
1568
|
+
toggleNotification({
|
1569
|
+
type: "danger",
|
1570
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1571
|
+
});
|
1572
|
+
trackUsage("didNotBulkUnpublishEntries");
|
1573
|
+
throw err;
|
1574
|
+
}
|
1575
|
+
},
|
1576
|
+
[trackUsage, unpublishManyDocuments, toggleNotification, formatMessage, formatAPIError]
|
1577
|
+
);
|
1578
|
+
const [createDocument] = useCreateDocumentMutation();
|
1579
|
+
const create = React__namespace.useCallback(
|
1580
|
+
async ({ model, params }, data, trackerProperty) => {
|
1581
|
+
try {
|
1207
1582
|
const res = await createDocument({
|
1208
1583
|
model,
|
1209
1584
|
data,
|
@@ -1222,6 +1597,7 @@ const useDocumentActions = () => {
|
|
1222
1597
|
defaultMessage: "Saved document"
|
1223
1598
|
})
|
1224
1599
|
});
|
1600
|
+
setCurrentStep("contentManager.success");
|
1225
1601
|
return res.data;
|
1226
1602
|
} catch (err) {
|
1227
1603
|
toggleNotification({
|
@@ -1323,10 +1699,10 @@ const useDocumentActions = () => {
|
|
1323
1699
|
update
|
1324
1700
|
};
|
1325
1701
|
};
|
1326
|
-
const ProtectedHistoryPage =
|
1327
|
-
() => Promise.resolve().then(() => require("./History-
|
1702
|
+
const ProtectedHistoryPage = React__namespace.lazy(
|
1703
|
+
() => Promise.resolve().then(() => require("./History-CeCDhoJG.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1328
1704
|
);
|
1329
|
-
const routes$
|
1705
|
+
const routes$2 = [
|
1330
1706
|
{
|
1331
1707
|
path: ":collectionType/:slug/:id/history",
|
1332
1708
|
Component: ProtectedHistoryPage
|
@@ -1336,32 +1712,45 @@ const routes$1 = [
|
|
1336
1712
|
Component: ProtectedHistoryPage
|
1337
1713
|
}
|
1338
1714
|
];
|
1715
|
+
const ProtectedPreviewPage = React__namespace.lazy(
|
1716
|
+
() => Promise.resolve().then(() => require("./Preview-CT28Ckpg.js")).then((mod) => ({ default: mod.ProtectedPreviewPage }))
|
1717
|
+
);
|
1718
|
+
const routes$1 = [
|
1719
|
+
{
|
1720
|
+
path: ":collectionType/:slug/:id/preview",
|
1721
|
+
Component: ProtectedPreviewPage
|
1722
|
+
},
|
1723
|
+
{
|
1724
|
+
path: ":collectionType/:slug/preview",
|
1725
|
+
Component: ProtectedPreviewPage
|
1726
|
+
}
|
1727
|
+
];
|
1339
1728
|
const ProtectedEditViewPage = React.lazy(
|
1340
|
-
() => Promise.resolve().then(() => require("./EditViewPage-
|
1729
|
+
() => Promise.resolve().then(() => require("./EditViewPage-BwisF04Q.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1341
1730
|
);
|
1342
1731
|
const ProtectedListViewPage = React.lazy(
|
1343
|
-
() => Promise.resolve().then(() => require("./ListViewPage-
|
1732
|
+
() => Promise.resolve().then(() => require("./ListViewPage-BKTZFhsM.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1344
1733
|
);
|
1345
1734
|
const ProtectedListConfiguration = React.lazy(
|
1346
|
-
() => Promise.resolve().then(() => require("./ListConfigurationPage-
|
1735
|
+
() => Promise.resolve().then(() => require("./ListConfigurationPage-C-bAd44a.js")).then((mod) => ({
|
1347
1736
|
default: mod.ProtectedListConfiguration
|
1348
1737
|
}))
|
1349
1738
|
);
|
1350
1739
|
const ProtectedEditConfigurationPage = React.lazy(
|
1351
|
-
() => Promise.resolve().then(() => require("./EditConfigurationPage-
|
1740
|
+
() => Promise.resolve().then(() => require("./EditConfigurationPage-D2rtvneE.js")).then((mod) => ({
|
1352
1741
|
default: mod.ProtectedEditConfigurationPage
|
1353
1742
|
}))
|
1354
1743
|
);
|
1355
1744
|
const ProtectedComponentConfigurationPage = React.lazy(
|
1356
|
-
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-
|
1745
|
+
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-BSEZcJVB.js")).then((mod) => ({
|
1357
1746
|
default: mod.ProtectedComponentConfigurationPage
|
1358
1747
|
}))
|
1359
1748
|
);
|
1360
1749
|
const NoPermissions = React.lazy(
|
1361
|
-
() => Promise.resolve().then(() => require("./NoPermissionsPage-
|
1750
|
+
() => Promise.resolve().then(() => require("./NoPermissionsPage-CChGWBj5.js")).then((mod) => ({ default: mod.NoPermissions }))
|
1362
1751
|
);
|
1363
1752
|
const NoContentType = React.lazy(
|
1364
|
-
() => Promise.resolve().then(() => require("./NoContentTypePage-
|
1753
|
+
() => Promise.resolve().then(() => require("./NoContentTypePage-D3Cm3v3q.js")).then((mod) => ({ default: mod.NoContentType }))
|
1365
1754
|
);
|
1366
1755
|
const CollectionTypePages = () => {
|
1367
1756
|
const { collectionType } = reactRouterDom.useParams();
|
@@ -1373,7 +1762,7 @@ const CollectionTypePages = () => {
|
|
1373
1762
|
const CLONE_RELATIVE_PATH = ":collectionType/:slug/clone/:origin";
|
1374
1763
|
const CLONE_PATH = `/content-manager/${CLONE_RELATIVE_PATH}`;
|
1375
1764
|
const LIST_RELATIVE_PATH = ":collectionType/:slug";
|
1376
|
-
const LIST_PATH = `/content-manager
|
1765
|
+
const LIST_PATH = `/content-manager/collection-types/:slug`;
|
1377
1766
|
const routes = [
|
1378
1767
|
{
|
1379
1768
|
path: LIST_RELATIVE_PATH,
|
@@ -1407,6 +1796,7 @@ const routes = [
|
|
1407
1796
|
path: "no-content-types",
|
1408
1797
|
Component: NoContentType
|
1409
1798
|
},
|
1799
|
+
...routes$2,
|
1410
1800
|
...routes$1
|
1411
1801
|
];
|
1412
1802
|
const DocumentActions = ({ actions: actions2 }) => {
|
@@ -1505,6 +1895,11 @@ const DocumentActionButton = (action) => {
|
|
1505
1895
|
) : null
|
1506
1896
|
] });
|
1507
1897
|
};
|
1898
|
+
const MenuItem = styledComponents.styled(designSystem.Menu.Item)`
|
1899
|
+
&:hover {
|
1900
|
+
background: ${({ theme, isVariantDanger, isDisabled }) => isVariantDanger && !isDisabled ? theme.colors.danger100 : "neutral"};
|
1901
|
+
}
|
1902
|
+
`;
|
1508
1903
|
const DocumentActionsMenu = ({
|
1509
1904
|
actions: actions2,
|
1510
1905
|
children,
|
@@ -1560,51 +1955,35 @@ const DocumentActionsMenu = ({
|
|
1560
1955
|
]
|
1561
1956
|
}
|
1562
1957
|
),
|
1563
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, {
|
1958
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1564
1959
|
actions2.map((action) => {
|
1565
1960
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
1566
|
-
|
1961
|
+
MenuItem,
|
1567
1962
|
{
|
1568
1963
|
disabled: action.disabled,
|
1569
1964
|
onSelect: handleClick(action),
|
1570
1965
|
display: "block",
|
1571
|
-
|
1572
|
-
|
1573
|
-
|
1574
|
-
|
1575
|
-
|
1576
|
-
|
1577
|
-
|
1578
|
-
|
1579
|
-
|
1580
|
-
|
1581
|
-
|
1582
|
-
|
1583
|
-
|
1584
|
-
|
1585
|
-
|
1586
|
-
|
1587
|
-
|
1588
|
-
|
1589
|
-
|
1590
|
-
|
1591
|
-
|
1592
|
-
designSystem.Flex,
|
1593
|
-
{
|
1594
|
-
alignItems: "center",
|
1595
|
-
background: "alternative100",
|
1596
|
-
borderStyle: "solid",
|
1597
|
-
borderColor: "alternative200",
|
1598
|
-
borderWidth: "1px",
|
1599
|
-
height: 5,
|
1600
|
-
paddingLeft: 2,
|
1601
|
-
paddingRight: 2,
|
1602
|
-
hasRadius: true,
|
1603
|
-
color: "alternative600",
|
1604
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", fontWeight: "bold", lineHeight: 1, children: formatMessage({ id: "global.new", defaultMessage: "New" }) })
|
1605
|
-
}
|
1606
|
-
)
|
1607
|
-
] })
|
1966
|
+
isVariantDanger: action.variant === "danger",
|
1967
|
+
isDisabled: action.disabled,
|
1968
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "space-between", gap: 4, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
1969
|
+
designSystem.Flex,
|
1970
|
+
{
|
1971
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1972
|
+
gap: 2,
|
1973
|
+
tag: "span",
|
1974
|
+
children: [
|
1975
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
1976
|
+
designSystem.Flex,
|
1977
|
+
{
|
1978
|
+
tag: "span",
|
1979
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1980
|
+
children: action.icon
|
1981
|
+
}
|
1982
|
+
),
|
1983
|
+
action.label
|
1984
|
+
]
|
1985
|
+
}
|
1986
|
+
) })
|
1608
1987
|
},
|
1609
1988
|
action.id
|
1610
1989
|
);
|
@@ -1684,11 +2063,11 @@ const DocumentActionConfirmDialog = ({
|
|
1684
2063
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
1685
2064
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: content }),
|
1686
2065
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
|
1687
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", children: formatMessage({
|
2066
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", fullWidth: true, children: formatMessage({
|
1688
2067
|
id: "app.components.Button.cancel",
|
1689
2068
|
defaultMessage: "Cancel"
|
1690
2069
|
}) }) }),
|
1691
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, children: formatMessage({
|
2070
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
|
1692
2071
|
id: "app.components.Button.confirm",
|
1693
2072
|
defaultMessage: "Confirm"
|
1694
2073
|
}) })
|
@@ -1715,6 +2094,18 @@ const DocumentActionModal = ({
|
|
1715
2094
|
typeof Footer === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Footer, { onClose: handleClose }) : Footer
|
1716
2095
|
] }) });
|
1717
2096
|
};
|
2097
|
+
const transformData = (data) => {
|
2098
|
+
if (Array.isArray(data)) {
|
2099
|
+
return data.map(transformData);
|
2100
|
+
}
|
2101
|
+
if (typeof data === "object" && data !== null) {
|
2102
|
+
if ("apiData" in data) {
|
2103
|
+
return data.apiData;
|
2104
|
+
}
|
2105
|
+
return mapValues__default.default(transformData)(data);
|
2106
|
+
}
|
2107
|
+
return data;
|
2108
|
+
};
|
1718
2109
|
const PublishAction$1 = ({
|
1719
2110
|
activeTab,
|
1720
2111
|
documentId,
|
@@ -1729,6 +2120,7 @@ const PublishAction$1 = ({
|
|
1729
2120
|
const { _unstableFormatValidationErrors: formatValidationErrors } = strapiAdmin.useAPIErrorHandler();
|
1730
2121
|
const isListView = reactRouterDom.useMatch(LIST_PATH) !== null;
|
1731
2122
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2123
|
+
const { id } = reactRouterDom.useParams();
|
1732
2124
|
const { formatMessage } = reactIntl.useIntl();
|
1733
2125
|
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1734
2126
|
const { publish } = useDocumentActions();
|
@@ -1808,7 +2200,9 @@ const PublishAction$1 = ({
|
|
1808
2200
|
const performPublish = async () => {
|
1809
2201
|
setSubmitting(true);
|
1810
2202
|
try {
|
1811
|
-
const { errors } = await validate(
|
2203
|
+
const { errors } = await validate(true, {
|
2204
|
+
status: "published"
|
2205
|
+
});
|
1812
2206
|
if (errors) {
|
1813
2207
|
toggleNotification({
|
1814
2208
|
type: "danger",
|
@@ -1826,13 +2220,15 @@ const PublishAction$1 = ({
|
|
1826
2220
|
documentId,
|
1827
2221
|
params
|
1828
2222
|
},
|
1829
|
-
formValues
|
2223
|
+
transformData(formValues)
|
1830
2224
|
);
|
1831
2225
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1832
|
-
|
1833
|
-
|
1834
|
-
|
1835
|
-
|
2226
|
+
if (id === "create") {
|
2227
|
+
navigate({
|
2228
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
2229
|
+
search: rawQuery
|
2230
|
+
});
|
2231
|
+
}
|
1836
2232
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1837
2233
|
setErrors(formatValidationErrors(res.error));
|
1838
2234
|
}
|
@@ -1885,6 +2281,7 @@ const PublishAction$1 = ({
|
|
1885
2281
|
};
|
1886
2282
|
};
|
1887
2283
|
PublishAction$1.type = "publish";
|
2284
|
+
PublishAction$1.position = "panel";
|
1888
2285
|
const UpdateAction = ({
|
1889
2286
|
activeTab,
|
1890
2287
|
documentId,
|
@@ -1907,96 +2304,134 @@ const UpdateAction = ({
|
|
1907
2304
|
const validate = strapiAdmin.useForm("UpdateAction", (state) => state.validate);
|
1908
2305
|
const setErrors = strapiAdmin.useForm("UpdateAction", (state) => state.setErrors);
|
1909
2306
|
const resetForm = strapiAdmin.useForm("PublishAction", ({ resetForm: resetForm2 }) => resetForm2);
|
1910
|
-
|
1911
|
-
|
1912
|
-
|
1913
|
-
|
1914
|
-
|
1915
|
-
|
1916
|
-
|
1917
|
-
|
1918
|
-
|
1919
|
-
|
1920
|
-
|
1921
|
-
|
1922
|
-
|
1923
|
-
|
1924
|
-
|
1925
|
-
|
1926
|
-
|
1927
|
-
|
1928
|
-
|
1929
|
-
|
1930
|
-
|
1931
|
-
|
1932
|
-
|
1933
|
-
|
1934
|
-
|
1935
|
-
|
1936
|
-
|
1937
|
-
|
1938
|
-
if (
|
1939
|
-
|
1940
|
-
{
|
1941
|
-
model,
|
1942
|
-
documentId: cloneMatch.params.origin,
|
1943
|
-
params
|
1944
|
-
},
|
1945
|
-
document
|
1946
|
-
);
|
1947
|
-
if ("data" in res) {
|
1948
|
-
navigate(
|
1949
|
-
{
|
1950
|
-
pathname: `../${res.data.documentId}`,
|
1951
|
-
search: rawQuery
|
1952
|
-
},
|
1953
|
-
{ relative: "path" }
|
1954
|
-
);
|
1955
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1956
|
-
setErrors(formatValidationErrors(res.error));
|
1957
|
-
}
|
1958
|
-
} else if (documentId || collectionType === SINGLE_TYPES) {
|
1959
|
-
const res = await update(
|
2307
|
+
const handleUpdate = React__namespace.useCallback(async () => {
|
2308
|
+
setSubmitting(true);
|
2309
|
+
try {
|
2310
|
+
if (!modified) {
|
2311
|
+
return;
|
2312
|
+
}
|
2313
|
+
const { errors } = await validate(true, {
|
2314
|
+
status: "draft"
|
2315
|
+
});
|
2316
|
+
if (errors) {
|
2317
|
+
toggleNotification({
|
2318
|
+
type: "danger",
|
2319
|
+
message: formatMessage({
|
2320
|
+
id: "content-manager.validation.error",
|
2321
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2322
|
+
})
|
2323
|
+
});
|
2324
|
+
return;
|
2325
|
+
}
|
2326
|
+
if (isCloning) {
|
2327
|
+
const res = await clone(
|
2328
|
+
{
|
2329
|
+
model,
|
2330
|
+
documentId: cloneMatch.params.origin,
|
2331
|
+
params
|
2332
|
+
},
|
2333
|
+
transformData(document)
|
2334
|
+
);
|
2335
|
+
if ("data" in res) {
|
2336
|
+
navigate(
|
1960
2337
|
{
|
1961
|
-
|
1962
|
-
|
1963
|
-
documentId,
|
1964
|
-
params
|
2338
|
+
pathname: `../${res.data.documentId}`,
|
2339
|
+
search: rawQuery
|
1965
2340
|
},
|
1966
|
-
|
2341
|
+
{ relative: "path" }
|
1967
2342
|
);
|
1968
|
-
|
1969
|
-
|
1970
|
-
|
1971
|
-
|
1972
|
-
|
2343
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2344
|
+
setErrors(formatValidationErrors(res.error));
|
2345
|
+
}
|
2346
|
+
} else if (documentId || collectionType === SINGLE_TYPES) {
|
2347
|
+
const res = await update(
|
2348
|
+
{
|
2349
|
+
collectionType,
|
2350
|
+
model,
|
2351
|
+
documentId,
|
2352
|
+
params
|
2353
|
+
},
|
2354
|
+
transformData(document)
|
2355
|
+
);
|
2356
|
+
if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2357
|
+
setErrors(formatValidationErrors(res.error));
|
1973
2358
|
} else {
|
1974
|
-
|
2359
|
+
resetForm();
|
2360
|
+
}
|
2361
|
+
} else {
|
2362
|
+
const res = await create(
|
2363
|
+
{
|
2364
|
+
model,
|
2365
|
+
params
|
2366
|
+
},
|
2367
|
+
transformData(document)
|
2368
|
+
);
|
2369
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
2370
|
+
navigate(
|
1975
2371
|
{
|
1976
|
-
|
1977
|
-
|
2372
|
+
pathname: `../${res.data.documentId}`,
|
2373
|
+
search: rawQuery
|
1978
2374
|
},
|
1979
|
-
|
2375
|
+
{ replace: true, relative: "path" }
|
1980
2376
|
);
|
1981
|
-
|
1982
|
-
|
1983
|
-
{
|
1984
|
-
pathname: `../${res.data.documentId}`,
|
1985
|
-
search: rawQuery
|
1986
|
-
},
|
1987
|
-
{ replace: true, relative: "path" }
|
1988
|
-
);
|
1989
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1990
|
-
setErrors(formatValidationErrors(res.error));
|
1991
|
-
}
|
2377
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2378
|
+
setErrors(formatValidationErrors(res.error));
|
1992
2379
|
}
|
1993
|
-
} finally {
|
1994
|
-
setSubmitting(false);
|
1995
2380
|
}
|
2381
|
+
} finally {
|
2382
|
+
setSubmitting(false);
|
1996
2383
|
}
|
2384
|
+
}, [
|
2385
|
+
clone,
|
2386
|
+
cloneMatch?.params.origin,
|
2387
|
+
collectionType,
|
2388
|
+
create,
|
2389
|
+
document,
|
2390
|
+
documentId,
|
2391
|
+
formatMessage,
|
2392
|
+
formatValidationErrors,
|
2393
|
+
isCloning,
|
2394
|
+
model,
|
2395
|
+
modified,
|
2396
|
+
navigate,
|
2397
|
+
params,
|
2398
|
+
rawQuery,
|
2399
|
+
resetForm,
|
2400
|
+
setErrors,
|
2401
|
+
setSubmitting,
|
2402
|
+
toggleNotification,
|
2403
|
+
update,
|
2404
|
+
validate
|
2405
|
+
]);
|
2406
|
+
React__namespace.useEffect(() => {
|
2407
|
+
const handleKeyDown = (e) => {
|
2408
|
+
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
|
2409
|
+
e.preventDefault();
|
2410
|
+
handleUpdate();
|
2411
|
+
}
|
2412
|
+
};
|
2413
|
+
window.addEventListener("keydown", handleKeyDown);
|
2414
|
+
return () => {
|
2415
|
+
window.removeEventListener("keydown", handleKeyDown);
|
2416
|
+
};
|
2417
|
+
}, [handleUpdate]);
|
2418
|
+
return {
|
2419
|
+
/**
|
2420
|
+
* Disabled when:
|
2421
|
+
* - the form is submitting
|
2422
|
+
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
2423
|
+
* - the active tab is the published tab
|
2424
|
+
*/
|
2425
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
2426
|
+
label: formatMessage({
|
2427
|
+
id: "global.save",
|
2428
|
+
defaultMessage: "Save"
|
2429
|
+
}),
|
2430
|
+
onClick: handleUpdate
|
1997
2431
|
};
|
1998
2432
|
};
|
1999
2433
|
UpdateAction.type = "update";
|
2434
|
+
UpdateAction.position = "panel";
|
2000
2435
|
const UNPUBLISH_DRAFT_OPTIONS = {
|
2001
2436
|
KEEP: "keep",
|
2002
2437
|
DISCARD: "discard"
|
@@ -2119,6 +2554,7 @@ const UnpublishAction$1 = ({
|
|
2119
2554
|
};
|
2120
2555
|
};
|
2121
2556
|
UnpublishAction$1.type = "unpublish";
|
2557
|
+
UnpublishAction$1.position = "panel";
|
2122
2558
|
const DiscardAction = ({
|
2123
2559
|
activeTab,
|
2124
2560
|
documentId,
|
@@ -2169,6 +2605,7 @@ const DiscardAction = ({
|
|
2169
2605
|
};
|
2170
2606
|
};
|
2171
2607
|
DiscardAction.type = "discard";
|
2608
|
+
DiscardAction.position = "panel";
|
2172
2609
|
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2173
2610
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2174
2611
|
const RelativeTime = React__namespace.forwardRef(
|
@@ -2181,7 +2618,7 @@ const RelativeTime = React__namespace.forwardRef(
|
|
2181
2618
|
});
|
2182
2619
|
const unit = intervals.find((intervalUnit) => {
|
2183
2620
|
return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
|
2184
|
-
});
|
2621
|
+
}) ?? "seconds";
|
2185
2622
|
const relativeTime = dateFns.isPast(timestamp) ? -interval[unit] : interval[unit];
|
2186
2623
|
const customInterval = customIntervals.find(
|
2187
2624
|
(custom) => interval[custom.unit] < custom.threshold
|
@@ -2215,19 +2652,29 @@ const getDisplayName = ({
|
|
2215
2652
|
return email ?? "";
|
2216
2653
|
};
|
2217
2654
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2218
|
-
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2219
|
-
const statusVariant = status === "draft" ? "
|
2220
|
-
|
2655
|
+
const DocumentStatus = ({ status = "draft", size = "S", ...restProps }) => {
|
2656
|
+
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2657
|
+
const { formatMessage } = reactIntl.useIntl();
|
2658
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Status, { ...restProps, size, variant: statusVariant, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: formatMessage({
|
2659
|
+
id: `content-manager.containers.List.${status}`,
|
2660
|
+
defaultMessage: capitalise(status)
|
2661
|
+
}) }) });
|
2221
2662
|
};
|
2222
2663
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
2223
2664
|
const { formatMessage } = reactIntl.useIntl();
|
2224
2665
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2666
|
+
const params = reactRouterDom.useParams();
|
2225
2667
|
const title = isCreating ? formatMessage({
|
2226
2668
|
id: "content-manager.containers.edit.title.new",
|
2227
2669
|
defaultMessage: "Create an entry"
|
2228
2670
|
}) : documentTitle;
|
2229
2671
|
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2230
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
2672
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
2673
|
+
strapiAdmin.BackButton,
|
2674
|
+
{
|
2675
|
+
fallback: params.collectionType === SINGLE_TYPES ? void 0 : `../${COLLECTION_TYPES}/${params.slug}`
|
2676
|
+
}
|
2677
|
+
),
|
2231
2678
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2232
2679
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
|
2233
2680
|
/* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
|
@@ -2278,7 +2725,7 @@ const HeaderToolbar = () => {
|
|
2278
2725
|
meta: isCloning ? void 0 : meta,
|
2279
2726
|
collectionType
|
2280
2727
|
},
|
2281
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2728
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("header"),
|
2282
2729
|
children: (actions2) => {
|
2283
2730
|
const headerActions = actions2.filter((action) => {
|
2284
2731
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -2315,12 +2762,12 @@ const Information = ({ activeTab }) => {
|
|
2315
2762
|
isDisplayed: !!publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME],
|
2316
2763
|
label: formatMessage({
|
2317
2764
|
id: "content-manager.containers.edit.information.last-published.label",
|
2318
|
-
defaultMessage: "
|
2765
|
+
defaultMessage: "Published"
|
2319
2766
|
}),
|
2320
2767
|
value: formatMessage(
|
2321
2768
|
{
|
2322
2769
|
id: "content-manager.containers.edit.information.last-published.value",
|
2323
|
-
defaultMessage: `
|
2770
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2324
2771
|
},
|
2325
2772
|
{
|
2326
2773
|
time: /* @__PURE__ */ jsxRuntime.jsx(RelativeTime, { timestamp: new Date(publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME]) }),
|
@@ -2333,12 +2780,12 @@ const Information = ({ activeTab }) => {
|
|
2333
2780
|
isDisplayed: !!createAndUpdateDocument?.[UPDATED_AT_ATTRIBUTE_NAME],
|
2334
2781
|
label: formatMessage({
|
2335
2782
|
id: "content-manager.containers.edit.information.last-draft.label",
|
2336
|
-
defaultMessage: "
|
2783
|
+
defaultMessage: "Updated"
|
2337
2784
|
}),
|
2338
2785
|
value: formatMessage(
|
2339
2786
|
{
|
2340
2787
|
id: "content-manager.containers.edit.information.last-draft.value",
|
2341
|
-
defaultMessage: `
|
2788
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2342
2789
|
},
|
2343
2790
|
{
|
2344
2791
|
time: /* @__PURE__ */ jsxRuntime.jsx(
|
@@ -2356,12 +2803,12 @@ const Information = ({ activeTab }) => {
|
|
2356
2803
|
isDisplayed: !!createAndUpdateDocument?.[CREATED_AT_ATTRIBUTE_NAME],
|
2357
2804
|
label: formatMessage({
|
2358
2805
|
id: "content-manager.containers.edit.information.document.label",
|
2359
|
-
defaultMessage: "
|
2806
|
+
defaultMessage: "Created"
|
2360
2807
|
}),
|
2361
2808
|
value: formatMessage(
|
2362
2809
|
{
|
2363
2810
|
id: "content-manager.containers.edit.information.document.value",
|
2364
|
-
defaultMessage: `
|
2811
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2365
2812
|
},
|
2366
2813
|
{
|
2367
2814
|
time: /* @__PURE__ */ jsxRuntime.jsx(
|
@@ -2399,25 +2846,77 @@ const Information = ({ activeTab }) => {
|
|
2399
2846
|
);
|
2400
2847
|
};
|
2401
2848
|
const HeaderActions = ({ actions: actions2 }) => {
|
2402
|
-
|
2403
|
-
|
2849
|
+
const [dialogId, setDialogId] = React__namespace.useState(null);
|
2850
|
+
const handleClick = (action) => async (e) => {
|
2851
|
+
if (!("options" in action)) {
|
2852
|
+
const { onClick = () => false, dialog, id } = action;
|
2853
|
+
const muteDialog = await onClick(e);
|
2854
|
+
if (dialog && !muteDialog) {
|
2855
|
+
e.preventDefault();
|
2856
|
+
setDialogId(id);
|
2857
|
+
}
|
2858
|
+
}
|
2859
|
+
};
|
2860
|
+
const handleClose = () => {
|
2861
|
+
setDialogId(null);
|
2862
|
+
};
|
2863
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 1, children: actions2.map((action) => {
|
2864
|
+
if (action.options) {
|
2404
2865
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
2405
2866
|
designSystem.SingleSelect,
|
2406
2867
|
{
|
2407
2868
|
size: "S",
|
2408
|
-
disabled: action.disabled,
|
2409
|
-
"aria-label": action.label,
|
2410
2869
|
onChange: action.onSelect,
|
2411
|
-
|
2870
|
+
"aria-label": action.label,
|
2871
|
+
...action,
|
2412
2872
|
children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { ...option, children: label }, option.value))
|
2413
2873
|
},
|
2414
2874
|
action.id
|
2415
2875
|
);
|
2416
2876
|
} else {
|
2417
|
-
|
2877
|
+
if (action.type === "icon") {
|
2878
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
|
2879
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
2880
|
+
designSystem.IconButton,
|
2881
|
+
{
|
2882
|
+
disabled: action.disabled,
|
2883
|
+
label: action.label,
|
2884
|
+
size: "S",
|
2885
|
+
onClick: handleClick(action),
|
2886
|
+
children: action.icon
|
2887
|
+
}
|
2888
|
+
),
|
2889
|
+
action.dialog ? /* @__PURE__ */ jsxRuntime.jsx(
|
2890
|
+
HeaderActionDialog,
|
2891
|
+
{
|
2892
|
+
...action.dialog,
|
2893
|
+
isOpen: dialogId === action.id,
|
2894
|
+
onClose: handleClose
|
2895
|
+
}
|
2896
|
+
) : null
|
2897
|
+
] }, action.id);
|
2898
|
+
}
|
2418
2899
|
}
|
2419
2900
|
}) });
|
2420
2901
|
};
|
2902
|
+
const HeaderActionDialog = ({
|
2903
|
+
onClose,
|
2904
|
+
onCancel,
|
2905
|
+
title,
|
2906
|
+
content: Content,
|
2907
|
+
isOpen
|
2908
|
+
}) => {
|
2909
|
+
const handleClose = async () => {
|
2910
|
+
if (onCancel) {
|
2911
|
+
await onCancel();
|
2912
|
+
}
|
2913
|
+
onClose();
|
2914
|
+
};
|
2915
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
2916
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
2917
|
+
typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : Content
|
2918
|
+
] }) });
|
2919
|
+
};
|
2421
2920
|
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
2422
2921
|
const navigate = reactRouterDom.useNavigate();
|
2423
2922
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2434,6 +2933,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2434
2933
|
};
|
2435
2934
|
};
|
2436
2935
|
ConfigureTheViewAction.type = "configure-the-view";
|
2936
|
+
ConfigureTheViewAction.position = "header";
|
2437
2937
|
const EditTheModelAction = ({ model }) => {
|
2438
2938
|
const navigate = reactRouterDom.useNavigate();
|
2439
2939
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2450,6 +2950,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2450
2950
|
};
|
2451
2951
|
};
|
2452
2952
|
EditTheModelAction.type = "edit-the-model";
|
2953
|
+
EditTheModelAction.position = "header";
|
2453
2954
|
const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
2454
2955
|
const navigate = reactRouterDom.useNavigate();
|
2455
2956
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2458,12 +2959,16 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2458
2959
|
const { delete: deleteAction } = useDocumentActions();
|
2459
2960
|
const { toggleNotification } = strapiAdmin.useNotification();
|
2460
2961
|
const setSubmitting = strapiAdmin.useForm("DeleteAction", (state) => state.setSubmitting);
|
2962
|
+
const isLocalized = document?.locale != null;
|
2461
2963
|
return {
|
2462
2964
|
disabled: !canDelete || !document,
|
2463
|
-
label: formatMessage(
|
2464
|
-
|
2465
|
-
|
2466
|
-
|
2965
|
+
label: formatMessage(
|
2966
|
+
{
|
2967
|
+
id: "content-manager.actions.delete.label",
|
2968
|
+
defaultMessage: "Delete entry{isLocalized, select, true { (all locales)} other {}}"
|
2969
|
+
},
|
2970
|
+
{ isLocalized }
|
2971
|
+
),
|
2467
2972
|
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {}),
|
2468
2973
|
dialog: {
|
2469
2974
|
type: "dialog",
|
@@ -2501,422 +3006,120 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2501
3006
|
model,
|
2502
3007
|
collectionType,
|
2503
3008
|
params: {
|
2504
|
-
locale: "*"
|
2505
|
-
}
|
2506
|
-
});
|
2507
|
-
if (!("error" in res)) {
|
2508
|
-
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
2509
|
-
}
|
2510
|
-
} finally {
|
2511
|
-
if (!listViewPathMatch) {
|
2512
|
-
setSubmitting(false);
|
2513
|
-
}
|
2514
|
-
}
|
2515
|
-
}
|
2516
|
-
},
|
2517
|
-
variant: "danger",
|
2518
|
-
position: ["header", "table-row"]
|
2519
|
-
};
|
2520
|
-
};
|
2521
|
-
DeleteAction$1.type = "delete";
|
2522
|
-
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2523
|
-
const Panels = () => {
|
2524
|
-
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2525
|
-
const [
|
2526
|
-
{
|
2527
|
-
query: { status }
|
2528
|
-
}
|
2529
|
-
] = strapiAdmin.useQueryParams({
|
2530
|
-
status: "draft"
|
2531
|
-
});
|
2532
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2533
|
-
const plugins = strapiAdmin.useStrapiApp("Panels", (state) => state.plugins);
|
2534
|
-
const props = {
|
2535
|
-
activeTab: status,
|
2536
|
-
model,
|
2537
|
-
documentId: id,
|
2538
|
-
document: isCloning ? void 0 : document,
|
2539
|
-
meta: isCloning ? void 0 : meta,
|
2540
|
-
collectionType
|
2541
|
-
};
|
2542
|
-
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
|
2543
|
-
strapiAdmin.DescriptionComponentRenderer,
|
2544
|
-
{
|
2545
|
-
props,
|
2546
|
-
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2547
|
-
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsxRuntime.jsx(Panel, { ...description, children: content }, id2))
|
2548
|
-
}
|
2549
|
-
) });
|
2550
|
-
};
|
2551
|
-
const ActionsPanel = () => {
|
2552
|
-
const { formatMessage } = reactIntl.useIntl();
|
2553
|
-
return {
|
2554
|
-
title: formatMessage({
|
2555
|
-
id: "content-manager.containers.edit.panels.default.title",
|
2556
|
-
defaultMessage: "Document"
|
2557
|
-
}),
|
2558
|
-
content: /* @__PURE__ */ jsxRuntime.jsx(ActionsPanelContent, {})
|
2559
|
-
};
|
2560
|
-
};
|
2561
|
-
ActionsPanel.type = "actions";
|
2562
|
-
const ActionsPanelContent = () => {
|
2563
|
-
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2564
|
-
const [
|
2565
|
-
{
|
2566
|
-
query: { status = "draft" }
|
2567
|
-
}
|
2568
|
-
] = strapiAdmin.useQueryParams();
|
2569
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2570
|
-
const plugins = strapiAdmin.useStrapiApp("ActionsPanel", (state) => state.plugins);
|
2571
|
-
const props = {
|
2572
|
-
activeTab: status,
|
2573
|
-
model,
|
2574
|
-
documentId: id,
|
2575
|
-
document: isCloning ? void 0 : document,
|
2576
|
-
meta: isCloning ? void 0 : meta,
|
2577
|
-
collectionType
|
2578
|
-
};
|
2579
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, width: "100%", children: [
|
2580
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
2581
|
-
strapiAdmin.DescriptionComponentRenderer,
|
2582
|
-
{
|
2583
|
-
props,
|
2584
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2585
|
-
children: (actions2) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActions, { actions: actions2 })
|
2586
|
-
}
|
2587
|
-
),
|
2588
|
-
/* @__PURE__ */ jsxRuntime.jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
2589
|
-
] });
|
2590
|
-
};
|
2591
|
-
const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
2592
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
2593
|
-
designSystem.Flex,
|
2594
|
-
{
|
2595
|
-
ref,
|
2596
|
-
tag: "aside",
|
2597
|
-
"aria-labelledby": "additional-information",
|
2598
|
-
background: "neutral0",
|
2599
|
-
borderColor: "neutral150",
|
2600
|
-
hasRadius: true,
|
2601
|
-
paddingBottom: 4,
|
2602
|
-
paddingLeft: 4,
|
2603
|
-
paddingRight: 4,
|
2604
|
-
paddingTop: 4,
|
2605
|
-
shadow: "tableShadow",
|
2606
|
-
gap: 3,
|
2607
|
-
direction: "column",
|
2608
|
-
justifyContent: "stretch",
|
2609
|
-
alignItems: "flex-start",
|
2610
|
-
children: [
|
2611
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2612
|
-
children
|
2613
|
-
]
|
2614
|
-
}
|
2615
|
-
);
|
2616
|
-
});
|
2617
|
-
const HOOKS = {
|
2618
|
-
/**
|
2619
|
-
* Hook that allows to mutate the displayed headers of the list view table
|
2620
|
-
* @constant
|
2621
|
-
* @type {string}
|
2622
|
-
*/
|
2623
|
-
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2624
|
-
/**
|
2625
|
-
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2626
|
-
* @constant
|
2627
|
-
* @type {string}
|
2628
|
-
*/
|
2629
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2630
|
-
/**
|
2631
|
-
* Hook that allows to mutate the CM's edit view layout
|
2632
|
-
* @constant
|
2633
|
-
* @type {string}
|
2634
|
-
*/
|
2635
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2636
|
-
/**
|
2637
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
2638
|
-
* @constant
|
2639
|
-
* @type {string}
|
2640
|
-
*/
|
2641
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2642
|
-
};
|
2643
|
-
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2644
|
-
endpoints: (builder) => ({
|
2645
|
-
getContentTypeConfiguration: builder.query({
|
2646
|
-
query: (uid) => ({
|
2647
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2648
|
-
method: "GET"
|
2649
|
-
}),
|
2650
|
-
transformResponse: (response) => response.data,
|
2651
|
-
providesTags: (_result, _error, uid) => [
|
2652
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2653
|
-
{ type: "ContentTypeSettings", id: "LIST" }
|
2654
|
-
]
|
2655
|
-
}),
|
2656
|
-
getAllContentTypeSettings: builder.query({
|
2657
|
-
query: () => "/content-manager/content-types-settings",
|
2658
|
-
transformResponse: (response) => response.data,
|
2659
|
-
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2660
|
-
}),
|
2661
|
-
updateContentTypeConfiguration: builder.mutation({
|
2662
|
-
query: ({ uid, ...body }) => ({
|
2663
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2664
|
-
method: "PUT",
|
2665
|
-
data: body
|
2666
|
-
}),
|
2667
|
-
transformResponse: (response) => response.data,
|
2668
|
-
invalidatesTags: (_result, _error, { uid }) => [
|
2669
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2670
|
-
{ type: "ContentTypeSettings", id: "LIST" },
|
2671
|
-
// Is this necessary?
|
2672
|
-
{ type: "InitialData" }
|
2673
|
-
]
|
2674
|
-
})
|
2675
|
-
})
|
2676
|
-
});
|
2677
|
-
const {
|
2678
|
-
useGetContentTypeConfigurationQuery,
|
2679
|
-
useGetAllContentTypeSettingsQuery,
|
2680
|
-
useUpdateContentTypeConfigurationMutation
|
2681
|
-
} = contentTypesApi;
|
2682
|
-
const checkIfAttributeIsDisplayable = (attribute) => {
|
2683
|
-
const { type } = attribute;
|
2684
|
-
if (type === "relation") {
|
2685
|
-
return !attribute.relation.toLowerCase().includes("morph");
|
2686
|
-
}
|
2687
|
-
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2688
|
-
};
|
2689
|
-
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2690
|
-
if (!mainFieldName) {
|
2691
|
-
return void 0;
|
2692
|
-
}
|
2693
|
-
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2694
|
-
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2695
|
-
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2696
|
-
);
|
2697
|
-
return {
|
2698
|
-
name: mainFieldName,
|
2699
|
-
type: mainFieldType ?? "string"
|
2700
|
-
};
|
2701
|
-
};
|
2702
|
-
const DEFAULT_SETTINGS = {
|
2703
|
-
bulkable: false,
|
2704
|
-
filterable: false,
|
2705
|
-
searchable: false,
|
2706
|
-
pagination: false,
|
2707
|
-
defaultSortBy: "",
|
2708
|
-
defaultSortOrder: "asc",
|
2709
|
-
mainField: "id",
|
2710
|
-
pageSize: 10
|
2711
|
-
};
|
2712
|
-
const useDocumentLayout = (model) => {
|
2713
|
-
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2714
|
-
const [{ query }] = strapiAdmin.useQueryParams();
|
2715
|
-
const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2716
|
-
const { toggleNotification } = strapiAdmin.useNotification();
|
2717
|
-
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
2718
|
-
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2719
|
-
const {
|
2720
|
-
data,
|
2721
|
-
isLoading: isLoadingConfigs,
|
2722
|
-
error,
|
2723
|
-
isFetching: isFetchingConfigs
|
2724
|
-
} = useGetContentTypeConfigurationQuery(model);
|
2725
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2726
|
-
React__namespace.useEffect(() => {
|
2727
|
-
if (error) {
|
2728
|
-
toggleNotification({
|
2729
|
-
type: "danger",
|
2730
|
-
message: formatAPIError(error)
|
2731
|
-
});
|
2732
|
-
}
|
2733
|
-
}, [error, formatAPIError, toggleNotification]);
|
2734
|
-
const editLayout = React__namespace.useMemo(
|
2735
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2736
|
-
layout: [],
|
2737
|
-
components: {},
|
2738
|
-
metadatas: {},
|
2739
|
-
options: {},
|
2740
|
-
settings: DEFAULT_SETTINGS
|
2741
|
-
},
|
2742
|
-
[data, isLoading, schemas, schema, components]
|
2743
|
-
);
|
2744
|
-
const listLayout = React__namespace.useMemo(() => {
|
2745
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2746
|
-
layout: [],
|
2747
|
-
metadatas: {},
|
2748
|
-
options: {},
|
2749
|
-
settings: DEFAULT_SETTINGS
|
2750
|
-
};
|
2751
|
-
}, [data, isLoading, schemas, schema, components]);
|
2752
|
-
const { layout: edit } = React__namespace.useMemo(
|
2753
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2754
|
-
layout: editLayout,
|
2755
|
-
query
|
2756
|
-
}),
|
2757
|
-
[editLayout, query, runHookWaterfall]
|
2758
|
-
);
|
2759
|
-
return {
|
2760
|
-
error,
|
2761
|
-
isLoading,
|
2762
|
-
edit,
|
2763
|
-
list: listLayout
|
2764
|
-
};
|
2765
|
-
};
|
2766
|
-
const useDocLayout = () => {
|
2767
|
-
const { model } = useDoc();
|
2768
|
-
return useDocumentLayout(model);
|
2769
|
-
};
|
2770
|
-
const formatEditLayout = (data, {
|
2771
|
-
schemas,
|
2772
|
-
schema,
|
2773
|
-
components
|
2774
|
-
}) => {
|
2775
|
-
let currentPanelIndex = 0;
|
2776
|
-
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2777
|
-
data.contentType.layouts.edit,
|
2778
|
-
schema?.attributes,
|
2779
|
-
data.contentType.metadatas,
|
2780
|
-
{ configurations: data.components, schemas: components },
|
2781
|
-
schemas
|
2782
|
-
).reduce((panels, row) => {
|
2783
|
-
if (row.some((field) => field.type === "dynamiczone")) {
|
2784
|
-
panels.push([row]);
|
2785
|
-
currentPanelIndex += 2;
|
2786
|
-
} else {
|
2787
|
-
if (!panels[currentPanelIndex]) {
|
2788
|
-
panels.push([]);
|
2789
|
-
}
|
2790
|
-
panels[currentPanelIndex].push(row);
|
2791
|
-
}
|
2792
|
-
return panels;
|
2793
|
-
}, []);
|
2794
|
-
const componentEditAttributes = Object.entries(data.components).reduce(
|
2795
|
-
(acc, [uid, configuration]) => {
|
2796
|
-
acc[uid] = {
|
2797
|
-
layout: convertEditLayoutToFieldLayouts(
|
2798
|
-
configuration.layouts.edit,
|
2799
|
-
components[uid].attributes,
|
2800
|
-
configuration.metadatas,
|
2801
|
-
{ configurations: data.components, schemas: components }
|
2802
|
-
),
|
2803
|
-
settings: {
|
2804
|
-
...configuration.settings,
|
2805
|
-
icon: components[uid].info.icon,
|
2806
|
-
displayName: components[uid].info.displayName
|
3009
|
+
locale: "*"
|
3010
|
+
}
|
3011
|
+
});
|
3012
|
+
if (!("error" in res)) {
|
3013
|
+
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
3014
|
+
}
|
3015
|
+
} finally {
|
3016
|
+
if (!listViewPathMatch) {
|
3017
|
+
setSubmitting(false);
|
3018
|
+
}
|
2807
3019
|
}
|
2808
|
-
}
|
2809
|
-
return acc;
|
2810
|
-
},
|
2811
|
-
{}
|
2812
|
-
);
|
2813
|
-
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2814
|
-
(acc, [attribute, metadata]) => {
|
2815
|
-
return {
|
2816
|
-
...acc,
|
2817
|
-
[attribute]: metadata.edit
|
2818
|
-
};
|
2819
|
-
},
|
2820
|
-
{}
|
2821
|
-
);
|
2822
|
-
return {
|
2823
|
-
layout: panelledEditAttributes,
|
2824
|
-
components: componentEditAttributes,
|
2825
|
-
metadatas: editMetadatas,
|
2826
|
-
settings: {
|
2827
|
-
...data.contentType.settings,
|
2828
|
-
displayName: schema?.info.displayName
|
3020
|
+
}
|
2829
3021
|
},
|
2830
|
-
|
2831
|
-
|
2832
|
-
...schema?.pluginOptions,
|
2833
|
-
...data.contentType.options
|
2834
|
-
}
|
3022
|
+
variant: "danger",
|
3023
|
+
position: ["header", "table-row"]
|
2835
3024
|
};
|
2836
3025
|
};
|
2837
|
-
|
2838
|
-
|
2839
|
-
|
2840
|
-
|
2841
|
-
|
2842
|
-
|
2843
|
-
|
2844
|
-
|
2845
|
-
|
2846
|
-
|
2847
|
-
|
2848
|
-
|
2849
|
-
|
2850
|
-
|
2851
|
-
|
2852
|
-
|
2853
|
-
|
2854
|
-
|
2855
|
-
|
2856
|
-
|
2857
|
-
|
2858
|
-
|
2859
|
-
|
2860
|
-
|
2861
|
-
|
2862
|
-
|
2863
|
-
|
2864
|
-
|
2865
|
-
|
3026
|
+
DeleteAction$1.type = "delete";
|
3027
|
+
DeleteAction$1.position = ["header", "table-row"];
|
3028
|
+
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
3029
|
+
const Panels = () => {
|
3030
|
+
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
3031
|
+
const [
|
3032
|
+
{
|
3033
|
+
query: { status }
|
3034
|
+
}
|
3035
|
+
] = strapiAdmin.useQueryParams({
|
3036
|
+
status: "draft"
|
3037
|
+
});
|
3038
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
3039
|
+
const plugins = strapiAdmin.useStrapiApp("Panels", (state) => state.plugins);
|
3040
|
+
const props = {
|
3041
|
+
activeTab: status,
|
3042
|
+
model,
|
3043
|
+
documentId: id,
|
3044
|
+
document: isCloning ? void 0 : document,
|
3045
|
+
meta: isCloning ? void 0 : meta,
|
3046
|
+
collectionType
|
3047
|
+
};
|
3048
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
|
3049
|
+
strapiAdmin.DescriptionComponentRenderer,
|
3050
|
+
{
|
3051
|
+
props,
|
3052
|
+
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
3053
|
+
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsxRuntime.jsx(Panel, { ...description, children: content }, id2))
|
3054
|
+
}
|
3055
|
+
) });
|
2866
3056
|
};
|
2867
|
-
const
|
2868
|
-
|
2869
|
-
schema,
|
2870
|
-
components
|
2871
|
-
}) => {
|
2872
|
-
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2873
|
-
(acc, [attribute, metadata]) => {
|
2874
|
-
return {
|
2875
|
-
...acc,
|
2876
|
-
[attribute]: metadata.list
|
2877
|
-
};
|
2878
|
-
},
|
2879
|
-
{}
|
2880
|
-
);
|
2881
|
-
const listAttributes = convertListLayoutToFieldLayouts(
|
2882
|
-
data.contentType.layouts.list,
|
2883
|
-
schema?.attributes,
|
2884
|
-
listMetadatas,
|
2885
|
-
{ configurations: data.components, schemas: components },
|
2886
|
-
schemas
|
2887
|
-
);
|
3057
|
+
const ActionsPanel = () => {
|
3058
|
+
const { formatMessage } = reactIntl.useIntl();
|
2888
3059
|
return {
|
2889
|
-
|
2890
|
-
|
2891
|
-
|
2892
|
-
|
2893
|
-
|
2894
|
-
...schema?.pluginOptions,
|
2895
|
-
...data.contentType.options
|
2896
|
-
}
|
3060
|
+
title: formatMessage({
|
3061
|
+
id: "content-manager.containers.edit.panels.default.title",
|
3062
|
+
defaultMessage: "Entry"
|
3063
|
+
}),
|
3064
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(ActionsPanelContent, {})
|
2897
3065
|
};
|
2898
3066
|
};
|
2899
|
-
|
2900
|
-
|
2901
|
-
|
2902
|
-
|
2903
|
-
|
3067
|
+
ActionsPanel.type = "actions";
|
3068
|
+
const ActionsPanelContent = () => {
|
3069
|
+
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
3070
|
+
const [
|
3071
|
+
{
|
3072
|
+
query: { status = "draft" }
|
2904
3073
|
}
|
2905
|
-
|
2906
|
-
|
2907
|
-
|
2908
|
-
|
2909
|
-
|
2910
|
-
|
2911
|
-
|
2912
|
-
|
2913
|
-
|
2914
|
-
|
2915
|
-
|
2916
|
-
|
2917
|
-
|
2918
|
-
|
3074
|
+
] = strapiAdmin.useQueryParams();
|
3075
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
3076
|
+
const plugins = strapiAdmin.useStrapiApp("ActionsPanel", (state) => state.plugins);
|
3077
|
+
const props = {
|
3078
|
+
activeTab: status,
|
3079
|
+
model,
|
3080
|
+
documentId: id,
|
3081
|
+
document: isCloning ? void 0 : document,
|
3082
|
+
meta: isCloning ? void 0 : meta,
|
3083
|
+
collectionType
|
3084
|
+
};
|
3085
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, width: "100%", children: [
|
3086
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
3087
|
+
strapiAdmin.DescriptionComponentRenderer,
|
3088
|
+
{
|
3089
|
+
props,
|
3090
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("panel"),
|
3091
|
+
children: (actions2) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActions, { actions: actions2 })
|
3092
|
+
}
|
3093
|
+
),
|
3094
|
+
/* @__PURE__ */ jsxRuntime.jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
3095
|
+
] });
|
2919
3096
|
};
|
3097
|
+
const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
3098
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
3099
|
+
designSystem.Flex,
|
3100
|
+
{
|
3101
|
+
ref,
|
3102
|
+
tag: "aside",
|
3103
|
+
"aria-labelledby": "additional-information",
|
3104
|
+
background: "neutral0",
|
3105
|
+
borderColor: "neutral150",
|
3106
|
+
hasRadius: true,
|
3107
|
+
paddingBottom: 4,
|
3108
|
+
paddingLeft: 4,
|
3109
|
+
paddingRight: 4,
|
3110
|
+
paddingTop: 4,
|
3111
|
+
shadow: "tableShadow",
|
3112
|
+
gap: 3,
|
3113
|
+
direction: "column",
|
3114
|
+
justifyContent: "stretch",
|
3115
|
+
alignItems: "flex-start",
|
3116
|
+
children: [
|
3117
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", textColor: "neutral600", children: title }),
|
3118
|
+
children
|
3119
|
+
]
|
3120
|
+
}
|
3121
|
+
);
|
3122
|
+
});
|
2920
3123
|
const ConfirmBulkActionDialog = ({
|
2921
3124
|
onToggleDialog,
|
2922
3125
|
isOpen = false,
|
@@ -3161,18 +3364,10 @@ const SelectedEntriesTableContent = ({
|
|
3161
3364
|
search: row.locale && `?plugins[i18n][locale]=${row.locale}`
|
3162
3365
|
},
|
3163
3366
|
state: { from: pathname },
|
3164
|
-
label: formatMessage(
|
3165
|
-
|
3166
|
-
|
3167
|
-
|
3168
|
-
{
|
3169
|
-
id: "content-manager.components.ListViewHelperPluginTable.row-line",
|
3170
|
-
defaultMessage: "item line {number}"
|
3171
|
-
},
|
3172
|
-
{ number: index2 + 1 }
|
3173
|
-
)
|
3174
|
-
}
|
3175
|
-
),
|
3367
|
+
label: formatMessage({
|
3368
|
+
id: "content-manager.bulk-publish.edit",
|
3369
|
+
defaultMessage: "Edit"
|
3370
|
+
}),
|
3176
3371
|
target: "_blank",
|
3177
3372
|
marginLeft: "auto",
|
3178
3373
|
variant: "ghost",
|
@@ -3346,8 +3541,7 @@ const PublishAction = ({ documents, model }) => {
|
|
3346
3541
|
const refetchList = () => {
|
3347
3542
|
contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
|
3348
3543
|
};
|
3349
|
-
if (!showPublishButton)
|
3350
|
-
return null;
|
3544
|
+
if (!showPublishButton) return null;
|
3351
3545
|
return {
|
3352
3546
|
actionType: "publish",
|
3353
3547
|
variant: "tertiary",
|
@@ -3415,8 +3609,7 @@ const DeleteAction = ({ documents, model }) => {
|
|
3415
3609
|
selectRow([]);
|
3416
3610
|
}
|
3417
3611
|
};
|
3418
|
-
if (!hasDeletePermission)
|
3419
|
-
return null;
|
3612
|
+
if (!hasDeletePermission) return null;
|
3420
3613
|
return {
|
3421
3614
|
variant: "danger-light",
|
3422
3615
|
label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
|
@@ -3465,8 +3658,7 @@ const UnpublishAction = ({ documents, model }) => {
|
|
3465
3658
|
}
|
3466
3659
|
};
|
3467
3660
|
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
|
3468
|
-
if (!showUnpublishButton)
|
3469
|
-
return null;
|
3661
|
+
if (!showUnpublishButton) return null;
|
3470
3662
|
return {
|
3471
3663
|
variant: "tertiary",
|
3472
3664
|
label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
|
@@ -3571,7 +3763,7 @@ const TableActions = ({ document }) => {
|
|
3571
3763
|
strapiAdmin.DescriptionComponentRenderer,
|
3572
3764
|
{
|
3573
3765
|
props,
|
3574
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
3766
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("table-row").filter((action) => action.name !== "PublishAction"),
|
3575
3767
|
children: (actions2) => {
|
3576
3768
|
const tableRowActions = actions2.filter((action) => {
|
3577
3769
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3630,6 +3822,7 @@ const EditAction = ({ documentId }) => {
|
|
3630
3822
|
};
|
3631
3823
|
};
|
3632
3824
|
EditAction.type = "edit";
|
3825
|
+
EditAction.position = "table-row";
|
3633
3826
|
const StyledPencil = styledComponents.styled(Icons.Pencil)`
|
3634
3827
|
path {
|
3635
3828
|
fill: currentColor;
|
@@ -3706,6 +3899,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3706
3899
|
};
|
3707
3900
|
};
|
3708
3901
|
CloneAction.type = "clone";
|
3902
|
+
CloneAction.position = "table-row";
|
3709
3903
|
const StyledDuplicate = styledComponents.styled(Icons.Duplicate)`
|
3710
3904
|
path {
|
3711
3905
|
fill: currentColor;
|
@@ -3792,7 +3986,14 @@ class ContentManagerPlugin {
|
|
3792
3986
|
addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
|
3793
3987
|
addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
|
3794
3988
|
getBulkActions: () => this.bulkActions,
|
3795
|
-
getDocumentActions: () =>
|
3989
|
+
getDocumentActions: (position) => {
|
3990
|
+
if (position) {
|
3991
|
+
return this.documentActions.filter(
|
3992
|
+
(action) => action.position == void 0 || [action.position].flat().includes(position)
|
3993
|
+
);
|
3994
|
+
}
|
3995
|
+
return this.documentActions;
|
3996
|
+
},
|
3796
3997
|
getEditViewSidePanels: () => this.editViewSidePanels,
|
3797
3998
|
getHeaderActions: () => this.headerActions
|
3798
3999
|
}
|
@@ -3802,10 +4003,8 @@ class ContentManagerPlugin {
|
|
3802
4003
|
const getPrintableType = (value) => {
|
3803
4004
|
const nativeType = typeof value;
|
3804
4005
|
if (nativeType === "object") {
|
3805
|
-
if (value === null)
|
3806
|
-
|
3807
|
-
if (Array.isArray(value))
|
3808
|
-
return "array";
|
4006
|
+
if (value === null) return "null";
|
4007
|
+
if (Array.isArray(value)) return "array";
|
3809
4008
|
if (value instanceof Object && value.constructor.name !== "Object") {
|
3810
4009
|
return value.constructor.name;
|
3811
4010
|
}
|
@@ -3816,17 +4015,27 @@ const HistoryAction = ({ model, document }) => {
|
|
3816
4015
|
const { formatMessage } = reactIntl.useIntl();
|
3817
4016
|
const [{ query }] = strapiAdmin.useQueryParams();
|
3818
4017
|
const navigate = reactRouterDom.useNavigate();
|
4018
|
+
const { trackUsage } = strapiAdmin.useTracking();
|
4019
|
+
const { pathname } = reactRouterDom.useLocation();
|
3819
4020
|
const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
|
3820
4021
|
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3821
4022
|
return null;
|
3822
4023
|
}
|
4024
|
+
const handleOnClick = () => {
|
4025
|
+
const destination = { pathname: "history", search: pluginsQueryParams };
|
4026
|
+
trackUsage("willNavigate", {
|
4027
|
+
from: pathname,
|
4028
|
+
to: `${pathname}/${destination.pathname}`
|
4029
|
+
});
|
4030
|
+
navigate(destination);
|
4031
|
+
};
|
3823
4032
|
return {
|
3824
4033
|
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
|
3825
4034
|
label: formatMessage({
|
3826
4035
|
id: "content-manager.history.document-action",
|
3827
4036
|
defaultMessage: "Content History"
|
3828
4037
|
}),
|
3829
|
-
onClick:
|
4038
|
+
onClick: handleOnClick,
|
3830
4039
|
disabled: (
|
3831
4040
|
/**
|
3832
4041
|
* The user is creating a new document.
|
@@ -3848,6 +4057,7 @@ const HistoryAction = ({ model, document }) => {
|
|
3848
4057
|
};
|
3849
4058
|
};
|
3850
4059
|
HistoryAction.type = "history";
|
4060
|
+
HistoryAction.position = "header";
|
3851
4061
|
const historyAdmin = {
|
3852
4062
|
bootstrap(app) {
|
3853
4063
|
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
@@ -3894,6 +4104,88 @@ const { setInitialData } = actions;
|
|
3894
4104
|
const reducer = toolkit.combineReducers({
|
3895
4105
|
app: reducer$1
|
3896
4106
|
});
|
4107
|
+
const previewApi = contentManagerApi.injectEndpoints({
|
4108
|
+
endpoints: (builder) => ({
|
4109
|
+
getPreviewUrl: builder.query({
|
4110
|
+
query({ query, params }) {
|
4111
|
+
return {
|
4112
|
+
url: `/content-manager/preview/url/${params.contentType}`,
|
4113
|
+
method: "GET",
|
4114
|
+
config: {
|
4115
|
+
params: query
|
4116
|
+
}
|
4117
|
+
};
|
4118
|
+
}
|
4119
|
+
})
|
4120
|
+
})
|
4121
|
+
});
|
4122
|
+
const { useGetPreviewUrlQuery } = previewApi;
|
4123
|
+
const ConditionalTooltip = ({ isShown, label, children }) => {
|
4124
|
+
if (isShown) {
|
4125
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { label, children });
|
4126
|
+
}
|
4127
|
+
return children;
|
4128
|
+
};
|
4129
|
+
const PreviewSidePanel = ({ model, documentId, document }) => {
|
4130
|
+
const { formatMessage } = reactIntl.useIntl();
|
4131
|
+
const { trackUsage } = strapiAdmin.useTracking();
|
4132
|
+
const { pathname } = reactRouterDom.useLocation();
|
4133
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
4134
|
+
const isModified = strapiAdmin.useForm("PreviewSidePanel", (state) => state.modified);
|
4135
|
+
const { data, error } = useGetPreviewUrlQuery({
|
4136
|
+
params: {
|
4137
|
+
contentType: model
|
4138
|
+
},
|
4139
|
+
query: {
|
4140
|
+
documentId,
|
4141
|
+
locale: document?.locale,
|
4142
|
+
status: document?.status
|
4143
|
+
}
|
4144
|
+
});
|
4145
|
+
if (!data?.data?.url || error) {
|
4146
|
+
return null;
|
4147
|
+
}
|
4148
|
+
const trackNavigation = () => {
|
4149
|
+
const destinationPathname = pathname.replace(/\/$/, "") + "/preview";
|
4150
|
+
trackUsage("willNavigate", { from: pathname, to: destinationPathname });
|
4151
|
+
};
|
4152
|
+
return {
|
4153
|
+
title: formatMessage({ id: "content-manager.preview.panel.title", defaultMessage: "Preview" }),
|
4154
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(
|
4155
|
+
ConditionalTooltip,
|
4156
|
+
{
|
4157
|
+
label: formatMessage({
|
4158
|
+
id: "content-manager.preview.panel.button-disabled-tooltip",
|
4159
|
+
defaultMessage: "Please save to open the preview"
|
4160
|
+
}),
|
4161
|
+
isShown: isModified,
|
4162
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { cursor: "not-allowed", width: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(
|
4163
|
+
designSystem.Button,
|
4164
|
+
{
|
4165
|
+
variant: "tertiary",
|
4166
|
+
tag: reactRouterDom.Link,
|
4167
|
+
to: { pathname: "preview", search: qs.stringify(query, { encode: false }) },
|
4168
|
+
onClick: trackNavigation,
|
4169
|
+
width: "100%",
|
4170
|
+
disabled: isModified,
|
4171
|
+
pointerEvents: isModified ? "none" : void 0,
|
4172
|
+
tabIndex: isModified ? -1 : void 0,
|
4173
|
+
children: formatMessage({
|
4174
|
+
id: "content-manager.preview.panel.button",
|
4175
|
+
defaultMessage: "Open preview"
|
4176
|
+
})
|
4177
|
+
}
|
4178
|
+
) })
|
4179
|
+
}
|
4180
|
+
)
|
4181
|
+
};
|
4182
|
+
};
|
4183
|
+
const previewAdmin = {
|
4184
|
+
bootstrap(app) {
|
4185
|
+
const contentManagerPluginApis = app.getPlugin("content-manager").apis;
|
4186
|
+
contentManagerPluginApis.addEditViewSidePanel([PreviewSidePanel]);
|
4187
|
+
}
|
4188
|
+
};
|
3897
4189
|
const index = {
|
3898
4190
|
register(app) {
|
3899
4191
|
const cm = new ContentManagerPlugin();
|
@@ -3913,7 +4205,7 @@ const index = {
|
|
3913
4205
|
app.router.addRoute({
|
3914
4206
|
path: "content-manager/*",
|
3915
4207
|
lazy: async () => {
|
3916
|
-
const { Layout } = await Promise.resolve().then(() => require("./layout-
|
4208
|
+
const { Layout } = await Promise.resolve().then(() => require("./layout-B_qdWGny.js"));
|
3917
4209
|
return {
|
3918
4210
|
Component: Layout
|
3919
4211
|
};
|
@@ -3926,11 +4218,14 @@ const index = {
|
|
3926
4218
|
if (typeof historyAdmin.bootstrap === "function") {
|
3927
4219
|
historyAdmin.bootstrap(app);
|
3928
4220
|
}
|
4221
|
+
if (typeof previewAdmin.bootstrap === "function") {
|
4222
|
+
previewAdmin.bootstrap(app);
|
4223
|
+
}
|
3929
4224
|
},
|
3930
4225
|
async registerTrads({ locales }) {
|
3931
4226
|
const importedTrads = await Promise.all(
|
3932
4227
|
locales.map((locale) => {
|
3933
|
-
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-
|
4228
|
+
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-BK8Xyl5I.js")), "./translations/es.json": () => Promise.resolve().then(() => require("./es-9K52xZIr.js")), "./translations/eu.json": () => Promise.resolve().then(() => require("./eu-VDH-3ovk.js")), "./translations/fr.json": () => Promise.resolve().then(() => require("./fr-B2Kyv8Z9.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-7sfIbjxE.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`, 3).then(({ default: data }) => {
|
3934
4229
|
return {
|
3935
4230
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3936
4231
|
locale
|
@@ -3976,6 +4271,7 @@ exports.getMainField = getMainField;
|
|
3976
4271
|
exports.getTranslation = getTranslation;
|
3977
4272
|
exports.index = index;
|
3978
4273
|
exports.setInitialData = setInitialData;
|
4274
|
+
exports.useContentManagerContext = useContentManagerContext;
|
3979
4275
|
exports.useContentTypeSchema = useContentTypeSchema;
|
3980
4276
|
exports.useDoc = useDoc;
|
3981
4277
|
exports.useDocLayout = useDocLayout;
|
@@ -3987,5 +4283,6 @@ exports.useGetAllContentTypeSettingsQuery = useGetAllContentTypeSettingsQuery;
|
|
3987
4283
|
exports.useGetAllDocumentsQuery = useGetAllDocumentsQuery;
|
3988
4284
|
exports.useGetContentTypeConfigurationQuery = useGetContentTypeConfigurationQuery;
|
3989
4285
|
exports.useGetInitialDataQuery = useGetInitialDataQuery;
|
4286
|
+
exports.useGetPreviewUrlQuery = useGetPreviewUrlQuery;
|
3990
4287
|
exports.useUpdateContentTypeConfigurationMutation = useUpdateContentTypeConfigurationMutation;
|
3991
|
-
//# sourceMappingURL=index-
|
4288
|
+
//# sourceMappingURL=index-CnX_j5h-.js.map
|