@strapi/content-manager 0.0.0-experimental.a65a85fdea97faae8679d3ffc5f9d79af61abd26 → 0.0.0-experimental.a9a5a36dd73072c19eadeff5f387e8286b2a4d22
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-B1bIXVuX.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage--2aLCv-G.mjs.map → ComponentConfigurationPage-B1bIXVuX.mjs.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-43KmCNQE.js → ComponentConfigurationPage-Bqgx7Mes.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-43KmCNQE.js.map → ComponentConfigurationPage-Bqgx7Mes.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-BFEwvdMW.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-BfFzJ4Br.js.map → EditConfigurationPage-BFEwvdMW.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-CUcGHHvQ.mjs → EditConfigurationPage-ZO0vOO8q.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-CUcGHHvQ.mjs.map → EditConfigurationPage-ZO0vOO8q.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-CzOT5Kpj.js → EditViewPage-DA95Ha6J.js} +46 -48
- package/dist/_chunks/EditViewPage-DA95Ha6J.js.map +1 -0
- package/dist/_chunks/{EditViewPage-Bm8lgcm6.mjs → EditViewPage-DlLEyUL6.mjs} +47 -47
- package/dist/_chunks/EditViewPage-DlLEyUL6.mjs.map +1 -0
- package/dist/_chunks/{Field-Caef4JjM.js → Field-CnK8dO8N.js} +948 -777
- package/dist/_chunks/Field-CnK8dO8N.js.map +1 -0
- package/dist/_chunks/{Field-Dlh0uGnL.mjs → Field-Dq7bDnuh.mjs} +896 -724
- package/dist/_chunks/Field-Dq7bDnuh.mjs.map +1 -0
- package/dist/_chunks/{Form-EnaQL_6L.mjs → Form-B_JE0dbz.mjs} +43 -41
- package/dist/_chunks/Form-B_JE0dbz.mjs.map +1 -0
- package/dist/_chunks/{Form-BzuAjtRq.js → Form-BpiR4piS.js} +42 -41
- package/dist/_chunks/Form-BpiR4piS.js.map +1 -0
- package/dist/_chunks/{History-D6sbCJvo.mjs → History-CBNGU7a-.mjs} +149 -65
- package/dist/_chunks/History-CBNGU7a-.mjs.map +1 -0
- package/dist/_chunks/{History-C17LiyRg.js → History-DdIstl8b.js} +149 -66
- package/dist/_chunks/History-DdIstl8b.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-Ce4qs7qE.mjs → ListConfigurationPage-5dr4qpue.mjs} +58 -58
- package/dist/_chunks/ListConfigurationPage-5dr4qpue.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-Dks5SX6f.js → ListConfigurationPage-DkKRparB.js} +61 -62
- package/dist/_chunks/ListConfigurationPage-DkKRparB.js.map +1 -0
- package/dist/_chunks/{ListViewPage-Be7S5aKL.mjs → ListViewPage-DecLrYV6.mjs} +90 -106
- package/dist/_chunks/ListViewPage-DecLrYV6.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-BwrZrPsh.js → ListViewPage-wE0lXqoD.js} +95 -111
- package/dist/_chunks/ListViewPage-wE0lXqoD.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-CIPmYQMm.mjs → NoContentTypePage-CiIcfYsd.mjs} +7 -7
- package/dist/_chunks/NoContentTypePage-CiIcfYsd.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-Cu5r1-JT.js → NoContentTypePage-DEKR6tf9.js} +5 -5
- package/dist/_chunks/NoContentTypePage-DEKR6tf9.js.map +1 -0
- package/dist/_chunks/{NoPermissionsPage-DhJ7LYrr.mjs → NoPermissionsPage-CM5UD8ee.mjs} +5 -6
- package/dist/_chunks/NoPermissionsPage-CM5UD8ee.mjs.map +1 -0
- package/dist/_chunks/{NoPermissionsPage-C-j6TEUF.js → NoPermissionsPage-DmNfF2Bb.js} +4 -5
- package/dist/_chunks/NoPermissionsPage-DmNfF2Bb.js.map +1 -0
- package/dist/_chunks/{Relations-CY7AtkDA.mjs → Relations-Dqz0C1fz.mjs} +66 -56
- package/dist/_chunks/Relations-Dqz0C1fz.mjs.map +1 -0
- package/dist/_chunks/{Relations-Czs-uZ-s.js → Relations-L0xYRoSQ.js} +70 -61
- package/dist/_chunks/Relations-L0xYRoSQ.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-BSn97i8U.mjs} +1644 -911
- package/dist/_chunks/index-BSn97i8U.mjs.map +1 -0
- package/dist/_chunks/{index-X_2tafck.js → index-DyvUPg1a.js} +1622 -890
- package/dist/_chunks/index-DyvUPg1a.js.map +1 -0
- package/dist/_chunks/{layout-Dnh0PNp9.mjs → layout-DPaHUusj.mjs} +32 -27
- package/dist/_chunks/layout-DPaHUusj.mjs.map +1 -0
- package/dist/_chunks/{layout-dBc7wN7L.js → layout-TPqF2oJ5.js} +32 -29
- package/dist/_chunks/layout-TPqF2oJ5.js.map +1 -0
- package/dist/_chunks/{relations-4pHtBrHJ.js → relations-BWYS9gkn.js} +2 -2
- package/dist/_chunks/{relations-4pHtBrHJ.js.map → relations-BWYS9gkn.js.map} +1 -1
- package/dist/_chunks/{relations-Dx7tMKJN.mjs → relations-Ck7-ecDT.mjs} +2 -2
- package/dist/_chunks/{relations-Dx7tMKJN.mjs.map → relations-Ck7-ecDT.mjs.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/WysiwygStyles.d.ts +59 -52
- 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 +547 -416
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +555 -424
- 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/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 +9 -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 }) => ({
|
@@ -347,12 +237,15 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
347
237
|
]
|
348
238
|
}),
|
349
239
|
deleteManyDocuments: builder.mutation({
|
350
|
-
query: ({ model, ...body }) => ({
|
240
|
+
query: ({ model, params, ...body }) => ({
|
351
241
|
url: `/content-manager/collection-types/${model}/actions/bulkDelete`,
|
352
242
|
method: "POST",
|
353
|
-
data: body
|
243
|
+
data: body,
|
244
|
+
config: {
|
245
|
+
params
|
246
|
+
}
|
354
247
|
}),
|
355
|
-
invalidatesTags: (_res, _error, { model
|
248
|
+
invalidatesTags: (_res, _error, { model }) => [{ type: "Document", id: `${model}_LIST` }]
|
356
249
|
}),
|
357
250
|
discardDocument: builder.mutation({
|
358
251
|
query: ({ collectionType, model, documentId, params }) => ({
|
@@ -463,10 +356,13 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
463
356
|
}
|
464
357
|
}),
|
465
358
|
publishManyDocuments: builder.mutation({
|
466
|
-
query: ({ model, ...body }) => ({
|
359
|
+
query: ({ model, params, ...body }) => ({
|
467
360
|
url: `/content-manager/collection-types/${model}/actions/bulkPublish`,
|
468
361
|
method: "POST",
|
469
|
-
data: body
|
362
|
+
data: body,
|
363
|
+
config: {
|
364
|
+
params
|
365
|
+
}
|
470
366
|
}),
|
471
367
|
invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
|
472
368
|
}),
|
@@ -508,10 +404,13 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
508
404
|
}
|
509
405
|
}),
|
510
406
|
unpublishManyDocuments: builder.mutation({
|
511
|
-
query: ({ model, ...body }) => ({
|
407
|
+
query: ({ model, params, ...body }) => ({
|
512
408
|
url: `/content-manager/collection-types/${model}/actions/bulkUnpublish`,
|
513
409
|
method: "POST",
|
514
|
-
data: body
|
410
|
+
data: body,
|
411
|
+
config: {
|
412
|
+
params
|
413
|
+
}
|
515
414
|
}),
|
516
415
|
invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
|
517
416
|
})
|
@@ -535,6 +434,24 @@ const {
|
|
535
434
|
useUnpublishDocumentMutation,
|
536
435
|
useUnpublishManyDocumentsMutation
|
537
436
|
} = documentApi;
|
437
|
+
const buildValidParams = (query) => {
|
438
|
+
if (!query)
|
439
|
+
return query;
|
440
|
+
const { plugins: _, ...validQueryParams } = {
|
441
|
+
...query,
|
442
|
+
...Object.values(query?.plugins ?? {}).reduce(
|
443
|
+
(acc, current) => Object.assign(acc, current),
|
444
|
+
{}
|
445
|
+
)
|
446
|
+
};
|
447
|
+
if ("_q" in validQueryParams) {
|
448
|
+
validQueryParams._q = encodeURIComponent(validQueryParams._q);
|
449
|
+
}
|
450
|
+
return validQueryParams;
|
451
|
+
};
|
452
|
+
const isBaseQueryError = (error) => {
|
453
|
+
return error.name !== void 0;
|
454
|
+
};
|
538
455
|
const createYupSchema = (attributes = {}, components = {}) => {
|
539
456
|
const createModelSchema = (attributes2) => yup__namespace.object().shape(
|
540
457
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
@@ -574,10 +491,14 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
574
491
|
yup__namespace.array().of(
|
575
492
|
yup__namespace.lazy(
|
576
493
|
(data) => {
|
577
|
-
const
|
578
|
-
|
494
|
+
const attributes3 = components?.[data?.__component]?.attributes;
|
495
|
+
const validation = yup__namespace.object().shape({
|
579
496
|
__component: yup__namespace.string().required().oneOf(Object.keys(components))
|
580
|
-
}).nullable(false)
|
497
|
+
}).nullable(false);
|
498
|
+
if (!attributes3) {
|
499
|
+
return validation;
|
500
|
+
}
|
501
|
+
return validation.concat(createModelSchema(attributes3));
|
581
502
|
}
|
582
503
|
)
|
583
504
|
)
|
@@ -587,11 +508,25 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
587
508
|
return {
|
588
509
|
...acc,
|
589
510
|
[name]: transformSchema(
|
590
|
-
yup__namespace.
|
591
|
-
|
592
|
-
|
593
|
-
})
|
594
|
-
|
511
|
+
yup__namespace.lazy((value) => {
|
512
|
+
if (!value) {
|
513
|
+
return yup__namespace.mixed().nullable(true);
|
514
|
+
} else if (Array.isArray(value)) {
|
515
|
+
return yup__namespace.array().of(
|
516
|
+
yup__namespace.object().shape({
|
517
|
+
id: yup__namespace.string().required()
|
518
|
+
})
|
519
|
+
);
|
520
|
+
} else if (typeof value === "object") {
|
521
|
+
return yup__namespace.object();
|
522
|
+
} else {
|
523
|
+
return yup__namespace.mixed().test(
|
524
|
+
"type-error",
|
525
|
+
"Relation values must be either null, an array of objects with {id} or an object.",
|
526
|
+
() => false
|
527
|
+
);
|
528
|
+
}
|
529
|
+
})
|
595
530
|
)
|
596
531
|
};
|
597
532
|
default:
|
@@ -650,13 +585,18 @@ const createAttributeSchema = (attribute) => {
|
|
650
585
|
}
|
651
586
|
};
|
652
587
|
const addRequiredValidation = (attribute) => (schema) => {
|
653
|
-
if (attribute.required) {
|
654
|
-
return schema.required
|
655
|
-
id: strapiAdmin.translatedErrors.required.id,
|
656
|
-
defaultMessage: "This field is required."
|
657
|
-
});
|
588
|
+
if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
|
589
|
+
return schema.min(1, strapiAdmin.translatedErrors.required);
|
658
590
|
}
|
659
|
-
|
591
|
+
if (attribute.required && attribute.type !== "relation") {
|
592
|
+
return schema.required(strapiAdmin.translatedErrors.required);
|
593
|
+
}
|
594
|
+
return schema?.nullable ? schema.nullable() : (
|
595
|
+
// In some cases '.nullable' will not be available on the schema.
|
596
|
+
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
597
|
+
// In these cases we should just return the schema as it is.
|
598
|
+
schema
|
599
|
+
);
|
660
600
|
};
|
661
601
|
const addMinLengthValidation = (attribute) => (schema) => {
|
662
602
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
@@ -683,6 +623,28 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
683
623
|
const addMinValidation = (attribute) => (schema) => {
|
684
624
|
if ("min" in attribute) {
|
685
625
|
const min = toInteger(attribute.min);
|
626
|
+
if (attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") {
|
627
|
+
if (!attribute.required && "test" in schema && min) {
|
628
|
+
return schema.test(
|
629
|
+
"custom-min",
|
630
|
+
{
|
631
|
+
...strapiAdmin.translatedErrors.min,
|
632
|
+
values: {
|
633
|
+
min: attribute.min
|
634
|
+
}
|
635
|
+
},
|
636
|
+
(value) => {
|
637
|
+
if (!value) {
|
638
|
+
return true;
|
639
|
+
}
|
640
|
+
if (Array.isArray(value) && value.length === 0) {
|
641
|
+
return true;
|
642
|
+
}
|
643
|
+
return value.length >= min;
|
644
|
+
}
|
645
|
+
);
|
646
|
+
}
|
647
|
+
}
|
686
648
|
if ("min" in schema && min) {
|
687
649
|
return schema.min(min, {
|
688
650
|
...strapiAdmin.translatedErrors.min,
|
@@ -728,24 +690,6 @@ const addRegexValidation = (attribute) => (schema) => {
|
|
728
690
|
}
|
729
691
|
return schema;
|
730
692
|
};
|
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
693
|
const initApi = contentManagerApi.injectEndpoints({
|
750
694
|
endpoints: (builder) => ({
|
751
695
|
getInitialData: builder.query({
|
@@ -759,27 +703,20 @@ const { useGetInitialDataQuery } = initApi;
|
|
759
703
|
const useContentTypeSchema = (model) => {
|
760
704
|
const { toggleNotification } = strapiAdmin.useNotification();
|
761
705
|
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
|
-
});
|
706
|
+
const { data, error, isLoading, isFetching } = useGetInitialDataQuery(void 0);
|
707
|
+
const { components, contentType, contentTypes } = React__namespace.useMemo(() => {
|
708
|
+
const contentType2 = data?.contentTypes.find((ct) => ct.uid === model);
|
709
|
+
const componentsByKey = data?.components.reduce((acc, component) => {
|
710
|
+
acc[component.uid] = component;
|
711
|
+
return acc;
|
712
|
+
}, {});
|
713
|
+
const components2 = extractContentTypeComponents(contentType2?.attributes, componentsByKey);
|
714
|
+
return {
|
715
|
+
components: Object.keys(components2).length === 0 ? void 0 : components2,
|
716
|
+
contentType: contentType2,
|
717
|
+
contentTypes: data?.contentTypes ?? []
|
718
|
+
};
|
719
|
+
}, [model, data]);
|
783
720
|
React__namespace.useEffect(() => {
|
784
721
|
if (error) {
|
785
722
|
toggleNotification({
|
@@ -834,7 +771,10 @@ const useDocument = (args, opts) => {
|
|
834
771
|
isLoading: isLoadingDocument,
|
835
772
|
isFetching: isFetchingDocument,
|
836
773
|
error
|
837
|
-
} = useGetDocumentQuery(args,
|
774
|
+
} = useGetDocumentQuery(args, {
|
775
|
+
...opts,
|
776
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
777
|
+
});
|
838
778
|
const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
|
839
779
|
React__namespace.useEffect(() => {
|
840
780
|
if (error) {
|
@@ -862,7 +802,7 @@ const useDocument = (args, opts) => {
|
|
862
802
|
return null;
|
863
803
|
} catch (error2) {
|
864
804
|
if (error2 instanceof yup.ValidationError) {
|
865
|
-
return
|
805
|
+
return strapiAdmin.getYupValidationErrors(error2);
|
866
806
|
}
|
867
807
|
throw error2;
|
868
808
|
}
|
@@ -958,14 +898,53 @@ const useDocumentActions = () => {
|
|
958
898
|
},
|
959
899
|
[trackUsage, deleteDocument, toggleNotification, formatMessage, formatAPIError]
|
960
900
|
);
|
901
|
+
const [deleteManyDocuments] = useDeleteManyDocumentsMutation();
|
902
|
+
const deleteMany = React__namespace.useCallback(
|
903
|
+
async ({ model, documentIds, params }) => {
|
904
|
+
try {
|
905
|
+
trackUsage("willBulkDeleteEntries");
|
906
|
+
const res = await deleteManyDocuments({
|
907
|
+
model,
|
908
|
+
documentIds,
|
909
|
+
params
|
910
|
+
});
|
911
|
+
if ("error" in res) {
|
912
|
+
toggleNotification({
|
913
|
+
type: "danger",
|
914
|
+
message: formatAPIError(res.error)
|
915
|
+
});
|
916
|
+
return { error: res.error };
|
917
|
+
}
|
918
|
+
toggleNotification({
|
919
|
+
type: "success",
|
920
|
+
title: formatMessage({
|
921
|
+
id: getTranslation("success.records.delete"),
|
922
|
+
defaultMessage: "Successfully deleted."
|
923
|
+
}),
|
924
|
+
message: ""
|
925
|
+
});
|
926
|
+
trackUsage("didBulkDeleteEntries");
|
927
|
+
return res.data;
|
928
|
+
} catch (err) {
|
929
|
+
toggleNotification({
|
930
|
+
type: "danger",
|
931
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
932
|
+
});
|
933
|
+
trackUsage("didNotBulkDeleteEntries");
|
934
|
+
throw err;
|
935
|
+
}
|
936
|
+
},
|
937
|
+
[trackUsage, deleteManyDocuments, toggleNotification, formatMessage, formatAPIError]
|
938
|
+
);
|
961
939
|
const [discardDocument] = useDiscardDocumentMutation();
|
962
940
|
const discard = React__namespace.useCallback(
|
963
|
-
async ({ collectionType, model, documentId }) => {
|
941
|
+
async ({ collectionType, model, documentId, params }) => {
|
964
942
|
try {
|
965
943
|
const res = await discardDocument({
|
966
944
|
collectionType,
|
967
945
|
model,
|
968
|
-
documentId
|
946
|
+
documentId,
|
947
|
+
params
|
969
948
|
});
|
970
949
|
if ("error" in res) {
|
971
950
|
toggleNotification({
|
@@ -1027,6 +1006,43 @@ const useDocumentActions = () => {
|
|
1027
1006
|
},
|
1028
1007
|
[trackUsage, publishDocument, toggleNotification, formatMessage, formatAPIError]
|
1029
1008
|
);
|
1009
|
+
const [publishManyDocuments] = usePublishManyDocumentsMutation();
|
1010
|
+
const publishMany = React__namespace.useCallback(
|
1011
|
+
async ({ model, documentIds, params }) => {
|
1012
|
+
try {
|
1013
|
+
const res = await publishManyDocuments({
|
1014
|
+
model,
|
1015
|
+
documentIds,
|
1016
|
+
params
|
1017
|
+
});
|
1018
|
+
if ("error" in res) {
|
1019
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1020
|
+
return { error: res.error };
|
1021
|
+
}
|
1022
|
+
toggleNotification({
|
1023
|
+
type: "success",
|
1024
|
+
message: formatMessage({
|
1025
|
+
id: getTranslation("success.record.publish"),
|
1026
|
+
defaultMessage: "Published document"
|
1027
|
+
})
|
1028
|
+
});
|
1029
|
+
return res.data;
|
1030
|
+
} catch (err) {
|
1031
|
+
toggleNotification({
|
1032
|
+
type: "danger",
|
1033
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1034
|
+
});
|
1035
|
+
throw err;
|
1036
|
+
}
|
1037
|
+
},
|
1038
|
+
[
|
1039
|
+
// trackUsage,
|
1040
|
+
publishManyDocuments,
|
1041
|
+
toggleNotification,
|
1042
|
+
formatMessage,
|
1043
|
+
formatAPIError
|
1044
|
+
]
|
1045
|
+
);
|
1030
1046
|
const [updateDocument] = useUpdateDocumentMutation();
|
1031
1047
|
const update = React__namespace.useCallback(
|
1032
1048
|
async ({ collectionType, model, documentId, params }, data, trackerProperty) => {
|
@@ -1101,6 +1117,41 @@ const useDocumentActions = () => {
|
|
1101
1117
|
},
|
1102
1118
|
[trackUsage, unpublishDocument, toggleNotification, formatMessage, formatAPIError]
|
1103
1119
|
);
|
1120
|
+
const [unpublishManyDocuments] = useUnpublishManyDocumentsMutation();
|
1121
|
+
const unpublishMany = React__namespace.useCallback(
|
1122
|
+
async ({ model, documentIds, params }) => {
|
1123
|
+
try {
|
1124
|
+
trackUsage("willBulkUnpublishEntries");
|
1125
|
+
const res = await unpublishManyDocuments({
|
1126
|
+
model,
|
1127
|
+
documentIds,
|
1128
|
+
params
|
1129
|
+
});
|
1130
|
+
if ("error" in res) {
|
1131
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1132
|
+
return { error: res.error };
|
1133
|
+
}
|
1134
|
+
trackUsage("didBulkUnpublishEntries");
|
1135
|
+
toggleNotification({
|
1136
|
+
type: "success",
|
1137
|
+
title: formatMessage({
|
1138
|
+
id: getTranslation("success.records.unpublish"),
|
1139
|
+
defaultMessage: "Successfully unpublished."
|
1140
|
+
}),
|
1141
|
+
message: ""
|
1142
|
+
});
|
1143
|
+
return res.data;
|
1144
|
+
} catch (err) {
|
1145
|
+
toggleNotification({
|
1146
|
+
type: "danger",
|
1147
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1148
|
+
});
|
1149
|
+
trackUsage("didNotBulkUnpublishEntries");
|
1150
|
+
throw err;
|
1151
|
+
}
|
1152
|
+
},
|
1153
|
+
[trackUsage, unpublishManyDocuments, toggleNotification, formatMessage, formatAPIError]
|
1154
|
+
);
|
1104
1155
|
const [createDocument] = useCreateDocumentMutation();
|
1105
1156
|
const create = React__namespace.useCallback(
|
1106
1157
|
async ({ model, params }, data, trackerProperty) => {
|
@@ -1214,15 +1265,18 @@ const useDocumentActions = () => {
|
|
1214
1265
|
clone,
|
1215
1266
|
create,
|
1216
1267
|
delete: _delete,
|
1268
|
+
deleteMany,
|
1217
1269
|
discard,
|
1218
1270
|
getDocument,
|
1219
1271
|
publish,
|
1272
|
+
publishMany,
|
1220
1273
|
unpublish,
|
1274
|
+
unpublishMany,
|
1221
1275
|
update
|
1222
1276
|
};
|
1223
1277
|
};
|
1224
1278
|
const ProtectedHistoryPage = React.lazy(
|
1225
|
-
() => Promise.resolve().then(() => require("./History-
|
1279
|
+
() => Promise.resolve().then(() => require("./History-DdIstl8b.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1226
1280
|
);
|
1227
1281
|
const routes$1 = [
|
1228
1282
|
{
|
@@ -1235,31 +1289,31 @@ const routes$1 = [
|
|
1235
1289
|
}
|
1236
1290
|
];
|
1237
1291
|
const ProtectedEditViewPage = React.lazy(
|
1238
|
-
() => Promise.resolve().then(() => require("./EditViewPage-
|
1292
|
+
() => Promise.resolve().then(() => require("./EditViewPage-DA95Ha6J.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1239
1293
|
);
|
1240
1294
|
const ProtectedListViewPage = React.lazy(
|
1241
|
-
() => Promise.resolve().then(() => require("./ListViewPage-
|
1295
|
+
() => Promise.resolve().then(() => require("./ListViewPage-wE0lXqoD.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1242
1296
|
);
|
1243
1297
|
const ProtectedListConfiguration = React.lazy(
|
1244
|
-
() => Promise.resolve().then(() => require("./ListConfigurationPage-
|
1298
|
+
() => Promise.resolve().then(() => require("./ListConfigurationPage-DkKRparB.js")).then((mod) => ({
|
1245
1299
|
default: mod.ProtectedListConfiguration
|
1246
1300
|
}))
|
1247
1301
|
);
|
1248
1302
|
const ProtectedEditConfigurationPage = React.lazy(
|
1249
|
-
() => Promise.resolve().then(() => require("./EditConfigurationPage-
|
1303
|
+
() => Promise.resolve().then(() => require("./EditConfigurationPage-BFEwvdMW.js")).then((mod) => ({
|
1250
1304
|
default: mod.ProtectedEditConfigurationPage
|
1251
1305
|
}))
|
1252
1306
|
);
|
1253
1307
|
const ProtectedComponentConfigurationPage = React.lazy(
|
1254
|
-
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-
|
1308
|
+
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-Bqgx7Mes.js")).then((mod) => ({
|
1255
1309
|
default: mod.ProtectedComponentConfigurationPage
|
1256
1310
|
}))
|
1257
1311
|
);
|
1258
1312
|
const NoPermissions = React.lazy(
|
1259
|
-
() => Promise.resolve().then(() => require("./NoPermissionsPage-
|
1313
|
+
() => Promise.resolve().then(() => require("./NoPermissionsPage-DmNfF2Bb.js")).then((mod) => ({ default: mod.NoPermissions }))
|
1260
1314
|
);
|
1261
1315
|
const NoContentType = React.lazy(
|
1262
|
-
() => Promise.resolve().then(() => require("./NoContentTypePage-
|
1316
|
+
() => Promise.resolve().then(() => require("./NoContentTypePage-DEKR6tf9.js")).then((mod) => ({ default: mod.NoContentType }))
|
1263
1317
|
);
|
1264
1318
|
const CollectionTypePages = () => {
|
1265
1319
|
const { collectionType } = reactRouterDom.useParams();
|
@@ -1386,7 +1440,7 @@ const DocumentActionButton = (action) => {
|
|
1386
1440
|
DocumentActionConfirmDialog,
|
1387
1441
|
{
|
1388
1442
|
...action.dialog,
|
1389
|
-
variant: action.variant,
|
1443
|
+
variant: action.dialog?.variant ?? action.variant,
|
1390
1444
|
isOpen: dialogId === action.id,
|
1391
1445
|
onClose: handleClose
|
1392
1446
|
}
|
@@ -1449,7 +1503,7 @@ const DocumentActionsMenu = ({
|
|
1449
1503
|
variant,
|
1450
1504
|
children: [
|
1451
1505
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.More, { "aria-hidden": true, focusable: false }),
|
1452
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, {
|
1506
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { tag: "span", children: label || formatMessage({
|
1453
1507
|
id: "content-manager.containers.edit.panels.default.more-actions",
|
1454
1508
|
defaultMessage: "More document actions"
|
1455
1509
|
}) })
|
@@ -1465,8 +1519,8 @@ const DocumentActionsMenu = ({
|
|
1465
1519
|
onSelect: handleClick(action),
|
1466
1520
|
display: "block",
|
1467
1521
|
children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", gap: 4, children: [
|
1468
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { color: convertActionVariantToColor(action.variant), gap: 2,
|
1469
|
-
action.icon,
|
1522
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { color: convertActionVariantToColor(action.variant), gap: 2, tag: "span", children: [
|
1523
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { tag: "span", color: convertActionVariantToIconColor(action.variant), children: action.icon }),
|
1470
1524
|
action.label
|
1471
1525
|
] }),
|
1472
1526
|
action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsxRuntime.jsx(
|
@@ -1527,6 +1581,18 @@ const convertActionVariantToColor = (variant = "secondary") => {
|
|
1527
1581
|
return "primary600";
|
1528
1582
|
}
|
1529
1583
|
};
|
1584
|
+
const convertActionVariantToIconColor = (variant = "secondary") => {
|
1585
|
+
switch (variant) {
|
1586
|
+
case "danger":
|
1587
|
+
return "danger600";
|
1588
|
+
case "secondary":
|
1589
|
+
return "neutral500";
|
1590
|
+
case "success":
|
1591
|
+
return "success600";
|
1592
|
+
default:
|
1593
|
+
return "primary600";
|
1594
|
+
}
|
1595
|
+
};
|
1530
1596
|
const DocumentActionConfirmDialog = ({
|
1531
1597
|
onClose,
|
1532
1598
|
onCancel,
|
@@ -1549,61 +1615,42 @@ const DocumentActionConfirmDialog = ({
|
|
1549
1615
|
}
|
1550
1616
|
onClose();
|
1551
1617
|
};
|
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
|
-
] });
|
1618
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
1619
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
1620
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: content }),
|
1621
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
|
1622
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", children: formatMessage({
|
1623
|
+
id: "app.components.Button.cancel",
|
1624
|
+
defaultMessage: "Cancel"
|
1625
|
+
}) }) }),
|
1626
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, children: formatMessage({
|
1627
|
+
id: "app.components.Button.confirm",
|
1628
|
+
defaultMessage: "Confirm"
|
1629
|
+
}) })
|
1630
|
+
] })
|
1631
|
+
] }) });
|
1568
1632
|
};
|
1569
1633
|
const DocumentActionModal = ({
|
1570
1634
|
isOpen,
|
1571
1635
|
title,
|
1572
1636
|
onClose,
|
1573
1637
|
footer: Footer,
|
1574
|
-
content,
|
1638
|
+
content: Content,
|
1575
1639
|
onModalClose
|
1576
1640
|
}) => {
|
1577
|
-
const id = React__namespace.useId();
|
1578
|
-
if (!isOpen) {
|
1579
|
-
return null;
|
1580
|
-
}
|
1581
1641
|
const handleClose = () => {
|
1582
1642
|
if (onClose) {
|
1583
1643
|
onClose();
|
1584
1644
|
}
|
1585
1645
|
onModalClose();
|
1586
1646
|
};
|
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
|
-
] });
|
1647
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Content, { children: [
|
1648
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Title, { children: title }) }),
|
1649
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, { children: typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : Content }),
|
1650
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Footer, { children: typeof Footer === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Footer, { onClose: handleClose }) : Footer })
|
1651
|
+
] }) });
|
1605
1652
|
};
|
1606
|
-
const PublishAction = ({
|
1653
|
+
const PublishAction$1 = ({
|
1607
1654
|
activeTab,
|
1608
1655
|
documentId,
|
1609
1656
|
model,
|
@@ -1622,6 +1669,12 @@ const PublishAction = ({
|
|
1622
1669
|
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1623
1670
|
);
|
1624
1671
|
const { publish } = useDocumentActions();
|
1672
|
+
const [
|
1673
|
+
countDraftRelations,
|
1674
|
+
{ isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
|
1675
|
+
] = useLazyGetDraftRelationCountQuery();
|
1676
|
+
const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React__namespace.useState(0);
|
1677
|
+
const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React__namespace.useState(0);
|
1625
1678
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1626
1679
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
1627
1680
|
const modified = strapiAdmin.useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
@@ -1630,65 +1683,148 @@ const PublishAction = ({
|
|
1630
1683
|
const validate = strapiAdmin.useForm("PublishAction", (state) => state.validate);
|
1631
1684
|
const setErrors = strapiAdmin.useForm("PublishAction", (state) => state.setErrors);
|
1632
1685
|
const formValues = strapiAdmin.useForm("PublishAction", ({ values }) => values);
|
1633
|
-
|
1634
|
-
|
1635
|
-
|
1636
|
-
|
1637
|
-
|
1638
|
-
|
1639
|
-
|
1640
|
-
|
1641
|
-
|
1642
|
-
|
1643
|
-
|
1644
|
-
|
1645
|
-
|
1646
|
-
|
1647
|
-
|
1648
|
-
|
1649
|
-
|
1686
|
+
React__namespace.useEffect(() => {
|
1687
|
+
if (isErrorDraftRelations) {
|
1688
|
+
toggleNotification({
|
1689
|
+
type: "danger",
|
1690
|
+
message: formatMessage({
|
1691
|
+
id: getTranslation("error.records.fetch-draft-relatons"),
|
1692
|
+
defaultMessage: "An error occurred while fetching draft relations on this document."
|
1693
|
+
})
|
1694
|
+
});
|
1695
|
+
}
|
1696
|
+
}, [isErrorDraftRelations, toggleNotification, formatMessage]);
|
1697
|
+
React__namespace.useEffect(() => {
|
1698
|
+
const localDraftRelations = /* @__PURE__ */ new Set();
|
1699
|
+
const extractDraftRelations = (data) => {
|
1700
|
+
const relations = data.connect || [];
|
1701
|
+
relations.forEach((relation) => {
|
1702
|
+
if (relation.status === "draft") {
|
1703
|
+
localDraftRelations.add(relation.id);
|
1704
|
+
}
|
1705
|
+
});
|
1706
|
+
};
|
1707
|
+
const traverseAndExtract = (data) => {
|
1708
|
+
Object.entries(data).forEach(([key, value]) => {
|
1709
|
+
if (key === "connect" && Array.isArray(value)) {
|
1710
|
+
extractDraftRelations({ connect: value });
|
1711
|
+
} else if (typeof value === "object" && value !== null) {
|
1712
|
+
traverseAndExtract(value);
|
1713
|
+
}
|
1714
|
+
});
|
1715
|
+
};
|
1716
|
+
if (!documentId || modified) {
|
1717
|
+
traverseAndExtract(formValues);
|
1718
|
+
setLocalCountOfDraftRelations(localDraftRelations.size);
|
1719
|
+
}
|
1720
|
+
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
1721
|
+
React__namespace.useEffect(() => {
|
1722
|
+
if (documentId) {
|
1723
|
+
const fetchDraftRelationsCount = async () => {
|
1724
|
+
const { data, error } = await countDraftRelations({
|
1725
|
+
collectionType,
|
1726
|
+
model,
|
1727
|
+
documentId,
|
1728
|
+
params
|
1729
|
+
});
|
1730
|
+
if (error) {
|
1731
|
+
throw error;
|
1732
|
+
}
|
1733
|
+
if (data) {
|
1734
|
+
setServerCountOfDraftRelations(data.data);
|
1735
|
+
}
|
1736
|
+
};
|
1737
|
+
fetchDraftRelationsCount();
|
1738
|
+
}
|
1739
|
+
}, [documentId, countDraftRelations, collectionType, model, params]);
|
1740
|
+
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
1741
|
+
if (!schema?.options?.draftAndPublish) {
|
1742
|
+
return null;
|
1743
|
+
}
|
1744
|
+
const performPublish = async () => {
|
1745
|
+
setSubmitting(true);
|
1746
|
+
try {
|
1747
|
+
const { errors } = await validate();
|
1748
|
+
if (errors) {
|
1749
|
+
toggleNotification({
|
1750
|
+
type: "danger",
|
1751
|
+
message: formatMessage({
|
1752
|
+
id: "content-manager.validation.error",
|
1753
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
1754
|
+
})
|
1755
|
+
});
|
1756
|
+
return;
|
1757
|
+
}
|
1758
|
+
const res = await publish(
|
1759
|
+
{
|
1760
|
+
collectionType,
|
1761
|
+
model,
|
1762
|
+
documentId,
|
1763
|
+
params
|
1764
|
+
},
|
1765
|
+
formValues
|
1766
|
+
);
|
1767
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1768
|
+
navigate({
|
1769
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1770
|
+
search: rawQuery
|
1771
|
+
});
|
1772
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1773
|
+
setErrors(formatValidationErrors(res.error));
|
1774
|
+
}
|
1775
|
+
} finally {
|
1776
|
+
setSubmitting(false);
|
1777
|
+
}
|
1778
|
+
};
|
1779
|
+
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
1780
|
+
const hasDraftRelations = totalDraftRelations > 0;
|
1781
|
+
return {
|
1782
|
+
/**
|
1783
|
+
* Disabled when:
|
1784
|
+
* - currently if you're cloning a document we don't support publish & clone at the same time.
|
1785
|
+
* - the form is submitting
|
1786
|
+
* - the active tab is the published tab
|
1787
|
+
* - the document is already published & not modified
|
1788
|
+
* - the document is being created & not modified
|
1789
|
+
* - the user doesn't have the permission to publish
|
1790
|
+
* - the user doesn't have the permission to create a new document
|
1791
|
+
* - the user doesn't have the permission to update the document
|
1792
|
+
*/
|
1793
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish || Boolean(!document?.documentId && !canCreate || document?.documentId && !canUpdate),
|
1650
1794
|
label: formatMessage({
|
1651
1795
|
id: "app.utils.publish",
|
1652
1796
|
defaultMessage: "Publish"
|
1653
1797
|
}),
|
1654
1798
|
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));
|
1799
|
+
if (hasDraftRelations) {
|
1800
|
+
return;
|
1801
|
+
}
|
1802
|
+
await performPublish();
|
1803
|
+
},
|
1804
|
+
dialog: hasDraftRelations ? {
|
1805
|
+
type: "dialog",
|
1806
|
+
variant: "danger",
|
1807
|
+
footer: null,
|
1808
|
+
title: formatMessage({
|
1809
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
|
1810
|
+
defaultMessage: "Confirmation"
|
1811
|
+
}),
|
1812
|
+
content: formatMessage(
|
1813
|
+
{
|
1814
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
1815
|
+
defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
|
1816
|
+
},
|
1817
|
+
{
|
1818
|
+
count: totalDraftRelations
|
1684
1819
|
}
|
1685
|
-
|
1686
|
-
|
1820
|
+
),
|
1821
|
+
onConfirm: async () => {
|
1822
|
+
await performPublish();
|
1687
1823
|
}
|
1688
|
-
}
|
1824
|
+
} : void 0
|
1689
1825
|
};
|
1690
1826
|
};
|
1691
|
-
PublishAction.type = "publish";
|
1827
|
+
PublishAction$1.type = "publish";
|
1692
1828
|
const UpdateAction = ({
|
1693
1829
|
activeTab,
|
1694
1830
|
documentId,
|
@@ -1784,10 +1920,13 @@ const UpdateAction = ({
|
|
1784
1920
|
document
|
1785
1921
|
);
|
1786
1922
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1787
|
-
navigate(
|
1788
|
-
|
1789
|
-
|
1790
|
-
|
1923
|
+
navigate(
|
1924
|
+
{
|
1925
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1926
|
+
search: rawQuery
|
1927
|
+
},
|
1928
|
+
{ replace: true }
|
1929
|
+
);
|
1791
1930
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1792
1931
|
setErrors(formatValidationErrors(res.error));
|
1793
1932
|
}
|
@@ -1803,7 +1942,7 @@ const UNPUBLISH_DRAFT_OPTIONS = {
|
|
1803
1942
|
KEEP: "keep",
|
1804
1943
|
DISCARD: "discard"
|
1805
1944
|
};
|
1806
|
-
const UnpublishAction = ({
|
1945
|
+
const UnpublishAction$1 = ({
|
1807
1946
|
activeTab,
|
1808
1947
|
documentId,
|
1809
1948
|
model,
|
@@ -1819,10 +1958,8 @@ const UnpublishAction = ({
|
|
1819
1958
|
const { toggleNotification } = strapiAdmin.useNotification();
|
1820
1959
|
const [shouldKeepDraft, setShouldKeepDraft] = React__namespace.useState(true);
|
1821
1960
|
const isDocumentModified = document?.status === "modified";
|
1822
|
-
const handleChange = (
|
1823
|
-
|
1824
|
-
setShouldKeepDraft(e.target.value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1825
|
-
}
|
1961
|
+
const handleChange = (value) => {
|
1962
|
+
setShouldKeepDraft(value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1826
1963
|
};
|
1827
1964
|
if (!schema?.options?.draftAndPublish) {
|
1828
1965
|
return null;
|
@@ -1866,45 +2003,30 @@ const UnpublishAction = ({
|
|
1866
2003
|
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "flex-start", direction: "column", gap: 6, children: [
|
1867
2004
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", direction: "column", gap: 2, children: [
|
1868
2005
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
1869
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2006
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
1870
2007
|
id: "content-manager.actions.unpublish.dialog.body",
|
1871
2008
|
defaultMessage: "Are you sure?"
|
1872
2009
|
}) })
|
1873
2010
|
] }),
|
1874
2011
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
1875
|
-
designSystem.
|
2012
|
+
designSystem.Radio.Group,
|
1876
2013
|
{
|
1877
|
-
|
1878
|
-
|
1879
|
-
|
1880
|
-
|
1881
|
-
|
2014
|
+
defaultValue: UNPUBLISH_DRAFT_OPTIONS.KEEP,
|
2015
|
+
name: "discard-options",
|
2016
|
+
"aria-label": formatMessage({
|
2017
|
+
id: "content-manager.actions.unpublish.dialog.radio-label",
|
2018
|
+
defaultMessage: "Choose an option to unpublish the document."
|
2019
|
+
}),
|
2020
|
+
onValueChange: handleChange,
|
1882
2021
|
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
|
-
)
|
2022
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Radio.Item, { checked: shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.KEEP, children: formatMessage({
|
2023
|
+
id: "content-manager.actions.unpublish.dialog.option.keep-draft",
|
2024
|
+
defaultMessage: "Keep draft"
|
2025
|
+
}) }),
|
2026
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Radio.Item, { checked: !shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.DISCARD, children: formatMessage({
|
2027
|
+
id: "content-manager.actions.unpublish.dialog.option.replace-draft",
|
2028
|
+
defaultMessage: "Replace draft"
|
2029
|
+
}) })
|
1908
2030
|
]
|
1909
2031
|
}
|
1910
2032
|
)
|
@@ -1937,7 +2059,7 @@ const UnpublishAction = ({
|
|
1937
2059
|
position: ["panel", "table-row"]
|
1938
2060
|
};
|
1939
2061
|
};
|
1940
|
-
UnpublishAction.type = "unpublish";
|
2062
|
+
UnpublishAction$1.type = "unpublish";
|
1941
2063
|
const DiscardAction = ({
|
1942
2064
|
activeTab,
|
1943
2065
|
documentId,
|
@@ -1971,7 +2093,7 @@ const DiscardAction = ({
|
|
1971
2093
|
}),
|
1972
2094
|
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, children: [
|
1973
2095
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
1974
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2096
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
1975
2097
|
id: "content-manager.actions.discard.dialog.body",
|
1976
2098
|
defaultMessage: "Are you sure?"
|
1977
2099
|
}) })
|
@@ -1988,12 +2110,12 @@ const DiscardAction = ({
|
|
1988
2110
|
};
|
1989
2111
|
};
|
1990
2112
|
DiscardAction.type = "discard";
|
1991
|
-
const StyledCrossCircle =
|
2113
|
+
const StyledCrossCircle = styledComponents.styled(Icons.CrossCircle)`
|
1992
2114
|
path {
|
1993
2115
|
fill: currentColor;
|
1994
2116
|
}
|
1995
2117
|
`;
|
1996
|
-
const DEFAULT_ACTIONS = [PublishAction, UpdateAction, UnpublishAction, DiscardAction];
|
2118
|
+
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
1997
2119
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
1998
2120
|
const RelativeTime = React__namespace.forwardRef(
|
1999
2121
|
({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {
|
@@ -2041,7 +2163,7 @@ const getDisplayName = ({
|
|
2041
2163
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2042
2164
|
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2043
2165
|
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, {
|
2166
|
+
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
2167
|
};
|
2046
2168
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
2047
2169
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2050,23 +2172,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
|
2050
2172
|
id: "content-manager.containers.edit.title.new",
|
2051
2173
|
defaultMessage: "Create an entry"
|
2052
2174
|
}) : documentTitle;
|
2053
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop:
|
2175
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2054
2176
|
/* @__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
|
2177
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2178
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
|
2179
|
+
/* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
|
2180
|
+
] }),
|
2181
|
+
status ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 1, children: /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
|
2070
2182
|
] });
|
2071
2183
|
};
|
2072
2184
|
const HeaderToolbar = () => {
|
@@ -2218,7 +2330,7 @@ const Information = ({ activeTab }) => {
|
|
2218
2330
|
borderColor: "neutral150",
|
2219
2331
|
direction: "column",
|
2220
2332
|
marginTop: 2,
|
2221
|
-
|
2333
|
+
tag: "dl",
|
2222
2334
|
padding: 5,
|
2223
2335
|
gap: 3,
|
2224
2336
|
alignItems: "flex-start",
|
@@ -2226,8 +2338,8 @@ const Information = ({ activeTab }) => {
|
|
2226
2338
|
marginRight: "-0.4rem",
|
2227
2339
|
width: "calc(100% + 8px)",
|
2228
2340
|
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, {
|
2341
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "dt", variant: "pi", fontWeight: "bold", children: info.label }),
|
2342
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "dd", variant: "pi", textColor: "neutral600", children: info.value })
|
2231
2343
|
] }, info.label))
|
2232
2344
|
}
|
2233
2345
|
);
|
@@ -2260,7 +2372,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2260
2372
|
id: "app.links.configure-view",
|
2261
2373
|
defaultMessage: "Configure the view"
|
2262
2374
|
}),
|
2263
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2375
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ListPlus, {}),
|
2264
2376
|
onClick: () => {
|
2265
2377
|
navigate(`../${collectionType}/${model}/configurations/edit`);
|
2266
2378
|
},
|
@@ -2268,11 +2380,6 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2268
2380
|
};
|
2269
2381
|
};
|
2270
2382
|
ConfigureTheViewAction.type = "configure-the-view";
|
2271
|
-
const StyledCog = styled__default.default(Icons.Cog)`
|
2272
|
-
path {
|
2273
|
-
fill: currentColor;
|
2274
|
-
}
|
2275
|
-
`;
|
2276
2383
|
const EditTheModelAction = ({ model }) => {
|
2277
2384
|
const navigate = reactRouterDom.useNavigate();
|
2278
2385
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2281,7 +2388,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2281
2388
|
id: "content-manager.link-to-ctb",
|
2282
2389
|
defaultMessage: "Edit the model"
|
2283
2390
|
}),
|
2284
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2391
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, {}),
|
2285
2392
|
onClick: () => {
|
2286
2393
|
navigate(`/plugins/content-type-builder/content-types/${model}`);
|
2287
2394
|
},
|
@@ -2289,12 +2396,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2289
2396
|
};
|
2290
2397
|
};
|
2291
2398
|
EditTheModelAction.type = "edit-the-model";
|
2292
|
-
const
|
2293
|
-
path {
|
2294
|
-
fill: currentColor;
|
2295
|
-
}
|
2296
|
-
`;
|
2297
|
-
const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
2399
|
+
const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
2298
2400
|
const navigate = reactRouterDom.useNavigate();
|
2299
2401
|
const { formatMessage } = reactIntl.useIntl();
|
2300
2402
|
const listViewPathMatch = reactRouterDom.useMatch(LIST_PATH);
|
@@ -2308,7 +2410,7 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
|
2308
2410
|
id: "content-manager.actions.delete.label",
|
2309
2411
|
defaultMessage: "Delete document"
|
2310
2412
|
}),
|
2311
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2413
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {}),
|
2312
2414
|
dialog: {
|
2313
2415
|
type: "dialog",
|
2314
2416
|
title: formatMessage({
|
@@ -2317,7 +2419,7 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
|
2317
2419
|
}),
|
2318
2420
|
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, children: [
|
2319
2421
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
2320
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2422
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
2321
2423
|
id: "content-manager.actions.delete.dialog.body",
|
2322
2424
|
defaultMessage: "Are you sure?"
|
2323
2425
|
}) })
|
@@ -2362,13 +2464,8 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
|
2362
2464
|
position: ["header", "table-row"]
|
2363
2465
|
};
|
2364
2466
|
};
|
2365
|
-
DeleteAction.type = "delete";
|
2366
|
-
const
|
2367
|
-
path {
|
2368
|
-
fill: currentColor;
|
2369
|
-
}
|
2370
|
-
`;
|
2371
|
-
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction];
|
2467
|
+
DeleteAction$1.type = "delete";
|
2468
|
+
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2372
2469
|
const Panels = () => {
|
2373
2470
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2374
2471
|
const [
|
@@ -2442,7 +2539,7 @@ const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
|
2442
2539
|
designSystem.Flex,
|
2443
2540
|
{
|
2444
2541
|
ref,
|
2445
|
-
|
2542
|
+
tag: "aside",
|
2446
2543
|
"aria-labelledby": "additional-information",
|
2447
2544
|
background: "neutral0",
|
2448
2545
|
borderColor: "neutral150",
|
@@ -2457,117 +2554,996 @@ const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
|
2457
2554
|
justifyContent: "stretch",
|
2458
2555
|
alignItems: "flex-start",
|
2459
2556
|
children: [
|
2460
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2557
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2461
2558
|
children
|
2462
2559
|
]
|
2463
2560
|
}
|
2464
2561
|
);
|
2465
2562
|
});
|
2466
|
-
const
|
2467
|
-
|
2468
|
-
|
2469
|
-
|
2470
|
-
|
2471
|
-
|
2472
|
-
|
2473
|
-
|
2474
|
-
|
2475
|
-
|
2476
|
-
|
2477
|
-
|
2478
|
-
|
2479
|
-
|
2480
|
-
|
2481
|
-
|
2482
|
-
|
2483
|
-
|
2484
|
-
|
2485
|
-
|
2486
|
-
|
2487
|
-
|
2488
|
-
|
2489
|
-
|
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
|
-
};
|
2520
|
-
const TableActions = ({ document }) => {
|
2521
|
-
const { formatMessage } = reactIntl.useIntl();
|
2522
|
-
const { model, collectionType } = useDoc();
|
2523
|
-
const plugins = strapiAdmin.useStrapiApp("TableActions", (state) => state.plugins);
|
2524
|
-
const props = {
|
2525
|
-
activeTab: null,
|
2526
|
-
model,
|
2527
|
-
documentId: document.documentId,
|
2528
|
-
collectionType,
|
2529
|
-
document
|
2530
|
-
};
|
2531
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
2532
|
-
strapiAdmin.DescriptionComponentRenderer,
|
2533
|
-
{
|
2534
|
-
props,
|
2535
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2536
|
-
children: (actions2) => {
|
2537
|
-
const tableRowActions = actions2.filter((action) => {
|
2538
|
-
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
2539
|
-
return positions.includes("table-row");
|
2540
|
-
});
|
2541
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
2542
|
-
DocumentActionsMenu,
|
2543
|
-
{
|
2544
|
-
actions: tableRowActions,
|
2545
|
-
label: formatMessage({
|
2546
|
-
id: "content-manager.containers.list.table.row-actions",
|
2547
|
-
defaultMessage: "Row action"
|
2548
|
-
}),
|
2549
|
-
variant: "ghost"
|
2550
|
-
}
|
2551
|
-
);
|
2552
|
-
}
|
2553
|
-
}
|
2554
|
-
);
|
2563
|
+
const HOOKS = {
|
2564
|
+
/**
|
2565
|
+
* Hook that allows to mutate the displayed headers of the list view table
|
2566
|
+
* @constant
|
2567
|
+
* @type {string}
|
2568
|
+
*/
|
2569
|
+
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2570
|
+
/**
|
2571
|
+
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2572
|
+
* @constant
|
2573
|
+
* @type {string}
|
2574
|
+
*/
|
2575
|
+
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2576
|
+
/**
|
2577
|
+
* Hook that allows to mutate the CM's edit view layout
|
2578
|
+
* @constant
|
2579
|
+
* @type {string}
|
2580
|
+
*/
|
2581
|
+
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2582
|
+
/**
|
2583
|
+
* Hook that allows to mutate the CM's single types links pre-set filters
|
2584
|
+
* @constant
|
2585
|
+
* @type {string}
|
2586
|
+
*/
|
2587
|
+
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2555
2588
|
};
|
2556
|
-
const
|
2557
|
-
|
2558
|
-
|
2559
|
-
|
2560
|
-
|
2561
|
-
|
2562
|
-
|
2563
|
-
|
2564
|
-
|
2565
|
-
|
2566
|
-
|
2567
|
-
|
2568
|
-
}),
|
2569
|
-
|
2570
|
-
|
2589
|
+
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2590
|
+
endpoints: (builder) => ({
|
2591
|
+
getContentTypeConfiguration: builder.query({
|
2592
|
+
query: (uid) => ({
|
2593
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
2594
|
+
method: "GET"
|
2595
|
+
}),
|
2596
|
+
transformResponse: (response) => response.data,
|
2597
|
+
providesTags: (_result, _error, uid) => [
|
2598
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
2599
|
+
{ type: "ContentTypeSettings", id: "LIST" }
|
2600
|
+
]
|
2601
|
+
}),
|
2602
|
+
getAllContentTypeSettings: builder.query({
|
2603
|
+
query: () => "/content-manager/content-types-settings",
|
2604
|
+
transformResponse: (response) => response.data,
|
2605
|
+
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2606
|
+
}),
|
2607
|
+
updateContentTypeConfiguration: builder.mutation({
|
2608
|
+
query: ({ uid, ...body }) => ({
|
2609
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
2610
|
+
method: "PUT",
|
2611
|
+
data: body
|
2612
|
+
}),
|
2613
|
+
transformResponse: (response) => response.data,
|
2614
|
+
invalidatesTags: (_result, _error, { uid }) => [
|
2615
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
2616
|
+
{ type: "ContentTypeSettings", id: "LIST" },
|
2617
|
+
// Is this necessary?
|
2618
|
+
{ type: "InitialData" }
|
2619
|
+
]
|
2620
|
+
})
|
2621
|
+
})
|
2622
|
+
});
|
2623
|
+
const {
|
2624
|
+
useGetContentTypeConfigurationQuery,
|
2625
|
+
useGetAllContentTypeSettingsQuery,
|
2626
|
+
useUpdateContentTypeConfigurationMutation
|
2627
|
+
} = contentTypesApi;
|
2628
|
+
const checkIfAttributeIsDisplayable = (attribute) => {
|
2629
|
+
const { type } = attribute;
|
2630
|
+
if (type === "relation") {
|
2631
|
+
return !attribute.relation.toLowerCase().includes("morph");
|
2632
|
+
}
|
2633
|
+
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2634
|
+
};
|
2635
|
+
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2636
|
+
if (!mainFieldName) {
|
2637
|
+
return void 0;
|
2638
|
+
}
|
2639
|
+
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2640
|
+
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2641
|
+
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2642
|
+
);
|
2643
|
+
return {
|
2644
|
+
name: mainFieldName,
|
2645
|
+
type: mainFieldType ?? "string"
|
2646
|
+
};
|
2647
|
+
};
|
2648
|
+
const DEFAULT_SETTINGS = {
|
2649
|
+
bulkable: false,
|
2650
|
+
filterable: false,
|
2651
|
+
searchable: false,
|
2652
|
+
pagination: false,
|
2653
|
+
defaultSortBy: "",
|
2654
|
+
defaultSortOrder: "asc",
|
2655
|
+
mainField: "id",
|
2656
|
+
pageSize: 10
|
2657
|
+
};
|
2658
|
+
const useDocumentLayout = (model) => {
|
2659
|
+
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2660
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
2661
|
+
const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2662
|
+
const { toggleNotification } = strapiAdmin.useNotification();
|
2663
|
+
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
2664
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2665
|
+
const {
|
2666
|
+
data,
|
2667
|
+
isLoading: isLoadingConfigs,
|
2668
|
+
error,
|
2669
|
+
isFetching: isFetchingConfigs
|
2670
|
+
} = useGetContentTypeConfigurationQuery(model);
|
2671
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2672
|
+
React__namespace.useEffect(() => {
|
2673
|
+
if (error) {
|
2674
|
+
toggleNotification({
|
2675
|
+
type: "danger",
|
2676
|
+
message: formatAPIError(error)
|
2677
|
+
});
|
2678
|
+
}
|
2679
|
+
}, [error, formatAPIError, toggleNotification]);
|
2680
|
+
const editLayout = React__namespace.useMemo(
|
2681
|
+
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2682
|
+
layout: [],
|
2683
|
+
components: {},
|
2684
|
+
metadatas: {},
|
2685
|
+
options: {},
|
2686
|
+
settings: DEFAULT_SETTINGS
|
2687
|
+
},
|
2688
|
+
[data, isLoading, schemas, schema, components]
|
2689
|
+
);
|
2690
|
+
const listLayout = React__namespace.useMemo(() => {
|
2691
|
+
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2692
|
+
layout: [],
|
2693
|
+
metadatas: {},
|
2694
|
+
options: {},
|
2695
|
+
settings: DEFAULT_SETTINGS
|
2696
|
+
};
|
2697
|
+
}, [data, isLoading, schemas, schema, components]);
|
2698
|
+
const { layout: edit } = React__namespace.useMemo(
|
2699
|
+
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2700
|
+
layout: editLayout,
|
2701
|
+
query
|
2702
|
+
}),
|
2703
|
+
[editLayout, query, runHookWaterfall]
|
2704
|
+
);
|
2705
|
+
return {
|
2706
|
+
error,
|
2707
|
+
isLoading,
|
2708
|
+
edit,
|
2709
|
+
list: listLayout
|
2710
|
+
};
|
2711
|
+
};
|
2712
|
+
const useDocLayout = () => {
|
2713
|
+
const { model } = useDoc();
|
2714
|
+
return useDocumentLayout(model);
|
2715
|
+
};
|
2716
|
+
const formatEditLayout = (data, {
|
2717
|
+
schemas,
|
2718
|
+
schema,
|
2719
|
+
components
|
2720
|
+
}) => {
|
2721
|
+
let currentPanelIndex = 0;
|
2722
|
+
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2723
|
+
data.contentType.layouts.edit,
|
2724
|
+
schema?.attributes,
|
2725
|
+
data.contentType.metadatas,
|
2726
|
+
{ configurations: data.components, schemas: components },
|
2727
|
+
schemas
|
2728
|
+
).reduce((panels, row) => {
|
2729
|
+
if (row.some((field) => field.type === "dynamiczone")) {
|
2730
|
+
panels.push([row]);
|
2731
|
+
currentPanelIndex += 2;
|
2732
|
+
} else {
|
2733
|
+
if (!panels[currentPanelIndex]) {
|
2734
|
+
panels.push([]);
|
2735
|
+
}
|
2736
|
+
panels[currentPanelIndex].push(row);
|
2737
|
+
}
|
2738
|
+
return panels;
|
2739
|
+
}, []);
|
2740
|
+
const componentEditAttributes = Object.entries(data.components).reduce(
|
2741
|
+
(acc, [uid, configuration]) => {
|
2742
|
+
acc[uid] = {
|
2743
|
+
layout: convertEditLayoutToFieldLayouts(
|
2744
|
+
configuration.layouts.edit,
|
2745
|
+
components[uid].attributes,
|
2746
|
+
configuration.metadatas
|
2747
|
+
),
|
2748
|
+
settings: {
|
2749
|
+
...configuration.settings,
|
2750
|
+
icon: components[uid].info.icon,
|
2751
|
+
displayName: components[uid].info.displayName
|
2752
|
+
}
|
2753
|
+
};
|
2754
|
+
return acc;
|
2755
|
+
},
|
2756
|
+
{}
|
2757
|
+
);
|
2758
|
+
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2759
|
+
(acc, [attribute, metadata]) => {
|
2760
|
+
return {
|
2761
|
+
...acc,
|
2762
|
+
[attribute]: metadata.edit
|
2763
|
+
};
|
2764
|
+
},
|
2765
|
+
{}
|
2766
|
+
);
|
2767
|
+
return {
|
2768
|
+
layout: panelledEditAttributes,
|
2769
|
+
components: componentEditAttributes,
|
2770
|
+
metadatas: editMetadatas,
|
2771
|
+
settings: {
|
2772
|
+
...data.contentType.settings,
|
2773
|
+
displayName: schema?.info.displayName
|
2774
|
+
},
|
2775
|
+
options: {
|
2776
|
+
...schema?.options,
|
2777
|
+
...schema?.pluginOptions,
|
2778
|
+
...data.contentType.options
|
2779
|
+
}
|
2780
|
+
};
|
2781
|
+
};
|
2782
|
+
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
2783
|
+
return rows.map(
|
2784
|
+
(row) => row.map((field) => {
|
2785
|
+
const attribute = attributes[field.name];
|
2786
|
+
if (!attribute) {
|
2787
|
+
return null;
|
2788
|
+
}
|
2789
|
+
const { edit: metadata } = metadatas[field.name];
|
2790
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
2791
|
+
return {
|
2792
|
+
attribute,
|
2793
|
+
disabled: !metadata.editable,
|
2794
|
+
hint: metadata.description,
|
2795
|
+
label: metadata.label ?? "",
|
2796
|
+
name: field.name,
|
2797
|
+
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
2798
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
2799
|
+
schemas,
|
2800
|
+
components: components?.schemas ?? {}
|
2801
|
+
}),
|
2802
|
+
placeholder: metadata.placeholder ?? "",
|
2803
|
+
required: attribute.required ?? false,
|
2804
|
+
size: field.size,
|
2805
|
+
unique: "unique" in attribute ? attribute.unique : false,
|
2806
|
+
visible: metadata.visible ?? true,
|
2807
|
+
type: attribute.type
|
2808
|
+
};
|
2809
|
+
}).filter((field) => field !== null)
|
2810
|
+
);
|
2811
|
+
};
|
2812
|
+
const formatListLayout = (data, {
|
2813
|
+
schemas,
|
2814
|
+
schema,
|
2815
|
+
components
|
2816
|
+
}) => {
|
2817
|
+
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2818
|
+
(acc, [attribute, metadata]) => {
|
2819
|
+
return {
|
2820
|
+
...acc,
|
2821
|
+
[attribute]: metadata.list
|
2822
|
+
};
|
2823
|
+
},
|
2824
|
+
{}
|
2825
|
+
);
|
2826
|
+
const listAttributes = convertListLayoutToFieldLayouts(
|
2827
|
+
data.contentType.layouts.list,
|
2828
|
+
schema?.attributes,
|
2829
|
+
listMetadatas,
|
2830
|
+
{ configurations: data.components, schemas: components },
|
2831
|
+
schemas
|
2832
|
+
);
|
2833
|
+
return {
|
2834
|
+
layout: listAttributes,
|
2835
|
+
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
2836
|
+
metadatas: listMetadatas,
|
2837
|
+
options: {
|
2838
|
+
...schema?.options,
|
2839
|
+
...schema?.pluginOptions,
|
2840
|
+
...data.contentType.options
|
2841
|
+
}
|
2842
|
+
};
|
2843
|
+
};
|
2844
|
+
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
2845
|
+
return columns.map((name) => {
|
2846
|
+
const attribute = attributes[name];
|
2847
|
+
if (!attribute) {
|
2848
|
+
return null;
|
2849
|
+
}
|
2850
|
+
const metadata = metadatas[name];
|
2851
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
2852
|
+
return {
|
2853
|
+
attribute,
|
2854
|
+
label: metadata.label ?? "",
|
2855
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
2856
|
+
schemas,
|
2857
|
+
components: components?.schemas ?? {}
|
2858
|
+
}),
|
2859
|
+
name,
|
2860
|
+
searchable: metadata.searchable ?? true,
|
2861
|
+
sortable: metadata.sortable ?? true
|
2862
|
+
};
|
2863
|
+
}).filter((field) => field !== null);
|
2864
|
+
};
|
2865
|
+
const ConfirmBulkActionDialog = ({
|
2866
|
+
onToggleDialog,
|
2867
|
+
isOpen = false,
|
2868
|
+
dialogBody,
|
2869
|
+
endAction
|
2870
|
+
}) => {
|
2871
|
+
const { formatMessage } = reactIntl.useIntl();
|
2872
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
2873
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: formatMessage({
|
2874
|
+
id: "app.components.ConfirmDialog.title",
|
2875
|
+
defaultMessage: "Confirmation"
|
2876
|
+
}) }),
|
2877
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
2878
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
2879
|
+
dialogBody
|
2880
|
+
] }) }),
|
2881
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
|
2882
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { fullWidth: true, onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
|
2883
|
+
id: "app.components.Button.cancel",
|
2884
|
+
defaultMessage: "Cancel"
|
2885
|
+
}) }) }),
|
2886
|
+
endAction
|
2887
|
+
] })
|
2888
|
+
] }) });
|
2889
|
+
};
|
2890
|
+
const BoldChunk$1 = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
|
2891
|
+
const ConfirmDialogPublishAll = ({
|
2892
|
+
isOpen,
|
2893
|
+
onToggleDialog,
|
2894
|
+
isConfirmButtonLoading = false,
|
2895
|
+
onConfirm
|
2896
|
+
}) => {
|
2897
|
+
const { formatMessage } = reactIntl.useIntl();
|
2898
|
+
const selectedEntries = strapiAdmin.useTable("ConfirmDialogPublishAll", (state) => state.selectedRows);
|
2899
|
+
const { toggleNotification } = strapiAdmin.useNotification();
|
2900
|
+
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler(getTranslation);
|
2901
|
+
const { model, schema } = useDoc();
|
2902
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
2903
|
+
const {
|
2904
|
+
data: countDraftRelations = 0,
|
2905
|
+
isLoading,
|
2906
|
+
error
|
2907
|
+
} = useGetManyDraftRelationCountQuery(
|
2908
|
+
{
|
2909
|
+
model,
|
2910
|
+
documentIds: selectedEntries.map((entry) => entry.documentId),
|
2911
|
+
locale: query?.plugins?.i18n?.locale
|
2912
|
+
},
|
2913
|
+
{
|
2914
|
+
skip: selectedEntries.length === 0
|
2915
|
+
}
|
2916
|
+
);
|
2917
|
+
React__namespace.useEffect(() => {
|
2918
|
+
if (error) {
|
2919
|
+
toggleNotification({ type: "danger", message: formatAPIError(error) });
|
2920
|
+
}
|
2921
|
+
}, [error, formatAPIError, toggleNotification]);
|
2922
|
+
if (error) {
|
2923
|
+
return null;
|
2924
|
+
}
|
2925
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
2926
|
+
ConfirmBulkActionDialog,
|
2927
|
+
{
|
2928
|
+
isOpen: isOpen && !isLoading,
|
2929
|
+
onToggleDialog,
|
2930
|
+
dialogBody: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
2931
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: [
|
2932
|
+
countDraftRelations > 0 && formatMessage(
|
2933
|
+
{
|
2934
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
2935
|
+
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. "
|
2936
|
+
},
|
2937
|
+
{
|
2938
|
+
b: BoldChunk$1,
|
2939
|
+
count: countDraftRelations,
|
2940
|
+
entities: selectedEntries.length
|
2941
|
+
}
|
2942
|
+
),
|
2943
|
+
formatMessage({
|
2944
|
+
id: getTranslation("popUpWarning.bodyMessage.contentType.publish.all"),
|
2945
|
+
defaultMessage: "Are you sure you want to publish these entries?"
|
2946
|
+
})
|
2947
|
+
] }),
|
2948
|
+
schema?.pluginOptions && "i18n" in schema.pluginOptions && schema?.pluginOptions.i18n && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", textAlign: "center", children: formatMessage(
|
2949
|
+
{
|
2950
|
+
id: getTranslation("Settings.list.actions.publishAdditionalInfos"),
|
2951
|
+
defaultMessage: "This will publish the active locale versions <em>(from Internationalization)</em>"
|
2952
|
+
},
|
2953
|
+
{
|
2954
|
+
em: Emphasis
|
2955
|
+
}
|
2956
|
+
) })
|
2957
|
+
] }),
|
2958
|
+
endAction: /* @__PURE__ */ jsxRuntime.jsx(
|
2959
|
+
designSystem.Button,
|
2960
|
+
{
|
2961
|
+
onClick: onConfirm,
|
2962
|
+
variant: "secondary",
|
2963
|
+
startIcon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Check, {}),
|
2964
|
+
loading: isConfirmButtonLoading,
|
2965
|
+
children: formatMessage({
|
2966
|
+
id: "app.utils.publish",
|
2967
|
+
defaultMessage: "Publish"
|
2968
|
+
})
|
2969
|
+
}
|
2970
|
+
)
|
2971
|
+
}
|
2972
|
+
);
|
2973
|
+
};
|
2974
|
+
const TypographyMaxWidth = styledComponents.styled(designSystem.Typography)`
|
2975
|
+
max-width: 300px;
|
2976
|
+
`;
|
2977
|
+
const formatErrorMessages = (errors, parentKey, formatMessage) => {
|
2978
|
+
const messages = [];
|
2979
|
+
Object.entries(errors).forEach(([key, value]) => {
|
2980
|
+
const currentKey = parentKey ? `${parentKey}.${key}` : key;
|
2981
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
2982
|
+
if ("id" in value && "defaultMessage" in value) {
|
2983
|
+
messages.push(
|
2984
|
+
formatMessage(
|
2985
|
+
{
|
2986
|
+
id: `${value.id}.withField`,
|
2987
|
+
defaultMessage: value.defaultMessage
|
2988
|
+
},
|
2989
|
+
{ field: currentKey }
|
2990
|
+
)
|
2991
|
+
);
|
2992
|
+
} else {
|
2993
|
+
messages.push(
|
2994
|
+
...formatErrorMessages(
|
2995
|
+
// @ts-expect-error TODO: check why value is not compatible with FormErrors
|
2996
|
+
value,
|
2997
|
+
currentKey,
|
2998
|
+
formatMessage
|
2999
|
+
)
|
3000
|
+
);
|
3001
|
+
}
|
3002
|
+
} else {
|
3003
|
+
messages.push(
|
3004
|
+
formatMessage(
|
3005
|
+
{
|
3006
|
+
id: `${value}.withField`,
|
3007
|
+
defaultMessage: value
|
3008
|
+
},
|
3009
|
+
{ field: currentKey }
|
3010
|
+
)
|
3011
|
+
);
|
3012
|
+
}
|
3013
|
+
});
|
3014
|
+
return messages;
|
3015
|
+
};
|
3016
|
+
const EntryValidationText = ({ validationErrors, status }) => {
|
3017
|
+
const { formatMessage } = reactIntl.useIntl();
|
3018
|
+
if (validationErrors) {
|
3019
|
+
const validationErrorsMessages = formatErrorMessages(validationErrors, "", formatMessage).join(
|
3020
|
+
" "
|
3021
|
+
);
|
3022
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3023
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.CrossCircle, { fill: "danger600" }),
|
3024
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsxRuntime.jsx(TypographyMaxWidth, { textColor: "danger600", variant: "omega", fontWeight: "semiBold", ellipsis: true, children: validationErrorsMessages }) })
|
3025
|
+
] });
|
3026
|
+
}
|
3027
|
+
if (status === "published") {
|
3028
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3029
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.CheckCircle, { fill: "success600" }),
|
3030
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
|
3031
|
+
id: "content-manager.bulk-publish.already-published",
|
3032
|
+
defaultMessage: "Already Published"
|
3033
|
+
}) })
|
3034
|
+
] });
|
3035
|
+
}
|
3036
|
+
if (status === "modified") {
|
3037
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3038
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.ArrowsCounterClockwise, { fill: "alternative600" }),
|
3039
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
|
3040
|
+
id: "content-manager.bulk-publish.modified",
|
3041
|
+
defaultMessage: "Ready to publish changes"
|
3042
|
+
}) })
|
3043
|
+
] });
|
3044
|
+
}
|
3045
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3046
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.CheckCircle, { fill: "success600" }),
|
3047
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
|
3048
|
+
id: "app.utils.ready-to-publish",
|
3049
|
+
defaultMessage: "Ready to publish"
|
3050
|
+
}) })
|
3051
|
+
] });
|
3052
|
+
};
|
3053
|
+
const TABLE_HEADERS = [
|
3054
|
+
{ name: "id", label: "id" },
|
3055
|
+
{ name: "name", label: "name" },
|
3056
|
+
{ name: "status", label: "status" },
|
3057
|
+
{ name: "publicationStatus", label: "Publication status" }
|
3058
|
+
];
|
3059
|
+
const SelectedEntriesTableContent = ({
|
3060
|
+
isPublishing,
|
3061
|
+
rowsToDisplay = [],
|
3062
|
+
entriesToPublish = [],
|
3063
|
+
validationErrors = {}
|
3064
|
+
}) => {
|
3065
|
+
const { pathname } = reactRouterDom.useLocation();
|
3066
|
+
const { formatMessage } = reactIntl.useIntl();
|
3067
|
+
const {
|
3068
|
+
list: {
|
3069
|
+
settings: { mainField }
|
3070
|
+
}
|
3071
|
+
} = useDocLayout();
|
3072
|
+
const shouldDisplayMainField = mainField != null && mainField !== "id";
|
3073
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Content, { children: [
|
3074
|
+
/* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Head, { children: [
|
3075
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.HeaderCheckboxCell, {}),
|
3076
|
+
TABLE_HEADERS.filter((head) => head.name !== "name" || shouldDisplayMainField).map(
|
3077
|
+
(head) => /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.HeaderCell, { ...head }, head.name)
|
3078
|
+
)
|
3079
|
+
] }),
|
3080
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Loading, {}),
|
3081
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Body, { children: rowsToDisplay.map((row, index2) => /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Row, { children: [
|
3082
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.CheckboxCell, { id: row.id }),
|
3083
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: row.id }) }),
|
3084
|
+
shouldDisplayMainField && /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: row[mainField] }) }),
|
3085
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: row.status, maxWidth: "min-content" }) }),
|
3086
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: isPublishing && entriesToPublish.includes(row.documentId) ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3087
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
|
3088
|
+
id: "content-manager.success.record.publishing",
|
3089
|
+
defaultMessage: "Publishing..."
|
3090
|
+
}) }),
|
3091
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, { small: true })
|
3092
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx(
|
3093
|
+
EntryValidationText,
|
3094
|
+
{
|
3095
|
+
validationErrors: validationErrors[row.documentId],
|
3096
|
+
status: row.status
|
3097
|
+
}
|
3098
|
+
) }),
|
3099
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
3100
|
+
designSystem.IconButton,
|
3101
|
+
{
|
3102
|
+
tag: reactRouterDom.Link,
|
3103
|
+
to: {
|
3104
|
+
pathname: `${pathname}/${row.documentId}`,
|
3105
|
+
search: row.locale && `?plugins[i18n][locale]=${row.locale}`
|
3106
|
+
},
|
3107
|
+
state: { from: pathname },
|
3108
|
+
label: formatMessage(
|
3109
|
+
{ id: "app.component.HelperPluginTable.edit", defaultMessage: "Edit {target}" },
|
3110
|
+
{
|
3111
|
+
target: formatMessage(
|
3112
|
+
{
|
3113
|
+
id: "content-manager.components.ListViewHelperPluginTable.row-line",
|
3114
|
+
defaultMessage: "item line {number}"
|
3115
|
+
},
|
3116
|
+
{ number: index2 + 1 }
|
3117
|
+
)
|
3118
|
+
}
|
3119
|
+
),
|
3120
|
+
target: "_blank",
|
3121
|
+
marginLeft: "auto",
|
3122
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, {})
|
3123
|
+
}
|
3124
|
+
) })
|
3125
|
+
] }, row.id)) })
|
3126
|
+
] });
|
3127
|
+
};
|
3128
|
+
const BoldChunk = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
|
3129
|
+
const SelectedEntriesModalContent = ({
|
3130
|
+
listViewSelectedEntries,
|
3131
|
+
toggleModal,
|
3132
|
+
setListViewSelectedDocuments,
|
3133
|
+
model
|
3134
|
+
}) => {
|
3135
|
+
const { formatMessage } = reactIntl.useIntl();
|
3136
|
+
const { schema, components } = useContentTypeSchema(model);
|
3137
|
+
const documentIds = listViewSelectedEntries.map(({ documentId }) => documentId);
|
3138
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3139
|
+
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
3140
|
+
const { data, isLoading, isFetching, refetch } = useGetAllDocumentsQuery(
|
3141
|
+
{
|
3142
|
+
model,
|
3143
|
+
params: {
|
3144
|
+
page: "1",
|
3145
|
+
pageSize: documentIds.length.toString(),
|
3146
|
+
sort: query.sort,
|
3147
|
+
filters: {
|
3148
|
+
documentId: {
|
3149
|
+
$in: documentIds
|
3150
|
+
}
|
3151
|
+
},
|
3152
|
+
locale: query.plugins?.i18n?.locale
|
3153
|
+
}
|
3154
|
+
},
|
3155
|
+
{
|
3156
|
+
selectFromResult: ({ data: data2, ...restRes }) => ({ data: data2?.results ?? [], ...restRes })
|
3157
|
+
}
|
3158
|
+
);
|
3159
|
+
const { rows, validationErrors } = React__namespace.useMemo(() => {
|
3160
|
+
if (data.length > 0 && schema) {
|
3161
|
+
const validate = createYupSchema(schema.attributes, components);
|
3162
|
+
const validationErrors2 = {};
|
3163
|
+
const rows2 = data.map((entry) => {
|
3164
|
+
try {
|
3165
|
+
validate.validateSync(entry, { abortEarly: false });
|
3166
|
+
return entry;
|
3167
|
+
} catch (e) {
|
3168
|
+
if (e instanceof yup.ValidationError) {
|
3169
|
+
validationErrors2[entry.documentId] = strapiAdmin.getYupValidationErrors(e);
|
3170
|
+
}
|
3171
|
+
return entry;
|
3172
|
+
}
|
3173
|
+
});
|
3174
|
+
return { rows: rows2, validationErrors: validationErrors2 };
|
3175
|
+
}
|
3176
|
+
return {
|
3177
|
+
rows: [],
|
3178
|
+
validationErrors: {}
|
3179
|
+
};
|
3180
|
+
}, [components, data, schema]);
|
3181
|
+
const [publishedCount, setPublishedCount] = React__namespace.useState(0);
|
3182
|
+
const [isDialogOpen, setIsDialogOpen] = React__namespace.useState(false);
|
3183
|
+
const { publishMany: bulkPublishAction } = useDocumentActions();
|
3184
|
+
const [, { isLoading: isSubmittingForm }] = usePublishManyDocumentsMutation();
|
3185
|
+
const selectedRows = strapiAdmin.useTable("publishAction", (state) => state.selectedRows);
|
3186
|
+
const selectedEntries = rows.filter(
|
3187
|
+
(entry) => selectedRows.some((selectedEntry) => selectedEntry.documentId === entry.documentId)
|
3188
|
+
);
|
3189
|
+
const entriesToPublish = selectedEntries.filter((entry) => !validationErrors[entry.documentId]).map((entry) => entry.documentId);
|
3190
|
+
const selectedEntriesWithErrorsCount = selectedEntries.filter(
|
3191
|
+
({ documentId }) => validationErrors[documentId]
|
3192
|
+
).length;
|
3193
|
+
const selectedEntriesPublished = selectedEntries.filter(
|
3194
|
+
({ status }) => status === "published"
|
3195
|
+
).length;
|
3196
|
+
const selectedEntriesWithNoErrorsCount = selectedEntries.length - selectedEntriesWithErrorsCount - selectedEntriesPublished;
|
3197
|
+
const toggleDialog = () => setIsDialogOpen((prev) => !prev);
|
3198
|
+
const handleConfirmBulkPublish = async () => {
|
3199
|
+
toggleDialog();
|
3200
|
+
const res = await bulkPublishAction({ model, documentIds: entriesToPublish, params });
|
3201
|
+
if (!("error" in res)) {
|
3202
|
+
setPublishedCount(res.count);
|
3203
|
+
const unpublishedEntries = rows.filter((row) => {
|
3204
|
+
return !entriesToPublish.includes(row.documentId);
|
3205
|
+
});
|
3206
|
+
setListViewSelectedDocuments(unpublishedEntries);
|
3207
|
+
}
|
3208
|
+
};
|
3209
|
+
const getFormattedCountMessage = () => {
|
3210
|
+
if (publishedCount) {
|
3211
|
+
return formatMessage(
|
3212
|
+
{
|
3213
|
+
id: getTranslation("containers.list.selectedEntriesModal.publishedCount"),
|
3214
|
+
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."
|
3215
|
+
},
|
3216
|
+
{
|
3217
|
+
publishedCount,
|
3218
|
+
withErrorsCount: selectedEntriesWithErrorsCount,
|
3219
|
+
b: BoldChunk
|
3220
|
+
}
|
3221
|
+
);
|
3222
|
+
}
|
3223
|
+
return formatMessage(
|
3224
|
+
{
|
3225
|
+
id: getTranslation("containers.list.selectedEntriesModal.selectedCount"),
|
3226
|
+
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."
|
3227
|
+
},
|
3228
|
+
{
|
3229
|
+
readyToPublishCount: selectedEntriesWithNoErrorsCount,
|
3230
|
+
withErrorsCount: selectedEntriesWithErrorsCount,
|
3231
|
+
alreadyPublishedCount: selectedEntriesPublished,
|
3232
|
+
b: BoldChunk
|
3233
|
+
}
|
3234
|
+
);
|
3235
|
+
};
|
3236
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
3237
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Body, { children: [
|
3238
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: getFormattedCountMessage() }),
|
3239
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 5, children: /* @__PURE__ */ jsxRuntime.jsx(
|
3240
|
+
SelectedEntriesTableContent,
|
3241
|
+
{
|
3242
|
+
isPublishing: isSubmittingForm,
|
3243
|
+
rowsToDisplay: rows,
|
3244
|
+
entriesToPublish,
|
3245
|
+
validationErrors
|
3246
|
+
}
|
3247
|
+
) })
|
3248
|
+
] }),
|
3249
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
3250
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
|
3251
|
+
id: "app.components.Button.cancel",
|
3252
|
+
defaultMessage: "Cancel"
|
3253
|
+
}) }),
|
3254
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3255
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
|
3256
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
3257
|
+
designSystem.Button,
|
3258
|
+
{
|
3259
|
+
onClick: toggleDialog,
|
3260
|
+
disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
|
3261
|
+
loading: isSubmittingForm,
|
3262
|
+
children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
|
3263
|
+
}
|
3264
|
+
)
|
3265
|
+
] })
|
3266
|
+
] }),
|
3267
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
3268
|
+
ConfirmDialogPublishAll,
|
3269
|
+
{
|
3270
|
+
isOpen: isDialogOpen,
|
3271
|
+
onToggleDialog: toggleDialog,
|
3272
|
+
isConfirmButtonLoading: isSubmittingForm,
|
3273
|
+
onConfirm: handleConfirmBulkPublish
|
3274
|
+
}
|
3275
|
+
)
|
3276
|
+
] });
|
3277
|
+
};
|
3278
|
+
const PublishAction = ({ documents, model }) => {
|
3279
|
+
const { formatMessage } = reactIntl.useIntl();
|
3280
|
+
const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
|
3281
|
+
const showPublishButton = hasPublishPermission && documents.some(({ status }) => status !== "published");
|
3282
|
+
const setListViewSelectedDocuments = strapiAdmin.useTable("publishAction", (state) => state.selectRow);
|
3283
|
+
const refetchList = () => {
|
3284
|
+
contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
|
3285
|
+
};
|
3286
|
+
if (!showPublishButton)
|
3287
|
+
return null;
|
3288
|
+
return {
|
3289
|
+
actionType: "publish",
|
3290
|
+
variant: "tertiary",
|
3291
|
+
label: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" }),
|
3292
|
+
dialog: {
|
3293
|
+
type: "modal",
|
3294
|
+
title: formatMessage({
|
3295
|
+
id: getTranslation("containers.ListPage.selectedEntriesModal.title"),
|
3296
|
+
defaultMessage: "Publish entries"
|
3297
|
+
}),
|
3298
|
+
content: ({ onClose }) => {
|
3299
|
+
return /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Root, { rows: documents, defaultSelectedRows: documents, headers: TABLE_HEADERS, children: /* @__PURE__ */ jsxRuntime.jsx(
|
3300
|
+
SelectedEntriesModalContent,
|
3301
|
+
{
|
3302
|
+
listViewSelectedEntries: documents,
|
3303
|
+
toggleModal: () => {
|
3304
|
+
onClose();
|
3305
|
+
refetchList();
|
3306
|
+
},
|
3307
|
+
setListViewSelectedDocuments,
|
3308
|
+
model
|
3309
|
+
}
|
3310
|
+
) });
|
3311
|
+
},
|
3312
|
+
onClose: () => {
|
3313
|
+
refetchList();
|
3314
|
+
}
|
3315
|
+
}
|
3316
|
+
};
|
3317
|
+
};
|
3318
|
+
const BulkActionsRenderer = () => {
|
3319
|
+
const plugins = strapiAdmin.useStrapiApp("BulkActionsRenderer", (state) => state.plugins);
|
3320
|
+
const { model, collectionType } = useDoc();
|
3321
|
+
const { selectedRows } = strapiAdmin.useTable("BulkActionsRenderer", (state) => state);
|
3322
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
|
3323
|
+
strapiAdmin.DescriptionComponentRenderer,
|
3324
|
+
{
|
3325
|
+
props: {
|
3326
|
+
model,
|
3327
|
+
collectionType,
|
3328
|
+
documents: selectedRows
|
3329
|
+
},
|
3330
|
+
descriptions: plugins["content-manager"].apis.getBulkActions(),
|
3331
|
+
children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActionButton, { ...action }, action.id))
|
3332
|
+
}
|
3333
|
+
) });
|
3334
|
+
};
|
3335
|
+
const DeleteAction = ({ documents, model }) => {
|
3336
|
+
const { formatMessage } = reactIntl.useIntl();
|
3337
|
+
const { schema: contentType } = useDoc();
|
3338
|
+
const selectRow = strapiAdmin.useTable("DeleteAction", (state) => state.selectRow);
|
3339
|
+
const hasI18nEnabled = Boolean(contentType?.pluginOptions?.i18n);
|
3340
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3341
|
+
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
3342
|
+
const hasDeletePermission = useDocumentRBAC("deleteAction", (state) => state.canDelete);
|
3343
|
+
const { deleteMany: bulkDeleteAction } = useDocumentActions();
|
3344
|
+
const documentIds = documents.map(({ documentId }) => documentId);
|
3345
|
+
const handleConfirmBulkDelete = async () => {
|
3346
|
+
const res = await bulkDeleteAction({
|
3347
|
+
documentIds,
|
3348
|
+
model,
|
3349
|
+
params
|
3350
|
+
});
|
3351
|
+
if (!("error" in res)) {
|
3352
|
+
selectRow([]);
|
3353
|
+
}
|
3354
|
+
};
|
3355
|
+
if (!hasDeletePermission)
|
3356
|
+
return null;
|
3357
|
+
return {
|
3358
|
+
variant: "danger-light",
|
3359
|
+
label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
|
3360
|
+
dialog: {
|
3361
|
+
type: "dialog",
|
3362
|
+
title: formatMessage({
|
3363
|
+
id: "app.components.ConfirmDialog.title",
|
3364
|
+
defaultMessage: "Confirmation"
|
3365
|
+
}),
|
3366
|
+
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3367
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3368
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
|
3369
|
+
id: "popUpWarning.bodyMessage.contentType.delete.all",
|
3370
|
+
defaultMessage: "Are you sure you want to delete these entries?"
|
3371
|
+
}) }),
|
3372
|
+
hasI18nEnabled && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", children: formatMessage(
|
3373
|
+
{
|
3374
|
+
id: getTranslation("Settings.list.actions.deleteAdditionalInfos"),
|
3375
|
+
defaultMessage: "This will delete the active locale versions <em>(from Internationalization)</em>"
|
3376
|
+
},
|
3377
|
+
{
|
3378
|
+
em: Emphasis
|
3379
|
+
}
|
3380
|
+
) }) })
|
3381
|
+
] }),
|
3382
|
+
onConfirm: handleConfirmBulkDelete
|
3383
|
+
}
|
3384
|
+
};
|
3385
|
+
};
|
3386
|
+
DeleteAction.type = "delete";
|
3387
|
+
const UnpublishAction = ({ documents, model }) => {
|
3388
|
+
const { formatMessage } = reactIntl.useIntl();
|
3389
|
+
const { schema } = useDoc();
|
3390
|
+
const selectRow = strapiAdmin.useTable("UnpublishAction", (state) => state.selectRow);
|
3391
|
+
const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
|
3392
|
+
const hasI18nEnabled = Boolean(schema?.pluginOptions?.i18n);
|
3393
|
+
const hasDraftAndPublishEnabled = Boolean(schema?.options?.draftAndPublish);
|
3394
|
+
const { unpublishMany: bulkUnpublishAction } = useDocumentActions();
|
3395
|
+
const documentIds = documents.map(({ documentId }) => documentId);
|
3396
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3397
|
+
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
3398
|
+
const handleConfirmBulkUnpublish = async () => {
|
3399
|
+
const data = await bulkUnpublishAction({ documentIds, model, params });
|
3400
|
+
if (!("error" in data)) {
|
3401
|
+
selectRow([]);
|
3402
|
+
}
|
3403
|
+
};
|
3404
|
+
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
|
3405
|
+
if (!showUnpublishButton)
|
3406
|
+
return null;
|
3407
|
+
return {
|
3408
|
+
variant: "tertiary",
|
3409
|
+
label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
|
3410
|
+
dialog: {
|
3411
|
+
type: "dialog",
|
3412
|
+
title: formatMessage({
|
3413
|
+
id: "app.components.ConfirmDialog.title",
|
3414
|
+
defaultMessage: "Confirmation"
|
3415
|
+
}),
|
3416
|
+
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3417
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3418
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
|
3419
|
+
id: "popUpWarning.bodyMessage.contentType.unpublish.all",
|
3420
|
+
defaultMessage: "Are you sure you want to unpublish these entries?"
|
3421
|
+
}) }),
|
3422
|
+
hasI18nEnabled && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", children: formatMessage(
|
3423
|
+
{
|
3424
|
+
id: getTranslation("Settings.list.actions.unpublishAdditionalInfos"),
|
3425
|
+
defaultMessage: "This will unpublish the active locale versions <em>(from Internationalization)</em>"
|
3426
|
+
},
|
3427
|
+
{
|
3428
|
+
em: Emphasis
|
3429
|
+
}
|
3430
|
+
) }) })
|
3431
|
+
] }),
|
3432
|
+
confirmButton: formatMessage({
|
3433
|
+
id: "app.utils.unpublish",
|
3434
|
+
defaultMessage: "Unpublish"
|
3435
|
+
}),
|
3436
|
+
onConfirm: handleConfirmBulkUnpublish
|
3437
|
+
}
|
3438
|
+
};
|
3439
|
+
};
|
3440
|
+
UnpublishAction.type = "unpublish";
|
3441
|
+
const Emphasis = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", textColor: "danger500", children: chunks });
|
3442
|
+
const DEFAULT_BULK_ACTIONS = [PublishAction, UnpublishAction, DeleteAction];
|
3443
|
+
const AutoCloneFailureModalBody = ({ prohibitedFields }) => {
|
3444
|
+
const { formatMessage } = reactIntl.useIntl();
|
3445
|
+
const getDefaultErrorMessage = (reason) => {
|
3446
|
+
switch (reason) {
|
3447
|
+
case "relation":
|
3448
|
+
return "Duplicating the relation could remove it from the original entry.";
|
3449
|
+
case "unique":
|
3450
|
+
return "Identical values in a unique field are not allowed";
|
3451
|
+
default:
|
3452
|
+
return reason;
|
3453
|
+
}
|
3454
|
+
};
|
3455
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
3456
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", children: formatMessage({
|
3457
|
+
id: getTranslation("containers.list.autoCloneModal.title"),
|
3458
|
+
defaultMessage: "This entry can't be duplicated directly."
|
3459
|
+
}) }),
|
3460
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", children: formatMessage({
|
3461
|
+
id: getTranslation("containers.list.autoCloneModal.description"),
|
3462
|
+
defaultMessage: "A new entry will be created with the same content, but you'll have to change the following fields to save it."
|
3463
|
+
}) }) }),
|
3464
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { marginTop: 6, gap: 2, direction: "column", alignItems: "stretch", children: prohibitedFields.map(([fieldPath, reason]) => /* @__PURE__ */ jsxRuntime.jsxs(
|
3465
|
+
designSystem.Flex,
|
3466
|
+
{
|
3467
|
+
direction: "column",
|
3468
|
+
gap: 2,
|
3469
|
+
alignItems: "flex-start",
|
3470
|
+
borderColor: "neutral200",
|
3471
|
+
hasRadius: true,
|
3472
|
+
padding: 6,
|
3473
|
+
children: [
|
3474
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "row", tag: "ol", children: fieldPath.map((pathSegment, index2) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { fontWeight: "semiBold", tag: "li", children: [
|
3475
|
+
pathSegment,
|
3476
|
+
index2 !== fieldPath.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(
|
3477
|
+
Icons.ChevronRight,
|
3478
|
+
{
|
3479
|
+
fill: "neutral500",
|
3480
|
+
height: "0.8rem",
|
3481
|
+
width: "0.8rem",
|
3482
|
+
style: { margin: "0 0.8rem" }
|
3483
|
+
}
|
3484
|
+
)
|
3485
|
+
] }, index2)) }),
|
3486
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", textColor: "neutral600", children: formatMessage({
|
3487
|
+
id: getTranslation(`containers.list.autoCloneModal.error.${reason}`),
|
3488
|
+
defaultMessage: getDefaultErrorMessage(reason)
|
3489
|
+
}) })
|
3490
|
+
]
|
3491
|
+
},
|
3492
|
+
fieldPath.join()
|
3493
|
+
)) })
|
3494
|
+
] });
|
3495
|
+
};
|
3496
|
+
const TableActions = ({ document }) => {
|
3497
|
+
const { formatMessage } = reactIntl.useIntl();
|
3498
|
+
const { model, collectionType } = useDoc();
|
3499
|
+
const plugins = strapiAdmin.useStrapiApp("TableActions", (state) => state.plugins);
|
3500
|
+
const props = {
|
3501
|
+
activeTab: null,
|
3502
|
+
model,
|
3503
|
+
documentId: document.documentId,
|
3504
|
+
collectionType,
|
3505
|
+
document
|
3506
|
+
};
|
3507
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
3508
|
+
strapiAdmin.DescriptionComponentRenderer,
|
3509
|
+
{
|
3510
|
+
props,
|
3511
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3512
|
+
children: (actions2) => {
|
3513
|
+
const tableRowActions = actions2.filter((action) => {
|
3514
|
+
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
3515
|
+
return positions.includes("table-row");
|
3516
|
+
});
|
3517
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
3518
|
+
DocumentActionsMenu,
|
3519
|
+
{
|
3520
|
+
actions: tableRowActions,
|
3521
|
+
label: formatMessage({
|
3522
|
+
id: "content-manager.containers.list.table.row-actions",
|
3523
|
+
defaultMessage: "Row action"
|
3524
|
+
}),
|
3525
|
+
variant: "ghost"
|
3526
|
+
}
|
3527
|
+
);
|
3528
|
+
}
|
3529
|
+
}
|
3530
|
+
);
|
3531
|
+
};
|
3532
|
+
const EditAction = ({ documentId }) => {
|
3533
|
+
const navigate = reactRouterDom.useNavigate();
|
3534
|
+
const { formatMessage } = reactIntl.useIntl();
|
3535
|
+
const { canRead } = useDocumentRBAC("EditAction", ({ canRead: canRead2 }) => ({ canRead: canRead2 }));
|
3536
|
+
const { toggleNotification } = strapiAdmin.useNotification();
|
3537
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3538
|
+
return {
|
3539
|
+
disabled: !canRead,
|
3540
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(StyledPencil, {}),
|
3541
|
+
label: formatMessage({
|
3542
|
+
id: "content-manager.actions.edit.label",
|
3543
|
+
defaultMessage: "Edit"
|
3544
|
+
}),
|
3545
|
+
position: "table-row",
|
3546
|
+
onClick: async () => {
|
2571
3547
|
if (!documentId) {
|
2572
3548
|
console.error(
|
2573
3549
|
"You're trying to edit a document without an id, this is likely a bug with Strapi. Please open an issue."
|
@@ -2591,7 +3567,7 @@ const EditAction = ({ documentId }) => {
|
|
2591
3567
|
};
|
2592
3568
|
};
|
2593
3569
|
EditAction.type = "edit";
|
2594
|
-
const StyledPencil =
|
3570
|
+
const StyledPencil = styledComponents.styled(Icons.Pencil)`
|
2595
3571
|
path {
|
2596
3572
|
fill: currentColor;
|
2597
3573
|
}
|
@@ -2651,7 +3627,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
2651
3627
|
/* @__PURE__ */ jsxRuntime.jsx(
|
2652
3628
|
designSystem.LinkButton,
|
2653
3629
|
{
|
2654
|
-
|
3630
|
+
tag: reactRouterDom.NavLink,
|
2655
3631
|
to: {
|
2656
3632
|
pathname: `clone/${documentId}`
|
2657
3633
|
},
|
@@ -2667,7 +3643,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
2667
3643
|
};
|
2668
3644
|
};
|
2669
3645
|
CloneAction.type = "clone";
|
2670
|
-
const StyledDuplicate =
|
3646
|
+
const StyledDuplicate = styledComponents.styled(Icons.Duplicate)`
|
2671
3647
|
path {
|
2672
3648
|
fill: currentColor;
|
2673
3649
|
}
|
@@ -2684,442 +3660,183 @@ class ContentManagerPlugin {
|
|
2684
3660
|
documentActions = [
|
2685
3661
|
...DEFAULT_ACTIONS,
|
2686
3662
|
...DEFAULT_TABLE_ROW_ACTIONS,
|
2687
|
-
...DEFAULT_HEADER_ACTIONS
|
2688
|
-
HistoryAction
|
3663
|
+
...DEFAULT_HEADER_ACTIONS
|
2689
3664
|
];
|
2690
3665
|
editViewSidePanels = [ActionsPanel];
|
2691
3666
|
headerActions = [];
|
2692
3667
|
constructor() {
|
2693
3668
|
}
|
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);
|
3669
|
+
addEditViewSidePanel(panels) {
|
3670
|
+
if (Array.isArray(panels)) {
|
3671
|
+
this.editViewSidePanels = [...this.editViewSidePanels, ...panels];
|
3672
|
+
} else if (typeof panels === "function") {
|
3673
|
+
this.editViewSidePanels = panels(this.editViewSidePanels);
|
2725
3674
|
} else {
|
2726
3675
|
throw new Error(
|
2727
|
-
`Expected the \`
|
2728
|
-
|
3676
|
+
`Expected the \`panels\` passed to \`addEditViewSidePanel\` to be an array or a function, but received ${getPrintableType(
|
3677
|
+
panels
|
2729
3678
|
)}`
|
2730
3679
|
);
|
2731
3680
|
}
|
2732
3681
|
}
|
2733
|
-
|
3682
|
+
addDocumentAction(actions2) {
|
2734
3683
|
if (Array.isArray(actions2)) {
|
2735
|
-
this.
|
3684
|
+
this.documentActions = [...this.documentActions, ...actions2];
|
2736
3685
|
} else if (typeof actions2 === "function") {
|
2737
|
-
this.
|
3686
|
+
this.documentActions = actions2(this.documentActions);
|
2738
3687
|
} else {
|
2739
3688
|
throw new Error(
|
2740
|
-
`Expected the \`actions\` passed to \`
|
3689
|
+
`Expected the \`actions\` passed to \`addDocumentAction\` to be an array or a function, but received ${getPrintableType(
|
2741
3690
|
actions2
|
2742
3691
|
)}`
|
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;
|
3692
|
+
);
|
3693
|
+
}
|
3694
|
+
}
|
3695
|
+
addDocumentHeaderAction(actions2) {
|
3696
|
+
if (Array.isArray(actions2)) {
|
3697
|
+
this.headerActions = [...this.headerActions, ...actions2];
|
3698
|
+
} else if (typeof actions2 === "function") {
|
3699
|
+
this.headerActions = actions2(this.headerActions);
|
2982
3700
|
} else {
|
2983
|
-
|
2984
|
-
|
2985
|
-
|
2986
|
-
|
3701
|
+
throw new Error(
|
3702
|
+
`Expected the \`actions\` passed to \`addDocumentHeaderAction\` to be an array or a function, but received ${getPrintableType(
|
3703
|
+
actions2
|
3704
|
+
)}`
|
3705
|
+
);
|
2987
3706
|
}
|
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
|
3707
|
+
}
|
3708
|
+
addBulkAction(actions2) {
|
3709
|
+
if (Array.isArray(actions2)) {
|
3710
|
+
this.bulkActions = [...this.bulkActions, ...actions2];
|
3711
|
+
} else if (typeof actions2 === "function") {
|
3712
|
+
this.bulkActions = actions2(this.bulkActions);
|
3713
|
+
} else {
|
3714
|
+
throw new Error(
|
3715
|
+
`Expected the \`actions\` passed to \`addBulkAction\` to be an array or a function, but received ${getPrintableType(
|
3716
|
+
actions2
|
3717
|
+
)}`
|
3718
|
+
);
|
3029
3719
|
}
|
3030
|
-
}
|
3031
|
-
|
3032
|
-
|
3033
|
-
|
3034
|
-
|
3035
|
-
|
3036
|
-
|
3037
|
-
|
3720
|
+
}
|
3721
|
+
get config() {
|
3722
|
+
return {
|
3723
|
+
id: PLUGIN_ID,
|
3724
|
+
name: "Content Manager",
|
3725
|
+
injectionZones: INJECTION_ZONES,
|
3726
|
+
apis: {
|
3727
|
+
addBulkAction: this.addBulkAction.bind(this),
|
3728
|
+
addDocumentAction: this.addDocumentAction.bind(this),
|
3729
|
+
addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
|
3730
|
+
addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
|
3731
|
+
getBulkActions: () => this.bulkActions,
|
3732
|
+
getDocumentActions: () => this.documentActions,
|
3733
|
+
getEditViewSidePanels: () => this.editViewSidePanels,
|
3734
|
+
getHeaderActions: () => this.headerActions
|
3038
3735
|
}
|
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
|
-
);
|
3736
|
+
};
|
3737
|
+
}
|
3738
|
+
}
|
3739
|
+
const getPrintableType = (value) => {
|
3740
|
+
const nativeType = typeof value;
|
3741
|
+
if (nativeType === "object") {
|
3742
|
+
if (value === null)
|
3743
|
+
return "null";
|
3744
|
+
if (Array.isArray(value))
|
3745
|
+
return "array";
|
3746
|
+
if (value instanceof Object && value.constructor.name !== "Object") {
|
3747
|
+
return value.constructor.name;
|
3748
|
+
}
|
3749
|
+
}
|
3750
|
+
return nativeType;
|
3061
3751
|
};
|
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
|
-
);
|
3752
|
+
const HistoryAction = ({ model, document }) => {
|
3753
|
+
const { formatMessage } = reactIntl.useIntl();
|
3754
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3755
|
+
const navigate = reactRouterDom.useNavigate();
|
3756
|
+
const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
|
3757
|
+
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3758
|
+
return null;
|
3759
|
+
}
|
3083
3760
|
return {
|
3084
|
-
|
3085
|
-
|
3086
|
-
|
3087
|
-
|
3088
|
-
|
3089
|
-
|
3090
|
-
|
3091
|
-
|
3761
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
|
3762
|
+
label: formatMessage({
|
3763
|
+
id: "content-manager.history.document-action",
|
3764
|
+
defaultMessage: "Content History"
|
3765
|
+
}),
|
3766
|
+
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
3767
|
+
disabled: (
|
3768
|
+
/**
|
3769
|
+
* The user is creating a new document.
|
3770
|
+
* It hasn't been saved yet, so there's no history to go to
|
3771
|
+
*/
|
3772
|
+
!document || /**
|
3773
|
+
* The document has been created but the current dimension has never been saved.
|
3774
|
+
* For example, the user is creating a new locale in an existing document,
|
3775
|
+
* so there's no history for the document in that locale
|
3776
|
+
*/
|
3777
|
+
!document.id || /**
|
3778
|
+
* History is only available for content types created by the user.
|
3779
|
+
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
3780
|
+
* which start with `admin::` or `plugin::`
|
3781
|
+
*/
|
3782
|
+
!model.startsWith("api::")
|
3783
|
+
),
|
3784
|
+
position: "header"
|
3092
3785
|
};
|
3093
3786
|
};
|
3094
|
-
|
3095
|
-
|
3096
|
-
|
3097
|
-
|
3098
|
-
|
3099
|
-
|
3100
|
-
|
3101
|
-
|
3102
|
-
|
3103
|
-
|
3104
|
-
|
3105
|
-
|
3106
|
-
|
3107
|
-
|
3108
|
-
|
3109
|
-
|
3110
|
-
|
3111
|
-
|
3112
|
-
};
|
3113
|
-
}).filter((field) => field !== null);
|
3787
|
+
HistoryAction.type = "history";
|
3788
|
+
const historyAdmin = {
|
3789
|
+
bootstrap(app) {
|
3790
|
+
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
3791
|
+
addDocumentAction((actions2) => {
|
3792
|
+
const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
|
3793
|
+
actions2.splice(indexOfDeleteAction, 0, HistoryAction);
|
3794
|
+
return actions2;
|
3795
|
+
});
|
3796
|
+
}
|
3797
|
+
};
|
3798
|
+
const initialState = {
|
3799
|
+
collectionTypeLinks: [],
|
3800
|
+
components: [],
|
3801
|
+
fieldSizes: {},
|
3802
|
+
models: [],
|
3803
|
+
singleTypeLinks: [],
|
3804
|
+
isLoading: true
|
3114
3805
|
};
|
3806
|
+
const appSlice = toolkit.createSlice({
|
3807
|
+
name: "app",
|
3808
|
+
initialState,
|
3809
|
+
reducers: {
|
3810
|
+
setInitialData(state, action) {
|
3811
|
+
const {
|
3812
|
+
authorizedCollectionTypeLinks,
|
3813
|
+
authorizedSingleTypeLinks,
|
3814
|
+
components,
|
3815
|
+
contentTypeSchemas,
|
3816
|
+
fieldSizes
|
3817
|
+
} = action.payload;
|
3818
|
+
state.collectionTypeLinks = authorizedCollectionTypeLinks.filter(
|
3819
|
+
({ isDisplayed }) => isDisplayed
|
3820
|
+
);
|
3821
|
+
state.singleTypeLinks = authorizedSingleTypeLinks.filter(({ isDisplayed }) => isDisplayed);
|
3822
|
+
state.components = components;
|
3823
|
+
state.models = contentTypeSchemas;
|
3824
|
+
state.fieldSizes = fieldSizes;
|
3825
|
+
state.isLoading = false;
|
3826
|
+
}
|
3827
|
+
}
|
3828
|
+
});
|
3829
|
+
const { actions, reducer: reducer$1 } = appSlice;
|
3830
|
+
const { setInitialData } = actions;
|
3831
|
+
const reducer = toolkit.combineReducers({
|
3832
|
+
app: reducer$1
|
3833
|
+
});
|
3115
3834
|
const index = {
|
3116
3835
|
register(app) {
|
3117
3836
|
const cm = new ContentManagerPlugin();
|
3118
3837
|
app.addReducers({
|
3119
|
-
[contentManagerApi.reducerPath]: contentManagerApi.reducer,
|
3120
3838
|
[PLUGIN_ID]: reducer
|
3121
3839
|
});
|
3122
|
-
app.addMiddlewares([() => contentManagerApi.middleware]);
|
3123
3840
|
app.addMenuLink({
|
3124
3841
|
to: PLUGIN_ID,
|
3125
3842
|
icon: Icons.Feather,
|
@@ -3128,14 +3845,29 @@ const index = {
|
|
3128
3845
|
defaultMessage: "Content Manager"
|
3129
3846
|
},
|
3130
3847
|
permissions: [],
|
3131
|
-
|
3848
|
+
position: 1
|
3849
|
+
});
|
3850
|
+
app.router.addRoute({
|
3851
|
+
path: "content-manager/*",
|
3852
|
+
lazy: async () => {
|
3853
|
+
const { Layout } = await Promise.resolve().then(() => require("./layout-TPqF2oJ5.js"));
|
3854
|
+
return {
|
3855
|
+
Component: Layout
|
3856
|
+
};
|
3857
|
+
},
|
3858
|
+
children: routes
|
3132
3859
|
});
|
3133
3860
|
app.registerPlugin(cm.config);
|
3134
3861
|
},
|
3862
|
+
bootstrap(app) {
|
3863
|
+
if (typeof historyAdmin.bootstrap === "function") {
|
3864
|
+
historyAdmin.bootstrap(app);
|
3865
|
+
}
|
3866
|
+
},
|
3135
3867
|
async registerTrads({ locales }) {
|
3136
3868
|
const importedTrads = await Promise.all(
|
3137
3869
|
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-
|
3870
|
+
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
3871
|
return {
|
3140
3872
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3141
3873
|
locale
|
@@ -3152,6 +3884,7 @@ const index = {
|
|
3152
3884
|
}
|
3153
3885
|
};
|
3154
3886
|
exports.ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD = ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD;
|
3887
|
+
exports.BulkActionsRenderer = BulkActionsRenderer;
|
3155
3888
|
exports.COLLECTION_TYPES = COLLECTION_TYPES;
|
3156
3889
|
exports.CREATOR_FIELDS = CREATOR_FIELDS;
|
3157
3890
|
exports.DEFAULT_SETTINGS = DEFAULT_SETTINGS;
|
@@ -3178,7 +3911,6 @@ exports.getDisplayName = getDisplayName;
|
|
3178
3911
|
exports.getMainField = getMainField;
|
3179
3912
|
exports.getTranslation = getTranslation;
|
3180
3913
|
exports.index = index;
|
3181
|
-
exports.routes = routes;
|
3182
3914
|
exports.setInitialData = setInitialData;
|
3183
3915
|
exports.useContentTypeSchema = useContentTypeSchema;
|
3184
3916
|
exports.useDoc = useDoc;
|
@@ -3192,4 +3924,4 @@ exports.useGetAllDocumentsQuery = useGetAllDocumentsQuery;
|
|
3192
3924
|
exports.useGetContentTypeConfigurationQuery = useGetContentTypeConfigurationQuery;
|
3193
3925
|
exports.useGetInitialDataQuery = useGetInitialDataQuery;
|
3194
3926
|
exports.useUpdateContentTypeConfigurationMutation = useUpdateContentTypeConfigurationMutation;
|
3195
|
-
//# sourceMappingURL=index-
|
3927
|
+
//# sourceMappingURL=index-DyvUPg1a.js.map
|