@strapi/content-manager 0.0.0-experimental.826f263c58b6886b849d3f03b81f7a530bc51c91 → 0.0.0-experimental.8e52d29d243dccc7c24beb53412cf1c9c0b36d11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +18 -3
- package/dist/_chunks/{ComponentConfigurationPage-DJcn1DrO.js → ComponentConfigurationPage--MCP7Aew.js} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-DJcn1DrO.js.map → ComponentConfigurationPage--MCP7Aew.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-CR5XdR33.mjs → ComponentConfigurationPage-DT41asyM.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-CR5XdR33.mjs.map → ComponentConfigurationPage-DT41asyM.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-DmCIb4kD.mjs → EditConfigurationPage-DznPxn9p.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-DmCIb4kD.mjs.map → EditConfigurationPage-DznPxn9p.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-tDtWj7R2.js → EditConfigurationPage-qgnNvv_u.js} +4 -4
- package/dist/_chunks/{EditConfigurationPage-tDtWj7R2.js.map → EditConfigurationPage-qgnNvv_u.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-DvaV7U9b.mjs → EditViewPage-B_k7z288.mjs} +72 -50
- package/dist/_chunks/EditViewPage-B_k7z288.mjs.map +1 -0
- package/dist/_chunks/{EditViewPage-CoQEnFlC.js → EditViewPage-Bb4S7p8c.js} +70 -48
- package/dist/_chunks/EditViewPage-Bb4S7p8c.js.map +1 -0
- package/dist/_chunks/{Field-ZdrmmQ4Y.js → Field-ByR1mllE.js} +582 -230
- package/dist/_chunks/Field-ByR1mllE.js.map +1 -0
- package/dist/_chunks/{Field-Cz_J9551.mjs → Field-DmwbE0TL.mjs} +580 -228
- package/dist/_chunks/Field-DmwbE0TL.mjs.map +1 -0
- package/dist/_chunks/{Form-Bpig5rch.js → Form-BpeyAyS1.js} +52 -34
- package/dist/_chunks/Form-BpeyAyS1.js.map +1 -0
- package/dist/_chunks/{Form-Dxmihyw8.mjs → Form-Dvt5eouJ.mjs} +54 -36
- package/dist/_chunks/Form-Dvt5eouJ.mjs.map +1 -0
- package/dist/_chunks/{History-BZP8n7KT.mjs → History-CAERKpYl.mjs} +171 -77
- package/dist/_chunks/History-CAERKpYl.mjs.map +1 -0
- package/dist/_chunks/{History-BfX6XmZK.js → History-d-IgDGPl.js} +170 -76
- package/dist/_chunks/History-d-IgDGPl.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DxKuVkKz.mjs → ListConfigurationPage-CVVT45M8.mjs} +59 -49
- package/dist/_chunks/ListConfigurationPage-CVVT45M8.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-B3CXj8PY.js → ListConfigurationPage-DSX98CYb.js} +58 -47
- package/dist/_chunks/ListConfigurationPage-DSX98CYb.js.map +1 -0
- package/dist/_chunks/{ListViewPage-Bk9VO__I.js → ListViewPage-C9gPPp-V.js} +117 -105
- package/dist/_chunks/ListViewPage-C9gPPp-V.js.map +1 -0
- package/dist/_chunks/{ListViewPage-D5D3tVPq.mjs → ListViewPage-Q4g6kHDl.mjs} +115 -103
- package/dist/_chunks/ListViewPage-Q4g6kHDl.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DnMeuQCj.mjs → NoContentTypePage-BY4YRGs0.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-DnMeuQCj.mjs.map → NoContentTypePage-BY4YRGs0.mjs.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-DsB2F7Z1.js → NoContentTypePage-D09gppmy.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-DsB2F7Z1.js.map → NoContentTypePage-D09gppmy.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-BQDM64_b.js → NoPermissionsPage-32WgThJG.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-BQDM64_b.js.map → NoPermissionsPage-32WgThJG.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-OyoME_Tf.mjs → NoPermissionsPage-CyM16RKL.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-OyoME_Tf.mjs.map → NoPermissionsPage-CyM16RKL.mjs.map} +1 -1
- package/dist/_chunks/Preview-C2WFq4S8.mjs +267 -0
- package/dist/_chunks/Preview-C2WFq4S8.mjs.map +1 -0
- package/dist/_chunks/Preview-PpV3g9wJ.js +286 -0
- package/dist/_chunks/Preview-PpV3g9wJ.js.map +1 -0
- package/dist/_chunks/{Relations-BOYZmuWy.mjs → Relations-B_Yn9xGB.mjs} +73 -37
- package/dist/_chunks/Relations-B_Yn9xGB.mjs.map +1 -0
- package/dist/_chunks/{Relations-B6B3A3mb.js → Relations-mWaebC5t.js} +72 -36
- package/dist/_chunks/Relations-mWaebC5t.js.map +1 -0
- package/dist/_chunks/{en-BN1bvFK7.js → en-CHOp_xJv.js} +30 -16
- package/dist/_chunks/{en-BN1bvFK7.js.map → en-CHOp_xJv.js.map} +1 -1
- package/dist/_chunks/{en-Dzv55oQw.mjs → en-D_BMf0hT.mjs} +30 -16
- package/dist/_chunks/{en-Dzv55oQw.mjs.map → en-D_BMf0hT.mjs.map} +1 -1
- package/dist/_chunks/{es-EUonQTon.js → es-9K52xZIr.js} +2 -2
- package/dist/_chunks/{ja-CcFe8diO.js.map → es-9K52xZIr.js.map} +1 -1
- package/dist/_chunks/{es-CeXiYflN.mjs → es-D34tqjMw.mjs} +2 -2
- package/dist/_chunks/{es-CeXiYflN.mjs.map → es-D34tqjMw.mjs.map} +1 -1
- package/dist/_chunks/{fr-CD9VFbPM.mjs → fr--pg5jUbt.mjs} +13 -3
- package/dist/_chunks/{fr-CD9VFbPM.mjs.map → fr--pg5jUbt.mjs.map} +1 -1
- package/dist/_chunks/{fr-B7kGGg3E.js → fr-B2Kyv8Z9.js} +13 -3
- package/dist/_chunks/{fr-B7kGGg3E.js.map → fr-B2Kyv8Z9.js.map} +1 -1
- package/dist/_chunks/{index-VHviNMeW.mjs → index-CbytGVdz.mjs} +1154 -887
- package/dist/_chunks/index-CbytGVdz.mjs.map +1 -0
- package/dist/_chunks/{index-DzN3kBgx.js → index-iun2i4xv.js} +1133 -865
- package/dist/_chunks/index-iun2i4xv.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-CPn1PM6x.mjs → layout-Btu_cMRF.mjs} +41 -23
- package/dist/_chunks/layout-Btu_cMRF.mjs.map +1 -0
- package/dist/_chunks/{layout-b91XRlD2.js → layout-CkaP4K5_.js} +39 -21
- package/dist/_chunks/layout-CkaP4K5_.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-BsqxS6tR.mjs → relations-Cn5re8ia.mjs} +6 -7
- package/dist/_chunks/relations-Cn5re8ia.mjs.map +1 -0
- package/dist/_chunks/{relations-CA7IYmcP.js → relations-O_v9g0v_.js} +6 -7
- package/dist/_chunks/relations-O_v9g0v_.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 +8 -7
- package/dist/admin/src/exports.d.ts +1 -1
- package/dist/admin/src/history/components/VersionInputRenderer.d.ts +1 -1
- package/dist/admin/src/history/index.d.ts +3 -0
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +32 -1
- package/dist/admin/src/index.d.ts +1 -0
- package/dist/admin/src/pages/EditView/EditViewPage.d.ts +9 -1
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +8 -3
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +4 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +20 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +6 -58
- package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
- package/dist/admin/src/pages/ListView/components/BulkActions/Actions.d.ts +3 -30
- package/dist/admin/src/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.d.ts +2 -2
- 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/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 +551 -263
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +552 -264
- 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/uid.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/controllers/validation/dimensions.d.ts +4 -2
- package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -1
- package/dist/server/src/history/services/history.d.ts.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
- package/dist/server/src/history/services/utils.d.ts +4 -4
- 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/services/utils/populate.d.ts.map +1 -1
- package/dist/server/src/utils/index.d.ts +2 -0
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/dist/shared/contracts/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 +13 -13
- package/dist/_chunks/EditViewPage-CoQEnFlC.js.map +0 -1
- package/dist/_chunks/EditViewPage-DvaV7U9b.mjs.map +0 -1
- package/dist/_chunks/Field-Cz_J9551.mjs.map +0 -1
- package/dist/_chunks/Field-ZdrmmQ4Y.js.map +0 -1
- package/dist/_chunks/Form-Bpig5rch.js.map +0 -1
- package/dist/_chunks/Form-Dxmihyw8.mjs.map +0 -1
- package/dist/_chunks/History-BZP8n7KT.mjs.map +0 -1
- package/dist/_chunks/History-BfX6XmZK.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-B3CXj8PY.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DxKuVkKz.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-Bk9VO__I.js.map +0 -1
- package/dist/_chunks/ListViewPage-D5D3tVPq.mjs.map +0 -1
- package/dist/_chunks/Relations-B6B3A3mb.js.map +0 -1
- package/dist/_chunks/Relations-BOYZmuWy.mjs.map +0 -1
- package/dist/_chunks/index-DzN3kBgx.js.map +0 -1
- package/dist/_chunks/index-VHviNMeW.mjs.map +0 -1
- package/dist/_chunks/layout-CPn1PM6x.mjs.map +0 -1
- package/dist/_chunks/layout-b91XRlD2.js.map +0 -1
- package/dist/_chunks/relations-BsqxS6tR.mjs.map +0 -1
- package/dist/_chunks/relations-CA7IYmcP.js.map +0 -1
- package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
- package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
- package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
- package/strapi-server.js +0 -3
@@ -2,15 +2,16 @@
|
|
2
2
|
const Icons = require("@strapi/icons");
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
4
4
|
const strapiAdmin = require("@strapi/admin/strapi-admin");
|
5
|
-
const qs = require("qs");
|
6
|
-
const reactIntl = require("react-intl");
|
7
|
-
const reactRouterDom = require("react-router-dom");
|
8
5
|
const React = require("react");
|
9
6
|
const designSystem = require("@strapi/design-system");
|
10
|
-
const
|
7
|
+
const mapValues = require("lodash/fp/mapValues");
|
8
|
+
const reactIntl = require("react-intl");
|
9
|
+
const reactRouterDom = require("react-router-dom");
|
11
10
|
const yup = require("yup");
|
12
11
|
const pipe = require("lodash/fp/pipe");
|
13
12
|
const dateFns = require("date-fns");
|
13
|
+
const styledComponents = require("styled-components");
|
14
|
+
const qs = require("qs");
|
14
15
|
const toolkit = require("@reduxjs/toolkit");
|
15
16
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
16
17
|
function _interopNamespace(e) {
|
@@ -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) => {
|
@@ -70,42 +72,6 @@ const useInjectionZone = (area) => {
|
|
70
72
|
const [page, position] = area.split(".");
|
71
73
|
return contentManagerPlugin.getInjectedComponents(page, position);
|
72
74
|
};
|
73
|
-
const HistoryAction = ({ model, document }) => {
|
74
|
-
const { formatMessage } = reactIntl.useIntl();
|
75
|
-
const [{ query }] = strapiAdmin.useQueryParams();
|
76
|
-
const navigate = reactRouterDom.useNavigate();
|
77
|
-
const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
|
78
|
-
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
79
|
-
return null;
|
80
|
-
}
|
81
|
-
return {
|
82
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
|
83
|
-
label: formatMessage({
|
84
|
-
id: "content-manager.history.document-action",
|
85
|
-
defaultMessage: "Content History"
|
86
|
-
}),
|
87
|
-
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
88
|
-
disabled: (
|
89
|
-
/**
|
90
|
-
* The user is creating a new document.
|
91
|
-
* It hasn't been saved yet, so there's no history to go to
|
92
|
-
*/
|
93
|
-
!document || /**
|
94
|
-
* The document has been created but the current dimension has never been saved.
|
95
|
-
* For example, the user is creating a new locale in an existing document,
|
96
|
-
* so there's no history for the document in that locale
|
97
|
-
*/
|
98
|
-
!document.id || /**
|
99
|
-
* History is only available for content types created by the user.
|
100
|
-
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
101
|
-
* which start with `admin::` or `plugin::`
|
102
|
-
*/
|
103
|
-
!model.startsWith("api::")
|
104
|
-
),
|
105
|
-
position: "header"
|
106
|
-
};
|
107
|
-
};
|
108
|
-
HistoryAction.type = "history";
|
109
75
|
const ID = "id";
|
110
76
|
const CREATED_BY_ATTRIBUTE_NAME = "createdBy";
|
111
77
|
const UPDATED_BY_ATTRIBUTE_NAME = "updatedBy";
|
@@ -157,6 +123,7 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
157
123
|
if (!slug) {
|
158
124
|
throw new Error("Cannot find the slug param in the URL");
|
159
125
|
}
|
126
|
+
const [{ rawQuery }] = strapiAdmin.useQueryParams();
|
160
127
|
const userPermissions = strapiAdmin.useAuth("DocumentRBAC", (state) => state.permissions);
|
161
128
|
const contentTypePermissions = React__namespace.useMemo(() => {
|
162
129
|
const contentTypePermissions2 = userPermissions.filter(
|
@@ -167,7 +134,14 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
167
134
|
return { ...acc, [action]: [permission] };
|
168
135
|
}, {});
|
169
136
|
}, [slug, userPermissions]);
|
170
|
-
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
|
+
);
|
171
145
|
const canCreateFields = !isLoading && allowedActions.canCreate ? extractAndDedupeFields(contentTypePermissions.create) : [];
|
172
146
|
const canReadFields = !isLoading && allowedActions.canRead ? extractAndDedupeFields(contentTypePermissions.read) : [];
|
173
147
|
const canUpdateFields = !isLoading && allowedActions.canUpdate ? extractAndDedupeFields(contentTypePermissions.update) : [];
|
@@ -215,10 +189,12 @@ const contentManagerApi = strapiAdmin.adminApi.enhanceEndpoints({
|
|
215
189
|
"Document",
|
216
190
|
"InitialData",
|
217
191
|
"HistoryVersion",
|
218
|
-
"Relations"
|
192
|
+
"Relations",
|
193
|
+
"UidAvailability"
|
219
194
|
]
|
220
195
|
});
|
221
196
|
const documentApi = contentManagerApi.injectEndpoints({
|
197
|
+
overrideExisting: true,
|
222
198
|
endpoints: (builder) => ({
|
223
199
|
autoCloneDocument: builder.mutation({
|
224
200
|
query: ({ model, sourceId, query }) => ({
|
@@ -228,7 +204,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
228
204
|
params: query
|
229
205
|
}
|
230
206
|
}),
|
231
|
-
invalidatesTags: (_result,
|
207
|
+
invalidatesTags: (_result, error, { model }) => {
|
208
|
+
if (error) {
|
209
|
+
return [];
|
210
|
+
}
|
211
|
+
return [{ type: "Document", id: `${model}_LIST` }];
|
212
|
+
}
|
232
213
|
}),
|
233
214
|
cloneDocument: builder.mutation({
|
234
215
|
query: ({ model, sourceId, data, params }) => ({
|
@@ -239,7 +220,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
239
220
|
params
|
240
221
|
}
|
241
222
|
}),
|
242
|
-
invalidatesTags: (_result, _error, { model }) => [
|
223
|
+
invalidatesTags: (_result, _error, { model }) => [
|
224
|
+
{ type: "Document", id: `${model}_LIST` },
|
225
|
+
{ type: "UidAvailability", id: model }
|
226
|
+
]
|
243
227
|
}),
|
244
228
|
/**
|
245
229
|
* Creates a new collection-type document. This should ONLY be used for collection-types.
|
@@ -256,7 +240,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
256
240
|
}),
|
257
241
|
invalidatesTags: (result, _error, { model }) => [
|
258
242
|
{ type: "Document", id: `${model}_LIST` },
|
259
|
-
"Relations"
|
243
|
+
"Relations",
|
244
|
+
{ type: "UidAvailability", id: model }
|
260
245
|
]
|
261
246
|
}),
|
262
247
|
deleteDocument: builder.mutation({
|
@@ -297,7 +282,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
297
282
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
298
283
|
},
|
299
284
|
{ type: "Document", id: `${model}_LIST` },
|
300
|
-
"Relations"
|
285
|
+
"Relations",
|
286
|
+
{ type: "UidAvailability", id: model }
|
301
287
|
];
|
302
288
|
}
|
303
289
|
}),
|
@@ -315,6 +301,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
315
301
|
}),
|
316
302
|
providesTags: (result, _error, arg) => {
|
317
303
|
return [
|
304
|
+
{ type: "Document", id: `ALL_LIST` },
|
318
305
|
{ type: "Document", id: `${arg.model}_LIST` },
|
319
306
|
...result?.results.map(({ documentId }) => ({
|
320
307
|
type: "Document",
|
@@ -353,6 +340,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
353
340
|
{
|
354
341
|
type: "Document",
|
355
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`
|
356
348
|
}
|
357
349
|
];
|
358
350
|
}
|
@@ -416,8 +408,21 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
416
408
|
type: "Document",
|
417
409
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
418
410
|
},
|
419
|
-
"Relations"
|
411
|
+
"Relations",
|
412
|
+
{ type: "UidAvailability", id: model }
|
420
413
|
];
|
414
|
+
},
|
415
|
+
async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
|
416
|
+
const patchResult = dispatch(
|
417
|
+
documentApi.util.updateQueryData("getDocument", patch, (draft) => {
|
418
|
+
Object.assign(draft.data, data);
|
419
|
+
})
|
420
|
+
);
|
421
|
+
try {
|
422
|
+
await queryFulfilled;
|
423
|
+
} catch {
|
424
|
+
patchResult.undo();
|
425
|
+
}
|
421
426
|
}
|
422
427
|
}),
|
423
428
|
unpublishDocument: builder.mutation({
|
@@ -487,20 +492,39 @@ const buildValidParams = (query) => {
|
|
487
492
|
const isBaseQueryError = (error) => {
|
488
493
|
return error.name !== void 0;
|
489
494
|
};
|
490
|
-
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 }) => {
|
491
514
|
const createModelSchema = (attributes2) => yup__namespace.object().shape(
|
492
515
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
493
516
|
if (DOCUMENT_META_FIELDS.includes(name)) {
|
494
517
|
return acc;
|
495
518
|
}
|
496
519
|
const validations = [
|
520
|
+
addNullableValidation,
|
497
521
|
addRequiredValidation,
|
498
522
|
addMinLengthValidation,
|
499
523
|
addMaxLengthValidation,
|
500
524
|
addMinValidation,
|
501
525
|
addMaxValidation,
|
502
526
|
addRegexValidation
|
503
|
-
].map((fn) => fn(attribute));
|
527
|
+
].map((fn) => fn(attribute, options));
|
504
528
|
const transformSchema = pipe__default.default(...validations);
|
505
529
|
switch (attribute.type) {
|
506
530
|
case "component": {
|
@@ -510,12 +534,12 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
510
534
|
...acc,
|
511
535
|
[name]: transformSchema(
|
512
536
|
yup__namespace.array().of(createModelSchema(attributes3).nullable(false))
|
513
|
-
)
|
537
|
+
).test(arrayValidator(attribute, options))
|
514
538
|
};
|
515
539
|
} else {
|
516
540
|
return {
|
517
541
|
...acc,
|
518
|
-
[name]: transformSchema(createModelSchema(attributes3))
|
542
|
+
[name]: transformSchema(createModelSchema(attributes3).nullable())
|
519
543
|
};
|
520
544
|
}
|
521
545
|
}
|
@@ -537,7 +561,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
537
561
|
}
|
538
562
|
)
|
539
563
|
)
|
540
|
-
)
|
564
|
+
).test(arrayValidator(attribute, options))
|
541
565
|
};
|
542
566
|
case "relation":
|
543
567
|
return {
|
@@ -549,7 +573,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
549
573
|
} else if (Array.isArray(value)) {
|
550
574
|
return yup__namespace.array().of(
|
551
575
|
yup__namespace.object().shape({
|
552
|
-
id: yup__namespace.
|
576
|
+
id: yup__namespace.number().required()
|
553
577
|
})
|
554
578
|
);
|
555
579
|
} else if (typeof value === "object") {
|
@@ -601,6 +625,14 @@ const createAttributeSchema = (attribute) => {
|
|
601
625
|
if (!value || typeof value === "string" && value.length === 0) {
|
602
626
|
return true;
|
603
627
|
}
|
628
|
+
if (typeof value === "object") {
|
629
|
+
try {
|
630
|
+
JSON.stringify(value);
|
631
|
+
return true;
|
632
|
+
} catch (err) {
|
633
|
+
return false;
|
634
|
+
}
|
635
|
+
}
|
604
636
|
try {
|
605
637
|
JSON.parse(value);
|
606
638
|
return true;
|
@@ -619,13 +651,7 @@ const createAttributeSchema = (attribute) => {
|
|
619
651
|
return yup__namespace.mixed();
|
620
652
|
}
|
621
653
|
};
|
622
|
-
const
|
623
|
-
if (attribute.required) {
|
624
|
-
return schema.required({
|
625
|
-
id: strapiAdmin.translatedErrors.required.id,
|
626
|
-
defaultMessage: "This field is required."
|
627
|
-
});
|
628
|
-
}
|
654
|
+
const nullableSchema = (schema) => {
|
629
655
|
return schema?.nullable ? schema.nullable() : (
|
630
656
|
// In some cases '.nullable' will not be available on the schema.
|
631
657
|
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
@@ -633,7 +659,22 @@ const addRequiredValidation = (attribute) => (schema) => {
|
|
633
659
|
schema
|
634
660
|
);
|
635
661
|
};
|
636
|
-
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
|
+
}
|
637
678
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
638
679
|
return schema.min(attribute.minLength, {
|
639
680
|
...strapiAdmin.translatedErrors.minLength,
|
@@ -655,10 +696,13 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
655
696
|
}
|
656
697
|
return schema;
|
657
698
|
};
|
658
|
-
const addMinValidation = (attribute) => (schema) => {
|
659
|
-
if ("
|
699
|
+
const addMinValidation = (attribute, options) => (schema) => {
|
700
|
+
if (options.status === "draft") {
|
701
|
+
return schema;
|
702
|
+
}
|
703
|
+
if ("min" in attribute && "min" in schema) {
|
660
704
|
const min = toInteger(attribute.min);
|
661
|
-
if (
|
705
|
+
if (min) {
|
662
706
|
return schema.min(min, {
|
663
707
|
...strapiAdmin.translatedErrors.min,
|
664
708
|
values: {
|
@@ -776,16 +820,115 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
|
|
776
820
|
}, {});
|
777
821
|
return componentsByKey;
|
778
822
|
};
|
779
|
-
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);
|
780
922
|
const { toggleNotification } = strapiAdmin.useNotification();
|
781
923
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
924
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
782
925
|
const {
|
783
|
-
|
784
|
-
isLoading:
|
785
|
-
|
786
|
-
|
787
|
-
} =
|
788
|
-
const
|
926
|
+
data,
|
927
|
+
isLoading: isLoadingConfigs,
|
928
|
+
error,
|
929
|
+
isFetching: isFetchingConfigs
|
930
|
+
} = useGetContentTypeConfigurationQuery(model);
|
931
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
789
932
|
React__namespace.useEffect(() => {
|
790
933
|
if (error) {
|
791
934
|
toggleNotification({
|
@@ -793,68 +936,322 @@ const useDocument = (args, opts) => {
|
|
793
936
|
message: formatAPIError(error)
|
794
937
|
});
|
795
938
|
}
|
796
|
-
}, [
|
797
|
-
const
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
(document) => {
|
805
|
-
if (!validationSchema) {
|
806
|
-
throw new Error(
|
807
|
-
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
808
|
-
);
|
809
|
-
}
|
810
|
-
try {
|
811
|
-
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
812
|
-
return null;
|
813
|
-
} catch (error2) {
|
814
|
-
if (error2 instanceof yup.ValidationError) {
|
815
|
-
return strapiAdmin.getYupValidationErrors(error2);
|
816
|
-
}
|
817
|
-
throw error2;
|
818
|
-
}
|
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
|
819
947
|
},
|
820
|
-
[
|
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]
|
821
964
|
);
|
822
|
-
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
823
965
|
return {
|
824
|
-
|
825
|
-
document: data?.data,
|
826
|
-
meta: data?.meta,
|
966
|
+
error,
|
827
967
|
isLoading,
|
828
|
-
|
829
|
-
|
968
|
+
edit,
|
969
|
+
list: listLayout
|
830
970
|
};
|
831
971
|
};
|
832
|
-
const
|
833
|
-
const {
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
972
|
+
const useDocLayout = () => {
|
973
|
+
const { model } = useDoc();
|
974
|
+
return useDocumentLayout(model);
|
975
|
+
};
|
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) {
|
840
1199
|
throw new Error("Could not find model in url params");
|
841
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;
|
842
1208
|
return {
|
843
1209
|
collectionType,
|
844
1210
|
model: slug,
|
845
|
-
id:
|
846
|
-
...
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
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
|
852
1252
|
};
|
853
1253
|
};
|
854
1254
|
const prefixPluginTranslations = (trad, pluginId) => {
|
855
|
-
if (!pluginId) {
|
856
|
-
throw new TypeError("pluginId can't be empty");
|
857
|
-
}
|
858
1255
|
return Object.keys(trad).reduce((acc, current) => {
|
859
1256
|
acc[`${pluginId}.${current}`] = trad[current];
|
860
1257
|
return acc;
|
@@ -870,6 +1267,8 @@ const useDocumentActions = () => {
|
|
870
1267
|
const { formatMessage } = reactIntl.useIntl();
|
871
1268
|
const { trackUsage } = strapiAdmin.useTracking();
|
872
1269
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
1270
|
+
const navigate = reactRouterDom.useNavigate();
|
1271
|
+
const setCurrentStep = strapiAdmin.useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
873
1272
|
const [deleteDocument] = useDeleteDocumentMutation();
|
874
1273
|
const _delete = React__namespace.useCallback(
|
875
1274
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -948,12 +1347,13 @@ const useDocumentActions = () => {
|
|
948
1347
|
);
|
949
1348
|
const [discardDocument] = useDiscardDocumentMutation();
|
950
1349
|
const discard = React__namespace.useCallback(
|
951
|
-
async ({ collectionType, model, documentId }) => {
|
1350
|
+
async ({ collectionType, model, documentId, params }) => {
|
952
1351
|
try {
|
953
1352
|
const res = await discardDocument({
|
954
1353
|
collectionType,
|
955
1354
|
model,
|
956
|
-
documentId
|
1355
|
+
documentId,
|
1356
|
+
params
|
957
1357
|
});
|
958
1358
|
if ("error" in res) {
|
959
1359
|
toggleNotification({
|
@@ -1183,6 +1583,7 @@ const useDocumentActions = () => {
|
|
1183
1583
|
defaultMessage: "Saved document"
|
1184
1584
|
})
|
1185
1585
|
});
|
1586
|
+
setCurrentStep("contentManager.success");
|
1186
1587
|
return res.data;
|
1187
1588
|
} catch (err) {
|
1188
1589
|
toggleNotification({
|
@@ -1204,7 +1605,6 @@ const useDocumentActions = () => {
|
|
1204
1605
|
sourceId
|
1205
1606
|
});
|
1206
1607
|
if ("error" in res) {
|
1207
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1208
1608
|
return { error: res.error };
|
1209
1609
|
}
|
1210
1610
|
toggleNotification({
|
@@ -1223,7 +1623,7 @@ const useDocumentActions = () => {
|
|
1223
1623
|
throw err;
|
1224
1624
|
}
|
1225
1625
|
},
|
1226
|
-
[autoCloneDocument,
|
1626
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1227
1627
|
);
|
1228
1628
|
const [cloneDocument] = useCloneDocumentMutation();
|
1229
1629
|
const clone = React__namespace.useCallback(
|
@@ -1249,6 +1649,7 @@ const useDocumentActions = () => {
|
|
1249
1649
|
defaultMessage: "Cloned document"
|
1250
1650
|
})
|
1251
1651
|
});
|
1652
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1252
1653
|
return res.data;
|
1253
1654
|
} catch (err) {
|
1254
1655
|
toggleNotification({
|
@@ -1259,7 +1660,7 @@ const useDocumentActions = () => {
|
|
1259
1660
|
throw err;
|
1260
1661
|
}
|
1261
1662
|
},
|
1262
|
-
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
|
1663
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1263
1664
|
);
|
1264
1665
|
const [getDoc] = useLazyGetDocumentQuery();
|
1265
1666
|
const getDocument = React__namespace.useCallback(
|
@@ -1284,10 +1685,10 @@ const useDocumentActions = () => {
|
|
1284
1685
|
update
|
1285
1686
|
};
|
1286
1687
|
};
|
1287
|
-
const ProtectedHistoryPage =
|
1288
|
-
() => Promise.resolve().then(() => require("./History-
|
1688
|
+
const ProtectedHistoryPage = React__namespace.lazy(
|
1689
|
+
() => Promise.resolve().then(() => require("./History-d-IgDGPl.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1289
1690
|
);
|
1290
|
-
const routes$
|
1691
|
+
const routes$2 = [
|
1291
1692
|
{
|
1292
1693
|
path: ":collectionType/:slug/:id/history",
|
1293
1694
|
Component: ProtectedHistoryPage
|
@@ -1297,32 +1698,45 @@ const routes$1 = [
|
|
1297
1698
|
Component: ProtectedHistoryPage
|
1298
1699
|
}
|
1299
1700
|
];
|
1701
|
+
const ProtectedPreviewPage = React__namespace.lazy(
|
1702
|
+
() => Promise.resolve().then(() => require("./Preview-PpV3g9wJ.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
|
+
];
|
1300
1714
|
const ProtectedEditViewPage = React.lazy(
|
1301
|
-
() => Promise.resolve().then(() => require("./EditViewPage-
|
1715
|
+
() => Promise.resolve().then(() => require("./EditViewPage-Bb4S7p8c.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1302
1716
|
);
|
1303
1717
|
const ProtectedListViewPage = React.lazy(
|
1304
|
-
() => Promise.resolve().then(() => require("./ListViewPage-
|
1718
|
+
() => Promise.resolve().then(() => require("./ListViewPage-C9gPPp-V.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1305
1719
|
);
|
1306
1720
|
const ProtectedListConfiguration = React.lazy(
|
1307
|
-
() => Promise.resolve().then(() => require("./ListConfigurationPage-
|
1721
|
+
() => Promise.resolve().then(() => require("./ListConfigurationPage-DSX98CYb.js")).then((mod) => ({
|
1308
1722
|
default: mod.ProtectedListConfiguration
|
1309
1723
|
}))
|
1310
1724
|
);
|
1311
1725
|
const ProtectedEditConfigurationPage = React.lazy(
|
1312
|
-
() => Promise.resolve().then(() => require("./EditConfigurationPage-
|
1726
|
+
() => Promise.resolve().then(() => require("./EditConfigurationPage-qgnNvv_u.js")).then((mod) => ({
|
1313
1727
|
default: mod.ProtectedEditConfigurationPage
|
1314
1728
|
}))
|
1315
1729
|
);
|
1316
1730
|
const ProtectedComponentConfigurationPage = React.lazy(
|
1317
|
-
() => Promise.resolve().then(() => require("./ComponentConfigurationPage
|
1731
|
+
() => Promise.resolve().then(() => require("./ComponentConfigurationPage--MCP7Aew.js")).then((mod) => ({
|
1318
1732
|
default: mod.ProtectedComponentConfigurationPage
|
1319
1733
|
}))
|
1320
1734
|
);
|
1321
1735
|
const NoPermissions = React.lazy(
|
1322
|
-
() => Promise.resolve().then(() => require("./NoPermissionsPage-
|
1736
|
+
() => Promise.resolve().then(() => require("./NoPermissionsPage-32WgThJG.js")).then((mod) => ({ default: mod.NoPermissions }))
|
1323
1737
|
);
|
1324
1738
|
const NoContentType = React.lazy(
|
1325
|
-
() => Promise.resolve().then(() => require("./NoContentTypePage-
|
1739
|
+
() => Promise.resolve().then(() => require("./NoContentTypePage-D09gppmy.js")).then((mod) => ({ default: mod.NoContentType }))
|
1326
1740
|
);
|
1327
1741
|
const CollectionTypePages = () => {
|
1328
1742
|
const { collectionType } = reactRouterDom.useParams();
|
@@ -1368,6 +1782,7 @@ const routes = [
|
|
1368
1782
|
path: "no-content-types",
|
1369
1783
|
Component: NoContentType
|
1370
1784
|
},
|
1785
|
+
...routes$2,
|
1371
1786
|
...routes$1
|
1372
1787
|
];
|
1373
1788
|
const DocumentActions = ({ actions: actions2 }) => {
|
@@ -1436,12 +1851,14 @@ const DocumentActionButton = (action) => {
|
|
1436
1851
|
/* @__PURE__ */ jsxRuntime.jsx(
|
1437
1852
|
designSystem.Button,
|
1438
1853
|
{
|
1439
|
-
flex:
|
1854
|
+
flex: "auto",
|
1440
1855
|
startIcon: action.icon,
|
1441
1856
|
disabled: action.disabled,
|
1442
1857
|
onClick: handleClick(action),
|
1443
1858
|
justifyContent: "center",
|
1444
1859
|
variant: action.variant || "default",
|
1860
|
+
paddingTop: "7px",
|
1861
|
+
paddingBottom: "7px",
|
1445
1862
|
children: action.label
|
1446
1863
|
}
|
1447
1864
|
),
|
@@ -1449,7 +1866,7 @@ const DocumentActionButton = (action) => {
|
|
1449
1866
|
DocumentActionConfirmDialog,
|
1450
1867
|
{
|
1451
1868
|
...action.dialog,
|
1452
|
-
variant: action.variant,
|
1869
|
+
variant: action.dialog?.variant ?? action.variant,
|
1453
1870
|
isOpen: dialogId === action.id,
|
1454
1871
|
onClose: handleClose
|
1455
1872
|
}
|
@@ -1506,9 +1923,9 @@ const DocumentActionsMenu = ({
|
|
1506
1923
|
disabled: isDisabled,
|
1507
1924
|
size: "S",
|
1508
1925
|
endIcon: null,
|
1509
|
-
paddingTop: "
|
1510
|
-
paddingLeft: "
|
1511
|
-
paddingRight: "
|
1926
|
+
paddingTop: "4px",
|
1927
|
+
paddingLeft: "7px",
|
1928
|
+
paddingRight: "7px",
|
1512
1929
|
variant,
|
1513
1930
|
children: [
|
1514
1931
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.More, { "aria-hidden": true, focusable: false }),
|
@@ -1519,7 +1936,7 @@ const DocumentActionsMenu = ({
|
|
1519
1936
|
]
|
1520
1937
|
}
|
1521
1938
|
),
|
1522
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, {
|
1939
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1523
1940
|
actions2.map((action) => {
|
1524
1941
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
1525
1942
|
designSystem.Menu.Item,
|
@@ -1528,10 +1945,25 @@ const DocumentActionsMenu = ({
|
|
1528
1945
|
onSelect: handleClick(action),
|
1529
1946
|
display: "block",
|
1530
1947
|
children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", gap: 4, children: [
|
1531
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
1532
|
-
|
1533
|
-
|
1534
|
-
|
1948
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
1949
|
+
designSystem.Flex,
|
1950
|
+
{
|
1951
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1952
|
+
gap: 2,
|
1953
|
+
tag: "span",
|
1954
|
+
children: [
|
1955
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
1956
|
+
designSystem.Flex,
|
1957
|
+
{
|
1958
|
+
tag: "span",
|
1959
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1960
|
+
children: action.icon
|
1961
|
+
}
|
1962
|
+
),
|
1963
|
+
action.label
|
1964
|
+
]
|
1965
|
+
}
|
1966
|
+
),
|
1535
1967
|
action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsxRuntime.jsx(
|
1536
1968
|
designSystem.Flex,
|
1537
1969
|
{
|
@@ -1590,9 +2022,21 @@ const convertActionVariantToColor = (variant = "secondary") => {
|
|
1590
2022
|
return "primary600";
|
1591
2023
|
}
|
1592
2024
|
};
|
1593
|
-
const
|
1594
|
-
|
1595
|
-
|
2025
|
+
const convertActionVariantToIconColor = (variant = "secondary") => {
|
2026
|
+
switch (variant) {
|
2027
|
+
case "danger":
|
2028
|
+
return "danger600";
|
2029
|
+
case "secondary":
|
2030
|
+
return "neutral500";
|
2031
|
+
case "success":
|
2032
|
+
return "success600";
|
2033
|
+
default:
|
2034
|
+
return "primary600";
|
2035
|
+
}
|
2036
|
+
};
|
2037
|
+
const DocumentActionConfirmDialog = ({
|
2038
|
+
onClose,
|
2039
|
+
onCancel,
|
1596
2040
|
onConfirm,
|
1597
2041
|
title,
|
1598
2042
|
content,
|
@@ -1612,22 +2056,20 @@ const DocumentActionConfirmDialog = ({
|
|
1612
2056
|
}
|
1613
2057
|
onClose();
|
1614
2058
|
};
|
1615
|
-
return /* @__PURE__ */ jsxRuntime.
|
1616
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.
|
1617
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
1618
|
-
|
1619
|
-
{
|
1620
|
-
|
1621
|
-
|
1622
|
-
|
1623
|
-
|
1624
|
-
|
1625
|
-
|
1626
|
-
|
1627
|
-
|
1628
|
-
|
1629
|
-
)
|
1630
|
-
] });
|
2059
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
2060
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
2061
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: content }),
|
2062
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
|
2063
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", fullWidth: true, children: formatMessage({
|
2064
|
+
id: "app.components.Button.cancel",
|
2065
|
+
defaultMessage: "Cancel"
|
2066
|
+
}) }) }),
|
2067
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
|
2068
|
+
id: "app.components.Button.confirm",
|
2069
|
+
defaultMessage: "Confirm"
|
2070
|
+
}) })
|
2071
|
+
] })
|
2072
|
+
] }) });
|
1631
2073
|
};
|
1632
2074
|
const DocumentActionModal = ({
|
1633
2075
|
isOpen,
|
@@ -1637,34 +2079,29 @@ const DocumentActionModal = ({
|
|
1637
2079
|
content: Content,
|
1638
2080
|
onModalClose
|
1639
2081
|
}) => {
|
1640
|
-
const id = React__namespace.useId();
|
1641
|
-
if (!isOpen) {
|
1642
|
-
return null;
|
1643
|
-
}
|
1644
2082
|
const handleClose = () => {
|
1645
2083
|
if (onClose) {
|
1646
2084
|
onClose();
|
1647
2085
|
}
|
1648
2086
|
onModalClose();
|
1649
2087
|
};
|
1650
|
-
return /* @__PURE__ */ jsxRuntime.
|
1651
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.
|
1652
|
-
|
1653
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
1654
|
-
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1659
|
-
|
1660
|
-
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
1664
|
-
|
1665
|
-
|
1666
|
-
|
1667
|
-
] });
|
2088
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Content, { children: [
|
2089
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Title, { children: title }) }),
|
2090
|
+
typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, { children: Content }),
|
2091
|
+
typeof Footer === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Footer, { onClose: handleClose }) : Footer
|
2092
|
+
] }) });
|
2093
|
+
};
|
2094
|
+
const transformData = (data) => {
|
2095
|
+
if (Array.isArray(data)) {
|
2096
|
+
return data.map(transformData);
|
2097
|
+
}
|
2098
|
+
if (typeof data === "object" && data !== null) {
|
2099
|
+
if ("apiData" in data) {
|
2100
|
+
return data.apiData;
|
2101
|
+
}
|
2102
|
+
return mapValues__default.default(transformData)(data);
|
2103
|
+
}
|
2104
|
+
return data;
|
1668
2105
|
};
|
1669
2106
|
const PublishAction$1 = ({
|
1670
2107
|
activeTab,
|
@@ -1678,13 +2115,17 @@ const PublishAction$1 = ({
|
|
1678
2115
|
const navigate = reactRouterDom.useNavigate();
|
1679
2116
|
const { toggleNotification } = strapiAdmin.useNotification();
|
1680
2117
|
const { _unstableFormatValidationErrors: formatValidationErrors } = strapiAdmin.useAPIErrorHandler();
|
2118
|
+
const isListView = reactRouterDom.useMatch(LIST_PATH) !== null;
|
1681
2119
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
1682
2120
|
const { formatMessage } = reactIntl.useIntl();
|
1683
|
-
const { canPublish
|
1684
|
-
"PublishAction",
|
1685
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1686
|
-
);
|
2121
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1687
2122
|
const { publish } = useDocumentActions();
|
2123
|
+
const [
|
2124
|
+
countDraftRelations,
|
2125
|
+
{ isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
|
2126
|
+
] = useLazyGetDraftRelationCountQuery();
|
2127
|
+
const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React__namespace.useState(0);
|
2128
|
+
const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React__namespace.useState(0);
|
1688
2129
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1689
2130
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
1690
2131
|
const modified = strapiAdmin.useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
@@ -1693,10 +2134,105 @@ const PublishAction$1 = ({
|
|
1693
2134
|
const validate = strapiAdmin.useForm("PublishAction", (state) => state.validate);
|
1694
2135
|
const setErrors = strapiAdmin.useForm("PublishAction", (state) => state.setErrors);
|
1695
2136
|
const formValues = strapiAdmin.useForm("PublishAction", ({ values }) => values);
|
2137
|
+
React__namespace.useEffect(() => {
|
2138
|
+
if (isErrorDraftRelations) {
|
2139
|
+
toggleNotification({
|
2140
|
+
type: "danger",
|
2141
|
+
message: formatMessage({
|
2142
|
+
id: getTranslation("error.records.fetch-draft-relatons"),
|
2143
|
+
defaultMessage: "An error occurred while fetching draft relations on this document."
|
2144
|
+
})
|
2145
|
+
});
|
2146
|
+
}
|
2147
|
+
}, [isErrorDraftRelations, toggleNotification, formatMessage]);
|
2148
|
+
React__namespace.useEffect(() => {
|
2149
|
+
const localDraftRelations = /* @__PURE__ */ new Set();
|
2150
|
+
const extractDraftRelations = (data) => {
|
2151
|
+
const relations = data.connect || [];
|
2152
|
+
relations.forEach((relation) => {
|
2153
|
+
if (relation.status === "draft") {
|
2154
|
+
localDraftRelations.add(relation.id);
|
2155
|
+
}
|
2156
|
+
});
|
2157
|
+
};
|
2158
|
+
const traverseAndExtract = (data) => {
|
2159
|
+
Object.entries(data).forEach(([key, value]) => {
|
2160
|
+
if (key === "connect" && Array.isArray(value)) {
|
2161
|
+
extractDraftRelations({ connect: value });
|
2162
|
+
} else if (typeof value === "object" && value !== null) {
|
2163
|
+
traverseAndExtract(value);
|
2164
|
+
}
|
2165
|
+
});
|
2166
|
+
};
|
2167
|
+
if (!documentId || modified) {
|
2168
|
+
traverseAndExtract(formValues);
|
2169
|
+
setLocalCountOfDraftRelations(localDraftRelations.size);
|
2170
|
+
}
|
2171
|
+
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
2172
|
+
React__namespace.useEffect(() => {
|
2173
|
+
if (!document || !document.documentId || isListView) {
|
2174
|
+
return;
|
2175
|
+
}
|
2176
|
+
const fetchDraftRelationsCount = async () => {
|
2177
|
+
const { data, error } = await countDraftRelations({
|
2178
|
+
collectionType,
|
2179
|
+
model,
|
2180
|
+
documentId,
|
2181
|
+
params
|
2182
|
+
});
|
2183
|
+
if (error) {
|
2184
|
+
throw error;
|
2185
|
+
}
|
2186
|
+
if (data) {
|
2187
|
+
setServerCountOfDraftRelations(data.data);
|
2188
|
+
}
|
2189
|
+
};
|
2190
|
+
fetchDraftRelationsCount();
|
2191
|
+
}, [isListView, document, documentId, countDraftRelations, collectionType, model, params]);
|
1696
2192
|
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
1697
2193
|
if (!schema?.options?.draftAndPublish) {
|
1698
2194
|
return null;
|
1699
2195
|
}
|
2196
|
+
const performPublish = async () => {
|
2197
|
+
setSubmitting(true);
|
2198
|
+
try {
|
2199
|
+
const { errors } = await validate(true, {
|
2200
|
+
status: "published"
|
2201
|
+
});
|
2202
|
+
if (errors) {
|
2203
|
+
toggleNotification({
|
2204
|
+
type: "danger",
|
2205
|
+
message: formatMessage({
|
2206
|
+
id: "content-manager.validation.error",
|
2207
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2208
|
+
})
|
2209
|
+
});
|
2210
|
+
return;
|
2211
|
+
}
|
2212
|
+
const res = await publish(
|
2213
|
+
{
|
2214
|
+
collectionType,
|
2215
|
+
model,
|
2216
|
+
documentId,
|
2217
|
+
params
|
2218
|
+
},
|
2219
|
+
transformData(formValues)
|
2220
|
+
);
|
2221
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
2222
|
+
navigate({
|
2223
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
2224
|
+
search: rawQuery
|
2225
|
+
});
|
2226
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2227
|
+
setErrors(formatValidationErrors(res.error));
|
2228
|
+
}
|
2229
|
+
} finally {
|
2230
|
+
setSubmitting(false);
|
2231
|
+
}
|
2232
|
+
};
|
2233
|
+
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
2234
|
+
const enableDraftRelationsCount = false;
|
2235
|
+
const hasDraftRelations = enableDraftRelationsCount;
|
1700
2236
|
return {
|
1701
2237
|
/**
|
1702
2238
|
* Disabled when:
|
@@ -1706,49 +2242,36 @@ const PublishAction$1 = ({
|
|
1706
2242
|
* - the document is already published & not modified
|
1707
2243
|
* - the document is being created & not modified
|
1708
2244
|
* - the user doesn't have the permission to publish
|
1709
|
-
* - the user doesn't have the permission to create a new document
|
1710
|
-
* - the user doesn't have the permission to update the document
|
1711
2245
|
*/
|
1712
|
-
disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish
|
2246
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
1713
2247
|
label: formatMessage({
|
1714
2248
|
id: "app.utils.publish",
|
1715
2249
|
defaultMessage: "Publish"
|
1716
2250
|
}),
|
1717
2251
|
onClick: async () => {
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
|
1726
|
-
|
1727
|
-
|
1728
|
-
|
1729
|
-
|
1730
|
-
|
1731
|
-
|
1732
|
-
|
1733
|
-
|
1734
|
-
|
1735
|
-
documentId,
|
1736
|
-
params
|
1737
|
-
},
|
1738
|
-
formValues
|
1739
|
-
);
|
1740
|
-
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1741
|
-
navigate({
|
1742
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1743
|
-
search: rawQuery
|
1744
|
-
});
|
1745
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1746
|
-
setErrors(formatValidationErrors(res.error));
|
2252
|
+
await performPublish();
|
2253
|
+
},
|
2254
|
+
dialog: hasDraftRelations ? {
|
2255
|
+
type: "dialog",
|
2256
|
+
variant: "danger",
|
2257
|
+
footer: null,
|
2258
|
+
title: formatMessage({
|
2259
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
|
2260
|
+
defaultMessage: "Confirmation"
|
2261
|
+
}),
|
2262
|
+
content: formatMessage(
|
2263
|
+
{
|
2264
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
2265
|
+
defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
|
2266
|
+
},
|
2267
|
+
{
|
2268
|
+
count: totalDraftRelations
|
1747
2269
|
}
|
1748
|
-
|
1749
|
-
|
2270
|
+
),
|
2271
|
+
onConfirm: async () => {
|
2272
|
+
await performPublish();
|
1750
2273
|
}
|
1751
|
-
}
|
2274
|
+
} : void 0
|
1752
2275
|
};
|
1753
2276
|
};
|
1754
2277
|
PublishAction$1.type = "publish";
|
@@ -1764,10 +2287,6 @@ const UpdateAction = ({
|
|
1764
2287
|
const cloneMatch = reactRouterDom.useMatch(CLONE_PATH);
|
1765
2288
|
const isCloning = cloneMatch !== null;
|
1766
2289
|
const { formatMessage } = reactIntl.useIntl();
|
1767
|
-
const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1768
|
-
canCreate: canCreate2,
|
1769
|
-
canUpdate: canUpdate2
|
1770
|
-
}));
|
1771
2290
|
const { create, update, clone } = useDocumentActions();
|
1772
2291
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1773
2292
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
@@ -1784,10 +2303,8 @@ const UpdateAction = ({
|
|
1784
2303
|
* - the form is submitting
|
1785
2304
|
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
1786
2305
|
* - the active tab is the published tab
|
1787
|
-
* - the user doesn't have the permission to create a new document
|
1788
|
-
* - the user doesn't have the permission to update the document
|
1789
2306
|
*/
|
1790
|
-
disabled: isSubmitting || !modified && !isCloning || activeTab === "published"
|
2307
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1791
2308
|
label: formatMessage({
|
1792
2309
|
id: "content-manager.containers.Edit.save",
|
1793
2310
|
defaultMessage: "Save"
|
@@ -1795,7 +2312,9 @@ const UpdateAction = ({
|
|
1795
2312
|
onClick: async () => {
|
1796
2313
|
setSubmitting(true);
|
1797
2314
|
try {
|
1798
|
-
const { errors } = await validate(
|
2315
|
+
const { errors } = await validate(true, {
|
2316
|
+
status: "draft"
|
2317
|
+
});
|
1799
2318
|
if (errors) {
|
1800
2319
|
toggleNotification({
|
1801
2320
|
type: "danger",
|
@@ -1813,13 +2332,16 @@ const UpdateAction = ({
|
|
1813
2332
|
documentId: cloneMatch.params.origin,
|
1814
2333
|
params
|
1815
2334
|
},
|
1816
|
-
document
|
2335
|
+
transformData(document)
|
1817
2336
|
);
|
1818
2337
|
if ("data" in res) {
|
1819
|
-
navigate(
|
1820
|
-
|
1821
|
-
|
1822
|
-
|
2338
|
+
navigate(
|
2339
|
+
{
|
2340
|
+
pathname: `../${res.data.documentId}`,
|
2341
|
+
search: rawQuery
|
2342
|
+
},
|
2343
|
+
{ relative: "path" }
|
2344
|
+
);
|
1823
2345
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1824
2346
|
setErrors(formatValidationErrors(res.error));
|
1825
2347
|
}
|
@@ -1831,7 +2353,7 @@ const UpdateAction = ({
|
|
1831
2353
|
documentId,
|
1832
2354
|
params
|
1833
2355
|
},
|
1834
|
-
document
|
2356
|
+
transformData(document)
|
1835
2357
|
);
|
1836
2358
|
if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1837
2359
|
setErrors(formatValidationErrors(res.error));
|
@@ -1844,13 +2366,16 @@ const UpdateAction = ({
|
|
1844
2366
|
model,
|
1845
2367
|
params
|
1846
2368
|
},
|
1847
|
-
document
|
2369
|
+
transformData(document)
|
1848
2370
|
);
|
1849
2371
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1850
|
-
navigate(
|
1851
|
-
|
1852
|
-
|
1853
|
-
|
2372
|
+
navigate(
|
2373
|
+
{
|
2374
|
+
pathname: `../${res.data.documentId}`,
|
2375
|
+
search: rawQuery
|
2376
|
+
},
|
2377
|
+
{ replace: true, relative: "path" }
|
2378
|
+
);
|
1854
2379
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1855
2380
|
setErrors(formatValidationErrors(res.error));
|
1856
2381
|
}
|
@@ -1882,10 +2407,8 @@ const UnpublishAction$1 = ({
|
|
1882
2407
|
const { toggleNotification } = strapiAdmin.useNotification();
|
1883
2408
|
const [shouldKeepDraft, setShouldKeepDraft] = React__namespace.useState(true);
|
1884
2409
|
const isDocumentModified = document?.status === "modified";
|
1885
|
-
const handleChange = (
|
1886
|
-
|
1887
|
-
setShouldKeepDraft(e.target.value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1888
|
-
}
|
2410
|
+
const handleChange = (value) => {
|
2411
|
+
setShouldKeepDraft(value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1889
2412
|
};
|
1890
2413
|
if (!schema?.options?.draftAndPublish) {
|
1891
2414
|
return null;
|
@@ -1896,7 +2419,7 @@ const UnpublishAction$1 = ({
|
|
1896
2419
|
id: "app.utils.unpublish",
|
1897
2420
|
defaultMessage: "Unpublish"
|
1898
2421
|
}),
|
1899
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2422
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Cross, {}),
|
1900
2423
|
onClick: async () => {
|
1901
2424
|
if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
|
1902
2425
|
if (!documentId) {
|
@@ -1935,40 +2458,24 @@ const UnpublishAction$1 = ({
|
|
1935
2458
|
}) })
|
1936
2459
|
] }),
|
1937
2460
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
1938
|
-
designSystem.
|
2461
|
+
designSystem.Radio.Group,
|
1939
2462
|
{
|
1940
|
-
|
1941
|
-
|
1942
|
-
|
1943
|
-
|
1944
|
-
|
1945
|
-
|
2463
|
+
defaultValue: UNPUBLISH_DRAFT_OPTIONS.KEEP,
|
2464
|
+
name: "discard-options",
|
2465
|
+
"aria-label": formatMessage({
|
2466
|
+
id: "content-manager.actions.unpublish.dialog.radio-label",
|
2467
|
+
defaultMessage: "Choose an option to unpublish the document."
|
2468
|
+
}),
|
2469
|
+
onValueChange: handleChange,
|
1946
2470
|
children: [
|
1947
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.
|
1948
|
-
|
1949
|
-
|
1950
|
-
|
1951
|
-
|
1952
|
-
|
1953
|
-
|
1954
|
-
|
1955
|
-
id: "content-manager.actions.unpublish.dialog.option.keep-draft",
|
1956
|
-
defaultMessage: "Keep draft"
|
1957
|
-
})
|
1958
|
-
}
|
1959
|
-
),
|
1960
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
1961
|
-
designSystem.Radio,
|
1962
|
-
{
|
1963
|
-
checked: !shouldKeepDraft,
|
1964
|
-
value: UNPUBLISH_DRAFT_OPTIONS.DISCARD,
|
1965
|
-
name: "discard-options",
|
1966
|
-
children: formatMessage({
|
1967
|
-
id: "content-manager.actions.unpublish.dialog.option.replace-draft",
|
1968
|
-
defaultMessage: "Replace draft"
|
1969
|
-
})
|
1970
|
-
}
|
1971
|
-
)
|
2471
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Radio.Item, { checked: shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.KEEP, children: formatMessage({
|
2472
|
+
id: "content-manager.actions.unpublish.dialog.option.keep-draft",
|
2473
|
+
defaultMessage: "Keep draft"
|
2474
|
+
}) }),
|
2475
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Radio.Item, { checked: !shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.DISCARD, children: formatMessage({
|
2476
|
+
id: "content-manager.actions.unpublish.dialog.option.replace-draft",
|
2477
|
+
defaultMessage: "Replace draft"
|
2478
|
+
}) })
|
1972
2479
|
]
|
1973
2480
|
}
|
1974
2481
|
)
|
@@ -2024,7 +2531,7 @@ const DiscardAction = ({
|
|
2024
2531
|
id: "content-manager.actions.discard.label",
|
2025
2532
|
defaultMessage: "Discard changes"
|
2026
2533
|
}),
|
2027
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2534
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Cross, {}),
|
2028
2535
|
position: ["panel", "table-row"],
|
2029
2536
|
variant: "danger",
|
2030
2537
|
dialog: {
|
@@ -2052,11 +2559,6 @@ const DiscardAction = ({
|
|
2052
2559
|
};
|
2053
2560
|
};
|
2054
2561
|
DiscardAction.type = "discard";
|
2055
|
-
const StyledCrossCircle = styledComponents.styled(Icons.CrossCircle)`
|
2056
|
-
path {
|
2057
|
-
fill: currentColor;
|
2058
|
-
}
|
2059
|
-
`;
|
2060
2562
|
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2061
2563
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2062
2564
|
const RelativeTime = React__namespace.forwardRef(
|
@@ -2104,8 +2606,12 @@ const getDisplayName = ({
|
|
2104
2606
|
};
|
2105
2607
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2106
2608
|
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2107
|
-
const statusVariant = status === "draft" ? "
|
2108
|
-
|
2609
|
+
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2610
|
+
const { formatMessage } = reactIntl.useIntl();
|
2611
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: formatMessage({
|
2612
|
+
id: `content-manager.containers.List.${status}`,
|
2613
|
+
defaultMessage: capitalise(status)
|
2614
|
+
}) }) });
|
2109
2615
|
};
|
2110
2616
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
2111
2617
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2114,23 +2620,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
|
2114
2620
|
id: "content-manager.containers.edit.title.new",
|
2115
2621
|
defaultMessage: "Create an entry"
|
2116
2622
|
}) : documentTitle;
|
2117
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop:
|
2623
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2118
2624
|
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.BackButton, {}),
|
2119
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
2120
|
-
designSystem.
|
2121
|
-
{
|
2122
|
-
|
2123
|
-
|
2124
|
-
paddingTop: 1,
|
2125
|
-
gap: "80px",
|
2126
|
-
alignItems: "flex-start",
|
2127
|
-
children: [
|
2128
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
|
2129
|
-
/* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
|
2130
|
-
]
|
2131
|
-
}
|
2132
|
-
),
|
2133
|
-
status ? /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: isCloning ? "draft" : status }) : null
|
2625
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2626
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
|
2627
|
+
/* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
|
2628
|
+
] }),
|
2629
|
+
status ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 1, children: /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
|
2134
2630
|
] });
|
2135
2631
|
};
|
2136
2632
|
const HeaderToolbar = () => {
|
@@ -2213,12 +2709,12 @@ const Information = ({ activeTab }) => {
|
|
2213
2709
|
isDisplayed: !!publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME],
|
2214
2710
|
label: formatMessage({
|
2215
2711
|
id: "content-manager.containers.edit.information.last-published.label",
|
2216
|
-
defaultMessage: "
|
2712
|
+
defaultMessage: "Published"
|
2217
2713
|
}),
|
2218
2714
|
value: formatMessage(
|
2219
2715
|
{
|
2220
2716
|
id: "content-manager.containers.edit.information.last-published.value",
|
2221
|
-
defaultMessage: `
|
2717
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2222
2718
|
},
|
2223
2719
|
{
|
2224
2720
|
time: /* @__PURE__ */ jsxRuntime.jsx(RelativeTime, { timestamp: new Date(publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME]) }),
|
@@ -2231,12 +2727,12 @@ const Information = ({ activeTab }) => {
|
|
2231
2727
|
isDisplayed: !!createAndUpdateDocument?.[UPDATED_AT_ATTRIBUTE_NAME],
|
2232
2728
|
label: formatMessage({
|
2233
2729
|
id: "content-manager.containers.edit.information.last-draft.label",
|
2234
|
-
defaultMessage: "
|
2730
|
+
defaultMessage: "Updated"
|
2235
2731
|
}),
|
2236
2732
|
value: formatMessage(
|
2237
2733
|
{
|
2238
2734
|
id: "content-manager.containers.edit.information.last-draft.value",
|
2239
|
-
defaultMessage: `
|
2735
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2240
2736
|
},
|
2241
2737
|
{
|
2242
2738
|
time: /* @__PURE__ */ jsxRuntime.jsx(
|
@@ -2254,12 +2750,12 @@ const Information = ({ activeTab }) => {
|
|
2254
2750
|
isDisplayed: !!createAndUpdateDocument?.[CREATED_AT_ATTRIBUTE_NAME],
|
2255
2751
|
label: formatMessage({
|
2256
2752
|
id: "content-manager.containers.edit.information.document.label",
|
2257
|
-
defaultMessage: "
|
2753
|
+
defaultMessage: "Created"
|
2258
2754
|
}),
|
2259
2755
|
value: formatMessage(
|
2260
2756
|
{
|
2261
2757
|
id: "content-manager.containers.edit.information.document.value",
|
2262
|
-
defaultMessage: `
|
2758
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2263
2759
|
},
|
2264
2760
|
{
|
2265
2761
|
time: /* @__PURE__ */ jsxRuntime.jsx(
|
@@ -2297,25 +2793,77 @@ const Information = ({ activeTab }) => {
|
|
2297
2793
|
);
|
2298
2794
|
};
|
2299
2795
|
const HeaderActions = ({ actions: actions2 }) => {
|
2300
|
-
|
2301
|
-
|
2796
|
+
const [dialogId, setDialogId] = React__namespace.useState(null);
|
2797
|
+
const handleClick = (action) => async (e) => {
|
2798
|
+
if (!("options" in action)) {
|
2799
|
+
const { onClick = () => false, dialog, id } = action;
|
2800
|
+
const muteDialog = await onClick(e);
|
2801
|
+
if (dialog && !muteDialog) {
|
2802
|
+
e.preventDefault();
|
2803
|
+
setDialogId(id);
|
2804
|
+
}
|
2805
|
+
}
|
2806
|
+
};
|
2807
|
+
const handleClose = () => {
|
2808
|
+
setDialogId(null);
|
2809
|
+
};
|
2810
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 1, children: actions2.map((action) => {
|
2811
|
+
if (action.options) {
|
2302
2812
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
2303
2813
|
designSystem.SingleSelect,
|
2304
2814
|
{
|
2305
2815
|
size: "S",
|
2306
|
-
disabled: action.disabled,
|
2307
|
-
"aria-label": action.label,
|
2308
2816
|
onChange: action.onSelect,
|
2309
|
-
|
2817
|
+
"aria-label": action.label,
|
2818
|
+
...action,
|
2310
2819
|
children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { ...option, children: label }, option.value))
|
2311
2820
|
},
|
2312
2821
|
action.id
|
2313
2822
|
);
|
2314
2823
|
} else {
|
2315
|
-
|
2824
|
+
if (action.type === "icon") {
|
2825
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
|
2826
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
2827
|
+
designSystem.IconButton,
|
2828
|
+
{
|
2829
|
+
disabled: action.disabled,
|
2830
|
+
label: action.label,
|
2831
|
+
size: "S",
|
2832
|
+
onClick: handleClick(action),
|
2833
|
+
children: action.icon
|
2834
|
+
}
|
2835
|
+
),
|
2836
|
+
action.dialog ? /* @__PURE__ */ jsxRuntime.jsx(
|
2837
|
+
HeaderActionDialog,
|
2838
|
+
{
|
2839
|
+
...action.dialog,
|
2840
|
+
isOpen: dialogId === action.id,
|
2841
|
+
onClose: handleClose
|
2842
|
+
}
|
2843
|
+
) : null
|
2844
|
+
] }, action.id);
|
2845
|
+
}
|
2316
2846
|
}
|
2317
2847
|
}) });
|
2318
2848
|
};
|
2849
|
+
const HeaderActionDialog = ({
|
2850
|
+
onClose,
|
2851
|
+
onCancel,
|
2852
|
+
title,
|
2853
|
+
content: Content,
|
2854
|
+
isOpen
|
2855
|
+
}) => {
|
2856
|
+
const handleClose = async () => {
|
2857
|
+
if (onCancel) {
|
2858
|
+
await onCancel();
|
2859
|
+
}
|
2860
|
+
onClose();
|
2861
|
+
};
|
2862
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
2863
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
2864
|
+
typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : Content
|
2865
|
+
] }) });
|
2866
|
+
};
|
2319
2867
|
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
2320
2868
|
const navigate = reactRouterDom.useNavigate();
|
2321
2869
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2356,12 +2904,16 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2356
2904
|
const { delete: deleteAction } = useDocumentActions();
|
2357
2905
|
const { toggleNotification } = strapiAdmin.useNotification();
|
2358
2906
|
const setSubmitting = strapiAdmin.useForm("DeleteAction", (state) => state.setSubmitting);
|
2907
|
+
const isLocalized = document?.locale != null;
|
2359
2908
|
return {
|
2360
2909
|
disabled: !canDelete || !document,
|
2361
|
-
label: formatMessage(
|
2362
|
-
|
2363
|
-
|
2364
|
-
|
2910
|
+
label: formatMessage(
|
2911
|
+
{
|
2912
|
+
id: "content-manager.actions.delete.label",
|
2913
|
+
defaultMessage: "Delete entry{isLocalized, select, true { (all locales)} other {}}"
|
2914
|
+
},
|
2915
|
+
{ isLocalized }
|
2916
|
+
),
|
2365
2917
|
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {}),
|
2366
2918
|
dialog: {
|
2367
2919
|
type: "dialog",
|
@@ -2451,7 +3003,7 @@ const ActionsPanel = () => {
|
|
2451
3003
|
return {
|
2452
3004
|
title: formatMessage({
|
2453
3005
|
id: "content-manager.containers.edit.panels.default.title",
|
2454
|
-
defaultMessage: "
|
3006
|
+
defaultMessage: "Entry"
|
2455
3007
|
}),
|
2456
3008
|
content: /* @__PURE__ */ jsxRuntime.jsx(ActionsPanelContent, {})
|
2457
3009
|
};
|
@@ -2470,350 +3022,48 @@ const ActionsPanelContent = () => {
|
|
2470
3022
|
activeTab: status,
|
2471
3023
|
model,
|
2472
3024
|
documentId: id,
|
2473
|
-
document: isCloning ? void 0 : document,
|
2474
|
-
meta: isCloning ? void 0 : meta,
|
2475
|
-
collectionType
|
2476
|
-
};
|
2477
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, width: "100%", children: [
|
2478
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
2479
|
-
strapiAdmin.DescriptionComponentRenderer,
|
2480
|
-
{
|
2481
|
-
props,
|
2482
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2483
|
-
children: (actions2) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActions, { actions: actions2 })
|
2484
|
-
}
|
2485
|
-
),
|
2486
|
-
/* @__PURE__ */ jsxRuntime.jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
2487
|
-
] });
|
2488
|
-
};
|
2489
|
-
const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
2490
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
2491
|
-
designSystem.Flex,
|
2492
|
-
{
|
2493
|
-
ref,
|
2494
|
-
tag: "aside",
|
2495
|
-
"aria-labelledby": "additional-information",
|
2496
|
-
background: "neutral0",
|
2497
|
-
borderColor: "neutral150",
|
2498
|
-
hasRadius: true,
|
2499
|
-
paddingBottom: 4,
|
2500
|
-
paddingLeft: 4,
|
2501
|
-
paddingRight: 4,
|
2502
|
-
paddingTop: 4,
|
2503
|
-
shadow: "tableShadow",
|
2504
|
-
gap: 3,
|
2505
|
-
direction: "column",
|
2506
|
-
justifyContent: "stretch",
|
2507
|
-
alignItems: "flex-start",
|
2508
|
-
children: [
|
2509
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2510
|
-
children
|
2511
|
-
]
|
2512
|
-
}
|
2513
|
-
);
|
2514
|
-
});
|
2515
|
-
const HOOKS = {
|
2516
|
-
/**
|
2517
|
-
* Hook that allows to mutate the displayed headers of the list view table
|
2518
|
-
* @constant
|
2519
|
-
* @type {string}
|
2520
|
-
*/
|
2521
|
-
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2522
|
-
/**
|
2523
|
-
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2524
|
-
* @constant
|
2525
|
-
* @type {string}
|
2526
|
-
*/
|
2527
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2528
|
-
/**
|
2529
|
-
* Hook that allows to mutate the CM's edit view layout
|
2530
|
-
* @constant
|
2531
|
-
* @type {string}
|
2532
|
-
*/
|
2533
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2534
|
-
/**
|
2535
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
2536
|
-
* @constant
|
2537
|
-
* @type {string}
|
2538
|
-
*/
|
2539
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2540
|
-
};
|
2541
|
-
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2542
|
-
endpoints: (builder) => ({
|
2543
|
-
getContentTypeConfiguration: builder.query({
|
2544
|
-
query: (uid) => ({
|
2545
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2546
|
-
method: "GET"
|
2547
|
-
}),
|
2548
|
-
transformResponse: (response) => response.data,
|
2549
|
-
providesTags: (_result, _error, uid) => [
|
2550
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2551
|
-
{ type: "ContentTypeSettings", id: "LIST" }
|
2552
|
-
]
|
2553
|
-
}),
|
2554
|
-
getAllContentTypeSettings: builder.query({
|
2555
|
-
query: () => "/content-manager/content-types-settings",
|
2556
|
-
transformResponse: (response) => response.data,
|
2557
|
-
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2558
|
-
}),
|
2559
|
-
updateContentTypeConfiguration: builder.mutation({
|
2560
|
-
query: ({ uid, ...body }) => ({
|
2561
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2562
|
-
method: "PUT",
|
2563
|
-
data: body
|
2564
|
-
}),
|
2565
|
-
transformResponse: (response) => response.data,
|
2566
|
-
invalidatesTags: (_result, _error, { uid }) => [
|
2567
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2568
|
-
{ type: "ContentTypeSettings", id: "LIST" },
|
2569
|
-
// Is this necessary?
|
2570
|
-
{ type: "InitialData" }
|
2571
|
-
]
|
2572
|
-
})
|
2573
|
-
})
|
2574
|
-
});
|
2575
|
-
const {
|
2576
|
-
useGetContentTypeConfigurationQuery,
|
2577
|
-
useGetAllContentTypeSettingsQuery,
|
2578
|
-
useUpdateContentTypeConfigurationMutation
|
2579
|
-
} = contentTypesApi;
|
2580
|
-
const checkIfAttributeIsDisplayable = (attribute) => {
|
2581
|
-
const { type } = attribute;
|
2582
|
-
if (type === "relation") {
|
2583
|
-
return !attribute.relation.toLowerCase().includes("morph");
|
2584
|
-
}
|
2585
|
-
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2586
|
-
};
|
2587
|
-
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2588
|
-
if (!mainFieldName) {
|
2589
|
-
return void 0;
|
2590
|
-
}
|
2591
|
-
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2592
|
-
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2593
|
-
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2594
|
-
);
|
2595
|
-
return {
|
2596
|
-
name: mainFieldName,
|
2597
|
-
type: mainFieldType ?? "string"
|
2598
|
-
};
|
2599
|
-
};
|
2600
|
-
const DEFAULT_SETTINGS = {
|
2601
|
-
bulkable: false,
|
2602
|
-
filterable: false,
|
2603
|
-
searchable: false,
|
2604
|
-
pagination: false,
|
2605
|
-
defaultSortBy: "",
|
2606
|
-
defaultSortOrder: "asc",
|
2607
|
-
mainField: "id",
|
2608
|
-
pageSize: 10
|
2609
|
-
};
|
2610
|
-
const useDocumentLayout = (model) => {
|
2611
|
-
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2612
|
-
const [{ query }] = strapiAdmin.useQueryParams();
|
2613
|
-
const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2614
|
-
const { toggleNotification } = strapiAdmin.useNotification();
|
2615
|
-
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
2616
|
-
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2617
|
-
const {
|
2618
|
-
data,
|
2619
|
-
isLoading: isLoadingConfigs,
|
2620
|
-
error,
|
2621
|
-
isFetching: isFetchingConfigs
|
2622
|
-
} = useGetContentTypeConfigurationQuery(model);
|
2623
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2624
|
-
React__namespace.useEffect(() => {
|
2625
|
-
if (error) {
|
2626
|
-
toggleNotification({
|
2627
|
-
type: "danger",
|
2628
|
-
message: formatAPIError(error)
|
2629
|
-
});
|
2630
|
-
}
|
2631
|
-
}, [error, formatAPIError, toggleNotification]);
|
2632
|
-
const editLayout = React__namespace.useMemo(
|
2633
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2634
|
-
layout: [],
|
2635
|
-
components: {},
|
2636
|
-
metadatas: {},
|
2637
|
-
options: {},
|
2638
|
-
settings: DEFAULT_SETTINGS
|
2639
|
-
},
|
2640
|
-
[data, isLoading, schemas, schema, components]
|
2641
|
-
);
|
2642
|
-
const listLayout = React__namespace.useMemo(() => {
|
2643
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2644
|
-
layout: [],
|
2645
|
-
metadatas: {},
|
2646
|
-
options: {},
|
2647
|
-
settings: DEFAULT_SETTINGS
|
2648
|
-
};
|
2649
|
-
}, [data, isLoading, schemas, schema, components]);
|
2650
|
-
const { layout: edit } = React__namespace.useMemo(
|
2651
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2652
|
-
layout: editLayout,
|
2653
|
-
query
|
2654
|
-
}),
|
2655
|
-
[editLayout, query, runHookWaterfall]
|
2656
|
-
);
|
2657
|
-
return {
|
2658
|
-
error,
|
2659
|
-
isLoading,
|
2660
|
-
edit,
|
2661
|
-
list: listLayout
|
2662
|
-
};
|
2663
|
-
};
|
2664
|
-
const useDocLayout = () => {
|
2665
|
-
const { model } = useDoc();
|
2666
|
-
return useDocumentLayout(model);
|
2667
|
-
};
|
2668
|
-
const formatEditLayout = (data, {
|
2669
|
-
schemas,
|
2670
|
-
schema,
|
2671
|
-
components
|
2672
|
-
}) => {
|
2673
|
-
let currentPanelIndex = 0;
|
2674
|
-
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2675
|
-
data.contentType.layouts.edit,
|
2676
|
-
schema?.attributes,
|
2677
|
-
data.contentType.metadatas,
|
2678
|
-
{ configurations: data.components, schemas: components },
|
2679
|
-
schemas
|
2680
|
-
).reduce((panels, row) => {
|
2681
|
-
if (row.some((field) => field.type === "dynamiczone")) {
|
2682
|
-
panels.push([row]);
|
2683
|
-
currentPanelIndex += 2;
|
2684
|
-
} else {
|
2685
|
-
if (!panels[currentPanelIndex]) {
|
2686
|
-
panels.push([]);
|
2687
|
-
}
|
2688
|
-
panels[currentPanelIndex].push(row);
|
2689
|
-
}
|
2690
|
-
return panels;
|
2691
|
-
}, []);
|
2692
|
-
const componentEditAttributes = Object.entries(data.components).reduce(
|
2693
|
-
(acc, [uid, configuration]) => {
|
2694
|
-
acc[uid] = {
|
2695
|
-
layout: convertEditLayoutToFieldLayouts(
|
2696
|
-
configuration.layouts.edit,
|
2697
|
-
components[uid].attributes,
|
2698
|
-
configuration.metadatas
|
2699
|
-
),
|
2700
|
-
settings: {
|
2701
|
-
...configuration.settings,
|
2702
|
-
icon: components[uid].info.icon,
|
2703
|
-
displayName: components[uid].info.displayName
|
2704
|
-
}
|
2705
|
-
};
|
2706
|
-
return acc;
|
2707
|
-
},
|
2708
|
-
{}
|
2709
|
-
);
|
2710
|
-
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2711
|
-
(acc, [attribute, metadata]) => {
|
2712
|
-
return {
|
2713
|
-
...acc,
|
2714
|
-
[attribute]: metadata.edit
|
2715
|
-
};
|
2716
|
-
},
|
2717
|
-
{}
|
2718
|
-
);
|
2719
|
-
return {
|
2720
|
-
layout: panelledEditAttributes,
|
2721
|
-
components: componentEditAttributes,
|
2722
|
-
metadatas: editMetadatas,
|
2723
|
-
settings: {
|
2724
|
-
...data.contentType.settings,
|
2725
|
-
displayName: schema?.info.displayName
|
2726
|
-
},
|
2727
|
-
options: {
|
2728
|
-
...schema?.options,
|
2729
|
-
...schema?.pluginOptions,
|
2730
|
-
...data.contentType.options
|
2731
|
-
}
|
2732
|
-
};
|
2733
|
-
};
|
2734
|
-
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
2735
|
-
return rows.map(
|
2736
|
-
(row) => row.map((field) => {
|
2737
|
-
const attribute = attributes[field.name];
|
2738
|
-
if (!attribute) {
|
2739
|
-
return null;
|
2740
|
-
}
|
2741
|
-
const { edit: metadata } = metadatas[field.name];
|
2742
|
-
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
2743
|
-
return {
|
2744
|
-
attribute,
|
2745
|
-
disabled: !metadata.editable,
|
2746
|
-
hint: metadata.description,
|
2747
|
-
label: metadata.label ?? "",
|
2748
|
-
name: field.name,
|
2749
|
-
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
2750
|
-
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
2751
|
-
schemas,
|
2752
|
-
components: components?.schemas ?? {}
|
2753
|
-
}),
|
2754
|
-
placeholder: metadata.placeholder ?? "",
|
2755
|
-
required: attribute.required ?? false,
|
2756
|
-
size: field.size,
|
2757
|
-
unique: "unique" in attribute ? attribute.unique : false,
|
2758
|
-
visible: metadata.visible ?? true,
|
2759
|
-
type: attribute.type
|
2760
|
-
};
|
2761
|
-
}).filter((field) => field !== null)
|
2762
|
-
);
|
2763
|
-
};
|
2764
|
-
const formatListLayout = (data, {
|
2765
|
-
schemas,
|
2766
|
-
schema,
|
2767
|
-
components
|
2768
|
-
}) => {
|
2769
|
-
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2770
|
-
(acc, [attribute, metadata]) => {
|
2771
|
-
return {
|
2772
|
-
...acc,
|
2773
|
-
[attribute]: metadata.list
|
2774
|
-
};
|
2775
|
-
},
|
2776
|
-
{}
|
2777
|
-
);
|
2778
|
-
const listAttributes = convertListLayoutToFieldLayouts(
|
2779
|
-
data.contentType.layouts.list,
|
2780
|
-
schema?.attributes,
|
2781
|
-
listMetadatas,
|
2782
|
-
{ configurations: data.components, schemas: components },
|
2783
|
-
schemas
|
2784
|
-
);
|
2785
|
-
return {
|
2786
|
-
layout: listAttributes,
|
2787
|
-
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
2788
|
-
metadatas: listMetadatas,
|
2789
|
-
options: {
|
2790
|
-
...schema?.options,
|
2791
|
-
...schema?.pluginOptions,
|
2792
|
-
...data.contentType.options
|
2793
|
-
}
|
2794
|
-
};
|
2795
|
-
};
|
2796
|
-
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
2797
|
-
return columns.map((name) => {
|
2798
|
-
const attribute = attributes[name];
|
2799
|
-
if (!attribute) {
|
2800
|
-
return null;
|
2801
|
-
}
|
2802
|
-
const metadata = metadatas[name];
|
2803
|
-
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
2804
|
-
return {
|
2805
|
-
attribute,
|
2806
|
-
label: metadata.label ?? "",
|
2807
|
-
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
2808
|
-
schemas,
|
2809
|
-
components: components?.schemas ?? {}
|
2810
|
-
}),
|
2811
|
-
name,
|
2812
|
-
searchable: metadata.searchable ?? true,
|
2813
|
-
sortable: metadata.sortable ?? true
|
2814
|
-
};
|
2815
|
-
}).filter((field) => field !== null);
|
3025
|
+
document: isCloning ? void 0 : document,
|
3026
|
+
meta: isCloning ? void 0 : meta,
|
3027
|
+
collectionType
|
3028
|
+
};
|
3029
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, width: "100%", children: [
|
3030
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
3031
|
+
strapiAdmin.DescriptionComponentRenderer,
|
3032
|
+
{
|
3033
|
+
props,
|
3034
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3035
|
+
children: (actions2) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActions, { actions: actions2 })
|
3036
|
+
}
|
3037
|
+
),
|
3038
|
+
/* @__PURE__ */ jsxRuntime.jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
3039
|
+
] });
|
2816
3040
|
};
|
3041
|
+
const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
3042
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
3043
|
+
designSystem.Flex,
|
3044
|
+
{
|
3045
|
+
ref,
|
3046
|
+
tag: "aside",
|
3047
|
+
"aria-labelledby": "additional-information",
|
3048
|
+
background: "neutral0",
|
3049
|
+
borderColor: "neutral150",
|
3050
|
+
hasRadius: true,
|
3051
|
+
paddingBottom: 4,
|
3052
|
+
paddingLeft: 4,
|
3053
|
+
paddingRight: 4,
|
3054
|
+
paddingTop: 4,
|
3055
|
+
shadow: "tableShadow",
|
3056
|
+
gap: 3,
|
3057
|
+
direction: "column",
|
3058
|
+
justifyContent: "stretch",
|
3059
|
+
alignItems: "flex-start",
|
3060
|
+
children: [
|
3061
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", textColor: "neutral600", children: title }),
|
3062
|
+
children
|
3063
|
+
]
|
3064
|
+
}
|
3065
|
+
);
|
3066
|
+
});
|
2817
3067
|
const ConfirmBulkActionDialog = ({
|
2818
3068
|
onToggleDialog,
|
2819
3069
|
isOpen = false,
|
@@ -2821,30 +3071,23 @@ const ConfirmBulkActionDialog = ({
|
|
2821
3071
|
endAction
|
2822
3072
|
}) => {
|
2823
3073
|
const { formatMessage } = reactIntl.useIntl();
|
2824
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
2825
|
-
designSystem.Dialog,
|
2826
|
-
|
2827
|
-
|
2828
|
-
|
2829
|
-
|
2830
|
-
|
2831
|
-
|
2832
|
-
|
2833
|
-
|
2834
|
-
|
2835
|
-
|
2836
|
-
|
2837
|
-
|
2838
|
-
|
2839
|
-
|
2840
|
-
|
2841
|
-
}) }),
|
2842
|
-
endAction
|
2843
|
-
}
|
2844
|
-
)
|
2845
|
-
]
|
2846
|
-
}
|
2847
|
-
);
|
3074
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
3075
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: formatMessage({
|
3076
|
+
id: "app.components.ConfirmDialog.title",
|
3077
|
+
defaultMessage: "Confirmation"
|
3078
|
+
}) }),
|
3079
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3080
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3081
|
+
dialogBody
|
3082
|
+
] }) }),
|
3083
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
|
3084
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { fullWidth: true, onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
|
3085
|
+
id: "app.components.Button.cancel",
|
3086
|
+
defaultMessage: "Cancel"
|
3087
|
+
}) }) }),
|
3088
|
+
endAction
|
3089
|
+
] })
|
3090
|
+
] }) });
|
2848
3091
|
};
|
2849
3092
|
const BoldChunk$1 = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
|
2850
3093
|
const ConfirmDialogPublishAll = ({
|
@@ -2859,6 +3102,7 @@ const ConfirmDialogPublishAll = ({
|
|
2859
3102
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler(getTranslation);
|
2860
3103
|
const { model, schema } = useDoc();
|
2861
3104
|
const [{ query }] = strapiAdmin.useQueryParams();
|
3105
|
+
const enableDraftRelationsCount = false;
|
2862
3106
|
const {
|
2863
3107
|
data: countDraftRelations = 0,
|
2864
3108
|
isLoading,
|
@@ -2870,7 +3114,7 @@ const ConfirmDialogPublishAll = ({
|
|
2870
3114
|
locale: query?.plugins?.i18n?.locale
|
2871
3115
|
},
|
2872
3116
|
{
|
2873
|
-
skip:
|
3117
|
+
skip: !enableDraftRelationsCount
|
2874
3118
|
}
|
2875
3119
|
);
|
2876
3120
|
React__namespace.useEffect(() => {
|
@@ -2949,16 +3193,30 @@ const formatErrorMessages = (errors, parentKey, formatMessage) => {
|
|
2949
3193
|
)
|
2950
3194
|
);
|
2951
3195
|
} else {
|
2952
|
-
messages.push(
|
3196
|
+
messages.push(
|
3197
|
+
...formatErrorMessages(
|
3198
|
+
// @ts-expect-error TODO: check why value is not compatible with FormErrors
|
3199
|
+
value,
|
3200
|
+
currentKey,
|
3201
|
+
formatMessage
|
3202
|
+
)
|
3203
|
+
);
|
2953
3204
|
}
|
3205
|
+
} else {
|
3206
|
+
messages.push(
|
3207
|
+
formatMessage(
|
3208
|
+
{
|
3209
|
+
id: `${value}.withField`,
|
3210
|
+
defaultMessage: value
|
3211
|
+
},
|
3212
|
+
{ field: currentKey }
|
3213
|
+
)
|
3214
|
+
);
|
2954
3215
|
}
|
2955
3216
|
});
|
2956
3217
|
return messages;
|
2957
3218
|
};
|
2958
|
-
const EntryValidationText = ({
|
2959
|
-
validationErrors,
|
2960
|
-
isPublished = false
|
2961
|
-
}) => {
|
3219
|
+
const EntryValidationText = ({ validationErrors, status }) => {
|
2962
3220
|
const { formatMessage } = reactIntl.useIntl();
|
2963
3221
|
if (validationErrors) {
|
2964
3222
|
const validationErrorsMessages = formatErrorMessages(validationErrors, "", formatMessage).join(
|
@@ -2969,7 +3227,7 @@ const EntryValidationText = ({
|
|
2969
3227
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsxRuntime.jsx(TypographyMaxWidth, { textColor: "danger600", variant: "omega", fontWeight: "semiBold", ellipsis: true, children: validationErrorsMessages }) })
|
2970
3228
|
] });
|
2971
3229
|
}
|
2972
|
-
if (
|
3230
|
+
if (status === "published") {
|
2973
3231
|
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
2974
3232
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.CheckCircle, { fill: "success600" }),
|
2975
3233
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
|
@@ -2978,6 +3236,15 @@ const EntryValidationText = ({
|
|
2978
3236
|
}) })
|
2979
3237
|
] });
|
2980
3238
|
}
|
3239
|
+
if (status === "modified") {
|
3240
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3241
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.ArrowsCounterClockwise, { fill: "alternative600" }),
|
3242
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
|
3243
|
+
id: "content-manager.bulk-publish.modified",
|
3244
|
+
defaultMessage: "Ready to publish changes"
|
3245
|
+
}) })
|
3246
|
+
] });
|
3247
|
+
}
|
2981
3248
|
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
2982
3249
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.CheckCircle, { fill: "success600" }),
|
2983
3250
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
|
@@ -3029,10 +3296,10 @@ const SelectedEntriesTableContent = ({
|
|
3029
3296
|
EntryValidationText,
|
3030
3297
|
{
|
3031
3298
|
validationErrors: validationErrors[row.documentId],
|
3032
|
-
|
3299
|
+
status: row.status
|
3033
3300
|
}
|
3034
3301
|
) }),
|
3035
|
-
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
3302
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
3036
3303
|
designSystem.IconButton,
|
3037
3304
|
{
|
3038
3305
|
tag: reactRouterDom.Link,
|
@@ -3055,9 +3322,10 @@ const SelectedEntriesTableContent = ({
|
|
3055
3322
|
),
|
3056
3323
|
target: "_blank",
|
3057
3324
|
marginLeft: "auto",
|
3058
|
-
|
3325
|
+
variant: "ghost",
|
3326
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, { width: "1.6rem", height: "1.6rem" })
|
3059
3327
|
}
|
3060
|
-
) })
|
3328
|
+
) }) })
|
3061
3329
|
] }, row.id)) })
|
3062
3330
|
] });
|
3063
3331
|
};
|
@@ -3094,7 +3362,13 @@ const SelectedEntriesModalContent = ({
|
|
3094
3362
|
);
|
3095
3363
|
const { rows, validationErrors } = React__namespace.useMemo(() => {
|
3096
3364
|
if (data.length > 0 && schema) {
|
3097
|
-
const validate = createYupSchema(
|
3365
|
+
const validate = createYupSchema(
|
3366
|
+
schema.attributes,
|
3367
|
+
components,
|
3368
|
+
// Since this is the "Publish" action, the validation
|
3369
|
+
// schema must enforce the rules for published entities
|
3370
|
+
{ status: "published" }
|
3371
|
+
);
|
3098
3372
|
const validationErrors2 = {};
|
3099
3373
|
const rows2 = data.map((entry) => {
|
3100
3374
|
try {
|
@@ -3170,7 +3444,7 @@ const SelectedEntriesModalContent = ({
|
|
3170
3444
|
);
|
3171
3445
|
};
|
3172
3446
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
3173
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.
|
3447
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Body, { children: [
|
3174
3448
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: getFormattedCountMessage() }),
|
3175
3449
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 5, children: /* @__PURE__ */ jsxRuntime.jsx(
|
3176
3450
|
SelectedEntriesTableContent,
|
@@ -3182,27 +3456,24 @@ const SelectedEntriesModalContent = ({
|
|
3182
3456
|
}
|
3183
3457
|
) })
|
3184
3458
|
] }),
|
3185
|
-
/* @__PURE__ */ jsxRuntime.
|
3186
|
-
designSystem.
|
3187
|
-
|
3188
|
-
|
3189
|
-
|
3190
|
-
|
3191
|
-
}) }),
|
3192
|
-
|
3193
|
-
|
3194
|
-
|
3195
|
-
|
3196
|
-
|
3197
|
-
|
3198
|
-
|
3199
|
-
|
3200
|
-
|
3201
|
-
|
3202
|
-
|
3203
|
-
] })
|
3204
|
-
}
|
3205
|
-
),
|
3459
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
3460
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
|
3461
|
+
id: "app.components.Button.cancel",
|
3462
|
+
defaultMessage: "Cancel"
|
3463
|
+
}) }),
|
3464
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3465
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
|
3466
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
3467
|
+
designSystem.Button,
|
3468
|
+
{
|
3469
|
+
onClick: toggleDialog,
|
3470
|
+
disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
|
3471
|
+
loading: isSubmittingForm,
|
3472
|
+
children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
|
3473
|
+
}
|
3474
|
+
)
|
3475
|
+
] })
|
3476
|
+
] }),
|
3206
3477
|
/* @__PURE__ */ jsxRuntime.jsx(
|
3207
3478
|
ConfirmDialogPublishAll,
|
3208
3479
|
{
|
@@ -3267,143 +3538,10 @@ const BulkActionsRenderer = () => {
|
|
3267
3538
|
documents: selectedRows
|
3268
3539
|
},
|
3269
3540
|
descriptions: plugins["content-manager"].apis.getBulkActions(),
|
3270
|
-
children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsxRuntime.jsx(
|
3541
|
+
children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActionButton, { ...action }, action.id))
|
3271
3542
|
}
|
3272
3543
|
) });
|
3273
3544
|
};
|
3274
|
-
const BulkActionAction = (action) => {
|
3275
|
-
const [dialogId, setDialogId] = React__namespace.useState(null);
|
3276
|
-
const { toggleNotification } = strapiAdmin.useNotification();
|
3277
|
-
const handleClick = (action2) => (e) => {
|
3278
|
-
const { onClick, dialog, id } = action2;
|
3279
|
-
if (onClick) {
|
3280
|
-
onClick(e);
|
3281
|
-
}
|
3282
|
-
if (dialog) {
|
3283
|
-
switch (dialog.type) {
|
3284
|
-
case "notification":
|
3285
|
-
toggleNotification({
|
3286
|
-
title: dialog.title,
|
3287
|
-
message: dialog.content,
|
3288
|
-
type: dialog.status,
|
3289
|
-
timeout: dialog.timeout,
|
3290
|
-
onClose: dialog.onClose
|
3291
|
-
});
|
3292
|
-
break;
|
3293
|
-
case "dialog":
|
3294
|
-
case "modal": {
|
3295
|
-
e.preventDefault();
|
3296
|
-
setDialogId(id);
|
3297
|
-
}
|
3298
|
-
}
|
3299
|
-
}
|
3300
|
-
};
|
3301
|
-
const handleClose = () => {
|
3302
|
-
setDialogId(null);
|
3303
|
-
if (action.dialog?.type === "modal" && action.dialog?.onClose) {
|
3304
|
-
action.dialog.onClose();
|
3305
|
-
}
|
3306
|
-
};
|
3307
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
3308
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
3309
|
-
designSystem.Button,
|
3310
|
-
{
|
3311
|
-
disabled: action.disabled,
|
3312
|
-
startIcon: action.icon,
|
3313
|
-
variant: action.variant,
|
3314
|
-
onClick: handleClick(action),
|
3315
|
-
children: action.label
|
3316
|
-
}
|
3317
|
-
),
|
3318
|
-
action.dialog?.type === "dialog" ? /* @__PURE__ */ jsxRuntime.jsx(
|
3319
|
-
BulkActionConfirmDialog,
|
3320
|
-
{
|
3321
|
-
...action.dialog,
|
3322
|
-
variant: action.variant,
|
3323
|
-
isOpen: dialogId === action.id,
|
3324
|
-
onClose: handleClose
|
3325
|
-
}
|
3326
|
-
) : null,
|
3327
|
-
action.dialog?.type === "modal" ? /* @__PURE__ */ jsxRuntime.jsx(
|
3328
|
-
BulkActionModal,
|
3329
|
-
{
|
3330
|
-
...action.dialog,
|
3331
|
-
onModalClose: handleClose,
|
3332
|
-
isOpen: dialogId === action.id
|
3333
|
-
}
|
3334
|
-
) : null
|
3335
|
-
] });
|
3336
|
-
};
|
3337
|
-
const BulkActionConfirmDialog = ({
|
3338
|
-
onClose,
|
3339
|
-
onCancel,
|
3340
|
-
onConfirm,
|
3341
|
-
title,
|
3342
|
-
content,
|
3343
|
-
confirmButton,
|
3344
|
-
isOpen,
|
3345
|
-
variant = "secondary"
|
3346
|
-
}) => {
|
3347
|
-
const { formatMessage } = reactIntl.useIntl();
|
3348
|
-
const handleClose = async () => {
|
3349
|
-
if (onCancel) {
|
3350
|
-
await onCancel();
|
3351
|
-
}
|
3352
|
-
onClose();
|
3353
|
-
};
|
3354
|
-
const handleConfirm = async () => {
|
3355
|
-
if (onConfirm) {
|
3356
|
-
await onConfirm();
|
3357
|
-
}
|
3358
|
-
onClose();
|
3359
|
-
};
|
3360
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog, { isOpen, title, onClose: handleClose, children: [
|
3361
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.DialogBody, { icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, {}), children: content }),
|
3362
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
3363
|
-
designSystem.DialogFooter,
|
3364
|
-
{
|
3365
|
-
startAction: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleClose, variant: "tertiary", children: formatMessage({
|
3366
|
-
id: "app.components.Button.cancel",
|
3367
|
-
defaultMessage: "Cancel"
|
3368
|
-
}) }),
|
3369
|
-
endAction: /* @__PURE__ */ jsxRuntime.jsx(
|
3370
|
-
designSystem.Button,
|
3371
|
-
{
|
3372
|
-
onClick: handleConfirm,
|
3373
|
-
variant: variant === "danger-light" ? variant : "secondary",
|
3374
|
-
startIcon: variant === "danger-light" ? /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {}) : /* @__PURE__ */ jsxRuntime.jsx(Icons.Check, {}),
|
3375
|
-
children: confirmButton ? confirmButton : formatMessage({
|
3376
|
-
id: "app.components.Button.confirm",
|
3377
|
-
defaultMessage: "Confirm"
|
3378
|
-
})
|
3379
|
-
}
|
3380
|
-
)
|
3381
|
-
}
|
3382
|
-
)
|
3383
|
-
] });
|
3384
|
-
};
|
3385
|
-
const BulkActionModal = ({
|
3386
|
-
isOpen,
|
3387
|
-
title,
|
3388
|
-
onClose,
|
3389
|
-
content: Content,
|
3390
|
-
onModalClose
|
3391
|
-
}) => {
|
3392
|
-
const id = React__namespace.useId();
|
3393
|
-
if (!isOpen) {
|
3394
|
-
return null;
|
3395
|
-
}
|
3396
|
-
const handleClose = () => {
|
3397
|
-
if (onClose) {
|
3398
|
-
onClose();
|
3399
|
-
}
|
3400
|
-
onModalClose();
|
3401
|
-
};
|
3402
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.ModalLayout, { borderRadius: "4px", overflow: "hidden", onClose: handleClose, labelledBy: id, children: [
|
3403
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", textColor: "neutral800", tag: "h2", id, children: title }) }),
|
3404
|
-
/* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose })
|
3405
|
-
] });
|
3406
|
-
};
|
3407
3545
|
const DeleteAction = ({ documents, model }) => {
|
3408
3546
|
const { formatMessage } = reactIntl.useIntl();
|
3409
3547
|
const { schema: contentType } = useDoc();
|
@@ -3436,6 +3574,7 @@ const DeleteAction = ({ documents, model }) => {
|
|
3436
3574
|
defaultMessage: "Confirmation"
|
3437
3575
|
}),
|
3438
3576
|
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3577
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3439
3578
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
|
3440
3579
|
id: "popUpWarning.bodyMessage.contentType.delete.all",
|
3441
3580
|
defaultMessage: "Are you sure you want to delete these entries?"
|
@@ -3472,7 +3611,7 @@ const UnpublishAction = ({ documents, model }) => {
|
|
3472
3611
|
selectRow([]);
|
3473
3612
|
}
|
3474
3613
|
};
|
3475
|
-
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published");
|
3614
|
+
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
|
3476
3615
|
if (!showUnpublishButton)
|
3477
3616
|
return null;
|
3478
3617
|
return {
|
@@ -3485,6 +3624,7 @@ const UnpublishAction = ({ documents, model }) => {
|
|
3485
3624
|
defaultMessage: "Confirmation"
|
3486
3625
|
}),
|
3487
3626
|
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3627
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3488
3628
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
|
3489
3629
|
id: "popUpWarning.bodyMessage.contentType.unpublish.all",
|
3490
3630
|
defaultMessage: "Are you sure you want to unpublish these entries?"
|
@@ -3578,7 +3718,7 @@ const TableActions = ({ document }) => {
|
|
3578
3718
|
strapiAdmin.DescriptionComponentRenderer,
|
3579
3719
|
{
|
3580
3720
|
props,
|
3581
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3721
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
3582
3722
|
children: (actions2) => {
|
3583
3723
|
const tableRowActions = actions2.filter((action) => {
|
3584
3724
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3689,7 +3829,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3689
3829
|
}),
|
3690
3830
|
content: /* @__PURE__ */ jsxRuntime.jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
3691
3831
|
footer: ({ onClose }) => {
|
3692
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.
|
3832
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
3693
3833
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
3694
3834
|
id: "cancel",
|
3695
3835
|
defaultMessage: "Cancel"
|
@@ -3730,8 +3870,7 @@ class ContentManagerPlugin {
|
|
3730
3870
|
documentActions = [
|
3731
3871
|
...DEFAULT_ACTIONS,
|
3732
3872
|
...DEFAULT_TABLE_ROW_ACTIONS,
|
3733
|
-
...DEFAULT_HEADER_ACTIONS
|
3734
|
-
HistoryAction
|
3873
|
+
...DEFAULT_HEADER_ACTIONS
|
3735
3874
|
];
|
3736
3875
|
editViewSidePanels = [ActionsPanel];
|
3737
3876
|
headerActions = [];
|
@@ -3820,6 +3959,52 @@ const getPrintableType = (value) => {
|
|
3820
3959
|
}
|
3821
3960
|
return nativeType;
|
3822
3961
|
};
|
3962
|
+
const HistoryAction = ({ model, document }) => {
|
3963
|
+
const { formatMessage } = reactIntl.useIntl();
|
3964
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3965
|
+
const navigate = reactRouterDom.useNavigate();
|
3966
|
+
const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
|
3967
|
+
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3968
|
+
return null;
|
3969
|
+
}
|
3970
|
+
return {
|
3971
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
|
3972
|
+
label: formatMessage({
|
3973
|
+
id: "content-manager.history.document-action",
|
3974
|
+
defaultMessage: "Content History"
|
3975
|
+
}),
|
3976
|
+
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
3977
|
+
disabled: (
|
3978
|
+
/**
|
3979
|
+
* The user is creating a new document.
|
3980
|
+
* It hasn't been saved yet, so there's no history to go to
|
3981
|
+
*/
|
3982
|
+
!document || /**
|
3983
|
+
* The document has been created but the current dimension has never been saved.
|
3984
|
+
* For example, the user is creating a new locale in an existing document,
|
3985
|
+
* so there's no history for the document in that locale
|
3986
|
+
*/
|
3987
|
+
!document.id || /**
|
3988
|
+
* History is only available for content types created by the user.
|
3989
|
+
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
3990
|
+
* which start with `admin::` or `plugin::`
|
3991
|
+
*/
|
3992
|
+
!model.startsWith("api::")
|
3993
|
+
),
|
3994
|
+
position: "header"
|
3995
|
+
};
|
3996
|
+
};
|
3997
|
+
HistoryAction.type = "history";
|
3998
|
+
const historyAdmin = {
|
3999
|
+
bootstrap(app) {
|
4000
|
+
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
4001
|
+
addDocumentAction((actions2) => {
|
4002
|
+
const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
|
4003
|
+
actions2.splice(indexOfDeleteAction, 0, HistoryAction);
|
4004
|
+
return actions2;
|
4005
|
+
});
|
4006
|
+
}
|
4007
|
+
};
|
3823
4008
|
const initialState = {
|
3824
4009
|
collectionTypeLinks: [],
|
3825
4010
|
components: [],
|
@@ -3856,6 +4041,70 @@ const { setInitialData } = actions;
|
|
3856
4041
|
const reducer = toolkit.combineReducers({
|
3857
4042
|
app: reducer$1
|
3858
4043
|
});
|
4044
|
+
const previewApi = contentManagerApi.injectEndpoints({
|
4045
|
+
endpoints: (builder) => ({
|
4046
|
+
getPreviewUrl: builder.query({
|
4047
|
+
query({ query, params }) {
|
4048
|
+
return {
|
4049
|
+
url: `/content-manager/preview/url/${params.contentType}`,
|
4050
|
+
method: "GET",
|
4051
|
+
config: {
|
4052
|
+
params: query
|
4053
|
+
}
|
4054
|
+
};
|
4055
|
+
}
|
4056
|
+
})
|
4057
|
+
})
|
4058
|
+
});
|
4059
|
+
const { useGetPreviewUrlQuery } = previewApi;
|
4060
|
+
const PreviewSidePanel = ({ model, documentId, document }) => {
|
4061
|
+
const { formatMessage } = reactIntl.useIntl();
|
4062
|
+
const { trackUsage } = strapiAdmin.useTracking();
|
4063
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
4064
|
+
const { data, error } = useGetPreviewUrlQuery({
|
4065
|
+
params: {
|
4066
|
+
contentType: model
|
4067
|
+
},
|
4068
|
+
query: {
|
4069
|
+
documentId,
|
4070
|
+
locale: document?.locale,
|
4071
|
+
status: document?.status
|
4072
|
+
}
|
4073
|
+
});
|
4074
|
+
if (!data?.data?.url || error) {
|
4075
|
+
return null;
|
4076
|
+
}
|
4077
|
+
const handleClick = () => {
|
4078
|
+
trackUsage("willOpenPreview");
|
4079
|
+
};
|
4080
|
+
return {
|
4081
|
+
title: formatMessage({ id: "content-manager.preview.panel.title", defaultMessage: "Preview" }),
|
4082
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, width: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(
|
4083
|
+
designSystem.Button,
|
4084
|
+
{
|
4085
|
+
variant: "tertiary",
|
4086
|
+
tag: reactRouterDom.Link,
|
4087
|
+
to: { pathname: "preview", search: qs.stringify(query, { encode: false }) },
|
4088
|
+
onClick: handleClick,
|
4089
|
+
flex: "auto",
|
4090
|
+
children: formatMessage({
|
4091
|
+
id: "content-manager.preview.panel.button",
|
4092
|
+
defaultMessage: "Open preview"
|
4093
|
+
})
|
4094
|
+
}
|
4095
|
+
) })
|
4096
|
+
};
|
4097
|
+
};
|
4098
|
+
const FEATURE_ID = "preview";
|
4099
|
+
const previewAdmin = {
|
4100
|
+
bootstrap(app) {
|
4101
|
+
if (!window.strapi.future.isEnabled(FEATURE_ID)) {
|
4102
|
+
return;
|
4103
|
+
}
|
4104
|
+
const contentManagerPluginApis = app.getPlugin("content-manager").apis;
|
4105
|
+
contentManagerPluginApis.addEditViewSidePanel([PreviewSidePanel]);
|
4106
|
+
}
|
4107
|
+
};
|
3859
4108
|
const index = {
|
3860
4109
|
register(app) {
|
3861
4110
|
const cm = new ContentManagerPlugin();
|
@@ -3870,15 +4119,32 @@ const index = {
|
|
3870
4119
|
defaultMessage: "Content Manager"
|
3871
4120
|
},
|
3872
4121
|
permissions: [],
|
3873
|
-
Component: () => Promise.resolve().then(() => require("./layout-b91XRlD2.js")).then((mod) => ({ default: mod.Layout })),
|
3874
4122
|
position: 1
|
3875
4123
|
});
|
4124
|
+
app.router.addRoute({
|
4125
|
+
path: "content-manager/*",
|
4126
|
+
lazy: async () => {
|
4127
|
+
const { Layout } = await Promise.resolve().then(() => require("./layout-CkaP4K5_.js"));
|
4128
|
+
return {
|
4129
|
+
Component: Layout
|
4130
|
+
};
|
4131
|
+
},
|
4132
|
+
children: routes
|
4133
|
+
});
|
3876
4134
|
app.registerPlugin(cm.config);
|
3877
4135
|
},
|
4136
|
+
bootstrap(app) {
|
4137
|
+
if (typeof historyAdmin.bootstrap === "function") {
|
4138
|
+
historyAdmin.bootstrap(app);
|
4139
|
+
}
|
4140
|
+
if (typeof previewAdmin.bootstrap === "function") {
|
4141
|
+
previewAdmin.bootstrap(app);
|
4142
|
+
}
|
4143
|
+
},
|
3878
4144
|
async registerTrads({ locales }) {
|
3879
4145
|
const importedTrads = await Promise.all(
|
3880
4146
|
locales.map((locale) => {
|
3881
|
-
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-
|
4147
|
+
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-CHOp_xJv.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 }) => {
|
3882
4148
|
return {
|
3883
4149
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3884
4150
|
locale
|
@@ -3896,6 +4162,7 @@ const index = {
|
|
3896
4162
|
};
|
3897
4163
|
exports.ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD = ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD;
|
3898
4164
|
exports.BulkActionsRenderer = BulkActionsRenderer;
|
4165
|
+
exports.CLONE_PATH = CLONE_PATH;
|
3899
4166
|
exports.COLLECTION_TYPES = COLLECTION_TYPES;
|
3900
4167
|
exports.CREATOR_FIELDS = CREATOR_FIELDS;
|
3901
4168
|
exports.DEFAULT_SETTINGS = DEFAULT_SETTINGS;
|
@@ -3922,8 +4189,8 @@ exports.getDisplayName = getDisplayName;
|
|
3922
4189
|
exports.getMainField = getMainField;
|
3923
4190
|
exports.getTranslation = getTranslation;
|
3924
4191
|
exports.index = index;
|
3925
|
-
exports.routes = routes;
|
3926
4192
|
exports.setInitialData = setInitialData;
|
4193
|
+
exports.useContentManagerContext = useContentManagerContext;
|
3927
4194
|
exports.useContentTypeSchema = useContentTypeSchema;
|
3928
4195
|
exports.useDoc = useDoc;
|
3929
4196
|
exports.useDocLayout = useDocLayout;
|
@@ -3935,5 +4202,6 @@ exports.useGetAllContentTypeSettingsQuery = useGetAllContentTypeSettingsQuery;
|
|
3935
4202
|
exports.useGetAllDocumentsQuery = useGetAllDocumentsQuery;
|
3936
4203
|
exports.useGetContentTypeConfigurationQuery = useGetContentTypeConfigurationQuery;
|
3937
4204
|
exports.useGetInitialDataQuery = useGetInitialDataQuery;
|
4205
|
+
exports.useGetPreviewUrlQuery = useGetPreviewUrlQuery;
|
3938
4206
|
exports.useUpdateContentTypeConfigurationMutation = useUpdateContentTypeConfigurationMutation;
|
3939
|
-
//# sourceMappingURL=index-
|
4207
|
+
//# sourceMappingURL=index-iun2i4xv.js.map
|