@strapi/content-manager 0.0.0-experimental.f31889311d753b5f7d95198ae84d8fce1d156cd6 → 0.0.0-experimental.f49f46a1c17445a39e8af3f63124bcccf73842e6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/{ComponentConfigurationPage-BNxtMIfV.js → ComponentConfigurationPage-ClKl_TA2.js} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-BNxtMIfV.js.map → ComponentConfigurationPage-ClKl_TA2.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-BWOQWCv2.mjs → ComponentConfigurationPage-D3ZWDAHG.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-BWOQWCv2.mjs.map → ComponentConfigurationPage-D3ZWDAHG.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-GTp-Ucnw.mjs → EditConfigurationPage-BYCBSJxP.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-GTp-Ucnw.mjs.map → EditConfigurationPage-BYCBSJxP.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-D340bYlT.js → EditConfigurationPage-OWez0Kxp.js} +4 -4
- package/dist/_chunks/{EditConfigurationPage-D340bYlT.js.map → EditConfigurationPage-OWez0Kxp.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-BVMS5hT-.mjs → EditViewPage-5pdbvsO_.mjs} +63 -12
- package/dist/_chunks/EditViewPage-5pdbvsO_.mjs.map +1 -0
- package/dist/_chunks/{EditViewPage-CXkmnAvI.js → EditViewPage-BEs5iGDi.js} +62 -11
- package/dist/_chunks/EditViewPage-BEs5iGDi.js.map +1 -0
- package/dist/_chunks/{Field-Ibi32diw.js → Field-DNHm4wHx.js} +210 -119
- package/dist/_chunks/Field-DNHm4wHx.js.map +1 -0
- package/dist/_chunks/{Field-nNgv5bpd.mjs → Field-DcKuFHYK.mjs} +208 -117
- package/dist/_chunks/Field-DcKuFHYK.mjs.map +1 -0
- package/dist/_chunks/{Form-DodJsI2A.mjs → Form-CGwM_-5c.mjs} +36 -17
- package/dist/_chunks/Form-CGwM_-5c.mjs.map +1 -0
- package/dist/_chunks/{Form-Dhnh34ym.js → Form-CoRxWJOz.js} +36 -17
- package/dist/_chunks/Form-CoRxWJOz.js.map +1 -0
- package/dist/_chunks/{History-C9auUkDi.js → History-BcUTQrfG.js} +40 -97
- package/dist/_chunks/History-BcUTQrfG.js.map +1 -0
- package/dist/_chunks/{History-CKCSQXz_.mjs → History-DEvr3Q_V.mjs} +42 -99
- package/dist/_chunks/History-DEvr3Q_V.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-Bg4rWUjX.js → ListConfigurationPage-BE_Ho7tV.js} +17 -6
- package/dist/_chunks/ListConfigurationPage-BE_Ho7tV.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-CKEC4ttG.mjs → ListConfigurationPage-BM4zZZcM.mjs} +18 -7
- package/dist/_chunks/ListConfigurationPage-BM4zZZcM.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-B7_WJUjG.mjs → ListViewPage-BK2mkrql.mjs} +65 -39
- package/dist/_chunks/ListViewPage-BK2mkrql.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-C2gIeYHG.js → ListViewPage-BkT8Eao0.js} +68 -42
- package/dist/_chunks/ListViewPage-BkT8Eao0.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-Ckem6Ll6.mjs → NoContentTypePage-BvcAutu9.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-Ckem6Ll6.mjs.map → NoContentTypePage-BvcAutu9.mjs.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-DqgdUfyn.js → NoContentTypePage-C8mtyc4H.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-DqgdUfyn.js.map → NoContentTypePage-C8mtyc4H.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-CF29Q-sW.js → NoPermissionsPage-B5Y9Y78B.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-CF29Q-sW.js.map → NoPermissionsPage-B5Y9Y78B.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-BO-GEjA4.mjs → NoPermissionsPage-BmbRz7PR.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-BO-GEjA4.mjs.map → NoPermissionsPage-BmbRz7PR.mjs.map} +1 -1
- package/dist/_chunks/Preview-BF8ZDYqS.js +286 -0
- package/dist/_chunks/Preview-BF8ZDYqS.js.map +1 -0
- package/dist/_chunks/Preview-DcexhKJE.mjs +267 -0
- package/dist/_chunks/Preview-DcexhKJE.mjs.map +1 -0
- package/dist/_chunks/{Relations-C0uC9J4f.js → Relations-BKnoK1R0.js} +72 -36
- package/dist/_chunks/Relations-BKnoK1R0.js.map +1 -0
- package/dist/_chunks/{Relations-DItV5eow.mjs → Relations-BjIzc4EK.mjs} +73 -37
- package/dist/_chunks/Relations-BjIzc4EK.mjs.map +1 -0
- package/dist/_chunks/{en-BrCTWlZv.mjs → en-CfIXaZf9.mjs} +26 -14
- package/dist/_chunks/{en-BrCTWlZv.mjs.map → en-CfIXaZf9.mjs.map} +1 -1
- package/dist/_chunks/{en-uOUIxfcQ.js → en-DTWPCdTS.js} +26 -14
- package/dist/_chunks/{en-uOUIxfcQ.js.map → en-DTWPCdTS.js.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/{index-DrNe6ctw.mjs → index-BW-rXkjn.mjs} +1027 -761
- package/dist/_chunks/index-BW-rXkjn.mjs.map +1 -0
- package/dist/_chunks/{index-Dd0nXyJF.js → index-DOzAG2cq.js} +1008 -741
- package/dist/_chunks/index-DOzAG2cq.js.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-B3ez7kvr.mjs → layout-DFVbgjp2.mjs} +8 -7
- package/dist/_chunks/layout-DFVbgjp2.mjs.map +1 -0
- package/dist/_chunks/{layout-CLLtt_5O.js → layout-RC3W2obV.js} +8 -7
- package/dist/_chunks/layout-RC3W2obV.js.map +1 -0
- 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-B0hlsUU_.mjs → relations-Dogh8HWI.mjs} +6 -7
- package/dist/_chunks/relations-Dogh8HWI.mjs.map +1 -0
- package/dist/_chunks/{relations-bRxcNv1q.js → relations-zam7-5H7.js} +6 -7
- package/dist/_chunks/relations-zam7-5H7.js.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/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +5 -4
- package/dist/admin/src/exports.d.ts +1 -1
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +32 -1
- package/dist/admin/src/pages/EditView/EditViewPage.d.ts +9 -1
- package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +4 -48
- package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
- package/dist/admin/src/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/constants.d.ts +1 -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/api.d.ts +1 -1
- package/dist/admin/src/services/components.d.ts +2 -2
- package/dist/admin/src/services/contentTypes.d.ts +3 -3
- package/dist/admin/src/services/documents.d.ts +19 -17
- package/dist/admin/src/services/init.d.ts +1 -1
- package/dist/admin/src/services/relations.d.ts +2 -2
- package/dist/admin/src/services/uid.d.ts +3 -3
- package/dist/admin/src/utils/validation.d.ts +4 -1
- package/dist/server/index.js +421 -183
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +421 -183
- 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 +15 -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 +3 -3
- package/dist/server/src/history/services/utils.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +4 -4
- package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
- package/dist/server/src/preview/constants.d.ts +2 -0
- package/dist/server/src/preview/constants.d.ts.map +1 -0
- 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 +15 -0
- package/dist/server/src/preview/services/index.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview-config.d.ts +30 -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 +18 -0
- package/dist/server/src/preview/utils.d.ts.map +1 -0
- 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 +8 -8
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +4 -4
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/permission-checker.d.ts.map +1 -1
- package/dist/server/src/services/utils/configuration/index.d.ts +2 -2
- package/dist/server/src/services/utils/configuration/layouts.d.ts +2 -2
- 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/collection-types.d.ts +3 -1
- package/dist/shared/contracts/collection-types.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 +14 -14
- package/dist/_chunks/EditViewPage-BVMS5hT-.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-CXkmnAvI.js.map +0 -1
- package/dist/_chunks/Field-Ibi32diw.js.map +0 -1
- package/dist/_chunks/Field-nNgv5bpd.mjs.map +0 -1
- package/dist/_chunks/Form-Dhnh34ym.js.map +0 -1
- package/dist/_chunks/Form-DodJsI2A.mjs.map +0 -1
- package/dist/_chunks/History-C9auUkDi.js.map +0 -1
- package/dist/_chunks/History-CKCSQXz_.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-Bg4rWUjX.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-CKEC4ttG.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-B7_WJUjG.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-C2gIeYHG.js.map +0 -1
- package/dist/_chunks/Relations-C0uC9J4f.js.map +0 -1
- package/dist/_chunks/Relations-DItV5eow.mjs.map +0 -1
- package/dist/_chunks/index-Dd0nXyJF.js.map +0 -1
- package/dist/_chunks/index-DrNe6ctw.mjs.map +0 -1
- package/dist/_chunks/layout-B3ez7kvr.mjs.map +0 -1
- package/dist/_chunks/layout-CLLtt_5O.js.map +0 -1
- package/dist/_chunks/relations-B0hlsUU_.mjs.map +0 -1
- package/dist/_chunks/relations-bRxcNv1q.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,6 +4,7 @@ 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");
|
9
10
|
const styledComponents = require("styled-components");
|
@@ -32,6 +33,7 @@ function _interopNamespace(e) {
|
|
32
33
|
return Object.freeze(n);
|
33
34
|
}
|
34
35
|
const React__namespace = /* @__PURE__ */ _interopNamespace(React);
|
36
|
+
const mapValues__default = /* @__PURE__ */ _interopDefault(mapValues);
|
35
37
|
const yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
|
36
38
|
const pipe__default = /* @__PURE__ */ _interopDefault(pipe);
|
37
39
|
const __variableDynamicImportRuntimeHelper = (glob, path) => {
|
@@ -121,6 +123,7 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
121
123
|
if (!slug) {
|
122
124
|
throw new Error("Cannot find the slug param in the URL");
|
123
125
|
}
|
126
|
+
const [{ rawQuery }] = strapiAdmin.useQueryParams();
|
124
127
|
const userPermissions = strapiAdmin.useAuth("DocumentRBAC", (state) => state.permissions);
|
125
128
|
const contentTypePermissions = React__namespace.useMemo(() => {
|
126
129
|
const contentTypePermissions2 = userPermissions.filter(
|
@@ -131,7 +134,14 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
131
134
|
return { ...acc, [action]: [permission] };
|
132
135
|
}, {});
|
133
136
|
}, [slug, userPermissions]);
|
134
|
-
const { isLoading, allowedActions } = strapiAdmin.useRBAC(
|
137
|
+
const { isLoading, allowedActions } = strapiAdmin.useRBAC(
|
138
|
+
contentTypePermissions,
|
139
|
+
permissions ?? void 0,
|
140
|
+
// TODO: useRBAC context should be typed and built differently
|
141
|
+
// We are passing raw query as context to the hook so that it can
|
142
|
+
// rely on the locale provided from DocumentRBAC for its permission calculations.
|
143
|
+
rawQuery
|
144
|
+
);
|
135
145
|
const canCreateFields = !isLoading && allowedActions.canCreate ? extractAndDedupeFields(contentTypePermissions.create) : [];
|
136
146
|
const canReadFields = !isLoading && allowedActions.canRead ? extractAndDedupeFields(contentTypePermissions.read) : [];
|
137
147
|
const canUpdateFields = !isLoading && allowedActions.canUpdate ? extractAndDedupeFields(contentTypePermissions.update) : [];
|
@@ -179,7 +189,8 @@ const contentManagerApi = strapiAdmin.adminApi.enhanceEndpoints({
|
|
179
189
|
"Document",
|
180
190
|
"InitialData",
|
181
191
|
"HistoryVersion",
|
182
|
-
"Relations"
|
192
|
+
"Relations",
|
193
|
+
"UidAvailability"
|
183
194
|
]
|
184
195
|
});
|
185
196
|
const documentApi = contentManagerApi.injectEndpoints({
|
@@ -209,7 +220,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
209
220
|
params
|
210
221
|
}
|
211
222
|
}),
|
212
|
-
invalidatesTags: (_result, _error, { model }) => [
|
223
|
+
invalidatesTags: (_result, _error, { model }) => [
|
224
|
+
{ type: "Document", id: `${model}_LIST` },
|
225
|
+
{ type: "UidAvailability", id: model }
|
226
|
+
]
|
213
227
|
}),
|
214
228
|
/**
|
215
229
|
* Creates a new collection-type document. This should ONLY be used for collection-types.
|
@@ -226,7 +240,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
226
240
|
}),
|
227
241
|
invalidatesTags: (result, _error, { model }) => [
|
228
242
|
{ type: "Document", id: `${model}_LIST` },
|
229
|
-
"Relations"
|
243
|
+
"Relations",
|
244
|
+
{ type: "UidAvailability", id: model }
|
230
245
|
]
|
231
246
|
}),
|
232
247
|
deleteDocument: builder.mutation({
|
@@ -267,7 +282,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
267
282
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
268
283
|
},
|
269
284
|
{ type: "Document", id: `${model}_LIST` },
|
270
|
-
"Relations"
|
285
|
+
"Relations",
|
286
|
+
{ type: "UidAvailability", id: model }
|
271
287
|
];
|
272
288
|
}
|
273
289
|
}),
|
@@ -324,6 +340,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
324
340
|
{
|
325
341
|
type: "Document",
|
326
342
|
id: collectionType !== SINGLE_TYPES ? `${model}_${result && "documentId" in result ? result.documentId : documentId}` : model
|
343
|
+
},
|
344
|
+
// Make it easy to invalidate all individual documents queries for a model
|
345
|
+
{
|
346
|
+
type: "Document",
|
347
|
+
id: `${model}_ALL_ITEMS`
|
327
348
|
}
|
328
349
|
];
|
329
350
|
}
|
@@ -387,7 +408,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
387
408
|
type: "Document",
|
388
409
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
389
410
|
},
|
390
|
-
"Relations"
|
411
|
+
"Relations",
|
412
|
+
{ type: "UidAvailability", id: model }
|
391
413
|
];
|
392
414
|
},
|
393
415
|
async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
|
@@ -470,20 +492,39 @@ const buildValidParams = (query) => {
|
|
470
492
|
const isBaseQueryError = (error) => {
|
471
493
|
return error.name !== void 0;
|
472
494
|
};
|
473
|
-
const
|
495
|
+
const arrayValidator = (attribute, options) => ({
|
496
|
+
message: strapiAdmin.translatedErrors.required,
|
497
|
+
test(value) {
|
498
|
+
if (options.status === "draft") {
|
499
|
+
return true;
|
500
|
+
}
|
501
|
+
if (!attribute.required) {
|
502
|
+
return true;
|
503
|
+
}
|
504
|
+
if (!value) {
|
505
|
+
return false;
|
506
|
+
}
|
507
|
+
if (Array.isArray(value) && value.length === 0) {
|
508
|
+
return false;
|
509
|
+
}
|
510
|
+
return true;
|
511
|
+
}
|
512
|
+
});
|
513
|
+
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
474
514
|
const createModelSchema = (attributes2) => yup__namespace.object().shape(
|
475
515
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
476
516
|
if (DOCUMENT_META_FIELDS.includes(name)) {
|
477
517
|
return acc;
|
478
518
|
}
|
479
519
|
const validations = [
|
520
|
+
addNullableValidation,
|
480
521
|
addRequiredValidation,
|
481
522
|
addMinLengthValidation,
|
482
523
|
addMaxLengthValidation,
|
483
524
|
addMinValidation,
|
484
525
|
addMaxValidation,
|
485
526
|
addRegexValidation
|
486
|
-
].map((fn) => fn(attribute));
|
527
|
+
].map((fn) => fn(attribute, options));
|
487
528
|
const transformSchema = pipe__default.default(...validations);
|
488
529
|
switch (attribute.type) {
|
489
530
|
case "component": {
|
@@ -493,12 +534,12 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
493
534
|
...acc,
|
494
535
|
[name]: transformSchema(
|
495
536
|
yup__namespace.array().of(createModelSchema(attributes3).nullable(false))
|
496
|
-
)
|
537
|
+
).test(arrayValidator(attribute, options))
|
497
538
|
};
|
498
539
|
} else {
|
499
540
|
return {
|
500
541
|
...acc,
|
501
|
-
[name]: transformSchema(createModelSchema(attributes3))
|
542
|
+
[name]: transformSchema(createModelSchema(attributes3).nullable())
|
502
543
|
};
|
503
544
|
}
|
504
545
|
}
|
@@ -520,7 +561,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
520
561
|
}
|
521
562
|
)
|
522
563
|
)
|
523
|
-
)
|
564
|
+
).test(arrayValidator(attribute, options))
|
524
565
|
};
|
525
566
|
case "relation":
|
526
567
|
return {
|
@@ -532,7 +573,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
532
573
|
} else if (Array.isArray(value)) {
|
533
574
|
return yup__namespace.array().of(
|
534
575
|
yup__namespace.object().shape({
|
535
|
-
id: yup__namespace.
|
576
|
+
id: yup__namespace.number().required()
|
536
577
|
})
|
537
578
|
);
|
538
579
|
} else if (typeof value === "object") {
|
@@ -584,6 +625,14 @@ const createAttributeSchema = (attribute) => {
|
|
584
625
|
if (!value || typeof value === "string" && value.length === 0) {
|
585
626
|
return true;
|
586
627
|
}
|
628
|
+
if (typeof value === "object") {
|
629
|
+
try {
|
630
|
+
JSON.stringify(value);
|
631
|
+
return true;
|
632
|
+
} catch (err) {
|
633
|
+
return false;
|
634
|
+
}
|
635
|
+
}
|
587
636
|
try {
|
588
637
|
JSON.parse(value);
|
589
638
|
return true;
|
@@ -602,13 +651,7 @@ const createAttributeSchema = (attribute) => {
|
|
602
651
|
return yup__namespace.mixed();
|
603
652
|
}
|
604
653
|
};
|
605
|
-
const
|
606
|
-
if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
|
607
|
-
return schema.min(1, strapiAdmin.translatedErrors.required);
|
608
|
-
}
|
609
|
-
if (attribute.required && attribute.type !== "relation") {
|
610
|
-
return schema.required(strapiAdmin.translatedErrors.required);
|
611
|
-
}
|
654
|
+
const nullableSchema = (schema) => {
|
612
655
|
return schema?.nullable ? schema.nullable() : (
|
613
656
|
// In some cases '.nullable' will not be available on the schema.
|
614
657
|
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
@@ -616,7 +659,22 @@ const addRequiredValidation = (attribute) => (schema) => {
|
|
616
659
|
schema
|
617
660
|
);
|
618
661
|
};
|
619
|
-
const
|
662
|
+
const addNullableValidation = () => (schema) => {
|
663
|
+
return nullableSchema(schema);
|
664
|
+
};
|
665
|
+
const addRequiredValidation = (attribute, options) => (schema) => {
|
666
|
+
if (options.status === "draft" || !attribute.required) {
|
667
|
+
return schema;
|
668
|
+
}
|
669
|
+
if (attribute.required && "required" in schema) {
|
670
|
+
return schema.required(strapiAdmin.translatedErrors.required);
|
671
|
+
}
|
672
|
+
return schema;
|
673
|
+
};
|
674
|
+
const addMinLengthValidation = (attribute, options) => (schema) => {
|
675
|
+
if (options.status === "draft") {
|
676
|
+
return schema;
|
677
|
+
}
|
620
678
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
621
679
|
return schema.min(attribute.minLength, {
|
622
680
|
...strapiAdmin.translatedErrors.minLength,
|
@@ -638,32 +696,13 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
638
696
|
}
|
639
697
|
return schema;
|
640
698
|
};
|
641
|
-
const addMinValidation = (attribute) => (schema) => {
|
642
|
-
if ("
|
699
|
+
const addMinValidation = (attribute, options) => (schema) => {
|
700
|
+
if (options.status === "draft") {
|
701
|
+
return schema;
|
702
|
+
}
|
703
|
+
if ("min" in attribute && "min" in schema) {
|
643
704
|
const min = toInteger(attribute.min);
|
644
|
-
if (
|
645
|
-
if (!attribute.required && "test" in schema && min) {
|
646
|
-
return schema.test(
|
647
|
-
"custom-min",
|
648
|
-
{
|
649
|
-
...strapiAdmin.translatedErrors.min,
|
650
|
-
values: {
|
651
|
-
min: attribute.min
|
652
|
-
}
|
653
|
-
},
|
654
|
-
(value) => {
|
655
|
-
if (!value) {
|
656
|
-
return true;
|
657
|
-
}
|
658
|
-
if (Array.isArray(value) && value.length === 0) {
|
659
|
-
return true;
|
660
|
-
}
|
661
|
-
return value.length >= min;
|
662
|
-
}
|
663
|
-
);
|
664
|
-
}
|
665
|
-
}
|
666
|
-
if ("min" in schema && min) {
|
705
|
+
if (min) {
|
667
706
|
return schema.min(min, {
|
668
707
|
...strapiAdmin.translatedErrors.min,
|
669
708
|
values: {
|
@@ -781,19 +820,115 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
|
|
781
820
|
}, {});
|
782
821
|
return componentsByKey;
|
783
822
|
};
|
784
|
-
const
|
823
|
+
const HOOKS = {
|
824
|
+
/**
|
825
|
+
* Hook that allows to mutate the displayed headers of the list view table
|
826
|
+
* @constant
|
827
|
+
* @type {string}
|
828
|
+
*/
|
829
|
+
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
830
|
+
/**
|
831
|
+
* Hook that allows to mutate the CM's collection types links pre-set filters
|
832
|
+
* @constant
|
833
|
+
* @type {string}
|
834
|
+
*/
|
835
|
+
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
836
|
+
/**
|
837
|
+
* Hook that allows to mutate the CM's edit view layout
|
838
|
+
* @constant
|
839
|
+
* @type {string}
|
840
|
+
*/
|
841
|
+
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
842
|
+
/**
|
843
|
+
* Hook that allows to mutate the CM's single types links pre-set filters
|
844
|
+
* @constant
|
845
|
+
* @type {string}
|
846
|
+
*/
|
847
|
+
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
848
|
+
};
|
849
|
+
const contentTypesApi = contentManagerApi.injectEndpoints({
|
850
|
+
endpoints: (builder) => ({
|
851
|
+
getContentTypeConfiguration: builder.query({
|
852
|
+
query: (uid) => ({
|
853
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
854
|
+
method: "GET"
|
855
|
+
}),
|
856
|
+
transformResponse: (response) => response.data,
|
857
|
+
providesTags: (_result, _error, uid) => [
|
858
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
859
|
+
{ type: "ContentTypeSettings", id: "LIST" }
|
860
|
+
]
|
861
|
+
}),
|
862
|
+
getAllContentTypeSettings: builder.query({
|
863
|
+
query: () => "/content-manager/content-types-settings",
|
864
|
+
transformResponse: (response) => response.data,
|
865
|
+
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
866
|
+
}),
|
867
|
+
updateContentTypeConfiguration: builder.mutation({
|
868
|
+
query: ({ uid, ...body }) => ({
|
869
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
870
|
+
method: "PUT",
|
871
|
+
data: body
|
872
|
+
}),
|
873
|
+
transformResponse: (response) => response.data,
|
874
|
+
invalidatesTags: (_result, _error, { uid }) => [
|
875
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
876
|
+
{ type: "ContentTypeSettings", id: "LIST" },
|
877
|
+
// Is this necessary?
|
878
|
+
{ type: "InitialData" }
|
879
|
+
]
|
880
|
+
})
|
881
|
+
})
|
882
|
+
});
|
883
|
+
const {
|
884
|
+
useGetContentTypeConfigurationQuery,
|
885
|
+
useGetAllContentTypeSettingsQuery,
|
886
|
+
useUpdateContentTypeConfigurationMutation
|
887
|
+
} = contentTypesApi;
|
888
|
+
const checkIfAttributeIsDisplayable = (attribute) => {
|
889
|
+
const { type } = attribute;
|
890
|
+
if (type === "relation") {
|
891
|
+
return !attribute.relation.toLowerCase().includes("morph");
|
892
|
+
}
|
893
|
+
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
894
|
+
};
|
895
|
+
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
896
|
+
if (!mainFieldName) {
|
897
|
+
return void 0;
|
898
|
+
}
|
899
|
+
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
900
|
+
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
901
|
+
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
902
|
+
);
|
903
|
+
return {
|
904
|
+
name: mainFieldName,
|
905
|
+
type: mainFieldType ?? "string"
|
906
|
+
};
|
907
|
+
};
|
908
|
+
const DEFAULT_SETTINGS = {
|
909
|
+
bulkable: false,
|
910
|
+
filterable: false,
|
911
|
+
searchable: false,
|
912
|
+
pagination: false,
|
913
|
+
defaultSortBy: "",
|
914
|
+
defaultSortOrder: "asc",
|
915
|
+
mainField: "id",
|
916
|
+
pageSize: 10
|
917
|
+
};
|
918
|
+
const useDocumentLayout = (model) => {
|
919
|
+
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
920
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
921
|
+
const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
785
922
|
const { toggleNotification } = strapiAdmin.useNotification();
|
786
923
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
924
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
787
925
|
const {
|
788
|
-
|
789
|
-
isLoading:
|
790
|
-
|
791
|
-
|
792
|
-
} =
|
793
|
-
|
794
|
-
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
795
|
-
});
|
796
|
-
const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
|
926
|
+
data,
|
927
|
+
isLoading: isLoadingConfigs,
|
928
|
+
error,
|
929
|
+
isFetching: isFetchingConfigs
|
930
|
+
} = useGetContentTypeConfigurationQuery(model);
|
931
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
797
932
|
React__namespace.useEffect(() => {
|
798
933
|
if (error) {
|
799
934
|
toggleNotification({
|
@@ -801,90 +936,346 @@ const useDocument = (args, opts) => {
|
|
801
936
|
message: formatAPIError(error)
|
802
937
|
});
|
803
938
|
}
|
804
|
-
}, [
|
805
|
-
const
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
(document) => {
|
813
|
-
if (!validationSchema) {
|
814
|
-
throw new Error(
|
815
|
-
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
816
|
-
);
|
817
|
-
}
|
818
|
-
try {
|
819
|
-
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
820
|
-
return null;
|
821
|
-
} catch (error2) {
|
822
|
-
if (error2 instanceof yup.ValidationError) {
|
823
|
-
return strapiAdmin.getYupValidationErrors(error2);
|
824
|
-
}
|
825
|
-
throw error2;
|
826
|
-
}
|
939
|
+
}, [error, formatAPIError, toggleNotification]);
|
940
|
+
const editLayout = React__namespace.useMemo(
|
941
|
+
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
942
|
+
layout: [],
|
943
|
+
components: {},
|
944
|
+
metadatas: {},
|
945
|
+
options: {},
|
946
|
+
settings: DEFAULT_SETTINGS
|
827
947
|
},
|
828
|
-
[
|
948
|
+
[data, isLoading, schemas, schema, components]
|
949
|
+
);
|
950
|
+
const listLayout = React__namespace.useMemo(() => {
|
951
|
+
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
952
|
+
layout: [],
|
953
|
+
metadatas: {},
|
954
|
+
options: {},
|
955
|
+
settings: DEFAULT_SETTINGS
|
956
|
+
};
|
957
|
+
}, [data, isLoading, schemas, schema, components]);
|
958
|
+
const { layout: edit } = React__namespace.useMemo(
|
959
|
+
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
960
|
+
layout: editLayout,
|
961
|
+
query
|
962
|
+
}),
|
963
|
+
[editLayout, query, runHookWaterfall]
|
829
964
|
);
|
830
|
-
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
831
965
|
return {
|
832
|
-
|
833
|
-
document: data?.data,
|
834
|
-
meta: data?.meta,
|
966
|
+
error,
|
835
967
|
isLoading,
|
836
|
-
|
837
|
-
|
838
|
-
};
|
839
|
-
};
|
840
|
-
const useDoc = () => {
|
841
|
-
const { id, slug, collectionType, origin } = reactRouterDom.useParams();
|
842
|
-
const [{ query }] = strapiAdmin.useQueryParams();
|
843
|
-
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
844
|
-
if (!collectionType) {
|
845
|
-
throw new Error("Could not find collectionType in url params");
|
846
|
-
}
|
847
|
-
if (!slug) {
|
848
|
-
throw new Error("Could not find model in url params");
|
849
|
-
}
|
850
|
-
return {
|
851
|
-
collectionType,
|
852
|
-
model: slug,
|
853
|
-
id: origin || id === "create" ? void 0 : id,
|
854
|
-
...useDocument(
|
855
|
-
{ documentId: origin || id, model: slug, collectionType, params },
|
856
|
-
{
|
857
|
-
skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
|
858
|
-
}
|
859
|
-
)
|
968
|
+
edit,
|
969
|
+
list: listLayout
|
860
970
|
};
|
861
971
|
};
|
862
|
-
const
|
863
|
-
|
864
|
-
|
865
|
-
}
|
866
|
-
return Object.keys(trad).reduce((acc, current) => {
|
867
|
-
acc[`${pluginId}.${current}`] = trad[current];
|
868
|
-
return acc;
|
869
|
-
}, {});
|
870
|
-
};
|
871
|
-
const getTranslation = (id) => `content-manager.${id}`;
|
872
|
-
const DEFAULT_UNEXPECTED_ERROR_MSG = {
|
873
|
-
id: "notification.error",
|
874
|
-
defaultMessage: "An error occurred, please try again"
|
972
|
+
const useDocLayout = () => {
|
973
|
+
const { model } = useDoc();
|
974
|
+
return useDocumentLayout(model);
|
875
975
|
};
|
876
|
-
const
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
const
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
976
|
+
const formatEditLayout = (data, {
|
977
|
+
schemas,
|
978
|
+
schema,
|
979
|
+
components
|
980
|
+
}) => {
|
981
|
+
let currentPanelIndex = 0;
|
982
|
+
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
983
|
+
data.contentType.layouts.edit,
|
984
|
+
schema?.attributes,
|
985
|
+
data.contentType.metadatas,
|
986
|
+
{ configurations: data.components, schemas: components },
|
987
|
+
schemas
|
988
|
+
).reduce((panels, row) => {
|
989
|
+
if (row.some((field) => field.type === "dynamiczone")) {
|
990
|
+
panels.push([row]);
|
991
|
+
currentPanelIndex += 2;
|
992
|
+
} else {
|
993
|
+
if (!panels[currentPanelIndex]) {
|
994
|
+
panels.push([row]);
|
995
|
+
} else {
|
996
|
+
panels[currentPanelIndex].push(row);
|
997
|
+
}
|
998
|
+
}
|
999
|
+
return panels;
|
1000
|
+
}, []);
|
1001
|
+
const componentEditAttributes = Object.entries(data.components).reduce(
|
1002
|
+
(acc, [uid, configuration]) => {
|
1003
|
+
acc[uid] = {
|
1004
|
+
layout: convertEditLayoutToFieldLayouts(
|
1005
|
+
configuration.layouts.edit,
|
1006
|
+
components[uid].attributes,
|
1007
|
+
configuration.metadatas,
|
1008
|
+
{ configurations: data.components, schemas: components }
|
1009
|
+
),
|
1010
|
+
settings: {
|
1011
|
+
...configuration.settings,
|
1012
|
+
icon: components[uid].info.icon,
|
1013
|
+
displayName: components[uid].info.displayName
|
1014
|
+
}
|
1015
|
+
};
|
1016
|
+
return acc;
|
1017
|
+
},
|
1018
|
+
{}
|
1019
|
+
);
|
1020
|
+
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1021
|
+
(acc, [attribute, metadata]) => {
|
1022
|
+
return {
|
1023
|
+
...acc,
|
1024
|
+
[attribute]: metadata.edit
|
1025
|
+
};
|
1026
|
+
},
|
1027
|
+
{}
|
1028
|
+
);
|
1029
|
+
return {
|
1030
|
+
layout: panelledEditAttributes,
|
1031
|
+
components: componentEditAttributes,
|
1032
|
+
metadatas: editMetadatas,
|
1033
|
+
settings: {
|
1034
|
+
...data.contentType.settings,
|
1035
|
+
displayName: schema?.info.displayName
|
1036
|
+
},
|
1037
|
+
options: {
|
1038
|
+
...schema?.options,
|
1039
|
+
...schema?.pluginOptions,
|
1040
|
+
...data.contentType.options
|
1041
|
+
}
|
1042
|
+
};
|
1043
|
+
};
|
1044
|
+
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
1045
|
+
return rows.map(
|
1046
|
+
(row) => row.map((field) => {
|
1047
|
+
const attribute = attributes[field.name];
|
1048
|
+
if (!attribute) {
|
1049
|
+
return null;
|
1050
|
+
}
|
1051
|
+
const { edit: metadata } = metadatas[field.name];
|
1052
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1053
|
+
return {
|
1054
|
+
attribute,
|
1055
|
+
disabled: !metadata.editable,
|
1056
|
+
hint: metadata.description,
|
1057
|
+
label: metadata.label ?? "",
|
1058
|
+
name: field.name,
|
1059
|
+
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
1060
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1061
|
+
schemas,
|
1062
|
+
components: components?.schemas ?? {}
|
1063
|
+
}),
|
1064
|
+
placeholder: metadata.placeholder ?? "",
|
1065
|
+
required: attribute.required ?? false,
|
1066
|
+
size: field.size,
|
1067
|
+
unique: "unique" in attribute ? attribute.unique : false,
|
1068
|
+
visible: metadata.visible ?? true,
|
1069
|
+
type: attribute.type
|
1070
|
+
};
|
1071
|
+
}).filter((field) => field !== null)
|
1072
|
+
);
|
1073
|
+
};
|
1074
|
+
const formatListLayout = (data, {
|
1075
|
+
schemas,
|
1076
|
+
schema,
|
1077
|
+
components
|
1078
|
+
}) => {
|
1079
|
+
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1080
|
+
(acc, [attribute, metadata]) => {
|
1081
|
+
return {
|
1082
|
+
...acc,
|
1083
|
+
[attribute]: metadata.list
|
1084
|
+
};
|
1085
|
+
},
|
1086
|
+
{}
|
1087
|
+
);
|
1088
|
+
const listAttributes = convertListLayoutToFieldLayouts(
|
1089
|
+
data.contentType.layouts.list,
|
1090
|
+
schema?.attributes,
|
1091
|
+
listMetadatas,
|
1092
|
+
{ configurations: data.components, schemas: components },
|
1093
|
+
schemas
|
1094
|
+
);
|
1095
|
+
return {
|
1096
|
+
layout: listAttributes,
|
1097
|
+
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
1098
|
+
metadatas: listMetadatas,
|
1099
|
+
options: {
|
1100
|
+
...schema?.options,
|
1101
|
+
...schema?.pluginOptions,
|
1102
|
+
...data.contentType.options
|
1103
|
+
}
|
1104
|
+
};
|
1105
|
+
};
|
1106
|
+
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
1107
|
+
return columns.map((name) => {
|
1108
|
+
const attribute = attributes[name];
|
1109
|
+
if (!attribute) {
|
1110
|
+
return null;
|
1111
|
+
}
|
1112
|
+
const metadata = metadatas[name];
|
1113
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1114
|
+
return {
|
1115
|
+
attribute,
|
1116
|
+
label: metadata.label ?? "",
|
1117
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1118
|
+
schemas,
|
1119
|
+
components: components?.schemas ?? {}
|
1120
|
+
}),
|
1121
|
+
name,
|
1122
|
+
searchable: metadata.searchable ?? true,
|
1123
|
+
sortable: metadata.sortable ?? true
|
1124
|
+
};
|
1125
|
+
}).filter((field) => field !== null);
|
1126
|
+
};
|
1127
|
+
const useDocument = (args, opts) => {
|
1128
|
+
const { toggleNotification } = strapiAdmin.useNotification();
|
1129
|
+
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
1130
|
+
const {
|
1131
|
+
currentData: data,
|
1132
|
+
isLoading: isLoadingDocument,
|
1133
|
+
isFetching: isFetchingDocument,
|
1134
|
+
error
|
1135
|
+
} = useGetDocumentQuery(args, {
|
1136
|
+
...opts,
|
1137
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
1138
|
+
});
|
1139
|
+
const {
|
1140
|
+
components,
|
1141
|
+
schema,
|
1142
|
+
schemas,
|
1143
|
+
isLoading: isLoadingSchema
|
1144
|
+
} = useContentTypeSchema(args.model);
|
1145
|
+
React__namespace.useEffect(() => {
|
1146
|
+
if (error) {
|
1147
|
+
toggleNotification({
|
1148
|
+
type: "danger",
|
1149
|
+
message: formatAPIError(error)
|
1150
|
+
});
|
1151
|
+
}
|
1152
|
+
}, [toggleNotification, error, formatAPIError, args.collectionType]);
|
1153
|
+
const validationSchema = React__namespace.useMemo(() => {
|
1154
|
+
if (!schema) {
|
1155
|
+
return null;
|
1156
|
+
}
|
1157
|
+
return createYupSchema(schema.attributes, components);
|
1158
|
+
}, [schema, components]);
|
1159
|
+
const validate = React__namespace.useCallback(
|
1160
|
+
(document) => {
|
1161
|
+
if (!validationSchema) {
|
1162
|
+
throw new Error(
|
1163
|
+
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
1164
|
+
);
|
1165
|
+
}
|
1166
|
+
try {
|
1167
|
+
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
1168
|
+
return null;
|
1169
|
+
} catch (error2) {
|
1170
|
+
if (error2 instanceof yup.ValidationError) {
|
1171
|
+
return strapiAdmin.getYupValidationErrors(error2);
|
1172
|
+
}
|
1173
|
+
throw error2;
|
1174
|
+
}
|
1175
|
+
},
|
1176
|
+
[validationSchema]
|
1177
|
+
);
|
1178
|
+
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
1179
|
+
const hasError = !!error;
|
1180
|
+
return {
|
1181
|
+
components,
|
1182
|
+
document: data?.data,
|
1183
|
+
meta: data?.meta,
|
1184
|
+
isLoading,
|
1185
|
+
hasError,
|
1186
|
+
schema,
|
1187
|
+
schemas,
|
1188
|
+
validate
|
1189
|
+
};
|
1190
|
+
};
|
1191
|
+
const useDoc = () => {
|
1192
|
+
const { id, slug, collectionType, origin } = reactRouterDom.useParams();
|
1193
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
1194
|
+
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
1195
|
+
if (!collectionType) {
|
1196
|
+
throw new Error("Could not find collectionType in url params");
|
1197
|
+
}
|
1198
|
+
if (!slug) {
|
1199
|
+
throw new Error("Could not find model in url params");
|
1200
|
+
}
|
1201
|
+
const document = useDocument(
|
1202
|
+
{ documentId: origin || id, model: slug, collectionType, params },
|
1203
|
+
{
|
1204
|
+
skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
|
1205
|
+
}
|
1206
|
+
);
|
1207
|
+
const returnId = origin || id === "create" ? void 0 : id;
|
1208
|
+
return {
|
1209
|
+
collectionType,
|
1210
|
+
model: slug,
|
1211
|
+
id: returnId,
|
1212
|
+
...document
|
1213
|
+
};
|
1214
|
+
};
|
1215
|
+
const useContentManagerContext = () => {
|
1216
|
+
const {
|
1217
|
+
collectionType,
|
1218
|
+
model,
|
1219
|
+
id,
|
1220
|
+
components,
|
1221
|
+
isLoading: isLoadingDoc,
|
1222
|
+
schema,
|
1223
|
+
schemas
|
1224
|
+
} = useDoc();
|
1225
|
+
const layout = useDocumentLayout(model);
|
1226
|
+
const form = strapiAdmin.useForm("useContentManagerContext", (state) => state);
|
1227
|
+
const isSingleType = collectionType === SINGLE_TYPES;
|
1228
|
+
const slug = model;
|
1229
|
+
const isCreatingEntry = id === "create";
|
1230
|
+
useContentTypeSchema();
|
1231
|
+
const isLoading = isLoadingDoc || layout.isLoading;
|
1232
|
+
const error = layout.error;
|
1233
|
+
return {
|
1234
|
+
error,
|
1235
|
+
isLoading,
|
1236
|
+
// Base metadata
|
1237
|
+
model,
|
1238
|
+
collectionType,
|
1239
|
+
id,
|
1240
|
+
slug,
|
1241
|
+
isCreatingEntry,
|
1242
|
+
isSingleType,
|
1243
|
+
hasDraftAndPublish: schema?.options?.draftAndPublish ?? false,
|
1244
|
+
// All schema infos
|
1245
|
+
components,
|
1246
|
+
contentType: schema,
|
1247
|
+
contentTypes: schemas,
|
1248
|
+
// Form state
|
1249
|
+
form,
|
1250
|
+
// layout infos
|
1251
|
+
layout
|
1252
|
+
};
|
1253
|
+
};
|
1254
|
+
const prefixPluginTranslations = (trad, pluginId) => {
|
1255
|
+
return Object.keys(trad).reduce((acc, current) => {
|
1256
|
+
acc[`${pluginId}.${current}`] = trad[current];
|
1257
|
+
return acc;
|
1258
|
+
}, {});
|
1259
|
+
};
|
1260
|
+
const getTranslation = (id) => `content-manager.${id}`;
|
1261
|
+
const DEFAULT_UNEXPECTED_ERROR_MSG = {
|
1262
|
+
id: "notification.error",
|
1263
|
+
defaultMessage: "An error occurred, please try again"
|
1264
|
+
};
|
1265
|
+
const useDocumentActions = () => {
|
1266
|
+
const { toggleNotification } = strapiAdmin.useNotification();
|
1267
|
+
const { formatMessage } = reactIntl.useIntl();
|
1268
|
+
const { trackUsage } = strapiAdmin.useTracking();
|
1269
|
+
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
1270
|
+
const navigate = reactRouterDom.useNavigate();
|
1271
|
+
const setCurrentStep = strapiAdmin.useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
1272
|
+
const [deleteDocument] = useDeleteDocumentMutation();
|
1273
|
+
const _delete = React__namespace.useCallback(
|
1274
|
+
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
1275
|
+
try {
|
1276
|
+
trackUsage("willDeleteEntry", trackerProperty);
|
1277
|
+
const res = await deleteDocument({
|
1278
|
+
collectionType,
|
888
1279
|
model,
|
889
1280
|
documentId,
|
890
1281
|
params
|
@@ -1192,6 +1583,7 @@ const useDocumentActions = () => {
|
|
1192
1583
|
defaultMessage: "Saved document"
|
1193
1584
|
})
|
1194
1585
|
});
|
1586
|
+
setCurrentStep("contentManager.success");
|
1195
1587
|
return res.data;
|
1196
1588
|
} catch (err) {
|
1197
1589
|
toggleNotification({
|
@@ -1231,7 +1623,7 @@ const useDocumentActions = () => {
|
|
1231
1623
|
throw err;
|
1232
1624
|
}
|
1233
1625
|
},
|
1234
|
-
[autoCloneDocument,
|
1626
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1235
1627
|
);
|
1236
1628
|
const [cloneDocument] = useCloneDocumentMutation();
|
1237
1629
|
const clone = React__namespace.useCallback(
|
@@ -1257,6 +1649,7 @@ const useDocumentActions = () => {
|
|
1257
1649
|
defaultMessage: "Cloned document"
|
1258
1650
|
})
|
1259
1651
|
});
|
1652
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1260
1653
|
return res.data;
|
1261
1654
|
} catch (err) {
|
1262
1655
|
toggleNotification({
|
@@ -1267,7 +1660,7 @@ const useDocumentActions = () => {
|
|
1267
1660
|
throw err;
|
1268
1661
|
}
|
1269
1662
|
},
|
1270
|
-
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
|
1663
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1271
1664
|
);
|
1272
1665
|
const [getDoc] = useLazyGetDocumentQuery();
|
1273
1666
|
const getDocument = React__namespace.useCallback(
|
@@ -1292,10 +1685,10 @@ const useDocumentActions = () => {
|
|
1292
1685
|
update
|
1293
1686
|
};
|
1294
1687
|
};
|
1295
|
-
const ProtectedHistoryPage =
|
1296
|
-
() => Promise.resolve().then(() => require("./History-
|
1688
|
+
const ProtectedHistoryPage = React__namespace.lazy(
|
1689
|
+
() => Promise.resolve().then(() => require("./History-BcUTQrfG.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1297
1690
|
);
|
1298
|
-
const routes$
|
1691
|
+
const routes$2 = [
|
1299
1692
|
{
|
1300
1693
|
path: ":collectionType/:slug/:id/history",
|
1301
1694
|
Component: ProtectedHistoryPage
|
@@ -1305,32 +1698,45 @@ const routes$1 = [
|
|
1305
1698
|
Component: ProtectedHistoryPage
|
1306
1699
|
}
|
1307
1700
|
];
|
1701
|
+
const ProtectedPreviewPage = React__namespace.lazy(
|
1702
|
+
() => Promise.resolve().then(() => require("./Preview-BF8ZDYqS.js")).then((mod) => ({ default: mod.ProtectedPreviewPage }))
|
1703
|
+
);
|
1704
|
+
const routes$1 = [
|
1705
|
+
{
|
1706
|
+
path: ":collectionType/:slug/:id/preview",
|
1707
|
+
Component: ProtectedPreviewPage
|
1708
|
+
},
|
1709
|
+
{
|
1710
|
+
path: ":collectionType/:slug/preview",
|
1711
|
+
Component: ProtectedPreviewPage
|
1712
|
+
}
|
1713
|
+
];
|
1308
1714
|
const ProtectedEditViewPage = React.lazy(
|
1309
|
-
() => Promise.resolve().then(() => require("./EditViewPage-
|
1715
|
+
() => Promise.resolve().then(() => require("./EditViewPage-BEs5iGDi.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1310
1716
|
);
|
1311
1717
|
const ProtectedListViewPage = React.lazy(
|
1312
|
-
() => Promise.resolve().then(() => require("./ListViewPage-
|
1718
|
+
() => Promise.resolve().then(() => require("./ListViewPage-BkT8Eao0.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1313
1719
|
);
|
1314
1720
|
const ProtectedListConfiguration = React.lazy(
|
1315
|
-
() => Promise.resolve().then(() => require("./ListConfigurationPage-
|
1721
|
+
() => Promise.resolve().then(() => require("./ListConfigurationPage-BE_Ho7tV.js")).then((mod) => ({
|
1316
1722
|
default: mod.ProtectedListConfiguration
|
1317
1723
|
}))
|
1318
1724
|
);
|
1319
1725
|
const ProtectedEditConfigurationPage = React.lazy(
|
1320
|
-
() => Promise.resolve().then(() => require("./EditConfigurationPage-
|
1726
|
+
() => Promise.resolve().then(() => require("./EditConfigurationPage-OWez0Kxp.js")).then((mod) => ({
|
1321
1727
|
default: mod.ProtectedEditConfigurationPage
|
1322
1728
|
}))
|
1323
1729
|
);
|
1324
1730
|
const ProtectedComponentConfigurationPage = React.lazy(
|
1325
|
-
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-
|
1731
|
+
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-ClKl_TA2.js")).then((mod) => ({
|
1326
1732
|
default: mod.ProtectedComponentConfigurationPage
|
1327
1733
|
}))
|
1328
1734
|
);
|
1329
1735
|
const NoPermissions = React.lazy(
|
1330
|
-
() => Promise.resolve().then(() => require("./NoPermissionsPage-
|
1736
|
+
() => Promise.resolve().then(() => require("./NoPermissionsPage-B5Y9Y78B.js")).then((mod) => ({ default: mod.NoPermissions }))
|
1331
1737
|
);
|
1332
1738
|
const NoContentType = React.lazy(
|
1333
|
-
() => Promise.resolve().then(() => require("./NoContentTypePage-
|
1739
|
+
() => Promise.resolve().then(() => require("./NoContentTypePage-C8mtyc4H.js")).then((mod) => ({ default: mod.NoContentType }))
|
1334
1740
|
);
|
1335
1741
|
const CollectionTypePages = () => {
|
1336
1742
|
const { collectionType } = reactRouterDom.useParams();
|
@@ -1342,7 +1748,7 @@ const CollectionTypePages = () => {
|
|
1342
1748
|
const CLONE_RELATIVE_PATH = ":collectionType/:slug/clone/:origin";
|
1343
1749
|
const CLONE_PATH = `/content-manager/${CLONE_RELATIVE_PATH}`;
|
1344
1750
|
const LIST_RELATIVE_PATH = ":collectionType/:slug";
|
1345
|
-
const LIST_PATH = `/content-manager
|
1751
|
+
const LIST_PATH = `/content-manager/collection-types/:slug`;
|
1346
1752
|
const routes = [
|
1347
1753
|
{
|
1348
1754
|
path: LIST_RELATIVE_PATH,
|
@@ -1376,6 +1782,7 @@ const routes = [
|
|
1376
1782
|
path: "no-content-types",
|
1377
1783
|
Component: NoContentType
|
1378
1784
|
},
|
1785
|
+
...routes$2,
|
1379
1786
|
...routes$1
|
1380
1787
|
];
|
1381
1788
|
const DocumentActions = ({ actions: actions2 }) => {
|
@@ -1444,12 +1851,14 @@ const DocumentActionButton = (action) => {
|
|
1444
1851
|
/* @__PURE__ */ jsxRuntime.jsx(
|
1445
1852
|
designSystem.Button,
|
1446
1853
|
{
|
1447
|
-
flex:
|
1854
|
+
flex: "auto",
|
1448
1855
|
startIcon: action.icon,
|
1449
1856
|
disabled: action.disabled,
|
1450
1857
|
onClick: handleClick(action),
|
1451
1858
|
justifyContent: "center",
|
1452
1859
|
variant: action.variant || "default",
|
1860
|
+
paddingTop: "7px",
|
1861
|
+
paddingBottom: "7px",
|
1453
1862
|
children: action.label
|
1454
1863
|
}
|
1455
1864
|
),
|
@@ -1472,6 +1881,11 @@ const DocumentActionButton = (action) => {
|
|
1472
1881
|
) : null
|
1473
1882
|
] });
|
1474
1883
|
};
|
1884
|
+
const MenuItem = styledComponents.styled(designSystem.Menu.Item)`
|
1885
|
+
&:hover {
|
1886
|
+
background: ${({ theme, isVariantDanger, isDisabled }) => isVariantDanger && !isDisabled ? theme.colors.danger100 : "neutral"};
|
1887
|
+
}
|
1888
|
+
`;
|
1475
1889
|
const DocumentActionsMenu = ({
|
1476
1890
|
actions: actions2,
|
1477
1891
|
children,
|
@@ -1527,44 +1941,35 @@ const DocumentActionsMenu = ({
|
|
1527
1941
|
]
|
1528
1942
|
}
|
1529
1943
|
),
|
1530
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, {
|
1944
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1531
1945
|
actions2.map((action) => {
|
1532
1946
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
1533
|
-
|
1947
|
+
MenuItem,
|
1534
1948
|
{
|
1535
1949
|
disabled: action.disabled,
|
1536
1950
|
onSelect: handleClick(action),
|
1537
1951
|
display: "block",
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
1543
|
-
|
1544
|
-
|
1545
|
-
|
1546
|
-
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1554
|
-
|
1555
|
-
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
height: 5,
|
1560
|
-
paddingLeft: 2,
|
1561
|
-
paddingRight: 2,
|
1562
|
-
hasRadius: true,
|
1563
|
-
color: "alternative600",
|
1564
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", fontWeight: "bold", lineHeight: 1, children: formatMessage({ id: "global.new", defaultMessage: "New" }) })
|
1565
|
-
}
|
1566
|
-
)
|
1567
|
-
] })
|
1952
|
+
isVariantDanger: action.variant === "danger",
|
1953
|
+
isDisabled: action.disabled,
|
1954
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "space-between", gap: 4, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
1955
|
+
designSystem.Flex,
|
1956
|
+
{
|
1957
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1958
|
+
gap: 2,
|
1959
|
+
tag: "span",
|
1960
|
+
children: [
|
1961
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
1962
|
+
designSystem.Flex,
|
1963
|
+
{
|
1964
|
+
tag: "span",
|
1965
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1966
|
+
children: action.icon
|
1967
|
+
}
|
1968
|
+
),
|
1969
|
+
action.label
|
1970
|
+
]
|
1971
|
+
}
|
1972
|
+
) })
|
1568
1973
|
},
|
1569
1974
|
action.id
|
1570
1975
|
);
|
@@ -1606,6 +2011,18 @@ const convertActionVariantToColor = (variant = "secondary") => {
|
|
1606
2011
|
return "primary600";
|
1607
2012
|
}
|
1608
2013
|
};
|
2014
|
+
const convertActionVariantToIconColor = (variant = "secondary") => {
|
2015
|
+
switch (variant) {
|
2016
|
+
case "danger":
|
2017
|
+
return "danger600";
|
2018
|
+
case "secondary":
|
2019
|
+
return "neutral500";
|
2020
|
+
case "success":
|
2021
|
+
return "success600";
|
2022
|
+
default:
|
2023
|
+
return "primary600";
|
2024
|
+
}
|
2025
|
+
};
|
1609
2026
|
const DocumentActionConfirmDialog = ({
|
1610
2027
|
onClose,
|
1611
2028
|
onCancel,
|
@@ -1632,11 +2049,11 @@ const DocumentActionConfirmDialog = ({
|
|
1632
2049
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
1633
2050
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: content }),
|
1634
2051
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
|
1635
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", children: formatMessage({
|
2052
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", fullWidth: true, children: formatMessage({
|
1636
2053
|
id: "app.components.Button.cancel",
|
1637
2054
|
defaultMessage: "Cancel"
|
1638
2055
|
}) }) }),
|
1639
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, children: formatMessage({
|
2056
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
|
1640
2057
|
id: "app.components.Button.confirm",
|
1641
2058
|
defaultMessage: "Confirm"
|
1642
2059
|
}) })
|
@@ -1663,6 +2080,18 @@ const DocumentActionModal = ({
|
|
1663
2080
|
typeof Footer === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Footer, { onClose: handleClose }) : Footer
|
1664
2081
|
] }) });
|
1665
2082
|
};
|
2083
|
+
const transformData = (data) => {
|
2084
|
+
if (Array.isArray(data)) {
|
2085
|
+
return data.map(transformData);
|
2086
|
+
}
|
2087
|
+
if (typeof data === "object" && data !== null) {
|
2088
|
+
if ("apiData" in data) {
|
2089
|
+
return data.apiData;
|
2090
|
+
}
|
2091
|
+
return mapValues__default.default(transformData)(data);
|
2092
|
+
}
|
2093
|
+
return data;
|
2094
|
+
};
|
1666
2095
|
const PublishAction$1 = ({
|
1667
2096
|
activeTab,
|
1668
2097
|
documentId,
|
@@ -1675,12 +2104,10 @@ const PublishAction$1 = ({
|
|
1675
2104
|
const navigate = reactRouterDom.useNavigate();
|
1676
2105
|
const { toggleNotification } = strapiAdmin.useNotification();
|
1677
2106
|
const { _unstableFormatValidationErrors: formatValidationErrors } = strapiAdmin.useAPIErrorHandler();
|
2107
|
+
const isListView = reactRouterDom.useMatch(LIST_PATH) !== null;
|
1678
2108
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
1679
2109
|
const { formatMessage } = reactIntl.useIntl();
|
1680
|
-
const { canPublish
|
1681
|
-
"PublishAction",
|
1682
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1683
|
-
);
|
2110
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1684
2111
|
const { publish } = useDocumentActions();
|
1685
2112
|
const [
|
1686
2113
|
countDraftRelations,
|
@@ -1732,24 +2159,25 @@ const PublishAction$1 = ({
|
|
1732
2159
|
}
|
1733
2160
|
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
1734
2161
|
React__namespace.useEffect(() => {
|
1735
|
-
if (documentId) {
|
1736
|
-
|
1737
|
-
const { data, error } = await countDraftRelations({
|
1738
|
-
collectionType,
|
1739
|
-
model,
|
1740
|
-
documentId,
|
1741
|
-
params
|
1742
|
-
});
|
1743
|
-
if (error) {
|
1744
|
-
throw error;
|
1745
|
-
}
|
1746
|
-
if (data) {
|
1747
|
-
setServerCountOfDraftRelations(data.data);
|
1748
|
-
}
|
1749
|
-
};
|
1750
|
-
fetchDraftRelationsCount();
|
2162
|
+
if (!document || !document.documentId || isListView) {
|
2163
|
+
return;
|
1751
2164
|
}
|
1752
|
-
|
2165
|
+
const fetchDraftRelationsCount = async () => {
|
2166
|
+
const { data, error } = await countDraftRelations({
|
2167
|
+
collectionType,
|
2168
|
+
model,
|
2169
|
+
documentId,
|
2170
|
+
params
|
2171
|
+
});
|
2172
|
+
if (error) {
|
2173
|
+
throw error;
|
2174
|
+
}
|
2175
|
+
if (data) {
|
2176
|
+
setServerCountOfDraftRelations(data.data);
|
2177
|
+
}
|
2178
|
+
};
|
2179
|
+
fetchDraftRelationsCount();
|
2180
|
+
}, [isListView, document, documentId, countDraftRelations, collectionType, model, params]);
|
1753
2181
|
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
1754
2182
|
if (!schema?.options?.draftAndPublish) {
|
1755
2183
|
return null;
|
@@ -1757,7 +2185,9 @@ const PublishAction$1 = ({
|
|
1757
2185
|
const performPublish = async () => {
|
1758
2186
|
setSubmitting(true);
|
1759
2187
|
try {
|
1760
|
-
const { errors } = await validate(
|
2188
|
+
const { errors } = await validate(true, {
|
2189
|
+
status: "published"
|
2190
|
+
});
|
1761
2191
|
if (errors) {
|
1762
2192
|
toggleNotification({
|
1763
2193
|
type: "danger",
|
@@ -1775,7 +2205,7 @@ const PublishAction$1 = ({
|
|
1775
2205
|
documentId,
|
1776
2206
|
params
|
1777
2207
|
},
|
1778
|
-
formValues
|
2208
|
+
transformData(formValues)
|
1779
2209
|
);
|
1780
2210
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1781
2211
|
navigate({
|
@@ -1790,7 +2220,8 @@ const PublishAction$1 = ({
|
|
1790
2220
|
}
|
1791
2221
|
};
|
1792
2222
|
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
1793
|
-
const
|
2223
|
+
const enableDraftRelationsCount = false;
|
2224
|
+
const hasDraftRelations = enableDraftRelationsCount;
|
1794
2225
|
return {
|
1795
2226
|
/**
|
1796
2227
|
* Disabled when:
|
@@ -1807,9 +2238,6 @@ const PublishAction$1 = ({
|
|
1807
2238
|
defaultMessage: "Publish"
|
1808
2239
|
}),
|
1809
2240
|
onClick: async () => {
|
1810
|
-
if (hasDraftRelations) {
|
1811
|
-
return;
|
1812
|
-
}
|
1813
2241
|
await performPublish();
|
1814
2242
|
},
|
1815
2243
|
dialog: hasDraftRelations ? {
|
@@ -1848,10 +2276,6 @@ const UpdateAction = ({
|
|
1848
2276
|
const cloneMatch = reactRouterDom.useMatch(CLONE_PATH);
|
1849
2277
|
const isCloning = cloneMatch !== null;
|
1850
2278
|
const { formatMessage } = reactIntl.useIntl();
|
1851
|
-
useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1852
|
-
canCreate: canCreate2,
|
1853
|
-
canUpdate: canUpdate2
|
1854
|
-
}));
|
1855
2279
|
const { create, update, clone } = useDocumentActions();
|
1856
2280
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1857
2281
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
@@ -1871,13 +2295,15 @@ const UpdateAction = ({
|
|
1871
2295
|
*/
|
1872
2296
|
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1873
2297
|
label: formatMessage({
|
1874
|
-
id: "
|
2298
|
+
id: "global.save",
|
1875
2299
|
defaultMessage: "Save"
|
1876
2300
|
}),
|
1877
2301
|
onClick: async () => {
|
1878
2302
|
setSubmitting(true);
|
1879
2303
|
try {
|
1880
|
-
const { errors } = await validate(
|
2304
|
+
const { errors } = await validate(true, {
|
2305
|
+
status: "draft"
|
2306
|
+
});
|
1881
2307
|
if (errors) {
|
1882
2308
|
toggleNotification({
|
1883
2309
|
type: "danger",
|
@@ -1895,7 +2321,7 @@ const UpdateAction = ({
|
|
1895
2321
|
documentId: cloneMatch.params.origin,
|
1896
2322
|
params
|
1897
2323
|
},
|
1898
|
-
document
|
2324
|
+
transformData(document)
|
1899
2325
|
);
|
1900
2326
|
if ("data" in res) {
|
1901
2327
|
navigate(
|
@@ -1916,7 +2342,7 @@ const UpdateAction = ({
|
|
1916
2342
|
documentId,
|
1917
2343
|
params
|
1918
2344
|
},
|
1919
|
-
document
|
2345
|
+
transformData(document)
|
1920
2346
|
);
|
1921
2347
|
if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1922
2348
|
setErrors(formatValidationErrors(res.error));
|
@@ -1929,7 +2355,7 @@ const UpdateAction = ({
|
|
1929
2355
|
model,
|
1930
2356
|
params
|
1931
2357
|
},
|
1932
|
-
document
|
2358
|
+
transformData(document)
|
1933
2359
|
);
|
1934
2360
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1935
2361
|
navigate(
|
@@ -1982,7 +2408,7 @@ const UnpublishAction$1 = ({
|
|
1982
2408
|
id: "app.utils.unpublish",
|
1983
2409
|
defaultMessage: "Unpublish"
|
1984
2410
|
}),
|
1985
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2411
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Cross, {}),
|
1986
2412
|
onClick: async () => {
|
1987
2413
|
if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
|
1988
2414
|
if (!documentId) {
|
@@ -2094,7 +2520,7 @@ const DiscardAction = ({
|
|
2094
2520
|
id: "content-manager.actions.discard.label",
|
2095
2521
|
defaultMessage: "Discard changes"
|
2096
2522
|
}),
|
2097
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2523
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Cross, {}),
|
2098
2524
|
position: ["panel", "table-row"],
|
2099
2525
|
variant: "danger",
|
2100
2526
|
dialog: {
|
@@ -2122,11 +2548,6 @@ const DiscardAction = ({
|
|
2122
2548
|
};
|
2123
2549
|
};
|
2124
2550
|
DiscardAction.type = "discard";
|
2125
|
-
const StyledCrossCircle = styledComponents.styled(Icons.CrossCircle)`
|
2126
|
-
path {
|
2127
|
-
fill: currentColor;
|
2128
|
-
}
|
2129
|
-
`;
|
2130
2551
|
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2131
2552
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2132
2553
|
const RelativeTime = React__namespace.forwardRef(
|
@@ -2139,7 +2560,7 @@ const RelativeTime = React__namespace.forwardRef(
|
|
2139
2560
|
});
|
2140
2561
|
const unit = intervals.find((intervalUnit) => {
|
2141
2562
|
return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
|
2142
|
-
});
|
2563
|
+
}) ?? "seconds";
|
2143
2564
|
const relativeTime = dateFns.isPast(timestamp) ? -interval[unit] : interval[unit];
|
2144
2565
|
const customInterval = customIntervals.find(
|
2145
2566
|
(custom) => interval[custom.unit] < custom.threshold
|
@@ -2173,19 +2594,29 @@ const getDisplayName = ({
|
|
2173
2594
|
return email ?? "";
|
2174
2595
|
};
|
2175
2596
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2176
|
-
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2177
|
-
const statusVariant = status === "draft" ? "
|
2178
|
-
|
2597
|
+
const DocumentStatus = ({ status = "draft", size = "S", ...restProps }) => {
|
2598
|
+
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2599
|
+
const { formatMessage } = reactIntl.useIntl();
|
2600
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Status, { ...restProps, size, variant: statusVariant, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: formatMessage({
|
2601
|
+
id: `content-manager.containers.List.${status}`,
|
2602
|
+
defaultMessage: capitalise(status)
|
2603
|
+
}) }) });
|
2179
2604
|
};
|
2180
2605
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
2181
2606
|
const { formatMessage } = reactIntl.useIntl();
|
2182
2607
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2608
|
+
const params = reactRouterDom.useParams();
|
2183
2609
|
const title = isCreating ? formatMessage({
|
2184
2610
|
id: "content-manager.containers.edit.title.new",
|
2185
2611
|
defaultMessage: "Create an entry"
|
2186
2612
|
}) : documentTitle;
|
2187
2613
|
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2188
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
2614
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
2615
|
+
strapiAdmin.BackButton,
|
2616
|
+
{
|
2617
|
+
fallback: params.collectionType === SINGLE_TYPES ? void 0 : `../${COLLECTION_TYPES}/${params.slug}`
|
2618
|
+
}
|
2619
|
+
),
|
2189
2620
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2190
2621
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
|
2191
2622
|
/* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
|
@@ -2273,12 +2704,12 @@ const Information = ({ activeTab }) => {
|
|
2273
2704
|
isDisplayed: !!publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME],
|
2274
2705
|
label: formatMessage({
|
2275
2706
|
id: "content-manager.containers.edit.information.last-published.label",
|
2276
|
-
defaultMessage: "
|
2707
|
+
defaultMessage: "Published"
|
2277
2708
|
}),
|
2278
2709
|
value: formatMessage(
|
2279
2710
|
{
|
2280
2711
|
id: "content-manager.containers.edit.information.last-published.value",
|
2281
|
-
defaultMessage: `
|
2712
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2282
2713
|
},
|
2283
2714
|
{
|
2284
2715
|
time: /* @__PURE__ */ jsxRuntime.jsx(RelativeTime, { timestamp: new Date(publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME]) }),
|
@@ -2291,12 +2722,12 @@ const Information = ({ activeTab }) => {
|
|
2291
2722
|
isDisplayed: !!createAndUpdateDocument?.[UPDATED_AT_ATTRIBUTE_NAME],
|
2292
2723
|
label: formatMessage({
|
2293
2724
|
id: "content-manager.containers.edit.information.last-draft.label",
|
2294
|
-
defaultMessage: "
|
2725
|
+
defaultMessage: "Updated"
|
2295
2726
|
}),
|
2296
2727
|
value: formatMessage(
|
2297
2728
|
{
|
2298
2729
|
id: "content-manager.containers.edit.information.last-draft.value",
|
2299
|
-
defaultMessage: `
|
2730
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2300
2731
|
},
|
2301
2732
|
{
|
2302
2733
|
time: /* @__PURE__ */ jsxRuntime.jsx(
|
@@ -2314,12 +2745,12 @@ const Information = ({ activeTab }) => {
|
|
2314
2745
|
isDisplayed: !!createAndUpdateDocument?.[CREATED_AT_ATTRIBUTE_NAME],
|
2315
2746
|
label: formatMessage({
|
2316
2747
|
id: "content-manager.containers.edit.information.document.label",
|
2317
|
-
defaultMessage: "
|
2748
|
+
defaultMessage: "Created"
|
2318
2749
|
}),
|
2319
2750
|
value: formatMessage(
|
2320
2751
|
{
|
2321
2752
|
id: "content-manager.containers.edit.information.document.value",
|
2322
|
-
defaultMessage: `
|
2753
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2323
2754
|
},
|
2324
2755
|
{
|
2325
2756
|
time: /* @__PURE__ */ jsxRuntime.jsx(
|
@@ -2357,523 +2788,277 @@ const Information = ({ activeTab }) => {
|
|
2357
2788
|
);
|
2358
2789
|
};
|
2359
2790
|
const HeaderActions = ({ actions: actions2 }) => {
|
2360
|
-
|
2361
|
-
|
2791
|
+
const [dialogId, setDialogId] = React__namespace.useState(null);
|
2792
|
+
const handleClick = (action) => async (e) => {
|
2793
|
+
if (!("options" in action)) {
|
2794
|
+
const { onClick = () => false, dialog, id } = action;
|
2795
|
+
const muteDialog = await onClick(e);
|
2796
|
+
if (dialog && !muteDialog) {
|
2797
|
+
e.preventDefault();
|
2798
|
+
setDialogId(id);
|
2799
|
+
}
|
2800
|
+
}
|
2801
|
+
};
|
2802
|
+
const handleClose = () => {
|
2803
|
+
setDialogId(null);
|
2804
|
+
};
|
2805
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 1, children: actions2.map((action) => {
|
2806
|
+
if (action.options) {
|
2362
2807
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
2363
2808
|
designSystem.SingleSelect,
|
2364
2809
|
{
|
2365
2810
|
size: "S",
|
2366
|
-
disabled: action.disabled,
|
2367
|
-
"aria-label": action.label,
|
2368
2811
|
onChange: action.onSelect,
|
2369
|
-
|
2812
|
+
"aria-label": action.label,
|
2813
|
+
...action,
|
2370
2814
|
children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { ...option, children: label }, option.value))
|
2371
2815
|
},
|
2372
2816
|
action.id
|
2373
2817
|
);
|
2374
2818
|
} else {
|
2375
|
-
|
2376
|
-
|
2377
|
-
|
2378
|
-
|
2379
|
-
|
2380
|
-
|
2381
|
-
|
2382
|
-
|
2383
|
-
|
2384
|
-
|
2385
|
-
defaultMessage: "Configure the view"
|
2386
|
-
}),
|
2387
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ListPlus, {}),
|
2388
|
-
onClick: () => {
|
2389
|
-
navigate(`../${collectionType}/${model}/configurations/edit`);
|
2390
|
-
},
|
2391
|
-
position: "header"
|
2392
|
-
};
|
2393
|
-
};
|
2394
|
-
ConfigureTheViewAction.type = "configure-the-view";
|
2395
|
-
const EditTheModelAction = ({ model }) => {
|
2396
|
-
const navigate = reactRouterDom.useNavigate();
|
2397
|
-
const { formatMessage } = reactIntl.useIntl();
|
2398
|
-
return {
|
2399
|
-
label: formatMessage({
|
2400
|
-
id: "content-manager.link-to-ctb",
|
2401
|
-
defaultMessage: "Edit the model"
|
2402
|
-
}),
|
2403
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, {}),
|
2404
|
-
onClick: () => {
|
2405
|
-
navigate(`/plugins/content-type-builder/content-types/${model}`);
|
2406
|
-
},
|
2407
|
-
position: "header"
|
2408
|
-
};
|
2409
|
-
};
|
2410
|
-
EditTheModelAction.type = "edit-the-model";
|
2411
|
-
const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
2412
|
-
const navigate = reactRouterDom.useNavigate();
|
2413
|
-
const { formatMessage } = reactIntl.useIntl();
|
2414
|
-
const listViewPathMatch = reactRouterDom.useMatch(LIST_PATH);
|
2415
|
-
const canDelete = useDocumentRBAC("DeleteAction", (state) => state.canDelete);
|
2416
|
-
const { delete: deleteAction } = useDocumentActions();
|
2417
|
-
const { toggleNotification } = strapiAdmin.useNotification();
|
2418
|
-
const setSubmitting = strapiAdmin.useForm("DeleteAction", (state) => state.setSubmitting);
|
2419
|
-
return {
|
2420
|
-
disabled: !canDelete || !document,
|
2421
|
-
label: formatMessage({
|
2422
|
-
id: "content-manager.actions.delete.label",
|
2423
|
-
defaultMessage: "Delete document"
|
2424
|
-
}),
|
2425
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {}),
|
2426
|
-
dialog: {
|
2427
|
-
type: "dialog",
|
2428
|
-
title: formatMessage({
|
2429
|
-
id: "app.components.ConfirmDialog.title",
|
2430
|
-
defaultMessage: "Confirmation"
|
2431
|
-
}),
|
2432
|
-
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, children: [
|
2433
|
-
/* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
2434
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
2435
|
-
id: "content-manager.actions.delete.dialog.body",
|
2436
|
-
defaultMessage: "Are you sure?"
|
2437
|
-
}) })
|
2438
|
-
] }),
|
2439
|
-
onConfirm: async () => {
|
2440
|
-
if (!listViewPathMatch) {
|
2441
|
-
setSubmitting(true);
|
2442
|
-
}
|
2443
|
-
try {
|
2444
|
-
if (!documentId && collectionType !== SINGLE_TYPES) {
|
2445
|
-
console.error(
|
2446
|
-
"You're trying to delete a document without an id, this is likely a bug with Strapi. Please open an issue."
|
2447
|
-
);
|
2448
|
-
toggleNotification({
|
2449
|
-
message: formatMessage({
|
2450
|
-
id: "content-manager.actions.delete.error",
|
2451
|
-
defaultMessage: "An error occurred while trying to delete the document."
|
2452
|
-
}),
|
2453
|
-
type: "danger"
|
2454
|
-
});
|
2455
|
-
return;
|
2456
|
-
}
|
2457
|
-
const res = await deleteAction({
|
2458
|
-
documentId,
|
2459
|
-
model,
|
2460
|
-
collectionType,
|
2461
|
-
params: {
|
2462
|
-
locale: "*"
|
2819
|
+
if (action.type === "icon") {
|
2820
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
|
2821
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
2822
|
+
designSystem.IconButton,
|
2823
|
+
{
|
2824
|
+
disabled: action.disabled,
|
2825
|
+
label: action.label,
|
2826
|
+
size: "S",
|
2827
|
+
onClick: handleClick(action),
|
2828
|
+
children: action.icon
|
2463
2829
|
}
|
2464
|
-
|
2465
|
-
|
2466
|
-
|
2467
|
-
|
2468
|
-
|
2469
|
-
|
2470
|
-
|
2471
|
-
|
2472
|
-
|
2830
|
+
),
|
2831
|
+
action.dialog ? /* @__PURE__ */ jsxRuntime.jsx(
|
2832
|
+
HeaderActionDialog,
|
2833
|
+
{
|
2834
|
+
...action.dialog,
|
2835
|
+
isOpen: dialogId === action.id,
|
2836
|
+
onClose: handleClose
|
2837
|
+
}
|
2838
|
+
) : null
|
2839
|
+
] }, action.id);
|
2473
2840
|
}
|
2474
|
-
},
|
2475
|
-
variant: "danger",
|
2476
|
-
position: ["header", "table-row"]
|
2477
|
-
};
|
2478
|
-
};
|
2479
|
-
DeleteAction$1.type = "delete";
|
2480
|
-
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2481
|
-
const Panels = () => {
|
2482
|
-
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2483
|
-
const [
|
2484
|
-
{
|
2485
|
-
query: { status }
|
2486
|
-
}
|
2487
|
-
] = strapiAdmin.useQueryParams({
|
2488
|
-
status: "draft"
|
2489
|
-
});
|
2490
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2491
|
-
const plugins = strapiAdmin.useStrapiApp("Panels", (state) => state.plugins);
|
2492
|
-
const props = {
|
2493
|
-
activeTab: status,
|
2494
|
-
model,
|
2495
|
-
documentId: id,
|
2496
|
-
document: isCloning ? void 0 : document,
|
2497
|
-
meta: isCloning ? void 0 : meta,
|
2498
|
-
collectionType
|
2499
|
-
};
|
2500
|
-
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
|
2501
|
-
strapiAdmin.DescriptionComponentRenderer,
|
2502
|
-
{
|
2503
|
-
props,
|
2504
|
-
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2505
|
-
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsxRuntime.jsx(Panel, { ...description, children: content }, id2))
|
2506
|
-
}
|
2507
|
-
) });
|
2508
|
-
};
|
2509
|
-
const ActionsPanel = () => {
|
2510
|
-
const { formatMessage } = reactIntl.useIntl();
|
2511
|
-
return {
|
2512
|
-
title: formatMessage({
|
2513
|
-
id: "content-manager.containers.edit.panels.default.title",
|
2514
|
-
defaultMessage: "Document"
|
2515
|
-
}),
|
2516
|
-
content: /* @__PURE__ */ jsxRuntime.jsx(ActionsPanelContent, {})
|
2517
|
-
};
|
2518
|
-
};
|
2519
|
-
ActionsPanel.type = "actions";
|
2520
|
-
const ActionsPanelContent = () => {
|
2521
|
-
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2522
|
-
const [
|
2523
|
-
{
|
2524
|
-
query: { status = "draft" }
|
2525
2841
|
}
|
2526
|
-
|
2527
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2528
|
-
const plugins = strapiAdmin.useStrapiApp("ActionsPanel", (state) => state.plugins);
|
2529
|
-
const props = {
|
2530
|
-
activeTab: status,
|
2531
|
-
model,
|
2532
|
-
documentId: id,
|
2533
|
-
document: isCloning ? void 0 : document,
|
2534
|
-
meta: isCloning ? void 0 : meta,
|
2535
|
-
collectionType
|
2536
|
-
};
|
2537
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, width: "100%", children: [
|
2538
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
2539
|
-
strapiAdmin.DescriptionComponentRenderer,
|
2540
|
-
{
|
2541
|
-
props,
|
2542
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2543
|
-
children: (actions2) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActions, { actions: actions2 })
|
2544
|
-
}
|
2545
|
-
),
|
2546
|
-
/* @__PURE__ */ jsxRuntime.jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
2547
|
-
] });
|
2842
|
+
}) });
|
2548
2843
|
};
|
2549
|
-
const
|
2550
|
-
|
2551
|
-
|
2552
|
-
|
2553
|
-
|
2554
|
-
|
2555
|
-
|
2556
|
-
|
2557
|
-
|
2558
|
-
|
2559
|
-
paddingBottom: 4,
|
2560
|
-
paddingLeft: 4,
|
2561
|
-
paddingRight: 4,
|
2562
|
-
paddingTop: 4,
|
2563
|
-
shadow: "tableShadow",
|
2564
|
-
gap: 3,
|
2565
|
-
direction: "column",
|
2566
|
-
justifyContent: "stretch",
|
2567
|
-
alignItems: "flex-start",
|
2568
|
-
children: [
|
2569
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2570
|
-
children
|
2571
|
-
]
|
2844
|
+
const HeaderActionDialog = ({
|
2845
|
+
onClose,
|
2846
|
+
onCancel,
|
2847
|
+
title,
|
2848
|
+
content: Content,
|
2849
|
+
isOpen
|
2850
|
+
}) => {
|
2851
|
+
const handleClose = async () => {
|
2852
|
+
if (onCancel) {
|
2853
|
+
await onCancel();
|
2572
2854
|
}
|
2573
|
-
|
2574
|
-
}
|
2575
|
-
|
2576
|
-
|
2577
|
-
|
2578
|
-
|
2579
|
-
* @type {string}
|
2580
|
-
*/
|
2581
|
-
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2582
|
-
/**
|
2583
|
-
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2584
|
-
* @constant
|
2585
|
-
* @type {string}
|
2586
|
-
*/
|
2587
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2588
|
-
/**
|
2589
|
-
* Hook that allows to mutate the CM's edit view layout
|
2590
|
-
* @constant
|
2591
|
-
* @type {string}
|
2592
|
-
*/
|
2593
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2594
|
-
/**
|
2595
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
2596
|
-
* @constant
|
2597
|
-
* @type {string}
|
2598
|
-
*/
|
2599
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2855
|
+
onClose();
|
2856
|
+
};
|
2857
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
2858
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
2859
|
+
typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : Content
|
2860
|
+
] }) });
|
2600
2861
|
};
|
2601
|
-
const
|
2602
|
-
|
2603
|
-
|
2604
|
-
|
2605
|
-
|
2606
|
-
|
2607
|
-
|
2608
|
-
transformResponse: (response) => response.data,
|
2609
|
-
providesTags: (_result, _error, uid) => [
|
2610
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2611
|
-
{ type: "ContentTypeSettings", id: "LIST" }
|
2612
|
-
]
|
2613
|
-
}),
|
2614
|
-
getAllContentTypeSettings: builder.query({
|
2615
|
-
query: () => "/content-manager/content-types-settings",
|
2616
|
-
transformResponse: (response) => response.data,
|
2617
|
-
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2862
|
+
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
2863
|
+
const navigate = reactRouterDom.useNavigate();
|
2864
|
+
const { formatMessage } = reactIntl.useIntl();
|
2865
|
+
return {
|
2866
|
+
label: formatMessage({
|
2867
|
+
id: "app.links.configure-view",
|
2868
|
+
defaultMessage: "Configure the view"
|
2618
2869
|
}),
|
2619
|
-
|
2620
|
-
|
2621
|
-
|
2622
|
-
|
2623
|
-
|
2624
|
-
|
2625
|
-
transformResponse: (response) => response.data,
|
2626
|
-
invalidatesTags: (_result, _error, { uid }) => [
|
2627
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2628
|
-
{ type: "ContentTypeSettings", id: "LIST" },
|
2629
|
-
// Is this necessary?
|
2630
|
-
{ type: "InitialData" }
|
2631
|
-
]
|
2632
|
-
})
|
2633
|
-
})
|
2634
|
-
});
|
2635
|
-
const {
|
2636
|
-
useGetContentTypeConfigurationQuery,
|
2637
|
-
useGetAllContentTypeSettingsQuery,
|
2638
|
-
useUpdateContentTypeConfigurationMutation
|
2639
|
-
} = contentTypesApi;
|
2640
|
-
const checkIfAttributeIsDisplayable = (attribute) => {
|
2641
|
-
const { type } = attribute;
|
2642
|
-
if (type === "relation") {
|
2643
|
-
return !attribute.relation.toLowerCase().includes("morph");
|
2644
|
-
}
|
2645
|
-
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2870
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ListPlus, {}),
|
2871
|
+
onClick: () => {
|
2872
|
+
navigate(`../${collectionType}/${model}/configurations/edit`);
|
2873
|
+
},
|
2874
|
+
position: "header"
|
2875
|
+
};
|
2646
2876
|
};
|
2647
|
-
|
2648
|
-
|
2649
|
-
|
2650
|
-
}
|
2651
|
-
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2652
|
-
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2653
|
-
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2654
|
-
);
|
2877
|
+
ConfigureTheViewAction.type = "configure-the-view";
|
2878
|
+
const EditTheModelAction = ({ model }) => {
|
2879
|
+
const navigate = reactRouterDom.useNavigate();
|
2880
|
+
const { formatMessage } = reactIntl.useIntl();
|
2655
2881
|
return {
|
2656
|
-
|
2657
|
-
|
2882
|
+
label: formatMessage({
|
2883
|
+
id: "content-manager.link-to-ctb",
|
2884
|
+
defaultMessage: "Edit the model"
|
2885
|
+
}),
|
2886
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, {}),
|
2887
|
+
onClick: () => {
|
2888
|
+
navigate(`/plugins/content-type-builder/content-types/${model}`);
|
2889
|
+
},
|
2890
|
+
position: "header"
|
2658
2891
|
};
|
2659
2892
|
};
|
2660
|
-
|
2661
|
-
|
2662
|
-
|
2663
|
-
|
2664
|
-
|
2665
|
-
|
2666
|
-
|
2667
|
-
mainField: "id",
|
2668
|
-
pageSize: 10
|
2669
|
-
};
|
2670
|
-
const useDocumentLayout = (model) => {
|
2671
|
-
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2672
|
-
const [{ query }] = strapiAdmin.useQueryParams();
|
2673
|
-
const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2893
|
+
EditTheModelAction.type = "edit-the-model";
|
2894
|
+
const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
2895
|
+
const navigate = reactRouterDom.useNavigate();
|
2896
|
+
const { formatMessage } = reactIntl.useIntl();
|
2897
|
+
const listViewPathMatch = reactRouterDom.useMatch(LIST_PATH);
|
2898
|
+
const canDelete = useDocumentRBAC("DeleteAction", (state) => state.canDelete);
|
2899
|
+
const { delete: deleteAction } = useDocumentActions();
|
2674
2900
|
const { toggleNotification } = strapiAdmin.useNotification();
|
2675
|
-
const
|
2676
|
-
const
|
2677
|
-
const {
|
2678
|
-
data,
|
2679
|
-
isLoading: isLoadingConfigs,
|
2680
|
-
error,
|
2681
|
-
isFetching: isFetchingConfigs
|
2682
|
-
} = useGetContentTypeConfigurationQuery(model);
|
2683
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2684
|
-
React__namespace.useEffect(() => {
|
2685
|
-
if (error) {
|
2686
|
-
toggleNotification({
|
2687
|
-
type: "danger",
|
2688
|
-
message: formatAPIError(error)
|
2689
|
-
});
|
2690
|
-
}
|
2691
|
-
}, [error, formatAPIError, toggleNotification]);
|
2692
|
-
const editLayout = React__namespace.useMemo(
|
2693
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2694
|
-
layout: [],
|
2695
|
-
components: {},
|
2696
|
-
metadatas: {},
|
2697
|
-
options: {},
|
2698
|
-
settings: DEFAULT_SETTINGS
|
2699
|
-
},
|
2700
|
-
[data, isLoading, schemas, schema, components]
|
2701
|
-
);
|
2702
|
-
const listLayout = React__namespace.useMemo(() => {
|
2703
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2704
|
-
layout: [],
|
2705
|
-
metadatas: {},
|
2706
|
-
options: {},
|
2707
|
-
settings: DEFAULT_SETTINGS
|
2708
|
-
};
|
2709
|
-
}, [data, isLoading, schemas, schema, components]);
|
2710
|
-
const { layout: edit } = React__namespace.useMemo(
|
2711
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2712
|
-
layout: editLayout,
|
2713
|
-
query
|
2714
|
-
}),
|
2715
|
-
[editLayout, query, runHookWaterfall]
|
2716
|
-
);
|
2901
|
+
const setSubmitting = strapiAdmin.useForm("DeleteAction", (state) => state.setSubmitting);
|
2902
|
+
const isLocalized = document?.locale != null;
|
2717
2903
|
return {
|
2718
|
-
|
2719
|
-
|
2720
|
-
|
2721
|
-
|
2722
|
-
|
2723
|
-
}
|
2724
|
-
|
2725
|
-
|
2726
|
-
|
2727
|
-
|
2728
|
-
|
2729
|
-
|
2730
|
-
|
2731
|
-
|
2732
|
-
})
|
2733
|
-
|
2734
|
-
|
2735
|
-
|
2736
|
-
|
2737
|
-
|
2738
|
-
|
2739
|
-
|
2740
|
-
|
2741
|
-
|
2742
|
-
|
2743
|
-
|
2744
|
-
|
2745
|
-
|
2746
|
-
|
2747
|
-
|
2748
|
-
|
2749
|
-
|
2750
|
-
|
2751
|
-
|
2752
|
-
|
2753
|
-
|
2754
|
-
|
2755
|
-
|
2756
|
-
|
2757
|
-
|
2758
|
-
|
2759
|
-
|
2760
|
-
|
2761
|
-
|
2762
|
-
|
2763
|
-
|
2904
|
+
disabled: !canDelete || !document,
|
2905
|
+
label: formatMessage(
|
2906
|
+
{
|
2907
|
+
id: "content-manager.actions.delete.label",
|
2908
|
+
defaultMessage: "Delete entry{isLocalized, select, true { (all locales)} other {}}"
|
2909
|
+
},
|
2910
|
+
{ isLocalized }
|
2911
|
+
),
|
2912
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {}),
|
2913
|
+
dialog: {
|
2914
|
+
type: "dialog",
|
2915
|
+
title: formatMessage({
|
2916
|
+
id: "app.components.ConfirmDialog.title",
|
2917
|
+
defaultMessage: "Confirmation"
|
2918
|
+
}),
|
2919
|
+
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, children: [
|
2920
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
2921
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
2922
|
+
id: "content-manager.actions.delete.dialog.body",
|
2923
|
+
defaultMessage: "Are you sure?"
|
2924
|
+
}) })
|
2925
|
+
] }),
|
2926
|
+
onConfirm: async () => {
|
2927
|
+
if (!listViewPathMatch) {
|
2928
|
+
setSubmitting(true);
|
2929
|
+
}
|
2930
|
+
try {
|
2931
|
+
if (!documentId && collectionType !== SINGLE_TYPES) {
|
2932
|
+
console.error(
|
2933
|
+
"You're trying to delete a document without an id, this is likely a bug with Strapi. Please open an issue."
|
2934
|
+
);
|
2935
|
+
toggleNotification({
|
2936
|
+
message: formatMessage({
|
2937
|
+
id: "content-manager.actions.delete.error",
|
2938
|
+
defaultMessage: "An error occurred while trying to delete the document."
|
2939
|
+
}),
|
2940
|
+
type: "danger"
|
2941
|
+
});
|
2942
|
+
return;
|
2943
|
+
}
|
2944
|
+
const res = await deleteAction({
|
2945
|
+
documentId,
|
2946
|
+
model,
|
2947
|
+
collectionType,
|
2948
|
+
params: {
|
2949
|
+
locale: "*"
|
2950
|
+
}
|
2951
|
+
});
|
2952
|
+
if (!("error" in res)) {
|
2953
|
+
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
2954
|
+
}
|
2955
|
+
} finally {
|
2956
|
+
if (!listViewPathMatch) {
|
2957
|
+
setSubmitting(false);
|
2958
|
+
}
|
2764
2959
|
}
|
2765
|
-
}
|
2766
|
-
return acc;
|
2767
|
-
},
|
2768
|
-
{}
|
2769
|
-
);
|
2770
|
-
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2771
|
-
(acc, [attribute, metadata]) => {
|
2772
|
-
return {
|
2773
|
-
...acc,
|
2774
|
-
[attribute]: metadata.edit
|
2775
|
-
};
|
2776
|
-
},
|
2777
|
-
{}
|
2778
|
-
);
|
2779
|
-
return {
|
2780
|
-
layout: panelledEditAttributes,
|
2781
|
-
components: componentEditAttributes,
|
2782
|
-
metadatas: editMetadatas,
|
2783
|
-
settings: {
|
2784
|
-
...data.contentType.settings,
|
2785
|
-
displayName: schema?.info.displayName
|
2960
|
+
}
|
2786
2961
|
},
|
2787
|
-
|
2788
|
-
|
2789
|
-
...schema?.pluginOptions,
|
2790
|
-
...data.contentType.options
|
2791
|
-
}
|
2962
|
+
variant: "danger",
|
2963
|
+
position: ["header", "table-row"]
|
2792
2964
|
};
|
2793
2965
|
};
|
2794
|
-
|
2795
|
-
|
2796
|
-
|
2797
|
-
|
2798
|
-
|
2799
|
-
|
2800
|
-
}
|
2801
|
-
|
2802
|
-
|
2803
|
-
|
2804
|
-
|
2805
|
-
|
2806
|
-
|
2807
|
-
|
2808
|
-
|
2809
|
-
|
2810
|
-
|
2811
|
-
|
2812
|
-
|
2813
|
-
|
2814
|
-
|
2815
|
-
|
2816
|
-
|
2817
|
-
|
2818
|
-
|
2819
|
-
|
2820
|
-
}
|
2821
|
-
}
|
2822
|
-
);
|
2966
|
+
DeleteAction$1.type = "delete";
|
2967
|
+
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2968
|
+
const Panels = () => {
|
2969
|
+
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2970
|
+
const [
|
2971
|
+
{
|
2972
|
+
query: { status }
|
2973
|
+
}
|
2974
|
+
] = strapiAdmin.useQueryParams({
|
2975
|
+
status: "draft"
|
2976
|
+
});
|
2977
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
2978
|
+
const plugins = strapiAdmin.useStrapiApp("Panels", (state) => state.plugins);
|
2979
|
+
const props = {
|
2980
|
+
activeTab: status,
|
2981
|
+
model,
|
2982
|
+
documentId: id,
|
2983
|
+
document: isCloning ? void 0 : document,
|
2984
|
+
meta: isCloning ? void 0 : meta,
|
2985
|
+
collectionType
|
2986
|
+
};
|
2987
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
|
2988
|
+
strapiAdmin.DescriptionComponentRenderer,
|
2989
|
+
{
|
2990
|
+
props,
|
2991
|
+
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2992
|
+
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsxRuntime.jsx(Panel, { ...description, children: content }, id2))
|
2993
|
+
}
|
2994
|
+
) });
|
2823
2995
|
};
|
2824
|
-
const
|
2825
|
-
|
2826
|
-
schema,
|
2827
|
-
components
|
2828
|
-
}) => {
|
2829
|
-
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2830
|
-
(acc, [attribute, metadata]) => {
|
2831
|
-
return {
|
2832
|
-
...acc,
|
2833
|
-
[attribute]: metadata.list
|
2834
|
-
};
|
2835
|
-
},
|
2836
|
-
{}
|
2837
|
-
);
|
2838
|
-
const listAttributes = convertListLayoutToFieldLayouts(
|
2839
|
-
data.contentType.layouts.list,
|
2840
|
-
schema?.attributes,
|
2841
|
-
listMetadatas,
|
2842
|
-
{ configurations: data.components, schemas: components },
|
2843
|
-
schemas
|
2844
|
-
);
|
2996
|
+
const ActionsPanel = () => {
|
2997
|
+
const { formatMessage } = reactIntl.useIntl();
|
2845
2998
|
return {
|
2846
|
-
|
2847
|
-
|
2848
|
-
|
2849
|
-
|
2850
|
-
|
2851
|
-
...schema?.pluginOptions,
|
2852
|
-
...data.contentType.options
|
2853
|
-
}
|
2999
|
+
title: formatMessage({
|
3000
|
+
id: "content-manager.containers.edit.panels.default.title",
|
3001
|
+
defaultMessage: "Entry"
|
3002
|
+
}),
|
3003
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(ActionsPanelContent, {})
|
2854
3004
|
};
|
2855
3005
|
};
|
2856
|
-
|
2857
|
-
|
2858
|
-
|
2859
|
-
|
2860
|
-
|
3006
|
+
ActionsPanel.type = "actions";
|
3007
|
+
const ActionsPanelContent = () => {
|
3008
|
+
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
3009
|
+
const [
|
3010
|
+
{
|
3011
|
+
query: { status = "draft" }
|
2861
3012
|
}
|
2862
|
-
|
2863
|
-
|
2864
|
-
|
2865
|
-
|
2866
|
-
|
2867
|
-
|
2868
|
-
|
2869
|
-
|
2870
|
-
|
2871
|
-
|
2872
|
-
|
2873
|
-
|
2874
|
-
|
2875
|
-
|
3013
|
+
] = strapiAdmin.useQueryParams();
|
3014
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
3015
|
+
const plugins = strapiAdmin.useStrapiApp("ActionsPanel", (state) => state.plugins);
|
3016
|
+
const props = {
|
3017
|
+
activeTab: status,
|
3018
|
+
model,
|
3019
|
+
documentId: id,
|
3020
|
+
document: isCloning ? void 0 : document,
|
3021
|
+
meta: isCloning ? void 0 : meta,
|
3022
|
+
collectionType
|
3023
|
+
};
|
3024
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, width: "100%", children: [
|
3025
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
3026
|
+
strapiAdmin.DescriptionComponentRenderer,
|
3027
|
+
{
|
3028
|
+
props,
|
3029
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3030
|
+
children: (actions2) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActions, { actions: actions2 })
|
3031
|
+
}
|
3032
|
+
),
|
3033
|
+
/* @__PURE__ */ jsxRuntime.jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
3034
|
+
] });
|
2876
3035
|
};
|
3036
|
+
const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
3037
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
3038
|
+
designSystem.Flex,
|
3039
|
+
{
|
3040
|
+
ref,
|
3041
|
+
tag: "aside",
|
3042
|
+
"aria-labelledby": "additional-information",
|
3043
|
+
background: "neutral0",
|
3044
|
+
borderColor: "neutral150",
|
3045
|
+
hasRadius: true,
|
3046
|
+
paddingBottom: 4,
|
3047
|
+
paddingLeft: 4,
|
3048
|
+
paddingRight: 4,
|
3049
|
+
paddingTop: 4,
|
3050
|
+
shadow: "tableShadow",
|
3051
|
+
gap: 3,
|
3052
|
+
direction: "column",
|
3053
|
+
justifyContent: "stretch",
|
3054
|
+
alignItems: "flex-start",
|
3055
|
+
children: [
|
3056
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", textColor: "neutral600", children: title }),
|
3057
|
+
children
|
3058
|
+
]
|
3059
|
+
}
|
3060
|
+
);
|
3061
|
+
});
|
2877
3062
|
const ConfirmBulkActionDialog = ({
|
2878
3063
|
onToggleDialog,
|
2879
3064
|
isOpen = false,
|
@@ -2912,6 +3097,7 @@ const ConfirmDialogPublishAll = ({
|
|
2912
3097
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler(getTranslation);
|
2913
3098
|
const { model, schema } = useDoc();
|
2914
3099
|
const [{ query }] = strapiAdmin.useQueryParams();
|
3100
|
+
const enableDraftRelationsCount = false;
|
2915
3101
|
const {
|
2916
3102
|
data: countDraftRelations = 0,
|
2917
3103
|
isLoading,
|
@@ -2923,7 +3109,7 @@ const ConfirmDialogPublishAll = ({
|
|
2923
3109
|
locale: query?.plugins?.i18n?.locale
|
2924
3110
|
},
|
2925
3111
|
{
|
2926
|
-
skip:
|
3112
|
+
skip: !enableDraftRelationsCount
|
2927
3113
|
}
|
2928
3114
|
);
|
2929
3115
|
React__namespace.useEffect(() => {
|
@@ -3108,7 +3294,7 @@ const SelectedEntriesTableContent = ({
|
|
3108
3294
|
status: row.status
|
3109
3295
|
}
|
3110
3296
|
) }),
|
3111
|
-
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
3297
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
3112
3298
|
designSystem.IconButton,
|
3113
3299
|
{
|
3114
3300
|
tag: reactRouterDom.Link,
|
@@ -3117,23 +3303,16 @@ const SelectedEntriesTableContent = ({
|
|
3117
3303
|
search: row.locale && `?plugins[i18n][locale]=${row.locale}`
|
3118
3304
|
},
|
3119
3305
|
state: { from: pathname },
|
3120
|
-
label: formatMessage(
|
3121
|
-
|
3122
|
-
|
3123
|
-
|
3124
|
-
{
|
3125
|
-
id: "content-manager.components.ListViewHelperPluginTable.row-line",
|
3126
|
-
defaultMessage: "item line {number}"
|
3127
|
-
},
|
3128
|
-
{ number: index2 + 1 }
|
3129
|
-
)
|
3130
|
-
}
|
3131
|
-
),
|
3306
|
+
label: formatMessage({
|
3307
|
+
id: "content-manager.bulk-publish.edit",
|
3308
|
+
defaultMessage: "Edit"
|
3309
|
+
}),
|
3132
3310
|
target: "_blank",
|
3133
3311
|
marginLeft: "auto",
|
3134
|
-
|
3312
|
+
variant: "ghost",
|
3313
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, { width: "1.6rem", height: "1.6rem" })
|
3135
3314
|
}
|
3136
|
-
) })
|
3315
|
+
) }) })
|
3137
3316
|
] }, row.id)) })
|
3138
3317
|
] });
|
3139
3318
|
};
|
@@ -3170,7 +3349,13 @@ const SelectedEntriesModalContent = ({
|
|
3170
3349
|
);
|
3171
3350
|
const { rows, validationErrors } = React__namespace.useMemo(() => {
|
3172
3351
|
if (data.length > 0 && schema) {
|
3173
|
-
const validate = createYupSchema(
|
3352
|
+
const validate = createYupSchema(
|
3353
|
+
schema.attributes,
|
3354
|
+
components,
|
3355
|
+
// Since this is the "Publish" action, the validation
|
3356
|
+
// schema must enforce the rules for published entities
|
3357
|
+
{ status: "published" }
|
3358
|
+
);
|
3174
3359
|
const validationErrors2 = {};
|
3175
3360
|
const rows2 = data.map((entry) => {
|
3176
3361
|
try {
|
@@ -3520,7 +3705,7 @@ const TableActions = ({ document }) => {
|
|
3520
3705
|
strapiAdmin.DescriptionComponentRenderer,
|
3521
3706
|
{
|
3522
3707
|
props,
|
3523
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3708
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
3524
3709
|
children: (actions2) => {
|
3525
3710
|
const tableRowActions = actions2.filter((action) => {
|
3526
3711
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3631,7 +3816,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3631
3816
|
}),
|
3632
3817
|
content: /* @__PURE__ */ jsxRuntime.jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
3633
3818
|
footer: ({ onClose }) => {
|
3634
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.
|
3819
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
3635
3820
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
3636
3821
|
id: "cancel",
|
3637
3822
|
defaultMessage: "Cancel"
|
@@ -3765,17 +3950,27 @@ const HistoryAction = ({ model, document }) => {
|
|
3765
3950
|
const { formatMessage } = reactIntl.useIntl();
|
3766
3951
|
const [{ query }] = strapiAdmin.useQueryParams();
|
3767
3952
|
const navigate = reactRouterDom.useNavigate();
|
3953
|
+
const { trackUsage } = strapiAdmin.useTracking();
|
3954
|
+
const { pathname } = reactRouterDom.useLocation();
|
3768
3955
|
const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
|
3769
3956
|
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3770
3957
|
return null;
|
3771
3958
|
}
|
3959
|
+
const handleOnClick = () => {
|
3960
|
+
const destination = { pathname: "history", search: pluginsQueryParams };
|
3961
|
+
trackUsage("willNavigate", {
|
3962
|
+
from: pathname,
|
3963
|
+
to: `${pathname}/${destination.pathname}`
|
3964
|
+
});
|
3965
|
+
navigate(destination);
|
3966
|
+
};
|
3772
3967
|
return {
|
3773
3968
|
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
|
3774
3969
|
label: formatMessage({
|
3775
3970
|
id: "content-manager.history.document-action",
|
3776
3971
|
defaultMessage: "Content History"
|
3777
3972
|
}),
|
3778
|
-
onClick:
|
3973
|
+
onClick: handleOnClick,
|
3779
3974
|
disabled: (
|
3780
3975
|
/**
|
3781
3976
|
* The user is creating a new document.
|
@@ -3843,6 +4038,72 @@ const { setInitialData } = actions;
|
|
3843
4038
|
const reducer = toolkit.combineReducers({
|
3844
4039
|
app: reducer$1
|
3845
4040
|
});
|
4041
|
+
const previewApi = contentManagerApi.injectEndpoints({
|
4042
|
+
endpoints: (builder) => ({
|
4043
|
+
getPreviewUrl: builder.query({
|
4044
|
+
query({ query, params }) {
|
4045
|
+
return {
|
4046
|
+
url: `/content-manager/preview/url/${params.contentType}`,
|
4047
|
+
method: "GET",
|
4048
|
+
config: {
|
4049
|
+
params: query
|
4050
|
+
}
|
4051
|
+
};
|
4052
|
+
}
|
4053
|
+
})
|
4054
|
+
})
|
4055
|
+
});
|
4056
|
+
const { useGetPreviewUrlQuery } = previewApi;
|
4057
|
+
const PreviewSidePanel = ({ model, documentId, document }) => {
|
4058
|
+
const { formatMessage } = reactIntl.useIntl();
|
4059
|
+
const { trackUsage } = strapiAdmin.useTracking();
|
4060
|
+
const { pathname } = reactRouterDom.useLocation();
|
4061
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
4062
|
+
const { data, error } = useGetPreviewUrlQuery({
|
4063
|
+
params: {
|
4064
|
+
contentType: model
|
4065
|
+
},
|
4066
|
+
query: {
|
4067
|
+
documentId,
|
4068
|
+
locale: document?.locale,
|
4069
|
+
status: document?.status
|
4070
|
+
}
|
4071
|
+
});
|
4072
|
+
if (!data?.data?.url || error) {
|
4073
|
+
return null;
|
4074
|
+
}
|
4075
|
+
const trackNavigation = () => {
|
4076
|
+
const destinationPathname = pathname.replace(/\/$/, "") + "/preview";
|
4077
|
+
trackUsage("willNavigate", { from: pathname, to: destinationPathname });
|
4078
|
+
};
|
4079
|
+
return {
|
4080
|
+
title: formatMessage({ id: "content-manager.preview.panel.title", defaultMessage: "Preview" }),
|
4081
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, width: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(
|
4082
|
+
designSystem.Button,
|
4083
|
+
{
|
4084
|
+
variant: "tertiary",
|
4085
|
+
tag: reactRouterDom.Link,
|
4086
|
+
to: { pathname: "preview", search: qs.stringify(query, { encode: false }) },
|
4087
|
+
onClick: trackNavigation,
|
4088
|
+
flex: "auto",
|
4089
|
+
children: formatMessage({
|
4090
|
+
id: "content-manager.preview.panel.button",
|
4091
|
+
defaultMessage: "Open preview"
|
4092
|
+
})
|
4093
|
+
}
|
4094
|
+
) })
|
4095
|
+
};
|
4096
|
+
};
|
4097
|
+
const FEATURE_ID = "preview";
|
4098
|
+
const previewAdmin = {
|
4099
|
+
bootstrap(app) {
|
4100
|
+
if (!window.strapi.future.isEnabled(FEATURE_ID)) {
|
4101
|
+
return;
|
4102
|
+
}
|
4103
|
+
const contentManagerPluginApis = app.getPlugin("content-manager").apis;
|
4104
|
+
contentManagerPluginApis.addEditViewSidePanel([PreviewSidePanel]);
|
4105
|
+
}
|
4106
|
+
};
|
3846
4107
|
const index = {
|
3847
4108
|
register(app) {
|
3848
4109
|
const cm = new ContentManagerPlugin();
|
@@ -3862,7 +4123,7 @@ const index = {
|
|
3862
4123
|
app.router.addRoute({
|
3863
4124
|
path: "content-manager/*",
|
3864
4125
|
lazy: async () => {
|
3865
|
-
const { Layout } = await Promise.resolve().then(() => require("./layout-
|
4126
|
+
const { Layout } = await Promise.resolve().then(() => require("./layout-RC3W2obV.js"));
|
3866
4127
|
return {
|
3867
4128
|
Component: Layout
|
3868
4129
|
};
|
@@ -3875,11 +4136,14 @@ const index = {
|
|
3875
4136
|
if (typeof historyAdmin.bootstrap === "function") {
|
3876
4137
|
historyAdmin.bootstrap(app);
|
3877
4138
|
}
|
4139
|
+
if (typeof previewAdmin.bootstrap === "function") {
|
4140
|
+
previewAdmin.bootstrap(app);
|
4141
|
+
}
|
3878
4142
|
},
|
3879
4143
|
async registerTrads({ locales }) {
|
3880
4144
|
const importedTrads = await Promise.all(
|
3881
4145
|
locales.map((locale) => {
|
3882
|
-
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-
|
4146
|
+
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-DTWPCdTS.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`).then(({ default: data }) => {
|
3883
4147
|
return {
|
3884
4148
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3885
4149
|
locale
|
@@ -3897,6 +4161,7 @@ const index = {
|
|
3897
4161
|
};
|
3898
4162
|
exports.ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD = ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD;
|
3899
4163
|
exports.BulkActionsRenderer = BulkActionsRenderer;
|
4164
|
+
exports.CLONE_PATH = CLONE_PATH;
|
3900
4165
|
exports.COLLECTION_TYPES = COLLECTION_TYPES;
|
3901
4166
|
exports.CREATOR_FIELDS = CREATOR_FIELDS;
|
3902
4167
|
exports.DEFAULT_SETTINGS = DEFAULT_SETTINGS;
|
@@ -3924,6 +4189,7 @@ exports.getMainField = getMainField;
|
|
3924
4189
|
exports.getTranslation = getTranslation;
|
3925
4190
|
exports.index = index;
|
3926
4191
|
exports.setInitialData = setInitialData;
|
4192
|
+
exports.useContentManagerContext = useContentManagerContext;
|
3927
4193
|
exports.useContentTypeSchema = useContentTypeSchema;
|
3928
4194
|
exports.useDoc = useDoc;
|
3929
4195
|
exports.useDocLayout = useDocLayout;
|
@@ -3935,5 +4201,6 @@ exports.useGetAllContentTypeSettingsQuery = useGetAllContentTypeSettingsQuery;
|
|
3935
4201
|
exports.useGetAllDocumentsQuery = useGetAllDocumentsQuery;
|
3936
4202
|
exports.useGetContentTypeConfigurationQuery = useGetContentTypeConfigurationQuery;
|
3937
4203
|
exports.useGetInitialDataQuery = useGetInitialDataQuery;
|
4204
|
+
exports.useGetPreviewUrlQuery = useGetPreviewUrlQuery;
|
3938
4205
|
exports.useUpdateContentTypeConfigurationMutation = useUpdateContentTypeConfigurationMutation;
|
3939
|
-
//# sourceMappingURL=index-
|
4206
|
+
//# sourceMappingURL=index-DOzAG2cq.js.map
|