@strapi/content-manager 0.0.0-experimental.a65a85fdea97faae8679d3ffc5f9d79af61abd26 → 0.0.0-experimental.abc
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/{CardDragPreview-DSVYodBX.js → CardDragPreview-C0QyJgRA.js} +10 -14
- package/dist/_chunks/CardDragPreview-C0QyJgRA.js.map +1 -0
- package/dist/_chunks/{CardDragPreview-ikSG4M46.mjs → CardDragPreview-DOxamsuj.mjs} +7 -9
- package/dist/_chunks/CardDragPreview-DOxamsuj.mjs.map +1 -0
- package/dist/_chunks/{ComponentConfigurationPage--2aLCv-G.mjs → ComponentConfigurationPage-B3yDbeU1.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage--2aLCv-G.mjs.map → ComponentConfigurationPage-B3yDbeU1.mjs.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-43KmCNQE.js → ComponentConfigurationPage-KXSuLnQD.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-43KmCNQE.js.map → ComponentConfigurationPage-KXSuLnQD.js.map} +1 -1
- package/dist/_chunks/{ComponentIcon-BBQsYCVn.js → ComponentIcon-BXdiCGQp.js} +8 -2
- package/dist/_chunks/ComponentIcon-BXdiCGQp.js.map +1 -0
- package/dist/_chunks/{ComponentIcon-BOFnK76n.mjs → ComponentIcon-u4bIXTFY.mjs} +9 -3
- package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +1 -0
- package/dist/_chunks/{EditConfigurationPage-BfFzJ4Br.js → EditConfigurationPage-BQ17--5R.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-BfFzJ4Br.js.map → EditConfigurationPage-BQ17--5R.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-CUcGHHvQ.mjs → EditConfigurationPage-D7PrLO8j.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-CUcGHHvQ.mjs.map → EditConfigurationPage-D7PrLO8j.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-Bm8lgcm6.mjs → EditViewPage-B7VgwJaG.mjs} +58 -47
- package/dist/_chunks/EditViewPage-B7VgwJaG.mjs.map +1 -0
- package/dist/_chunks/{EditViewPage-CzOT5Kpj.js → EditViewPage-BgjdnGz2.js} +57 -48
- package/dist/_chunks/EditViewPage-BgjdnGz2.js.map +1 -0
- package/dist/_chunks/{Field-Caef4JjM.js → Field-CdK7ZLmv.js} +1030 -800
- package/dist/_chunks/Field-CdK7ZLmv.js.map +1 -0
- package/dist/_chunks/{Field-Dlh0uGnL.mjs → Field-tHCw4lGA.mjs} +981 -750
- package/dist/_chunks/Field-tHCw4lGA.mjs.map +1 -0
- package/dist/_chunks/{Form-EnaQL_6L.mjs → Form-BJxdTv3Q.mjs} +56 -43
- package/dist/_chunks/Form-BJxdTv3Q.mjs.map +1 -0
- package/dist/_chunks/{Form-BzuAjtRq.js → Form-C_0KTVvV.js} +55 -43
- package/dist/_chunks/Form-C_0KTVvV.js.map +1 -0
- package/dist/_chunks/{History-D6sbCJvo.mjs → History-DR2txJLE.mjs} +151 -57
- package/dist/_chunks/History-DR2txJLE.mjs.map +1 -0
- package/dist/_chunks/{History-C17LiyRg.js → History-nuEzM5qm.js} +151 -58
- package/dist/_chunks/History-nuEzM5qm.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-Dks5SX6f.js → ListConfigurationPage-CnB86Psm.js} +70 -61
- package/dist/_chunks/ListConfigurationPage-CnB86Psm.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-Ce4qs7qE.mjs → ListConfigurationPage-voFVtXu6.mjs} +67 -57
- package/dist/_chunks/ListConfigurationPage-voFVtXu6.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-Be7S5aKL.mjs → ListViewPage-B_GaWgRH.mjs} +95 -106
- package/dist/_chunks/ListViewPage-B_GaWgRH.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-BwrZrPsh.js → ListViewPage-SXIXm-RM.js} +100 -111
- package/dist/_chunks/ListViewPage-SXIXm-RM.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-Cu5r1-JT.js → NoContentTypePage-BzsQ3hLZ.js} +5 -5
- package/dist/_chunks/NoContentTypePage-BzsQ3hLZ.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-CIPmYQMm.mjs → NoContentTypePage-CYiGpsbj.mjs} +7 -7
- package/dist/_chunks/NoContentTypePage-CYiGpsbj.mjs.map +1 -0
- package/dist/_chunks/{NoPermissionsPage-DhJ7LYrr.mjs → NoPermissionsPage-B5baIHal.mjs} +5 -6
- package/dist/_chunks/NoPermissionsPage-B5baIHal.mjs.map +1 -0
- package/dist/_chunks/{NoPermissionsPage-C-j6TEUF.js → NoPermissionsPage-IGkId4C5.js} +4 -5
- package/dist/_chunks/NoPermissionsPage-IGkId4C5.js.map +1 -0
- package/dist/_chunks/{Relations-CY7AtkDA.mjs → Relations-CIYDdKU-.mjs} +67 -57
- package/dist/_chunks/Relations-CIYDdKU-.mjs.map +1 -0
- package/dist/_chunks/{Relations-Czs-uZ-s.js → Relations-Dhuurpx2.js} +71 -62
- package/dist/_chunks/Relations-Dhuurpx2.js.map +1 -0
- package/dist/_chunks/{en-MBPul9Su.mjs → en-BrCTWlZv.mjs} +11 -4
- package/dist/_chunks/{en-MBPul9Su.mjs.map → en-BrCTWlZv.mjs.map} +1 -1
- package/dist/_chunks/{en-C-V1_90f.js → en-uOUIxfcQ.js} +11 -4
- package/dist/_chunks/{en-C-V1_90f.js.map → en-uOUIxfcQ.js.map} +1 -1
- package/dist/_chunks/{index-DNVx8ssZ.mjs → index-C9TJPyni.mjs} +1696 -912
- package/dist/_chunks/index-C9TJPyni.mjs.map +1 -0
- package/dist/_chunks/{index-X_2tafck.js → index-CdT0kHZ8.js} +1626 -843
- package/dist/_chunks/index-CdT0kHZ8.js.map +1 -0
- package/dist/_chunks/{layout-Dnh0PNp9.mjs → layout-BNqvLR_b.mjs} +45 -28
- package/dist/_chunks/layout-BNqvLR_b.mjs.map +1 -0
- package/dist/_chunks/{layout-dBc7wN7L.js → layout-C6dxWYT7.js} +45 -30
- package/dist/_chunks/layout-C6dxWYT7.js.map +1 -0
- package/dist/_chunks/{relations-Dx7tMKJN.mjs → relations-CkKqKw65.mjs} +2 -2
- package/dist/_chunks/{relations-Dx7tMKJN.mjs.map → relations-CkKqKw65.mjs.map} +1 -1
- package/dist/_chunks/{relations-4pHtBrHJ.js → relations-DtFaDnP1.js} +2 -2
- package/dist/_chunks/{relations-4pHtBrHJ.js.map → relations-DtFaDnP1.js.map} +1 -1
- package/dist/_chunks/useDragAndDrop-DdHgKsqq.mjs.map +1 -1
- package/dist/_chunks/useDragAndDrop-J0TUUbR6.js.map +1 -1
- package/dist/_chunks/usePrev-B9w_-eYc.js +15 -0
- package/dist/_chunks/usePrev-B9w_-eYc.js.map +1 -0
- package/dist/_chunks/usePrev-DH6iah0A.mjs +16 -0
- package/dist/_chunks/usePrev-DH6iah0A.mjs.map +1 -0
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +5 -4
- package/dist/admin/src/components/ComponentIcon.d.ts +6 -3
- package/dist/admin/src/content-manager.d.ts +3 -3
- package/dist/admin/src/exports.d.ts +1 -0
- 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 +5 -8
- package/dist/admin/src/hooks/useDocumentActions.d.ts +24 -3
- package/dist/admin/src/hooks/useDocumentLayout.d.ts +2 -2
- package/dist/admin/src/hooks/useDragAndDrop.d.ts +4 -4
- package/dist/admin/src/hooks/useKeyboardDragAndDrop.d.ts +1 -1
- package/dist/admin/src/index.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +11 -4
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.d.ts +3 -3
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +4 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Component/Input.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.d.ts +3 -5
- package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/Field.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +30 -18
- package/dist/admin/src/pages/EditView/components/FormInputs/UID.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +3 -49
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/Field.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 +48 -53
- package/dist/admin/src/pages/EditView/components/InputRenderer.d.ts +2 -10
- 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/pages/ListView/components/BulkActions/PublishAction.d.ts +9 -26
- package/dist/admin/src/services/api.d.ts +2 -3
- package/dist/admin/src/services/components.d.ts +2 -2
- package/dist/admin/src/services/contentTypes.d.ts +5 -5
- package/dist/admin/src/services/documents.d.ts +29 -17
- package/dist/admin/src/services/init.d.ts +2 -2
- package/dist/admin/src/services/relations.d.ts +3 -3
- package/dist/admin/src/services/uid.d.ts +3 -3
- package/dist/admin/src/utils/api.d.ts +4 -18
- package/dist/admin/src/utils/validation.d.ts +1 -6
- package/dist/server/index.js +602 -426
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +610 -434
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/controllers/single-types.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 +8 -0
- package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -0
- package/dist/server/src/controllers/validation/dimensions.d.ts +11 -0
- package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -0
- package/dist/server/src/controllers/validation/index.d.ts +1 -1
- package/dist/server/src/history/services/history.d.ts +2 -4
- package/dist/server/src/history/services/history.d.ts.map +1 -1
- package/dist/server/src/history/services/index.d.ts +6 -2
- package/dist/server/src/history/services/index.d.ts.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts +9 -0
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -0
- package/dist/server/src/history/services/utils.d.ts +41 -9
- package/dist/server/src/history/services/utils.d.ts.map +1 -1
- package/dist/server/src/history/utils.d.ts +6 -2
- package/dist/server/src/history/utils.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +18 -39
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts +13 -12
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts +8 -29
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +18 -39
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/utils/populate.d.ts +8 -1
- package/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/dist/shared/contracts/collection-types.d.ts +14 -6
- package/dist/shared/contracts/collection-types.d.ts.map +1 -1
- package/dist/shared/contracts/relations.d.ts +2 -2
- package/dist/shared/contracts/relations.d.ts.map +1 -1
- package/package.json +13 -14
- package/dist/_chunks/CardDragPreview-DSVYodBX.js.map +0 -1
- package/dist/_chunks/CardDragPreview-ikSG4M46.mjs.map +0 -1
- package/dist/_chunks/ComponentIcon-BBQsYCVn.js.map +0 -1
- package/dist/_chunks/ComponentIcon-BOFnK76n.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-Bm8lgcm6.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-CzOT5Kpj.js.map +0 -1
- package/dist/_chunks/Field-Caef4JjM.js.map +0 -1
- package/dist/_chunks/Field-Dlh0uGnL.mjs.map +0 -1
- package/dist/_chunks/Form-BzuAjtRq.js.map +0 -1
- package/dist/_chunks/Form-EnaQL_6L.mjs.map +0 -1
- package/dist/_chunks/History-C17LiyRg.js.map +0 -1
- package/dist/_chunks/History-D6sbCJvo.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-Ce4qs7qE.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-Dks5SX6f.js.map +0 -1
- package/dist/_chunks/ListViewPage-Be7S5aKL.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-BwrZrPsh.js.map +0 -1
- package/dist/_chunks/NoContentTypePage-CIPmYQMm.mjs.map +0 -1
- package/dist/_chunks/NoContentTypePage-Cu5r1-JT.js.map +0 -1
- package/dist/_chunks/NoPermissionsPage-C-j6TEUF.js.map +0 -1
- package/dist/_chunks/NoPermissionsPage-DhJ7LYrr.mjs.map +0 -1
- package/dist/_chunks/Relations-CY7AtkDA.mjs.map +0 -1
- package/dist/_chunks/Relations-Czs-uZ-s.js.map +0 -1
- package/dist/_chunks/index-DNVx8ssZ.mjs.map +0 -1
- package/dist/_chunks/index-X_2tafck.js.map +0 -1
- package/dist/_chunks/layout-Dnh0PNp9.mjs.map +0 -1
- package/dist/_chunks/layout-dBc7wN7L.js.map +0 -1
- package/dist/_chunks/urls-CbOsUOoW.mjs +0 -7
- package/dist/_chunks/urls-CbOsUOoW.mjs.map +0 -1
- package/dist/_chunks/urls-DzZya_gm.js +0 -6
- package/dist/_chunks/urls-DzZya_gm.js.map +0 -1
- package/dist/server/src/controllers/utils/dimensions.d.ts +0 -5
- package/dist/server/src/controllers/utils/dimensions.d.ts.map +0 -1
@@ -2,17 +2,15 @@
|
|
2
2
|
const Icons = require("@strapi/icons");
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
4
4
|
const strapiAdmin = require("@strapi/admin/strapi-admin");
|
5
|
-
const qs = require("qs");
|
6
|
-
const reactIntl = require("react-intl");
|
7
|
-
const reactRouterDom = require("react-router-dom");
|
8
5
|
const React = require("react");
|
9
6
|
const designSystem = require("@strapi/design-system");
|
10
|
-
const
|
7
|
+
const reactIntl = require("react-intl");
|
8
|
+
const reactRouterDom = require("react-router-dom");
|
9
|
+
const styledComponents = require("styled-components");
|
11
10
|
const yup = require("yup");
|
12
|
-
const react = require("@reduxjs/toolkit/query/react");
|
13
|
-
const axios = require("axios");
|
14
11
|
const pipe = require("lodash/fp/pipe");
|
15
12
|
const dateFns = require("date-fns");
|
13
|
+
const qs = require("qs");
|
16
14
|
const toolkit = require("@reduxjs/toolkit");
|
17
15
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
18
16
|
function _interopNamespace(e) {
|
@@ -34,7 +32,6 @@ function _interopNamespace(e) {
|
|
34
32
|
return Object.freeze(n);
|
35
33
|
}
|
36
34
|
const React__namespace = /* @__PURE__ */ _interopNamespace(React);
|
37
|
-
const styled__default = /* @__PURE__ */ _interopDefault(styled);
|
38
35
|
const yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
|
39
36
|
const pipe__default = /* @__PURE__ */ _interopDefault(pipe);
|
40
37
|
const __variableDynamicImportRuntimeHelper = (glob, path) => {
|
@@ -73,42 +70,6 @@ const useInjectionZone = (area) => {
|
|
73
70
|
const [page, position] = area.split(".");
|
74
71
|
return contentManagerPlugin.getInjectedComponents(page, position);
|
75
72
|
};
|
76
|
-
const HistoryAction = ({ model, document }) => {
|
77
|
-
const { formatMessage } = reactIntl.useIntl();
|
78
|
-
const [{ query }] = strapiAdmin.useQueryParams();
|
79
|
-
const navigate = reactRouterDom.useNavigate();
|
80
|
-
const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
|
81
|
-
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
82
|
-
return null;
|
83
|
-
}
|
84
|
-
return {
|
85
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
|
86
|
-
label: formatMessage({
|
87
|
-
id: "content-manager.history.document-action",
|
88
|
-
defaultMessage: "Content History"
|
89
|
-
}),
|
90
|
-
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
91
|
-
disabled: (
|
92
|
-
/**
|
93
|
-
* The user is creating a new document.
|
94
|
-
* It hasn't been saved yet, so there's no history to go to
|
95
|
-
*/
|
96
|
-
!document || /**
|
97
|
-
* The document has been created but the current dimension has never been saved.
|
98
|
-
* For example, the user is creating a new locale in an existing document,
|
99
|
-
* so there's no history for the document in that locale
|
100
|
-
*/
|
101
|
-
!document.id || /**
|
102
|
-
* History is only available for content types created by the user.
|
103
|
-
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
104
|
-
* which start with `admin::` or `plugin::`
|
105
|
-
*/
|
106
|
-
!model.startsWith("api::")
|
107
|
-
),
|
108
|
-
position: "header"
|
109
|
-
};
|
110
|
-
};
|
111
|
-
HistoryAction.type = "history";
|
112
73
|
const ID = "id";
|
113
74
|
const CREATED_BY_ATTRIBUTE_NAME = "createdBy";
|
114
75
|
const UPDATED_BY_ATTRIBUTE_NAME = "updatedBy";
|
@@ -179,9 +140,8 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
179
140
|
const name = removeNumericalStrings(fieldName.split("."));
|
180
141
|
const componentFieldNames = fieldsUserCanAction.filter((field) => field.split(".").length > 1);
|
181
142
|
if (fieldType === "component") {
|
182
|
-
|
183
|
-
|
184
|
-
return field.includes(fieldName);
|
143
|
+
return componentFieldNames.some((field) => {
|
144
|
+
return field.includes(name.join("."));
|
185
145
|
});
|
186
146
|
}
|
187
147
|
if (name.length > 1) {
|
@@ -211,78 +171,8 @@ const extractAndDedupeFields = (permissions = []) => permissions.flatMap((permis
|
|
211
171
|
(field, index2, arr) => arr.indexOf(field) === index2 && typeof field === "string"
|
212
172
|
);
|
213
173
|
const removeNumericalStrings = (arr) => arr.filter((item) => isNaN(Number(item)));
|
214
|
-
const
|
215
|
-
|
216
|
-
return query;
|
217
|
-
const { plugins: _, ...validQueryParams } = {
|
218
|
-
...query,
|
219
|
-
...Object.values(query?.plugins ?? {}).reduce(
|
220
|
-
(acc, current) => Object.assign(acc, current),
|
221
|
-
{}
|
222
|
-
)
|
223
|
-
};
|
224
|
-
if ("_q" in validQueryParams) {
|
225
|
-
validQueryParams._q = encodeURIComponent(validQueryParams._q);
|
226
|
-
}
|
227
|
-
return validQueryParams;
|
228
|
-
};
|
229
|
-
const axiosBaseQuery = () => async (query, { signal }) => {
|
230
|
-
try {
|
231
|
-
const { get, post, del, put } = strapiAdmin.getFetchClient();
|
232
|
-
if (typeof query === "string") {
|
233
|
-
const result = await get(query, { signal });
|
234
|
-
return { data: result.data };
|
235
|
-
} else {
|
236
|
-
const { url, method = "GET", data, config } = query;
|
237
|
-
if (method === "POST") {
|
238
|
-
const result2 = await post(url, data, { ...config, signal });
|
239
|
-
return { data: result2.data };
|
240
|
-
}
|
241
|
-
if (method === "DELETE") {
|
242
|
-
const result2 = await del(url, { ...config, signal });
|
243
|
-
return { data: result2.data };
|
244
|
-
}
|
245
|
-
if (method === "PUT") {
|
246
|
-
const result2 = await put(url, data, { ...config, signal });
|
247
|
-
return { data: result2.data };
|
248
|
-
}
|
249
|
-
const result = await get(url, { ...config, signal });
|
250
|
-
return { data: result.data };
|
251
|
-
}
|
252
|
-
} catch (err) {
|
253
|
-
if (axios.isAxiosError(err)) {
|
254
|
-
if (typeof err.response?.data === "object" && err.response?.data !== null && "error" in err.response?.data) {
|
255
|
-
return { data: void 0, error: err.response?.data.error };
|
256
|
-
} else {
|
257
|
-
return {
|
258
|
-
data: void 0,
|
259
|
-
error: {
|
260
|
-
name: "UnknownError",
|
261
|
-
message: "There was an unknown error response from the API",
|
262
|
-
details: err.response?.data,
|
263
|
-
status: err.response?.status
|
264
|
-
}
|
265
|
-
};
|
266
|
-
}
|
267
|
-
}
|
268
|
-
const error = err;
|
269
|
-
return {
|
270
|
-
data: void 0,
|
271
|
-
error: {
|
272
|
-
name: error.name,
|
273
|
-
message: error.message,
|
274
|
-
stack: error.stack
|
275
|
-
}
|
276
|
-
};
|
277
|
-
}
|
278
|
-
};
|
279
|
-
const isBaseQueryError = (error) => {
|
280
|
-
return error.name !== void 0;
|
281
|
-
};
|
282
|
-
const contentManagerApi = react.createApi({
|
283
|
-
reducerPath: "contentManagerApi",
|
284
|
-
baseQuery: axiosBaseQuery(),
|
285
|
-
tagTypes: [
|
174
|
+
const contentManagerApi = strapiAdmin.adminApi.enhanceEndpoints({
|
175
|
+
addTagTypes: [
|
286
176
|
"ComponentConfiguration",
|
287
177
|
"ContentTypesConfiguration",
|
288
178
|
"ContentTypeSettings",
|
@@ -290,10 +180,10 @@ const contentManagerApi = react.createApi({
|
|
290
180
|
"InitialData",
|
291
181
|
"HistoryVersion",
|
292
182
|
"Relations"
|
293
|
-
]
|
294
|
-
endpoints: () => ({})
|
183
|
+
]
|
295
184
|
});
|
296
185
|
const documentApi = contentManagerApi.injectEndpoints({
|
186
|
+
overrideExisting: true,
|
297
187
|
endpoints: (builder) => ({
|
298
188
|
autoCloneDocument: builder.mutation({
|
299
189
|
query: ({ model, sourceId, query }) => ({
|
@@ -303,7 +193,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
303
193
|
params: query
|
304
194
|
}
|
305
195
|
}),
|
306
|
-
invalidatesTags: (_result,
|
196
|
+
invalidatesTags: (_result, error, { model }) => {
|
197
|
+
if (error) {
|
198
|
+
return [];
|
199
|
+
}
|
200
|
+
return [{ type: "Document", id: `${model}_LIST` }];
|
201
|
+
}
|
307
202
|
}),
|
308
203
|
cloneDocument: builder.mutation({
|
309
204
|
query: ({ model, sourceId, data, params }) => ({
|
@@ -347,12 +242,15 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
347
242
|
]
|
348
243
|
}),
|
349
244
|
deleteManyDocuments: builder.mutation({
|
350
|
-
query: ({ model, ...body }) => ({
|
245
|
+
query: ({ model, params, ...body }) => ({
|
351
246
|
url: `/content-manager/collection-types/${model}/actions/bulkDelete`,
|
352
247
|
method: "POST",
|
353
|
-
data: body
|
248
|
+
data: body,
|
249
|
+
config: {
|
250
|
+
params
|
251
|
+
}
|
354
252
|
}),
|
355
|
-
invalidatesTags: (_res, _error, { model
|
253
|
+
invalidatesTags: (_res, _error, { model }) => [{ type: "Document", id: `${model}_LIST` }]
|
356
254
|
}),
|
357
255
|
discardDocument: builder.mutation({
|
358
256
|
query: ({ collectionType, model, documentId, params }) => ({
|
@@ -387,6 +285,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
387
285
|
}),
|
388
286
|
providesTags: (result, _error, arg) => {
|
389
287
|
return [
|
288
|
+
{ type: "Document", id: `ALL_LIST` },
|
390
289
|
{ type: "Document", id: `${arg.model}_LIST` },
|
391
290
|
...result?.results.map(({ documentId }) => ({
|
392
291
|
type: "Document",
|
@@ -425,6 +324,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
425
324
|
{
|
426
325
|
type: "Document",
|
427
326
|
id: collectionType !== SINGLE_TYPES ? `${model}_${result && "documentId" in result ? result.documentId : documentId}` : model
|
327
|
+
},
|
328
|
+
// Make it easy to invalidate all individual documents queries for a model
|
329
|
+
{
|
330
|
+
type: "Document",
|
331
|
+
id: `${model}_ALL_ITEMS`
|
428
332
|
}
|
429
333
|
];
|
430
334
|
}
|
@@ -463,10 +367,13 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
463
367
|
}
|
464
368
|
}),
|
465
369
|
publishManyDocuments: builder.mutation({
|
466
|
-
query: ({ model, ...body }) => ({
|
370
|
+
query: ({ model, params, ...body }) => ({
|
467
371
|
url: `/content-manager/collection-types/${model}/actions/bulkPublish`,
|
468
372
|
method: "POST",
|
469
|
-
data: body
|
373
|
+
data: body,
|
374
|
+
config: {
|
375
|
+
params
|
376
|
+
}
|
470
377
|
}),
|
471
378
|
invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
|
472
379
|
}),
|
@@ -487,6 +394,18 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
487
394
|
},
|
488
395
|
"Relations"
|
489
396
|
];
|
397
|
+
},
|
398
|
+
async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
|
399
|
+
const patchResult = dispatch(
|
400
|
+
documentApi.util.updateQueryData("getDocument", patch, (draft) => {
|
401
|
+
Object.assign(draft.data, data);
|
402
|
+
})
|
403
|
+
);
|
404
|
+
try {
|
405
|
+
await queryFulfilled;
|
406
|
+
} catch {
|
407
|
+
patchResult.undo();
|
408
|
+
}
|
490
409
|
}
|
491
410
|
}),
|
492
411
|
unpublishDocument: builder.mutation({
|
@@ -508,10 +427,13 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
508
427
|
}
|
509
428
|
}),
|
510
429
|
unpublishManyDocuments: builder.mutation({
|
511
|
-
query: ({ model, ...body }) => ({
|
430
|
+
query: ({ model, params, ...body }) => ({
|
512
431
|
url: `/content-manager/collection-types/${model}/actions/bulkUnpublish`,
|
513
432
|
method: "POST",
|
514
|
-
data: body
|
433
|
+
data: body,
|
434
|
+
config: {
|
435
|
+
params
|
436
|
+
}
|
515
437
|
}),
|
516
438
|
invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
|
517
439
|
})
|
@@ -535,6 +457,24 @@ const {
|
|
535
457
|
useUnpublishDocumentMutation,
|
536
458
|
useUnpublishManyDocumentsMutation
|
537
459
|
} = documentApi;
|
460
|
+
const buildValidParams = (query) => {
|
461
|
+
if (!query)
|
462
|
+
return query;
|
463
|
+
const { plugins: _, ...validQueryParams } = {
|
464
|
+
...query,
|
465
|
+
...Object.values(query?.plugins ?? {}).reduce(
|
466
|
+
(acc, current) => Object.assign(acc, current),
|
467
|
+
{}
|
468
|
+
)
|
469
|
+
};
|
470
|
+
if ("_q" in validQueryParams) {
|
471
|
+
validQueryParams._q = encodeURIComponent(validQueryParams._q);
|
472
|
+
}
|
473
|
+
return validQueryParams;
|
474
|
+
};
|
475
|
+
const isBaseQueryError = (error) => {
|
476
|
+
return error.name !== void 0;
|
477
|
+
};
|
538
478
|
const createYupSchema = (attributes = {}, components = {}) => {
|
539
479
|
const createModelSchema = (attributes2) => yup__namespace.object().shape(
|
540
480
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
@@ -574,10 +514,14 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
574
514
|
yup__namespace.array().of(
|
575
515
|
yup__namespace.lazy(
|
576
516
|
(data) => {
|
577
|
-
const
|
578
|
-
|
517
|
+
const attributes3 = components?.[data?.__component]?.attributes;
|
518
|
+
const validation = yup__namespace.object().shape({
|
579
519
|
__component: yup__namespace.string().required().oneOf(Object.keys(components))
|
580
|
-
}).nullable(false)
|
520
|
+
}).nullable(false);
|
521
|
+
if (!attributes3) {
|
522
|
+
return validation;
|
523
|
+
}
|
524
|
+
return validation.concat(createModelSchema(attributes3));
|
581
525
|
}
|
582
526
|
)
|
583
527
|
)
|
@@ -587,11 +531,25 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
587
531
|
return {
|
588
532
|
...acc,
|
589
533
|
[name]: transformSchema(
|
590
|
-
yup__namespace.
|
591
|
-
|
592
|
-
|
593
|
-
})
|
594
|
-
|
534
|
+
yup__namespace.lazy((value) => {
|
535
|
+
if (!value) {
|
536
|
+
return yup__namespace.mixed().nullable(true);
|
537
|
+
} else if (Array.isArray(value)) {
|
538
|
+
return yup__namespace.array().of(
|
539
|
+
yup__namespace.object().shape({
|
540
|
+
id: yup__namespace.string().required()
|
541
|
+
})
|
542
|
+
);
|
543
|
+
} else if (typeof value === "object") {
|
544
|
+
return yup__namespace.object();
|
545
|
+
} else {
|
546
|
+
return yup__namespace.mixed().test(
|
547
|
+
"type-error",
|
548
|
+
"Relation values must be either null, an array of objects with {id} or an object.",
|
549
|
+
() => false
|
550
|
+
);
|
551
|
+
}
|
552
|
+
})
|
595
553
|
)
|
596
554
|
};
|
597
555
|
default:
|
@@ -631,6 +589,14 @@ const createAttributeSchema = (attribute) => {
|
|
631
589
|
if (!value || typeof value === "string" && value.length === 0) {
|
632
590
|
return true;
|
633
591
|
}
|
592
|
+
if (typeof value === "object") {
|
593
|
+
try {
|
594
|
+
JSON.stringify(value);
|
595
|
+
return true;
|
596
|
+
} catch (err) {
|
597
|
+
return false;
|
598
|
+
}
|
599
|
+
}
|
634
600
|
try {
|
635
601
|
JSON.parse(value);
|
636
602
|
return true;
|
@@ -650,13 +616,18 @@ const createAttributeSchema = (attribute) => {
|
|
650
616
|
}
|
651
617
|
};
|
652
618
|
const addRequiredValidation = (attribute) => (schema) => {
|
653
|
-
if (attribute.required) {
|
654
|
-
return schema.required
|
655
|
-
|
656
|
-
|
657
|
-
|
619
|
+
if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
|
620
|
+
return schema.min(1, strapiAdmin.translatedErrors.required);
|
621
|
+
}
|
622
|
+
if (attribute.required && attribute.type !== "relation") {
|
623
|
+
return schema.required(strapiAdmin.translatedErrors.required);
|
658
624
|
}
|
659
|
-
return schema.nullable()
|
625
|
+
return schema?.nullable ? schema.nullable() : (
|
626
|
+
// In some cases '.nullable' will not be available on the schema.
|
627
|
+
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
628
|
+
// In these cases we should just return the schema as it is.
|
629
|
+
schema
|
630
|
+
);
|
660
631
|
};
|
661
632
|
const addMinLengthValidation = (attribute) => (schema) => {
|
662
633
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
@@ -683,6 +654,28 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
683
654
|
const addMinValidation = (attribute) => (schema) => {
|
684
655
|
if ("min" in attribute) {
|
685
656
|
const min = toInteger(attribute.min);
|
657
|
+
if (attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") {
|
658
|
+
if (!attribute.required && "test" in schema && min) {
|
659
|
+
return schema.test(
|
660
|
+
"custom-min",
|
661
|
+
{
|
662
|
+
...strapiAdmin.translatedErrors.min,
|
663
|
+
values: {
|
664
|
+
min: attribute.min
|
665
|
+
}
|
666
|
+
},
|
667
|
+
(value) => {
|
668
|
+
if (!value) {
|
669
|
+
return true;
|
670
|
+
}
|
671
|
+
if (Array.isArray(value) && value.length === 0) {
|
672
|
+
return true;
|
673
|
+
}
|
674
|
+
return value.length >= min;
|
675
|
+
}
|
676
|
+
);
|
677
|
+
}
|
678
|
+
}
|
686
679
|
if ("min" in schema && min) {
|
687
680
|
return schema.min(min, {
|
688
681
|
...strapiAdmin.translatedErrors.min,
|
@@ -728,24 +721,6 @@ const addRegexValidation = (attribute) => (schema) => {
|
|
728
721
|
}
|
729
722
|
return schema;
|
730
723
|
};
|
731
|
-
const extractValuesFromYupError = (errorType, errorParams) => {
|
732
|
-
if (!errorType || !errorParams) {
|
733
|
-
return {};
|
734
|
-
}
|
735
|
-
return {
|
736
|
-
[errorType]: errorParams[errorType]
|
737
|
-
};
|
738
|
-
};
|
739
|
-
const getInnerErrors = (error) => (error?.inner || []).reduce((acc, currentError) => {
|
740
|
-
if (currentError.path) {
|
741
|
-
acc[currentError.path.split("[").join(".").split("]").join("")] = {
|
742
|
-
id: currentError.message,
|
743
|
-
defaultMessage: currentError.message,
|
744
|
-
values: extractValuesFromYupError(currentError?.type, currentError?.params)
|
745
|
-
};
|
746
|
-
}
|
747
|
-
return acc;
|
748
|
-
}, {});
|
749
724
|
const initApi = contentManagerApi.injectEndpoints({
|
750
725
|
endpoints: (builder) => ({
|
751
726
|
getInitialData: builder.query({
|
@@ -759,27 +734,20 @@ const { useGetInitialDataQuery } = initApi;
|
|
759
734
|
const useContentTypeSchema = (model) => {
|
760
735
|
const { toggleNotification } = strapiAdmin.useNotification();
|
761
736
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
762
|
-
const {
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
)
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
error: res.error,
|
777
|
-
components: Object.keys(components2).length === 0 ? void 0 : components2,
|
778
|
-
contentType: contentType2,
|
779
|
-
contentTypes: res.data?.contentTypes ?? []
|
780
|
-
};
|
781
|
-
}
|
782
|
-
});
|
737
|
+
const { data, error, isLoading, isFetching } = useGetInitialDataQuery(void 0);
|
738
|
+
const { components, contentType, contentTypes } = React__namespace.useMemo(() => {
|
739
|
+
const contentType2 = data?.contentTypes.find((ct) => ct.uid === model);
|
740
|
+
const componentsByKey = data?.components.reduce((acc, component) => {
|
741
|
+
acc[component.uid] = component;
|
742
|
+
return acc;
|
743
|
+
}, {});
|
744
|
+
const components2 = extractContentTypeComponents(contentType2?.attributes, componentsByKey);
|
745
|
+
return {
|
746
|
+
components: Object.keys(components2).length === 0 ? void 0 : components2,
|
747
|
+
contentType: contentType2,
|
748
|
+
contentTypes: data?.contentTypes ?? []
|
749
|
+
};
|
750
|
+
}, [model, data]);
|
783
751
|
React__namespace.useEffect(() => {
|
784
752
|
if (error) {
|
785
753
|
toggleNotification({
|
@@ -834,7 +802,10 @@ const useDocument = (args, opts) => {
|
|
834
802
|
isLoading: isLoadingDocument,
|
835
803
|
isFetching: isFetchingDocument,
|
836
804
|
error
|
837
|
-
} = useGetDocumentQuery(args,
|
805
|
+
} = useGetDocumentQuery(args, {
|
806
|
+
...opts,
|
807
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
808
|
+
});
|
838
809
|
const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
|
839
810
|
React__namespace.useEffect(() => {
|
840
811
|
if (error) {
|
@@ -862,7 +833,7 @@ const useDocument = (args, opts) => {
|
|
862
833
|
return null;
|
863
834
|
} catch (error2) {
|
864
835
|
if (error2 instanceof yup.ValidationError) {
|
865
|
-
return
|
836
|
+
return strapiAdmin.getYupValidationErrors(error2);
|
866
837
|
}
|
867
838
|
throw error2;
|
868
839
|
}
|
@@ -958,14 +929,53 @@ const useDocumentActions = () => {
|
|
958
929
|
},
|
959
930
|
[trackUsage, deleteDocument, toggleNotification, formatMessage, formatAPIError]
|
960
931
|
);
|
932
|
+
const [deleteManyDocuments] = useDeleteManyDocumentsMutation();
|
933
|
+
const deleteMany = React__namespace.useCallback(
|
934
|
+
async ({ model, documentIds, params }) => {
|
935
|
+
try {
|
936
|
+
trackUsage("willBulkDeleteEntries");
|
937
|
+
const res = await deleteManyDocuments({
|
938
|
+
model,
|
939
|
+
documentIds,
|
940
|
+
params
|
941
|
+
});
|
942
|
+
if ("error" in res) {
|
943
|
+
toggleNotification({
|
944
|
+
type: "danger",
|
945
|
+
message: formatAPIError(res.error)
|
946
|
+
});
|
947
|
+
return { error: res.error };
|
948
|
+
}
|
949
|
+
toggleNotification({
|
950
|
+
type: "success",
|
951
|
+
title: formatMessage({
|
952
|
+
id: getTranslation("success.records.delete"),
|
953
|
+
defaultMessage: "Successfully deleted."
|
954
|
+
}),
|
955
|
+
message: ""
|
956
|
+
});
|
957
|
+
trackUsage("didBulkDeleteEntries");
|
958
|
+
return res.data;
|
959
|
+
} catch (err) {
|
960
|
+
toggleNotification({
|
961
|
+
type: "danger",
|
962
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
963
|
+
});
|
964
|
+
trackUsage("didNotBulkDeleteEntries");
|
965
|
+
throw err;
|
966
|
+
}
|
967
|
+
},
|
968
|
+
[trackUsage, deleteManyDocuments, toggleNotification, formatMessage, formatAPIError]
|
969
|
+
);
|
961
970
|
const [discardDocument] = useDiscardDocumentMutation();
|
962
971
|
const discard = React__namespace.useCallback(
|
963
|
-
async ({ collectionType, model, documentId }) => {
|
972
|
+
async ({ collectionType, model, documentId, params }) => {
|
964
973
|
try {
|
965
974
|
const res = await discardDocument({
|
966
975
|
collectionType,
|
967
976
|
model,
|
968
|
-
documentId
|
977
|
+
documentId,
|
978
|
+
params
|
969
979
|
});
|
970
980
|
if ("error" in res) {
|
971
981
|
toggleNotification({
|
@@ -1027,6 +1037,43 @@ const useDocumentActions = () => {
|
|
1027
1037
|
},
|
1028
1038
|
[trackUsage, publishDocument, toggleNotification, formatMessage, formatAPIError]
|
1029
1039
|
);
|
1040
|
+
const [publishManyDocuments] = usePublishManyDocumentsMutation();
|
1041
|
+
const publishMany = React__namespace.useCallback(
|
1042
|
+
async ({ model, documentIds, params }) => {
|
1043
|
+
try {
|
1044
|
+
const res = await publishManyDocuments({
|
1045
|
+
model,
|
1046
|
+
documentIds,
|
1047
|
+
params
|
1048
|
+
});
|
1049
|
+
if ("error" in res) {
|
1050
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1051
|
+
return { error: res.error };
|
1052
|
+
}
|
1053
|
+
toggleNotification({
|
1054
|
+
type: "success",
|
1055
|
+
message: formatMessage({
|
1056
|
+
id: getTranslation("success.record.publish"),
|
1057
|
+
defaultMessage: "Published document"
|
1058
|
+
})
|
1059
|
+
});
|
1060
|
+
return res.data;
|
1061
|
+
} catch (err) {
|
1062
|
+
toggleNotification({
|
1063
|
+
type: "danger",
|
1064
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1065
|
+
});
|
1066
|
+
throw err;
|
1067
|
+
}
|
1068
|
+
},
|
1069
|
+
[
|
1070
|
+
// trackUsage,
|
1071
|
+
publishManyDocuments,
|
1072
|
+
toggleNotification,
|
1073
|
+
formatMessage,
|
1074
|
+
formatAPIError
|
1075
|
+
]
|
1076
|
+
);
|
1030
1077
|
const [updateDocument] = useUpdateDocumentMutation();
|
1031
1078
|
const update = React__namespace.useCallback(
|
1032
1079
|
async ({ collectionType, model, documentId, params }, data, trackerProperty) => {
|
@@ -1101,6 +1148,41 @@ const useDocumentActions = () => {
|
|
1101
1148
|
},
|
1102
1149
|
[trackUsage, unpublishDocument, toggleNotification, formatMessage, formatAPIError]
|
1103
1150
|
);
|
1151
|
+
const [unpublishManyDocuments] = useUnpublishManyDocumentsMutation();
|
1152
|
+
const unpublishMany = React__namespace.useCallback(
|
1153
|
+
async ({ model, documentIds, params }) => {
|
1154
|
+
try {
|
1155
|
+
trackUsage("willBulkUnpublishEntries");
|
1156
|
+
const res = await unpublishManyDocuments({
|
1157
|
+
model,
|
1158
|
+
documentIds,
|
1159
|
+
params
|
1160
|
+
});
|
1161
|
+
if ("error" in res) {
|
1162
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1163
|
+
return { error: res.error };
|
1164
|
+
}
|
1165
|
+
trackUsage("didBulkUnpublishEntries");
|
1166
|
+
toggleNotification({
|
1167
|
+
type: "success",
|
1168
|
+
title: formatMessage({
|
1169
|
+
id: getTranslation("success.records.unpublish"),
|
1170
|
+
defaultMessage: "Successfully unpublished."
|
1171
|
+
}),
|
1172
|
+
message: ""
|
1173
|
+
});
|
1174
|
+
return res.data;
|
1175
|
+
} catch (err) {
|
1176
|
+
toggleNotification({
|
1177
|
+
type: "danger",
|
1178
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1179
|
+
});
|
1180
|
+
trackUsage("didNotBulkUnpublishEntries");
|
1181
|
+
throw err;
|
1182
|
+
}
|
1183
|
+
},
|
1184
|
+
[trackUsage, unpublishManyDocuments, toggleNotification, formatMessage, formatAPIError]
|
1185
|
+
);
|
1104
1186
|
const [createDocument] = useCreateDocumentMutation();
|
1105
1187
|
const create = React__namespace.useCallback(
|
1106
1188
|
async ({ model, params }, data, trackerProperty) => {
|
@@ -1144,7 +1226,6 @@ const useDocumentActions = () => {
|
|
1144
1226
|
sourceId
|
1145
1227
|
});
|
1146
1228
|
if ("error" in res) {
|
1147
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1148
1229
|
return { error: res.error };
|
1149
1230
|
}
|
1150
1231
|
toggleNotification({
|
@@ -1214,15 +1295,18 @@ const useDocumentActions = () => {
|
|
1214
1295
|
clone,
|
1215
1296
|
create,
|
1216
1297
|
delete: _delete,
|
1298
|
+
deleteMany,
|
1217
1299
|
discard,
|
1218
1300
|
getDocument,
|
1219
1301
|
publish,
|
1302
|
+
publishMany,
|
1220
1303
|
unpublish,
|
1304
|
+
unpublishMany,
|
1221
1305
|
update
|
1222
1306
|
};
|
1223
1307
|
};
|
1224
1308
|
const ProtectedHistoryPage = React.lazy(
|
1225
|
-
() => Promise.resolve().then(() => require("./History-
|
1309
|
+
() => Promise.resolve().then(() => require("./History-nuEzM5qm.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1226
1310
|
);
|
1227
1311
|
const routes$1 = [
|
1228
1312
|
{
|
@@ -1235,31 +1319,31 @@ const routes$1 = [
|
|
1235
1319
|
}
|
1236
1320
|
];
|
1237
1321
|
const ProtectedEditViewPage = React.lazy(
|
1238
|
-
() => Promise.resolve().then(() => require("./EditViewPage-
|
1322
|
+
() => Promise.resolve().then(() => require("./EditViewPage-BgjdnGz2.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1239
1323
|
);
|
1240
1324
|
const ProtectedListViewPage = React.lazy(
|
1241
|
-
() => Promise.resolve().then(() => require("./ListViewPage-
|
1325
|
+
() => Promise.resolve().then(() => require("./ListViewPage-SXIXm-RM.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1242
1326
|
);
|
1243
1327
|
const ProtectedListConfiguration = React.lazy(
|
1244
|
-
() => Promise.resolve().then(() => require("./ListConfigurationPage-
|
1328
|
+
() => Promise.resolve().then(() => require("./ListConfigurationPage-CnB86Psm.js")).then((mod) => ({
|
1245
1329
|
default: mod.ProtectedListConfiguration
|
1246
1330
|
}))
|
1247
1331
|
);
|
1248
1332
|
const ProtectedEditConfigurationPage = React.lazy(
|
1249
|
-
() => Promise.resolve().then(() => require("./EditConfigurationPage-
|
1333
|
+
() => Promise.resolve().then(() => require("./EditConfigurationPage-BQ17--5R.js")).then((mod) => ({
|
1250
1334
|
default: mod.ProtectedEditConfigurationPage
|
1251
1335
|
}))
|
1252
1336
|
);
|
1253
1337
|
const ProtectedComponentConfigurationPage = React.lazy(
|
1254
|
-
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-
|
1338
|
+
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-KXSuLnQD.js")).then((mod) => ({
|
1255
1339
|
default: mod.ProtectedComponentConfigurationPage
|
1256
1340
|
}))
|
1257
1341
|
);
|
1258
1342
|
const NoPermissions = React.lazy(
|
1259
|
-
() => Promise.resolve().then(() => require("./NoPermissionsPage-
|
1343
|
+
() => Promise.resolve().then(() => require("./NoPermissionsPage-IGkId4C5.js")).then((mod) => ({ default: mod.NoPermissions }))
|
1260
1344
|
);
|
1261
1345
|
const NoContentType = React.lazy(
|
1262
|
-
() => Promise.resolve().then(() => require("./NoContentTypePage-
|
1346
|
+
() => Promise.resolve().then(() => require("./NoContentTypePage-BzsQ3hLZ.js")).then((mod) => ({ default: mod.NoContentType }))
|
1263
1347
|
);
|
1264
1348
|
const CollectionTypePages = () => {
|
1265
1349
|
const { collectionType } = reactRouterDom.useParams();
|
@@ -1373,12 +1457,14 @@ const DocumentActionButton = (action) => {
|
|
1373
1457
|
/* @__PURE__ */ jsxRuntime.jsx(
|
1374
1458
|
designSystem.Button,
|
1375
1459
|
{
|
1376
|
-
flex:
|
1460
|
+
flex: "auto",
|
1377
1461
|
startIcon: action.icon,
|
1378
1462
|
disabled: action.disabled,
|
1379
1463
|
onClick: handleClick(action),
|
1380
1464
|
justifyContent: "center",
|
1381
1465
|
variant: action.variant || "default",
|
1466
|
+
paddingTop: "7px",
|
1467
|
+
paddingBottom: "7px",
|
1382
1468
|
children: action.label
|
1383
1469
|
}
|
1384
1470
|
),
|
@@ -1386,7 +1472,7 @@ const DocumentActionButton = (action) => {
|
|
1386
1472
|
DocumentActionConfirmDialog,
|
1387
1473
|
{
|
1388
1474
|
...action.dialog,
|
1389
|
-
variant: action.variant,
|
1475
|
+
variant: action.dialog?.variant ?? action.variant,
|
1390
1476
|
isOpen: dialogId === action.id,
|
1391
1477
|
onClose: handleClose
|
1392
1478
|
}
|
@@ -1438,18 +1524,18 @@ const DocumentActionsMenu = ({
|
|
1438
1524
|
};
|
1439
1525
|
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Root, { open: isOpen, onOpenChange: setIsOpen, children: [
|
1440
1526
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
1441
|
-
|
1527
|
+
StyledMoreButton,
|
1442
1528
|
{
|
1443
1529
|
disabled: isDisabled,
|
1444
1530
|
size: "S",
|
1445
1531
|
endIcon: null,
|
1446
|
-
paddingTop: "
|
1447
|
-
paddingLeft: "
|
1448
|
-
paddingRight: "
|
1532
|
+
paddingTop: "4px",
|
1533
|
+
paddingLeft: "7px",
|
1534
|
+
paddingRight: "7px",
|
1449
1535
|
variant,
|
1450
1536
|
children: [
|
1451
1537
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.More, { "aria-hidden": true, focusable: false }),
|
1452
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, {
|
1538
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { tag: "span", children: label || formatMessage({
|
1453
1539
|
id: "content-manager.containers.edit.panels.default.more-actions",
|
1454
1540
|
defaultMessage: "More document actions"
|
1455
1541
|
}) })
|
@@ -1465,10 +1551,25 @@ const DocumentActionsMenu = ({
|
|
1465
1551
|
onSelect: handleClick(action),
|
1466
1552
|
display: "block",
|
1467
1553
|
children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", gap: 4, children: [
|
1468
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1554
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
1555
|
+
designSystem.Flex,
|
1556
|
+
{
|
1557
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1558
|
+
gap: 2,
|
1559
|
+
tag: "span",
|
1560
|
+
children: [
|
1561
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
1562
|
+
designSystem.Flex,
|
1563
|
+
{
|
1564
|
+
tag: "span",
|
1565
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1566
|
+
children: action.icon
|
1567
|
+
}
|
1568
|
+
),
|
1569
|
+
action.label
|
1570
|
+
]
|
1571
|
+
}
|
1572
|
+
),
|
1472
1573
|
action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsxRuntime.jsx(
|
1473
1574
|
designSystem.Flex,
|
1474
1575
|
{
|
@@ -1527,6 +1628,23 @@ const convertActionVariantToColor = (variant = "secondary") => {
|
|
1527
1628
|
return "primary600";
|
1528
1629
|
}
|
1529
1630
|
};
|
1631
|
+
const convertActionVariantToIconColor = (variant = "secondary") => {
|
1632
|
+
switch (variant) {
|
1633
|
+
case "danger":
|
1634
|
+
return "danger600";
|
1635
|
+
case "secondary":
|
1636
|
+
return "neutral500";
|
1637
|
+
case "success":
|
1638
|
+
return "success600";
|
1639
|
+
default:
|
1640
|
+
return "primary600";
|
1641
|
+
}
|
1642
|
+
};
|
1643
|
+
const StyledMoreButton = styledComponents.styled(designSystem.Menu.Trigger)`
|
1644
|
+
& > span {
|
1645
|
+
display: flex;
|
1646
|
+
}
|
1647
|
+
`;
|
1530
1648
|
const DocumentActionConfirmDialog = ({
|
1531
1649
|
onClose,
|
1532
1650
|
onCancel,
|
@@ -1549,61 +1667,42 @@ const DocumentActionConfirmDialog = ({
|
|
1549
1667
|
}
|
1550
1668
|
onClose();
|
1551
1669
|
};
|
1552
|
-
return /* @__PURE__ */ jsxRuntime.
|
1553
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.
|
1554
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
1555
|
-
|
1556
|
-
{
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
|
1566
|
-
)
|
1567
|
-
] });
|
1670
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
1671
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
1672
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: content }),
|
1673
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
|
1674
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", children: formatMessage({
|
1675
|
+
id: "app.components.Button.cancel",
|
1676
|
+
defaultMessage: "Cancel"
|
1677
|
+
}) }) }),
|
1678
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, children: formatMessage({
|
1679
|
+
id: "app.components.Button.confirm",
|
1680
|
+
defaultMessage: "Confirm"
|
1681
|
+
}) })
|
1682
|
+
] })
|
1683
|
+
] }) });
|
1568
1684
|
};
|
1569
1685
|
const DocumentActionModal = ({
|
1570
1686
|
isOpen,
|
1571
1687
|
title,
|
1572
1688
|
onClose,
|
1573
1689
|
footer: Footer,
|
1574
|
-
content,
|
1690
|
+
content: Content,
|
1575
1691
|
onModalClose
|
1576
1692
|
}) => {
|
1577
|
-
const id = React__namespace.useId();
|
1578
|
-
if (!isOpen) {
|
1579
|
-
return null;
|
1580
|
-
}
|
1581
1693
|
const handleClose = () => {
|
1582
1694
|
if (onClose) {
|
1583
1695
|
onClose();
|
1584
1696
|
}
|
1585
1697
|
onModalClose();
|
1586
1698
|
};
|
1587
|
-
return /* @__PURE__ */ jsxRuntime.
|
1588
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.
|
1589
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.
|
1590
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
1591
|
-
|
1592
|
-
{
|
1593
|
-
paddingTop: 4,
|
1594
|
-
paddingBottom: 4,
|
1595
|
-
paddingLeft: 5,
|
1596
|
-
paddingRight: 5,
|
1597
|
-
borderWidth: "1px 0 0 0",
|
1598
|
-
borderStyle: "solid",
|
1599
|
-
borderColor: "neutral150",
|
1600
|
-
background: "neutral100",
|
1601
|
-
children: typeof Footer === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Footer, { onClose: handleClose }) : Footer
|
1602
|
-
}
|
1603
|
-
)
|
1604
|
-
] });
|
1699
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Content, { children: [
|
1700
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Title, { children: title }) }),
|
1701
|
+
typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, { children: Content }),
|
1702
|
+
typeof Footer === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Footer, { onClose: handleClose }) : Footer
|
1703
|
+
] }) });
|
1605
1704
|
};
|
1606
|
-
const PublishAction = ({
|
1705
|
+
const PublishAction$1 = ({
|
1607
1706
|
activeTab,
|
1608
1707
|
documentId,
|
1609
1708
|
model,
|
@@ -1622,6 +1721,12 @@ const PublishAction = ({
|
|
1622
1721
|
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1623
1722
|
);
|
1624
1723
|
const { publish } = useDocumentActions();
|
1724
|
+
const [
|
1725
|
+
countDraftRelations,
|
1726
|
+
{ isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
|
1727
|
+
] = useLazyGetDraftRelationCountQuery();
|
1728
|
+
const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React__namespace.useState(0);
|
1729
|
+
const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React__namespace.useState(0);
|
1625
1730
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1626
1731
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
1627
1732
|
const modified = strapiAdmin.useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
@@ -1630,10 +1735,101 @@ const PublishAction = ({
|
|
1630
1735
|
const validate = strapiAdmin.useForm("PublishAction", (state) => state.validate);
|
1631
1736
|
const setErrors = strapiAdmin.useForm("PublishAction", (state) => state.setErrors);
|
1632
1737
|
const formValues = strapiAdmin.useForm("PublishAction", ({ values }) => values);
|
1738
|
+
React__namespace.useEffect(() => {
|
1739
|
+
if (isErrorDraftRelations) {
|
1740
|
+
toggleNotification({
|
1741
|
+
type: "danger",
|
1742
|
+
message: formatMessage({
|
1743
|
+
id: getTranslation("error.records.fetch-draft-relatons"),
|
1744
|
+
defaultMessage: "An error occurred while fetching draft relations on this document."
|
1745
|
+
})
|
1746
|
+
});
|
1747
|
+
}
|
1748
|
+
}, [isErrorDraftRelations, toggleNotification, formatMessage]);
|
1749
|
+
React__namespace.useEffect(() => {
|
1750
|
+
const localDraftRelations = /* @__PURE__ */ new Set();
|
1751
|
+
const extractDraftRelations = (data) => {
|
1752
|
+
const relations = data.connect || [];
|
1753
|
+
relations.forEach((relation) => {
|
1754
|
+
if (relation.status === "draft") {
|
1755
|
+
localDraftRelations.add(relation.id);
|
1756
|
+
}
|
1757
|
+
});
|
1758
|
+
};
|
1759
|
+
const traverseAndExtract = (data) => {
|
1760
|
+
Object.entries(data).forEach(([key, value]) => {
|
1761
|
+
if (key === "connect" && Array.isArray(value)) {
|
1762
|
+
extractDraftRelations({ connect: value });
|
1763
|
+
} else if (typeof value === "object" && value !== null) {
|
1764
|
+
traverseAndExtract(value);
|
1765
|
+
}
|
1766
|
+
});
|
1767
|
+
};
|
1768
|
+
if (!documentId || modified) {
|
1769
|
+
traverseAndExtract(formValues);
|
1770
|
+
setLocalCountOfDraftRelations(localDraftRelations.size);
|
1771
|
+
}
|
1772
|
+
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
1773
|
+
React__namespace.useEffect(() => {
|
1774
|
+
if (documentId) {
|
1775
|
+
const fetchDraftRelationsCount = async () => {
|
1776
|
+
const { data, error } = await countDraftRelations({
|
1777
|
+
collectionType,
|
1778
|
+
model,
|
1779
|
+
documentId,
|
1780
|
+
params
|
1781
|
+
});
|
1782
|
+
if (error) {
|
1783
|
+
throw error;
|
1784
|
+
}
|
1785
|
+
if (data) {
|
1786
|
+
setServerCountOfDraftRelations(data.data);
|
1787
|
+
}
|
1788
|
+
};
|
1789
|
+
fetchDraftRelationsCount();
|
1790
|
+
}
|
1791
|
+
}, [documentId, countDraftRelations, collectionType, model, params]);
|
1633
1792
|
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
1634
1793
|
if (!schema?.options?.draftAndPublish) {
|
1635
1794
|
return null;
|
1636
1795
|
}
|
1796
|
+
const performPublish = async () => {
|
1797
|
+
setSubmitting(true);
|
1798
|
+
try {
|
1799
|
+
const { errors } = await validate();
|
1800
|
+
if (errors) {
|
1801
|
+
toggleNotification({
|
1802
|
+
type: "danger",
|
1803
|
+
message: formatMessage({
|
1804
|
+
id: "content-manager.validation.error",
|
1805
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
1806
|
+
})
|
1807
|
+
});
|
1808
|
+
return;
|
1809
|
+
}
|
1810
|
+
const res = await publish(
|
1811
|
+
{
|
1812
|
+
collectionType,
|
1813
|
+
model,
|
1814
|
+
documentId,
|
1815
|
+
params
|
1816
|
+
},
|
1817
|
+
formValues
|
1818
|
+
);
|
1819
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1820
|
+
navigate({
|
1821
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1822
|
+
search: rawQuery
|
1823
|
+
});
|
1824
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1825
|
+
setErrors(formatValidationErrors(res.error));
|
1826
|
+
}
|
1827
|
+
} finally {
|
1828
|
+
setSubmitting(false);
|
1829
|
+
}
|
1830
|
+
};
|
1831
|
+
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
1832
|
+
const hasDraftRelations = totalDraftRelations > 0;
|
1637
1833
|
return {
|
1638
1834
|
/**
|
1639
1835
|
* Disabled when:
|
@@ -1643,52 +1839,42 @@ const PublishAction = ({
|
|
1643
1839
|
* - the document is already published & not modified
|
1644
1840
|
* - the document is being created & not modified
|
1645
1841
|
* - the user doesn't have the permission to publish
|
1646
|
-
* - the user doesn't have the permission to create a new document
|
1647
|
-
* - the user doesn't have the permission to update the document
|
1648
1842
|
*/
|
1649
|
-
disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish
|
1843
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
1650
1844
|
label: formatMessage({
|
1651
1845
|
id: "app.utils.publish",
|
1652
1846
|
defaultMessage: "Publish"
|
1653
1847
|
}),
|
1654
1848
|
onClick: async () => {
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1659
|
-
|
1660
|
-
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
1664
|
-
|
1665
|
-
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1669
|
-
|
1670
|
-
|
1671
|
-
|
1672
|
-
|
1673
|
-
|
1674
|
-
|
1675
|
-
formValues
|
1676
|
-
);
|
1677
|
-
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1678
|
-
navigate({
|
1679
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1680
|
-
search: rawQuery
|
1681
|
-
});
|
1682
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1683
|
-
setErrors(formatValidationErrors(res.error));
|
1849
|
+
if (hasDraftRelations) {
|
1850
|
+
return;
|
1851
|
+
}
|
1852
|
+
await performPublish();
|
1853
|
+
},
|
1854
|
+
dialog: hasDraftRelations ? {
|
1855
|
+
type: "dialog",
|
1856
|
+
variant: "danger",
|
1857
|
+
footer: null,
|
1858
|
+
title: formatMessage({
|
1859
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
|
1860
|
+
defaultMessage: "Confirmation"
|
1861
|
+
}),
|
1862
|
+
content: formatMessage(
|
1863
|
+
{
|
1864
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
1865
|
+
defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
|
1866
|
+
},
|
1867
|
+
{
|
1868
|
+
count: totalDraftRelations
|
1684
1869
|
}
|
1685
|
-
|
1686
|
-
|
1870
|
+
),
|
1871
|
+
onConfirm: async () => {
|
1872
|
+
await performPublish();
|
1687
1873
|
}
|
1688
|
-
}
|
1874
|
+
} : void 0
|
1689
1875
|
};
|
1690
1876
|
};
|
1691
|
-
PublishAction.type = "publish";
|
1877
|
+
PublishAction$1.type = "publish";
|
1692
1878
|
const UpdateAction = ({
|
1693
1879
|
activeTab,
|
1694
1880
|
documentId,
|
@@ -1701,7 +1887,7 @@ const UpdateAction = ({
|
|
1701
1887
|
const cloneMatch = reactRouterDom.useMatch(CLONE_PATH);
|
1702
1888
|
const isCloning = cloneMatch !== null;
|
1703
1889
|
const { formatMessage } = reactIntl.useIntl();
|
1704
|
-
|
1890
|
+
useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1705
1891
|
canCreate: canCreate2,
|
1706
1892
|
canUpdate: canUpdate2
|
1707
1893
|
}));
|
@@ -1721,10 +1907,8 @@ const UpdateAction = ({
|
|
1721
1907
|
* - the form is submitting
|
1722
1908
|
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
1723
1909
|
* - the active tab is the published tab
|
1724
|
-
* - the user doesn't have the permission to create a new document
|
1725
|
-
* - the user doesn't have the permission to update the document
|
1726
1910
|
*/
|
1727
|
-
disabled: isSubmitting || !modified && !isCloning || activeTab === "published"
|
1911
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1728
1912
|
label: formatMessage({
|
1729
1913
|
id: "content-manager.containers.Edit.save",
|
1730
1914
|
defaultMessage: "Save"
|
@@ -1753,10 +1937,13 @@ const UpdateAction = ({
|
|
1753
1937
|
document
|
1754
1938
|
);
|
1755
1939
|
if ("data" in res) {
|
1756
|
-
navigate(
|
1757
|
-
|
1758
|
-
|
1759
|
-
|
1940
|
+
navigate(
|
1941
|
+
{
|
1942
|
+
pathname: `../${res.data.documentId}`,
|
1943
|
+
search: rawQuery
|
1944
|
+
},
|
1945
|
+
{ relative: "path" }
|
1946
|
+
);
|
1760
1947
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1761
1948
|
setErrors(formatValidationErrors(res.error));
|
1762
1949
|
}
|
@@ -1784,10 +1971,13 @@ const UpdateAction = ({
|
|
1784
1971
|
document
|
1785
1972
|
);
|
1786
1973
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1787
|
-
navigate(
|
1788
|
-
|
1789
|
-
|
1790
|
-
|
1974
|
+
navigate(
|
1975
|
+
{
|
1976
|
+
pathname: `../${res.data.documentId}`,
|
1977
|
+
search: rawQuery
|
1978
|
+
},
|
1979
|
+
{ replace: true, relative: "path" }
|
1980
|
+
);
|
1791
1981
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1792
1982
|
setErrors(formatValidationErrors(res.error));
|
1793
1983
|
}
|
@@ -1803,7 +1993,7 @@ const UNPUBLISH_DRAFT_OPTIONS = {
|
|
1803
1993
|
KEEP: "keep",
|
1804
1994
|
DISCARD: "discard"
|
1805
1995
|
};
|
1806
|
-
const UnpublishAction = ({
|
1996
|
+
const UnpublishAction$1 = ({
|
1807
1997
|
activeTab,
|
1808
1998
|
documentId,
|
1809
1999
|
model,
|
@@ -1819,10 +2009,8 @@ const UnpublishAction = ({
|
|
1819
2009
|
const { toggleNotification } = strapiAdmin.useNotification();
|
1820
2010
|
const [shouldKeepDraft, setShouldKeepDraft] = React__namespace.useState(true);
|
1821
2011
|
const isDocumentModified = document?.status === "modified";
|
1822
|
-
const handleChange = (
|
1823
|
-
|
1824
|
-
setShouldKeepDraft(e.target.value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1825
|
-
}
|
2012
|
+
const handleChange = (value) => {
|
2013
|
+
setShouldKeepDraft(value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1826
2014
|
};
|
1827
2015
|
if (!schema?.options?.draftAndPublish) {
|
1828
2016
|
return null;
|
@@ -1866,45 +2054,30 @@ const UnpublishAction = ({
|
|
1866
2054
|
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "flex-start", direction: "column", gap: 6, children: [
|
1867
2055
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", direction: "column", gap: 2, children: [
|
1868
2056
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
1869
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2057
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
1870
2058
|
id: "content-manager.actions.unpublish.dialog.body",
|
1871
2059
|
defaultMessage: "Are you sure?"
|
1872
2060
|
}) })
|
1873
2061
|
] }),
|
1874
2062
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
1875
|
-
designSystem.
|
2063
|
+
designSystem.Radio.Group,
|
1876
2064
|
{
|
1877
|
-
|
1878
|
-
|
1879
|
-
|
1880
|
-
|
1881
|
-
|
2065
|
+
defaultValue: UNPUBLISH_DRAFT_OPTIONS.KEEP,
|
2066
|
+
name: "discard-options",
|
2067
|
+
"aria-label": formatMessage({
|
2068
|
+
id: "content-manager.actions.unpublish.dialog.radio-label",
|
2069
|
+
defaultMessage: "Choose an option to unpublish the document."
|
2070
|
+
}),
|
2071
|
+
onValueChange: handleChange,
|
1882
2072
|
children: [
|
1883
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.
|
1884
|
-
|
1885
|
-
|
1886
|
-
|
1887
|
-
|
1888
|
-
|
1889
|
-
|
1890
|
-
|
1891
|
-
id: "content-manager.actions.unpublish.dialog.option.keep-draft",
|
1892
|
-
defaultMessage: "Keep draft"
|
1893
|
-
})
|
1894
|
-
}
|
1895
|
-
),
|
1896
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
1897
|
-
designSystem.Radio,
|
1898
|
-
{
|
1899
|
-
checked: !shouldKeepDraft,
|
1900
|
-
value: UNPUBLISH_DRAFT_OPTIONS.DISCARD,
|
1901
|
-
name: "discard-options",
|
1902
|
-
children: formatMessage({
|
1903
|
-
id: "content-manager.actions.unpublish.dialog.option.replace-draft",
|
1904
|
-
defaultMessage: "Replace draft"
|
1905
|
-
})
|
1906
|
-
}
|
1907
|
-
)
|
2073
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Radio.Item, { checked: shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.KEEP, children: formatMessage({
|
2074
|
+
id: "content-manager.actions.unpublish.dialog.option.keep-draft",
|
2075
|
+
defaultMessage: "Keep draft"
|
2076
|
+
}) }),
|
2077
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Radio.Item, { checked: !shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.DISCARD, children: formatMessage({
|
2078
|
+
id: "content-manager.actions.unpublish.dialog.option.replace-draft",
|
2079
|
+
defaultMessage: "Replace draft"
|
2080
|
+
}) })
|
1908
2081
|
]
|
1909
2082
|
}
|
1910
2083
|
)
|
@@ -1937,7 +2110,7 @@ const UnpublishAction = ({
|
|
1937
2110
|
position: ["panel", "table-row"]
|
1938
2111
|
};
|
1939
2112
|
};
|
1940
|
-
UnpublishAction.type = "unpublish";
|
2113
|
+
UnpublishAction$1.type = "unpublish";
|
1941
2114
|
const DiscardAction = ({
|
1942
2115
|
activeTab,
|
1943
2116
|
documentId,
|
@@ -1971,7 +2144,7 @@ const DiscardAction = ({
|
|
1971
2144
|
}),
|
1972
2145
|
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, children: [
|
1973
2146
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
1974
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2147
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
1975
2148
|
id: "content-manager.actions.discard.dialog.body",
|
1976
2149
|
defaultMessage: "Are you sure?"
|
1977
2150
|
}) })
|
@@ -1988,12 +2161,12 @@ const DiscardAction = ({
|
|
1988
2161
|
};
|
1989
2162
|
};
|
1990
2163
|
DiscardAction.type = "discard";
|
1991
|
-
const StyledCrossCircle =
|
2164
|
+
const StyledCrossCircle = styledComponents.styled(Icons.CrossCircle)`
|
1992
2165
|
path {
|
1993
2166
|
fill: currentColor;
|
1994
2167
|
}
|
1995
2168
|
`;
|
1996
|
-
const DEFAULT_ACTIONS = [PublishAction, UpdateAction, UnpublishAction, DiscardAction];
|
2169
|
+
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
1997
2170
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
1998
2171
|
const RelativeTime = React__namespace.forwardRef(
|
1999
2172
|
({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {
|
@@ -2041,7 +2214,7 @@ const getDisplayName = ({
|
|
2041
2214
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2042
2215
|
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2043
2216
|
const statusVariant = status === "draft" ? "primary" : status === "published" ? "success" : "alternative";
|
2044
|
-
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2217
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: capitalise(status) }) });
|
2045
2218
|
};
|
2046
2219
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
2047
2220
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2050,23 +2223,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
|
2050
2223
|
id: "content-manager.containers.edit.title.new",
|
2051
2224
|
defaultMessage: "Create an entry"
|
2052
2225
|
}) : documentTitle;
|
2053
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop:
|
2226
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2054
2227
|
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.BackButton, {}),
|
2055
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
2056
|
-
designSystem.
|
2057
|
-
{
|
2058
|
-
|
2059
|
-
|
2060
|
-
paddingTop: 1,
|
2061
|
-
gap: "80px",
|
2062
|
-
alignItems: "flex-start",
|
2063
|
-
children: [
|
2064
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", as: "h1", children: title }),
|
2065
|
-
/* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
|
2066
|
-
]
|
2067
|
-
}
|
2068
|
-
),
|
2069
|
-
status ? /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: isCloning ? "draft" : status }) : null
|
2228
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2229
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
|
2230
|
+
/* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
|
2231
|
+
] }),
|
2232
|
+
status ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 1, children: /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
|
2070
2233
|
] });
|
2071
2234
|
};
|
2072
2235
|
const HeaderToolbar = () => {
|
@@ -2218,7 +2381,7 @@ const Information = ({ activeTab }) => {
|
|
2218
2381
|
borderColor: "neutral150",
|
2219
2382
|
direction: "column",
|
2220
2383
|
marginTop: 2,
|
2221
|
-
|
2384
|
+
tag: "dl",
|
2222
2385
|
padding: 5,
|
2223
2386
|
gap: 3,
|
2224
2387
|
alignItems: "flex-start",
|
@@ -2226,8 +2389,8 @@ const Information = ({ activeTab }) => {
|
|
2226
2389
|
marginRight: "-0.4rem",
|
2227
2390
|
width: "calc(100% + 8px)",
|
2228
2391
|
children: information.map((info) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 1, direction: "column", alignItems: "flex-start", children: [
|
2229
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2230
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2392
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "dt", variant: "pi", fontWeight: "bold", children: info.label }),
|
2393
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "dd", variant: "pi", textColor: "neutral600", children: info.value })
|
2231
2394
|
] }, info.label))
|
2232
2395
|
}
|
2233
2396
|
);
|
@@ -2260,7 +2423,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2260
2423
|
id: "app.links.configure-view",
|
2261
2424
|
defaultMessage: "Configure the view"
|
2262
2425
|
}),
|
2263
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2426
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ListPlus, {}),
|
2264
2427
|
onClick: () => {
|
2265
2428
|
navigate(`../${collectionType}/${model}/configurations/edit`);
|
2266
2429
|
},
|
@@ -2268,11 +2431,6 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2268
2431
|
};
|
2269
2432
|
};
|
2270
2433
|
ConfigureTheViewAction.type = "configure-the-view";
|
2271
|
-
const StyledCog = styled__default.default(Icons.Cog)`
|
2272
|
-
path {
|
2273
|
-
fill: currentColor;
|
2274
|
-
}
|
2275
|
-
`;
|
2276
2434
|
const EditTheModelAction = ({ model }) => {
|
2277
2435
|
const navigate = reactRouterDom.useNavigate();
|
2278
2436
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2281,7 +2439,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2281
2439
|
id: "content-manager.link-to-ctb",
|
2282
2440
|
defaultMessage: "Edit the model"
|
2283
2441
|
}),
|
2284
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2442
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, {}),
|
2285
2443
|
onClick: () => {
|
2286
2444
|
navigate(`/plugins/content-type-builder/content-types/${model}`);
|
2287
2445
|
},
|
@@ -2289,12 +2447,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2289
2447
|
};
|
2290
2448
|
};
|
2291
2449
|
EditTheModelAction.type = "edit-the-model";
|
2292
|
-
const
|
2293
|
-
path {
|
2294
|
-
fill: currentColor;
|
2295
|
-
}
|
2296
|
-
`;
|
2297
|
-
const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
2450
|
+
const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
2298
2451
|
const navigate = reactRouterDom.useNavigate();
|
2299
2452
|
const { formatMessage } = reactIntl.useIntl();
|
2300
2453
|
const listViewPathMatch = reactRouterDom.useMatch(LIST_PATH);
|
@@ -2308,7 +2461,7 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
|
2308
2461
|
id: "content-manager.actions.delete.label",
|
2309
2462
|
defaultMessage: "Delete document"
|
2310
2463
|
}),
|
2311
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2464
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {}),
|
2312
2465
|
dialog: {
|
2313
2466
|
type: "dialog",
|
2314
2467
|
title: formatMessage({
|
@@ -2317,7 +2470,7 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
|
2317
2470
|
}),
|
2318
2471
|
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, children: [
|
2319
2472
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
2320
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2473
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
2321
2474
|
id: "content-manager.actions.delete.dialog.body",
|
2322
2475
|
defaultMessage: "Are you sure?"
|
2323
2476
|
}) })
|
@@ -2362,13 +2515,8 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
|
2362
2515
|
position: ["header", "table-row"]
|
2363
2516
|
};
|
2364
2517
|
};
|
2365
|
-
DeleteAction.type = "delete";
|
2366
|
-
const
|
2367
|
-
path {
|
2368
|
-
fill: currentColor;
|
2369
|
-
}
|
2370
|
-
`;
|
2371
|
-
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction];
|
2518
|
+
DeleteAction$1.type = "delete";
|
2519
|
+
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2372
2520
|
const Panels = () => {
|
2373
2521
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2374
2522
|
const [
|
@@ -2442,7 +2590,7 @@ const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
|
2442
2590
|
designSystem.Flex,
|
2443
2591
|
{
|
2444
2592
|
ref,
|
2445
|
-
|
2593
|
+
tag: "aside",
|
2446
2594
|
"aria-labelledby": "additional-information",
|
2447
2595
|
background: "neutral0",
|
2448
2596
|
borderColor: "neutral150",
|
@@ -2457,68 +2605,947 @@ const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
|
2457
2605
|
justifyContent: "stretch",
|
2458
2606
|
alignItems: "flex-start",
|
2459
2607
|
children: [
|
2460
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2608
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2461
2609
|
children
|
2462
2610
|
]
|
2463
2611
|
}
|
2464
2612
|
);
|
2465
2613
|
});
|
2466
|
-
const
|
2467
|
-
|
2468
|
-
|
2469
|
-
|
2470
|
-
|
2471
|
-
|
2472
|
-
|
2473
|
-
|
2474
|
-
|
2475
|
-
|
2476
|
-
|
2477
|
-
|
2614
|
+
const HOOKS = {
|
2615
|
+
/**
|
2616
|
+
* Hook that allows to mutate the displayed headers of the list view table
|
2617
|
+
* @constant
|
2618
|
+
* @type {string}
|
2619
|
+
*/
|
2620
|
+
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2621
|
+
/**
|
2622
|
+
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2623
|
+
* @constant
|
2624
|
+
* @type {string}
|
2625
|
+
*/
|
2626
|
+
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2627
|
+
/**
|
2628
|
+
* Hook that allows to mutate the CM's edit view layout
|
2629
|
+
* @constant
|
2630
|
+
* @type {string}
|
2631
|
+
*/
|
2632
|
+
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2633
|
+
/**
|
2634
|
+
* Hook that allows to mutate the CM's single types links pre-set filters
|
2635
|
+
* @constant
|
2636
|
+
* @type {string}
|
2637
|
+
*/
|
2638
|
+
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2639
|
+
};
|
2640
|
+
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2641
|
+
endpoints: (builder) => ({
|
2642
|
+
getContentTypeConfiguration: builder.query({
|
2643
|
+
query: (uid) => ({
|
2644
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
2645
|
+
method: "GET"
|
2646
|
+
}),
|
2647
|
+
transformResponse: (response) => response.data,
|
2648
|
+
providesTags: (_result, _error, uid) => [
|
2649
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
2650
|
+
{ type: "ContentTypeSettings", id: "LIST" }
|
2651
|
+
]
|
2652
|
+
}),
|
2653
|
+
getAllContentTypeSettings: builder.query({
|
2654
|
+
query: () => "/content-manager/content-types-settings",
|
2655
|
+
transformResponse: (response) => response.data,
|
2656
|
+
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2657
|
+
}),
|
2658
|
+
updateContentTypeConfiguration: builder.mutation({
|
2659
|
+
query: ({ uid, ...body }) => ({
|
2660
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
2661
|
+
method: "PUT",
|
2662
|
+
data: body
|
2663
|
+
}),
|
2664
|
+
transformResponse: (response) => response.data,
|
2665
|
+
invalidatesTags: (_result, _error, { uid }) => [
|
2666
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
2667
|
+
{ type: "ContentTypeSettings", id: "LIST" },
|
2668
|
+
// Is this necessary?
|
2669
|
+
{ type: "InitialData" }
|
2670
|
+
]
|
2671
|
+
})
|
2672
|
+
})
|
2673
|
+
});
|
2674
|
+
const {
|
2675
|
+
useGetContentTypeConfigurationQuery,
|
2676
|
+
useGetAllContentTypeSettingsQuery,
|
2677
|
+
useUpdateContentTypeConfigurationMutation
|
2678
|
+
} = contentTypesApi;
|
2679
|
+
const checkIfAttributeIsDisplayable = (attribute) => {
|
2680
|
+
const { type } = attribute;
|
2681
|
+
if (type === "relation") {
|
2682
|
+
return !attribute.relation.toLowerCase().includes("morph");
|
2683
|
+
}
|
2684
|
+
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2685
|
+
};
|
2686
|
+
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2687
|
+
if (!mainFieldName) {
|
2688
|
+
return void 0;
|
2689
|
+
}
|
2690
|
+
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2691
|
+
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2692
|
+
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2693
|
+
);
|
2694
|
+
return {
|
2695
|
+
name: mainFieldName,
|
2696
|
+
type: mainFieldType ?? "string"
|
2478
2697
|
};
|
2479
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
2480
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", children: formatMessage({
|
2481
|
-
id: getTranslation("containers.list.autoCloneModal.title"),
|
2482
|
-
defaultMessage: "This entry can't be duplicated directly."
|
2483
|
-
}) }),
|
2484
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", children: formatMessage({
|
2485
|
-
id: getTranslation("containers.list.autoCloneModal.description"),
|
2486
|
-
defaultMessage: "A new entry will be created with the same content, but you'll have to change the following fields to save it."
|
2487
|
-
}) }) }),
|
2488
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { marginTop: 6, gap: 2, direction: "column", alignItems: "stretch", children: prohibitedFields.map(([fieldPath, reason]) => /* @__PURE__ */ jsxRuntime.jsxs(
|
2489
|
-
designSystem.Flex,
|
2490
|
-
{
|
2491
|
-
direction: "column",
|
2492
|
-
gap: 2,
|
2493
|
-
alignItems: "flex-start",
|
2494
|
-
borderColor: "neutral200",
|
2495
|
-
hasRadius: true,
|
2496
|
-
padding: 6,
|
2497
|
-
children: [
|
2498
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "row", as: "ol", children: fieldPath.map((pathSegment, index2) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { fontWeight: "semiBold", as: "li", children: [
|
2499
|
-
pathSegment,
|
2500
|
-
index2 !== fieldPath.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(
|
2501
|
-
Icons.ChevronRight,
|
2502
|
-
{
|
2503
|
-
fill: "neutral500",
|
2504
|
-
height: "0.8rem",
|
2505
|
-
width: "0.8rem",
|
2506
|
-
style: { margin: "0 0.8rem" }
|
2507
|
-
}
|
2508
|
-
)
|
2509
|
-
] }, index2)) }),
|
2510
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { as: "p", textColor: "neutral600", children: formatMessage({
|
2511
|
-
id: getTranslation(`containers.list.autoCloneModal.error.${reason}`),
|
2512
|
-
defaultMessage: getDefaultErrorMessage(reason)
|
2513
|
-
}) })
|
2514
|
-
]
|
2515
|
-
},
|
2516
|
-
fieldPath.join()
|
2517
|
-
)) })
|
2518
|
-
] });
|
2519
2698
|
};
|
2520
|
-
const
|
2521
|
-
|
2699
|
+
const DEFAULT_SETTINGS = {
|
2700
|
+
bulkable: false,
|
2701
|
+
filterable: false,
|
2702
|
+
searchable: false,
|
2703
|
+
pagination: false,
|
2704
|
+
defaultSortBy: "",
|
2705
|
+
defaultSortOrder: "asc",
|
2706
|
+
mainField: "id",
|
2707
|
+
pageSize: 10
|
2708
|
+
};
|
2709
|
+
const useDocumentLayout = (model) => {
|
2710
|
+
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2711
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
2712
|
+
const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2713
|
+
const { toggleNotification } = strapiAdmin.useNotification();
|
2714
|
+
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
2715
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2716
|
+
const {
|
2717
|
+
data,
|
2718
|
+
isLoading: isLoadingConfigs,
|
2719
|
+
error,
|
2720
|
+
isFetching: isFetchingConfigs
|
2721
|
+
} = useGetContentTypeConfigurationQuery(model);
|
2722
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2723
|
+
React__namespace.useEffect(() => {
|
2724
|
+
if (error) {
|
2725
|
+
toggleNotification({
|
2726
|
+
type: "danger",
|
2727
|
+
message: formatAPIError(error)
|
2728
|
+
});
|
2729
|
+
}
|
2730
|
+
}, [error, formatAPIError, toggleNotification]);
|
2731
|
+
const editLayout = React__namespace.useMemo(
|
2732
|
+
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2733
|
+
layout: [],
|
2734
|
+
components: {},
|
2735
|
+
metadatas: {},
|
2736
|
+
options: {},
|
2737
|
+
settings: DEFAULT_SETTINGS
|
2738
|
+
},
|
2739
|
+
[data, isLoading, schemas, schema, components]
|
2740
|
+
);
|
2741
|
+
const listLayout = React__namespace.useMemo(() => {
|
2742
|
+
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2743
|
+
layout: [],
|
2744
|
+
metadatas: {},
|
2745
|
+
options: {},
|
2746
|
+
settings: DEFAULT_SETTINGS
|
2747
|
+
};
|
2748
|
+
}, [data, isLoading, schemas, schema, components]);
|
2749
|
+
const { layout: edit } = React__namespace.useMemo(
|
2750
|
+
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2751
|
+
layout: editLayout,
|
2752
|
+
query
|
2753
|
+
}),
|
2754
|
+
[editLayout, query, runHookWaterfall]
|
2755
|
+
);
|
2756
|
+
return {
|
2757
|
+
error,
|
2758
|
+
isLoading,
|
2759
|
+
edit,
|
2760
|
+
list: listLayout
|
2761
|
+
};
|
2762
|
+
};
|
2763
|
+
const useDocLayout = () => {
|
2764
|
+
const { model } = useDoc();
|
2765
|
+
return useDocumentLayout(model);
|
2766
|
+
};
|
2767
|
+
const formatEditLayout = (data, {
|
2768
|
+
schemas,
|
2769
|
+
schema,
|
2770
|
+
components
|
2771
|
+
}) => {
|
2772
|
+
let currentPanelIndex = 0;
|
2773
|
+
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2774
|
+
data.contentType.layouts.edit,
|
2775
|
+
schema?.attributes,
|
2776
|
+
data.contentType.metadatas,
|
2777
|
+
{ configurations: data.components, schemas: components },
|
2778
|
+
schemas
|
2779
|
+
).reduce((panels, row) => {
|
2780
|
+
if (row.some((field) => field.type === "dynamiczone")) {
|
2781
|
+
panels.push([row]);
|
2782
|
+
currentPanelIndex += 2;
|
2783
|
+
} else {
|
2784
|
+
if (!panels[currentPanelIndex]) {
|
2785
|
+
panels.push([]);
|
2786
|
+
}
|
2787
|
+
panels[currentPanelIndex].push(row);
|
2788
|
+
}
|
2789
|
+
return panels;
|
2790
|
+
}, []);
|
2791
|
+
const componentEditAttributes = Object.entries(data.components).reduce(
|
2792
|
+
(acc, [uid, configuration]) => {
|
2793
|
+
acc[uid] = {
|
2794
|
+
layout: convertEditLayoutToFieldLayouts(
|
2795
|
+
configuration.layouts.edit,
|
2796
|
+
components[uid].attributes,
|
2797
|
+
configuration.metadatas
|
2798
|
+
),
|
2799
|
+
settings: {
|
2800
|
+
...configuration.settings,
|
2801
|
+
icon: components[uid].info.icon,
|
2802
|
+
displayName: components[uid].info.displayName
|
2803
|
+
}
|
2804
|
+
};
|
2805
|
+
return acc;
|
2806
|
+
},
|
2807
|
+
{}
|
2808
|
+
);
|
2809
|
+
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2810
|
+
(acc, [attribute, metadata]) => {
|
2811
|
+
return {
|
2812
|
+
...acc,
|
2813
|
+
[attribute]: metadata.edit
|
2814
|
+
};
|
2815
|
+
},
|
2816
|
+
{}
|
2817
|
+
);
|
2818
|
+
return {
|
2819
|
+
layout: panelledEditAttributes,
|
2820
|
+
components: componentEditAttributes,
|
2821
|
+
metadatas: editMetadatas,
|
2822
|
+
settings: {
|
2823
|
+
...data.contentType.settings,
|
2824
|
+
displayName: schema?.info.displayName
|
2825
|
+
},
|
2826
|
+
options: {
|
2827
|
+
...schema?.options,
|
2828
|
+
...schema?.pluginOptions,
|
2829
|
+
...data.contentType.options
|
2830
|
+
}
|
2831
|
+
};
|
2832
|
+
};
|
2833
|
+
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
2834
|
+
return rows.map(
|
2835
|
+
(row) => row.map((field) => {
|
2836
|
+
const attribute = attributes[field.name];
|
2837
|
+
if (!attribute) {
|
2838
|
+
return null;
|
2839
|
+
}
|
2840
|
+
const { edit: metadata } = metadatas[field.name];
|
2841
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
2842
|
+
return {
|
2843
|
+
attribute,
|
2844
|
+
disabled: !metadata.editable,
|
2845
|
+
hint: metadata.description,
|
2846
|
+
label: metadata.label ?? "",
|
2847
|
+
name: field.name,
|
2848
|
+
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
2849
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
2850
|
+
schemas,
|
2851
|
+
components: components?.schemas ?? {}
|
2852
|
+
}),
|
2853
|
+
placeholder: metadata.placeholder ?? "",
|
2854
|
+
required: attribute.required ?? false,
|
2855
|
+
size: field.size,
|
2856
|
+
unique: "unique" in attribute ? attribute.unique : false,
|
2857
|
+
visible: metadata.visible ?? true,
|
2858
|
+
type: attribute.type
|
2859
|
+
};
|
2860
|
+
}).filter((field) => field !== null)
|
2861
|
+
);
|
2862
|
+
};
|
2863
|
+
const formatListLayout = (data, {
|
2864
|
+
schemas,
|
2865
|
+
schema,
|
2866
|
+
components
|
2867
|
+
}) => {
|
2868
|
+
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2869
|
+
(acc, [attribute, metadata]) => {
|
2870
|
+
return {
|
2871
|
+
...acc,
|
2872
|
+
[attribute]: metadata.list
|
2873
|
+
};
|
2874
|
+
},
|
2875
|
+
{}
|
2876
|
+
);
|
2877
|
+
const listAttributes = convertListLayoutToFieldLayouts(
|
2878
|
+
data.contentType.layouts.list,
|
2879
|
+
schema?.attributes,
|
2880
|
+
listMetadatas,
|
2881
|
+
{ configurations: data.components, schemas: components },
|
2882
|
+
schemas
|
2883
|
+
);
|
2884
|
+
return {
|
2885
|
+
layout: listAttributes,
|
2886
|
+
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
2887
|
+
metadatas: listMetadatas,
|
2888
|
+
options: {
|
2889
|
+
...schema?.options,
|
2890
|
+
...schema?.pluginOptions,
|
2891
|
+
...data.contentType.options
|
2892
|
+
}
|
2893
|
+
};
|
2894
|
+
};
|
2895
|
+
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
2896
|
+
return columns.map((name) => {
|
2897
|
+
const attribute = attributes[name];
|
2898
|
+
if (!attribute) {
|
2899
|
+
return null;
|
2900
|
+
}
|
2901
|
+
const metadata = metadatas[name];
|
2902
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
2903
|
+
return {
|
2904
|
+
attribute,
|
2905
|
+
label: metadata.label ?? "",
|
2906
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
2907
|
+
schemas,
|
2908
|
+
components: components?.schemas ?? {}
|
2909
|
+
}),
|
2910
|
+
name,
|
2911
|
+
searchable: metadata.searchable ?? true,
|
2912
|
+
sortable: metadata.sortable ?? true
|
2913
|
+
};
|
2914
|
+
}).filter((field) => field !== null);
|
2915
|
+
};
|
2916
|
+
const ConfirmBulkActionDialog = ({
|
2917
|
+
onToggleDialog,
|
2918
|
+
isOpen = false,
|
2919
|
+
dialogBody,
|
2920
|
+
endAction
|
2921
|
+
}) => {
|
2922
|
+
const { formatMessage } = reactIntl.useIntl();
|
2923
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
2924
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: formatMessage({
|
2925
|
+
id: "app.components.ConfirmDialog.title",
|
2926
|
+
defaultMessage: "Confirmation"
|
2927
|
+
}) }),
|
2928
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
2929
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
2930
|
+
dialogBody
|
2931
|
+
] }) }),
|
2932
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
|
2933
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { fullWidth: true, onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
|
2934
|
+
id: "app.components.Button.cancel",
|
2935
|
+
defaultMessage: "Cancel"
|
2936
|
+
}) }) }),
|
2937
|
+
endAction
|
2938
|
+
] })
|
2939
|
+
] }) });
|
2940
|
+
};
|
2941
|
+
const BoldChunk$1 = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
|
2942
|
+
const ConfirmDialogPublishAll = ({
|
2943
|
+
isOpen,
|
2944
|
+
onToggleDialog,
|
2945
|
+
isConfirmButtonLoading = false,
|
2946
|
+
onConfirm
|
2947
|
+
}) => {
|
2948
|
+
const { formatMessage } = reactIntl.useIntl();
|
2949
|
+
const selectedEntries = strapiAdmin.useTable("ConfirmDialogPublishAll", (state) => state.selectedRows);
|
2950
|
+
const { toggleNotification } = strapiAdmin.useNotification();
|
2951
|
+
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler(getTranslation);
|
2952
|
+
const { model, schema } = useDoc();
|
2953
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
2954
|
+
const {
|
2955
|
+
data: countDraftRelations = 0,
|
2956
|
+
isLoading,
|
2957
|
+
error
|
2958
|
+
} = useGetManyDraftRelationCountQuery(
|
2959
|
+
{
|
2960
|
+
model,
|
2961
|
+
documentIds: selectedEntries.map((entry) => entry.documentId),
|
2962
|
+
locale: query?.plugins?.i18n?.locale
|
2963
|
+
},
|
2964
|
+
{
|
2965
|
+
skip: selectedEntries.length === 0
|
2966
|
+
}
|
2967
|
+
);
|
2968
|
+
React__namespace.useEffect(() => {
|
2969
|
+
if (error) {
|
2970
|
+
toggleNotification({ type: "danger", message: formatAPIError(error) });
|
2971
|
+
}
|
2972
|
+
}, [error, formatAPIError, toggleNotification]);
|
2973
|
+
if (error) {
|
2974
|
+
return null;
|
2975
|
+
}
|
2976
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
2977
|
+
ConfirmBulkActionDialog,
|
2978
|
+
{
|
2979
|
+
isOpen: isOpen && !isLoading,
|
2980
|
+
onToggleDialog,
|
2981
|
+
dialogBody: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
2982
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: [
|
2983
|
+
countDraftRelations > 0 && formatMessage(
|
2984
|
+
{
|
2985
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
2986
|
+
defaultMessage: "<b>{count} {count, plural, one { relation } other { relations } } out of {entities} { entities, plural, one { entry } other { entries } } {count, plural, one { is } other { are } }</b> not published yet and might lead to unexpected behavior. "
|
2987
|
+
},
|
2988
|
+
{
|
2989
|
+
b: BoldChunk$1,
|
2990
|
+
count: countDraftRelations,
|
2991
|
+
entities: selectedEntries.length
|
2992
|
+
}
|
2993
|
+
),
|
2994
|
+
formatMessage({
|
2995
|
+
id: getTranslation("popUpWarning.bodyMessage.contentType.publish.all"),
|
2996
|
+
defaultMessage: "Are you sure you want to publish these entries?"
|
2997
|
+
})
|
2998
|
+
] }),
|
2999
|
+
schema?.pluginOptions && "i18n" in schema.pluginOptions && schema?.pluginOptions.i18n && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", textAlign: "center", children: formatMessage(
|
3000
|
+
{
|
3001
|
+
id: getTranslation("Settings.list.actions.publishAdditionalInfos"),
|
3002
|
+
defaultMessage: "This will publish the active locale versions <em>(from Internationalization)</em>"
|
3003
|
+
},
|
3004
|
+
{
|
3005
|
+
em: Emphasis
|
3006
|
+
}
|
3007
|
+
) })
|
3008
|
+
] }),
|
3009
|
+
endAction: /* @__PURE__ */ jsxRuntime.jsx(
|
3010
|
+
designSystem.Button,
|
3011
|
+
{
|
3012
|
+
onClick: onConfirm,
|
3013
|
+
variant: "secondary",
|
3014
|
+
startIcon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Check, {}),
|
3015
|
+
loading: isConfirmButtonLoading,
|
3016
|
+
children: formatMessage({
|
3017
|
+
id: "app.utils.publish",
|
3018
|
+
defaultMessage: "Publish"
|
3019
|
+
})
|
3020
|
+
}
|
3021
|
+
)
|
3022
|
+
}
|
3023
|
+
);
|
3024
|
+
};
|
3025
|
+
const TypographyMaxWidth = styledComponents.styled(designSystem.Typography)`
|
3026
|
+
max-width: 300px;
|
3027
|
+
`;
|
3028
|
+
const formatErrorMessages = (errors, parentKey, formatMessage) => {
|
3029
|
+
const messages = [];
|
3030
|
+
Object.entries(errors).forEach(([key, value]) => {
|
3031
|
+
const currentKey = parentKey ? `${parentKey}.${key}` : key;
|
3032
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
3033
|
+
if ("id" in value && "defaultMessage" in value) {
|
3034
|
+
messages.push(
|
3035
|
+
formatMessage(
|
3036
|
+
{
|
3037
|
+
id: `${value.id}.withField`,
|
3038
|
+
defaultMessage: value.defaultMessage
|
3039
|
+
},
|
3040
|
+
{ field: currentKey }
|
3041
|
+
)
|
3042
|
+
);
|
3043
|
+
} else {
|
3044
|
+
messages.push(
|
3045
|
+
...formatErrorMessages(
|
3046
|
+
// @ts-expect-error TODO: check why value is not compatible with FormErrors
|
3047
|
+
value,
|
3048
|
+
currentKey,
|
3049
|
+
formatMessage
|
3050
|
+
)
|
3051
|
+
);
|
3052
|
+
}
|
3053
|
+
} else {
|
3054
|
+
messages.push(
|
3055
|
+
formatMessage(
|
3056
|
+
{
|
3057
|
+
id: `${value}.withField`,
|
3058
|
+
defaultMessage: value
|
3059
|
+
},
|
3060
|
+
{ field: currentKey }
|
3061
|
+
)
|
3062
|
+
);
|
3063
|
+
}
|
3064
|
+
});
|
3065
|
+
return messages;
|
3066
|
+
};
|
3067
|
+
const EntryValidationText = ({ validationErrors, status }) => {
|
3068
|
+
const { formatMessage } = reactIntl.useIntl();
|
3069
|
+
if (validationErrors) {
|
3070
|
+
const validationErrorsMessages = formatErrorMessages(validationErrors, "", formatMessage).join(
|
3071
|
+
" "
|
3072
|
+
);
|
3073
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3074
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.CrossCircle, { fill: "danger600" }),
|
3075
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsxRuntime.jsx(TypographyMaxWidth, { textColor: "danger600", variant: "omega", fontWeight: "semiBold", ellipsis: true, children: validationErrorsMessages }) })
|
3076
|
+
] });
|
3077
|
+
}
|
3078
|
+
if (status === "published") {
|
3079
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3080
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.CheckCircle, { fill: "success600" }),
|
3081
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
|
3082
|
+
id: "content-manager.bulk-publish.already-published",
|
3083
|
+
defaultMessage: "Already Published"
|
3084
|
+
}) })
|
3085
|
+
] });
|
3086
|
+
}
|
3087
|
+
if (status === "modified") {
|
3088
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3089
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.ArrowsCounterClockwise, { fill: "alternative600" }),
|
3090
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
|
3091
|
+
id: "content-manager.bulk-publish.modified",
|
3092
|
+
defaultMessage: "Ready to publish changes"
|
3093
|
+
}) })
|
3094
|
+
] });
|
3095
|
+
}
|
3096
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3097
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.CheckCircle, { fill: "success600" }),
|
3098
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
|
3099
|
+
id: "app.utils.ready-to-publish",
|
3100
|
+
defaultMessage: "Ready to publish"
|
3101
|
+
}) })
|
3102
|
+
] });
|
3103
|
+
};
|
3104
|
+
const TABLE_HEADERS = [
|
3105
|
+
{ name: "id", label: "id" },
|
3106
|
+
{ name: "name", label: "name" },
|
3107
|
+
{ name: "status", label: "status" },
|
3108
|
+
{ name: "publicationStatus", label: "Publication status" }
|
3109
|
+
];
|
3110
|
+
const SelectedEntriesTableContent = ({
|
3111
|
+
isPublishing,
|
3112
|
+
rowsToDisplay = [],
|
3113
|
+
entriesToPublish = [],
|
3114
|
+
validationErrors = {}
|
3115
|
+
}) => {
|
3116
|
+
const { pathname } = reactRouterDom.useLocation();
|
3117
|
+
const { formatMessage } = reactIntl.useIntl();
|
3118
|
+
const {
|
3119
|
+
list: {
|
3120
|
+
settings: { mainField }
|
3121
|
+
}
|
3122
|
+
} = useDocLayout();
|
3123
|
+
const shouldDisplayMainField = mainField != null && mainField !== "id";
|
3124
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Content, { children: [
|
3125
|
+
/* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Head, { children: [
|
3126
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.HeaderCheckboxCell, {}),
|
3127
|
+
TABLE_HEADERS.filter((head) => head.name !== "name" || shouldDisplayMainField).map(
|
3128
|
+
(head) => /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.HeaderCell, { ...head }, head.name)
|
3129
|
+
)
|
3130
|
+
] }),
|
3131
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Loading, {}),
|
3132
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Body, { children: rowsToDisplay.map((row, index2) => /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Row, { children: [
|
3133
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.CheckboxCell, { id: row.id }),
|
3134
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: row.id }) }),
|
3135
|
+
shouldDisplayMainField && /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: row[mainField] }) }),
|
3136
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: row.status, maxWidth: "min-content" }) }),
|
3137
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: isPublishing && entriesToPublish.includes(row.documentId) ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3138
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
|
3139
|
+
id: "content-manager.success.record.publishing",
|
3140
|
+
defaultMessage: "Publishing..."
|
3141
|
+
}) }),
|
3142
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, { small: true })
|
3143
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx(
|
3144
|
+
EntryValidationText,
|
3145
|
+
{
|
3146
|
+
validationErrors: validationErrors[row.documentId],
|
3147
|
+
status: row.status
|
3148
|
+
}
|
3149
|
+
) }),
|
3150
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
3151
|
+
designSystem.IconButton,
|
3152
|
+
{
|
3153
|
+
tag: reactRouterDom.Link,
|
3154
|
+
to: {
|
3155
|
+
pathname: `${pathname}/${row.documentId}`,
|
3156
|
+
search: row.locale && `?plugins[i18n][locale]=${row.locale}`
|
3157
|
+
},
|
3158
|
+
state: { from: pathname },
|
3159
|
+
label: formatMessage(
|
3160
|
+
{ id: "app.component.HelperPluginTable.edit", defaultMessage: "Edit {target}" },
|
3161
|
+
{
|
3162
|
+
target: formatMessage(
|
3163
|
+
{
|
3164
|
+
id: "content-manager.components.ListViewHelperPluginTable.row-line",
|
3165
|
+
defaultMessage: "item line {number}"
|
3166
|
+
},
|
3167
|
+
{ number: index2 + 1 }
|
3168
|
+
)
|
3169
|
+
}
|
3170
|
+
),
|
3171
|
+
target: "_blank",
|
3172
|
+
marginLeft: "auto",
|
3173
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, {})
|
3174
|
+
}
|
3175
|
+
) })
|
3176
|
+
] }, row.id)) })
|
3177
|
+
] });
|
3178
|
+
};
|
3179
|
+
const BoldChunk = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
|
3180
|
+
const SelectedEntriesModalContent = ({
|
3181
|
+
listViewSelectedEntries,
|
3182
|
+
toggleModal,
|
3183
|
+
setListViewSelectedDocuments,
|
3184
|
+
model
|
3185
|
+
}) => {
|
3186
|
+
const { formatMessage } = reactIntl.useIntl();
|
3187
|
+
const { schema, components } = useContentTypeSchema(model);
|
3188
|
+
const documentIds = listViewSelectedEntries.map(({ documentId }) => documentId);
|
3189
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3190
|
+
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
3191
|
+
const { data, isLoading, isFetching, refetch } = useGetAllDocumentsQuery(
|
3192
|
+
{
|
3193
|
+
model,
|
3194
|
+
params: {
|
3195
|
+
page: "1",
|
3196
|
+
pageSize: documentIds.length.toString(),
|
3197
|
+
sort: query.sort,
|
3198
|
+
filters: {
|
3199
|
+
documentId: {
|
3200
|
+
$in: documentIds
|
3201
|
+
}
|
3202
|
+
},
|
3203
|
+
locale: query.plugins?.i18n?.locale
|
3204
|
+
}
|
3205
|
+
},
|
3206
|
+
{
|
3207
|
+
selectFromResult: ({ data: data2, ...restRes }) => ({ data: data2?.results ?? [], ...restRes })
|
3208
|
+
}
|
3209
|
+
);
|
3210
|
+
const { rows, validationErrors } = React__namespace.useMemo(() => {
|
3211
|
+
if (data.length > 0 && schema) {
|
3212
|
+
const validate = createYupSchema(schema.attributes, components);
|
3213
|
+
const validationErrors2 = {};
|
3214
|
+
const rows2 = data.map((entry) => {
|
3215
|
+
try {
|
3216
|
+
validate.validateSync(entry, { abortEarly: false });
|
3217
|
+
return entry;
|
3218
|
+
} catch (e) {
|
3219
|
+
if (e instanceof yup.ValidationError) {
|
3220
|
+
validationErrors2[entry.documentId] = strapiAdmin.getYupValidationErrors(e);
|
3221
|
+
}
|
3222
|
+
return entry;
|
3223
|
+
}
|
3224
|
+
});
|
3225
|
+
return { rows: rows2, validationErrors: validationErrors2 };
|
3226
|
+
}
|
3227
|
+
return {
|
3228
|
+
rows: [],
|
3229
|
+
validationErrors: {}
|
3230
|
+
};
|
3231
|
+
}, [components, data, schema]);
|
3232
|
+
const [publishedCount, setPublishedCount] = React__namespace.useState(0);
|
3233
|
+
const [isDialogOpen, setIsDialogOpen] = React__namespace.useState(false);
|
3234
|
+
const { publishMany: bulkPublishAction } = useDocumentActions();
|
3235
|
+
const [, { isLoading: isSubmittingForm }] = usePublishManyDocumentsMutation();
|
3236
|
+
const selectedRows = strapiAdmin.useTable("publishAction", (state) => state.selectedRows);
|
3237
|
+
const selectedEntries = rows.filter(
|
3238
|
+
(entry) => selectedRows.some((selectedEntry) => selectedEntry.documentId === entry.documentId)
|
3239
|
+
);
|
3240
|
+
const entriesToPublish = selectedEntries.filter((entry) => !validationErrors[entry.documentId]).map((entry) => entry.documentId);
|
3241
|
+
const selectedEntriesWithErrorsCount = selectedEntries.filter(
|
3242
|
+
({ documentId }) => validationErrors[documentId]
|
3243
|
+
).length;
|
3244
|
+
const selectedEntriesPublished = selectedEntries.filter(
|
3245
|
+
({ status }) => status === "published"
|
3246
|
+
).length;
|
3247
|
+
const selectedEntriesWithNoErrorsCount = selectedEntries.length - selectedEntriesWithErrorsCount - selectedEntriesPublished;
|
3248
|
+
const toggleDialog = () => setIsDialogOpen((prev) => !prev);
|
3249
|
+
const handleConfirmBulkPublish = async () => {
|
3250
|
+
toggleDialog();
|
3251
|
+
const res = await bulkPublishAction({ model, documentIds: entriesToPublish, params });
|
3252
|
+
if (!("error" in res)) {
|
3253
|
+
setPublishedCount(res.count);
|
3254
|
+
const unpublishedEntries = rows.filter((row) => {
|
3255
|
+
return !entriesToPublish.includes(row.documentId);
|
3256
|
+
});
|
3257
|
+
setListViewSelectedDocuments(unpublishedEntries);
|
3258
|
+
}
|
3259
|
+
};
|
3260
|
+
const getFormattedCountMessage = () => {
|
3261
|
+
if (publishedCount) {
|
3262
|
+
return formatMessage(
|
3263
|
+
{
|
3264
|
+
id: getTranslation("containers.list.selectedEntriesModal.publishedCount"),
|
3265
|
+
defaultMessage: "<b>{publishedCount}</b> {publishedCount, plural, =0 {entries} one {entry} other {entries}} published. <b>{withErrorsCount}</b> {withErrorsCount, plural, =0 {entries} one {entry} other {entries}} waiting for action."
|
3266
|
+
},
|
3267
|
+
{
|
3268
|
+
publishedCount,
|
3269
|
+
withErrorsCount: selectedEntriesWithErrorsCount,
|
3270
|
+
b: BoldChunk
|
3271
|
+
}
|
3272
|
+
);
|
3273
|
+
}
|
3274
|
+
return formatMessage(
|
3275
|
+
{
|
3276
|
+
id: getTranslation("containers.list.selectedEntriesModal.selectedCount"),
|
3277
|
+
defaultMessage: "<b>{alreadyPublishedCount}</b> {alreadyPublishedCount, plural, =0 {entries} one {entry} other {entries}} already published. <b>{readyToPublishCount}</b> {readyToPublishCount, plural, =0 {entries} one {entry} other {entries}} ready to publish. <b>{withErrorsCount}</b> {withErrorsCount, plural, =0 {entries} one {entry} other {entries}} waiting for action."
|
3278
|
+
},
|
3279
|
+
{
|
3280
|
+
readyToPublishCount: selectedEntriesWithNoErrorsCount,
|
3281
|
+
withErrorsCount: selectedEntriesWithErrorsCount,
|
3282
|
+
alreadyPublishedCount: selectedEntriesPublished,
|
3283
|
+
b: BoldChunk
|
3284
|
+
}
|
3285
|
+
);
|
3286
|
+
};
|
3287
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
3288
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Body, { children: [
|
3289
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: getFormattedCountMessage() }),
|
3290
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 5, children: /* @__PURE__ */ jsxRuntime.jsx(
|
3291
|
+
SelectedEntriesTableContent,
|
3292
|
+
{
|
3293
|
+
isPublishing: isSubmittingForm,
|
3294
|
+
rowsToDisplay: rows,
|
3295
|
+
entriesToPublish,
|
3296
|
+
validationErrors
|
3297
|
+
}
|
3298
|
+
) })
|
3299
|
+
] }),
|
3300
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
3301
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
|
3302
|
+
id: "app.components.Button.cancel",
|
3303
|
+
defaultMessage: "Cancel"
|
3304
|
+
}) }),
|
3305
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3306
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
|
3307
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
3308
|
+
designSystem.Button,
|
3309
|
+
{
|
3310
|
+
onClick: toggleDialog,
|
3311
|
+
disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
|
3312
|
+
loading: isSubmittingForm,
|
3313
|
+
children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
|
3314
|
+
}
|
3315
|
+
)
|
3316
|
+
] })
|
3317
|
+
] }),
|
3318
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
3319
|
+
ConfirmDialogPublishAll,
|
3320
|
+
{
|
3321
|
+
isOpen: isDialogOpen,
|
3322
|
+
onToggleDialog: toggleDialog,
|
3323
|
+
isConfirmButtonLoading: isSubmittingForm,
|
3324
|
+
onConfirm: handleConfirmBulkPublish
|
3325
|
+
}
|
3326
|
+
)
|
3327
|
+
] });
|
3328
|
+
};
|
3329
|
+
const PublishAction = ({ documents, model }) => {
|
3330
|
+
const { formatMessage } = reactIntl.useIntl();
|
3331
|
+
const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
|
3332
|
+
const showPublishButton = hasPublishPermission && documents.some(({ status }) => status !== "published");
|
3333
|
+
const setListViewSelectedDocuments = strapiAdmin.useTable("publishAction", (state) => state.selectRow);
|
3334
|
+
const refetchList = () => {
|
3335
|
+
contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
|
3336
|
+
};
|
3337
|
+
if (!showPublishButton)
|
3338
|
+
return null;
|
3339
|
+
return {
|
3340
|
+
actionType: "publish",
|
3341
|
+
variant: "tertiary",
|
3342
|
+
label: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" }),
|
3343
|
+
dialog: {
|
3344
|
+
type: "modal",
|
3345
|
+
title: formatMessage({
|
3346
|
+
id: getTranslation("containers.ListPage.selectedEntriesModal.title"),
|
3347
|
+
defaultMessage: "Publish entries"
|
3348
|
+
}),
|
3349
|
+
content: ({ onClose }) => {
|
3350
|
+
return /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Root, { rows: documents, defaultSelectedRows: documents, headers: TABLE_HEADERS, children: /* @__PURE__ */ jsxRuntime.jsx(
|
3351
|
+
SelectedEntriesModalContent,
|
3352
|
+
{
|
3353
|
+
listViewSelectedEntries: documents,
|
3354
|
+
toggleModal: () => {
|
3355
|
+
onClose();
|
3356
|
+
refetchList();
|
3357
|
+
},
|
3358
|
+
setListViewSelectedDocuments,
|
3359
|
+
model
|
3360
|
+
}
|
3361
|
+
) });
|
3362
|
+
},
|
3363
|
+
onClose: () => {
|
3364
|
+
refetchList();
|
3365
|
+
}
|
3366
|
+
}
|
3367
|
+
};
|
3368
|
+
};
|
3369
|
+
const BulkActionsRenderer = () => {
|
3370
|
+
const plugins = strapiAdmin.useStrapiApp("BulkActionsRenderer", (state) => state.plugins);
|
3371
|
+
const { model, collectionType } = useDoc();
|
3372
|
+
const { selectedRows } = strapiAdmin.useTable("BulkActionsRenderer", (state) => state);
|
3373
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
|
3374
|
+
strapiAdmin.DescriptionComponentRenderer,
|
3375
|
+
{
|
3376
|
+
props: {
|
3377
|
+
model,
|
3378
|
+
collectionType,
|
3379
|
+
documents: selectedRows
|
3380
|
+
},
|
3381
|
+
descriptions: plugins["content-manager"].apis.getBulkActions(),
|
3382
|
+
children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActionButton, { ...action }, action.id))
|
3383
|
+
}
|
3384
|
+
) });
|
3385
|
+
};
|
3386
|
+
const DeleteAction = ({ documents, model }) => {
|
3387
|
+
const { formatMessage } = reactIntl.useIntl();
|
3388
|
+
const { schema: contentType } = useDoc();
|
3389
|
+
const selectRow = strapiAdmin.useTable("DeleteAction", (state) => state.selectRow);
|
3390
|
+
const hasI18nEnabled = Boolean(contentType?.pluginOptions?.i18n);
|
3391
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3392
|
+
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
3393
|
+
const hasDeletePermission = useDocumentRBAC("deleteAction", (state) => state.canDelete);
|
3394
|
+
const { deleteMany: bulkDeleteAction } = useDocumentActions();
|
3395
|
+
const documentIds = documents.map(({ documentId }) => documentId);
|
3396
|
+
const handleConfirmBulkDelete = async () => {
|
3397
|
+
const res = await bulkDeleteAction({
|
3398
|
+
documentIds,
|
3399
|
+
model,
|
3400
|
+
params
|
3401
|
+
});
|
3402
|
+
if (!("error" in res)) {
|
3403
|
+
selectRow([]);
|
3404
|
+
}
|
3405
|
+
};
|
3406
|
+
if (!hasDeletePermission)
|
3407
|
+
return null;
|
3408
|
+
return {
|
3409
|
+
variant: "danger-light",
|
3410
|
+
label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
|
3411
|
+
dialog: {
|
3412
|
+
type: "dialog",
|
3413
|
+
title: formatMessage({
|
3414
|
+
id: "app.components.ConfirmDialog.title",
|
3415
|
+
defaultMessage: "Confirmation"
|
3416
|
+
}),
|
3417
|
+
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3418
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3419
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
|
3420
|
+
id: "popUpWarning.bodyMessage.contentType.delete.all",
|
3421
|
+
defaultMessage: "Are you sure you want to delete these entries?"
|
3422
|
+
}) }),
|
3423
|
+
hasI18nEnabled && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", children: formatMessage(
|
3424
|
+
{
|
3425
|
+
id: getTranslation("Settings.list.actions.deleteAdditionalInfos"),
|
3426
|
+
defaultMessage: "This will delete the active locale versions <em>(from Internationalization)</em>"
|
3427
|
+
},
|
3428
|
+
{
|
3429
|
+
em: Emphasis
|
3430
|
+
}
|
3431
|
+
) }) })
|
3432
|
+
] }),
|
3433
|
+
onConfirm: handleConfirmBulkDelete
|
3434
|
+
}
|
3435
|
+
};
|
3436
|
+
};
|
3437
|
+
DeleteAction.type = "delete";
|
3438
|
+
const UnpublishAction = ({ documents, model }) => {
|
3439
|
+
const { formatMessage } = reactIntl.useIntl();
|
3440
|
+
const { schema } = useDoc();
|
3441
|
+
const selectRow = strapiAdmin.useTable("UnpublishAction", (state) => state.selectRow);
|
3442
|
+
const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
|
3443
|
+
const hasI18nEnabled = Boolean(schema?.pluginOptions?.i18n);
|
3444
|
+
const hasDraftAndPublishEnabled = Boolean(schema?.options?.draftAndPublish);
|
3445
|
+
const { unpublishMany: bulkUnpublishAction } = useDocumentActions();
|
3446
|
+
const documentIds = documents.map(({ documentId }) => documentId);
|
3447
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3448
|
+
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
3449
|
+
const handleConfirmBulkUnpublish = async () => {
|
3450
|
+
const data = await bulkUnpublishAction({ documentIds, model, params });
|
3451
|
+
if (!("error" in data)) {
|
3452
|
+
selectRow([]);
|
3453
|
+
}
|
3454
|
+
};
|
3455
|
+
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
|
3456
|
+
if (!showUnpublishButton)
|
3457
|
+
return null;
|
3458
|
+
return {
|
3459
|
+
variant: "tertiary",
|
3460
|
+
label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
|
3461
|
+
dialog: {
|
3462
|
+
type: "dialog",
|
3463
|
+
title: formatMessage({
|
3464
|
+
id: "app.components.ConfirmDialog.title",
|
3465
|
+
defaultMessage: "Confirmation"
|
3466
|
+
}),
|
3467
|
+
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3468
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3469
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
|
3470
|
+
id: "popUpWarning.bodyMessage.contentType.unpublish.all",
|
3471
|
+
defaultMessage: "Are you sure you want to unpublish these entries?"
|
3472
|
+
}) }),
|
3473
|
+
hasI18nEnabled && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", children: formatMessage(
|
3474
|
+
{
|
3475
|
+
id: getTranslation("Settings.list.actions.unpublishAdditionalInfos"),
|
3476
|
+
defaultMessage: "This will unpublish the active locale versions <em>(from Internationalization)</em>"
|
3477
|
+
},
|
3478
|
+
{
|
3479
|
+
em: Emphasis
|
3480
|
+
}
|
3481
|
+
) }) })
|
3482
|
+
] }),
|
3483
|
+
confirmButton: formatMessage({
|
3484
|
+
id: "app.utils.unpublish",
|
3485
|
+
defaultMessage: "Unpublish"
|
3486
|
+
}),
|
3487
|
+
onConfirm: handleConfirmBulkUnpublish
|
3488
|
+
}
|
3489
|
+
};
|
3490
|
+
};
|
3491
|
+
UnpublishAction.type = "unpublish";
|
3492
|
+
const Emphasis = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", textColor: "danger500", children: chunks });
|
3493
|
+
const DEFAULT_BULK_ACTIONS = [PublishAction, UnpublishAction, DeleteAction];
|
3494
|
+
const AutoCloneFailureModalBody = ({ prohibitedFields }) => {
|
3495
|
+
const { formatMessage } = reactIntl.useIntl();
|
3496
|
+
const getDefaultErrorMessage = (reason) => {
|
3497
|
+
switch (reason) {
|
3498
|
+
case "relation":
|
3499
|
+
return "Duplicating the relation could remove it from the original entry.";
|
3500
|
+
case "unique":
|
3501
|
+
return "Identical values in a unique field are not allowed";
|
3502
|
+
default:
|
3503
|
+
return reason;
|
3504
|
+
}
|
3505
|
+
};
|
3506
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
3507
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", children: formatMessage({
|
3508
|
+
id: getTranslation("containers.list.autoCloneModal.title"),
|
3509
|
+
defaultMessage: "This entry can't be duplicated directly."
|
3510
|
+
}) }),
|
3511
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", children: formatMessage({
|
3512
|
+
id: getTranslation("containers.list.autoCloneModal.description"),
|
3513
|
+
defaultMessage: "A new entry will be created with the same content, but you'll have to change the following fields to save it."
|
3514
|
+
}) }) }),
|
3515
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { marginTop: 6, gap: 2, direction: "column", alignItems: "stretch", children: prohibitedFields.map(([fieldPath, reason]) => /* @__PURE__ */ jsxRuntime.jsxs(
|
3516
|
+
designSystem.Flex,
|
3517
|
+
{
|
3518
|
+
direction: "column",
|
3519
|
+
gap: 2,
|
3520
|
+
alignItems: "flex-start",
|
3521
|
+
borderColor: "neutral200",
|
3522
|
+
hasRadius: true,
|
3523
|
+
padding: 6,
|
3524
|
+
children: [
|
3525
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "row", tag: "ol", children: fieldPath.map((pathSegment, index2) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { fontWeight: "semiBold", tag: "li", children: [
|
3526
|
+
pathSegment,
|
3527
|
+
index2 !== fieldPath.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(
|
3528
|
+
Icons.ChevronRight,
|
3529
|
+
{
|
3530
|
+
fill: "neutral500",
|
3531
|
+
height: "0.8rem",
|
3532
|
+
width: "0.8rem",
|
3533
|
+
style: { margin: "0 0.8rem" }
|
3534
|
+
}
|
3535
|
+
)
|
3536
|
+
] }, index2)) }),
|
3537
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", textColor: "neutral600", children: formatMessage({
|
3538
|
+
id: getTranslation(`containers.list.autoCloneModal.error.${reason}`),
|
3539
|
+
defaultMessage: getDefaultErrorMessage(reason)
|
3540
|
+
}) })
|
3541
|
+
]
|
3542
|
+
},
|
3543
|
+
fieldPath.join()
|
3544
|
+
)) })
|
3545
|
+
] });
|
3546
|
+
};
|
3547
|
+
const TableActions = ({ document }) => {
|
3548
|
+
const { formatMessage } = reactIntl.useIntl();
|
2522
3549
|
const { model, collectionType } = useDoc();
|
2523
3550
|
const plugins = strapiAdmin.useStrapiApp("TableActions", (state) => state.plugins);
|
2524
3551
|
const props = {
|
@@ -2591,7 +3618,7 @@ const EditAction = ({ documentId }) => {
|
|
2591
3618
|
};
|
2592
3619
|
};
|
2593
3620
|
EditAction.type = "edit";
|
2594
|
-
const StyledPencil =
|
3621
|
+
const StyledPencil = styledComponents.styled(Icons.Pencil)`
|
2595
3622
|
path {
|
2596
3623
|
fill: currentColor;
|
2597
3624
|
}
|
@@ -2651,7 +3678,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
2651
3678
|
/* @__PURE__ */ jsxRuntime.jsx(
|
2652
3679
|
designSystem.LinkButton,
|
2653
3680
|
{
|
2654
|
-
|
3681
|
+
tag: reactRouterDom.NavLink,
|
2655
3682
|
to: {
|
2656
3683
|
pathname: `clone/${documentId}`
|
2657
3684
|
},
|
@@ -2667,7 +3694,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
2667
3694
|
};
|
2668
3695
|
};
|
2669
3696
|
CloneAction.type = "clone";
|
2670
|
-
const StyledDuplicate =
|
3697
|
+
const StyledDuplicate = styledComponents.styled(Icons.Duplicate)`
|
2671
3698
|
path {
|
2672
3699
|
fill: currentColor;
|
2673
3700
|
}
|
@@ -2684,442 +3711,183 @@ class ContentManagerPlugin {
|
|
2684
3711
|
documentActions = [
|
2685
3712
|
...DEFAULT_ACTIONS,
|
2686
3713
|
...DEFAULT_TABLE_ROW_ACTIONS,
|
2687
|
-
...DEFAULT_HEADER_ACTIONS
|
2688
|
-
HistoryAction
|
3714
|
+
...DEFAULT_HEADER_ACTIONS
|
2689
3715
|
];
|
2690
3716
|
editViewSidePanels = [ActionsPanel];
|
2691
3717
|
headerActions = [];
|
2692
3718
|
constructor() {
|
2693
3719
|
}
|
2694
|
-
addEditViewSidePanel(panels) {
|
2695
|
-
if (Array.isArray(panels)) {
|
2696
|
-
this.editViewSidePanels = [...this.editViewSidePanels, ...panels];
|
2697
|
-
} else if (typeof panels === "function") {
|
2698
|
-
this.editViewSidePanels = panels(this.editViewSidePanels);
|
2699
|
-
} else {
|
2700
|
-
throw new Error(
|
2701
|
-
`Expected the \`panels\` passed to \`addEditViewSidePanel\` to be an array or a function, but received ${getPrintableType(
|
2702
|
-
panels
|
2703
|
-
)}`
|
2704
|
-
);
|
2705
|
-
}
|
2706
|
-
}
|
2707
|
-
addDocumentAction(actions2) {
|
2708
|
-
if (Array.isArray(actions2)) {
|
2709
|
-
this.documentActions = [...this.documentActions, ...actions2];
|
2710
|
-
} else if (typeof actions2 === "function") {
|
2711
|
-
this.documentActions = actions2(this.documentActions);
|
2712
|
-
} else {
|
2713
|
-
throw new Error(
|
2714
|
-
`Expected the \`actions\` passed to \`addDocumentAction\` to be an array or a function, but received ${getPrintableType(
|
2715
|
-
actions2
|
2716
|
-
)}`
|
2717
|
-
);
|
2718
|
-
}
|
2719
|
-
}
|
2720
|
-
addDocumentHeaderAction(actions2) {
|
2721
|
-
if (Array.isArray(actions2)) {
|
2722
|
-
this.headerActions = [...this.headerActions, ...actions2];
|
2723
|
-
} else if (typeof actions2 === "function") {
|
2724
|
-
this.headerActions = actions2(this.headerActions);
|
3720
|
+
addEditViewSidePanel(panels) {
|
3721
|
+
if (Array.isArray(panels)) {
|
3722
|
+
this.editViewSidePanels = [...this.editViewSidePanels, ...panels];
|
3723
|
+
} else if (typeof panels === "function") {
|
3724
|
+
this.editViewSidePanels = panels(this.editViewSidePanels);
|
2725
3725
|
} else {
|
2726
3726
|
throw new Error(
|
2727
|
-
`Expected the \`
|
2728
|
-
|
3727
|
+
`Expected the \`panels\` passed to \`addEditViewSidePanel\` to be an array or a function, but received ${getPrintableType(
|
3728
|
+
panels
|
2729
3729
|
)}`
|
2730
3730
|
);
|
2731
3731
|
}
|
2732
3732
|
}
|
2733
|
-
|
3733
|
+
addDocumentAction(actions2) {
|
2734
3734
|
if (Array.isArray(actions2)) {
|
2735
|
-
this.
|
3735
|
+
this.documentActions = [...this.documentActions, ...actions2];
|
2736
3736
|
} else if (typeof actions2 === "function") {
|
2737
|
-
this.
|
3737
|
+
this.documentActions = actions2(this.documentActions);
|
2738
3738
|
} else {
|
2739
3739
|
throw new Error(
|
2740
|
-
`Expected the \`actions\` passed to \`
|
3740
|
+
`Expected the \`actions\` passed to \`addDocumentAction\` to be an array or a function, but received ${getPrintableType(
|
2741
3741
|
actions2
|
2742
3742
|
)}`
|
2743
|
-
);
|
2744
|
-
}
|
2745
|
-
}
|
2746
|
-
|
2747
|
-
|
2748
|
-
|
2749
|
-
|
2750
|
-
|
2751
|
-
apis: {
|
2752
|
-
addBulkAction: this.addBulkAction.bind(this),
|
2753
|
-
addDocumentAction: this.addDocumentAction.bind(this),
|
2754
|
-
addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
|
2755
|
-
addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
|
2756
|
-
getBulkActions: () => this.bulkActions,
|
2757
|
-
getDocumentActions: () => this.documentActions,
|
2758
|
-
getEditViewSidePanels: () => this.editViewSidePanels,
|
2759
|
-
getHeaderActions: () => this.headerActions
|
2760
|
-
}
|
2761
|
-
};
|
2762
|
-
}
|
2763
|
-
}
|
2764
|
-
const getPrintableType = (value) => {
|
2765
|
-
const nativeType = typeof value;
|
2766
|
-
if (nativeType === "object") {
|
2767
|
-
if (value === null)
|
2768
|
-
return "null";
|
2769
|
-
if (Array.isArray(value))
|
2770
|
-
return "array";
|
2771
|
-
if (value instanceof Object && value.constructor.name !== "Object") {
|
2772
|
-
return value.constructor.name;
|
2773
|
-
}
|
2774
|
-
}
|
2775
|
-
return nativeType;
|
2776
|
-
};
|
2777
|
-
const initialState = {
|
2778
|
-
collectionTypeLinks: [],
|
2779
|
-
components: [],
|
2780
|
-
fieldSizes: {},
|
2781
|
-
models: [],
|
2782
|
-
singleTypeLinks: [],
|
2783
|
-
isLoading: true
|
2784
|
-
};
|
2785
|
-
const appSlice = toolkit.createSlice({
|
2786
|
-
name: "app",
|
2787
|
-
initialState,
|
2788
|
-
reducers: {
|
2789
|
-
setInitialData(state, action) {
|
2790
|
-
const {
|
2791
|
-
authorizedCollectionTypeLinks,
|
2792
|
-
authorizedSingleTypeLinks,
|
2793
|
-
components,
|
2794
|
-
contentTypeSchemas,
|
2795
|
-
fieldSizes
|
2796
|
-
} = action.payload;
|
2797
|
-
state.collectionTypeLinks = authorizedCollectionTypeLinks.filter(
|
2798
|
-
({ isDisplayed }) => isDisplayed
|
2799
|
-
);
|
2800
|
-
state.singleTypeLinks = authorizedSingleTypeLinks.filter(({ isDisplayed }) => isDisplayed);
|
2801
|
-
state.components = components;
|
2802
|
-
state.models = contentTypeSchemas;
|
2803
|
-
state.fieldSizes = fieldSizes;
|
2804
|
-
state.isLoading = false;
|
2805
|
-
}
|
2806
|
-
}
|
2807
|
-
});
|
2808
|
-
const { actions, reducer: reducer$1 } = appSlice;
|
2809
|
-
const { setInitialData } = actions;
|
2810
|
-
const reducer = toolkit.combineReducers({
|
2811
|
-
app: reducer$1
|
2812
|
-
});
|
2813
|
-
const HOOKS = {
|
2814
|
-
/**
|
2815
|
-
* Hook that allows to mutate the displayed headers of the list view table
|
2816
|
-
* @constant
|
2817
|
-
* @type {string}
|
2818
|
-
*/
|
2819
|
-
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2820
|
-
/**
|
2821
|
-
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2822
|
-
* @constant
|
2823
|
-
* @type {string}
|
2824
|
-
*/
|
2825
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2826
|
-
/**
|
2827
|
-
* Hook that allows to mutate the CM's edit view layout
|
2828
|
-
* @constant
|
2829
|
-
* @type {string}
|
2830
|
-
*/
|
2831
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2832
|
-
/**
|
2833
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
2834
|
-
* @constant
|
2835
|
-
* @type {string}
|
2836
|
-
*/
|
2837
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2838
|
-
};
|
2839
|
-
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2840
|
-
endpoints: (builder) => ({
|
2841
|
-
getContentTypeConfiguration: builder.query({
|
2842
|
-
query: (uid) => ({
|
2843
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2844
|
-
method: "GET"
|
2845
|
-
}),
|
2846
|
-
transformResponse: (response) => response.data,
|
2847
|
-
providesTags: (_result, _error, uid) => [
|
2848
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2849
|
-
{ type: "ContentTypeSettings", id: "LIST" }
|
2850
|
-
]
|
2851
|
-
}),
|
2852
|
-
getAllContentTypeSettings: builder.query({
|
2853
|
-
query: () => "/content-manager/content-types-settings",
|
2854
|
-
transformResponse: (response) => response.data,
|
2855
|
-
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2856
|
-
}),
|
2857
|
-
updateContentTypeConfiguration: builder.mutation({
|
2858
|
-
query: ({ uid, ...body }) => ({
|
2859
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2860
|
-
method: "PUT",
|
2861
|
-
data: body
|
2862
|
-
}),
|
2863
|
-
transformResponse: (response) => response.data,
|
2864
|
-
invalidatesTags: (_result, _error, { uid }) => [
|
2865
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2866
|
-
{ type: "ContentTypeSettings", id: "LIST" },
|
2867
|
-
// Is this necessary?
|
2868
|
-
{ type: "InitialData" }
|
2869
|
-
]
|
2870
|
-
})
|
2871
|
-
})
|
2872
|
-
});
|
2873
|
-
const {
|
2874
|
-
useGetContentTypeConfigurationQuery,
|
2875
|
-
useGetAllContentTypeSettingsQuery,
|
2876
|
-
useUpdateContentTypeConfigurationMutation
|
2877
|
-
} = contentTypesApi;
|
2878
|
-
const checkIfAttributeIsDisplayable = (attribute) => {
|
2879
|
-
const { type } = attribute;
|
2880
|
-
if (type === "relation") {
|
2881
|
-
return !attribute.relation.toLowerCase().includes("morph");
|
2882
|
-
}
|
2883
|
-
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2884
|
-
};
|
2885
|
-
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2886
|
-
if (!mainFieldName) {
|
2887
|
-
return void 0;
|
2888
|
-
}
|
2889
|
-
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2890
|
-
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2891
|
-
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2892
|
-
);
|
2893
|
-
return {
|
2894
|
-
name: mainFieldName,
|
2895
|
-
type: mainFieldType ?? "string"
|
2896
|
-
};
|
2897
|
-
};
|
2898
|
-
const DEFAULT_SETTINGS = {
|
2899
|
-
bulkable: false,
|
2900
|
-
filterable: false,
|
2901
|
-
searchable: false,
|
2902
|
-
pagination: false,
|
2903
|
-
defaultSortBy: "",
|
2904
|
-
defaultSortOrder: "asc",
|
2905
|
-
mainField: "id",
|
2906
|
-
pageSize: 10
|
2907
|
-
};
|
2908
|
-
const useDocumentLayout = (model) => {
|
2909
|
-
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2910
|
-
const [{ query }] = strapiAdmin.useQueryParams();
|
2911
|
-
const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2912
|
-
const { toggleNotification } = strapiAdmin.useNotification();
|
2913
|
-
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
2914
|
-
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2915
|
-
const {
|
2916
|
-
data,
|
2917
|
-
isLoading: isLoadingConfigs,
|
2918
|
-
error,
|
2919
|
-
isFetching: isFetchingConfigs
|
2920
|
-
} = useGetContentTypeConfigurationQuery(model);
|
2921
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2922
|
-
React__namespace.useEffect(() => {
|
2923
|
-
if (error) {
|
2924
|
-
toggleNotification({
|
2925
|
-
type: "danger",
|
2926
|
-
message: formatAPIError(error)
|
2927
|
-
});
|
2928
|
-
}
|
2929
|
-
}, [error, formatAPIError, toggleNotification]);
|
2930
|
-
const editLayout = React__namespace.useMemo(
|
2931
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2932
|
-
layout: [],
|
2933
|
-
components: {},
|
2934
|
-
metadatas: {},
|
2935
|
-
options: {},
|
2936
|
-
settings: DEFAULT_SETTINGS
|
2937
|
-
},
|
2938
|
-
[data, isLoading, schemas, schema, components]
|
2939
|
-
);
|
2940
|
-
const listLayout = React__namespace.useMemo(() => {
|
2941
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2942
|
-
layout: [],
|
2943
|
-
metadatas: {},
|
2944
|
-
options: {},
|
2945
|
-
settings: DEFAULT_SETTINGS
|
2946
|
-
};
|
2947
|
-
}, [data, isLoading, schemas, schema, components]);
|
2948
|
-
const { layout: edit } = React__namespace.useMemo(
|
2949
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2950
|
-
layout: editLayout,
|
2951
|
-
query
|
2952
|
-
}),
|
2953
|
-
[editLayout, query, runHookWaterfall]
|
2954
|
-
);
|
2955
|
-
return {
|
2956
|
-
error,
|
2957
|
-
isLoading,
|
2958
|
-
edit,
|
2959
|
-
list: listLayout
|
2960
|
-
};
|
2961
|
-
};
|
2962
|
-
const useDocLayout = () => {
|
2963
|
-
const { model } = useDoc();
|
2964
|
-
return useDocumentLayout(model);
|
2965
|
-
};
|
2966
|
-
const formatEditLayout = (data, {
|
2967
|
-
schemas,
|
2968
|
-
schema,
|
2969
|
-
components
|
2970
|
-
}) => {
|
2971
|
-
let currentPanelIndex = 0;
|
2972
|
-
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2973
|
-
data.contentType.layouts.edit,
|
2974
|
-
schema?.attributes,
|
2975
|
-
data.contentType.metadatas,
|
2976
|
-
{ configurations: data.components, schemas: components },
|
2977
|
-
schemas
|
2978
|
-
).reduce((panels, row) => {
|
2979
|
-
if (row.some((field) => field.type === "dynamiczone")) {
|
2980
|
-
panels.push([row]);
|
2981
|
-
currentPanelIndex += 2;
|
3743
|
+
);
|
3744
|
+
}
|
3745
|
+
}
|
3746
|
+
addDocumentHeaderAction(actions2) {
|
3747
|
+
if (Array.isArray(actions2)) {
|
3748
|
+
this.headerActions = [...this.headerActions, ...actions2];
|
3749
|
+
} else if (typeof actions2 === "function") {
|
3750
|
+
this.headerActions = actions2(this.headerActions);
|
2982
3751
|
} else {
|
2983
|
-
|
2984
|
-
|
2985
|
-
|
2986
|
-
|
3752
|
+
throw new Error(
|
3753
|
+
`Expected the \`actions\` passed to \`addDocumentHeaderAction\` to be an array or a function, but received ${getPrintableType(
|
3754
|
+
actions2
|
3755
|
+
)}`
|
3756
|
+
);
|
2987
3757
|
}
|
2988
|
-
|
2989
|
-
|
2990
|
-
|
2991
|
-
|
2992
|
-
|
2993
|
-
|
2994
|
-
|
2995
|
-
|
2996
|
-
|
2997
|
-
|
2998
|
-
|
2999
|
-
|
3000
|
-
icon: components[uid].info.icon,
|
3001
|
-
displayName: components[uid].info.displayName
|
3002
|
-
}
|
3003
|
-
};
|
3004
|
-
return acc;
|
3005
|
-
},
|
3006
|
-
{}
|
3007
|
-
);
|
3008
|
-
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
3009
|
-
(acc, [attribute, metadata]) => {
|
3010
|
-
return {
|
3011
|
-
...acc,
|
3012
|
-
[attribute]: metadata.edit
|
3013
|
-
};
|
3014
|
-
},
|
3015
|
-
{}
|
3016
|
-
);
|
3017
|
-
return {
|
3018
|
-
layout: panelledEditAttributes,
|
3019
|
-
components: componentEditAttributes,
|
3020
|
-
metadatas: editMetadatas,
|
3021
|
-
settings: {
|
3022
|
-
...data.contentType.settings,
|
3023
|
-
displayName: schema?.info.displayName
|
3024
|
-
},
|
3025
|
-
options: {
|
3026
|
-
...schema?.options,
|
3027
|
-
...schema?.pluginOptions,
|
3028
|
-
...data.contentType.options
|
3758
|
+
}
|
3759
|
+
addBulkAction(actions2) {
|
3760
|
+
if (Array.isArray(actions2)) {
|
3761
|
+
this.bulkActions = [...this.bulkActions, ...actions2];
|
3762
|
+
} else if (typeof actions2 === "function") {
|
3763
|
+
this.bulkActions = actions2(this.bulkActions);
|
3764
|
+
} else {
|
3765
|
+
throw new Error(
|
3766
|
+
`Expected the \`actions\` passed to \`addBulkAction\` to be an array or a function, but received ${getPrintableType(
|
3767
|
+
actions2
|
3768
|
+
)}`
|
3769
|
+
);
|
3029
3770
|
}
|
3030
|
-
}
|
3031
|
-
|
3032
|
-
|
3033
|
-
|
3034
|
-
|
3035
|
-
|
3036
|
-
|
3037
|
-
|
3771
|
+
}
|
3772
|
+
get config() {
|
3773
|
+
return {
|
3774
|
+
id: PLUGIN_ID,
|
3775
|
+
name: "Content Manager",
|
3776
|
+
injectionZones: INJECTION_ZONES,
|
3777
|
+
apis: {
|
3778
|
+
addBulkAction: this.addBulkAction.bind(this),
|
3779
|
+
addDocumentAction: this.addDocumentAction.bind(this),
|
3780
|
+
addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
|
3781
|
+
addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
|
3782
|
+
getBulkActions: () => this.bulkActions,
|
3783
|
+
getDocumentActions: () => this.documentActions,
|
3784
|
+
getEditViewSidePanels: () => this.editViewSidePanels,
|
3785
|
+
getHeaderActions: () => this.headerActions
|
3038
3786
|
}
|
3039
|
-
|
3040
|
-
|
3041
|
-
|
3042
|
-
|
3043
|
-
|
3044
|
-
|
3045
|
-
|
3046
|
-
|
3047
|
-
|
3048
|
-
|
3049
|
-
|
3050
|
-
|
3051
|
-
|
3052
|
-
|
3053
|
-
|
3054
|
-
size: field.size,
|
3055
|
-
unique: "unique" in attribute ? attribute.unique : false,
|
3056
|
-
visible: metadata.visible ?? true,
|
3057
|
-
type: attribute.type
|
3058
|
-
};
|
3059
|
-
}).filter((field) => field !== null)
|
3060
|
-
);
|
3787
|
+
};
|
3788
|
+
}
|
3789
|
+
}
|
3790
|
+
const getPrintableType = (value) => {
|
3791
|
+
const nativeType = typeof value;
|
3792
|
+
if (nativeType === "object") {
|
3793
|
+
if (value === null)
|
3794
|
+
return "null";
|
3795
|
+
if (Array.isArray(value))
|
3796
|
+
return "array";
|
3797
|
+
if (value instanceof Object && value.constructor.name !== "Object") {
|
3798
|
+
return value.constructor.name;
|
3799
|
+
}
|
3800
|
+
}
|
3801
|
+
return nativeType;
|
3061
3802
|
};
|
3062
|
-
const
|
3063
|
-
|
3064
|
-
|
3065
|
-
|
3066
|
-
}
|
3067
|
-
|
3068
|
-
|
3069
|
-
|
3070
|
-
...acc,
|
3071
|
-
[attribute]: metadata.list
|
3072
|
-
};
|
3073
|
-
},
|
3074
|
-
{}
|
3075
|
-
);
|
3076
|
-
const listAttributes = convertListLayoutToFieldLayouts(
|
3077
|
-
data.contentType.layouts.list,
|
3078
|
-
schema?.attributes,
|
3079
|
-
listMetadatas,
|
3080
|
-
{ configurations: data.components, schemas: components },
|
3081
|
-
schemas
|
3082
|
-
);
|
3803
|
+
const HistoryAction = ({ model, document }) => {
|
3804
|
+
const { formatMessage } = reactIntl.useIntl();
|
3805
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3806
|
+
const navigate = reactRouterDom.useNavigate();
|
3807
|
+
const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
|
3808
|
+
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3809
|
+
return null;
|
3810
|
+
}
|
3083
3811
|
return {
|
3084
|
-
|
3085
|
-
|
3086
|
-
|
3087
|
-
|
3088
|
-
|
3089
|
-
|
3090
|
-
|
3091
|
-
|
3812
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
|
3813
|
+
label: formatMessage({
|
3814
|
+
id: "content-manager.history.document-action",
|
3815
|
+
defaultMessage: "Content History"
|
3816
|
+
}),
|
3817
|
+
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
3818
|
+
disabled: (
|
3819
|
+
/**
|
3820
|
+
* The user is creating a new document.
|
3821
|
+
* It hasn't been saved yet, so there's no history to go to
|
3822
|
+
*/
|
3823
|
+
!document || /**
|
3824
|
+
* The document has been created but the current dimension has never been saved.
|
3825
|
+
* For example, the user is creating a new locale in an existing document,
|
3826
|
+
* so there's no history for the document in that locale
|
3827
|
+
*/
|
3828
|
+
!document.id || /**
|
3829
|
+
* History is only available for content types created by the user.
|
3830
|
+
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
3831
|
+
* which start with `admin::` or `plugin::`
|
3832
|
+
*/
|
3833
|
+
!model.startsWith("api::")
|
3834
|
+
),
|
3835
|
+
position: "header"
|
3092
3836
|
};
|
3093
3837
|
};
|
3094
|
-
|
3095
|
-
|
3096
|
-
|
3097
|
-
|
3098
|
-
|
3099
|
-
|
3100
|
-
|
3101
|
-
|
3102
|
-
|
3103
|
-
|
3104
|
-
|
3105
|
-
|
3106
|
-
|
3107
|
-
|
3108
|
-
|
3109
|
-
|
3110
|
-
|
3111
|
-
|
3112
|
-
};
|
3113
|
-
}).filter((field) => field !== null);
|
3838
|
+
HistoryAction.type = "history";
|
3839
|
+
const historyAdmin = {
|
3840
|
+
bootstrap(app) {
|
3841
|
+
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
3842
|
+
addDocumentAction((actions2) => {
|
3843
|
+
const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
|
3844
|
+
actions2.splice(indexOfDeleteAction, 0, HistoryAction);
|
3845
|
+
return actions2;
|
3846
|
+
});
|
3847
|
+
}
|
3848
|
+
};
|
3849
|
+
const initialState = {
|
3850
|
+
collectionTypeLinks: [],
|
3851
|
+
components: [],
|
3852
|
+
fieldSizes: {},
|
3853
|
+
models: [],
|
3854
|
+
singleTypeLinks: [],
|
3855
|
+
isLoading: true
|
3114
3856
|
};
|
3857
|
+
const appSlice = toolkit.createSlice({
|
3858
|
+
name: "app",
|
3859
|
+
initialState,
|
3860
|
+
reducers: {
|
3861
|
+
setInitialData(state, action) {
|
3862
|
+
const {
|
3863
|
+
authorizedCollectionTypeLinks,
|
3864
|
+
authorizedSingleTypeLinks,
|
3865
|
+
components,
|
3866
|
+
contentTypeSchemas,
|
3867
|
+
fieldSizes
|
3868
|
+
} = action.payload;
|
3869
|
+
state.collectionTypeLinks = authorizedCollectionTypeLinks.filter(
|
3870
|
+
({ isDisplayed }) => isDisplayed
|
3871
|
+
);
|
3872
|
+
state.singleTypeLinks = authorizedSingleTypeLinks.filter(({ isDisplayed }) => isDisplayed);
|
3873
|
+
state.components = components;
|
3874
|
+
state.models = contentTypeSchemas;
|
3875
|
+
state.fieldSizes = fieldSizes;
|
3876
|
+
state.isLoading = false;
|
3877
|
+
}
|
3878
|
+
}
|
3879
|
+
});
|
3880
|
+
const { actions, reducer: reducer$1 } = appSlice;
|
3881
|
+
const { setInitialData } = actions;
|
3882
|
+
const reducer = toolkit.combineReducers({
|
3883
|
+
app: reducer$1
|
3884
|
+
});
|
3115
3885
|
const index = {
|
3116
3886
|
register(app) {
|
3117
3887
|
const cm = new ContentManagerPlugin();
|
3118
3888
|
app.addReducers({
|
3119
|
-
[contentManagerApi.reducerPath]: contentManagerApi.reducer,
|
3120
3889
|
[PLUGIN_ID]: reducer
|
3121
3890
|
});
|
3122
|
-
app.addMiddlewares([() => contentManagerApi.middleware]);
|
3123
3891
|
app.addMenuLink({
|
3124
3892
|
to: PLUGIN_ID,
|
3125
3893
|
icon: Icons.Feather,
|
@@ -3128,14 +3896,29 @@ const index = {
|
|
3128
3896
|
defaultMessage: "Content Manager"
|
3129
3897
|
},
|
3130
3898
|
permissions: [],
|
3131
|
-
|
3899
|
+
position: 1
|
3900
|
+
});
|
3901
|
+
app.router.addRoute({
|
3902
|
+
path: "content-manager/*",
|
3903
|
+
lazy: async () => {
|
3904
|
+
const { Layout } = await Promise.resolve().then(() => require("./layout-C6dxWYT7.js"));
|
3905
|
+
return {
|
3906
|
+
Component: Layout
|
3907
|
+
};
|
3908
|
+
},
|
3909
|
+
children: routes
|
3132
3910
|
});
|
3133
3911
|
app.registerPlugin(cm.config);
|
3134
3912
|
},
|
3913
|
+
bootstrap(app) {
|
3914
|
+
if (typeof historyAdmin.bootstrap === "function") {
|
3915
|
+
historyAdmin.bootstrap(app);
|
3916
|
+
}
|
3917
|
+
},
|
3135
3918
|
async registerTrads({ locales }) {
|
3136
3919
|
const importedTrads = await Promise.all(
|
3137
3920
|
locales.map((locale) => {
|
3138
|
-
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-
|
3921
|
+
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-uOUIxfcQ.js")), "./translations/es.json": () => Promise.resolve().then(() => require("./es-EUonQTon.js")), "./translations/eu.json": () => Promise.resolve().then(() => require("./eu-VDH-3ovk.js")), "./translations/fr.json": () => Promise.resolve().then(() => require("./fr-B7kGGg3E.js")), "./translations/gu.json": () => Promise.resolve().then(() => require("./gu-BRmF601H.js")), "./translations/hi.json": () => Promise.resolve().then(() => require("./hi-CCJBptSq.js")), "./translations/hu.json": () => Promise.resolve().then(() => require("./hu-sNV_yLYy.js")), "./translations/id.json": () => Promise.resolve().then(() => require("./id-B5Ser98A.js")), "./translations/it.json": () => Promise.resolve().then(() => require("./it-DkBIs7vD.js")), "./translations/ja.json": () => Promise.resolve().then(() => require("./ja-CcFe8diO.js")), "./translations/ko.json": () => Promise.resolve().then(() => require("./ko-woFZPmLk.js")), "./translations/ml.json": () => Promise.resolve().then(() => require("./ml-C2W8N8k1.js")), "./translations/ms.json": () => Promise.resolve().then(() => require("./ms-BuFotyP_.js")), "./translations/nl.json": () => Promise.resolve().then(() => require("./nl-bbEOHChV.js")), "./translations/pl.json": () => Promise.resolve().then(() => require("./pl-uzwG-hk7.js")), "./translations/pt-BR.json": () => Promise.resolve().then(() => require("./pt-BR-BiOz37D9.js")), "./translations/pt.json": () => Promise.resolve().then(() => require("./pt-CeXQuq50.js")), "./translations/ru.json": () => Promise.resolve().then(() => require("./ru-BT3ybNny.js")), "./translations/sa.json": () => Promise.resolve().then(() => require("./sa-CcvkYInH.js")), "./translations/sk.json": () => Promise.resolve().then(() => require("./sk-CvY09Xjv.js")), "./translations/sv.json": () => Promise.resolve().then(() => require("./sv-MYDuzgvT.js")), "./translations/th.json": () => Promise.resolve().then(() => require("./th-D9_GfAjc.js")), "./translations/tr.json": () => Promise.resolve().then(() => require("./tr-D9UH-O_R.js")), "./translations/uk.json": () => Promise.resolve().then(() => require("./uk-C8EiqJY7.js")), "./translations/vi.json": () => Promise.resolve().then(() => require("./vi-CJlYDheJ.js")), "./translations/zh-Hans.json": () => Promise.resolve().then(() => require("./zh-Hans-9kOncHGw.js")), "./translations/zh.json": () => Promise.resolve().then(() => require("./zh-CQQfszqR.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
|
3139
3922
|
return {
|
3140
3923
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3141
3924
|
locale
|
@@ -3152,6 +3935,7 @@ const index = {
|
|
3152
3935
|
}
|
3153
3936
|
};
|
3154
3937
|
exports.ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD = ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD;
|
3938
|
+
exports.BulkActionsRenderer = BulkActionsRenderer;
|
3155
3939
|
exports.COLLECTION_TYPES = COLLECTION_TYPES;
|
3156
3940
|
exports.CREATOR_FIELDS = CREATOR_FIELDS;
|
3157
3941
|
exports.DEFAULT_SETTINGS = DEFAULT_SETTINGS;
|
@@ -3178,7 +3962,6 @@ exports.getDisplayName = getDisplayName;
|
|
3178
3962
|
exports.getMainField = getMainField;
|
3179
3963
|
exports.getTranslation = getTranslation;
|
3180
3964
|
exports.index = index;
|
3181
|
-
exports.routes = routes;
|
3182
3965
|
exports.setInitialData = setInitialData;
|
3183
3966
|
exports.useContentTypeSchema = useContentTypeSchema;
|
3184
3967
|
exports.useDoc = useDoc;
|
@@ -3192,4 +3975,4 @@ exports.useGetAllDocumentsQuery = useGetAllDocumentsQuery;
|
|
3192
3975
|
exports.useGetContentTypeConfigurationQuery = useGetContentTypeConfigurationQuery;
|
3193
3976
|
exports.useGetInitialDataQuery = useGetInitialDataQuery;
|
3194
3977
|
exports.useUpdateContentTypeConfigurationMutation = useUpdateContentTypeConfigurationMutation;
|
3195
|
-
//# sourceMappingURL=index-
|
3978
|
+
//# sourceMappingURL=index-CdT0kHZ8.js.map
|