@strapi/content-manager 0.0.0-experimental.e60ec1829240dae21c1e1d29076681c322288813 → 0.0.0-experimental.f31889311d753b5f7d95198ae84d8fce1d156cd6
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-DjWJdz6Y.js → ComponentConfigurationPage-BNxtMIfV.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-DjWJdz6Y.js.map → ComponentConfigurationPage-BNxtMIfV.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-BPvzFjM7.mjs → ComponentConfigurationPage-BWOQWCv2.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-BPvzFjM7.mjs.map → ComponentConfigurationPage-BWOQWCv2.mjs.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-Dmv83RlS.js → EditConfigurationPage-D340bYlT.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-Dmv83RlS.js.map → EditConfigurationPage-D340bYlT.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-DacbqQ_f.mjs → EditConfigurationPage-GTp-Ucnw.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-DacbqQ_f.mjs.map → EditConfigurationPage-GTp-Ucnw.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-DDS6H9HO.mjs → EditViewPage-BVMS5hT-.mjs} +47 -47
- package/dist/_chunks/EditViewPage-BVMS5hT-.mjs.map +1 -0
- package/dist/_chunks/{EditViewPage-DvNpQkam.js → EditViewPage-CXkmnAvI.js} +46 -48
- package/dist/_chunks/EditViewPage-CXkmnAvI.js.map +1 -0
- package/dist/_chunks/{Field-DmVKIAOo.js → Field-Ibi32diw.js} +953 -782
- package/dist/_chunks/Field-Ibi32diw.js.map +1 -0
- package/dist/_chunks/{Field-6gvGdPBV.mjs → Field-nNgv5bpd.mjs} +901 -729
- package/dist/_chunks/Field-nNgv5bpd.mjs.map +1 -0
- package/dist/_chunks/{Form-CPZC9vWa.js → Form-Dhnh34ym.js} +39 -38
- package/dist/_chunks/Form-Dhnh34ym.js.map +1 -0
- package/dist/_chunks/{Form-DW6K1IH-.mjs → Form-DodJsI2A.mjs} +39 -37
- package/dist/_chunks/Form-DodJsI2A.mjs.map +1 -0
- package/dist/_chunks/{History-DeAPlvtv.js → History-C9auUkDi.js} +149 -56
- package/dist/_chunks/History-C9auUkDi.js.map +1 -0
- package/dist/_chunks/{History-Dmr9fmUA.mjs → History-CKCSQXz_.mjs} +148 -54
- package/dist/_chunks/History-CKCSQXz_.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DPCwW5Vr.js → ListConfigurationPage-Bg4rWUjX.js} +58 -59
- package/dist/_chunks/ListConfigurationPage-Bg4rWUjX.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DhwvYcNv.mjs → ListConfigurationPage-CKEC4ttG.mjs} +54 -54
- package/dist/_chunks/ListConfigurationPage-CKEC4ttG.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-BtAwuYLE.mjs → ListViewPage-B7_WJUjG.mjs} +93 -104
- package/dist/_chunks/ListViewPage-B7_WJUjG.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-5ySZ-VUs.js → ListViewPage-C2gIeYHG.js} +98 -109
- package/dist/_chunks/ListViewPage-C2gIeYHG.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DSPxnxxp.mjs → NoContentTypePage-Ckem6Ll6.mjs} +3 -3
- package/dist/_chunks/NoContentTypePage-Ckem6Ll6.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DOC_yWOf.js → NoContentTypePage-DqgdUfyn.js} +3 -3
- package/dist/_chunks/NoContentTypePage-DqgdUfyn.js.map +1 -0
- package/dist/_chunks/{NoPermissionsPage-UWDC-1Tw.mjs → NoPermissionsPage-BO-GEjA4.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-UWDC-1Tw.mjs.map → NoPermissionsPage-BO-GEjA4.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-Dwu8rRJu.js → NoPermissionsPage-CF29Q-sW.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-Dwu8rRJu.js.map → NoPermissionsPage-CF29Q-sW.js.map} +1 -1
- package/dist/_chunks/{Relations-CgWtgnPe.js → Relations-C0uC9J4f.js} +70 -61
- package/dist/_chunks/Relations-C0uC9J4f.js.map +1 -0
- package/dist/_chunks/{Relations-J8cscLlR.mjs → Relations-DItV5eow.mjs} +66 -56
- package/dist/_chunks/Relations-DItV5eow.mjs.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-C6AH2hEl.js → index-Dd0nXyJF.js} +1649 -905
- package/dist/_chunks/index-Dd0nXyJF.js.map +1 -0
- package/dist/_chunks/{index-CwRRo1V9.mjs → index-DrNe6ctw.mjs} +1671 -926
- package/dist/_chunks/index-DrNe6ctw.mjs.map +1 -0
- package/dist/_chunks/{layout-jIDzX0Fp.mjs → layout-B3ez7kvr.mjs} +43 -26
- package/dist/_chunks/layout-B3ez7kvr.mjs.map +1 -0
- package/dist/_chunks/{layout-B_SXLhqf.js → layout-CLLtt_5O.js} +43 -28
- package/dist/_chunks/layout-CLLtt_5O.js.map +1 -0
- package/dist/_chunks/{relations-CuvIgCqI.mjs → relations-B0hlsUU_.mjs} +2 -2
- package/dist/_chunks/{relations-CuvIgCqI.mjs.map → relations-B0hlsUU_.mjs.map} +1 -1
- package/dist/_chunks/{relations-iBMa_OFG.js → relations-bRxcNv1q.js} +2 -2
- package/dist/_chunks/{relations-iBMa_OFG.js.map → relations-bRxcNv1q.js.map} +1 -1
- package/dist/_chunks/useDragAndDrop-DdHgKsqq.mjs.map +1 -1
- package/dist/_chunks/useDragAndDrop-J0TUUbR6.js.map +1 -1
- package/dist/_chunks/usePrev-B9w_-eYc.js +15 -0
- package/dist/_chunks/usePrev-B9w_-eYc.js.map +1 -0
- package/dist/_chunks/usePrev-DH6iah0A.mjs +16 -0
- package/dist/_chunks/usePrev-DH6iah0A.mjs.map +1 -0
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +5 -4
- package/dist/admin/src/components/ComponentIcon.d.ts +6 -3
- package/dist/admin/src/content-manager.d.ts +3 -3
- package/dist/admin/src/exports.d.ts +1 -0
- package/dist/admin/src/history/components/VersionInputRenderer.d.ts +1 -1
- package/dist/admin/src/history/index.d.ts +3 -0
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +5 -8
- package/dist/admin/src/hooks/useDocumentActions.d.ts +24 -3
- package/dist/admin/src/hooks/useDocumentLayout.d.ts +2 -2
- package/dist/admin/src/hooks/useDragAndDrop.d.ts +4 -4
- package/dist/admin/src/hooks/useKeyboardDragAndDrop.d.ts +1 -1
- package/dist/admin/src/index.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +11 -4
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.d.ts +3 -3
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +4 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Component/Input.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.d.ts +3 -5
- package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/Field.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +30 -18
- package/dist/admin/src/pages/EditView/components/FormInputs/UID.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +3 -49
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/Field.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/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 +392 -261
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +400 -269
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/controllers/single-types.d.ts.map +1 -1
- package/dist/server/src/controllers/uid.d.ts.map +1 -1
- package/dist/server/src/controllers/utils/metadata.d.ts +8 -0
- package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -0
- package/dist/server/src/controllers/validation/dimensions.d.ts +11 -0
- package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -0
- package/dist/server/src/controllers/validation/index.d.ts +1 -1
- package/dist/server/src/history/services/history.d.ts.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
- package/dist/server/src/history/services/utils.d.ts +1 -1
- package/dist/server/src/history/services/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-DDS6H9HO.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-DvNpQkam.js.map +0 -1
- package/dist/_chunks/Field-6gvGdPBV.mjs.map +0 -1
- package/dist/_chunks/Field-DmVKIAOo.js.map +0 -1
- package/dist/_chunks/Form-CPZC9vWa.js.map +0 -1
- package/dist/_chunks/Form-DW6K1IH-.mjs.map +0 -1
- package/dist/_chunks/History-DeAPlvtv.js.map +0 -1
- package/dist/_chunks/History-Dmr9fmUA.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DPCwW5Vr.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DhwvYcNv.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-5ySZ-VUs.js.map +0 -1
- package/dist/_chunks/ListViewPage-BtAwuYLE.mjs.map +0 -1
- package/dist/_chunks/NoContentTypePage-DOC_yWOf.js.map +0 -1
- package/dist/_chunks/NoContentTypePage-DSPxnxxp.mjs.map +0 -1
- package/dist/_chunks/Relations-CgWtgnPe.js.map +0 -1
- package/dist/_chunks/Relations-J8cscLlR.mjs.map +0 -1
- package/dist/_chunks/index-C6AH2hEl.js.map +0 -1
- package/dist/_chunks/index-CwRRo1V9.mjs.map +0 -1
- package/dist/_chunks/layout-B_SXLhqf.js.map +0 -1
- package/dist/_chunks/layout-jIDzX0Fp.mjs.map +0 -1
- package/dist/_chunks/urls-CbOsUOoW.mjs +0 -7
- package/dist/_chunks/urls-CbOsUOoW.mjs.map +0 -1
- package/dist/_chunks/urls-DzZya_gm.js +0 -6
- package/dist/_chunks/urls-DzZya_gm.js.map +0 -1
- package/dist/server/src/controllers/utils/dimensions.d.ts +0 -5
- package/dist/server/src/controllers/utils/dimensions.d.ts.map +0 -1
@@ -2,17 +2,15 @@
|
|
2
2
|
const Icons = require("@strapi/icons");
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
4
4
|
const strapiAdmin = require("@strapi/admin/strapi-admin");
|
5
|
-
const qs = require("qs");
|
6
|
-
const reactIntl = require("react-intl");
|
7
|
-
const reactRouterDom = require("react-router-dom");
|
8
5
|
const React = require("react");
|
9
6
|
const designSystem = require("@strapi/design-system");
|
10
|
-
const
|
7
|
+
const reactIntl = require("react-intl");
|
8
|
+
const reactRouterDom = require("react-router-dom");
|
9
|
+
const styledComponents = require("styled-components");
|
11
10
|
const yup = require("yup");
|
12
|
-
const react = require("@reduxjs/toolkit/query/react");
|
13
|
-
const axios = require("axios");
|
14
11
|
const pipe = require("lodash/fp/pipe");
|
15
12
|
const dateFns = require("date-fns");
|
13
|
+
const qs = require("qs");
|
16
14
|
const toolkit = require("@reduxjs/toolkit");
|
17
15
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
18
16
|
function _interopNamespace(e) {
|
@@ -34,7 +32,6 @@ function _interopNamespace(e) {
|
|
34
32
|
return Object.freeze(n);
|
35
33
|
}
|
36
34
|
const React__namespace = /* @__PURE__ */ _interopNamespace(React);
|
37
|
-
const styled__default = /* @__PURE__ */ _interopDefault(styled);
|
38
35
|
const yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
|
39
36
|
const pipe__default = /* @__PURE__ */ _interopDefault(pipe);
|
40
37
|
const __variableDynamicImportRuntimeHelper = (glob, path) => {
|
@@ -73,42 +70,6 @@ const useInjectionZone = (area) => {
|
|
73
70
|
const [page, position] = area.split(".");
|
74
71
|
return contentManagerPlugin.getInjectedComponents(page, position);
|
75
72
|
};
|
76
|
-
const HistoryAction = ({ model, document }) => {
|
77
|
-
const { formatMessage } = reactIntl.useIntl();
|
78
|
-
const [{ query }] = strapiAdmin.useQueryParams();
|
79
|
-
const navigate = reactRouterDom.useNavigate();
|
80
|
-
const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
|
81
|
-
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
82
|
-
return null;
|
83
|
-
}
|
84
|
-
return {
|
85
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
|
86
|
-
label: formatMessage({
|
87
|
-
id: "content-manager.history.document-action",
|
88
|
-
defaultMessage: "Content History"
|
89
|
-
}),
|
90
|
-
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
91
|
-
disabled: (
|
92
|
-
/**
|
93
|
-
* The user is creating a new document.
|
94
|
-
* It hasn't been saved yet, so there's no history to go to
|
95
|
-
*/
|
96
|
-
!document || /**
|
97
|
-
* The document has been created but the current dimension has never been saved.
|
98
|
-
* For example, the user is creating a new locale in an existing document,
|
99
|
-
* so there's no history for the document in that locale
|
100
|
-
*/
|
101
|
-
!document.id || /**
|
102
|
-
* History is only available for content types created by the user.
|
103
|
-
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
104
|
-
* which start with `admin::` or `plugin::`
|
105
|
-
*/
|
106
|
-
!model.startsWith("api::")
|
107
|
-
),
|
108
|
-
position: "header"
|
109
|
-
};
|
110
|
-
};
|
111
|
-
HistoryAction.type = "history";
|
112
73
|
const ID = "id";
|
113
74
|
const CREATED_BY_ATTRIBUTE_NAME = "createdBy";
|
114
75
|
const UPDATED_BY_ATTRIBUTE_NAME = "updatedBy";
|
@@ -179,9 +140,8 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
179
140
|
const name = removeNumericalStrings(fieldName.split("."));
|
180
141
|
const componentFieldNames = fieldsUserCanAction.filter((field) => field.split(".").length > 1);
|
181
142
|
if (fieldType === "component") {
|
182
|
-
|
183
|
-
|
184
|
-
return field.includes(fieldName);
|
143
|
+
return componentFieldNames.some((field) => {
|
144
|
+
return field.includes(name.join("."));
|
185
145
|
});
|
186
146
|
}
|
187
147
|
if (name.length > 1) {
|
@@ -211,78 +171,8 @@ const extractAndDedupeFields = (permissions = []) => permissions.flatMap((permis
|
|
211
171
|
(field, index2, arr) => arr.indexOf(field) === index2 && typeof field === "string"
|
212
172
|
);
|
213
173
|
const removeNumericalStrings = (arr) => arr.filter((item) => isNaN(Number(item)));
|
214
|
-
const
|
215
|
-
|
216
|
-
return query;
|
217
|
-
const { plugins: _, ...validQueryParams } = {
|
218
|
-
...query,
|
219
|
-
...Object.values(query?.plugins ?? {}).reduce(
|
220
|
-
(acc, current) => Object.assign(acc, current),
|
221
|
-
{}
|
222
|
-
)
|
223
|
-
};
|
224
|
-
if ("_q" in validQueryParams) {
|
225
|
-
validQueryParams._q = encodeURIComponent(validQueryParams._q);
|
226
|
-
}
|
227
|
-
return validQueryParams;
|
228
|
-
};
|
229
|
-
const axiosBaseQuery = () => async (query, { signal }) => {
|
230
|
-
try {
|
231
|
-
const { get, post, del, put } = strapiAdmin.getFetchClient();
|
232
|
-
if (typeof query === "string") {
|
233
|
-
const result = await get(query, { signal });
|
234
|
-
return { data: result.data };
|
235
|
-
} else {
|
236
|
-
const { url, method = "GET", data, config } = query;
|
237
|
-
if (method === "POST") {
|
238
|
-
const result2 = await post(url, data, { ...config, signal });
|
239
|
-
return { data: result2.data };
|
240
|
-
}
|
241
|
-
if (method === "DELETE") {
|
242
|
-
const result2 = await del(url, { ...config, signal });
|
243
|
-
return { data: result2.data };
|
244
|
-
}
|
245
|
-
if (method === "PUT") {
|
246
|
-
const result2 = await put(url, data, { ...config, signal });
|
247
|
-
return { data: result2.data };
|
248
|
-
}
|
249
|
-
const result = await get(url, { ...config, signal });
|
250
|
-
return { data: result.data };
|
251
|
-
}
|
252
|
-
} catch (err) {
|
253
|
-
if (axios.isAxiosError(err)) {
|
254
|
-
if (typeof err.response?.data === "object" && err.response?.data !== null && "error" in err.response?.data) {
|
255
|
-
return { data: void 0, error: err.response?.data.error };
|
256
|
-
} else {
|
257
|
-
return {
|
258
|
-
data: void 0,
|
259
|
-
error: {
|
260
|
-
name: "UnknownError",
|
261
|
-
message: "There was an unknown error response from the API",
|
262
|
-
details: err.response?.data,
|
263
|
-
status: err.response?.status
|
264
|
-
}
|
265
|
-
};
|
266
|
-
}
|
267
|
-
}
|
268
|
-
const error = err;
|
269
|
-
return {
|
270
|
-
data: void 0,
|
271
|
-
error: {
|
272
|
-
name: error.name,
|
273
|
-
message: error.message,
|
274
|
-
stack: error.stack
|
275
|
-
}
|
276
|
-
};
|
277
|
-
}
|
278
|
-
};
|
279
|
-
const isBaseQueryError = (error) => {
|
280
|
-
return error.name !== void 0;
|
281
|
-
};
|
282
|
-
const contentManagerApi = react.createApi({
|
283
|
-
reducerPath: "contentManagerApi",
|
284
|
-
baseQuery: axiosBaseQuery(),
|
285
|
-
tagTypes: [
|
174
|
+
const contentManagerApi = strapiAdmin.adminApi.enhanceEndpoints({
|
175
|
+
addTagTypes: [
|
286
176
|
"ComponentConfiguration",
|
287
177
|
"ContentTypesConfiguration",
|
288
178
|
"ContentTypeSettings",
|
@@ -290,10 +180,10 @@ const contentManagerApi = react.createApi({
|
|
290
180
|
"InitialData",
|
291
181
|
"HistoryVersion",
|
292
182
|
"Relations"
|
293
|
-
]
|
294
|
-
endpoints: () => ({})
|
183
|
+
]
|
295
184
|
});
|
296
185
|
const documentApi = contentManagerApi.injectEndpoints({
|
186
|
+
overrideExisting: true,
|
297
187
|
endpoints: (builder) => ({
|
298
188
|
autoCloneDocument: builder.mutation({
|
299
189
|
query: ({ model, sourceId, query }) => ({
|
@@ -303,7 +193,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
303
193
|
params: query
|
304
194
|
}
|
305
195
|
}),
|
306
|
-
invalidatesTags: (_result,
|
196
|
+
invalidatesTags: (_result, error, { model }) => {
|
197
|
+
if (error) {
|
198
|
+
return [];
|
199
|
+
}
|
200
|
+
return [{ type: "Document", id: `${model}_LIST` }];
|
201
|
+
}
|
307
202
|
}),
|
308
203
|
cloneDocument: builder.mutation({
|
309
204
|
query: ({ model, sourceId, data, params }) => ({
|
@@ -347,12 +242,15 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
347
242
|
]
|
348
243
|
}),
|
349
244
|
deleteManyDocuments: builder.mutation({
|
350
|
-
query: ({ model, ...body }) => ({
|
245
|
+
query: ({ model, params, ...body }) => ({
|
351
246
|
url: `/content-manager/collection-types/${model}/actions/bulkDelete`,
|
352
247
|
method: "POST",
|
353
|
-
data: body
|
248
|
+
data: body,
|
249
|
+
config: {
|
250
|
+
params
|
251
|
+
}
|
354
252
|
}),
|
355
|
-
invalidatesTags: (_res, _error, { model
|
253
|
+
invalidatesTags: (_res, _error, { model }) => [{ type: "Document", id: `${model}_LIST` }]
|
356
254
|
}),
|
357
255
|
discardDocument: builder.mutation({
|
358
256
|
query: ({ collectionType, model, documentId, params }) => ({
|
@@ -387,6 +285,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
387
285
|
}),
|
388
286
|
providesTags: (result, _error, arg) => {
|
389
287
|
return [
|
288
|
+
{ type: "Document", id: `ALL_LIST` },
|
390
289
|
{ type: "Document", id: `${arg.model}_LIST` },
|
391
290
|
...result?.results.map(({ documentId }) => ({
|
392
291
|
type: "Document",
|
@@ -463,10 +362,13 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
463
362
|
}
|
464
363
|
}),
|
465
364
|
publishManyDocuments: builder.mutation({
|
466
|
-
query: ({ model, ...body }) => ({
|
365
|
+
query: ({ model, params, ...body }) => ({
|
467
366
|
url: `/content-manager/collection-types/${model}/actions/bulkPublish`,
|
468
367
|
method: "POST",
|
469
|
-
data: body
|
368
|
+
data: body,
|
369
|
+
config: {
|
370
|
+
params
|
371
|
+
}
|
470
372
|
}),
|
471
373
|
invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
|
472
374
|
}),
|
@@ -487,6 +389,18 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
487
389
|
},
|
488
390
|
"Relations"
|
489
391
|
];
|
392
|
+
},
|
393
|
+
async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
|
394
|
+
const patchResult = dispatch(
|
395
|
+
documentApi.util.updateQueryData("getDocument", patch, (draft) => {
|
396
|
+
Object.assign(draft.data, data);
|
397
|
+
})
|
398
|
+
);
|
399
|
+
try {
|
400
|
+
await queryFulfilled;
|
401
|
+
} catch {
|
402
|
+
patchResult.undo();
|
403
|
+
}
|
490
404
|
}
|
491
405
|
}),
|
492
406
|
unpublishDocument: builder.mutation({
|
@@ -508,10 +422,13 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
508
422
|
}
|
509
423
|
}),
|
510
424
|
unpublishManyDocuments: builder.mutation({
|
511
|
-
query: ({ model, ...body }) => ({
|
425
|
+
query: ({ model, params, ...body }) => ({
|
512
426
|
url: `/content-manager/collection-types/${model}/actions/bulkUnpublish`,
|
513
427
|
method: "POST",
|
514
|
-
data: body
|
428
|
+
data: body,
|
429
|
+
config: {
|
430
|
+
params
|
431
|
+
}
|
515
432
|
}),
|
516
433
|
invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
|
517
434
|
})
|
@@ -535,6 +452,24 @@ const {
|
|
535
452
|
useUnpublishDocumentMutation,
|
536
453
|
useUnpublishManyDocumentsMutation
|
537
454
|
} = documentApi;
|
455
|
+
const buildValidParams = (query) => {
|
456
|
+
if (!query)
|
457
|
+
return query;
|
458
|
+
const { plugins: _, ...validQueryParams } = {
|
459
|
+
...query,
|
460
|
+
...Object.values(query?.plugins ?? {}).reduce(
|
461
|
+
(acc, current) => Object.assign(acc, current),
|
462
|
+
{}
|
463
|
+
)
|
464
|
+
};
|
465
|
+
if ("_q" in validQueryParams) {
|
466
|
+
validQueryParams._q = encodeURIComponent(validQueryParams._q);
|
467
|
+
}
|
468
|
+
return validQueryParams;
|
469
|
+
};
|
470
|
+
const isBaseQueryError = (error) => {
|
471
|
+
return error.name !== void 0;
|
472
|
+
};
|
538
473
|
const createYupSchema = (attributes = {}, components = {}) => {
|
539
474
|
const createModelSchema = (attributes2) => yup__namespace.object().shape(
|
540
475
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
@@ -574,10 +509,14 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
574
509
|
yup__namespace.array().of(
|
575
510
|
yup__namespace.lazy(
|
576
511
|
(data) => {
|
577
|
-
const
|
578
|
-
|
512
|
+
const attributes3 = components?.[data?.__component]?.attributes;
|
513
|
+
const validation = yup__namespace.object().shape({
|
579
514
|
__component: yup__namespace.string().required().oneOf(Object.keys(components))
|
580
|
-
}).nullable(false)
|
515
|
+
}).nullable(false);
|
516
|
+
if (!attributes3) {
|
517
|
+
return validation;
|
518
|
+
}
|
519
|
+
return validation.concat(createModelSchema(attributes3));
|
581
520
|
}
|
582
521
|
)
|
583
522
|
)
|
@@ -587,11 +526,25 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
587
526
|
return {
|
588
527
|
...acc,
|
589
528
|
[name]: transformSchema(
|
590
|
-
yup__namespace.
|
591
|
-
|
592
|
-
|
593
|
-
})
|
594
|
-
|
529
|
+
yup__namespace.lazy((value) => {
|
530
|
+
if (!value) {
|
531
|
+
return yup__namespace.mixed().nullable(true);
|
532
|
+
} else if (Array.isArray(value)) {
|
533
|
+
return yup__namespace.array().of(
|
534
|
+
yup__namespace.object().shape({
|
535
|
+
id: yup__namespace.string().required()
|
536
|
+
})
|
537
|
+
);
|
538
|
+
} else if (typeof value === "object") {
|
539
|
+
return yup__namespace.object();
|
540
|
+
} else {
|
541
|
+
return yup__namespace.mixed().test(
|
542
|
+
"type-error",
|
543
|
+
"Relation values must be either null, an array of objects with {id} or an object.",
|
544
|
+
() => false
|
545
|
+
);
|
546
|
+
}
|
547
|
+
})
|
595
548
|
)
|
596
549
|
};
|
597
550
|
default:
|
@@ -650,13 +603,18 @@ const createAttributeSchema = (attribute) => {
|
|
650
603
|
}
|
651
604
|
};
|
652
605
|
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
|
-
});
|
606
|
+
if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
|
607
|
+
return schema.min(1, strapiAdmin.translatedErrors.required);
|
658
608
|
}
|
659
|
-
|
609
|
+
if (attribute.required && attribute.type !== "relation") {
|
610
|
+
return schema.required(strapiAdmin.translatedErrors.required);
|
611
|
+
}
|
612
|
+
return schema?.nullable ? schema.nullable() : (
|
613
|
+
// In some cases '.nullable' will not be available on the schema.
|
614
|
+
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
615
|
+
// In these cases we should just return the schema as it is.
|
616
|
+
schema
|
617
|
+
);
|
660
618
|
};
|
661
619
|
const addMinLengthValidation = (attribute) => (schema) => {
|
662
620
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
@@ -683,6 +641,28 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
683
641
|
const addMinValidation = (attribute) => (schema) => {
|
684
642
|
if ("min" in attribute) {
|
685
643
|
const min = toInteger(attribute.min);
|
644
|
+
if (attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") {
|
645
|
+
if (!attribute.required && "test" in schema && min) {
|
646
|
+
return schema.test(
|
647
|
+
"custom-min",
|
648
|
+
{
|
649
|
+
...strapiAdmin.translatedErrors.min,
|
650
|
+
values: {
|
651
|
+
min: attribute.min
|
652
|
+
}
|
653
|
+
},
|
654
|
+
(value) => {
|
655
|
+
if (!value) {
|
656
|
+
return true;
|
657
|
+
}
|
658
|
+
if (Array.isArray(value) && value.length === 0) {
|
659
|
+
return true;
|
660
|
+
}
|
661
|
+
return value.length >= min;
|
662
|
+
}
|
663
|
+
);
|
664
|
+
}
|
665
|
+
}
|
686
666
|
if ("min" in schema && min) {
|
687
667
|
return schema.min(min, {
|
688
668
|
...strapiAdmin.translatedErrors.min,
|
@@ -728,24 +708,6 @@ const addRegexValidation = (attribute) => (schema) => {
|
|
728
708
|
}
|
729
709
|
return schema;
|
730
710
|
};
|
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
711
|
const initApi = contentManagerApi.injectEndpoints({
|
750
712
|
endpoints: (builder) => ({
|
751
713
|
getInitialData: builder.query({
|
@@ -759,27 +721,20 @@ const { useGetInitialDataQuery } = initApi;
|
|
759
721
|
const useContentTypeSchema = (model) => {
|
760
722
|
const { toggleNotification } = strapiAdmin.useNotification();
|
761
723
|
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
|
-
});
|
724
|
+
const { data, error, isLoading, isFetching } = useGetInitialDataQuery(void 0);
|
725
|
+
const { components, contentType, contentTypes } = React__namespace.useMemo(() => {
|
726
|
+
const contentType2 = data?.contentTypes.find((ct) => ct.uid === model);
|
727
|
+
const componentsByKey = data?.components.reduce((acc, component) => {
|
728
|
+
acc[component.uid] = component;
|
729
|
+
return acc;
|
730
|
+
}, {});
|
731
|
+
const components2 = extractContentTypeComponents(contentType2?.attributes, componentsByKey);
|
732
|
+
return {
|
733
|
+
components: Object.keys(components2).length === 0 ? void 0 : components2,
|
734
|
+
contentType: contentType2,
|
735
|
+
contentTypes: data?.contentTypes ?? []
|
736
|
+
};
|
737
|
+
}, [model, data]);
|
783
738
|
React__namespace.useEffect(() => {
|
784
739
|
if (error) {
|
785
740
|
toggleNotification({
|
@@ -834,7 +789,10 @@ const useDocument = (args, opts) => {
|
|
834
789
|
isLoading: isLoadingDocument,
|
835
790
|
isFetching: isFetchingDocument,
|
836
791
|
error
|
837
|
-
} = useGetDocumentQuery(args,
|
792
|
+
} = useGetDocumentQuery(args, {
|
793
|
+
...opts,
|
794
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
795
|
+
});
|
838
796
|
const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
|
839
797
|
React__namespace.useEffect(() => {
|
840
798
|
if (error) {
|
@@ -862,7 +820,7 @@ const useDocument = (args, opts) => {
|
|
862
820
|
return null;
|
863
821
|
} catch (error2) {
|
864
822
|
if (error2 instanceof yup.ValidationError) {
|
865
|
-
return
|
823
|
+
return strapiAdmin.getYupValidationErrors(error2);
|
866
824
|
}
|
867
825
|
throw error2;
|
868
826
|
}
|
@@ -958,14 +916,53 @@ const useDocumentActions = () => {
|
|
958
916
|
},
|
959
917
|
[trackUsage, deleteDocument, toggleNotification, formatMessage, formatAPIError]
|
960
918
|
);
|
919
|
+
const [deleteManyDocuments] = useDeleteManyDocumentsMutation();
|
920
|
+
const deleteMany = React__namespace.useCallback(
|
921
|
+
async ({ model, documentIds, params }) => {
|
922
|
+
try {
|
923
|
+
trackUsage("willBulkDeleteEntries");
|
924
|
+
const res = await deleteManyDocuments({
|
925
|
+
model,
|
926
|
+
documentIds,
|
927
|
+
params
|
928
|
+
});
|
929
|
+
if ("error" in res) {
|
930
|
+
toggleNotification({
|
931
|
+
type: "danger",
|
932
|
+
message: formatAPIError(res.error)
|
933
|
+
});
|
934
|
+
return { error: res.error };
|
935
|
+
}
|
936
|
+
toggleNotification({
|
937
|
+
type: "success",
|
938
|
+
title: formatMessage({
|
939
|
+
id: getTranslation("success.records.delete"),
|
940
|
+
defaultMessage: "Successfully deleted."
|
941
|
+
}),
|
942
|
+
message: ""
|
943
|
+
});
|
944
|
+
trackUsage("didBulkDeleteEntries");
|
945
|
+
return res.data;
|
946
|
+
} catch (err) {
|
947
|
+
toggleNotification({
|
948
|
+
type: "danger",
|
949
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
950
|
+
});
|
951
|
+
trackUsage("didNotBulkDeleteEntries");
|
952
|
+
throw err;
|
953
|
+
}
|
954
|
+
},
|
955
|
+
[trackUsage, deleteManyDocuments, toggleNotification, formatMessage, formatAPIError]
|
956
|
+
);
|
961
957
|
const [discardDocument] = useDiscardDocumentMutation();
|
962
958
|
const discard = React__namespace.useCallback(
|
963
|
-
async ({ collectionType, model, documentId }) => {
|
959
|
+
async ({ collectionType, model, documentId, params }) => {
|
964
960
|
try {
|
965
961
|
const res = await discardDocument({
|
966
962
|
collectionType,
|
967
963
|
model,
|
968
|
-
documentId
|
964
|
+
documentId,
|
965
|
+
params
|
969
966
|
});
|
970
967
|
if ("error" in res) {
|
971
968
|
toggleNotification({
|
@@ -1027,6 +1024,43 @@ const useDocumentActions = () => {
|
|
1027
1024
|
},
|
1028
1025
|
[trackUsage, publishDocument, toggleNotification, formatMessage, formatAPIError]
|
1029
1026
|
);
|
1027
|
+
const [publishManyDocuments] = usePublishManyDocumentsMutation();
|
1028
|
+
const publishMany = React__namespace.useCallback(
|
1029
|
+
async ({ model, documentIds, params }) => {
|
1030
|
+
try {
|
1031
|
+
const res = await publishManyDocuments({
|
1032
|
+
model,
|
1033
|
+
documentIds,
|
1034
|
+
params
|
1035
|
+
});
|
1036
|
+
if ("error" in res) {
|
1037
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1038
|
+
return { error: res.error };
|
1039
|
+
}
|
1040
|
+
toggleNotification({
|
1041
|
+
type: "success",
|
1042
|
+
message: formatMessage({
|
1043
|
+
id: getTranslation("success.record.publish"),
|
1044
|
+
defaultMessage: "Published document"
|
1045
|
+
})
|
1046
|
+
});
|
1047
|
+
return res.data;
|
1048
|
+
} catch (err) {
|
1049
|
+
toggleNotification({
|
1050
|
+
type: "danger",
|
1051
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1052
|
+
});
|
1053
|
+
throw err;
|
1054
|
+
}
|
1055
|
+
},
|
1056
|
+
[
|
1057
|
+
// trackUsage,
|
1058
|
+
publishManyDocuments,
|
1059
|
+
toggleNotification,
|
1060
|
+
formatMessage,
|
1061
|
+
formatAPIError
|
1062
|
+
]
|
1063
|
+
);
|
1030
1064
|
const [updateDocument] = useUpdateDocumentMutation();
|
1031
1065
|
const update = React__namespace.useCallback(
|
1032
1066
|
async ({ collectionType, model, documentId, params }, data, trackerProperty) => {
|
@@ -1101,6 +1135,41 @@ const useDocumentActions = () => {
|
|
1101
1135
|
},
|
1102
1136
|
[trackUsage, unpublishDocument, toggleNotification, formatMessage, formatAPIError]
|
1103
1137
|
);
|
1138
|
+
const [unpublishManyDocuments] = useUnpublishManyDocumentsMutation();
|
1139
|
+
const unpublishMany = React__namespace.useCallback(
|
1140
|
+
async ({ model, documentIds, params }) => {
|
1141
|
+
try {
|
1142
|
+
trackUsage("willBulkUnpublishEntries");
|
1143
|
+
const res = await unpublishManyDocuments({
|
1144
|
+
model,
|
1145
|
+
documentIds,
|
1146
|
+
params
|
1147
|
+
});
|
1148
|
+
if ("error" in res) {
|
1149
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1150
|
+
return { error: res.error };
|
1151
|
+
}
|
1152
|
+
trackUsage("didBulkUnpublishEntries");
|
1153
|
+
toggleNotification({
|
1154
|
+
type: "success",
|
1155
|
+
title: formatMessage({
|
1156
|
+
id: getTranslation("success.records.unpublish"),
|
1157
|
+
defaultMessage: "Successfully unpublished."
|
1158
|
+
}),
|
1159
|
+
message: ""
|
1160
|
+
});
|
1161
|
+
return res.data;
|
1162
|
+
} catch (err) {
|
1163
|
+
toggleNotification({
|
1164
|
+
type: "danger",
|
1165
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1166
|
+
});
|
1167
|
+
trackUsage("didNotBulkUnpublishEntries");
|
1168
|
+
throw err;
|
1169
|
+
}
|
1170
|
+
},
|
1171
|
+
[trackUsage, unpublishManyDocuments, toggleNotification, formatMessage, formatAPIError]
|
1172
|
+
);
|
1104
1173
|
const [createDocument] = useCreateDocumentMutation();
|
1105
1174
|
const create = React__namespace.useCallback(
|
1106
1175
|
async ({ model, params }, data, trackerProperty) => {
|
@@ -1144,7 +1213,6 @@ const useDocumentActions = () => {
|
|
1144
1213
|
sourceId
|
1145
1214
|
});
|
1146
1215
|
if ("error" in res) {
|
1147
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1148
1216
|
return { error: res.error };
|
1149
1217
|
}
|
1150
1218
|
toggleNotification({
|
@@ -1214,15 +1282,18 @@ const useDocumentActions = () => {
|
|
1214
1282
|
clone,
|
1215
1283
|
create,
|
1216
1284
|
delete: _delete,
|
1285
|
+
deleteMany,
|
1217
1286
|
discard,
|
1218
1287
|
getDocument,
|
1219
1288
|
publish,
|
1289
|
+
publishMany,
|
1220
1290
|
unpublish,
|
1291
|
+
unpublishMany,
|
1221
1292
|
update
|
1222
1293
|
};
|
1223
1294
|
};
|
1224
1295
|
const ProtectedHistoryPage = React.lazy(
|
1225
|
-
() => Promise.resolve().then(() => require("./History-
|
1296
|
+
() => Promise.resolve().then(() => require("./History-C9auUkDi.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1226
1297
|
);
|
1227
1298
|
const routes$1 = [
|
1228
1299
|
{
|
@@ -1235,31 +1306,31 @@ const routes$1 = [
|
|
1235
1306
|
}
|
1236
1307
|
];
|
1237
1308
|
const ProtectedEditViewPage = React.lazy(
|
1238
|
-
() => Promise.resolve().then(() => require("./EditViewPage-
|
1309
|
+
() => Promise.resolve().then(() => require("./EditViewPage-CXkmnAvI.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1239
1310
|
);
|
1240
1311
|
const ProtectedListViewPage = React.lazy(
|
1241
|
-
() => Promise.resolve().then(() => require("./ListViewPage-
|
1312
|
+
() => Promise.resolve().then(() => require("./ListViewPage-C2gIeYHG.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1242
1313
|
);
|
1243
1314
|
const ProtectedListConfiguration = React.lazy(
|
1244
|
-
() => Promise.resolve().then(() => require("./ListConfigurationPage-
|
1315
|
+
() => Promise.resolve().then(() => require("./ListConfigurationPage-Bg4rWUjX.js")).then((mod) => ({
|
1245
1316
|
default: mod.ProtectedListConfiguration
|
1246
1317
|
}))
|
1247
1318
|
);
|
1248
1319
|
const ProtectedEditConfigurationPage = React.lazy(
|
1249
|
-
() => Promise.resolve().then(() => require("./EditConfigurationPage-
|
1320
|
+
() => Promise.resolve().then(() => require("./EditConfigurationPage-D340bYlT.js")).then((mod) => ({
|
1250
1321
|
default: mod.ProtectedEditConfigurationPage
|
1251
1322
|
}))
|
1252
1323
|
);
|
1253
1324
|
const ProtectedComponentConfigurationPage = React.lazy(
|
1254
|
-
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-
|
1325
|
+
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-BNxtMIfV.js")).then((mod) => ({
|
1255
1326
|
default: mod.ProtectedComponentConfigurationPage
|
1256
1327
|
}))
|
1257
1328
|
);
|
1258
1329
|
const NoPermissions = React.lazy(
|
1259
|
-
() => Promise.resolve().then(() => require("./NoPermissionsPage-
|
1330
|
+
() => Promise.resolve().then(() => require("./NoPermissionsPage-CF29Q-sW.js")).then((mod) => ({ default: mod.NoPermissions }))
|
1260
1331
|
);
|
1261
1332
|
const NoContentType = React.lazy(
|
1262
|
-
() => Promise.resolve().then(() => require("./NoContentTypePage-
|
1333
|
+
() => Promise.resolve().then(() => require("./NoContentTypePage-DqgdUfyn.js")).then((mod) => ({ default: mod.NoContentType }))
|
1263
1334
|
);
|
1264
1335
|
const CollectionTypePages = () => {
|
1265
1336
|
const { collectionType } = reactRouterDom.useParams();
|
@@ -1386,7 +1457,7 @@ const DocumentActionButton = (action) => {
|
|
1386
1457
|
DocumentActionConfirmDialog,
|
1387
1458
|
{
|
1388
1459
|
...action.dialog,
|
1389
|
-
variant: action.variant,
|
1460
|
+
variant: action.dialog?.variant ?? action.variant,
|
1390
1461
|
isOpen: dialogId === action.id,
|
1391
1462
|
onClose: handleClose
|
1392
1463
|
}
|
@@ -1443,13 +1514,13 @@ const DocumentActionsMenu = ({
|
|
1443
1514
|
disabled: isDisabled,
|
1444
1515
|
size: "S",
|
1445
1516
|
endIcon: null,
|
1446
|
-
paddingTop: "
|
1447
|
-
paddingLeft: "
|
1448
|
-
paddingRight: "
|
1517
|
+
paddingTop: "4px",
|
1518
|
+
paddingLeft: "7px",
|
1519
|
+
paddingRight: "7px",
|
1449
1520
|
variant,
|
1450
1521
|
children: [
|
1451
1522
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.More, { "aria-hidden": true, focusable: false }),
|
1452
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, {
|
1523
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { tag: "span", children: label || formatMessage({
|
1453
1524
|
id: "content-manager.containers.edit.panels.default.more-actions",
|
1454
1525
|
defaultMessage: "More document actions"
|
1455
1526
|
}) })
|
@@ -1465,10 +1536,18 @@ const DocumentActionsMenu = ({
|
|
1465
1536
|
onSelect: handleClick(action),
|
1466
1537
|
display: "block",
|
1467
1538
|
children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", gap: 4, children: [
|
1468
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1539
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
1540
|
+
designSystem.Flex,
|
1541
|
+
{
|
1542
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1543
|
+
gap: 2,
|
1544
|
+
tag: "span",
|
1545
|
+
children: [
|
1546
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: action.icon }),
|
1547
|
+
action.label
|
1548
|
+
]
|
1549
|
+
}
|
1550
|
+
),
|
1472
1551
|
action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsxRuntime.jsx(
|
1473
1552
|
designSystem.Flex,
|
1474
1553
|
{
|
@@ -1549,61 +1628,42 @@ const DocumentActionConfirmDialog = ({
|
|
1549
1628
|
}
|
1550
1629
|
onClose();
|
1551
1630
|
};
|
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
|
-
] });
|
1631
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
1632
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
1633
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: content }),
|
1634
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
|
1635
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", children: formatMessage({
|
1636
|
+
id: "app.components.Button.cancel",
|
1637
|
+
defaultMessage: "Cancel"
|
1638
|
+
}) }) }),
|
1639
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, children: formatMessage({
|
1640
|
+
id: "app.components.Button.confirm",
|
1641
|
+
defaultMessage: "Confirm"
|
1642
|
+
}) })
|
1643
|
+
] })
|
1644
|
+
] }) });
|
1568
1645
|
};
|
1569
1646
|
const DocumentActionModal = ({
|
1570
1647
|
isOpen,
|
1571
1648
|
title,
|
1572
1649
|
onClose,
|
1573
1650
|
footer: Footer,
|
1574
|
-
content,
|
1651
|
+
content: Content,
|
1575
1652
|
onModalClose
|
1576
1653
|
}) => {
|
1577
|
-
const id = React__namespace.useId();
|
1578
|
-
if (!isOpen) {
|
1579
|
-
return null;
|
1580
|
-
}
|
1581
1654
|
const handleClose = () => {
|
1582
1655
|
if (onClose) {
|
1583
1656
|
onClose();
|
1584
1657
|
}
|
1585
1658
|
onModalClose();
|
1586
1659
|
};
|
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
|
-
] });
|
1660
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Content, { children: [
|
1661
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Title, { children: title }) }),
|
1662
|
+
typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, { children: Content }),
|
1663
|
+
typeof Footer === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Footer, { onClose: handleClose }) : Footer
|
1664
|
+
] }) });
|
1605
1665
|
};
|
1606
|
-
const PublishAction = ({
|
1666
|
+
const PublishAction$1 = ({
|
1607
1667
|
activeTab,
|
1608
1668
|
documentId,
|
1609
1669
|
model,
|
@@ -1622,6 +1682,12 @@ const PublishAction = ({
|
|
1622
1682
|
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1623
1683
|
);
|
1624
1684
|
const { publish } = useDocumentActions();
|
1685
|
+
const [
|
1686
|
+
countDraftRelations,
|
1687
|
+
{ isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
|
1688
|
+
] = useLazyGetDraftRelationCountQuery();
|
1689
|
+
const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React__namespace.useState(0);
|
1690
|
+
const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React__namespace.useState(0);
|
1625
1691
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1626
1692
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
1627
1693
|
const modified = strapiAdmin.useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
@@ -1630,65 +1696,146 @@ const PublishAction = ({
|
|
1630
1696
|
const validate = strapiAdmin.useForm("PublishAction", (state) => state.validate);
|
1631
1697
|
const setErrors = strapiAdmin.useForm("PublishAction", (state) => state.setErrors);
|
1632
1698
|
const formValues = strapiAdmin.useForm("PublishAction", ({ values }) => values);
|
1633
|
-
|
1634
|
-
|
1635
|
-
|
1636
|
-
|
1637
|
-
|
1638
|
-
|
1639
|
-
|
1640
|
-
|
1641
|
-
|
1642
|
-
|
1643
|
-
|
1644
|
-
|
1645
|
-
|
1646
|
-
|
1647
|
-
|
1699
|
+
React__namespace.useEffect(() => {
|
1700
|
+
if (isErrorDraftRelations) {
|
1701
|
+
toggleNotification({
|
1702
|
+
type: "danger",
|
1703
|
+
message: formatMessage({
|
1704
|
+
id: getTranslation("error.records.fetch-draft-relatons"),
|
1705
|
+
defaultMessage: "An error occurred while fetching draft relations on this document."
|
1706
|
+
})
|
1707
|
+
});
|
1708
|
+
}
|
1709
|
+
}, [isErrorDraftRelations, toggleNotification, formatMessage]);
|
1710
|
+
React__namespace.useEffect(() => {
|
1711
|
+
const localDraftRelations = /* @__PURE__ */ new Set();
|
1712
|
+
const extractDraftRelations = (data) => {
|
1713
|
+
const relations = data.connect || [];
|
1714
|
+
relations.forEach((relation) => {
|
1715
|
+
if (relation.status === "draft") {
|
1716
|
+
localDraftRelations.add(relation.id);
|
1717
|
+
}
|
1718
|
+
});
|
1719
|
+
};
|
1720
|
+
const traverseAndExtract = (data) => {
|
1721
|
+
Object.entries(data).forEach(([key, value]) => {
|
1722
|
+
if (key === "connect" && Array.isArray(value)) {
|
1723
|
+
extractDraftRelations({ connect: value });
|
1724
|
+
} else if (typeof value === "object" && value !== null) {
|
1725
|
+
traverseAndExtract(value);
|
1726
|
+
}
|
1727
|
+
});
|
1728
|
+
};
|
1729
|
+
if (!documentId || modified) {
|
1730
|
+
traverseAndExtract(formValues);
|
1731
|
+
setLocalCountOfDraftRelations(localDraftRelations.size);
|
1732
|
+
}
|
1733
|
+
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
1734
|
+
React__namespace.useEffect(() => {
|
1735
|
+
if (documentId) {
|
1736
|
+
const fetchDraftRelationsCount = async () => {
|
1737
|
+
const { data, error } = await countDraftRelations({
|
1738
|
+
collectionType,
|
1739
|
+
model,
|
1740
|
+
documentId,
|
1741
|
+
params
|
1742
|
+
});
|
1743
|
+
if (error) {
|
1744
|
+
throw error;
|
1745
|
+
}
|
1746
|
+
if (data) {
|
1747
|
+
setServerCountOfDraftRelations(data.data);
|
1748
|
+
}
|
1749
|
+
};
|
1750
|
+
fetchDraftRelationsCount();
|
1751
|
+
}
|
1752
|
+
}, [documentId, countDraftRelations, collectionType, model, params]);
|
1753
|
+
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
1754
|
+
if (!schema?.options?.draftAndPublish) {
|
1755
|
+
return null;
|
1756
|
+
}
|
1757
|
+
const performPublish = async () => {
|
1758
|
+
setSubmitting(true);
|
1759
|
+
try {
|
1760
|
+
const { errors } = await validate();
|
1761
|
+
if (errors) {
|
1762
|
+
toggleNotification({
|
1763
|
+
type: "danger",
|
1764
|
+
message: formatMessage({
|
1765
|
+
id: "content-manager.validation.error",
|
1766
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
1767
|
+
})
|
1768
|
+
});
|
1769
|
+
return;
|
1770
|
+
}
|
1771
|
+
const res = await publish(
|
1772
|
+
{
|
1773
|
+
collectionType,
|
1774
|
+
model,
|
1775
|
+
documentId,
|
1776
|
+
params
|
1777
|
+
},
|
1778
|
+
formValues
|
1779
|
+
);
|
1780
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1781
|
+
navigate({
|
1782
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1783
|
+
search: rawQuery
|
1784
|
+
});
|
1785
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1786
|
+
setErrors(formatValidationErrors(res.error));
|
1787
|
+
}
|
1788
|
+
} finally {
|
1789
|
+
setSubmitting(false);
|
1790
|
+
}
|
1791
|
+
};
|
1792
|
+
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
1793
|
+
const hasDraftRelations = totalDraftRelations > 0;
|
1794
|
+
return {
|
1795
|
+
/**
|
1796
|
+
* Disabled when:
|
1797
|
+
* - currently if you're cloning a document we don't support publish & clone at the same time.
|
1798
|
+
* - the form is submitting
|
1799
|
+
* - the active tab is the published tab
|
1800
|
+
* - the document is already published & not modified
|
1801
|
+
* - the document is being created & not modified
|
1802
|
+
* - the user doesn't have the permission to publish
|
1648
1803
|
*/
|
1649
|
-
disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish
|
1804
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
1650
1805
|
label: formatMessage({
|
1651
1806
|
id: "app.utils.publish",
|
1652
1807
|
defaultMessage: "Publish"
|
1653
1808
|
}),
|
1654
1809
|
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));
|
1810
|
+
if (hasDraftRelations) {
|
1811
|
+
return;
|
1812
|
+
}
|
1813
|
+
await performPublish();
|
1814
|
+
},
|
1815
|
+
dialog: hasDraftRelations ? {
|
1816
|
+
type: "dialog",
|
1817
|
+
variant: "danger",
|
1818
|
+
footer: null,
|
1819
|
+
title: formatMessage({
|
1820
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
|
1821
|
+
defaultMessage: "Confirmation"
|
1822
|
+
}),
|
1823
|
+
content: formatMessage(
|
1824
|
+
{
|
1825
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
1826
|
+
defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
|
1827
|
+
},
|
1828
|
+
{
|
1829
|
+
count: totalDraftRelations
|
1684
1830
|
}
|
1685
|
-
|
1686
|
-
|
1831
|
+
),
|
1832
|
+
onConfirm: async () => {
|
1833
|
+
await performPublish();
|
1687
1834
|
}
|
1688
|
-
}
|
1835
|
+
} : void 0
|
1689
1836
|
};
|
1690
1837
|
};
|
1691
|
-
PublishAction.type = "publish";
|
1838
|
+
PublishAction$1.type = "publish";
|
1692
1839
|
const UpdateAction = ({
|
1693
1840
|
activeTab,
|
1694
1841
|
documentId,
|
@@ -1701,7 +1848,7 @@ const UpdateAction = ({
|
|
1701
1848
|
const cloneMatch = reactRouterDom.useMatch(CLONE_PATH);
|
1702
1849
|
const isCloning = cloneMatch !== null;
|
1703
1850
|
const { formatMessage } = reactIntl.useIntl();
|
1704
|
-
|
1851
|
+
useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1705
1852
|
canCreate: canCreate2,
|
1706
1853
|
canUpdate: canUpdate2
|
1707
1854
|
}));
|
@@ -1721,10 +1868,8 @@ const UpdateAction = ({
|
|
1721
1868
|
* - the form is submitting
|
1722
1869
|
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
1723
1870
|
* - the active tab is the published tab
|
1724
|
-
* - the user doesn't have the permission to create a new document
|
1725
|
-
* - the user doesn't have the permission to update the document
|
1726
1871
|
*/
|
1727
|
-
disabled: isSubmitting || !modified && !isCloning || activeTab === "published"
|
1872
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1728
1873
|
label: formatMessage({
|
1729
1874
|
id: "content-manager.containers.Edit.save",
|
1730
1875
|
defaultMessage: "Save"
|
@@ -1753,10 +1898,13 @@ const UpdateAction = ({
|
|
1753
1898
|
document
|
1754
1899
|
);
|
1755
1900
|
if ("data" in res) {
|
1756
|
-
navigate(
|
1757
|
-
|
1758
|
-
|
1759
|
-
|
1901
|
+
navigate(
|
1902
|
+
{
|
1903
|
+
pathname: `../${res.data.documentId}`,
|
1904
|
+
search: rawQuery
|
1905
|
+
},
|
1906
|
+
{ relative: "path" }
|
1907
|
+
);
|
1760
1908
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1761
1909
|
setErrors(formatValidationErrors(res.error));
|
1762
1910
|
}
|
@@ -1784,10 +1932,13 @@ const UpdateAction = ({
|
|
1784
1932
|
document
|
1785
1933
|
);
|
1786
1934
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1787
|
-
navigate(
|
1788
|
-
|
1789
|
-
|
1790
|
-
|
1935
|
+
navigate(
|
1936
|
+
{
|
1937
|
+
pathname: `../${res.data.documentId}`,
|
1938
|
+
search: rawQuery
|
1939
|
+
},
|
1940
|
+
{ replace: true, relative: "path" }
|
1941
|
+
);
|
1791
1942
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1792
1943
|
setErrors(formatValidationErrors(res.error));
|
1793
1944
|
}
|
@@ -1803,7 +1954,7 @@ const UNPUBLISH_DRAFT_OPTIONS = {
|
|
1803
1954
|
KEEP: "keep",
|
1804
1955
|
DISCARD: "discard"
|
1805
1956
|
};
|
1806
|
-
const UnpublishAction = ({
|
1957
|
+
const UnpublishAction$1 = ({
|
1807
1958
|
activeTab,
|
1808
1959
|
documentId,
|
1809
1960
|
model,
|
@@ -1819,10 +1970,8 @@ const UnpublishAction = ({
|
|
1819
1970
|
const { toggleNotification } = strapiAdmin.useNotification();
|
1820
1971
|
const [shouldKeepDraft, setShouldKeepDraft] = React__namespace.useState(true);
|
1821
1972
|
const isDocumentModified = document?.status === "modified";
|
1822
|
-
const handleChange = (
|
1823
|
-
|
1824
|
-
setShouldKeepDraft(e.target.value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1825
|
-
}
|
1973
|
+
const handleChange = (value) => {
|
1974
|
+
setShouldKeepDraft(value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1826
1975
|
};
|
1827
1976
|
if (!schema?.options?.draftAndPublish) {
|
1828
1977
|
return null;
|
@@ -1866,45 +2015,30 @@ const UnpublishAction = ({
|
|
1866
2015
|
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "flex-start", direction: "column", gap: 6, children: [
|
1867
2016
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", direction: "column", gap: 2, children: [
|
1868
2017
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
1869
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2018
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
1870
2019
|
id: "content-manager.actions.unpublish.dialog.body",
|
1871
2020
|
defaultMessage: "Are you sure?"
|
1872
2021
|
}) })
|
1873
2022
|
] }),
|
1874
2023
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
1875
|
-
designSystem.
|
2024
|
+
designSystem.Radio.Group,
|
1876
2025
|
{
|
1877
|
-
|
1878
|
-
|
1879
|
-
|
1880
|
-
|
1881
|
-
|
2026
|
+
defaultValue: UNPUBLISH_DRAFT_OPTIONS.KEEP,
|
2027
|
+
name: "discard-options",
|
2028
|
+
"aria-label": formatMessage({
|
2029
|
+
id: "content-manager.actions.unpublish.dialog.radio-label",
|
2030
|
+
defaultMessage: "Choose an option to unpublish the document."
|
2031
|
+
}),
|
2032
|
+
onValueChange: handleChange,
|
1882
2033
|
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
|
-
)
|
2034
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Radio.Item, { checked: shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.KEEP, children: formatMessage({
|
2035
|
+
id: "content-manager.actions.unpublish.dialog.option.keep-draft",
|
2036
|
+
defaultMessage: "Keep draft"
|
2037
|
+
}) }),
|
2038
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Radio.Item, { checked: !shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.DISCARD, children: formatMessage({
|
2039
|
+
id: "content-manager.actions.unpublish.dialog.option.replace-draft",
|
2040
|
+
defaultMessage: "Replace draft"
|
2041
|
+
}) })
|
1908
2042
|
]
|
1909
2043
|
}
|
1910
2044
|
)
|
@@ -1937,7 +2071,7 @@ const UnpublishAction = ({
|
|
1937
2071
|
position: ["panel", "table-row"]
|
1938
2072
|
};
|
1939
2073
|
};
|
1940
|
-
UnpublishAction.type = "unpublish";
|
2074
|
+
UnpublishAction$1.type = "unpublish";
|
1941
2075
|
const DiscardAction = ({
|
1942
2076
|
activeTab,
|
1943
2077
|
documentId,
|
@@ -1971,7 +2105,7 @@ const DiscardAction = ({
|
|
1971
2105
|
}),
|
1972
2106
|
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, children: [
|
1973
2107
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
1974
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2108
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
1975
2109
|
id: "content-manager.actions.discard.dialog.body",
|
1976
2110
|
defaultMessage: "Are you sure?"
|
1977
2111
|
}) })
|
@@ -1988,12 +2122,12 @@ const DiscardAction = ({
|
|
1988
2122
|
};
|
1989
2123
|
};
|
1990
2124
|
DiscardAction.type = "discard";
|
1991
|
-
const StyledCrossCircle =
|
2125
|
+
const StyledCrossCircle = styledComponents.styled(Icons.CrossCircle)`
|
1992
2126
|
path {
|
1993
2127
|
fill: currentColor;
|
1994
2128
|
}
|
1995
2129
|
`;
|
1996
|
-
const DEFAULT_ACTIONS = [PublishAction, UpdateAction, UnpublishAction, DiscardAction];
|
2130
|
+
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
1997
2131
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
1998
2132
|
const RelativeTime = React__namespace.forwardRef(
|
1999
2133
|
({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {
|
@@ -2041,7 +2175,7 @@ const getDisplayName = ({
|
|
2041
2175
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2042
2176
|
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2043
2177
|
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, {
|
2178
|
+
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
2179
|
};
|
2046
2180
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
2047
2181
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2050,23 +2184,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
|
2050
2184
|
id: "content-manager.containers.edit.title.new",
|
2051
2185
|
defaultMessage: "Create an entry"
|
2052
2186
|
}) : documentTitle;
|
2053
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop:
|
2187
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2054
2188
|
/* @__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
|
2189
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2190
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
|
2191
|
+
/* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
|
2192
|
+
] }),
|
2193
|
+
status ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 1, children: /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
|
2070
2194
|
] });
|
2071
2195
|
};
|
2072
2196
|
const HeaderToolbar = () => {
|
@@ -2218,7 +2342,7 @@ const Information = ({ activeTab }) => {
|
|
2218
2342
|
borderColor: "neutral150",
|
2219
2343
|
direction: "column",
|
2220
2344
|
marginTop: 2,
|
2221
|
-
|
2345
|
+
tag: "dl",
|
2222
2346
|
padding: 5,
|
2223
2347
|
gap: 3,
|
2224
2348
|
alignItems: "flex-start",
|
@@ -2226,8 +2350,8 @@ const Information = ({ activeTab }) => {
|
|
2226
2350
|
marginRight: "-0.4rem",
|
2227
2351
|
width: "calc(100% + 8px)",
|
2228
2352
|
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, {
|
2353
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "dt", variant: "pi", fontWeight: "bold", children: info.label }),
|
2354
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "dd", variant: "pi", textColor: "neutral600", children: info.value })
|
2231
2355
|
] }, info.label))
|
2232
2356
|
}
|
2233
2357
|
);
|
@@ -2260,7 +2384,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2260
2384
|
id: "app.links.configure-view",
|
2261
2385
|
defaultMessage: "Configure the view"
|
2262
2386
|
}),
|
2263
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2387
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ListPlus, {}),
|
2264
2388
|
onClick: () => {
|
2265
2389
|
navigate(`../${collectionType}/${model}/configurations/edit`);
|
2266
2390
|
},
|
@@ -2268,11 +2392,6 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2268
2392
|
};
|
2269
2393
|
};
|
2270
2394
|
ConfigureTheViewAction.type = "configure-the-view";
|
2271
|
-
const StyledCog = styled__default.default(Icons.Cog)`
|
2272
|
-
path {
|
2273
|
-
fill: currentColor;
|
2274
|
-
}
|
2275
|
-
`;
|
2276
2395
|
const EditTheModelAction = ({ model }) => {
|
2277
2396
|
const navigate = reactRouterDom.useNavigate();
|
2278
2397
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2281,7 +2400,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2281
2400
|
id: "content-manager.link-to-ctb",
|
2282
2401
|
defaultMessage: "Edit the model"
|
2283
2402
|
}),
|
2284
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2403
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, {}),
|
2285
2404
|
onClick: () => {
|
2286
2405
|
navigate(`/plugins/content-type-builder/content-types/${model}`);
|
2287
2406
|
},
|
@@ -2289,12 +2408,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2289
2408
|
};
|
2290
2409
|
};
|
2291
2410
|
EditTheModelAction.type = "edit-the-model";
|
2292
|
-
const
|
2293
|
-
path {
|
2294
|
-
fill: currentColor;
|
2295
|
-
}
|
2296
|
-
`;
|
2297
|
-
const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
2411
|
+
const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
2298
2412
|
const navigate = reactRouterDom.useNavigate();
|
2299
2413
|
const { formatMessage } = reactIntl.useIntl();
|
2300
2414
|
const listViewPathMatch = reactRouterDom.useMatch(LIST_PATH);
|
@@ -2308,7 +2422,7 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
|
2308
2422
|
id: "content-manager.actions.delete.label",
|
2309
2423
|
defaultMessage: "Delete document"
|
2310
2424
|
}),
|
2311
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2425
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {}),
|
2312
2426
|
dialog: {
|
2313
2427
|
type: "dialog",
|
2314
2428
|
title: formatMessage({
|
@@ -2317,7 +2431,7 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
|
2317
2431
|
}),
|
2318
2432
|
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, children: [
|
2319
2433
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
2320
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2434
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
2321
2435
|
id: "content-manager.actions.delete.dialog.body",
|
2322
2436
|
defaultMessage: "Are you sure?"
|
2323
2437
|
}) })
|
@@ -2362,13 +2476,8 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
|
2362
2476
|
position: ["header", "table-row"]
|
2363
2477
|
};
|
2364
2478
|
};
|
2365
|
-
DeleteAction.type = "delete";
|
2366
|
-
const
|
2367
|
-
path {
|
2368
|
-
fill: currentColor;
|
2369
|
-
}
|
2370
|
-
`;
|
2371
|
-
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction];
|
2479
|
+
DeleteAction$1.type = "delete";
|
2480
|
+
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2372
2481
|
const Panels = () => {
|
2373
2482
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2374
2483
|
const [
|
@@ -2442,7 +2551,7 @@ const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
|
2442
2551
|
designSystem.Flex,
|
2443
2552
|
{
|
2444
2553
|
ref,
|
2445
|
-
|
2554
|
+
tag: "aside",
|
2446
2555
|
"aria-labelledby": "additional-information",
|
2447
2556
|
background: "neutral0",
|
2448
2557
|
borderColor: "neutral150",
|
@@ -2457,118 +2566,997 @@ const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
|
2457
2566
|
justifyContent: "stretch",
|
2458
2567
|
alignItems: "flex-start",
|
2459
2568
|
children: [
|
2460
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2569
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2461
2570
|
children
|
2462
2571
|
]
|
2463
2572
|
}
|
2464
2573
|
);
|
2465
2574
|
});
|
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
|
-
);
|
2575
|
+
const HOOKS = {
|
2576
|
+
/**
|
2577
|
+
* Hook that allows to mutate the displayed headers of the list view table
|
2578
|
+
* @constant
|
2579
|
+
* @type {string}
|
2580
|
+
*/
|
2581
|
+
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2582
|
+
/**
|
2583
|
+
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2584
|
+
* @constant
|
2585
|
+
* @type {string}
|
2586
|
+
*/
|
2587
|
+
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2588
|
+
/**
|
2589
|
+
* Hook that allows to mutate the CM's edit view layout
|
2590
|
+
* @constant
|
2591
|
+
* @type {string}
|
2592
|
+
*/
|
2593
|
+
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2594
|
+
/**
|
2595
|
+
* Hook that allows to mutate the CM's single types links pre-set filters
|
2596
|
+
* @constant
|
2597
|
+
* @type {string}
|
2598
|
+
*/
|
2599
|
+
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2555
2600
|
};
|
2556
|
-
const
|
2557
|
-
|
2558
|
-
|
2559
|
-
|
2560
|
-
|
2561
|
-
|
2562
|
-
|
2563
|
-
|
2564
|
-
|
2565
|
-
|
2566
|
-
|
2567
|
-
|
2568
|
-
}),
|
2569
|
-
|
2570
|
-
|
2571
|
-
|
2601
|
+
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2602
|
+
endpoints: (builder) => ({
|
2603
|
+
getContentTypeConfiguration: builder.query({
|
2604
|
+
query: (uid) => ({
|
2605
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
2606
|
+
method: "GET"
|
2607
|
+
}),
|
2608
|
+
transformResponse: (response) => response.data,
|
2609
|
+
providesTags: (_result, _error, uid) => [
|
2610
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
2611
|
+
{ type: "ContentTypeSettings", id: "LIST" }
|
2612
|
+
]
|
2613
|
+
}),
|
2614
|
+
getAllContentTypeSettings: builder.query({
|
2615
|
+
query: () => "/content-manager/content-types-settings",
|
2616
|
+
transformResponse: (response) => response.data,
|
2617
|
+
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2618
|
+
}),
|
2619
|
+
updateContentTypeConfiguration: builder.mutation({
|
2620
|
+
query: ({ uid, ...body }) => ({
|
2621
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
2622
|
+
method: "PUT",
|
2623
|
+
data: body
|
2624
|
+
}),
|
2625
|
+
transformResponse: (response) => response.data,
|
2626
|
+
invalidatesTags: (_result, _error, { uid }) => [
|
2627
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
2628
|
+
{ type: "ContentTypeSettings", id: "LIST" },
|
2629
|
+
// Is this necessary?
|
2630
|
+
{ type: "InitialData" }
|
2631
|
+
]
|
2632
|
+
})
|
2633
|
+
})
|
2634
|
+
});
|
2635
|
+
const {
|
2636
|
+
useGetContentTypeConfigurationQuery,
|
2637
|
+
useGetAllContentTypeSettingsQuery,
|
2638
|
+
useUpdateContentTypeConfigurationMutation
|
2639
|
+
} = contentTypesApi;
|
2640
|
+
const checkIfAttributeIsDisplayable = (attribute) => {
|
2641
|
+
const { type } = attribute;
|
2642
|
+
if (type === "relation") {
|
2643
|
+
return !attribute.relation.toLowerCase().includes("morph");
|
2644
|
+
}
|
2645
|
+
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2646
|
+
};
|
2647
|
+
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2648
|
+
if (!mainFieldName) {
|
2649
|
+
return void 0;
|
2650
|
+
}
|
2651
|
+
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2652
|
+
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2653
|
+
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2654
|
+
);
|
2655
|
+
return {
|
2656
|
+
name: mainFieldName,
|
2657
|
+
type: mainFieldType ?? "string"
|
2658
|
+
};
|
2659
|
+
};
|
2660
|
+
const DEFAULT_SETTINGS = {
|
2661
|
+
bulkable: false,
|
2662
|
+
filterable: false,
|
2663
|
+
searchable: false,
|
2664
|
+
pagination: false,
|
2665
|
+
defaultSortBy: "",
|
2666
|
+
defaultSortOrder: "asc",
|
2667
|
+
mainField: "id",
|
2668
|
+
pageSize: 10
|
2669
|
+
};
|
2670
|
+
const useDocumentLayout = (model) => {
|
2671
|
+
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2672
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
2673
|
+
const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2674
|
+
const { toggleNotification } = strapiAdmin.useNotification();
|
2675
|
+
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
2676
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2677
|
+
const {
|
2678
|
+
data,
|
2679
|
+
isLoading: isLoadingConfigs,
|
2680
|
+
error,
|
2681
|
+
isFetching: isFetchingConfigs
|
2682
|
+
} = useGetContentTypeConfigurationQuery(model);
|
2683
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2684
|
+
React__namespace.useEffect(() => {
|
2685
|
+
if (error) {
|
2686
|
+
toggleNotification({
|
2687
|
+
type: "danger",
|
2688
|
+
message: formatAPIError(error)
|
2689
|
+
});
|
2690
|
+
}
|
2691
|
+
}, [error, formatAPIError, toggleNotification]);
|
2692
|
+
const editLayout = React__namespace.useMemo(
|
2693
|
+
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2694
|
+
layout: [],
|
2695
|
+
components: {},
|
2696
|
+
metadatas: {},
|
2697
|
+
options: {},
|
2698
|
+
settings: DEFAULT_SETTINGS
|
2699
|
+
},
|
2700
|
+
[data, isLoading, schemas, schema, components]
|
2701
|
+
);
|
2702
|
+
const listLayout = React__namespace.useMemo(() => {
|
2703
|
+
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2704
|
+
layout: [],
|
2705
|
+
metadatas: {},
|
2706
|
+
options: {},
|
2707
|
+
settings: DEFAULT_SETTINGS
|
2708
|
+
};
|
2709
|
+
}, [data, isLoading, schemas, schema, components]);
|
2710
|
+
const { layout: edit } = React__namespace.useMemo(
|
2711
|
+
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2712
|
+
layout: editLayout,
|
2713
|
+
query
|
2714
|
+
}),
|
2715
|
+
[editLayout, query, runHookWaterfall]
|
2716
|
+
);
|
2717
|
+
return {
|
2718
|
+
error,
|
2719
|
+
isLoading,
|
2720
|
+
edit,
|
2721
|
+
list: listLayout
|
2722
|
+
};
|
2723
|
+
};
|
2724
|
+
const useDocLayout = () => {
|
2725
|
+
const { model } = useDoc();
|
2726
|
+
return useDocumentLayout(model);
|
2727
|
+
};
|
2728
|
+
const formatEditLayout = (data, {
|
2729
|
+
schemas,
|
2730
|
+
schema,
|
2731
|
+
components
|
2732
|
+
}) => {
|
2733
|
+
let currentPanelIndex = 0;
|
2734
|
+
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2735
|
+
data.contentType.layouts.edit,
|
2736
|
+
schema?.attributes,
|
2737
|
+
data.contentType.metadatas,
|
2738
|
+
{ configurations: data.components, schemas: components },
|
2739
|
+
schemas
|
2740
|
+
).reduce((panels, row) => {
|
2741
|
+
if (row.some((field) => field.type === "dynamiczone")) {
|
2742
|
+
panels.push([row]);
|
2743
|
+
currentPanelIndex += 2;
|
2744
|
+
} else {
|
2745
|
+
if (!panels[currentPanelIndex]) {
|
2746
|
+
panels.push([]);
|
2747
|
+
}
|
2748
|
+
panels[currentPanelIndex].push(row);
|
2749
|
+
}
|
2750
|
+
return panels;
|
2751
|
+
}, []);
|
2752
|
+
const componentEditAttributes = Object.entries(data.components).reduce(
|
2753
|
+
(acc, [uid, configuration]) => {
|
2754
|
+
acc[uid] = {
|
2755
|
+
layout: convertEditLayoutToFieldLayouts(
|
2756
|
+
configuration.layouts.edit,
|
2757
|
+
components[uid].attributes,
|
2758
|
+
configuration.metadatas
|
2759
|
+
),
|
2760
|
+
settings: {
|
2761
|
+
...configuration.settings,
|
2762
|
+
icon: components[uid].info.icon,
|
2763
|
+
displayName: components[uid].info.displayName
|
2764
|
+
}
|
2765
|
+
};
|
2766
|
+
return acc;
|
2767
|
+
},
|
2768
|
+
{}
|
2769
|
+
);
|
2770
|
+
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2771
|
+
(acc, [attribute, metadata]) => {
|
2772
|
+
return {
|
2773
|
+
...acc,
|
2774
|
+
[attribute]: metadata.edit
|
2775
|
+
};
|
2776
|
+
},
|
2777
|
+
{}
|
2778
|
+
);
|
2779
|
+
return {
|
2780
|
+
layout: panelledEditAttributes,
|
2781
|
+
components: componentEditAttributes,
|
2782
|
+
metadatas: editMetadatas,
|
2783
|
+
settings: {
|
2784
|
+
...data.contentType.settings,
|
2785
|
+
displayName: schema?.info.displayName
|
2786
|
+
},
|
2787
|
+
options: {
|
2788
|
+
...schema?.options,
|
2789
|
+
...schema?.pluginOptions,
|
2790
|
+
...data.contentType.options
|
2791
|
+
}
|
2792
|
+
};
|
2793
|
+
};
|
2794
|
+
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
2795
|
+
return rows.map(
|
2796
|
+
(row) => row.map((field) => {
|
2797
|
+
const attribute = attributes[field.name];
|
2798
|
+
if (!attribute) {
|
2799
|
+
return null;
|
2800
|
+
}
|
2801
|
+
const { edit: metadata } = metadatas[field.name];
|
2802
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
2803
|
+
return {
|
2804
|
+
attribute,
|
2805
|
+
disabled: !metadata.editable,
|
2806
|
+
hint: metadata.description,
|
2807
|
+
label: metadata.label ?? "",
|
2808
|
+
name: field.name,
|
2809
|
+
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
2810
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
2811
|
+
schemas,
|
2812
|
+
components: components?.schemas ?? {}
|
2813
|
+
}),
|
2814
|
+
placeholder: metadata.placeholder ?? "",
|
2815
|
+
required: attribute.required ?? false,
|
2816
|
+
size: field.size,
|
2817
|
+
unique: "unique" in attribute ? attribute.unique : false,
|
2818
|
+
visible: metadata.visible ?? true,
|
2819
|
+
type: attribute.type
|
2820
|
+
};
|
2821
|
+
}).filter((field) => field !== null)
|
2822
|
+
);
|
2823
|
+
};
|
2824
|
+
const formatListLayout = (data, {
|
2825
|
+
schemas,
|
2826
|
+
schema,
|
2827
|
+
components
|
2828
|
+
}) => {
|
2829
|
+
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2830
|
+
(acc, [attribute, metadata]) => {
|
2831
|
+
return {
|
2832
|
+
...acc,
|
2833
|
+
[attribute]: metadata.list
|
2834
|
+
};
|
2835
|
+
},
|
2836
|
+
{}
|
2837
|
+
);
|
2838
|
+
const listAttributes = convertListLayoutToFieldLayouts(
|
2839
|
+
data.contentType.layouts.list,
|
2840
|
+
schema?.attributes,
|
2841
|
+
listMetadatas,
|
2842
|
+
{ configurations: data.components, schemas: components },
|
2843
|
+
schemas
|
2844
|
+
);
|
2845
|
+
return {
|
2846
|
+
layout: listAttributes,
|
2847
|
+
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
2848
|
+
metadatas: listMetadatas,
|
2849
|
+
options: {
|
2850
|
+
...schema?.options,
|
2851
|
+
...schema?.pluginOptions,
|
2852
|
+
...data.contentType.options
|
2853
|
+
}
|
2854
|
+
};
|
2855
|
+
};
|
2856
|
+
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
2857
|
+
return columns.map((name) => {
|
2858
|
+
const attribute = attributes[name];
|
2859
|
+
if (!attribute) {
|
2860
|
+
return null;
|
2861
|
+
}
|
2862
|
+
const metadata = metadatas[name];
|
2863
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
2864
|
+
return {
|
2865
|
+
attribute,
|
2866
|
+
label: metadata.label ?? "",
|
2867
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
2868
|
+
schemas,
|
2869
|
+
components: components?.schemas ?? {}
|
2870
|
+
}),
|
2871
|
+
name,
|
2872
|
+
searchable: metadata.searchable ?? true,
|
2873
|
+
sortable: metadata.sortable ?? true
|
2874
|
+
};
|
2875
|
+
}).filter((field) => field !== null);
|
2876
|
+
};
|
2877
|
+
const ConfirmBulkActionDialog = ({
|
2878
|
+
onToggleDialog,
|
2879
|
+
isOpen = false,
|
2880
|
+
dialogBody,
|
2881
|
+
endAction
|
2882
|
+
}) => {
|
2883
|
+
const { formatMessage } = reactIntl.useIntl();
|
2884
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
2885
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: formatMessage({
|
2886
|
+
id: "app.components.ConfirmDialog.title",
|
2887
|
+
defaultMessage: "Confirmation"
|
2888
|
+
}) }),
|
2889
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
2890
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
2891
|
+
dialogBody
|
2892
|
+
] }) }),
|
2893
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
|
2894
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { fullWidth: true, onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
|
2895
|
+
id: "app.components.Button.cancel",
|
2896
|
+
defaultMessage: "Cancel"
|
2897
|
+
}) }) }),
|
2898
|
+
endAction
|
2899
|
+
] })
|
2900
|
+
] }) });
|
2901
|
+
};
|
2902
|
+
const BoldChunk$1 = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
|
2903
|
+
const ConfirmDialogPublishAll = ({
|
2904
|
+
isOpen,
|
2905
|
+
onToggleDialog,
|
2906
|
+
isConfirmButtonLoading = false,
|
2907
|
+
onConfirm
|
2908
|
+
}) => {
|
2909
|
+
const { formatMessage } = reactIntl.useIntl();
|
2910
|
+
const selectedEntries = strapiAdmin.useTable("ConfirmDialogPublishAll", (state) => state.selectedRows);
|
2911
|
+
const { toggleNotification } = strapiAdmin.useNotification();
|
2912
|
+
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler(getTranslation);
|
2913
|
+
const { model, schema } = useDoc();
|
2914
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
2915
|
+
const {
|
2916
|
+
data: countDraftRelations = 0,
|
2917
|
+
isLoading,
|
2918
|
+
error
|
2919
|
+
} = useGetManyDraftRelationCountQuery(
|
2920
|
+
{
|
2921
|
+
model,
|
2922
|
+
documentIds: selectedEntries.map((entry) => entry.documentId),
|
2923
|
+
locale: query?.plugins?.i18n?.locale
|
2924
|
+
},
|
2925
|
+
{
|
2926
|
+
skip: selectedEntries.length === 0
|
2927
|
+
}
|
2928
|
+
);
|
2929
|
+
React__namespace.useEffect(() => {
|
2930
|
+
if (error) {
|
2931
|
+
toggleNotification({ type: "danger", message: formatAPIError(error) });
|
2932
|
+
}
|
2933
|
+
}, [error, formatAPIError, toggleNotification]);
|
2934
|
+
if (error) {
|
2935
|
+
return null;
|
2936
|
+
}
|
2937
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
2938
|
+
ConfirmBulkActionDialog,
|
2939
|
+
{
|
2940
|
+
isOpen: isOpen && !isLoading,
|
2941
|
+
onToggleDialog,
|
2942
|
+
dialogBody: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
2943
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: [
|
2944
|
+
countDraftRelations > 0 && formatMessage(
|
2945
|
+
{
|
2946
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
2947
|
+
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. "
|
2948
|
+
},
|
2949
|
+
{
|
2950
|
+
b: BoldChunk$1,
|
2951
|
+
count: countDraftRelations,
|
2952
|
+
entities: selectedEntries.length
|
2953
|
+
}
|
2954
|
+
),
|
2955
|
+
formatMessage({
|
2956
|
+
id: getTranslation("popUpWarning.bodyMessage.contentType.publish.all"),
|
2957
|
+
defaultMessage: "Are you sure you want to publish these entries?"
|
2958
|
+
})
|
2959
|
+
] }),
|
2960
|
+
schema?.pluginOptions && "i18n" in schema.pluginOptions && schema?.pluginOptions.i18n && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", textAlign: "center", children: formatMessage(
|
2961
|
+
{
|
2962
|
+
id: getTranslation("Settings.list.actions.publishAdditionalInfos"),
|
2963
|
+
defaultMessage: "This will publish the active locale versions <em>(from Internationalization)</em>"
|
2964
|
+
},
|
2965
|
+
{
|
2966
|
+
em: Emphasis
|
2967
|
+
}
|
2968
|
+
) })
|
2969
|
+
] }),
|
2970
|
+
endAction: /* @__PURE__ */ jsxRuntime.jsx(
|
2971
|
+
designSystem.Button,
|
2972
|
+
{
|
2973
|
+
onClick: onConfirm,
|
2974
|
+
variant: "secondary",
|
2975
|
+
startIcon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Check, {}),
|
2976
|
+
loading: isConfirmButtonLoading,
|
2977
|
+
children: formatMessage({
|
2978
|
+
id: "app.utils.publish",
|
2979
|
+
defaultMessage: "Publish"
|
2980
|
+
})
|
2981
|
+
}
|
2982
|
+
)
|
2983
|
+
}
|
2984
|
+
);
|
2985
|
+
};
|
2986
|
+
const TypographyMaxWidth = styledComponents.styled(designSystem.Typography)`
|
2987
|
+
max-width: 300px;
|
2988
|
+
`;
|
2989
|
+
const formatErrorMessages = (errors, parentKey, formatMessage) => {
|
2990
|
+
const messages = [];
|
2991
|
+
Object.entries(errors).forEach(([key, value]) => {
|
2992
|
+
const currentKey = parentKey ? `${parentKey}.${key}` : key;
|
2993
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
2994
|
+
if ("id" in value && "defaultMessage" in value) {
|
2995
|
+
messages.push(
|
2996
|
+
formatMessage(
|
2997
|
+
{
|
2998
|
+
id: `${value.id}.withField`,
|
2999
|
+
defaultMessage: value.defaultMessage
|
3000
|
+
},
|
3001
|
+
{ field: currentKey }
|
3002
|
+
)
|
3003
|
+
);
|
3004
|
+
} else {
|
3005
|
+
messages.push(
|
3006
|
+
...formatErrorMessages(
|
3007
|
+
// @ts-expect-error TODO: check why value is not compatible with FormErrors
|
3008
|
+
value,
|
3009
|
+
currentKey,
|
3010
|
+
formatMessage
|
3011
|
+
)
|
3012
|
+
);
|
3013
|
+
}
|
3014
|
+
} else {
|
3015
|
+
messages.push(
|
3016
|
+
formatMessage(
|
3017
|
+
{
|
3018
|
+
id: `${value}.withField`,
|
3019
|
+
defaultMessage: value
|
3020
|
+
},
|
3021
|
+
{ field: currentKey }
|
3022
|
+
)
|
3023
|
+
);
|
3024
|
+
}
|
3025
|
+
});
|
3026
|
+
return messages;
|
3027
|
+
};
|
3028
|
+
const EntryValidationText = ({ validationErrors, status }) => {
|
3029
|
+
const { formatMessage } = reactIntl.useIntl();
|
3030
|
+
if (validationErrors) {
|
3031
|
+
const validationErrorsMessages = formatErrorMessages(validationErrors, "", formatMessage).join(
|
3032
|
+
" "
|
3033
|
+
);
|
3034
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3035
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.CrossCircle, { fill: "danger600" }),
|
3036
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsxRuntime.jsx(TypographyMaxWidth, { textColor: "danger600", variant: "omega", fontWeight: "semiBold", ellipsis: true, children: validationErrorsMessages }) })
|
3037
|
+
] });
|
3038
|
+
}
|
3039
|
+
if (status === "published") {
|
3040
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3041
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.CheckCircle, { fill: "success600" }),
|
3042
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
|
3043
|
+
id: "content-manager.bulk-publish.already-published",
|
3044
|
+
defaultMessage: "Already Published"
|
3045
|
+
}) })
|
3046
|
+
] });
|
3047
|
+
}
|
3048
|
+
if (status === "modified") {
|
3049
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3050
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.ArrowsCounterClockwise, { fill: "alternative600" }),
|
3051
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
|
3052
|
+
id: "content-manager.bulk-publish.modified",
|
3053
|
+
defaultMessage: "Ready to publish changes"
|
3054
|
+
}) })
|
3055
|
+
] });
|
3056
|
+
}
|
3057
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3058
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.CheckCircle, { fill: "success600" }),
|
3059
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
|
3060
|
+
id: "app.utils.ready-to-publish",
|
3061
|
+
defaultMessage: "Ready to publish"
|
3062
|
+
}) })
|
3063
|
+
] });
|
3064
|
+
};
|
3065
|
+
const TABLE_HEADERS = [
|
3066
|
+
{ name: "id", label: "id" },
|
3067
|
+
{ name: "name", label: "name" },
|
3068
|
+
{ name: "status", label: "status" },
|
3069
|
+
{ name: "publicationStatus", label: "Publication status" }
|
3070
|
+
];
|
3071
|
+
const SelectedEntriesTableContent = ({
|
3072
|
+
isPublishing,
|
3073
|
+
rowsToDisplay = [],
|
3074
|
+
entriesToPublish = [],
|
3075
|
+
validationErrors = {}
|
3076
|
+
}) => {
|
3077
|
+
const { pathname } = reactRouterDom.useLocation();
|
3078
|
+
const { formatMessage } = reactIntl.useIntl();
|
3079
|
+
const {
|
3080
|
+
list: {
|
3081
|
+
settings: { mainField }
|
3082
|
+
}
|
3083
|
+
} = useDocLayout();
|
3084
|
+
const shouldDisplayMainField = mainField != null && mainField !== "id";
|
3085
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Content, { children: [
|
3086
|
+
/* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Head, { children: [
|
3087
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.HeaderCheckboxCell, {}),
|
3088
|
+
TABLE_HEADERS.filter((head) => head.name !== "name" || shouldDisplayMainField).map(
|
3089
|
+
(head) => /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.HeaderCell, { ...head }, head.name)
|
3090
|
+
)
|
3091
|
+
] }),
|
3092
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Loading, {}),
|
3093
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Body, { children: rowsToDisplay.map((row, index2) => /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Row, { children: [
|
3094
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.CheckboxCell, { id: row.id }),
|
3095
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: row.id }) }),
|
3096
|
+
shouldDisplayMainField && /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: row[mainField] }) }),
|
3097
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: row.status, maxWidth: "min-content" }) }),
|
3098
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: isPublishing && entriesToPublish.includes(row.documentId) ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3099
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
|
3100
|
+
id: "content-manager.success.record.publishing",
|
3101
|
+
defaultMessage: "Publishing..."
|
3102
|
+
}) }),
|
3103
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, { small: true })
|
3104
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx(
|
3105
|
+
EntryValidationText,
|
3106
|
+
{
|
3107
|
+
validationErrors: validationErrors[row.documentId],
|
3108
|
+
status: row.status
|
3109
|
+
}
|
3110
|
+
) }),
|
3111
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
3112
|
+
designSystem.IconButton,
|
3113
|
+
{
|
3114
|
+
tag: reactRouterDom.Link,
|
3115
|
+
to: {
|
3116
|
+
pathname: `${pathname}/${row.documentId}`,
|
3117
|
+
search: row.locale && `?plugins[i18n][locale]=${row.locale}`
|
3118
|
+
},
|
3119
|
+
state: { from: pathname },
|
3120
|
+
label: formatMessage(
|
3121
|
+
{ id: "app.component.HelperPluginTable.edit", defaultMessage: "Edit {target}" },
|
3122
|
+
{
|
3123
|
+
target: formatMessage(
|
3124
|
+
{
|
3125
|
+
id: "content-manager.components.ListViewHelperPluginTable.row-line",
|
3126
|
+
defaultMessage: "item line {number}"
|
3127
|
+
},
|
3128
|
+
{ number: index2 + 1 }
|
3129
|
+
)
|
3130
|
+
}
|
3131
|
+
),
|
3132
|
+
target: "_blank",
|
3133
|
+
marginLeft: "auto",
|
3134
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, {})
|
3135
|
+
}
|
3136
|
+
) })
|
3137
|
+
] }, row.id)) })
|
3138
|
+
] });
|
3139
|
+
};
|
3140
|
+
const BoldChunk = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
|
3141
|
+
const SelectedEntriesModalContent = ({
|
3142
|
+
listViewSelectedEntries,
|
3143
|
+
toggleModal,
|
3144
|
+
setListViewSelectedDocuments,
|
3145
|
+
model
|
3146
|
+
}) => {
|
3147
|
+
const { formatMessage } = reactIntl.useIntl();
|
3148
|
+
const { schema, components } = useContentTypeSchema(model);
|
3149
|
+
const documentIds = listViewSelectedEntries.map(({ documentId }) => documentId);
|
3150
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3151
|
+
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
3152
|
+
const { data, isLoading, isFetching, refetch } = useGetAllDocumentsQuery(
|
3153
|
+
{
|
3154
|
+
model,
|
3155
|
+
params: {
|
3156
|
+
page: "1",
|
3157
|
+
pageSize: documentIds.length.toString(),
|
3158
|
+
sort: query.sort,
|
3159
|
+
filters: {
|
3160
|
+
documentId: {
|
3161
|
+
$in: documentIds
|
3162
|
+
}
|
3163
|
+
},
|
3164
|
+
locale: query.plugins?.i18n?.locale
|
3165
|
+
}
|
3166
|
+
},
|
3167
|
+
{
|
3168
|
+
selectFromResult: ({ data: data2, ...restRes }) => ({ data: data2?.results ?? [], ...restRes })
|
3169
|
+
}
|
3170
|
+
);
|
3171
|
+
const { rows, validationErrors } = React__namespace.useMemo(() => {
|
3172
|
+
if (data.length > 0 && schema) {
|
3173
|
+
const validate = createYupSchema(schema.attributes, components);
|
3174
|
+
const validationErrors2 = {};
|
3175
|
+
const rows2 = data.map((entry) => {
|
3176
|
+
try {
|
3177
|
+
validate.validateSync(entry, { abortEarly: false });
|
3178
|
+
return entry;
|
3179
|
+
} catch (e) {
|
3180
|
+
if (e instanceof yup.ValidationError) {
|
3181
|
+
validationErrors2[entry.documentId] = strapiAdmin.getYupValidationErrors(e);
|
3182
|
+
}
|
3183
|
+
return entry;
|
3184
|
+
}
|
3185
|
+
});
|
3186
|
+
return { rows: rows2, validationErrors: validationErrors2 };
|
3187
|
+
}
|
3188
|
+
return {
|
3189
|
+
rows: [],
|
3190
|
+
validationErrors: {}
|
3191
|
+
};
|
3192
|
+
}, [components, data, schema]);
|
3193
|
+
const [publishedCount, setPublishedCount] = React__namespace.useState(0);
|
3194
|
+
const [isDialogOpen, setIsDialogOpen] = React__namespace.useState(false);
|
3195
|
+
const { publishMany: bulkPublishAction } = useDocumentActions();
|
3196
|
+
const [, { isLoading: isSubmittingForm }] = usePublishManyDocumentsMutation();
|
3197
|
+
const selectedRows = strapiAdmin.useTable("publishAction", (state) => state.selectedRows);
|
3198
|
+
const selectedEntries = rows.filter(
|
3199
|
+
(entry) => selectedRows.some((selectedEntry) => selectedEntry.documentId === entry.documentId)
|
3200
|
+
);
|
3201
|
+
const entriesToPublish = selectedEntries.filter((entry) => !validationErrors[entry.documentId]).map((entry) => entry.documentId);
|
3202
|
+
const selectedEntriesWithErrorsCount = selectedEntries.filter(
|
3203
|
+
({ documentId }) => validationErrors[documentId]
|
3204
|
+
).length;
|
3205
|
+
const selectedEntriesPublished = selectedEntries.filter(
|
3206
|
+
({ status }) => status === "published"
|
3207
|
+
).length;
|
3208
|
+
const selectedEntriesWithNoErrorsCount = selectedEntries.length - selectedEntriesWithErrorsCount - selectedEntriesPublished;
|
3209
|
+
const toggleDialog = () => setIsDialogOpen((prev) => !prev);
|
3210
|
+
const handleConfirmBulkPublish = async () => {
|
3211
|
+
toggleDialog();
|
3212
|
+
const res = await bulkPublishAction({ model, documentIds: entriesToPublish, params });
|
3213
|
+
if (!("error" in res)) {
|
3214
|
+
setPublishedCount(res.count);
|
3215
|
+
const unpublishedEntries = rows.filter((row) => {
|
3216
|
+
return !entriesToPublish.includes(row.documentId);
|
3217
|
+
});
|
3218
|
+
setListViewSelectedDocuments(unpublishedEntries);
|
3219
|
+
}
|
3220
|
+
};
|
3221
|
+
const getFormattedCountMessage = () => {
|
3222
|
+
if (publishedCount) {
|
3223
|
+
return formatMessage(
|
3224
|
+
{
|
3225
|
+
id: getTranslation("containers.list.selectedEntriesModal.publishedCount"),
|
3226
|
+
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."
|
3227
|
+
},
|
3228
|
+
{
|
3229
|
+
publishedCount,
|
3230
|
+
withErrorsCount: selectedEntriesWithErrorsCount,
|
3231
|
+
b: BoldChunk
|
3232
|
+
}
|
3233
|
+
);
|
3234
|
+
}
|
3235
|
+
return formatMessage(
|
3236
|
+
{
|
3237
|
+
id: getTranslation("containers.list.selectedEntriesModal.selectedCount"),
|
3238
|
+
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."
|
3239
|
+
},
|
3240
|
+
{
|
3241
|
+
readyToPublishCount: selectedEntriesWithNoErrorsCount,
|
3242
|
+
withErrorsCount: selectedEntriesWithErrorsCount,
|
3243
|
+
alreadyPublishedCount: selectedEntriesPublished,
|
3244
|
+
b: BoldChunk
|
3245
|
+
}
|
3246
|
+
);
|
3247
|
+
};
|
3248
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
3249
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Body, { children: [
|
3250
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: getFormattedCountMessage() }),
|
3251
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 5, children: /* @__PURE__ */ jsxRuntime.jsx(
|
3252
|
+
SelectedEntriesTableContent,
|
3253
|
+
{
|
3254
|
+
isPublishing: isSubmittingForm,
|
3255
|
+
rowsToDisplay: rows,
|
3256
|
+
entriesToPublish,
|
3257
|
+
validationErrors
|
3258
|
+
}
|
3259
|
+
) })
|
3260
|
+
] }),
|
3261
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
3262
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
|
3263
|
+
id: "app.components.Button.cancel",
|
3264
|
+
defaultMessage: "Cancel"
|
3265
|
+
}) }),
|
3266
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3267
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
|
3268
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
3269
|
+
designSystem.Button,
|
3270
|
+
{
|
3271
|
+
onClick: toggleDialog,
|
3272
|
+
disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
|
3273
|
+
loading: isSubmittingForm,
|
3274
|
+
children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
|
3275
|
+
}
|
3276
|
+
)
|
3277
|
+
] })
|
3278
|
+
] }),
|
3279
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
3280
|
+
ConfirmDialogPublishAll,
|
3281
|
+
{
|
3282
|
+
isOpen: isDialogOpen,
|
3283
|
+
onToggleDialog: toggleDialog,
|
3284
|
+
isConfirmButtonLoading: isSubmittingForm,
|
3285
|
+
onConfirm: handleConfirmBulkPublish
|
3286
|
+
}
|
3287
|
+
)
|
3288
|
+
] });
|
3289
|
+
};
|
3290
|
+
const PublishAction = ({ documents, model }) => {
|
3291
|
+
const { formatMessage } = reactIntl.useIntl();
|
3292
|
+
const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
|
3293
|
+
const showPublishButton = hasPublishPermission && documents.some(({ status }) => status !== "published");
|
3294
|
+
const setListViewSelectedDocuments = strapiAdmin.useTable("publishAction", (state) => state.selectRow);
|
3295
|
+
const refetchList = () => {
|
3296
|
+
contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
|
3297
|
+
};
|
3298
|
+
if (!showPublishButton)
|
3299
|
+
return null;
|
3300
|
+
return {
|
3301
|
+
actionType: "publish",
|
3302
|
+
variant: "tertiary",
|
3303
|
+
label: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" }),
|
3304
|
+
dialog: {
|
3305
|
+
type: "modal",
|
3306
|
+
title: formatMessage({
|
3307
|
+
id: getTranslation("containers.ListPage.selectedEntriesModal.title"),
|
3308
|
+
defaultMessage: "Publish entries"
|
3309
|
+
}),
|
3310
|
+
content: ({ onClose }) => {
|
3311
|
+
return /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Root, { rows: documents, defaultSelectedRows: documents, headers: TABLE_HEADERS, children: /* @__PURE__ */ jsxRuntime.jsx(
|
3312
|
+
SelectedEntriesModalContent,
|
3313
|
+
{
|
3314
|
+
listViewSelectedEntries: documents,
|
3315
|
+
toggleModal: () => {
|
3316
|
+
onClose();
|
3317
|
+
refetchList();
|
3318
|
+
},
|
3319
|
+
setListViewSelectedDocuments,
|
3320
|
+
model
|
3321
|
+
}
|
3322
|
+
) });
|
3323
|
+
},
|
3324
|
+
onClose: () => {
|
3325
|
+
refetchList();
|
3326
|
+
}
|
3327
|
+
}
|
3328
|
+
};
|
3329
|
+
};
|
3330
|
+
const BulkActionsRenderer = () => {
|
3331
|
+
const plugins = strapiAdmin.useStrapiApp("BulkActionsRenderer", (state) => state.plugins);
|
3332
|
+
const { model, collectionType } = useDoc();
|
3333
|
+
const { selectedRows } = strapiAdmin.useTable("BulkActionsRenderer", (state) => state);
|
3334
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
|
3335
|
+
strapiAdmin.DescriptionComponentRenderer,
|
3336
|
+
{
|
3337
|
+
props: {
|
3338
|
+
model,
|
3339
|
+
collectionType,
|
3340
|
+
documents: selectedRows
|
3341
|
+
},
|
3342
|
+
descriptions: plugins["content-manager"].apis.getBulkActions(),
|
3343
|
+
children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActionButton, { ...action }, action.id))
|
3344
|
+
}
|
3345
|
+
) });
|
3346
|
+
};
|
3347
|
+
const DeleteAction = ({ documents, model }) => {
|
3348
|
+
const { formatMessage } = reactIntl.useIntl();
|
3349
|
+
const { schema: contentType } = useDoc();
|
3350
|
+
const selectRow = strapiAdmin.useTable("DeleteAction", (state) => state.selectRow);
|
3351
|
+
const hasI18nEnabled = Boolean(contentType?.pluginOptions?.i18n);
|
3352
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3353
|
+
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
3354
|
+
const hasDeletePermission = useDocumentRBAC("deleteAction", (state) => state.canDelete);
|
3355
|
+
const { deleteMany: bulkDeleteAction } = useDocumentActions();
|
3356
|
+
const documentIds = documents.map(({ documentId }) => documentId);
|
3357
|
+
const handleConfirmBulkDelete = async () => {
|
3358
|
+
const res = await bulkDeleteAction({
|
3359
|
+
documentIds,
|
3360
|
+
model,
|
3361
|
+
params
|
3362
|
+
});
|
3363
|
+
if (!("error" in res)) {
|
3364
|
+
selectRow([]);
|
3365
|
+
}
|
3366
|
+
};
|
3367
|
+
if (!hasDeletePermission)
|
3368
|
+
return null;
|
3369
|
+
return {
|
3370
|
+
variant: "danger-light",
|
3371
|
+
label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
|
3372
|
+
dialog: {
|
3373
|
+
type: "dialog",
|
3374
|
+
title: formatMessage({
|
3375
|
+
id: "app.components.ConfirmDialog.title",
|
3376
|
+
defaultMessage: "Confirmation"
|
3377
|
+
}),
|
3378
|
+
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3379
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3380
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
|
3381
|
+
id: "popUpWarning.bodyMessage.contentType.delete.all",
|
3382
|
+
defaultMessage: "Are you sure you want to delete these entries?"
|
3383
|
+
}) }),
|
3384
|
+
hasI18nEnabled && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", children: formatMessage(
|
3385
|
+
{
|
3386
|
+
id: getTranslation("Settings.list.actions.deleteAdditionalInfos"),
|
3387
|
+
defaultMessage: "This will delete the active locale versions <em>(from Internationalization)</em>"
|
3388
|
+
},
|
3389
|
+
{
|
3390
|
+
em: Emphasis
|
3391
|
+
}
|
3392
|
+
) }) })
|
3393
|
+
] }),
|
3394
|
+
onConfirm: handleConfirmBulkDelete
|
3395
|
+
}
|
3396
|
+
};
|
3397
|
+
};
|
3398
|
+
DeleteAction.type = "delete";
|
3399
|
+
const UnpublishAction = ({ documents, model }) => {
|
3400
|
+
const { formatMessage } = reactIntl.useIntl();
|
3401
|
+
const { schema } = useDoc();
|
3402
|
+
const selectRow = strapiAdmin.useTable("UnpublishAction", (state) => state.selectRow);
|
3403
|
+
const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
|
3404
|
+
const hasI18nEnabled = Boolean(schema?.pluginOptions?.i18n);
|
3405
|
+
const hasDraftAndPublishEnabled = Boolean(schema?.options?.draftAndPublish);
|
3406
|
+
const { unpublishMany: bulkUnpublishAction } = useDocumentActions();
|
3407
|
+
const documentIds = documents.map(({ documentId }) => documentId);
|
3408
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3409
|
+
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
3410
|
+
const handleConfirmBulkUnpublish = async () => {
|
3411
|
+
const data = await bulkUnpublishAction({ documentIds, model, params });
|
3412
|
+
if (!("error" in data)) {
|
3413
|
+
selectRow([]);
|
3414
|
+
}
|
3415
|
+
};
|
3416
|
+
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
|
3417
|
+
if (!showUnpublishButton)
|
3418
|
+
return null;
|
3419
|
+
return {
|
3420
|
+
variant: "tertiary",
|
3421
|
+
label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
|
3422
|
+
dialog: {
|
3423
|
+
type: "dialog",
|
3424
|
+
title: formatMessage({
|
3425
|
+
id: "app.components.ConfirmDialog.title",
|
3426
|
+
defaultMessage: "Confirmation"
|
3427
|
+
}),
|
3428
|
+
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3429
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3430
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
|
3431
|
+
id: "popUpWarning.bodyMessage.contentType.unpublish.all",
|
3432
|
+
defaultMessage: "Are you sure you want to unpublish these entries?"
|
3433
|
+
}) }),
|
3434
|
+
hasI18nEnabled && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", children: formatMessage(
|
3435
|
+
{
|
3436
|
+
id: getTranslation("Settings.list.actions.unpublishAdditionalInfos"),
|
3437
|
+
defaultMessage: "This will unpublish the active locale versions <em>(from Internationalization)</em>"
|
3438
|
+
},
|
3439
|
+
{
|
3440
|
+
em: Emphasis
|
3441
|
+
}
|
3442
|
+
) }) })
|
3443
|
+
] }),
|
3444
|
+
confirmButton: formatMessage({
|
3445
|
+
id: "app.utils.unpublish",
|
3446
|
+
defaultMessage: "Unpublish"
|
3447
|
+
}),
|
3448
|
+
onConfirm: handleConfirmBulkUnpublish
|
3449
|
+
}
|
3450
|
+
};
|
3451
|
+
};
|
3452
|
+
UnpublishAction.type = "unpublish";
|
3453
|
+
const Emphasis = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", textColor: "danger500", children: chunks });
|
3454
|
+
const DEFAULT_BULK_ACTIONS = [PublishAction, UnpublishAction, DeleteAction];
|
3455
|
+
const AutoCloneFailureModalBody = ({ prohibitedFields }) => {
|
3456
|
+
const { formatMessage } = reactIntl.useIntl();
|
3457
|
+
const getDefaultErrorMessage = (reason) => {
|
3458
|
+
switch (reason) {
|
3459
|
+
case "relation":
|
3460
|
+
return "Duplicating the relation could remove it from the original entry.";
|
3461
|
+
case "unique":
|
3462
|
+
return "Identical values in a unique field are not allowed";
|
3463
|
+
default:
|
3464
|
+
return reason;
|
3465
|
+
}
|
3466
|
+
};
|
3467
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
3468
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", children: formatMessage({
|
3469
|
+
id: getTranslation("containers.list.autoCloneModal.title"),
|
3470
|
+
defaultMessage: "This entry can't be duplicated directly."
|
3471
|
+
}) }),
|
3472
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", children: formatMessage({
|
3473
|
+
id: getTranslation("containers.list.autoCloneModal.description"),
|
3474
|
+
defaultMessage: "A new entry will be created with the same content, but you'll have to change the following fields to save it."
|
3475
|
+
}) }) }),
|
3476
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { marginTop: 6, gap: 2, direction: "column", alignItems: "stretch", children: prohibitedFields.map(([fieldPath, reason]) => /* @__PURE__ */ jsxRuntime.jsxs(
|
3477
|
+
designSystem.Flex,
|
3478
|
+
{
|
3479
|
+
direction: "column",
|
3480
|
+
gap: 2,
|
3481
|
+
alignItems: "flex-start",
|
3482
|
+
borderColor: "neutral200",
|
3483
|
+
hasRadius: true,
|
3484
|
+
padding: 6,
|
3485
|
+
children: [
|
3486
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "row", tag: "ol", children: fieldPath.map((pathSegment, index2) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { fontWeight: "semiBold", tag: "li", children: [
|
3487
|
+
pathSegment,
|
3488
|
+
index2 !== fieldPath.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(
|
3489
|
+
Icons.ChevronRight,
|
3490
|
+
{
|
3491
|
+
fill: "neutral500",
|
3492
|
+
height: "0.8rem",
|
3493
|
+
width: "0.8rem",
|
3494
|
+
style: { margin: "0 0.8rem" }
|
3495
|
+
}
|
3496
|
+
)
|
3497
|
+
] }, index2)) }),
|
3498
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", textColor: "neutral600", children: formatMessage({
|
3499
|
+
id: getTranslation(`containers.list.autoCloneModal.error.${reason}`),
|
3500
|
+
defaultMessage: getDefaultErrorMessage(reason)
|
3501
|
+
}) })
|
3502
|
+
]
|
3503
|
+
},
|
3504
|
+
fieldPath.join()
|
3505
|
+
)) })
|
3506
|
+
] });
|
3507
|
+
};
|
3508
|
+
const TableActions = ({ document }) => {
|
3509
|
+
const { formatMessage } = reactIntl.useIntl();
|
3510
|
+
const { model, collectionType } = useDoc();
|
3511
|
+
const plugins = strapiAdmin.useStrapiApp("TableActions", (state) => state.plugins);
|
3512
|
+
const props = {
|
3513
|
+
activeTab: null,
|
3514
|
+
model,
|
3515
|
+
documentId: document.documentId,
|
3516
|
+
collectionType,
|
3517
|
+
document
|
3518
|
+
};
|
3519
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
3520
|
+
strapiAdmin.DescriptionComponentRenderer,
|
3521
|
+
{
|
3522
|
+
props,
|
3523
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3524
|
+
children: (actions2) => {
|
3525
|
+
const tableRowActions = actions2.filter((action) => {
|
3526
|
+
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
3527
|
+
return positions.includes("table-row");
|
3528
|
+
});
|
3529
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
3530
|
+
DocumentActionsMenu,
|
3531
|
+
{
|
3532
|
+
actions: tableRowActions,
|
3533
|
+
label: formatMessage({
|
3534
|
+
id: "content-manager.containers.list.table.row-actions",
|
3535
|
+
defaultMessage: "Row action"
|
3536
|
+
}),
|
3537
|
+
variant: "ghost"
|
3538
|
+
}
|
3539
|
+
);
|
3540
|
+
}
|
3541
|
+
}
|
3542
|
+
);
|
3543
|
+
};
|
3544
|
+
const EditAction = ({ documentId }) => {
|
3545
|
+
const navigate = reactRouterDom.useNavigate();
|
3546
|
+
const { formatMessage } = reactIntl.useIntl();
|
3547
|
+
const { canRead } = useDocumentRBAC("EditAction", ({ canRead: canRead2 }) => ({ canRead: canRead2 }));
|
3548
|
+
const { toggleNotification } = strapiAdmin.useNotification();
|
3549
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3550
|
+
return {
|
3551
|
+
disabled: !canRead,
|
3552
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(StyledPencil, {}),
|
3553
|
+
label: formatMessage({
|
3554
|
+
id: "content-manager.actions.edit.label",
|
3555
|
+
defaultMessage: "Edit"
|
3556
|
+
}),
|
3557
|
+
position: "table-row",
|
3558
|
+
onClick: async () => {
|
3559
|
+
if (!documentId) {
|
2572
3560
|
console.error(
|
2573
3561
|
"You're trying to edit a document without an id, this is likely a bug with Strapi. Please open an issue."
|
2574
3562
|
);
|
@@ -2591,7 +3579,7 @@ const EditAction = ({ documentId }) => {
|
|
2591
3579
|
};
|
2592
3580
|
};
|
2593
3581
|
EditAction.type = "edit";
|
2594
|
-
const StyledPencil =
|
3582
|
+
const StyledPencil = styledComponents.styled(Icons.Pencil)`
|
2595
3583
|
path {
|
2596
3584
|
fill: currentColor;
|
2597
3585
|
}
|
@@ -2651,7 +3639,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
2651
3639
|
/* @__PURE__ */ jsxRuntime.jsx(
|
2652
3640
|
designSystem.LinkButton,
|
2653
3641
|
{
|
2654
|
-
|
3642
|
+
tag: reactRouterDom.NavLink,
|
2655
3643
|
to: {
|
2656
3644
|
pathname: `clone/${documentId}`
|
2657
3645
|
},
|
@@ -2667,7 +3655,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
2667
3655
|
};
|
2668
3656
|
};
|
2669
3657
|
CloneAction.type = "clone";
|
2670
|
-
const StyledDuplicate =
|
3658
|
+
const StyledDuplicate = styledComponents.styled(Icons.Duplicate)`
|
2671
3659
|
path {
|
2672
3660
|
fill: currentColor;
|
2673
3661
|
}
|
@@ -2684,442 +3672,183 @@ class ContentManagerPlugin {
|
|
2684
3672
|
documentActions = [
|
2685
3673
|
...DEFAULT_ACTIONS,
|
2686
3674
|
...DEFAULT_TABLE_ROW_ACTIONS,
|
2687
|
-
...DEFAULT_HEADER_ACTIONS
|
2688
|
-
HistoryAction
|
3675
|
+
...DEFAULT_HEADER_ACTIONS
|
2689
3676
|
];
|
2690
3677
|
editViewSidePanels = [ActionsPanel];
|
2691
3678
|
headerActions = [];
|
2692
3679
|
constructor() {
|
2693
3680
|
}
|
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);
|
3681
|
+
addEditViewSidePanel(panels) {
|
3682
|
+
if (Array.isArray(panels)) {
|
3683
|
+
this.editViewSidePanels = [...this.editViewSidePanels, ...panels];
|
3684
|
+
} else if (typeof panels === "function") {
|
3685
|
+
this.editViewSidePanels = panels(this.editViewSidePanels);
|
2725
3686
|
} else {
|
2726
3687
|
throw new Error(
|
2727
|
-
`Expected the \`
|
2728
|
-
|
3688
|
+
`Expected the \`panels\` passed to \`addEditViewSidePanel\` to be an array or a function, but received ${getPrintableType(
|
3689
|
+
panels
|
2729
3690
|
)}`
|
2730
3691
|
);
|
2731
3692
|
}
|
2732
3693
|
}
|
2733
|
-
|
3694
|
+
addDocumentAction(actions2) {
|
2734
3695
|
if (Array.isArray(actions2)) {
|
2735
|
-
this.
|
3696
|
+
this.documentActions = [...this.documentActions, ...actions2];
|
2736
3697
|
} else if (typeof actions2 === "function") {
|
2737
|
-
this.
|
3698
|
+
this.documentActions = actions2(this.documentActions);
|
2738
3699
|
} else {
|
2739
3700
|
throw new Error(
|
2740
|
-
`Expected the \`actions\` passed to \`
|
3701
|
+
`Expected the \`actions\` passed to \`addDocumentAction\` to be an array or a function, but received ${getPrintableType(
|
2741
3702
|
actions2
|
2742
3703
|
)}`
|
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;
|
3704
|
+
);
|
3705
|
+
}
|
3706
|
+
}
|
3707
|
+
addDocumentHeaderAction(actions2) {
|
3708
|
+
if (Array.isArray(actions2)) {
|
3709
|
+
this.headerActions = [...this.headerActions, ...actions2];
|
3710
|
+
} else if (typeof actions2 === "function") {
|
3711
|
+
this.headerActions = actions2(this.headerActions);
|
2982
3712
|
} else {
|
2983
|
-
|
2984
|
-
|
2985
|
-
|
2986
|
-
|
3713
|
+
throw new Error(
|
3714
|
+
`Expected the \`actions\` passed to \`addDocumentHeaderAction\` to be an array or a function, but received ${getPrintableType(
|
3715
|
+
actions2
|
3716
|
+
)}`
|
3717
|
+
);
|
2987
3718
|
}
|
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
|
3719
|
+
}
|
3720
|
+
addBulkAction(actions2) {
|
3721
|
+
if (Array.isArray(actions2)) {
|
3722
|
+
this.bulkActions = [...this.bulkActions, ...actions2];
|
3723
|
+
} else if (typeof actions2 === "function") {
|
3724
|
+
this.bulkActions = actions2(this.bulkActions);
|
3725
|
+
} else {
|
3726
|
+
throw new Error(
|
3727
|
+
`Expected the \`actions\` passed to \`addBulkAction\` to be an array or a function, but received ${getPrintableType(
|
3728
|
+
actions2
|
3729
|
+
)}`
|
3730
|
+
);
|
3029
3731
|
}
|
3030
|
-
}
|
3031
|
-
|
3032
|
-
|
3033
|
-
|
3034
|
-
|
3035
|
-
|
3036
|
-
|
3037
|
-
|
3732
|
+
}
|
3733
|
+
get config() {
|
3734
|
+
return {
|
3735
|
+
id: PLUGIN_ID,
|
3736
|
+
name: "Content Manager",
|
3737
|
+
injectionZones: INJECTION_ZONES,
|
3738
|
+
apis: {
|
3739
|
+
addBulkAction: this.addBulkAction.bind(this),
|
3740
|
+
addDocumentAction: this.addDocumentAction.bind(this),
|
3741
|
+
addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
|
3742
|
+
addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
|
3743
|
+
getBulkActions: () => this.bulkActions,
|
3744
|
+
getDocumentActions: () => this.documentActions,
|
3745
|
+
getEditViewSidePanels: () => this.editViewSidePanels,
|
3746
|
+
getHeaderActions: () => this.headerActions
|
3038
3747
|
}
|
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
|
-
);
|
3748
|
+
};
|
3749
|
+
}
|
3750
|
+
}
|
3751
|
+
const getPrintableType = (value) => {
|
3752
|
+
const nativeType = typeof value;
|
3753
|
+
if (nativeType === "object") {
|
3754
|
+
if (value === null)
|
3755
|
+
return "null";
|
3756
|
+
if (Array.isArray(value))
|
3757
|
+
return "array";
|
3758
|
+
if (value instanceof Object && value.constructor.name !== "Object") {
|
3759
|
+
return value.constructor.name;
|
3760
|
+
}
|
3761
|
+
}
|
3762
|
+
return nativeType;
|
3061
3763
|
};
|
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
|
-
);
|
3764
|
+
const HistoryAction = ({ model, document }) => {
|
3765
|
+
const { formatMessage } = reactIntl.useIntl();
|
3766
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3767
|
+
const navigate = reactRouterDom.useNavigate();
|
3768
|
+
const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
|
3769
|
+
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3770
|
+
return null;
|
3771
|
+
}
|
3083
3772
|
return {
|
3084
|
-
|
3085
|
-
|
3086
|
-
|
3087
|
-
|
3088
|
-
|
3089
|
-
|
3090
|
-
|
3091
|
-
|
3773
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
|
3774
|
+
label: formatMessage({
|
3775
|
+
id: "content-manager.history.document-action",
|
3776
|
+
defaultMessage: "Content History"
|
3777
|
+
}),
|
3778
|
+
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
3779
|
+
disabled: (
|
3780
|
+
/**
|
3781
|
+
* The user is creating a new document.
|
3782
|
+
* It hasn't been saved yet, so there's no history to go to
|
3783
|
+
*/
|
3784
|
+
!document || /**
|
3785
|
+
* The document has been created but the current dimension has never been saved.
|
3786
|
+
* For example, the user is creating a new locale in an existing document,
|
3787
|
+
* so there's no history for the document in that locale
|
3788
|
+
*/
|
3789
|
+
!document.id || /**
|
3790
|
+
* History is only available for content types created by the user.
|
3791
|
+
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
3792
|
+
* which start with `admin::` or `plugin::`
|
3793
|
+
*/
|
3794
|
+
!model.startsWith("api::")
|
3795
|
+
),
|
3796
|
+
position: "header"
|
3092
3797
|
};
|
3093
3798
|
};
|
3094
|
-
|
3095
|
-
|
3096
|
-
|
3097
|
-
|
3098
|
-
|
3099
|
-
|
3100
|
-
|
3101
|
-
|
3102
|
-
|
3103
|
-
|
3104
|
-
|
3105
|
-
|
3106
|
-
|
3107
|
-
|
3108
|
-
|
3109
|
-
|
3110
|
-
|
3111
|
-
|
3112
|
-
};
|
3113
|
-
}).filter((field) => field !== null);
|
3799
|
+
HistoryAction.type = "history";
|
3800
|
+
const historyAdmin = {
|
3801
|
+
bootstrap(app) {
|
3802
|
+
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
3803
|
+
addDocumentAction((actions2) => {
|
3804
|
+
const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
|
3805
|
+
actions2.splice(indexOfDeleteAction, 0, HistoryAction);
|
3806
|
+
return actions2;
|
3807
|
+
});
|
3808
|
+
}
|
3809
|
+
};
|
3810
|
+
const initialState = {
|
3811
|
+
collectionTypeLinks: [],
|
3812
|
+
components: [],
|
3813
|
+
fieldSizes: {},
|
3814
|
+
models: [],
|
3815
|
+
singleTypeLinks: [],
|
3816
|
+
isLoading: true
|
3114
3817
|
};
|
3818
|
+
const appSlice = toolkit.createSlice({
|
3819
|
+
name: "app",
|
3820
|
+
initialState,
|
3821
|
+
reducers: {
|
3822
|
+
setInitialData(state, action) {
|
3823
|
+
const {
|
3824
|
+
authorizedCollectionTypeLinks,
|
3825
|
+
authorizedSingleTypeLinks,
|
3826
|
+
components,
|
3827
|
+
contentTypeSchemas,
|
3828
|
+
fieldSizes
|
3829
|
+
} = action.payload;
|
3830
|
+
state.collectionTypeLinks = authorizedCollectionTypeLinks.filter(
|
3831
|
+
({ isDisplayed }) => isDisplayed
|
3832
|
+
);
|
3833
|
+
state.singleTypeLinks = authorizedSingleTypeLinks.filter(({ isDisplayed }) => isDisplayed);
|
3834
|
+
state.components = components;
|
3835
|
+
state.models = contentTypeSchemas;
|
3836
|
+
state.fieldSizes = fieldSizes;
|
3837
|
+
state.isLoading = false;
|
3838
|
+
}
|
3839
|
+
}
|
3840
|
+
});
|
3841
|
+
const { actions, reducer: reducer$1 } = appSlice;
|
3842
|
+
const { setInitialData } = actions;
|
3843
|
+
const reducer = toolkit.combineReducers({
|
3844
|
+
app: reducer$1
|
3845
|
+
});
|
3115
3846
|
const index = {
|
3116
3847
|
register(app) {
|
3117
3848
|
const cm = new ContentManagerPlugin();
|
3118
3849
|
app.addReducers({
|
3119
|
-
[contentManagerApi.reducerPath]: contentManagerApi.reducer,
|
3120
3850
|
[PLUGIN_ID]: reducer
|
3121
3851
|
});
|
3122
|
-
app.addMiddlewares([() => contentManagerApi.middleware]);
|
3123
3852
|
app.addMenuLink({
|
3124
3853
|
to: PLUGIN_ID,
|
3125
3854
|
icon: Icons.Feather,
|
@@ -3128,14 +3857,29 @@ const index = {
|
|
3128
3857
|
defaultMessage: "Content Manager"
|
3129
3858
|
},
|
3130
3859
|
permissions: [],
|
3131
|
-
|
3860
|
+
position: 1
|
3861
|
+
});
|
3862
|
+
app.router.addRoute({
|
3863
|
+
path: "content-manager/*",
|
3864
|
+
lazy: async () => {
|
3865
|
+
const { Layout } = await Promise.resolve().then(() => require("./layout-CLLtt_5O.js"));
|
3866
|
+
return {
|
3867
|
+
Component: Layout
|
3868
|
+
};
|
3869
|
+
},
|
3870
|
+
children: routes
|
3132
3871
|
});
|
3133
3872
|
app.registerPlugin(cm.config);
|
3134
3873
|
},
|
3874
|
+
bootstrap(app) {
|
3875
|
+
if (typeof historyAdmin.bootstrap === "function") {
|
3876
|
+
historyAdmin.bootstrap(app);
|
3877
|
+
}
|
3878
|
+
},
|
3135
3879
|
async registerTrads({ locales }) {
|
3136
3880
|
const importedTrads = await Promise.all(
|
3137
3881
|
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-
|
3882
|
+
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => Promise.resolve().then(() => require("./ar-BUUWXIYu.js")), "./translations/ca.json": () => Promise.resolve().then(() => require("./ca-Cmk45QO6.js")), "./translations/cs.json": () => Promise.resolve().then(() => require("./cs-CkJy6B2v.js")), "./translations/de.json": () => Promise.resolve().then(() => require("./de-CCEmbAah.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-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
3883
|
return {
|
3140
3884
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3141
3885
|
locale
|
@@ -3152,6 +3896,7 @@ const index = {
|
|
3152
3896
|
}
|
3153
3897
|
};
|
3154
3898
|
exports.ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD = ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD;
|
3899
|
+
exports.BulkActionsRenderer = BulkActionsRenderer;
|
3155
3900
|
exports.COLLECTION_TYPES = COLLECTION_TYPES;
|
3156
3901
|
exports.CREATOR_FIELDS = CREATOR_FIELDS;
|
3157
3902
|
exports.DEFAULT_SETTINGS = DEFAULT_SETTINGS;
|
@@ -3178,7 +3923,6 @@ exports.getDisplayName = getDisplayName;
|
|
3178
3923
|
exports.getMainField = getMainField;
|
3179
3924
|
exports.getTranslation = getTranslation;
|
3180
3925
|
exports.index = index;
|
3181
|
-
exports.routes = routes;
|
3182
3926
|
exports.setInitialData = setInitialData;
|
3183
3927
|
exports.useContentTypeSchema = useContentTypeSchema;
|
3184
3928
|
exports.useDoc = useDoc;
|
@@ -3192,4 +3936,4 @@ exports.useGetAllDocumentsQuery = useGetAllDocumentsQuery;
|
|
3192
3936
|
exports.useGetContentTypeConfigurationQuery = useGetContentTypeConfigurationQuery;
|
3193
3937
|
exports.useGetInitialDataQuery = useGetInitialDataQuery;
|
3194
3938
|
exports.useUpdateContentTypeConfigurationMutation = useUpdateContentTypeConfigurationMutation;
|
3195
|
-
//# sourceMappingURL=index-
|
3939
|
+
//# sourceMappingURL=index-Dd0nXyJF.js.map
|