@strapi/content-manager 0.0.0-experimental.e60ec1829240dae21c1e1d29076681c322288813 → 0.0.0-experimental.e9122b401c96877b6707775c4f893660eab93ae3
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-BPvzFjM7.mjs → ComponentConfigurationPage-CpBFh6_r.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-BPvzFjM7.mjs.map → ComponentConfigurationPage-CpBFh6_r.mjs.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-DjWJdz6Y.js → ComponentConfigurationPage-_zF8p6CY.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-DjWJdz6Y.js.map → ComponentConfigurationPage-_zF8p6CY.js.map} +1 -1
- package/dist/_chunks/{ComponentIcon-BBQsYCVn.js → ComponentIcon-BXdiCGQp.js} +8 -2
- package/dist/_chunks/ComponentIcon-BXdiCGQp.js.map +1 -0
- package/dist/_chunks/{ComponentIcon-BOFnK76n.mjs → ComponentIcon-u4bIXTFY.mjs} +9 -3
- package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +1 -0
- package/dist/_chunks/{EditConfigurationPage-DacbqQ_f.mjs → EditConfigurationPage-CE_yavTi.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-DacbqQ_f.mjs.map → EditConfigurationPage-CE_yavTi.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-Dmv83RlS.js → EditConfigurationPage-_aG2DJSU.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-Dmv83RlS.js.map → EditConfigurationPage-_aG2DJSU.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-DDS6H9HO.mjs → EditViewPage-DeTn7rAF.mjs} +59 -48
- package/dist/_chunks/EditViewPage-DeTn7rAF.mjs.map +1 -0
- package/dist/_chunks/{EditViewPage-DvNpQkam.js → EditViewPage-G9uNzwYL.js} +58 -49
- package/dist/_chunks/EditViewPage-G9uNzwYL.js.map +1 -0
- package/dist/_chunks/{Field-6gvGdPBV.mjs → Field-CnCKhI1R.mjs} +995 -795
- package/dist/_chunks/Field-CnCKhI1R.mjs.map +1 -0
- package/dist/_chunks/{Field-DmVKIAOo.js → Field-DDHUWEfV.js} +1041 -842
- package/dist/_chunks/Field-DDHUWEfV.js.map +1 -0
- package/dist/_chunks/{Form-CPZC9vWa.js → Form-DYETaKUX.js} +65 -45
- package/dist/_chunks/Form-DYETaKUX.js.map +1 -0
- package/dist/_chunks/{Form-DW6K1IH-.mjs → Form-IvVVwqRL.mjs} +65 -44
- package/dist/_chunks/Form-IvVVwqRL.mjs.map +1 -0
- package/dist/_chunks/{History-Dmr9fmUA.mjs → History-BMunT-do.mjs} +148 -54
- package/dist/_chunks/History-BMunT-do.mjs.map +1 -0
- package/dist/_chunks/{History-DeAPlvtv.js → History-CnZDctSO.js} +149 -56
- package/dist/_chunks/History-CnZDctSO.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DPCwW5Vr.js → ListConfigurationPage-BynalOp8.js} +67 -58
- package/dist/_chunks/ListConfigurationPage-BynalOp8.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DhwvYcNv.mjs → ListConfigurationPage-CDqkCxgV.mjs} +63 -53
- package/dist/_chunks/ListConfigurationPage-CDqkCxgV.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-5ySZ-VUs.js → ListViewPage-I88Ouzoq.js} +126 -137
- package/dist/_chunks/ListViewPage-I88Ouzoq.js.map +1 -0
- package/dist/_chunks/{ListViewPage-BtAwuYLE.mjs → ListViewPage-_5gS-DOF.mjs} +123 -134
- package/dist/_chunks/ListViewPage-_5gS-DOF.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DOC_yWOf.js → NoContentTypePage-BaWQ7HsA.js} +3 -3
- package/dist/_chunks/NoContentTypePage-BaWQ7HsA.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DSPxnxxp.mjs → NoContentTypePage-Dht-55hr.mjs} +3 -3
- package/dist/_chunks/NoContentTypePage-Dht-55hr.mjs.map +1 -0
- package/dist/_chunks/{NoPermissionsPage-UWDC-1Tw.mjs → NoPermissionsPage-Bs8D5W_v.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-UWDC-1Tw.mjs.map → NoPermissionsPage-Bs8D5W_v.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-Dwu8rRJu.js → NoPermissionsPage-DCVUh5at.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-Dwu8rRJu.js.map → NoPermissionsPage-DCVUh5at.js.map} +1 -1
- package/dist/_chunks/{Relations-CgWtgnPe.js → Relations-BPgFQeGj.js} +71 -62
- package/dist/_chunks/Relations-BPgFQeGj.js.map +1 -0
- package/dist/_chunks/{Relations-J8cscLlR.mjs → Relations-Chdt5qWc.mjs} +67 -57
- package/dist/_chunks/Relations-Chdt5qWc.mjs.map +1 -0
- package/dist/_chunks/{en-C-V1_90f.js → en-BVzUkPxZ.js} +16 -8
- package/dist/_chunks/{en-C-V1_90f.js.map → en-BVzUkPxZ.js.map} +1 -1
- package/dist/_chunks/{en-MBPul9Su.mjs → en-CPTj6CjC.mjs} +16 -8
- package/dist/_chunks/{en-MBPul9Su.mjs.map → en-CPTj6CjC.mjs.map} +1 -1
- package/dist/_chunks/{index-C6AH2hEl.js → index-BhbLFX4l.js} +1752 -903
- package/dist/_chunks/index-BhbLFX4l.js.map +1 -0
- package/dist/_chunks/{index-CwRRo1V9.mjs → index-D4UGPFZC.mjs} +1778 -928
- package/dist/_chunks/index-D4UGPFZC.mjs.map +1 -0
- package/dist/_chunks/{layout-B_SXLhqf.js → layout-CYA7s0qO.js} +45 -29
- package/dist/_chunks/layout-CYA7s0qO.js.map +1 -0
- package/dist/_chunks/{layout-jIDzX0Fp.mjs → layout-D4HI4_PS.mjs} +45 -27
- package/dist/_chunks/layout-D4HI4_PS.mjs.map +1 -0
- package/dist/_chunks/{relations-CuvIgCqI.mjs → relations-1pXaYpBK.mjs} +2 -2
- package/dist/_chunks/{relations-CuvIgCqI.mjs.map → relations-1pXaYpBK.mjs.map} +1 -1
- package/dist/_chunks/{relations-iBMa_OFG.js → relations-DDZ9OxNo.js} +2 -2
- package/dist/_chunks/{relations-iBMa_OFG.js.map → relations-DDZ9OxNo.js.map} +1 -1
- package/dist/_chunks/useDebounce-CtcjDB3L.js +28 -0
- package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs +29 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -0
- package/dist/_chunks/useDragAndDrop-DdHgKsqq.mjs.map +1 -1
- package/dist/_chunks/useDragAndDrop-J0TUUbR6.js.map +1 -1
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +8 -7
- package/dist/admin/src/components/ComponentIcon.d.ts +6 -3
- package/dist/admin/src/content-manager.d.ts +3 -3
- package/dist/admin/src/exports.d.ts +1 -0
- package/dist/admin/src/history/components/VersionInputRenderer.d.ts +1 -1
- package/dist/admin/src/history/index.d.ts +3 -0
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +5 -8
- package/dist/admin/src/hooks/useDocumentActions.d.ts +24 -3
- package/dist/admin/src/hooks/useDocumentLayout.d.ts +2 -2
- package/dist/admin/src/hooks/useDragAndDrop.d.ts +4 -4
- package/dist/admin/src/hooks/useKeyboardDragAndDrop.d.ts +1 -1
- package/dist/admin/src/index.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +11 -4
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.d.ts +3 -3
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +4 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Component/Input.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.d.ts +3 -5
- package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/Field.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +30 -18
- package/dist/admin/src/pages/EditView/components/FormInputs/UID.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +3 -49
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/Field.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +16 -53
- package/dist/admin/src/pages/EditView/components/Header.d.ts +10 -11
- 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 +31 -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 +5 -7
- package/dist/server/index.js +436 -281
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +444 -289
- 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/relations.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 +2 -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/policies/hasPermissions.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/permission-checker.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 +17 -7
- 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 +14 -15
- 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");
|
11
9
|
const yup = require("yup");
|
12
|
-
const react = require("@reduxjs/toolkit/query/react");
|
13
|
-
const axios = require("axios");
|
14
10
|
const pipe = require("lodash/fp/pipe");
|
15
11
|
const dateFns = require("date-fns");
|
12
|
+
const styledComponents = require("styled-components");
|
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,89 +171,20 @@ 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",
|
289
179
|
"Document",
|
290
180
|
"InitialData",
|
291
181
|
"HistoryVersion",
|
292
|
-
"Relations"
|
293
|
-
|
294
|
-
|
182
|
+
"Relations",
|
183
|
+
"UidAvailability"
|
184
|
+
]
|
295
185
|
});
|
296
186
|
const documentApi = contentManagerApi.injectEndpoints({
|
187
|
+
overrideExisting: true,
|
297
188
|
endpoints: (builder) => ({
|
298
189
|
autoCloneDocument: builder.mutation({
|
299
190
|
query: ({ model, sourceId, query }) => ({
|
@@ -303,7 +194,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
303
194
|
params: query
|
304
195
|
}
|
305
196
|
}),
|
306
|
-
invalidatesTags: (_result,
|
197
|
+
invalidatesTags: (_result, error, { model }) => {
|
198
|
+
if (error) {
|
199
|
+
return [];
|
200
|
+
}
|
201
|
+
return [{ type: "Document", id: `${model}_LIST` }];
|
202
|
+
}
|
307
203
|
}),
|
308
204
|
cloneDocument: builder.mutation({
|
309
205
|
query: ({ model, sourceId, data, params }) => ({
|
@@ -314,7 +210,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
314
210
|
params
|
315
211
|
}
|
316
212
|
}),
|
317
|
-
invalidatesTags: (_result, _error, { model }) => [
|
213
|
+
invalidatesTags: (_result, _error, { model }) => [
|
214
|
+
{ type: "Document", id: `${model}_LIST` },
|
215
|
+
{ type: "UidAvailability", id: model }
|
216
|
+
]
|
318
217
|
}),
|
319
218
|
/**
|
320
219
|
* Creates a new collection-type document. This should ONLY be used for collection-types.
|
@@ -331,7 +230,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
331
230
|
}),
|
332
231
|
invalidatesTags: (result, _error, { model }) => [
|
333
232
|
{ type: "Document", id: `${model}_LIST` },
|
334
|
-
"Relations"
|
233
|
+
"Relations",
|
234
|
+
{ type: "UidAvailability", id: model }
|
335
235
|
]
|
336
236
|
}),
|
337
237
|
deleteDocument: builder.mutation({
|
@@ -347,12 +247,15 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
347
247
|
]
|
348
248
|
}),
|
349
249
|
deleteManyDocuments: builder.mutation({
|
350
|
-
query: ({ model, ...body }) => ({
|
250
|
+
query: ({ model, params, ...body }) => ({
|
351
251
|
url: `/content-manager/collection-types/${model}/actions/bulkDelete`,
|
352
252
|
method: "POST",
|
353
|
-
data: body
|
253
|
+
data: body,
|
254
|
+
config: {
|
255
|
+
params
|
256
|
+
}
|
354
257
|
}),
|
355
|
-
invalidatesTags: (_res, _error, { model
|
258
|
+
invalidatesTags: (_res, _error, { model }) => [{ type: "Document", id: `${model}_LIST` }]
|
356
259
|
}),
|
357
260
|
discardDocument: builder.mutation({
|
358
261
|
query: ({ collectionType, model, documentId, params }) => ({
|
@@ -369,7 +272,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
369
272
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
370
273
|
},
|
371
274
|
{ type: "Document", id: `${model}_LIST` },
|
372
|
-
"Relations"
|
275
|
+
"Relations",
|
276
|
+
{ type: "UidAvailability", id: model }
|
373
277
|
];
|
374
278
|
}
|
375
279
|
}),
|
@@ -387,6 +291,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
387
291
|
}),
|
388
292
|
providesTags: (result, _error, arg) => {
|
389
293
|
return [
|
294
|
+
{ type: "Document", id: `ALL_LIST` },
|
390
295
|
{ type: "Document", id: `${arg.model}_LIST` },
|
391
296
|
...result?.results.map(({ documentId }) => ({
|
392
297
|
type: "Document",
|
@@ -425,6 +330,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
425
330
|
{
|
426
331
|
type: "Document",
|
427
332
|
id: collectionType !== SINGLE_TYPES ? `${model}_${result && "documentId" in result ? result.documentId : documentId}` : model
|
333
|
+
},
|
334
|
+
// Make it easy to invalidate all individual documents queries for a model
|
335
|
+
{
|
336
|
+
type: "Document",
|
337
|
+
id: `${model}_ALL_ITEMS`
|
428
338
|
}
|
429
339
|
];
|
430
340
|
}
|
@@ -463,10 +373,13 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
463
373
|
}
|
464
374
|
}),
|
465
375
|
publishManyDocuments: builder.mutation({
|
466
|
-
query: ({ model, ...body }) => ({
|
376
|
+
query: ({ model, params, ...body }) => ({
|
467
377
|
url: `/content-manager/collection-types/${model}/actions/bulkPublish`,
|
468
378
|
method: "POST",
|
469
|
-
data: body
|
379
|
+
data: body,
|
380
|
+
config: {
|
381
|
+
params
|
382
|
+
}
|
470
383
|
}),
|
471
384
|
invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
|
472
385
|
}),
|
@@ -485,8 +398,21 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
485
398
|
type: "Document",
|
486
399
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
487
400
|
},
|
488
|
-
"Relations"
|
401
|
+
"Relations",
|
402
|
+
{ type: "UidAvailability", id: model }
|
489
403
|
];
|
404
|
+
},
|
405
|
+
async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
|
406
|
+
const patchResult = dispatch(
|
407
|
+
documentApi.util.updateQueryData("getDocument", patch, (draft) => {
|
408
|
+
Object.assign(draft.data, data);
|
409
|
+
})
|
410
|
+
);
|
411
|
+
try {
|
412
|
+
await queryFulfilled;
|
413
|
+
} catch {
|
414
|
+
patchResult.undo();
|
415
|
+
}
|
490
416
|
}
|
491
417
|
}),
|
492
418
|
unpublishDocument: builder.mutation({
|
@@ -508,10 +434,13 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
508
434
|
}
|
509
435
|
}),
|
510
436
|
unpublishManyDocuments: builder.mutation({
|
511
|
-
query: ({ model, ...body }) => ({
|
437
|
+
query: ({ model, params, ...body }) => ({
|
512
438
|
url: `/content-manager/collection-types/${model}/actions/bulkUnpublish`,
|
513
439
|
method: "POST",
|
514
|
-
data: body
|
440
|
+
data: body,
|
441
|
+
config: {
|
442
|
+
params
|
443
|
+
}
|
515
444
|
}),
|
516
445
|
invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
|
517
446
|
})
|
@@ -535,7 +464,25 @@ const {
|
|
535
464
|
useUnpublishDocumentMutation,
|
536
465
|
useUnpublishManyDocumentsMutation
|
537
466
|
} = documentApi;
|
538
|
-
const
|
467
|
+
const buildValidParams = (query) => {
|
468
|
+
if (!query)
|
469
|
+
return query;
|
470
|
+
const { plugins: _, ...validQueryParams } = {
|
471
|
+
...query,
|
472
|
+
...Object.values(query?.plugins ?? {}).reduce(
|
473
|
+
(acc, current) => Object.assign(acc, current),
|
474
|
+
{}
|
475
|
+
)
|
476
|
+
};
|
477
|
+
if ("_q" in validQueryParams) {
|
478
|
+
validQueryParams._q = encodeURIComponent(validQueryParams._q);
|
479
|
+
}
|
480
|
+
return validQueryParams;
|
481
|
+
};
|
482
|
+
const isBaseQueryError = (error) => {
|
483
|
+
return error.name !== void 0;
|
484
|
+
};
|
485
|
+
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
539
486
|
const createModelSchema = (attributes2) => yup__namespace.object().shape(
|
540
487
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
541
488
|
if (DOCUMENT_META_FIELDS.includes(name)) {
|
@@ -548,7 +495,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
548
495
|
addMinValidation,
|
549
496
|
addMaxValidation,
|
550
497
|
addRegexValidation
|
551
|
-
].map((fn) => fn(attribute));
|
498
|
+
].map((fn) => fn(attribute, options));
|
552
499
|
const transformSchema = pipe__default.default(...validations);
|
553
500
|
switch (attribute.type) {
|
554
501
|
case "component": {
|
@@ -574,10 +521,14 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
574
521
|
yup__namespace.array().of(
|
575
522
|
yup__namespace.lazy(
|
576
523
|
(data) => {
|
577
|
-
const
|
578
|
-
|
524
|
+
const attributes3 = components?.[data?.__component]?.attributes;
|
525
|
+
const validation = yup__namespace.object().shape({
|
579
526
|
__component: yup__namespace.string().required().oneOf(Object.keys(components))
|
580
|
-
}).nullable(false)
|
527
|
+
}).nullable(false);
|
528
|
+
if (!attributes3) {
|
529
|
+
return validation;
|
530
|
+
}
|
531
|
+
return validation.concat(createModelSchema(attributes3));
|
581
532
|
}
|
582
533
|
)
|
583
534
|
)
|
@@ -587,11 +538,25 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
587
538
|
return {
|
588
539
|
...acc,
|
589
540
|
[name]: transformSchema(
|
590
|
-
yup__namespace.
|
591
|
-
|
592
|
-
|
593
|
-
})
|
594
|
-
|
541
|
+
yup__namespace.lazy((value) => {
|
542
|
+
if (!value) {
|
543
|
+
return yup__namespace.mixed().nullable(true);
|
544
|
+
} else if (Array.isArray(value)) {
|
545
|
+
return yup__namespace.array().of(
|
546
|
+
yup__namespace.object().shape({
|
547
|
+
id: yup__namespace.string().required()
|
548
|
+
})
|
549
|
+
);
|
550
|
+
} else if (typeof value === "object") {
|
551
|
+
return yup__namespace.object();
|
552
|
+
} else {
|
553
|
+
return yup__namespace.mixed().test(
|
554
|
+
"type-error",
|
555
|
+
"Relation values must be either null, an array of objects with {id} or an object.",
|
556
|
+
() => false
|
557
|
+
);
|
558
|
+
}
|
559
|
+
})
|
595
560
|
)
|
596
561
|
};
|
597
562
|
default:
|
@@ -631,6 +596,14 @@ const createAttributeSchema = (attribute) => {
|
|
631
596
|
if (!value || typeof value === "string" && value.length === 0) {
|
632
597
|
return true;
|
633
598
|
}
|
599
|
+
if (typeof value === "object") {
|
600
|
+
try {
|
601
|
+
JSON.stringify(value);
|
602
|
+
return true;
|
603
|
+
} catch (err) {
|
604
|
+
return false;
|
605
|
+
}
|
606
|
+
}
|
634
607
|
try {
|
635
608
|
JSON.parse(value);
|
636
609
|
return true;
|
@@ -649,16 +622,30 @@ const createAttributeSchema = (attribute) => {
|
|
649
622
|
return yup__namespace.mixed();
|
650
623
|
}
|
651
624
|
};
|
652
|
-
const
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
625
|
+
const nullableSchema = (schema) => {
|
626
|
+
return schema?.nullable ? schema.nullable() : (
|
627
|
+
// In some cases '.nullable' will not be available on the schema.
|
628
|
+
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
629
|
+
// In these cases we should just return the schema as it is.
|
630
|
+
schema
|
631
|
+
);
|
632
|
+
};
|
633
|
+
const addRequiredValidation = (attribute, options) => (schema) => {
|
634
|
+
if (options.status === "draft") {
|
635
|
+
return nullableSchema(schema);
|
636
|
+
}
|
637
|
+
if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
|
638
|
+
return schema.min(1, strapiAdmin.translatedErrors.required);
|
639
|
+
}
|
640
|
+
if (attribute.required && attribute.type !== "relation") {
|
641
|
+
return schema.required(strapiAdmin.translatedErrors.required);
|
658
642
|
}
|
659
|
-
return schema
|
643
|
+
return nullableSchema(schema);
|
660
644
|
};
|
661
|
-
const addMinLengthValidation = (attribute) => (schema) => {
|
645
|
+
const addMinLengthValidation = (attribute, options) => (schema) => {
|
646
|
+
if (options.status === "draft") {
|
647
|
+
return schema;
|
648
|
+
}
|
662
649
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
663
650
|
return schema.min(attribute.minLength, {
|
664
651
|
...strapiAdmin.translatedErrors.minLength,
|
@@ -680,9 +667,31 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
680
667
|
}
|
681
668
|
return schema;
|
682
669
|
};
|
683
|
-
const addMinValidation = (attribute) => (schema) => {
|
670
|
+
const addMinValidation = (attribute, options) => (schema) => {
|
684
671
|
if ("min" in attribute) {
|
685
672
|
const min = toInteger(attribute.min);
|
673
|
+
if (attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") {
|
674
|
+
if (options.status !== "draft" && !attribute.required && "test" in schema && min) {
|
675
|
+
return schema.test(
|
676
|
+
"custom-min",
|
677
|
+
{
|
678
|
+
...strapiAdmin.translatedErrors.min,
|
679
|
+
values: {
|
680
|
+
min: attribute.min
|
681
|
+
}
|
682
|
+
},
|
683
|
+
(value) => {
|
684
|
+
if (!value) {
|
685
|
+
return true;
|
686
|
+
}
|
687
|
+
if (Array.isArray(value) && value.length === 0) {
|
688
|
+
return true;
|
689
|
+
}
|
690
|
+
return value.length >= min;
|
691
|
+
}
|
692
|
+
);
|
693
|
+
}
|
694
|
+
}
|
686
695
|
if ("min" in schema && min) {
|
687
696
|
return schema.min(min, {
|
688
697
|
...strapiAdmin.translatedErrors.min,
|
@@ -728,24 +737,6 @@ const addRegexValidation = (attribute) => (schema) => {
|
|
728
737
|
}
|
729
738
|
return schema;
|
730
739
|
};
|
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
740
|
const initApi = contentManagerApi.injectEndpoints({
|
750
741
|
endpoints: (builder) => ({
|
751
742
|
getInitialData: builder.query({
|
@@ -759,27 +750,20 @@ const { useGetInitialDataQuery } = initApi;
|
|
759
750
|
const useContentTypeSchema = (model) => {
|
760
751
|
const { toggleNotification } = strapiAdmin.useNotification();
|
761
752
|
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
|
-
});
|
753
|
+
const { data, error, isLoading, isFetching } = useGetInitialDataQuery(void 0);
|
754
|
+
const { components, contentType, contentTypes } = React__namespace.useMemo(() => {
|
755
|
+
const contentType2 = data?.contentTypes.find((ct) => ct.uid === model);
|
756
|
+
const componentsByKey = data?.components.reduce((acc, component) => {
|
757
|
+
acc[component.uid] = component;
|
758
|
+
return acc;
|
759
|
+
}, {});
|
760
|
+
const components2 = extractContentTypeComponents(contentType2?.attributes, componentsByKey);
|
761
|
+
return {
|
762
|
+
components: Object.keys(components2).length === 0 ? void 0 : components2,
|
763
|
+
contentType: contentType2,
|
764
|
+
contentTypes: data?.contentTypes ?? []
|
765
|
+
};
|
766
|
+
}, [model, data]);
|
783
767
|
React__namespace.useEffect(() => {
|
784
768
|
if (error) {
|
785
769
|
toggleNotification({
|
@@ -834,7 +818,10 @@ const useDocument = (args, opts) => {
|
|
834
818
|
isLoading: isLoadingDocument,
|
835
819
|
isFetching: isFetchingDocument,
|
836
820
|
error
|
837
|
-
} = useGetDocumentQuery(args,
|
821
|
+
} = useGetDocumentQuery(args, {
|
822
|
+
...opts,
|
823
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
824
|
+
});
|
838
825
|
const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
|
839
826
|
React__namespace.useEffect(() => {
|
840
827
|
if (error) {
|
@@ -862,7 +849,7 @@ const useDocument = (args, opts) => {
|
|
862
849
|
return null;
|
863
850
|
} catch (error2) {
|
864
851
|
if (error2 instanceof yup.ValidationError) {
|
865
|
-
return
|
852
|
+
return strapiAdmin.getYupValidationErrors(error2);
|
866
853
|
}
|
867
854
|
throw error2;
|
868
855
|
}
|
@@ -920,6 +907,7 @@ const useDocumentActions = () => {
|
|
920
907
|
const { formatMessage } = reactIntl.useIntl();
|
921
908
|
const { trackUsage } = strapiAdmin.useTracking();
|
922
909
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
910
|
+
const navigate = reactRouterDom.useNavigate();
|
923
911
|
const [deleteDocument] = useDeleteDocumentMutation();
|
924
912
|
const _delete = React__namespace.useCallback(
|
925
913
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -958,14 +946,53 @@ const useDocumentActions = () => {
|
|
958
946
|
},
|
959
947
|
[trackUsage, deleteDocument, toggleNotification, formatMessage, formatAPIError]
|
960
948
|
);
|
949
|
+
const [deleteManyDocuments] = useDeleteManyDocumentsMutation();
|
950
|
+
const deleteMany = React__namespace.useCallback(
|
951
|
+
async ({ model, documentIds, params }) => {
|
952
|
+
try {
|
953
|
+
trackUsage("willBulkDeleteEntries");
|
954
|
+
const res = await deleteManyDocuments({
|
955
|
+
model,
|
956
|
+
documentIds,
|
957
|
+
params
|
958
|
+
});
|
959
|
+
if ("error" in res) {
|
960
|
+
toggleNotification({
|
961
|
+
type: "danger",
|
962
|
+
message: formatAPIError(res.error)
|
963
|
+
});
|
964
|
+
return { error: res.error };
|
965
|
+
}
|
966
|
+
toggleNotification({
|
967
|
+
type: "success",
|
968
|
+
title: formatMessage({
|
969
|
+
id: getTranslation("success.records.delete"),
|
970
|
+
defaultMessage: "Successfully deleted."
|
971
|
+
}),
|
972
|
+
message: ""
|
973
|
+
});
|
974
|
+
trackUsage("didBulkDeleteEntries");
|
975
|
+
return res.data;
|
976
|
+
} catch (err) {
|
977
|
+
toggleNotification({
|
978
|
+
type: "danger",
|
979
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
980
|
+
});
|
981
|
+
trackUsage("didNotBulkDeleteEntries");
|
982
|
+
throw err;
|
983
|
+
}
|
984
|
+
},
|
985
|
+
[trackUsage, deleteManyDocuments, toggleNotification, formatMessage, formatAPIError]
|
986
|
+
);
|
961
987
|
const [discardDocument] = useDiscardDocumentMutation();
|
962
988
|
const discard = React__namespace.useCallback(
|
963
|
-
async ({ collectionType, model, documentId }) => {
|
989
|
+
async ({ collectionType, model, documentId, params }) => {
|
964
990
|
try {
|
965
991
|
const res = await discardDocument({
|
966
992
|
collectionType,
|
967
993
|
model,
|
968
|
-
documentId
|
994
|
+
documentId,
|
995
|
+
params
|
969
996
|
});
|
970
997
|
if ("error" in res) {
|
971
998
|
toggleNotification({
|
@@ -1027,6 +1054,43 @@ const useDocumentActions = () => {
|
|
1027
1054
|
},
|
1028
1055
|
[trackUsage, publishDocument, toggleNotification, formatMessage, formatAPIError]
|
1029
1056
|
);
|
1057
|
+
const [publishManyDocuments] = usePublishManyDocumentsMutation();
|
1058
|
+
const publishMany = React__namespace.useCallback(
|
1059
|
+
async ({ model, documentIds, params }) => {
|
1060
|
+
try {
|
1061
|
+
const res = await publishManyDocuments({
|
1062
|
+
model,
|
1063
|
+
documentIds,
|
1064
|
+
params
|
1065
|
+
});
|
1066
|
+
if ("error" in res) {
|
1067
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1068
|
+
return { error: res.error };
|
1069
|
+
}
|
1070
|
+
toggleNotification({
|
1071
|
+
type: "success",
|
1072
|
+
message: formatMessage({
|
1073
|
+
id: getTranslation("success.record.publish"),
|
1074
|
+
defaultMessage: "Published document"
|
1075
|
+
})
|
1076
|
+
});
|
1077
|
+
return res.data;
|
1078
|
+
} catch (err) {
|
1079
|
+
toggleNotification({
|
1080
|
+
type: "danger",
|
1081
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1082
|
+
});
|
1083
|
+
throw err;
|
1084
|
+
}
|
1085
|
+
},
|
1086
|
+
[
|
1087
|
+
// trackUsage,
|
1088
|
+
publishManyDocuments,
|
1089
|
+
toggleNotification,
|
1090
|
+
formatMessage,
|
1091
|
+
formatAPIError
|
1092
|
+
]
|
1093
|
+
);
|
1030
1094
|
const [updateDocument] = useUpdateDocumentMutation();
|
1031
1095
|
const update = React__namespace.useCallback(
|
1032
1096
|
async ({ collectionType, model, documentId, params }, data, trackerProperty) => {
|
@@ -1101,6 +1165,41 @@ const useDocumentActions = () => {
|
|
1101
1165
|
},
|
1102
1166
|
[trackUsage, unpublishDocument, toggleNotification, formatMessage, formatAPIError]
|
1103
1167
|
);
|
1168
|
+
const [unpublishManyDocuments] = useUnpublishManyDocumentsMutation();
|
1169
|
+
const unpublishMany = React__namespace.useCallback(
|
1170
|
+
async ({ model, documentIds, params }) => {
|
1171
|
+
try {
|
1172
|
+
trackUsage("willBulkUnpublishEntries");
|
1173
|
+
const res = await unpublishManyDocuments({
|
1174
|
+
model,
|
1175
|
+
documentIds,
|
1176
|
+
params
|
1177
|
+
});
|
1178
|
+
if ("error" in res) {
|
1179
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1180
|
+
return { error: res.error };
|
1181
|
+
}
|
1182
|
+
trackUsage("didBulkUnpublishEntries");
|
1183
|
+
toggleNotification({
|
1184
|
+
type: "success",
|
1185
|
+
title: formatMessage({
|
1186
|
+
id: getTranslation("success.records.unpublish"),
|
1187
|
+
defaultMessage: "Successfully unpublished."
|
1188
|
+
}),
|
1189
|
+
message: ""
|
1190
|
+
});
|
1191
|
+
return res.data;
|
1192
|
+
} catch (err) {
|
1193
|
+
toggleNotification({
|
1194
|
+
type: "danger",
|
1195
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1196
|
+
});
|
1197
|
+
trackUsage("didNotBulkUnpublishEntries");
|
1198
|
+
throw err;
|
1199
|
+
}
|
1200
|
+
},
|
1201
|
+
[trackUsage, unpublishManyDocuments, toggleNotification, formatMessage, formatAPIError]
|
1202
|
+
);
|
1104
1203
|
const [createDocument] = useCreateDocumentMutation();
|
1105
1204
|
const create = React__namespace.useCallback(
|
1106
1205
|
async ({ model, params }, data, trackerProperty) => {
|
@@ -1144,7 +1243,6 @@ const useDocumentActions = () => {
|
|
1144
1243
|
sourceId
|
1145
1244
|
});
|
1146
1245
|
if ("error" in res) {
|
1147
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1148
1246
|
return { error: res.error };
|
1149
1247
|
}
|
1150
1248
|
toggleNotification({
|
@@ -1163,7 +1261,7 @@ const useDocumentActions = () => {
|
|
1163
1261
|
throw err;
|
1164
1262
|
}
|
1165
1263
|
},
|
1166
|
-
[autoCloneDocument,
|
1264
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1167
1265
|
);
|
1168
1266
|
const [cloneDocument] = useCloneDocumentMutation();
|
1169
1267
|
const clone = React__namespace.useCallback(
|
@@ -1189,6 +1287,7 @@ const useDocumentActions = () => {
|
|
1189
1287
|
defaultMessage: "Cloned document"
|
1190
1288
|
})
|
1191
1289
|
});
|
1290
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1192
1291
|
return res.data;
|
1193
1292
|
} catch (err) {
|
1194
1293
|
toggleNotification({
|
@@ -1199,7 +1298,7 @@ const useDocumentActions = () => {
|
|
1199
1298
|
throw err;
|
1200
1299
|
}
|
1201
1300
|
},
|
1202
|
-
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
|
1301
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1203
1302
|
);
|
1204
1303
|
const [getDoc] = useLazyGetDocumentQuery();
|
1205
1304
|
const getDocument = React__namespace.useCallback(
|
@@ -1214,15 +1313,18 @@ const useDocumentActions = () => {
|
|
1214
1313
|
clone,
|
1215
1314
|
create,
|
1216
1315
|
delete: _delete,
|
1316
|
+
deleteMany,
|
1217
1317
|
discard,
|
1218
1318
|
getDocument,
|
1219
1319
|
publish,
|
1320
|
+
publishMany,
|
1220
1321
|
unpublish,
|
1322
|
+
unpublishMany,
|
1221
1323
|
update
|
1222
1324
|
};
|
1223
1325
|
};
|
1224
1326
|
const ProtectedHistoryPage = React.lazy(
|
1225
|
-
() => Promise.resolve().then(() => require("./History-
|
1327
|
+
() => Promise.resolve().then(() => require("./History-CnZDctSO.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1226
1328
|
);
|
1227
1329
|
const routes$1 = [
|
1228
1330
|
{
|
@@ -1235,31 +1337,31 @@ const routes$1 = [
|
|
1235
1337
|
}
|
1236
1338
|
];
|
1237
1339
|
const ProtectedEditViewPage = React.lazy(
|
1238
|
-
() => Promise.resolve().then(() => require("./EditViewPage-
|
1340
|
+
() => Promise.resolve().then(() => require("./EditViewPage-G9uNzwYL.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1239
1341
|
);
|
1240
1342
|
const ProtectedListViewPage = React.lazy(
|
1241
|
-
() => Promise.resolve().then(() => require("./ListViewPage-
|
1343
|
+
() => Promise.resolve().then(() => require("./ListViewPage-I88Ouzoq.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1242
1344
|
);
|
1243
1345
|
const ProtectedListConfiguration = React.lazy(
|
1244
|
-
() => Promise.resolve().then(() => require("./ListConfigurationPage-
|
1346
|
+
() => Promise.resolve().then(() => require("./ListConfigurationPage-BynalOp8.js")).then((mod) => ({
|
1245
1347
|
default: mod.ProtectedListConfiguration
|
1246
1348
|
}))
|
1247
1349
|
);
|
1248
1350
|
const ProtectedEditConfigurationPage = React.lazy(
|
1249
|
-
() => Promise.resolve().then(() => require("./EditConfigurationPage-
|
1351
|
+
() => Promise.resolve().then(() => require("./EditConfigurationPage-_aG2DJSU.js")).then((mod) => ({
|
1250
1352
|
default: mod.ProtectedEditConfigurationPage
|
1251
1353
|
}))
|
1252
1354
|
);
|
1253
1355
|
const ProtectedComponentConfigurationPage = React.lazy(
|
1254
|
-
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-
|
1356
|
+
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-_zF8p6CY.js")).then((mod) => ({
|
1255
1357
|
default: mod.ProtectedComponentConfigurationPage
|
1256
1358
|
}))
|
1257
1359
|
);
|
1258
1360
|
const NoPermissions = React.lazy(
|
1259
|
-
() => Promise.resolve().then(() => require("./NoPermissionsPage-
|
1361
|
+
() => Promise.resolve().then(() => require("./NoPermissionsPage-DCVUh5at.js")).then((mod) => ({ default: mod.NoPermissions }))
|
1260
1362
|
);
|
1261
1363
|
const NoContentType = React.lazy(
|
1262
|
-
() => Promise.resolve().then(() => require("./NoContentTypePage-
|
1364
|
+
() => Promise.resolve().then(() => require("./NoContentTypePage-BaWQ7HsA.js")).then((mod) => ({ default: mod.NoContentType }))
|
1263
1365
|
);
|
1264
1366
|
const CollectionTypePages = () => {
|
1265
1367
|
const { collectionType } = reactRouterDom.useParams();
|
@@ -1373,12 +1475,14 @@ const DocumentActionButton = (action) => {
|
|
1373
1475
|
/* @__PURE__ */ jsxRuntime.jsx(
|
1374
1476
|
designSystem.Button,
|
1375
1477
|
{
|
1376
|
-
flex:
|
1478
|
+
flex: "auto",
|
1377
1479
|
startIcon: action.icon,
|
1378
1480
|
disabled: action.disabled,
|
1379
1481
|
onClick: handleClick(action),
|
1380
1482
|
justifyContent: "center",
|
1381
1483
|
variant: action.variant || "default",
|
1484
|
+
paddingTop: "7px",
|
1485
|
+
paddingBottom: "7px",
|
1382
1486
|
children: action.label
|
1383
1487
|
}
|
1384
1488
|
),
|
@@ -1386,7 +1490,7 @@ const DocumentActionButton = (action) => {
|
|
1386
1490
|
DocumentActionConfirmDialog,
|
1387
1491
|
{
|
1388
1492
|
...action.dialog,
|
1389
|
-
variant: action.variant,
|
1493
|
+
variant: action.dialog?.variant ?? action.variant,
|
1390
1494
|
isOpen: dialogId === action.id,
|
1391
1495
|
onClose: handleClose
|
1392
1496
|
}
|
@@ -1443,13 +1547,13 @@ const DocumentActionsMenu = ({
|
|
1443
1547
|
disabled: isDisabled,
|
1444
1548
|
size: "S",
|
1445
1549
|
endIcon: null,
|
1446
|
-
paddingTop: "
|
1447
|
-
paddingLeft: "
|
1448
|
-
paddingRight: "
|
1550
|
+
paddingTop: "4px",
|
1551
|
+
paddingLeft: "7px",
|
1552
|
+
paddingRight: "7px",
|
1449
1553
|
variant,
|
1450
1554
|
children: [
|
1451
1555
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.More, { "aria-hidden": true, focusable: false }),
|
1452
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, {
|
1556
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { tag: "span", children: label || formatMessage({
|
1453
1557
|
id: "content-manager.containers.edit.panels.default.more-actions",
|
1454
1558
|
defaultMessage: "More document actions"
|
1455
1559
|
}) })
|
@@ -1465,10 +1569,25 @@ const DocumentActionsMenu = ({
|
|
1465
1569
|
onSelect: handleClick(action),
|
1466
1570
|
display: "block",
|
1467
1571
|
children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", gap: 4, children: [
|
1468
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1572
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
1573
|
+
designSystem.Flex,
|
1574
|
+
{
|
1575
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1576
|
+
gap: 2,
|
1577
|
+
tag: "span",
|
1578
|
+
children: [
|
1579
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
1580
|
+
designSystem.Flex,
|
1581
|
+
{
|
1582
|
+
tag: "span",
|
1583
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1584
|
+
children: action.icon
|
1585
|
+
}
|
1586
|
+
),
|
1587
|
+
action.label
|
1588
|
+
]
|
1589
|
+
}
|
1590
|
+
),
|
1472
1591
|
action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsxRuntime.jsx(
|
1473
1592
|
designSystem.Flex,
|
1474
1593
|
{
|
@@ -1527,6 +1646,18 @@ const convertActionVariantToColor = (variant = "secondary") => {
|
|
1527
1646
|
return "primary600";
|
1528
1647
|
}
|
1529
1648
|
};
|
1649
|
+
const convertActionVariantToIconColor = (variant = "secondary") => {
|
1650
|
+
switch (variant) {
|
1651
|
+
case "danger":
|
1652
|
+
return "danger600";
|
1653
|
+
case "secondary":
|
1654
|
+
return "neutral500";
|
1655
|
+
case "success":
|
1656
|
+
return "success600";
|
1657
|
+
default:
|
1658
|
+
return "primary600";
|
1659
|
+
}
|
1660
|
+
};
|
1530
1661
|
const DocumentActionConfirmDialog = ({
|
1531
1662
|
onClose,
|
1532
1663
|
onCancel,
|
@@ -1549,61 +1680,42 @@ const DocumentActionConfirmDialog = ({
|
|
1549
1680
|
}
|
1550
1681
|
onClose();
|
1551
1682
|
};
|
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
|
-
] });
|
1683
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
1684
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
1685
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: content }),
|
1686
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
|
1687
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", fullWidth: true, children: formatMessage({
|
1688
|
+
id: "app.components.Button.cancel",
|
1689
|
+
defaultMessage: "Cancel"
|
1690
|
+
}) }) }),
|
1691
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
|
1692
|
+
id: "app.components.Button.confirm",
|
1693
|
+
defaultMessage: "Confirm"
|
1694
|
+
}) })
|
1695
|
+
] })
|
1696
|
+
] }) });
|
1568
1697
|
};
|
1569
1698
|
const DocumentActionModal = ({
|
1570
1699
|
isOpen,
|
1571
1700
|
title,
|
1572
1701
|
onClose,
|
1573
1702
|
footer: Footer,
|
1574
|
-
content,
|
1703
|
+
content: Content,
|
1575
1704
|
onModalClose
|
1576
1705
|
}) => {
|
1577
|
-
const id = React__namespace.useId();
|
1578
|
-
if (!isOpen) {
|
1579
|
-
return null;
|
1580
|
-
}
|
1581
1706
|
const handleClose = () => {
|
1582
1707
|
if (onClose) {
|
1583
1708
|
onClose();
|
1584
1709
|
}
|
1585
1710
|
onModalClose();
|
1586
1711
|
};
|
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
|
-
] });
|
1712
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Content, { children: [
|
1713
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Title, { children: title }) }),
|
1714
|
+
typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, { children: Content }),
|
1715
|
+
typeof Footer === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Footer, { onClose: handleClose }) : Footer
|
1716
|
+
] }) });
|
1605
1717
|
};
|
1606
|
-
const PublishAction = ({
|
1718
|
+
const PublishAction$1 = ({
|
1607
1719
|
activeTab,
|
1608
1720
|
documentId,
|
1609
1721
|
model,
|
@@ -1615,13 +1727,17 @@ const PublishAction = ({
|
|
1615
1727
|
const navigate = reactRouterDom.useNavigate();
|
1616
1728
|
const { toggleNotification } = strapiAdmin.useNotification();
|
1617
1729
|
const { _unstableFormatValidationErrors: formatValidationErrors } = strapiAdmin.useAPIErrorHandler();
|
1730
|
+
const isListView = reactRouterDom.useMatch(LIST_PATH) !== null;
|
1618
1731
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
1619
1732
|
const { formatMessage } = reactIntl.useIntl();
|
1620
|
-
const { canPublish
|
1621
|
-
"PublishAction",
|
1622
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1623
|
-
);
|
1733
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1624
1734
|
const { publish } = useDocumentActions();
|
1735
|
+
const [
|
1736
|
+
countDraftRelations,
|
1737
|
+
{ isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
|
1738
|
+
] = useLazyGetDraftRelationCountQuery();
|
1739
|
+
const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React__namespace.useState(0);
|
1740
|
+
const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React__namespace.useState(0);
|
1625
1741
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1626
1742
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
1627
1743
|
const modified = strapiAdmin.useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
@@ -1630,10 +1746,103 @@ const PublishAction = ({
|
|
1630
1746
|
const validate = strapiAdmin.useForm("PublishAction", (state) => state.validate);
|
1631
1747
|
const setErrors = strapiAdmin.useForm("PublishAction", (state) => state.setErrors);
|
1632
1748
|
const formValues = strapiAdmin.useForm("PublishAction", ({ values }) => values);
|
1749
|
+
React__namespace.useEffect(() => {
|
1750
|
+
if (isErrorDraftRelations) {
|
1751
|
+
toggleNotification({
|
1752
|
+
type: "danger",
|
1753
|
+
message: formatMessage({
|
1754
|
+
id: getTranslation("error.records.fetch-draft-relatons"),
|
1755
|
+
defaultMessage: "An error occurred while fetching draft relations on this document."
|
1756
|
+
})
|
1757
|
+
});
|
1758
|
+
}
|
1759
|
+
}, [isErrorDraftRelations, toggleNotification, formatMessage]);
|
1760
|
+
React__namespace.useEffect(() => {
|
1761
|
+
const localDraftRelations = /* @__PURE__ */ new Set();
|
1762
|
+
const extractDraftRelations = (data) => {
|
1763
|
+
const relations = data.connect || [];
|
1764
|
+
relations.forEach((relation) => {
|
1765
|
+
if (relation.status === "draft") {
|
1766
|
+
localDraftRelations.add(relation.id);
|
1767
|
+
}
|
1768
|
+
});
|
1769
|
+
};
|
1770
|
+
const traverseAndExtract = (data) => {
|
1771
|
+
Object.entries(data).forEach(([key, value]) => {
|
1772
|
+
if (key === "connect" && Array.isArray(value)) {
|
1773
|
+
extractDraftRelations({ connect: value });
|
1774
|
+
} else if (typeof value === "object" && value !== null) {
|
1775
|
+
traverseAndExtract(value);
|
1776
|
+
}
|
1777
|
+
});
|
1778
|
+
};
|
1779
|
+
if (!documentId || modified) {
|
1780
|
+
traverseAndExtract(formValues);
|
1781
|
+
setLocalCountOfDraftRelations(localDraftRelations.size);
|
1782
|
+
}
|
1783
|
+
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
1784
|
+
React__namespace.useEffect(() => {
|
1785
|
+
if (!document || !document.documentId || isListView) {
|
1786
|
+
return;
|
1787
|
+
}
|
1788
|
+
const fetchDraftRelationsCount = async () => {
|
1789
|
+
const { data, error } = await countDraftRelations({
|
1790
|
+
collectionType,
|
1791
|
+
model,
|
1792
|
+
documentId,
|
1793
|
+
params
|
1794
|
+
});
|
1795
|
+
if (error) {
|
1796
|
+
throw error;
|
1797
|
+
}
|
1798
|
+
if (data) {
|
1799
|
+
setServerCountOfDraftRelations(data.data);
|
1800
|
+
}
|
1801
|
+
};
|
1802
|
+
fetchDraftRelationsCount();
|
1803
|
+
}, [isListView, document, documentId, countDraftRelations, collectionType, model, params]);
|
1633
1804
|
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
1634
1805
|
if (!schema?.options?.draftAndPublish) {
|
1635
1806
|
return null;
|
1636
1807
|
}
|
1808
|
+
const performPublish = async () => {
|
1809
|
+
setSubmitting(true);
|
1810
|
+
try {
|
1811
|
+
const { errors } = await validate();
|
1812
|
+
if (errors) {
|
1813
|
+
toggleNotification({
|
1814
|
+
type: "danger",
|
1815
|
+
message: formatMessage({
|
1816
|
+
id: "content-manager.validation.error",
|
1817
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
1818
|
+
})
|
1819
|
+
});
|
1820
|
+
return;
|
1821
|
+
}
|
1822
|
+
const res = await publish(
|
1823
|
+
{
|
1824
|
+
collectionType,
|
1825
|
+
model,
|
1826
|
+
documentId,
|
1827
|
+
params
|
1828
|
+
},
|
1829
|
+
formValues
|
1830
|
+
);
|
1831
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1832
|
+
navigate({
|
1833
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1834
|
+
search: rawQuery
|
1835
|
+
});
|
1836
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1837
|
+
setErrors(formatValidationErrors(res.error));
|
1838
|
+
}
|
1839
|
+
} finally {
|
1840
|
+
setSubmitting(false);
|
1841
|
+
}
|
1842
|
+
};
|
1843
|
+
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
1844
|
+
const enableDraftRelationsCount = false;
|
1845
|
+
const hasDraftRelations = enableDraftRelationsCount;
|
1637
1846
|
return {
|
1638
1847
|
/**
|
1639
1848
|
* Disabled when:
|
@@ -1643,52 +1852,39 @@ const PublishAction = ({
|
|
1643
1852
|
* - the document is already published & not modified
|
1644
1853
|
* - the document is being created & not modified
|
1645
1854
|
* - the user doesn't have the permission to publish
|
1646
|
-
* - the user doesn't have the permission to create a new document
|
1647
|
-
* - the user doesn't have the permission to update the document
|
1648
1855
|
*/
|
1649
|
-
disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish
|
1856
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
1650
1857
|
label: formatMessage({
|
1651
1858
|
id: "app.utils.publish",
|
1652
1859
|
defaultMessage: "Publish"
|
1653
1860
|
}),
|
1654
1861
|
onClick: async () => {
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1659
|
-
|
1660
|
-
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
1664
|
-
|
1665
|
-
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1669
|
-
|
1670
|
-
|
1671
|
-
|
1672
|
-
documentId,
|
1673
|
-
params
|
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));
|
1862
|
+
await performPublish();
|
1863
|
+
},
|
1864
|
+
dialog: hasDraftRelations ? {
|
1865
|
+
type: "dialog",
|
1866
|
+
variant: "danger",
|
1867
|
+
footer: null,
|
1868
|
+
title: formatMessage({
|
1869
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
|
1870
|
+
defaultMessage: "Confirmation"
|
1871
|
+
}),
|
1872
|
+
content: formatMessage(
|
1873
|
+
{
|
1874
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
1875
|
+
defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
|
1876
|
+
},
|
1877
|
+
{
|
1878
|
+
count: totalDraftRelations
|
1684
1879
|
}
|
1685
|
-
|
1686
|
-
|
1880
|
+
),
|
1881
|
+
onConfirm: async () => {
|
1882
|
+
await performPublish();
|
1687
1883
|
}
|
1688
|
-
}
|
1884
|
+
} : void 0
|
1689
1885
|
};
|
1690
1886
|
};
|
1691
|
-
PublishAction.type = "publish";
|
1887
|
+
PublishAction$1.type = "publish";
|
1692
1888
|
const UpdateAction = ({
|
1693
1889
|
activeTab,
|
1694
1890
|
documentId,
|
@@ -1701,10 +1897,6 @@ const UpdateAction = ({
|
|
1701
1897
|
const cloneMatch = reactRouterDom.useMatch(CLONE_PATH);
|
1702
1898
|
const isCloning = cloneMatch !== null;
|
1703
1899
|
const { formatMessage } = reactIntl.useIntl();
|
1704
|
-
const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1705
|
-
canCreate: canCreate2,
|
1706
|
-
canUpdate: canUpdate2
|
1707
|
-
}));
|
1708
1900
|
const { create, update, clone } = useDocumentActions();
|
1709
1901
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1710
1902
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
@@ -1721,10 +1913,8 @@ const UpdateAction = ({
|
|
1721
1913
|
* - the form is submitting
|
1722
1914
|
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
1723
1915
|
* - 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
1916
|
*/
|
1727
|
-
disabled: isSubmitting || !modified && !isCloning || activeTab === "published"
|
1917
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1728
1918
|
label: formatMessage({
|
1729
1919
|
id: "content-manager.containers.Edit.save",
|
1730
1920
|
defaultMessage: "Save"
|
@@ -1732,16 +1922,18 @@ const UpdateAction = ({
|
|
1732
1922
|
onClick: async () => {
|
1733
1923
|
setSubmitting(true);
|
1734
1924
|
try {
|
1735
|
-
|
1736
|
-
|
1737
|
-
|
1738
|
-
|
1739
|
-
|
1740
|
-
|
1741
|
-
|
1742
|
-
|
1743
|
-
|
1744
|
-
|
1925
|
+
if (activeTab !== "draft") {
|
1926
|
+
const { errors } = await validate();
|
1927
|
+
if (errors) {
|
1928
|
+
toggleNotification({
|
1929
|
+
type: "danger",
|
1930
|
+
message: formatMessage({
|
1931
|
+
id: "content-manager.validation.error",
|
1932
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
1933
|
+
})
|
1934
|
+
});
|
1935
|
+
return;
|
1936
|
+
}
|
1745
1937
|
}
|
1746
1938
|
if (isCloning) {
|
1747
1939
|
const res = await clone(
|
@@ -1753,10 +1945,13 @@ const UpdateAction = ({
|
|
1753
1945
|
document
|
1754
1946
|
);
|
1755
1947
|
if ("data" in res) {
|
1756
|
-
navigate(
|
1757
|
-
|
1758
|
-
|
1759
|
-
|
1948
|
+
navigate(
|
1949
|
+
{
|
1950
|
+
pathname: `../${res.data.documentId}`,
|
1951
|
+
search: rawQuery
|
1952
|
+
},
|
1953
|
+
{ relative: "path" }
|
1954
|
+
);
|
1760
1955
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1761
1956
|
setErrors(formatValidationErrors(res.error));
|
1762
1957
|
}
|
@@ -1784,10 +1979,13 @@ const UpdateAction = ({
|
|
1784
1979
|
document
|
1785
1980
|
);
|
1786
1981
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1787
|
-
navigate(
|
1788
|
-
|
1789
|
-
|
1790
|
-
|
1982
|
+
navigate(
|
1983
|
+
{
|
1984
|
+
pathname: `../${res.data.documentId}`,
|
1985
|
+
search: rawQuery
|
1986
|
+
},
|
1987
|
+
{ replace: true, relative: "path" }
|
1988
|
+
);
|
1791
1989
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1792
1990
|
setErrors(formatValidationErrors(res.error));
|
1793
1991
|
}
|
@@ -1803,7 +2001,7 @@ const UNPUBLISH_DRAFT_OPTIONS = {
|
|
1803
2001
|
KEEP: "keep",
|
1804
2002
|
DISCARD: "discard"
|
1805
2003
|
};
|
1806
|
-
const UnpublishAction = ({
|
2004
|
+
const UnpublishAction$1 = ({
|
1807
2005
|
activeTab,
|
1808
2006
|
documentId,
|
1809
2007
|
model,
|
@@ -1819,10 +2017,8 @@ const UnpublishAction = ({
|
|
1819
2017
|
const { toggleNotification } = strapiAdmin.useNotification();
|
1820
2018
|
const [shouldKeepDraft, setShouldKeepDraft] = React__namespace.useState(true);
|
1821
2019
|
const isDocumentModified = document?.status === "modified";
|
1822
|
-
const handleChange = (
|
1823
|
-
|
1824
|
-
setShouldKeepDraft(e.target.value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1825
|
-
}
|
2020
|
+
const handleChange = (value) => {
|
2021
|
+
setShouldKeepDraft(value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1826
2022
|
};
|
1827
2023
|
if (!schema?.options?.draftAndPublish) {
|
1828
2024
|
return null;
|
@@ -1833,7 +2029,7 @@ const UnpublishAction = ({
|
|
1833
2029
|
id: "app.utils.unpublish",
|
1834
2030
|
defaultMessage: "Unpublish"
|
1835
2031
|
}),
|
1836
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2032
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Cross, {}),
|
1837
2033
|
onClick: async () => {
|
1838
2034
|
if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
|
1839
2035
|
if (!documentId) {
|
@@ -1866,45 +2062,30 @@ const UnpublishAction = ({
|
|
1866
2062
|
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "flex-start", direction: "column", gap: 6, children: [
|
1867
2063
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", direction: "column", gap: 2, children: [
|
1868
2064
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
1869
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2065
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
1870
2066
|
id: "content-manager.actions.unpublish.dialog.body",
|
1871
2067
|
defaultMessage: "Are you sure?"
|
1872
2068
|
}) })
|
1873
2069
|
] }),
|
1874
2070
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
1875
|
-
designSystem.
|
2071
|
+
designSystem.Radio.Group,
|
1876
2072
|
{
|
1877
|
-
|
1878
|
-
|
1879
|
-
|
1880
|
-
|
1881
|
-
|
2073
|
+
defaultValue: UNPUBLISH_DRAFT_OPTIONS.KEEP,
|
2074
|
+
name: "discard-options",
|
2075
|
+
"aria-label": formatMessage({
|
2076
|
+
id: "content-manager.actions.unpublish.dialog.radio-label",
|
2077
|
+
defaultMessage: "Choose an option to unpublish the document."
|
2078
|
+
}),
|
2079
|
+
onValueChange: handleChange,
|
1882
2080
|
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
|
-
)
|
2081
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Radio.Item, { checked: shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.KEEP, children: formatMessage({
|
2082
|
+
id: "content-manager.actions.unpublish.dialog.option.keep-draft",
|
2083
|
+
defaultMessage: "Keep draft"
|
2084
|
+
}) }),
|
2085
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Radio.Item, { checked: !shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.DISCARD, children: formatMessage({
|
2086
|
+
id: "content-manager.actions.unpublish.dialog.option.replace-draft",
|
2087
|
+
defaultMessage: "Replace draft"
|
2088
|
+
}) })
|
1908
2089
|
]
|
1909
2090
|
}
|
1910
2091
|
)
|
@@ -1937,7 +2118,7 @@ const UnpublishAction = ({
|
|
1937
2118
|
position: ["panel", "table-row"]
|
1938
2119
|
};
|
1939
2120
|
};
|
1940
|
-
UnpublishAction.type = "unpublish";
|
2121
|
+
UnpublishAction$1.type = "unpublish";
|
1941
2122
|
const DiscardAction = ({
|
1942
2123
|
activeTab,
|
1943
2124
|
documentId,
|
@@ -1960,7 +2141,7 @@ const DiscardAction = ({
|
|
1960
2141
|
id: "content-manager.actions.discard.label",
|
1961
2142
|
defaultMessage: "Discard changes"
|
1962
2143
|
}),
|
1963
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2144
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Cross, {}),
|
1964
2145
|
position: ["panel", "table-row"],
|
1965
2146
|
variant: "danger",
|
1966
2147
|
dialog: {
|
@@ -1971,7 +2152,7 @@ const DiscardAction = ({
|
|
1971
2152
|
}),
|
1972
2153
|
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, children: [
|
1973
2154
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
1974
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2155
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
1975
2156
|
id: "content-manager.actions.discard.dialog.body",
|
1976
2157
|
defaultMessage: "Are you sure?"
|
1977
2158
|
}) })
|
@@ -1988,12 +2169,7 @@ const DiscardAction = ({
|
|
1988
2169
|
};
|
1989
2170
|
};
|
1990
2171
|
DiscardAction.type = "discard";
|
1991
|
-
const
|
1992
|
-
path {
|
1993
|
-
fill: currentColor;
|
1994
|
-
}
|
1995
|
-
`;
|
1996
|
-
const DEFAULT_ACTIONS = [PublishAction, UpdateAction, UnpublishAction, DiscardAction];
|
2172
|
+
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
1997
2173
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
1998
2174
|
const RelativeTime = React__namespace.forwardRef(
|
1999
2175
|
({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {
|
@@ -2040,8 +2216,8 @@ const getDisplayName = ({
|
|
2040
2216
|
};
|
2041
2217
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2042
2218
|
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2043
|
-
const statusVariant = status === "draft" ? "
|
2044
|
-
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2219
|
+
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2220
|
+
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
2221
|
};
|
2046
2222
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
2047
2223
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2050,23 +2226,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
|
2050
2226
|
id: "content-manager.containers.edit.title.new",
|
2051
2227
|
defaultMessage: "Create an entry"
|
2052
2228
|
}) : documentTitle;
|
2053
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop:
|
2229
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2054
2230
|
/* @__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
|
2231
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2232
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
|
2233
|
+
/* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
|
2234
|
+
] }),
|
2235
|
+
status ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 1, children: /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
|
2070
2236
|
] });
|
2071
2237
|
};
|
2072
2238
|
const HeaderToolbar = () => {
|
@@ -2218,7 +2384,7 @@ const Information = ({ activeTab }) => {
|
|
2218
2384
|
borderColor: "neutral150",
|
2219
2385
|
direction: "column",
|
2220
2386
|
marginTop: 2,
|
2221
|
-
|
2387
|
+
tag: "dl",
|
2222
2388
|
padding: 5,
|
2223
2389
|
gap: 3,
|
2224
2390
|
alignItems: "flex-start",
|
@@ -2226,15 +2392,29 @@ const Information = ({ activeTab }) => {
|
|
2226
2392
|
marginRight: "-0.4rem",
|
2227
2393
|
width: "calc(100% + 8px)",
|
2228
2394
|
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, {
|
2395
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "dt", variant: "pi", fontWeight: "bold", children: info.label }),
|
2396
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "dd", variant: "pi", textColor: "neutral600", children: info.value })
|
2231
2397
|
] }, info.label))
|
2232
2398
|
}
|
2233
2399
|
);
|
2234
2400
|
};
|
2235
2401
|
const HeaderActions = ({ actions: actions2 }) => {
|
2236
|
-
|
2237
|
-
|
2402
|
+
const [dialogId, setDialogId] = React__namespace.useState(null);
|
2403
|
+
const handleClick = (action) => async (e) => {
|
2404
|
+
if (!("options" in action)) {
|
2405
|
+
const { onClick = () => false, dialog, id } = action;
|
2406
|
+
const muteDialog = await onClick(e);
|
2407
|
+
if (dialog && !muteDialog) {
|
2408
|
+
e.preventDefault();
|
2409
|
+
setDialogId(id);
|
2410
|
+
}
|
2411
|
+
}
|
2412
|
+
};
|
2413
|
+
const handleClose = () => {
|
2414
|
+
setDialogId(null);
|
2415
|
+
};
|
2416
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 1, children: actions2.map((action) => {
|
2417
|
+
if (action.options) {
|
2238
2418
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
2239
2419
|
designSystem.SingleSelect,
|
2240
2420
|
{
|
@@ -2248,10 +2428,49 @@ const HeaderActions = ({ actions: actions2 }) => {
|
|
2248
2428
|
action.id
|
2249
2429
|
);
|
2250
2430
|
} else {
|
2251
|
-
|
2431
|
+
if (action.type === "icon") {
|
2432
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
|
2433
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
2434
|
+
designSystem.IconButton,
|
2435
|
+
{
|
2436
|
+
disabled: action.disabled,
|
2437
|
+
label: action.label,
|
2438
|
+
size: "S",
|
2439
|
+
onClick: handleClick(action),
|
2440
|
+
children: action.icon
|
2441
|
+
}
|
2442
|
+
),
|
2443
|
+
action.dialog ? /* @__PURE__ */ jsxRuntime.jsx(
|
2444
|
+
HeaderActionDialog,
|
2445
|
+
{
|
2446
|
+
...action.dialog,
|
2447
|
+
isOpen: dialogId === action.id,
|
2448
|
+
onClose: handleClose
|
2449
|
+
}
|
2450
|
+
) : null
|
2451
|
+
] }, action.id);
|
2452
|
+
}
|
2252
2453
|
}
|
2253
2454
|
}) });
|
2254
2455
|
};
|
2456
|
+
const HeaderActionDialog = ({
|
2457
|
+
onClose,
|
2458
|
+
onCancel,
|
2459
|
+
title,
|
2460
|
+
content: Content,
|
2461
|
+
isOpen
|
2462
|
+
}) => {
|
2463
|
+
const handleClose = async () => {
|
2464
|
+
if (onCancel) {
|
2465
|
+
await onCancel();
|
2466
|
+
}
|
2467
|
+
onClose();
|
2468
|
+
};
|
2469
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
2470
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
2471
|
+
typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : Content
|
2472
|
+
] }) });
|
2473
|
+
};
|
2255
2474
|
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
2256
2475
|
const navigate = reactRouterDom.useNavigate();
|
2257
2476
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2260,7 +2479,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2260
2479
|
id: "app.links.configure-view",
|
2261
2480
|
defaultMessage: "Configure the view"
|
2262
2481
|
}),
|
2263
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2482
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ListPlus, {}),
|
2264
2483
|
onClick: () => {
|
2265
2484
|
navigate(`../${collectionType}/${model}/configurations/edit`);
|
2266
2485
|
},
|
@@ -2268,11 +2487,6 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2268
2487
|
};
|
2269
2488
|
};
|
2270
2489
|
ConfigureTheViewAction.type = "configure-the-view";
|
2271
|
-
const StyledCog = styled__default.default(Icons.Cog)`
|
2272
|
-
path {
|
2273
|
-
fill: currentColor;
|
2274
|
-
}
|
2275
|
-
`;
|
2276
2490
|
const EditTheModelAction = ({ model }) => {
|
2277
2491
|
const navigate = reactRouterDom.useNavigate();
|
2278
2492
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2281,7 +2495,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2281
2495
|
id: "content-manager.link-to-ctb",
|
2282
2496
|
defaultMessage: "Edit the model"
|
2283
2497
|
}),
|
2284
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2498
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, {}),
|
2285
2499
|
onClick: () => {
|
2286
2500
|
navigate(`/plugins/content-type-builder/content-types/${model}`);
|
2287
2501
|
},
|
@@ -2289,12 +2503,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2289
2503
|
};
|
2290
2504
|
};
|
2291
2505
|
EditTheModelAction.type = "edit-the-model";
|
2292
|
-
const
|
2293
|
-
path {
|
2294
|
-
fill: currentColor;
|
2295
|
-
}
|
2296
|
-
`;
|
2297
|
-
const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
2506
|
+
const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
2298
2507
|
const navigate = reactRouterDom.useNavigate();
|
2299
2508
|
const { formatMessage } = reactIntl.useIntl();
|
2300
2509
|
const listViewPathMatch = reactRouterDom.useMatch(LIST_PATH);
|
@@ -2308,7 +2517,7 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
|
2308
2517
|
id: "content-manager.actions.delete.label",
|
2309
2518
|
defaultMessage: "Delete document"
|
2310
2519
|
}),
|
2311
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2520
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {}),
|
2312
2521
|
dialog: {
|
2313
2522
|
type: "dialog",
|
2314
2523
|
title: formatMessage({
|
@@ -2317,7 +2526,7 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
|
2317
2526
|
}),
|
2318
2527
|
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, children: [
|
2319
2528
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
2320
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2529
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
2321
2530
|
id: "content-manager.actions.delete.dialog.body",
|
2322
2531
|
defaultMessage: "Are you sure?"
|
2323
2532
|
}) })
|
@@ -2362,13 +2571,8 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
|
2362
2571
|
position: ["header", "table-row"]
|
2363
2572
|
};
|
2364
2573
|
};
|
2365
|
-
DeleteAction.type = "delete";
|
2366
|
-
const
|
2367
|
-
path {
|
2368
|
-
fill: currentColor;
|
2369
|
-
}
|
2370
|
-
`;
|
2371
|
-
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction];
|
2574
|
+
DeleteAction$1.type = "delete";
|
2575
|
+
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2372
2576
|
const Panels = () => {
|
2373
2577
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2374
2578
|
const [
|
@@ -2402,7 +2606,7 @@ const ActionsPanel = () => {
|
|
2402
2606
|
return {
|
2403
2607
|
title: formatMessage({
|
2404
2608
|
id: "content-manager.containers.edit.panels.default.title",
|
2405
|
-
defaultMessage: "
|
2609
|
+
defaultMessage: "Entry"
|
2406
2610
|
}),
|
2407
2611
|
content: /* @__PURE__ */ jsxRuntime.jsx(ActionsPanelContent, {})
|
2408
2612
|
};
|
@@ -2442,7 +2646,7 @@ const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
|
2442
2646
|
designSystem.Flex,
|
2443
2647
|
{
|
2444
2648
|
ref,
|
2445
|
-
|
2649
|
+
tag: "aside",
|
2446
2650
|
"aria-labelledby": "additional-information",
|
2447
2651
|
background: "neutral0",
|
2448
2652
|
borderColor: "neutral150",
|
@@ -2457,87 +2661,975 @@ const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
|
2457
2661
|
justifyContent: "stretch",
|
2458
2662
|
alignItems: "flex-start",
|
2459
2663
|
children: [
|
2460
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2664
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2461
2665
|
children
|
2462
2666
|
]
|
2463
2667
|
}
|
2464
2668
|
);
|
2465
2669
|
});
|
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
|
-
] });
|
2670
|
+
const HOOKS = {
|
2671
|
+
/**
|
2672
|
+
* Hook that allows to mutate the displayed headers of the list view table
|
2673
|
+
* @constant
|
2674
|
+
* @type {string}
|
2675
|
+
*/
|
2676
|
+
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2677
|
+
/**
|
2678
|
+
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2679
|
+
* @constant
|
2680
|
+
* @type {string}
|
2681
|
+
*/
|
2682
|
+
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2683
|
+
/**
|
2684
|
+
* Hook that allows to mutate the CM's edit view layout
|
2685
|
+
* @constant
|
2686
|
+
* @type {string}
|
2687
|
+
*/
|
2688
|
+
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2689
|
+
/**
|
2690
|
+
* Hook that allows to mutate the CM's single types links pre-set filters
|
2691
|
+
* @constant
|
2692
|
+
* @type {string}
|
2693
|
+
*/
|
2694
|
+
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2519
2695
|
};
|
2520
|
-
const
|
2521
|
-
|
2522
|
-
|
2523
|
-
|
2524
|
-
|
2525
|
-
|
2526
|
-
|
2527
|
-
|
2528
|
-
|
2529
|
-
|
2530
|
-
|
2531
|
-
|
2532
|
-
|
2533
|
-
{
|
2534
|
-
|
2535
|
-
|
2536
|
-
|
2537
|
-
|
2538
|
-
|
2539
|
-
|
2540
|
-
}
|
2696
|
+
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2697
|
+
endpoints: (builder) => ({
|
2698
|
+
getContentTypeConfiguration: builder.query({
|
2699
|
+
query: (uid) => ({
|
2700
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
2701
|
+
method: "GET"
|
2702
|
+
}),
|
2703
|
+
transformResponse: (response) => response.data,
|
2704
|
+
providesTags: (_result, _error, uid) => [
|
2705
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
2706
|
+
{ type: "ContentTypeSettings", id: "LIST" }
|
2707
|
+
]
|
2708
|
+
}),
|
2709
|
+
getAllContentTypeSettings: builder.query({
|
2710
|
+
query: () => "/content-manager/content-types-settings",
|
2711
|
+
transformResponse: (response) => response.data,
|
2712
|
+
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2713
|
+
}),
|
2714
|
+
updateContentTypeConfiguration: builder.mutation({
|
2715
|
+
query: ({ uid, ...body }) => ({
|
2716
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
2717
|
+
method: "PUT",
|
2718
|
+
data: body
|
2719
|
+
}),
|
2720
|
+
transformResponse: (response) => response.data,
|
2721
|
+
invalidatesTags: (_result, _error, { uid }) => [
|
2722
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
2723
|
+
{ type: "ContentTypeSettings", id: "LIST" },
|
2724
|
+
// Is this necessary?
|
2725
|
+
{ type: "InitialData" }
|
2726
|
+
]
|
2727
|
+
})
|
2728
|
+
})
|
2729
|
+
});
|
2730
|
+
const {
|
2731
|
+
useGetContentTypeConfigurationQuery,
|
2732
|
+
useGetAllContentTypeSettingsQuery,
|
2733
|
+
useUpdateContentTypeConfigurationMutation
|
2734
|
+
} = contentTypesApi;
|
2735
|
+
const checkIfAttributeIsDisplayable = (attribute) => {
|
2736
|
+
const { type } = attribute;
|
2737
|
+
if (type === "relation") {
|
2738
|
+
return !attribute.relation.toLowerCase().includes("morph");
|
2739
|
+
}
|
2740
|
+
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2741
|
+
};
|
2742
|
+
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2743
|
+
if (!mainFieldName) {
|
2744
|
+
return void 0;
|
2745
|
+
}
|
2746
|
+
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2747
|
+
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2748
|
+
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2749
|
+
);
|
2750
|
+
return {
|
2751
|
+
name: mainFieldName,
|
2752
|
+
type: mainFieldType ?? "string"
|
2753
|
+
};
|
2754
|
+
};
|
2755
|
+
const DEFAULT_SETTINGS = {
|
2756
|
+
bulkable: false,
|
2757
|
+
filterable: false,
|
2758
|
+
searchable: false,
|
2759
|
+
pagination: false,
|
2760
|
+
defaultSortBy: "",
|
2761
|
+
defaultSortOrder: "asc",
|
2762
|
+
mainField: "id",
|
2763
|
+
pageSize: 10
|
2764
|
+
};
|
2765
|
+
const useDocumentLayout = (model) => {
|
2766
|
+
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2767
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
2768
|
+
const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2769
|
+
const { toggleNotification } = strapiAdmin.useNotification();
|
2770
|
+
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
2771
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2772
|
+
const {
|
2773
|
+
data,
|
2774
|
+
isLoading: isLoadingConfigs,
|
2775
|
+
error,
|
2776
|
+
isFetching: isFetchingConfigs
|
2777
|
+
} = useGetContentTypeConfigurationQuery(model);
|
2778
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2779
|
+
React__namespace.useEffect(() => {
|
2780
|
+
if (error) {
|
2781
|
+
toggleNotification({
|
2782
|
+
type: "danger",
|
2783
|
+
message: formatAPIError(error)
|
2784
|
+
});
|
2785
|
+
}
|
2786
|
+
}, [error, formatAPIError, toggleNotification]);
|
2787
|
+
const editLayout = React__namespace.useMemo(
|
2788
|
+
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2789
|
+
layout: [],
|
2790
|
+
components: {},
|
2791
|
+
metadatas: {},
|
2792
|
+
options: {},
|
2793
|
+
settings: DEFAULT_SETTINGS
|
2794
|
+
},
|
2795
|
+
[data, isLoading, schemas, schema, components]
|
2796
|
+
);
|
2797
|
+
const listLayout = React__namespace.useMemo(() => {
|
2798
|
+
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2799
|
+
layout: [],
|
2800
|
+
metadatas: {},
|
2801
|
+
options: {},
|
2802
|
+
settings: DEFAULT_SETTINGS
|
2803
|
+
};
|
2804
|
+
}, [data, isLoading, schemas, schema, components]);
|
2805
|
+
const { layout: edit } = React__namespace.useMemo(
|
2806
|
+
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2807
|
+
layout: editLayout,
|
2808
|
+
query
|
2809
|
+
}),
|
2810
|
+
[editLayout, query, runHookWaterfall]
|
2811
|
+
);
|
2812
|
+
return {
|
2813
|
+
error,
|
2814
|
+
isLoading,
|
2815
|
+
edit,
|
2816
|
+
list: listLayout
|
2817
|
+
};
|
2818
|
+
};
|
2819
|
+
const useDocLayout = () => {
|
2820
|
+
const { model } = useDoc();
|
2821
|
+
return useDocumentLayout(model);
|
2822
|
+
};
|
2823
|
+
const formatEditLayout = (data, {
|
2824
|
+
schemas,
|
2825
|
+
schema,
|
2826
|
+
components
|
2827
|
+
}) => {
|
2828
|
+
let currentPanelIndex = 0;
|
2829
|
+
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2830
|
+
data.contentType.layouts.edit,
|
2831
|
+
schema?.attributes,
|
2832
|
+
data.contentType.metadatas,
|
2833
|
+
{ configurations: data.components, schemas: components },
|
2834
|
+
schemas
|
2835
|
+
).reduce((panels, row) => {
|
2836
|
+
if (row.some((field) => field.type === "dynamiczone")) {
|
2837
|
+
panels.push([row]);
|
2838
|
+
currentPanelIndex += 2;
|
2839
|
+
} else {
|
2840
|
+
if (!panels[currentPanelIndex]) {
|
2841
|
+
panels.push([]);
|
2842
|
+
}
|
2843
|
+
panels[currentPanelIndex].push(row);
|
2844
|
+
}
|
2845
|
+
return panels;
|
2846
|
+
}, []);
|
2847
|
+
const componentEditAttributes = Object.entries(data.components).reduce(
|
2848
|
+
(acc, [uid, configuration]) => {
|
2849
|
+
acc[uid] = {
|
2850
|
+
layout: convertEditLayoutToFieldLayouts(
|
2851
|
+
configuration.layouts.edit,
|
2852
|
+
components[uid].attributes,
|
2853
|
+
configuration.metadatas,
|
2854
|
+
{ configurations: data.components, schemas: components }
|
2855
|
+
),
|
2856
|
+
settings: {
|
2857
|
+
...configuration.settings,
|
2858
|
+
icon: components[uid].info.icon,
|
2859
|
+
displayName: components[uid].info.displayName
|
2860
|
+
}
|
2861
|
+
};
|
2862
|
+
return acc;
|
2863
|
+
},
|
2864
|
+
{}
|
2865
|
+
);
|
2866
|
+
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2867
|
+
(acc, [attribute, metadata]) => {
|
2868
|
+
return {
|
2869
|
+
...acc,
|
2870
|
+
[attribute]: metadata.edit
|
2871
|
+
};
|
2872
|
+
},
|
2873
|
+
{}
|
2874
|
+
);
|
2875
|
+
return {
|
2876
|
+
layout: panelledEditAttributes,
|
2877
|
+
components: componentEditAttributes,
|
2878
|
+
metadatas: editMetadatas,
|
2879
|
+
settings: {
|
2880
|
+
...data.contentType.settings,
|
2881
|
+
displayName: schema?.info.displayName
|
2882
|
+
},
|
2883
|
+
options: {
|
2884
|
+
...schema?.options,
|
2885
|
+
...schema?.pluginOptions,
|
2886
|
+
...data.contentType.options
|
2887
|
+
}
|
2888
|
+
};
|
2889
|
+
};
|
2890
|
+
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
2891
|
+
return rows.map(
|
2892
|
+
(row) => row.map((field) => {
|
2893
|
+
const attribute = attributes[field.name];
|
2894
|
+
if (!attribute) {
|
2895
|
+
return null;
|
2896
|
+
}
|
2897
|
+
const { edit: metadata } = metadatas[field.name];
|
2898
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
2899
|
+
return {
|
2900
|
+
attribute,
|
2901
|
+
disabled: !metadata.editable,
|
2902
|
+
hint: metadata.description,
|
2903
|
+
label: metadata.label ?? "",
|
2904
|
+
name: field.name,
|
2905
|
+
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
2906
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
2907
|
+
schemas,
|
2908
|
+
components: components?.schemas ?? {}
|
2909
|
+
}),
|
2910
|
+
placeholder: metadata.placeholder ?? "",
|
2911
|
+
required: attribute.required ?? false,
|
2912
|
+
size: field.size,
|
2913
|
+
unique: "unique" in attribute ? attribute.unique : false,
|
2914
|
+
visible: metadata.visible ?? true,
|
2915
|
+
type: attribute.type
|
2916
|
+
};
|
2917
|
+
}).filter((field) => field !== null)
|
2918
|
+
);
|
2919
|
+
};
|
2920
|
+
const formatListLayout = (data, {
|
2921
|
+
schemas,
|
2922
|
+
schema,
|
2923
|
+
components
|
2924
|
+
}) => {
|
2925
|
+
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2926
|
+
(acc, [attribute, metadata]) => {
|
2927
|
+
return {
|
2928
|
+
...acc,
|
2929
|
+
[attribute]: metadata.list
|
2930
|
+
};
|
2931
|
+
},
|
2932
|
+
{}
|
2933
|
+
);
|
2934
|
+
const listAttributes = convertListLayoutToFieldLayouts(
|
2935
|
+
data.contentType.layouts.list,
|
2936
|
+
schema?.attributes,
|
2937
|
+
listMetadatas,
|
2938
|
+
{ configurations: data.components, schemas: components },
|
2939
|
+
schemas
|
2940
|
+
);
|
2941
|
+
return {
|
2942
|
+
layout: listAttributes,
|
2943
|
+
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
2944
|
+
metadatas: listMetadatas,
|
2945
|
+
options: {
|
2946
|
+
...schema?.options,
|
2947
|
+
...schema?.pluginOptions,
|
2948
|
+
...data.contentType.options
|
2949
|
+
}
|
2950
|
+
};
|
2951
|
+
};
|
2952
|
+
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
2953
|
+
return columns.map((name) => {
|
2954
|
+
const attribute = attributes[name];
|
2955
|
+
if (!attribute) {
|
2956
|
+
return null;
|
2957
|
+
}
|
2958
|
+
const metadata = metadatas[name];
|
2959
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
2960
|
+
return {
|
2961
|
+
attribute,
|
2962
|
+
label: metadata.label ?? "",
|
2963
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
2964
|
+
schemas,
|
2965
|
+
components: components?.schemas ?? {}
|
2966
|
+
}),
|
2967
|
+
name,
|
2968
|
+
searchable: metadata.searchable ?? true,
|
2969
|
+
sortable: metadata.sortable ?? true
|
2970
|
+
};
|
2971
|
+
}).filter((field) => field !== null);
|
2972
|
+
};
|
2973
|
+
const ConfirmBulkActionDialog = ({
|
2974
|
+
onToggleDialog,
|
2975
|
+
isOpen = false,
|
2976
|
+
dialogBody,
|
2977
|
+
endAction
|
2978
|
+
}) => {
|
2979
|
+
const { formatMessage } = reactIntl.useIntl();
|
2980
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
2981
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: formatMessage({
|
2982
|
+
id: "app.components.ConfirmDialog.title",
|
2983
|
+
defaultMessage: "Confirmation"
|
2984
|
+
}) }),
|
2985
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
2986
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
2987
|
+
dialogBody
|
2988
|
+
] }) }),
|
2989
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
|
2990
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { fullWidth: true, onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
|
2991
|
+
id: "app.components.Button.cancel",
|
2992
|
+
defaultMessage: "Cancel"
|
2993
|
+
}) }) }),
|
2994
|
+
endAction
|
2995
|
+
] })
|
2996
|
+
] }) });
|
2997
|
+
};
|
2998
|
+
const BoldChunk$1 = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
|
2999
|
+
const ConfirmDialogPublishAll = ({
|
3000
|
+
isOpen,
|
3001
|
+
onToggleDialog,
|
3002
|
+
isConfirmButtonLoading = false,
|
3003
|
+
onConfirm
|
3004
|
+
}) => {
|
3005
|
+
const { formatMessage } = reactIntl.useIntl();
|
3006
|
+
const selectedEntries = strapiAdmin.useTable("ConfirmDialogPublishAll", (state) => state.selectedRows);
|
3007
|
+
const { toggleNotification } = strapiAdmin.useNotification();
|
3008
|
+
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler(getTranslation);
|
3009
|
+
const { model, schema } = useDoc();
|
3010
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3011
|
+
const enableDraftRelationsCount = false;
|
3012
|
+
const {
|
3013
|
+
data: countDraftRelations = 0,
|
3014
|
+
isLoading,
|
3015
|
+
error
|
3016
|
+
} = useGetManyDraftRelationCountQuery(
|
3017
|
+
{
|
3018
|
+
model,
|
3019
|
+
documentIds: selectedEntries.map((entry) => entry.documentId),
|
3020
|
+
locale: query?.plugins?.i18n?.locale
|
3021
|
+
},
|
3022
|
+
{
|
3023
|
+
skip: !enableDraftRelationsCount
|
3024
|
+
}
|
3025
|
+
);
|
3026
|
+
React__namespace.useEffect(() => {
|
3027
|
+
if (error) {
|
3028
|
+
toggleNotification({ type: "danger", message: formatAPIError(error) });
|
3029
|
+
}
|
3030
|
+
}, [error, formatAPIError, toggleNotification]);
|
3031
|
+
if (error) {
|
3032
|
+
return null;
|
3033
|
+
}
|
3034
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
3035
|
+
ConfirmBulkActionDialog,
|
3036
|
+
{
|
3037
|
+
isOpen: isOpen && !isLoading,
|
3038
|
+
onToggleDialog,
|
3039
|
+
dialogBody: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
3040
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: [
|
3041
|
+
countDraftRelations > 0 && formatMessage(
|
3042
|
+
{
|
3043
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
3044
|
+
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. "
|
3045
|
+
},
|
3046
|
+
{
|
3047
|
+
b: BoldChunk$1,
|
3048
|
+
count: countDraftRelations,
|
3049
|
+
entities: selectedEntries.length
|
3050
|
+
}
|
3051
|
+
),
|
3052
|
+
formatMessage({
|
3053
|
+
id: getTranslation("popUpWarning.bodyMessage.contentType.publish.all"),
|
3054
|
+
defaultMessage: "Are you sure you want to publish these entries?"
|
3055
|
+
})
|
3056
|
+
] }),
|
3057
|
+
schema?.pluginOptions && "i18n" in schema.pluginOptions && schema?.pluginOptions.i18n && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", textAlign: "center", children: formatMessage(
|
3058
|
+
{
|
3059
|
+
id: getTranslation("Settings.list.actions.publishAdditionalInfos"),
|
3060
|
+
defaultMessage: "This will publish the active locale versions <em>(from Internationalization)</em>"
|
3061
|
+
},
|
3062
|
+
{
|
3063
|
+
em: Emphasis
|
3064
|
+
}
|
3065
|
+
) })
|
3066
|
+
] }),
|
3067
|
+
endAction: /* @__PURE__ */ jsxRuntime.jsx(
|
3068
|
+
designSystem.Button,
|
3069
|
+
{
|
3070
|
+
onClick: onConfirm,
|
3071
|
+
variant: "secondary",
|
3072
|
+
startIcon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Check, {}),
|
3073
|
+
loading: isConfirmButtonLoading,
|
3074
|
+
children: formatMessage({
|
3075
|
+
id: "app.utils.publish",
|
3076
|
+
defaultMessage: "Publish"
|
3077
|
+
})
|
3078
|
+
}
|
3079
|
+
)
|
3080
|
+
}
|
3081
|
+
);
|
3082
|
+
};
|
3083
|
+
const TypographyMaxWidth = styledComponents.styled(designSystem.Typography)`
|
3084
|
+
max-width: 300px;
|
3085
|
+
`;
|
3086
|
+
const formatErrorMessages = (errors, parentKey, formatMessage) => {
|
3087
|
+
const messages = [];
|
3088
|
+
Object.entries(errors).forEach(([key, value]) => {
|
3089
|
+
const currentKey = parentKey ? `${parentKey}.${key}` : key;
|
3090
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
3091
|
+
if ("id" in value && "defaultMessage" in value) {
|
3092
|
+
messages.push(
|
3093
|
+
formatMessage(
|
3094
|
+
{
|
3095
|
+
id: `${value.id}.withField`,
|
3096
|
+
defaultMessage: value.defaultMessage
|
3097
|
+
},
|
3098
|
+
{ field: currentKey }
|
3099
|
+
)
|
3100
|
+
);
|
3101
|
+
} else {
|
3102
|
+
messages.push(
|
3103
|
+
...formatErrorMessages(
|
3104
|
+
// @ts-expect-error TODO: check why value is not compatible with FormErrors
|
3105
|
+
value,
|
3106
|
+
currentKey,
|
3107
|
+
formatMessage
|
3108
|
+
)
|
3109
|
+
);
|
3110
|
+
}
|
3111
|
+
} else {
|
3112
|
+
messages.push(
|
3113
|
+
formatMessage(
|
3114
|
+
{
|
3115
|
+
id: `${value}.withField`,
|
3116
|
+
defaultMessage: value
|
3117
|
+
},
|
3118
|
+
{ field: currentKey }
|
3119
|
+
)
|
3120
|
+
);
|
3121
|
+
}
|
3122
|
+
});
|
3123
|
+
return messages;
|
3124
|
+
};
|
3125
|
+
const EntryValidationText = ({ validationErrors, status }) => {
|
3126
|
+
const { formatMessage } = reactIntl.useIntl();
|
3127
|
+
if (validationErrors) {
|
3128
|
+
const validationErrorsMessages = formatErrorMessages(validationErrors, "", formatMessage).join(
|
3129
|
+
" "
|
3130
|
+
);
|
3131
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3132
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.CrossCircle, { fill: "danger600" }),
|
3133
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsxRuntime.jsx(TypographyMaxWidth, { textColor: "danger600", variant: "omega", fontWeight: "semiBold", ellipsis: true, children: validationErrorsMessages }) })
|
3134
|
+
] });
|
3135
|
+
}
|
3136
|
+
if (status === "published") {
|
3137
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3138
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.CheckCircle, { fill: "success600" }),
|
3139
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
|
3140
|
+
id: "content-manager.bulk-publish.already-published",
|
3141
|
+
defaultMessage: "Already Published"
|
3142
|
+
}) })
|
3143
|
+
] });
|
3144
|
+
}
|
3145
|
+
if (status === "modified") {
|
3146
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3147
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.ArrowsCounterClockwise, { fill: "alternative600" }),
|
3148
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
|
3149
|
+
id: "content-manager.bulk-publish.modified",
|
3150
|
+
defaultMessage: "Ready to publish changes"
|
3151
|
+
}) })
|
3152
|
+
] });
|
3153
|
+
}
|
3154
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3155
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.CheckCircle, { fill: "success600" }),
|
3156
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
|
3157
|
+
id: "app.utils.ready-to-publish",
|
3158
|
+
defaultMessage: "Ready to publish"
|
3159
|
+
}) })
|
3160
|
+
] });
|
3161
|
+
};
|
3162
|
+
const TABLE_HEADERS = [
|
3163
|
+
{ name: "id", label: "id" },
|
3164
|
+
{ name: "name", label: "name" },
|
3165
|
+
{ name: "status", label: "status" },
|
3166
|
+
{ name: "publicationStatus", label: "Publication status" }
|
3167
|
+
];
|
3168
|
+
const SelectedEntriesTableContent = ({
|
3169
|
+
isPublishing,
|
3170
|
+
rowsToDisplay = [],
|
3171
|
+
entriesToPublish = [],
|
3172
|
+
validationErrors = {}
|
3173
|
+
}) => {
|
3174
|
+
const { pathname } = reactRouterDom.useLocation();
|
3175
|
+
const { formatMessage } = reactIntl.useIntl();
|
3176
|
+
const {
|
3177
|
+
list: {
|
3178
|
+
settings: { mainField }
|
3179
|
+
}
|
3180
|
+
} = useDocLayout();
|
3181
|
+
const shouldDisplayMainField = mainField != null && mainField !== "id";
|
3182
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Content, { children: [
|
3183
|
+
/* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Head, { children: [
|
3184
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.HeaderCheckboxCell, {}),
|
3185
|
+
TABLE_HEADERS.filter((head) => head.name !== "name" || shouldDisplayMainField).map(
|
3186
|
+
(head) => /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.HeaderCell, { ...head }, head.name)
|
3187
|
+
)
|
3188
|
+
] }),
|
3189
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Loading, {}),
|
3190
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Body, { children: rowsToDisplay.map((row, index2) => /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Row, { children: [
|
3191
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.CheckboxCell, { id: row.id }),
|
3192
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: row.id }) }),
|
3193
|
+
shouldDisplayMainField && /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: row[mainField] }) }),
|
3194
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: row.status, maxWidth: "min-content" }) }),
|
3195
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: isPublishing && entriesToPublish.includes(row.documentId) ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3196
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
|
3197
|
+
id: "content-manager.success.record.publishing",
|
3198
|
+
defaultMessage: "Publishing..."
|
3199
|
+
}) }),
|
3200
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, { small: true })
|
3201
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx(
|
3202
|
+
EntryValidationText,
|
3203
|
+
{
|
3204
|
+
validationErrors: validationErrors[row.documentId],
|
3205
|
+
status: row.status
|
3206
|
+
}
|
3207
|
+
) }),
|
3208
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
3209
|
+
designSystem.IconButton,
|
3210
|
+
{
|
3211
|
+
tag: reactRouterDom.Link,
|
3212
|
+
to: {
|
3213
|
+
pathname: `${pathname}/${row.documentId}`,
|
3214
|
+
search: row.locale && `?plugins[i18n][locale]=${row.locale}`
|
3215
|
+
},
|
3216
|
+
state: { from: pathname },
|
3217
|
+
label: formatMessage(
|
3218
|
+
{ id: "app.component.HelperPluginTable.edit", defaultMessage: "Edit {target}" },
|
3219
|
+
{
|
3220
|
+
target: formatMessage(
|
3221
|
+
{
|
3222
|
+
id: "content-manager.components.ListViewHelperPluginTable.row-line",
|
3223
|
+
defaultMessage: "item line {number}"
|
3224
|
+
},
|
3225
|
+
{ number: index2 + 1 }
|
3226
|
+
)
|
3227
|
+
}
|
3228
|
+
),
|
3229
|
+
target: "_blank",
|
3230
|
+
marginLeft: "auto",
|
3231
|
+
variant: "ghost",
|
3232
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, { width: "1.6rem", height: "1.6rem" })
|
3233
|
+
}
|
3234
|
+
) }) })
|
3235
|
+
] }, row.id)) })
|
3236
|
+
] });
|
3237
|
+
};
|
3238
|
+
const BoldChunk = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
|
3239
|
+
const SelectedEntriesModalContent = ({
|
3240
|
+
listViewSelectedEntries,
|
3241
|
+
toggleModal,
|
3242
|
+
setListViewSelectedDocuments,
|
3243
|
+
model
|
3244
|
+
}) => {
|
3245
|
+
const { formatMessage } = reactIntl.useIntl();
|
3246
|
+
const { schema, components } = useContentTypeSchema(model);
|
3247
|
+
const documentIds = listViewSelectedEntries.map(({ documentId }) => documentId);
|
3248
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3249
|
+
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
3250
|
+
const { data, isLoading, isFetching, refetch } = useGetAllDocumentsQuery(
|
3251
|
+
{
|
3252
|
+
model,
|
3253
|
+
params: {
|
3254
|
+
page: "1",
|
3255
|
+
pageSize: documentIds.length.toString(),
|
3256
|
+
sort: query.sort,
|
3257
|
+
filters: {
|
3258
|
+
documentId: {
|
3259
|
+
$in: documentIds
|
3260
|
+
}
|
3261
|
+
},
|
3262
|
+
locale: query.plugins?.i18n?.locale
|
3263
|
+
}
|
3264
|
+
},
|
3265
|
+
{
|
3266
|
+
selectFromResult: ({ data: data2, ...restRes }) => ({ data: data2?.results ?? [], ...restRes })
|
3267
|
+
}
|
3268
|
+
);
|
3269
|
+
const { rows, validationErrors } = React__namespace.useMemo(() => {
|
3270
|
+
if (data.length > 0 && schema) {
|
3271
|
+
const validate = createYupSchema(
|
3272
|
+
schema.attributes,
|
3273
|
+
components,
|
3274
|
+
// Since this is the "Publish" action, the validation
|
3275
|
+
// schema must enforce the rules for published entities
|
3276
|
+
{ status: "published" }
|
3277
|
+
);
|
3278
|
+
const validationErrors2 = {};
|
3279
|
+
const rows2 = data.map((entry) => {
|
3280
|
+
try {
|
3281
|
+
validate.validateSync(entry, { abortEarly: false });
|
3282
|
+
return entry;
|
3283
|
+
} catch (e) {
|
3284
|
+
if (e instanceof yup.ValidationError) {
|
3285
|
+
validationErrors2[entry.documentId] = strapiAdmin.getYupValidationErrors(e);
|
3286
|
+
}
|
3287
|
+
return entry;
|
3288
|
+
}
|
3289
|
+
});
|
3290
|
+
return { rows: rows2, validationErrors: validationErrors2 };
|
3291
|
+
}
|
3292
|
+
return {
|
3293
|
+
rows: [],
|
3294
|
+
validationErrors: {}
|
3295
|
+
};
|
3296
|
+
}, [components, data, schema]);
|
3297
|
+
const [publishedCount, setPublishedCount] = React__namespace.useState(0);
|
3298
|
+
const [isDialogOpen, setIsDialogOpen] = React__namespace.useState(false);
|
3299
|
+
const { publishMany: bulkPublishAction } = useDocumentActions();
|
3300
|
+
const [, { isLoading: isSubmittingForm }] = usePublishManyDocumentsMutation();
|
3301
|
+
const selectedRows = strapiAdmin.useTable("publishAction", (state) => state.selectedRows);
|
3302
|
+
const selectedEntries = rows.filter(
|
3303
|
+
(entry) => selectedRows.some((selectedEntry) => selectedEntry.documentId === entry.documentId)
|
3304
|
+
);
|
3305
|
+
const entriesToPublish = selectedEntries.filter((entry) => !validationErrors[entry.documentId]).map((entry) => entry.documentId);
|
3306
|
+
const selectedEntriesWithErrorsCount = selectedEntries.filter(
|
3307
|
+
({ documentId }) => validationErrors[documentId]
|
3308
|
+
).length;
|
3309
|
+
const selectedEntriesPublished = selectedEntries.filter(
|
3310
|
+
({ status }) => status === "published"
|
3311
|
+
).length;
|
3312
|
+
const selectedEntriesWithNoErrorsCount = selectedEntries.length - selectedEntriesWithErrorsCount - selectedEntriesPublished;
|
3313
|
+
const toggleDialog = () => setIsDialogOpen((prev) => !prev);
|
3314
|
+
const handleConfirmBulkPublish = async () => {
|
3315
|
+
toggleDialog();
|
3316
|
+
const res = await bulkPublishAction({ model, documentIds: entriesToPublish, params });
|
3317
|
+
if (!("error" in res)) {
|
3318
|
+
setPublishedCount(res.count);
|
3319
|
+
const unpublishedEntries = rows.filter((row) => {
|
3320
|
+
return !entriesToPublish.includes(row.documentId);
|
3321
|
+
});
|
3322
|
+
setListViewSelectedDocuments(unpublishedEntries);
|
3323
|
+
}
|
3324
|
+
};
|
3325
|
+
const getFormattedCountMessage = () => {
|
3326
|
+
if (publishedCount) {
|
3327
|
+
return formatMessage(
|
3328
|
+
{
|
3329
|
+
id: getTranslation("containers.list.selectedEntriesModal.publishedCount"),
|
3330
|
+
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."
|
3331
|
+
},
|
3332
|
+
{
|
3333
|
+
publishedCount,
|
3334
|
+
withErrorsCount: selectedEntriesWithErrorsCount,
|
3335
|
+
b: BoldChunk
|
3336
|
+
}
|
3337
|
+
);
|
3338
|
+
}
|
3339
|
+
return formatMessage(
|
3340
|
+
{
|
3341
|
+
id: getTranslation("containers.list.selectedEntriesModal.selectedCount"),
|
3342
|
+
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."
|
3343
|
+
},
|
3344
|
+
{
|
3345
|
+
readyToPublishCount: selectedEntriesWithNoErrorsCount,
|
3346
|
+
withErrorsCount: selectedEntriesWithErrorsCount,
|
3347
|
+
alreadyPublishedCount: selectedEntriesPublished,
|
3348
|
+
b: BoldChunk
|
3349
|
+
}
|
3350
|
+
);
|
3351
|
+
};
|
3352
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
3353
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Body, { children: [
|
3354
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: getFormattedCountMessage() }),
|
3355
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 5, children: /* @__PURE__ */ jsxRuntime.jsx(
|
3356
|
+
SelectedEntriesTableContent,
|
3357
|
+
{
|
3358
|
+
isPublishing: isSubmittingForm,
|
3359
|
+
rowsToDisplay: rows,
|
3360
|
+
entriesToPublish,
|
3361
|
+
validationErrors
|
3362
|
+
}
|
3363
|
+
) })
|
3364
|
+
] }),
|
3365
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
3366
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
|
3367
|
+
id: "app.components.Button.cancel",
|
3368
|
+
defaultMessage: "Cancel"
|
3369
|
+
}) }),
|
3370
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3371
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
|
3372
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
3373
|
+
designSystem.Button,
|
3374
|
+
{
|
3375
|
+
onClick: toggleDialog,
|
3376
|
+
disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
|
3377
|
+
loading: isSubmittingForm,
|
3378
|
+
children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
|
3379
|
+
}
|
3380
|
+
)
|
3381
|
+
] })
|
3382
|
+
] }),
|
3383
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
3384
|
+
ConfirmDialogPublishAll,
|
3385
|
+
{
|
3386
|
+
isOpen: isDialogOpen,
|
3387
|
+
onToggleDialog: toggleDialog,
|
3388
|
+
isConfirmButtonLoading: isSubmittingForm,
|
3389
|
+
onConfirm: handleConfirmBulkPublish
|
3390
|
+
}
|
3391
|
+
)
|
3392
|
+
] });
|
3393
|
+
};
|
3394
|
+
const PublishAction = ({ documents, model }) => {
|
3395
|
+
const { formatMessage } = reactIntl.useIntl();
|
3396
|
+
const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
|
3397
|
+
const showPublishButton = hasPublishPermission && documents.some(({ status }) => status !== "published");
|
3398
|
+
const setListViewSelectedDocuments = strapiAdmin.useTable("publishAction", (state) => state.selectRow);
|
3399
|
+
const refetchList = () => {
|
3400
|
+
contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
|
3401
|
+
};
|
3402
|
+
if (!showPublishButton)
|
3403
|
+
return null;
|
3404
|
+
return {
|
3405
|
+
actionType: "publish",
|
3406
|
+
variant: "tertiary",
|
3407
|
+
label: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" }),
|
3408
|
+
dialog: {
|
3409
|
+
type: "modal",
|
3410
|
+
title: formatMessage({
|
3411
|
+
id: getTranslation("containers.ListPage.selectedEntriesModal.title"),
|
3412
|
+
defaultMessage: "Publish entries"
|
3413
|
+
}),
|
3414
|
+
content: ({ onClose }) => {
|
3415
|
+
return /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Root, { rows: documents, defaultSelectedRows: documents, headers: TABLE_HEADERS, children: /* @__PURE__ */ jsxRuntime.jsx(
|
3416
|
+
SelectedEntriesModalContent,
|
3417
|
+
{
|
3418
|
+
listViewSelectedEntries: documents,
|
3419
|
+
toggleModal: () => {
|
3420
|
+
onClose();
|
3421
|
+
refetchList();
|
3422
|
+
},
|
3423
|
+
setListViewSelectedDocuments,
|
3424
|
+
model
|
3425
|
+
}
|
3426
|
+
) });
|
3427
|
+
},
|
3428
|
+
onClose: () => {
|
3429
|
+
refetchList();
|
3430
|
+
}
|
3431
|
+
}
|
3432
|
+
};
|
3433
|
+
};
|
3434
|
+
const BulkActionsRenderer = () => {
|
3435
|
+
const plugins = strapiAdmin.useStrapiApp("BulkActionsRenderer", (state) => state.plugins);
|
3436
|
+
const { model, collectionType } = useDoc();
|
3437
|
+
const { selectedRows } = strapiAdmin.useTable("BulkActionsRenderer", (state) => state);
|
3438
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
|
3439
|
+
strapiAdmin.DescriptionComponentRenderer,
|
3440
|
+
{
|
3441
|
+
props: {
|
3442
|
+
model,
|
3443
|
+
collectionType,
|
3444
|
+
documents: selectedRows
|
3445
|
+
},
|
3446
|
+
descriptions: plugins["content-manager"].apis.getBulkActions(),
|
3447
|
+
children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActionButton, { ...action }, action.id))
|
3448
|
+
}
|
3449
|
+
) });
|
3450
|
+
};
|
3451
|
+
const DeleteAction = ({ documents, model }) => {
|
3452
|
+
const { formatMessage } = reactIntl.useIntl();
|
3453
|
+
const { schema: contentType } = useDoc();
|
3454
|
+
const selectRow = strapiAdmin.useTable("DeleteAction", (state) => state.selectRow);
|
3455
|
+
const hasI18nEnabled = Boolean(contentType?.pluginOptions?.i18n);
|
3456
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3457
|
+
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
3458
|
+
const hasDeletePermission = useDocumentRBAC("deleteAction", (state) => state.canDelete);
|
3459
|
+
const { deleteMany: bulkDeleteAction } = useDocumentActions();
|
3460
|
+
const documentIds = documents.map(({ documentId }) => documentId);
|
3461
|
+
const handleConfirmBulkDelete = async () => {
|
3462
|
+
const res = await bulkDeleteAction({
|
3463
|
+
documentIds,
|
3464
|
+
model,
|
3465
|
+
params
|
3466
|
+
});
|
3467
|
+
if (!("error" in res)) {
|
3468
|
+
selectRow([]);
|
3469
|
+
}
|
3470
|
+
};
|
3471
|
+
if (!hasDeletePermission)
|
3472
|
+
return null;
|
3473
|
+
return {
|
3474
|
+
variant: "danger-light",
|
3475
|
+
label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
|
3476
|
+
dialog: {
|
3477
|
+
type: "dialog",
|
3478
|
+
title: formatMessage({
|
3479
|
+
id: "app.components.ConfirmDialog.title",
|
3480
|
+
defaultMessage: "Confirmation"
|
3481
|
+
}),
|
3482
|
+
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3483
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3484
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
|
3485
|
+
id: "popUpWarning.bodyMessage.contentType.delete.all",
|
3486
|
+
defaultMessage: "Are you sure you want to delete these entries?"
|
3487
|
+
}) }),
|
3488
|
+
hasI18nEnabled && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", children: formatMessage(
|
3489
|
+
{
|
3490
|
+
id: getTranslation("Settings.list.actions.deleteAdditionalInfos"),
|
3491
|
+
defaultMessage: "This will delete the active locale versions <em>(from Internationalization)</em>"
|
3492
|
+
},
|
3493
|
+
{
|
3494
|
+
em: Emphasis
|
3495
|
+
}
|
3496
|
+
) }) })
|
3497
|
+
] }),
|
3498
|
+
onConfirm: handleConfirmBulkDelete
|
3499
|
+
}
|
3500
|
+
};
|
3501
|
+
};
|
3502
|
+
DeleteAction.type = "delete";
|
3503
|
+
const UnpublishAction = ({ documents, model }) => {
|
3504
|
+
const { formatMessage } = reactIntl.useIntl();
|
3505
|
+
const { schema } = useDoc();
|
3506
|
+
const selectRow = strapiAdmin.useTable("UnpublishAction", (state) => state.selectRow);
|
3507
|
+
const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
|
3508
|
+
const hasI18nEnabled = Boolean(schema?.pluginOptions?.i18n);
|
3509
|
+
const hasDraftAndPublishEnabled = Boolean(schema?.options?.draftAndPublish);
|
3510
|
+
const { unpublishMany: bulkUnpublishAction } = useDocumentActions();
|
3511
|
+
const documentIds = documents.map(({ documentId }) => documentId);
|
3512
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3513
|
+
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
3514
|
+
const handleConfirmBulkUnpublish = async () => {
|
3515
|
+
const data = await bulkUnpublishAction({ documentIds, model, params });
|
3516
|
+
if (!("error" in data)) {
|
3517
|
+
selectRow([]);
|
3518
|
+
}
|
3519
|
+
};
|
3520
|
+
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
|
3521
|
+
if (!showUnpublishButton)
|
3522
|
+
return null;
|
3523
|
+
return {
|
3524
|
+
variant: "tertiary",
|
3525
|
+
label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
|
3526
|
+
dialog: {
|
3527
|
+
type: "dialog",
|
3528
|
+
title: formatMessage({
|
3529
|
+
id: "app.components.ConfirmDialog.title",
|
3530
|
+
defaultMessage: "Confirmation"
|
3531
|
+
}),
|
3532
|
+
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3533
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3534
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
|
3535
|
+
id: "popUpWarning.bodyMessage.contentType.unpublish.all",
|
3536
|
+
defaultMessage: "Are you sure you want to unpublish these entries?"
|
3537
|
+
}) }),
|
3538
|
+
hasI18nEnabled && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", children: formatMessage(
|
3539
|
+
{
|
3540
|
+
id: getTranslation("Settings.list.actions.unpublishAdditionalInfos"),
|
3541
|
+
defaultMessage: "This will unpublish the active locale versions <em>(from Internationalization)</em>"
|
3542
|
+
},
|
3543
|
+
{
|
3544
|
+
em: Emphasis
|
3545
|
+
}
|
3546
|
+
) }) })
|
3547
|
+
] }),
|
3548
|
+
confirmButton: formatMessage({
|
3549
|
+
id: "app.utils.unpublish",
|
3550
|
+
defaultMessage: "Unpublish"
|
3551
|
+
}),
|
3552
|
+
onConfirm: handleConfirmBulkUnpublish
|
3553
|
+
}
|
3554
|
+
};
|
3555
|
+
};
|
3556
|
+
UnpublishAction.type = "unpublish";
|
3557
|
+
const Emphasis = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", textColor: "danger500", children: chunks });
|
3558
|
+
const DEFAULT_BULK_ACTIONS = [PublishAction, UnpublishAction, DeleteAction];
|
3559
|
+
const AutoCloneFailureModalBody = ({ prohibitedFields }) => {
|
3560
|
+
const { formatMessage } = reactIntl.useIntl();
|
3561
|
+
const getDefaultErrorMessage = (reason) => {
|
3562
|
+
switch (reason) {
|
3563
|
+
case "relation":
|
3564
|
+
return "Duplicating the relation could remove it from the original entry.";
|
3565
|
+
case "unique":
|
3566
|
+
return "Identical values in a unique field are not allowed";
|
3567
|
+
default:
|
3568
|
+
return reason;
|
3569
|
+
}
|
3570
|
+
};
|
3571
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
3572
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", children: formatMessage({
|
3573
|
+
id: getTranslation("containers.list.autoCloneModal.title"),
|
3574
|
+
defaultMessage: "This entry can't be duplicated directly."
|
3575
|
+
}) }),
|
3576
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", children: formatMessage({
|
3577
|
+
id: getTranslation("containers.list.autoCloneModal.description"),
|
3578
|
+
defaultMessage: "A new entry will be created with the same content, but you'll have to change the following fields to save it."
|
3579
|
+
}) }) }),
|
3580
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { marginTop: 6, gap: 2, direction: "column", alignItems: "stretch", children: prohibitedFields.map(([fieldPath, reason]) => /* @__PURE__ */ jsxRuntime.jsxs(
|
3581
|
+
designSystem.Flex,
|
3582
|
+
{
|
3583
|
+
direction: "column",
|
3584
|
+
gap: 2,
|
3585
|
+
alignItems: "flex-start",
|
3586
|
+
borderColor: "neutral200",
|
3587
|
+
hasRadius: true,
|
3588
|
+
padding: 6,
|
3589
|
+
children: [
|
3590
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "row", tag: "ol", children: fieldPath.map((pathSegment, index2) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { fontWeight: "semiBold", tag: "li", children: [
|
3591
|
+
pathSegment,
|
3592
|
+
index2 !== fieldPath.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(
|
3593
|
+
Icons.ChevronRight,
|
3594
|
+
{
|
3595
|
+
fill: "neutral500",
|
3596
|
+
height: "0.8rem",
|
3597
|
+
width: "0.8rem",
|
3598
|
+
style: { margin: "0 0.8rem" }
|
3599
|
+
}
|
3600
|
+
)
|
3601
|
+
] }, index2)) }),
|
3602
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", textColor: "neutral600", children: formatMessage({
|
3603
|
+
id: getTranslation(`containers.list.autoCloneModal.error.${reason}`),
|
3604
|
+
defaultMessage: getDefaultErrorMessage(reason)
|
3605
|
+
}) })
|
3606
|
+
]
|
3607
|
+
},
|
3608
|
+
fieldPath.join()
|
3609
|
+
)) })
|
3610
|
+
] });
|
3611
|
+
};
|
3612
|
+
const TableActions = ({ document }) => {
|
3613
|
+
const { formatMessage } = reactIntl.useIntl();
|
3614
|
+
const { model, collectionType } = useDoc();
|
3615
|
+
const plugins = strapiAdmin.useStrapiApp("TableActions", (state) => state.plugins);
|
3616
|
+
const props = {
|
3617
|
+
activeTab: null,
|
3618
|
+
model,
|
3619
|
+
documentId: document.documentId,
|
3620
|
+
collectionType,
|
3621
|
+
document
|
3622
|
+
};
|
3623
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
3624
|
+
strapiAdmin.DescriptionComponentRenderer,
|
3625
|
+
{
|
3626
|
+
props,
|
3627
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
3628
|
+
children: (actions2) => {
|
3629
|
+
const tableRowActions = actions2.filter((action) => {
|
3630
|
+
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
3631
|
+
return positions.includes("table-row");
|
3632
|
+
});
|
2541
3633
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
2542
3634
|
DocumentActionsMenu,
|
2543
3635
|
{
|
@@ -2591,7 +3683,7 @@ const EditAction = ({ documentId }) => {
|
|
2591
3683
|
};
|
2592
3684
|
};
|
2593
3685
|
EditAction.type = "edit";
|
2594
|
-
const StyledPencil =
|
3686
|
+
const StyledPencil = styledComponents.styled(Icons.Pencil)`
|
2595
3687
|
path {
|
2596
3688
|
fill: currentColor;
|
2597
3689
|
}
|
@@ -2643,7 +3735,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
2643
3735
|
}),
|
2644
3736
|
content: /* @__PURE__ */ jsxRuntime.jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
2645
3737
|
footer: ({ onClose }) => {
|
2646
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.
|
3738
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
2647
3739
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
2648
3740
|
id: "cancel",
|
2649
3741
|
defaultMessage: "Cancel"
|
@@ -2651,7 +3743,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
2651
3743
|
/* @__PURE__ */ jsxRuntime.jsx(
|
2652
3744
|
designSystem.LinkButton,
|
2653
3745
|
{
|
2654
|
-
|
3746
|
+
tag: reactRouterDom.NavLink,
|
2655
3747
|
to: {
|
2656
3748
|
pathname: `clone/${documentId}`
|
2657
3749
|
},
|
@@ -2667,7 +3759,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
2667
3759
|
};
|
2668
3760
|
};
|
2669
3761
|
CloneAction.type = "clone";
|
2670
|
-
const StyledDuplicate =
|
3762
|
+
const StyledDuplicate = styledComponents.styled(Icons.Duplicate)`
|
2671
3763
|
path {
|
2672
3764
|
fill: currentColor;
|
2673
3765
|
}
|
@@ -2684,442 +3776,183 @@ class ContentManagerPlugin {
|
|
2684
3776
|
documentActions = [
|
2685
3777
|
...DEFAULT_ACTIONS,
|
2686
3778
|
...DEFAULT_TABLE_ROW_ACTIONS,
|
2687
|
-
...DEFAULT_HEADER_ACTIONS
|
2688
|
-
HistoryAction
|
3779
|
+
...DEFAULT_HEADER_ACTIONS
|
2689
3780
|
];
|
2690
3781
|
editViewSidePanels = [ActionsPanel];
|
2691
3782
|
headerActions = [];
|
2692
3783
|
constructor() {
|
2693
3784
|
}
|
2694
3785
|
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);
|
3786
|
+
if (Array.isArray(panels)) {
|
3787
|
+
this.editViewSidePanels = [...this.editViewSidePanels, ...panels];
|
3788
|
+
} else if (typeof panels === "function") {
|
3789
|
+
this.editViewSidePanels = panels(this.editViewSidePanels);
|
2725
3790
|
} else {
|
2726
3791
|
throw new Error(
|
2727
|
-
`Expected the \`
|
2728
|
-
|
3792
|
+
`Expected the \`panels\` passed to \`addEditViewSidePanel\` to be an array or a function, but received ${getPrintableType(
|
3793
|
+
panels
|
2729
3794
|
)}`
|
2730
3795
|
);
|
2731
3796
|
}
|
2732
3797
|
}
|
2733
|
-
|
3798
|
+
addDocumentAction(actions2) {
|
2734
3799
|
if (Array.isArray(actions2)) {
|
2735
|
-
this.
|
3800
|
+
this.documentActions = [...this.documentActions, ...actions2];
|
2736
3801
|
} else if (typeof actions2 === "function") {
|
2737
|
-
this.
|
3802
|
+
this.documentActions = actions2(this.documentActions);
|
2738
3803
|
} else {
|
2739
3804
|
throw new Error(
|
2740
|
-
`Expected the \`actions\` passed to \`
|
3805
|
+
`Expected the \`actions\` passed to \`addDocumentAction\` to be an array or a function, but received ${getPrintableType(
|
2741
3806
|
actions2
|
2742
|
-
)}`
|
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;
|
3807
|
+
)}`
|
3808
|
+
);
|
3809
|
+
}
|
3810
|
+
}
|
3811
|
+
addDocumentHeaderAction(actions2) {
|
3812
|
+
if (Array.isArray(actions2)) {
|
3813
|
+
this.headerActions = [...this.headerActions, ...actions2];
|
3814
|
+
} else if (typeof actions2 === "function") {
|
3815
|
+
this.headerActions = actions2(this.headerActions);
|
2982
3816
|
} else {
|
2983
|
-
|
2984
|
-
|
2985
|
-
|
2986
|
-
|
3817
|
+
throw new Error(
|
3818
|
+
`Expected the \`actions\` passed to \`addDocumentHeaderAction\` to be an array or a function, but received ${getPrintableType(
|
3819
|
+
actions2
|
3820
|
+
)}`
|
3821
|
+
);
|
2987
3822
|
}
|
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
|
3823
|
+
}
|
3824
|
+
addBulkAction(actions2) {
|
3825
|
+
if (Array.isArray(actions2)) {
|
3826
|
+
this.bulkActions = [...this.bulkActions, ...actions2];
|
3827
|
+
} else if (typeof actions2 === "function") {
|
3828
|
+
this.bulkActions = actions2(this.bulkActions);
|
3829
|
+
} else {
|
3830
|
+
throw new Error(
|
3831
|
+
`Expected the \`actions\` passed to \`addBulkAction\` to be an array or a function, but received ${getPrintableType(
|
3832
|
+
actions2
|
3833
|
+
)}`
|
3834
|
+
);
|
3029
3835
|
}
|
3030
|
-
}
|
3031
|
-
|
3032
|
-
|
3033
|
-
|
3034
|
-
|
3035
|
-
|
3036
|
-
|
3037
|
-
|
3836
|
+
}
|
3837
|
+
get config() {
|
3838
|
+
return {
|
3839
|
+
id: PLUGIN_ID,
|
3840
|
+
name: "Content Manager",
|
3841
|
+
injectionZones: INJECTION_ZONES,
|
3842
|
+
apis: {
|
3843
|
+
addBulkAction: this.addBulkAction.bind(this),
|
3844
|
+
addDocumentAction: this.addDocumentAction.bind(this),
|
3845
|
+
addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
|
3846
|
+
addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
|
3847
|
+
getBulkActions: () => this.bulkActions,
|
3848
|
+
getDocumentActions: () => this.documentActions,
|
3849
|
+
getEditViewSidePanels: () => this.editViewSidePanels,
|
3850
|
+
getHeaderActions: () => this.headerActions
|
3038
3851
|
}
|
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
|
-
);
|
3852
|
+
};
|
3853
|
+
}
|
3854
|
+
}
|
3855
|
+
const getPrintableType = (value) => {
|
3856
|
+
const nativeType = typeof value;
|
3857
|
+
if (nativeType === "object") {
|
3858
|
+
if (value === null)
|
3859
|
+
return "null";
|
3860
|
+
if (Array.isArray(value))
|
3861
|
+
return "array";
|
3862
|
+
if (value instanceof Object && value.constructor.name !== "Object") {
|
3863
|
+
return value.constructor.name;
|
3864
|
+
}
|
3865
|
+
}
|
3866
|
+
return nativeType;
|
3061
3867
|
};
|
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
|
-
);
|
3868
|
+
const HistoryAction = ({ model, document }) => {
|
3869
|
+
const { formatMessage } = reactIntl.useIntl();
|
3870
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3871
|
+
const navigate = reactRouterDom.useNavigate();
|
3872
|
+
const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
|
3873
|
+
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3874
|
+
return null;
|
3875
|
+
}
|
3083
3876
|
return {
|
3084
|
-
|
3085
|
-
|
3086
|
-
|
3087
|
-
|
3088
|
-
|
3089
|
-
|
3090
|
-
|
3091
|
-
|
3877
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
|
3878
|
+
label: formatMessage({
|
3879
|
+
id: "content-manager.history.document-action",
|
3880
|
+
defaultMessage: "Content History"
|
3881
|
+
}),
|
3882
|
+
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
3883
|
+
disabled: (
|
3884
|
+
/**
|
3885
|
+
* The user is creating a new document.
|
3886
|
+
* It hasn't been saved yet, so there's no history to go to
|
3887
|
+
*/
|
3888
|
+
!document || /**
|
3889
|
+
* The document has been created but the current dimension has never been saved.
|
3890
|
+
* For example, the user is creating a new locale in an existing document,
|
3891
|
+
* so there's no history for the document in that locale
|
3892
|
+
*/
|
3893
|
+
!document.id || /**
|
3894
|
+
* History is only available for content types created by the user.
|
3895
|
+
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
3896
|
+
* which start with `admin::` or `plugin::`
|
3897
|
+
*/
|
3898
|
+
!model.startsWith("api::")
|
3899
|
+
),
|
3900
|
+
position: "header"
|
3092
3901
|
};
|
3093
3902
|
};
|
3094
|
-
|
3095
|
-
|
3096
|
-
|
3097
|
-
|
3098
|
-
|
3099
|
-
|
3100
|
-
|
3101
|
-
|
3102
|
-
|
3103
|
-
|
3104
|
-
|
3105
|
-
|
3106
|
-
|
3107
|
-
|
3108
|
-
|
3109
|
-
|
3110
|
-
|
3111
|
-
|
3112
|
-
};
|
3113
|
-
}).filter((field) => field !== null);
|
3903
|
+
HistoryAction.type = "history";
|
3904
|
+
const historyAdmin = {
|
3905
|
+
bootstrap(app) {
|
3906
|
+
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
3907
|
+
addDocumentAction((actions2) => {
|
3908
|
+
const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
|
3909
|
+
actions2.splice(indexOfDeleteAction, 0, HistoryAction);
|
3910
|
+
return actions2;
|
3911
|
+
});
|
3912
|
+
}
|
3913
|
+
};
|
3914
|
+
const initialState = {
|
3915
|
+
collectionTypeLinks: [],
|
3916
|
+
components: [],
|
3917
|
+
fieldSizes: {},
|
3918
|
+
models: [],
|
3919
|
+
singleTypeLinks: [],
|
3920
|
+
isLoading: true
|
3114
3921
|
};
|
3922
|
+
const appSlice = toolkit.createSlice({
|
3923
|
+
name: "app",
|
3924
|
+
initialState,
|
3925
|
+
reducers: {
|
3926
|
+
setInitialData(state, action) {
|
3927
|
+
const {
|
3928
|
+
authorizedCollectionTypeLinks,
|
3929
|
+
authorizedSingleTypeLinks,
|
3930
|
+
components,
|
3931
|
+
contentTypeSchemas,
|
3932
|
+
fieldSizes
|
3933
|
+
} = action.payload;
|
3934
|
+
state.collectionTypeLinks = authorizedCollectionTypeLinks.filter(
|
3935
|
+
({ isDisplayed }) => isDisplayed
|
3936
|
+
);
|
3937
|
+
state.singleTypeLinks = authorizedSingleTypeLinks.filter(({ isDisplayed }) => isDisplayed);
|
3938
|
+
state.components = components;
|
3939
|
+
state.models = contentTypeSchemas;
|
3940
|
+
state.fieldSizes = fieldSizes;
|
3941
|
+
state.isLoading = false;
|
3942
|
+
}
|
3943
|
+
}
|
3944
|
+
});
|
3945
|
+
const { actions, reducer: reducer$1 } = appSlice;
|
3946
|
+
const { setInitialData } = actions;
|
3947
|
+
const reducer = toolkit.combineReducers({
|
3948
|
+
app: reducer$1
|
3949
|
+
});
|
3115
3950
|
const index = {
|
3116
3951
|
register(app) {
|
3117
3952
|
const cm = new ContentManagerPlugin();
|
3118
3953
|
app.addReducers({
|
3119
|
-
[contentManagerApi.reducerPath]: contentManagerApi.reducer,
|
3120
3954
|
[PLUGIN_ID]: reducer
|
3121
3955
|
});
|
3122
|
-
app.addMiddlewares([() => contentManagerApi.middleware]);
|
3123
3956
|
app.addMenuLink({
|
3124
3957
|
to: PLUGIN_ID,
|
3125
3958
|
icon: Icons.Feather,
|
@@ -3128,14 +3961,29 @@ const index = {
|
|
3128
3961
|
defaultMessage: "Content Manager"
|
3129
3962
|
},
|
3130
3963
|
permissions: [],
|
3131
|
-
|
3964
|
+
position: 1
|
3965
|
+
});
|
3966
|
+
app.router.addRoute({
|
3967
|
+
path: "content-manager/*",
|
3968
|
+
lazy: async () => {
|
3969
|
+
const { Layout } = await Promise.resolve().then(() => require("./layout-CYA7s0qO.js"));
|
3970
|
+
return {
|
3971
|
+
Component: Layout
|
3972
|
+
};
|
3973
|
+
},
|
3974
|
+
children: routes
|
3132
3975
|
});
|
3133
3976
|
app.registerPlugin(cm.config);
|
3134
3977
|
},
|
3978
|
+
bootstrap(app) {
|
3979
|
+
if (typeof historyAdmin.bootstrap === "function") {
|
3980
|
+
historyAdmin.bootstrap(app);
|
3981
|
+
}
|
3982
|
+
},
|
3135
3983
|
async registerTrads({ locales }) {
|
3136
3984
|
const importedTrads = await Promise.all(
|
3137
3985
|
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-
|
3986
|
+
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-BVzUkPxZ.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
3987
|
return {
|
3140
3988
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3141
3989
|
locale
|
@@ -3152,6 +4000,8 @@ const index = {
|
|
3152
4000
|
}
|
3153
4001
|
};
|
3154
4002
|
exports.ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD = ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD;
|
4003
|
+
exports.BulkActionsRenderer = BulkActionsRenderer;
|
4004
|
+
exports.CLONE_PATH = CLONE_PATH;
|
3155
4005
|
exports.COLLECTION_TYPES = COLLECTION_TYPES;
|
3156
4006
|
exports.CREATOR_FIELDS = CREATOR_FIELDS;
|
3157
4007
|
exports.DEFAULT_SETTINGS = DEFAULT_SETTINGS;
|
@@ -3178,7 +4028,6 @@ exports.getDisplayName = getDisplayName;
|
|
3178
4028
|
exports.getMainField = getMainField;
|
3179
4029
|
exports.getTranslation = getTranslation;
|
3180
4030
|
exports.index = index;
|
3181
|
-
exports.routes = routes;
|
3182
4031
|
exports.setInitialData = setInitialData;
|
3183
4032
|
exports.useContentTypeSchema = useContentTypeSchema;
|
3184
4033
|
exports.useDoc = useDoc;
|
@@ -3192,4 +4041,4 @@ exports.useGetAllDocumentsQuery = useGetAllDocumentsQuery;
|
|
3192
4041
|
exports.useGetContentTypeConfigurationQuery = useGetContentTypeConfigurationQuery;
|
3193
4042
|
exports.useGetInitialDataQuery = useGetInitialDataQuery;
|
3194
4043
|
exports.useUpdateContentTypeConfigurationMutation = useUpdateContentTypeConfigurationMutation;
|
3195
|
-
//# sourceMappingURL=index-
|
4044
|
+
//# sourceMappingURL=index-BhbLFX4l.js.map
|