@strapi/content-manager 0.0.0-experimental.e60ec1829240dae21c1e1d29076681c322288813 → 0.0.0-experimental.f31889311d753b5f7d95198ae84d8fce1d156cd6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +18 -3
- package/dist/_chunks/{CardDragPreview-DSVYodBX.js → CardDragPreview-C0QyJgRA.js} +10 -14
- package/dist/_chunks/CardDragPreview-C0QyJgRA.js.map +1 -0
- package/dist/_chunks/{CardDragPreview-ikSG4M46.mjs → CardDragPreview-DOxamsuj.mjs} +7 -9
- package/dist/_chunks/CardDragPreview-DOxamsuj.mjs.map +1 -0
- package/dist/_chunks/{ComponentConfigurationPage-DjWJdz6Y.js → ComponentConfigurationPage-BNxtMIfV.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-DjWJdz6Y.js.map → ComponentConfigurationPage-BNxtMIfV.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-BPvzFjM7.mjs → ComponentConfigurationPage-BWOQWCv2.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-BPvzFjM7.mjs.map → ComponentConfigurationPage-BWOQWCv2.mjs.map} +1 -1
- package/dist/_chunks/{ComponentIcon-BBQsYCVn.js → ComponentIcon-BXdiCGQp.js} +8 -2
- package/dist/_chunks/ComponentIcon-BXdiCGQp.js.map +1 -0
- package/dist/_chunks/{ComponentIcon-BOFnK76n.mjs → ComponentIcon-u4bIXTFY.mjs} +9 -3
- package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +1 -0
- package/dist/_chunks/{EditConfigurationPage-Dmv83RlS.js → EditConfigurationPage-D340bYlT.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-Dmv83RlS.js.map → EditConfigurationPage-D340bYlT.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-DacbqQ_f.mjs → EditConfigurationPage-GTp-Ucnw.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-DacbqQ_f.mjs.map → EditConfigurationPage-GTp-Ucnw.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-DDS6H9HO.mjs → EditViewPage-BVMS5hT-.mjs} +47 -47
- package/dist/_chunks/EditViewPage-BVMS5hT-.mjs.map +1 -0
- package/dist/_chunks/{EditViewPage-DvNpQkam.js → EditViewPage-CXkmnAvI.js} +46 -48
- package/dist/_chunks/EditViewPage-CXkmnAvI.js.map +1 -0
- package/dist/_chunks/{Field-DmVKIAOo.js → Field-Ibi32diw.js} +953 -782
- package/dist/_chunks/Field-Ibi32diw.js.map +1 -0
- package/dist/_chunks/{Field-6gvGdPBV.mjs → Field-nNgv5bpd.mjs} +901 -729
- package/dist/_chunks/Field-nNgv5bpd.mjs.map +1 -0
- package/dist/_chunks/{Form-CPZC9vWa.js → Form-Dhnh34ym.js} +39 -38
- package/dist/_chunks/Form-Dhnh34ym.js.map +1 -0
- package/dist/_chunks/{Form-DW6K1IH-.mjs → Form-DodJsI2A.mjs} +39 -37
- package/dist/_chunks/Form-DodJsI2A.mjs.map +1 -0
- package/dist/_chunks/{History-DeAPlvtv.js → History-C9auUkDi.js} +149 -56
- package/dist/_chunks/History-C9auUkDi.js.map +1 -0
- package/dist/_chunks/{History-Dmr9fmUA.mjs → History-CKCSQXz_.mjs} +148 -54
- package/dist/_chunks/History-CKCSQXz_.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DPCwW5Vr.js → ListConfigurationPage-Bg4rWUjX.js} +58 -59
- package/dist/_chunks/ListConfigurationPage-Bg4rWUjX.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DhwvYcNv.mjs → ListConfigurationPage-CKEC4ttG.mjs} +54 -54
- package/dist/_chunks/ListConfigurationPage-CKEC4ttG.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-BtAwuYLE.mjs → ListViewPage-B7_WJUjG.mjs} +93 -104
- package/dist/_chunks/ListViewPage-B7_WJUjG.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-5ySZ-VUs.js → ListViewPage-C2gIeYHG.js} +98 -109
- package/dist/_chunks/ListViewPage-C2gIeYHG.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DSPxnxxp.mjs → NoContentTypePage-Ckem6Ll6.mjs} +3 -3
- package/dist/_chunks/NoContentTypePage-Ckem6Ll6.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DOC_yWOf.js → NoContentTypePage-DqgdUfyn.js} +3 -3
- package/dist/_chunks/NoContentTypePage-DqgdUfyn.js.map +1 -0
- package/dist/_chunks/{NoPermissionsPage-UWDC-1Tw.mjs → NoPermissionsPage-BO-GEjA4.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-UWDC-1Tw.mjs.map → NoPermissionsPage-BO-GEjA4.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-Dwu8rRJu.js → NoPermissionsPage-CF29Q-sW.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-Dwu8rRJu.js.map → NoPermissionsPage-CF29Q-sW.js.map} +1 -1
- package/dist/_chunks/{Relations-CgWtgnPe.js → Relations-C0uC9J4f.js} +70 -61
- package/dist/_chunks/Relations-C0uC9J4f.js.map +1 -0
- package/dist/_chunks/{Relations-J8cscLlR.mjs → Relations-DItV5eow.mjs} +66 -56
- package/dist/_chunks/Relations-DItV5eow.mjs.map +1 -0
- package/dist/_chunks/{en-MBPul9Su.mjs → en-BrCTWlZv.mjs} +11 -4
- package/dist/_chunks/{en-MBPul9Su.mjs.map → en-BrCTWlZv.mjs.map} +1 -1
- package/dist/_chunks/{en-C-V1_90f.js → en-uOUIxfcQ.js} +11 -4
- package/dist/_chunks/{en-C-V1_90f.js.map → en-uOUIxfcQ.js.map} +1 -1
- package/dist/_chunks/{index-C6AH2hEl.js → index-Dd0nXyJF.js} +1649 -905
- package/dist/_chunks/index-Dd0nXyJF.js.map +1 -0
- package/dist/_chunks/{index-CwRRo1V9.mjs → index-DrNe6ctw.mjs} +1671 -926
- package/dist/_chunks/index-DrNe6ctw.mjs.map +1 -0
- package/dist/_chunks/{layout-jIDzX0Fp.mjs → layout-B3ez7kvr.mjs} +43 -26
- package/dist/_chunks/layout-B3ez7kvr.mjs.map +1 -0
- package/dist/_chunks/{layout-B_SXLhqf.js → layout-CLLtt_5O.js} +43 -28
- package/dist/_chunks/layout-CLLtt_5O.js.map +1 -0
- package/dist/_chunks/{relations-CuvIgCqI.mjs → relations-B0hlsUU_.mjs} +2 -2
- package/dist/_chunks/{relations-CuvIgCqI.mjs.map → relations-B0hlsUU_.mjs.map} +1 -1
- package/dist/_chunks/{relations-iBMa_OFG.js → relations-bRxcNv1q.js} +2 -2
- package/dist/_chunks/{relations-iBMa_OFG.js.map → relations-bRxcNv1q.js.map} +1 -1
- package/dist/_chunks/useDragAndDrop-DdHgKsqq.mjs.map +1 -1
- package/dist/_chunks/useDragAndDrop-J0TUUbR6.js.map +1 -1
- package/dist/_chunks/usePrev-B9w_-eYc.js +15 -0
- package/dist/_chunks/usePrev-B9w_-eYc.js.map +1 -0
- package/dist/_chunks/usePrev-DH6iah0A.mjs +16 -0
- package/dist/_chunks/usePrev-DH6iah0A.mjs.map +1 -0
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +5 -4
- package/dist/admin/src/components/ComponentIcon.d.ts +6 -3
- package/dist/admin/src/content-manager.d.ts +3 -3
- package/dist/admin/src/exports.d.ts +1 -0
- package/dist/admin/src/history/components/VersionInputRenderer.d.ts +1 -1
- package/dist/admin/src/history/index.d.ts +3 -0
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +5 -8
- package/dist/admin/src/hooks/useDocumentActions.d.ts +24 -3
- package/dist/admin/src/hooks/useDocumentLayout.d.ts +2 -2
- package/dist/admin/src/hooks/useDragAndDrop.d.ts +4 -4
- package/dist/admin/src/hooks/useKeyboardDragAndDrop.d.ts +1 -1
- package/dist/admin/src/index.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +11 -4
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.d.ts +3 -3
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +4 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Component/Input.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.d.ts +3 -5
- package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/Field.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +30 -18
- package/dist/admin/src/pages/EditView/components/FormInputs/UID.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +3 -49
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/Field.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +59 -52
- package/dist/admin/src/pages/EditView/components/InputRenderer.d.ts +2 -10
- package/dist/admin/src/pages/ListView/components/BulkActions/Actions.d.ts +3 -30
- package/dist/admin/src/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.d.ts +2 -2
- package/dist/admin/src/pages/ListView/components/BulkActions/PublishAction.d.ts +9 -26
- package/dist/admin/src/services/api.d.ts +2 -3
- package/dist/admin/src/services/components.d.ts +2 -2
- package/dist/admin/src/services/contentTypes.d.ts +5 -5
- package/dist/admin/src/services/documents.d.ts +29 -17
- package/dist/admin/src/services/init.d.ts +2 -2
- package/dist/admin/src/services/relations.d.ts +3 -3
- package/dist/admin/src/services/uid.d.ts +3 -3
- package/dist/admin/src/utils/api.d.ts +4 -18
- package/dist/admin/src/utils/validation.d.ts +1 -6
- package/dist/server/index.js +392 -261
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +400 -269
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/controllers/single-types.d.ts.map +1 -1
- package/dist/server/src/controllers/uid.d.ts.map +1 -1
- package/dist/server/src/controllers/utils/metadata.d.ts +8 -0
- package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -0
- package/dist/server/src/controllers/validation/dimensions.d.ts +11 -0
- package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -0
- package/dist/server/src/controllers/validation/index.d.ts +1 -1
- package/dist/server/src/history/services/history.d.ts.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
- package/dist/server/src/history/services/utils.d.ts +1 -1
- package/dist/server/src/history/services/utils.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +18 -39
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts +13 -12
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts +8 -29
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +18 -39
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/utils/populate.d.ts +8 -1
- package/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/dist/shared/contracts/collection-types.d.ts +14 -6
- package/dist/shared/contracts/collection-types.d.ts.map +1 -1
- package/dist/shared/contracts/relations.d.ts +2 -2
- package/dist/shared/contracts/relations.d.ts.map +1 -1
- package/package.json +13 -14
- package/dist/_chunks/CardDragPreview-DSVYodBX.js.map +0 -1
- package/dist/_chunks/CardDragPreview-ikSG4M46.mjs.map +0 -1
- package/dist/_chunks/ComponentIcon-BBQsYCVn.js.map +0 -1
- package/dist/_chunks/ComponentIcon-BOFnK76n.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-DDS6H9HO.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-DvNpQkam.js.map +0 -1
- package/dist/_chunks/Field-6gvGdPBV.mjs.map +0 -1
- package/dist/_chunks/Field-DmVKIAOo.js.map +0 -1
- package/dist/_chunks/Form-CPZC9vWa.js.map +0 -1
- package/dist/_chunks/Form-DW6K1IH-.mjs.map +0 -1
- package/dist/_chunks/History-DeAPlvtv.js.map +0 -1
- package/dist/_chunks/History-Dmr9fmUA.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DPCwW5Vr.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DhwvYcNv.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-5ySZ-VUs.js.map +0 -1
- package/dist/_chunks/ListViewPage-BtAwuYLE.mjs.map +0 -1
- package/dist/_chunks/NoContentTypePage-DOC_yWOf.js.map +0 -1
- package/dist/_chunks/NoContentTypePage-DSPxnxxp.mjs.map +0 -1
- package/dist/_chunks/Relations-CgWtgnPe.js.map +0 -1
- package/dist/_chunks/Relations-J8cscLlR.mjs.map +0 -1
- package/dist/_chunks/index-C6AH2hEl.js.map +0 -1
- package/dist/_chunks/index-CwRRo1V9.mjs.map +0 -1
- package/dist/_chunks/layout-B_SXLhqf.js.map +0 -1
- package/dist/_chunks/layout-jIDzX0Fp.mjs.map +0 -1
- package/dist/_chunks/urls-CbOsUOoW.mjs +0 -7
- package/dist/_chunks/urls-CbOsUOoW.mjs.map +0 -1
- package/dist/_chunks/urls-DzZya_gm.js +0 -6
- package/dist/_chunks/urls-DzZya_gm.js.map +0 -1
- package/dist/server/src/controllers/utils/dimensions.d.ts +0 -5
- package/dist/server/src/controllers/utils/dimensions.d.ts.map +0 -1
@@ -1,19 +1,17 @@
|
|
1
|
-
import {
|
1
|
+
import { CrossCircle, More, WarningCircle, ListPlus, Pencil, Trash, Check, CheckCircle, ArrowsCounterClockwise, ChevronRight, Duplicate, ClockCounterClockwise, Feather } from "@strapi/icons";
|
2
2
|
import { jsx, Fragment, jsxs } from "react/jsx-runtime";
|
3
|
-
import { useStrapiApp,
|
4
|
-
import { stringify } from "qs";
|
5
|
-
import { useIntl } from "react-intl";
|
6
|
-
import { useNavigate, useParams, Navigate, useMatch, NavLink } from "react-router-dom";
|
3
|
+
import { useStrapiApp, createContext, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, getYupValidationErrors, useQueryParams, useTracking, useForm, BackButton, DescriptionComponentRenderer, useTable, Table } from "@strapi/admin/strapi-admin";
|
7
4
|
import * as React from "react";
|
8
5
|
import { lazy } from "react";
|
9
|
-
import { Menu, VisuallyHidden, Flex, Typography, Dialog,
|
10
|
-
import
|
6
|
+
import { Button, Menu, VisuallyHidden, Flex, Typography, Dialog, Modal, Radio, Status, Box, SingleSelect, SingleSelectOption, Loader, IconButton, Tooltip, LinkButton } from "@strapi/design-system";
|
7
|
+
import { useIntl } from "react-intl";
|
8
|
+
import { useParams, Navigate, useNavigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
|
9
|
+
import { styled } from "styled-components";
|
11
10
|
import * as yup from "yup";
|
12
11
|
import { ValidationError } from "yup";
|
13
|
-
import { createApi } from "@reduxjs/toolkit/query/react";
|
14
|
-
import { isAxiosError } from "axios";
|
15
12
|
import pipe from "lodash/fp/pipe";
|
16
13
|
import { intervalToDuration, isPast } from "date-fns";
|
14
|
+
import { stringify } from "qs";
|
17
15
|
import { createSlice, combineReducers } from "@reduxjs/toolkit";
|
18
16
|
const __variableDynamicImportRuntimeHelper = (glob, path) => {
|
19
17
|
const v = glob[path];
|
@@ -51,42 +49,6 @@ const useInjectionZone = (area) => {
|
|
51
49
|
const [page, position] = area.split(".");
|
52
50
|
return contentManagerPlugin.getInjectedComponents(page, position);
|
53
51
|
};
|
54
|
-
const HistoryAction = ({ model, document }) => {
|
55
|
-
const { formatMessage } = useIntl();
|
56
|
-
const [{ query }] = useQueryParams();
|
57
|
-
const navigate = useNavigate();
|
58
|
-
const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
|
59
|
-
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
60
|
-
return null;
|
61
|
-
}
|
62
|
-
return {
|
63
|
-
icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
|
64
|
-
label: formatMessage({
|
65
|
-
id: "content-manager.history.document-action",
|
66
|
-
defaultMessage: "Content History"
|
67
|
-
}),
|
68
|
-
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
69
|
-
disabled: (
|
70
|
-
/**
|
71
|
-
* The user is creating a new document.
|
72
|
-
* It hasn't been saved yet, so there's no history to go to
|
73
|
-
*/
|
74
|
-
!document || /**
|
75
|
-
* The document has been created but the current dimension has never been saved.
|
76
|
-
* For example, the user is creating a new locale in an existing document,
|
77
|
-
* so there's no history for the document in that locale
|
78
|
-
*/
|
79
|
-
!document.id || /**
|
80
|
-
* History is only available for content types created by the user.
|
81
|
-
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
82
|
-
* which start with `admin::` or `plugin::`
|
83
|
-
*/
|
84
|
-
!model.startsWith("api::")
|
85
|
-
),
|
86
|
-
position: "header"
|
87
|
-
};
|
88
|
-
};
|
89
|
-
HistoryAction.type = "history";
|
90
52
|
const ID = "id";
|
91
53
|
const CREATED_BY_ATTRIBUTE_NAME = "createdBy";
|
92
54
|
const UPDATED_BY_ATTRIBUTE_NAME = "updatedBy";
|
@@ -157,9 +119,8 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
157
119
|
const name = removeNumericalStrings(fieldName.split("."));
|
158
120
|
const componentFieldNames = fieldsUserCanAction.filter((field) => field.split(".").length > 1);
|
159
121
|
if (fieldType === "component") {
|
160
|
-
|
161
|
-
|
162
|
-
return field.includes(fieldName);
|
122
|
+
return componentFieldNames.some((field) => {
|
123
|
+
return field.includes(name.join("."));
|
163
124
|
});
|
164
125
|
}
|
165
126
|
if (name.length > 1) {
|
@@ -189,78 +150,8 @@ const extractAndDedupeFields = (permissions = []) => permissions.flatMap((permis
|
|
189
150
|
(field, index2, arr) => arr.indexOf(field) === index2 && typeof field === "string"
|
190
151
|
);
|
191
152
|
const removeNumericalStrings = (arr) => arr.filter((item) => isNaN(Number(item)));
|
192
|
-
const
|
193
|
-
|
194
|
-
return query;
|
195
|
-
const { plugins: _, ...validQueryParams } = {
|
196
|
-
...query,
|
197
|
-
...Object.values(query?.plugins ?? {}).reduce(
|
198
|
-
(acc, current) => Object.assign(acc, current),
|
199
|
-
{}
|
200
|
-
)
|
201
|
-
};
|
202
|
-
if ("_q" in validQueryParams) {
|
203
|
-
validQueryParams._q = encodeURIComponent(validQueryParams._q);
|
204
|
-
}
|
205
|
-
return validQueryParams;
|
206
|
-
};
|
207
|
-
const axiosBaseQuery = () => async (query, { signal }) => {
|
208
|
-
try {
|
209
|
-
const { get, post, del, put } = getFetchClient();
|
210
|
-
if (typeof query === "string") {
|
211
|
-
const result = await get(query, { signal });
|
212
|
-
return { data: result.data };
|
213
|
-
} else {
|
214
|
-
const { url, method = "GET", data, config } = query;
|
215
|
-
if (method === "POST") {
|
216
|
-
const result2 = await post(url, data, { ...config, signal });
|
217
|
-
return { data: result2.data };
|
218
|
-
}
|
219
|
-
if (method === "DELETE") {
|
220
|
-
const result2 = await del(url, { ...config, signal });
|
221
|
-
return { data: result2.data };
|
222
|
-
}
|
223
|
-
if (method === "PUT") {
|
224
|
-
const result2 = await put(url, data, { ...config, signal });
|
225
|
-
return { data: result2.data };
|
226
|
-
}
|
227
|
-
const result = await get(url, { ...config, signal });
|
228
|
-
return { data: result.data };
|
229
|
-
}
|
230
|
-
} catch (err) {
|
231
|
-
if (isAxiosError(err)) {
|
232
|
-
if (typeof err.response?.data === "object" && err.response?.data !== null && "error" in err.response?.data) {
|
233
|
-
return { data: void 0, error: err.response?.data.error };
|
234
|
-
} else {
|
235
|
-
return {
|
236
|
-
data: void 0,
|
237
|
-
error: {
|
238
|
-
name: "UnknownError",
|
239
|
-
message: "There was an unknown error response from the API",
|
240
|
-
details: err.response?.data,
|
241
|
-
status: err.response?.status
|
242
|
-
}
|
243
|
-
};
|
244
|
-
}
|
245
|
-
}
|
246
|
-
const error = err;
|
247
|
-
return {
|
248
|
-
data: void 0,
|
249
|
-
error: {
|
250
|
-
name: error.name,
|
251
|
-
message: error.message,
|
252
|
-
stack: error.stack
|
253
|
-
}
|
254
|
-
};
|
255
|
-
}
|
256
|
-
};
|
257
|
-
const isBaseQueryError = (error) => {
|
258
|
-
return error.name !== void 0;
|
259
|
-
};
|
260
|
-
const contentManagerApi = createApi({
|
261
|
-
reducerPath: "contentManagerApi",
|
262
|
-
baseQuery: axiosBaseQuery(),
|
263
|
-
tagTypes: [
|
153
|
+
const contentManagerApi = adminApi.enhanceEndpoints({
|
154
|
+
addTagTypes: [
|
264
155
|
"ComponentConfiguration",
|
265
156
|
"ContentTypesConfiguration",
|
266
157
|
"ContentTypeSettings",
|
@@ -268,10 +159,10 @@ const contentManagerApi = createApi({
|
|
268
159
|
"InitialData",
|
269
160
|
"HistoryVersion",
|
270
161
|
"Relations"
|
271
|
-
]
|
272
|
-
endpoints: () => ({})
|
162
|
+
]
|
273
163
|
});
|
274
164
|
const documentApi = contentManagerApi.injectEndpoints({
|
165
|
+
overrideExisting: true,
|
275
166
|
endpoints: (builder) => ({
|
276
167
|
autoCloneDocument: builder.mutation({
|
277
168
|
query: ({ model, sourceId, query }) => ({
|
@@ -281,7 +172,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
281
172
|
params: query
|
282
173
|
}
|
283
174
|
}),
|
284
|
-
invalidatesTags: (_result,
|
175
|
+
invalidatesTags: (_result, error, { model }) => {
|
176
|
+
if (error) {
|
177
|
+
return [];
|
178
|
+
}
|
179
|
+
return [{ type: "Document", id: `${model}_LIST` }];
|
180
|
+
}
|
285
181
|
}),
|
286
182
|
cloneDocument: builder.mutation({
|
287
183
|
query: ({ model, sourceId, data, params }) => ({
|
@@ -325,12 +221,15 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
325
221
|
]
|
326
222
|
}),
|
327
223
|
deleteManyDocuments: builder.mutation({
|
328
|
-
query: ({ model, ...body }) => ({
|
224
|
+
query: ({ model, params, ...body }) => ({
|
329
225
|
url: `/content-manager/collection-types/${model}/actions/bulkDelete`,
|
330
226
|
method: "POST",
|
331
|
-
data: body
|
227
|
+
data: body,
|
228
|
+
config: {
|
229
|
+
params
|
230
|
+
}
|
332
231
|
}),
|
333
|
-
invalidatesTags: (_res, _error, { model
|
232
|
+
invalidatesTags: (_res, _error, { model }) => [{ type: "Document", id: `${model}_LIST` }]
|
334
233
|
}),
|
335
234
|
discardDocument: builder.mutation({
|
336
235
|
query: ({ collectionType, model, documentId, params }) => ({
|
@@ -365,6 +264,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
365
264
|
}),
|
366
265
|
providesTags: (result, _error, arg) => {
|
367
266
|
return [
|
267
|
+
{ type: "Document", id: `ALL_LIST` },
|
368
268
|
{ type: "Document", id: `${arg.model}_LIST` },
|
369
269
|
...result?.results.map(({ documentId }) => ({
|
370
270
|
type: "Document",
|
@@ -441,10 +341,13 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
441
341
|
}
|
442
342
|
}),
|
443
343
|
publishManyDocuments: builder.mutation({
|
444
|
-
query: ({ model, ...body }) => ({
|
344
|
+
query: ({ model, params, ...body }) => ({
|
445
345
|
url: `/content-manager/collection-types/${model}/actions/bulkPublish`,
|
446
346
|
method: "POST",
|
447
|
-
data: body
|
347
|
+
data: body,
|
348
|
+
config: {
|
349
|
+
params
|
350
|
+
}
|
448
351
|
}),
|
449
352
|
invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
|
450
353
|
}),
|
@@ -465,6 +368,18 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
465
368
|
},
|
466
369
|
"Relations"
|
467
370
|
];
|
371
|
+
},
|
372
|
+
async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
|
373
|
+
const patchResult = dispatch(
|
374
|
+
documentApi.util.updateQueryData("getDocument", patch, (draft) => {
|
375
|
+
Object.assign(draft.data, data);
|
376
|
+
})
|
377
|
+
);
|
378
|
+
try {
|
379
|
+
await queryFulfilled;
|
380
|
+
} catch {
|
381
|
+
patchResult.undo();
|
382
|
+
}
|
468
383
|
}
|
469
384
|
}),
|
470
385
|
unpublishDocument: builder.mutation({
|
@@ -486,10 +401,13 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
486
401
|
}
|
487
402
|
}),
|
488
403
|
unpublishManyDocuments: builder.mutation({
|
489
|
-
query: ({ model, ...body }) => ({
|
404
|
+
query: ({ model, params, ...body }) => ({
|
490
405
|
url: `/content-manager/collection-types/${model}/actions/bulkUnpublish`,
|
491
406
|
method: "POST",
|
492
|
-
data: body
|
407
|
+
data: body,
|
408
|
+
config: {
|
409
|
+
params
|
410
|
+
}
|
493
411
|
}),
|
494
412
|
invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
|
495
413
|
})
|
@@ -513,6 +431,24 @@ const {
|
|
513
431
|
useUnpublishDocumentMutation,
|
514
432
|
useUnpublishManyDocumentsMutation
|
515
433
|
} = documentApi;
|
434
|
+
const buildValidParams = (query) => {
|
435
|
+
if (!query)
|
436
|
+
return query;
|
437
|
+
const { plugins: _, ...validQueryParams } = {
|
438
|
+
...query,
|
439
|
+
...Object.values(query?.plugins ?? {}).reduce(
|
440
|
+
(acc, current) => Object.assign(acc, current),
|
441
|
+
{}
|
442
|
+
)
|
443
|
+
};
|
444
|
+
if ("_q" in validQueryParams) {
|
445
|
+
validQueryParams._q = encodeURIComponent(validQueryParams._q);
|
446
|
+
}
|
447
|
+
return validQueryParams;
|
448
|
+
};
|
449
|
+
const isBaseQueryError = (error) => {
|
450
|
+
return error.name !== void 0;
|
451
|
+
};
|
516
452
|
const createYupSchema = (attributes = {}, components = {}) => {
|
517
453
|
const createModelSchema = (attributes2) => yup.object().shape(
|
518
454
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
@@ -552,10 +488,14 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
552
488
|
yup.array().of(
|
553
489
|
yup.lazy(
|
554
490
|
(data) => {
|
555
|
-
const
|
556
|
-
|
491
|
+
const attributes3 = components?.[data?.__component]?.attributes;
|
492
|
+
const validation = yup.object().shape({
|
557
493
|
__component: yup.string().required().oneOf(Object.keys(components))
|
558
|
-
}).nullable(false)
|
494
|
+
}).nullable(false);
|
495
|
+
if (!attributes3) {
|
496
|
+
return validation;
|
497
|
+
}
|
498
|
+
return validation.concat(createModelSchema(attributes3));
|
559
499
|
}
|
560
500
|
)
|
561
501
|
)
|
@@ -565,11 +505,25 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
565
505
|
return {
|
566
506
|
...acc,
|
567
507
|
[name]: transformSchema(
|
568
|
-
yup.
|
569
|
-
|
570
|
-
|
571
|
-
})
|
572
|
-
|
508
|
+
yup.lazy((value) => {
|
509
|
+
if (!value) {
|
510
|
+
return yup.mixed().nullable(true);
|
511
|
+
} else if (Array.isArray(value)) {
|
512
|
+
return yup.array().of(
|
513
|
+
yup.object().shape({
|
514
|
+
id: yup.string().required()
|
515
|
+
})
|
516
|
+
);
|
517
|
+
} else if (typeof value === "object") {
|
518
|
+
return yup.object();
|
519
|
+
} else {
|
520
|
+
return yup.mixed().test(
|
521
|
+
"type-error",
|
522
|
+
"Relation values must be either null, an array of objects with {id} or an object.",
|
523
|
+
() => false
|
524
|
+
);
|
525
|
+
}
|
526
|
+
})
|
573
527
|
)
|
574
528
|
};
|
575
529
|
default:
|
@@ -628,13 +582,18 @@ const createAttributeSchema = (attribute) => {
|
|
628
582
|
}
|
629
583
|
};
|
630
584
|
const addRequiredValidation = (attribute) => (schema) => {
|
631
|
-
if (attribute.required) {
|
632
|
-
return schema.required
|
633
|
-
id: translatedErrors.required.id,
|
634
|
-
defaultMessage: "This field is required."
|
635
|
-
});
|
585
|
+
if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
|
586
|
+
return schema.min(1, translatedErrors.required);
|
636
587
|
}
|
637
|
-
|
588
|
+
if (attribute.required && attribute.type !== "relation") {
|
589
|
+
return schema.required(translatedErrors.required);
|
590
|
+
}
|
591
|
+
return schema?.nullable ? schema.nullable() : (
|
592
|
+
// In some cases '.nullable' will not be available on the schema.
|
593
|
+
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
594
|
+
// In these cases we should just return the schema as it is.
|
595
|
+
schema
|
596
|
+
);
|
638
597
|
};
|
639
598
|
const addMinLengthValidation = (attribute) => (schema) => {
|
640
599
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
@@ -661,6 +620,28 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
661
620
|
const addMinValidation = (attribute) => (schema) => {
|
662
621
|
if ("min" in attribute) {
|
663
622
|
const min = toInteger(attribute.min);
|
623
|
+
if (attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") {
|
624
|
+
if (!attribute.required && "test" in schema && min) {
|
625
|
+
return schema.test(
|
626
|
+
"custom-min",
|
627
|
+
{
|
628
|
+
...translatedErrors.min,
|
629
|
+
values: {
|
630
|
+
min: attribute.min
|
631
|
+
}
|
632
|
+
},
|
633
|
+
(value) => {
|
634
|
+
if (!value) {
|
635
|
+
return true;
|
636
|
+
}
|
637
|
+
if (Array.isArray(value) && value.length === 0) {
|
638
|
+
return true;
|
639
|
+
}
|
640
|
+
return value.length >= min;
|
641
|
+
}
|
642
|
+
);
|
643
|
+
}
|
644
|
+
}
|
664
645
|
if ("min" in schema && min) {
|
665
646
|
return schema.min(min, {
|
666
647
|
...translatedErrors.min,
|
@@ -706,24 +687,6 @@ const addRegexValidation = (attribute) => (schema) => {
|
|
706
687
|
}
|
707
688
|
return schema;
|
708
689
|
};
|
709
|
-
const extractValuesFromYupError = (errorType, errorParams) => {
|
710
|
-
if (!errorType || !errorParams) {
|
711
|
-
return {};
|
712
|
-
}
|
713
|
-
return {
|
714
|
-
[errorType]: errorParams[errorType]
|
715
|
-
};
|
716
|
-
};
|
717
|
-
const getInnerErrors = (error) => (error?.inner || []).reduce((acc, currentError) => {
|
718
|
-
if (currentError.path) {
|
719
|
-
acc[currentError.path.split("[").join(".").split("]").join("")] = {
|
720
|
-
id: currentError.message,
|
721
|
-
defaultMessage: currentError.message,
|
722
|
-
values: extractValuesFromYupError(currentError?.type, currentError?.params)
|
723
|
-
};
|
724
|
-
}
|
725
|
-
return acc;
|
726
|
-
}, {});
|
727
690
|
const initApi = contentManagerApi.injectEndpoints({
|
728
691
|
endpoints: (builder) => ({
|
729
692
|
getInitialData: builder.query({
|
@@ -737,27 +700,20 @@ const { useGetInitialDataQuery } = initApi;
|
|
737
700
|
const useContentTypeSchema = (model) => {
|
738
701
|
const { toggleNotification } = useNotification();
|
739
702
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
740
|
-
const {
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
)
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
error: res.error,
|
755
|
-
components: Object.keys(components2).length === 0 ? void 0 : components2,
|
756
|
-
contentType: contentType2,
|
757
|
-
contentTypes: res.data?.contentTypes ?? []
|
758
|
-
};
|
759
|
-
}
|
760
|
-
});
|
703
|
+
const { data, error, isLoading, isFetching } = useGetInitialDataQuery(void 0);
|
704
|
+
const { components, contentType, contentTypes } = React.useMemo(() => {
|
705
|
+
const contentType2 = data?.contentTypes.find((ct) => ct.uid === model);
|
706
|
+
const componentsByKey = data?.components.reduce((acc, component) => {
|
707
|
+
acc[component.uid] = component;
|
708
|
+
return acc;
|
709
|
+
}, {});
|
710
|
+
const components2 = extractContentTypeComponents(contentType2?.attributes, componentsByKey);
|
711
|
+
return {
|
712
|
+
components: Object.keys(components2).length === 0 ? void 0 : components2,
|
713
|
+
contentType: contentType2,
|
714
|
+
contentTypes: data?.contentTypes ?? []
|
715
|
+
};
|
716
|
+
}, [model, data]);
|
761
717
|
React.useEffect(() => {
|
762
718
|
if (error) {
|
763
719
|
toggleNotification({
|
@@ -812,7 +768,10 @@ const useDocument = (args, opts) => {
|
|
812
768
|
isLoading: isLoadingDocument,
|
813
769
|
isFetching: isFetchingDocument,
|
814
770
|
error
|
815
|
-
} = useGetDocumentQuery(args,
|
771
|
+
} = useGetDocumentQuery(args, {
|
772
|
+
...opts,
|
773
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
774
|
+
});
|
816
775
|
const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
|
817
776
|
React.useEffect(() => {
|
818
777
|
if (error) {
|
@@ -840,7 +799,7 @@ const useDocument = (args, opts) => {
|
|
840
799
|
return null;
|
841
800
|
} catch (error2) {
|
842
801
|
if (error2 instanceof ValidationError) {
|
843
|
-
return
|
802
|
+
return getYupValidationErrors(error2);
|
844
803
|
}
|
845
804
|
throw error2;
|
846
805
|
}
|
@@ -936,14 +895,53 @@ const useDocumentActions = () => {
|
|
936
895
|
},
|
937
896
|
[trackUsage, deleteDocument, toggleNotification, formatMessage, formatAPIError]
|
938
897
|
);
|
898
|
+
const [deleteManyDocuments] = useDeleteManyDocumentsMutation();
|
899
|
+
const deleteMany = React.useCallback(
|
900
|
+
async ({ model, documentIds, params }) => {
|
901
|
+
try {
|
902
|
+
trackUsage("willBulkDeleteEntries");
|
903
|
+
const res = await deleteManyDocuments({
|
904
|
+
model,
|
905
|
+
documentIds,
|
906
|
+
params
|
907
|
+
});
|
908
|
+
if ("error" in res) {
|
909
|
+
toggleNotification({
|
910
|
+
type: "danger",
|
911
|
+
message: formatAPIError(res.error)
|
912
|
+
});
|
913
|
+
return { error: res.error };
|
914
|
+
}
|
915
|
+
toggleNotification({
|
916
|
+
type: "success",
|
917
|
+
title: formatMessage({
|
918
|
+
id: getTranslation("success.records.delete"),
|
919
|
+
defaultMessage: "Successfully deleted."
|
920
|
+
}),
|
921
|
+
message: ""
|
922
|
+
});
|
923
|
+
trackUsage("didBulkDeleteEntries");
|
924
|
+
return res.data;
|
925
|
+
} catch (err) {
|
926
|
+
toggleNotification({
|
927
|
+
type: "danger",
|
928
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
929
|
+
});
|
930
|
+
trackUsage("didNotBulkDeleteEntries");
|
931
|
+
throw err;
|
932
|
+
}
|
933
|
+
},
|
934
|
+
[trackUsage, deleteManyDocuments, toggleNotification, formatMessage, formatAPIError]
|
935
|
+
);
|
939
936
|
const [discardDocument] = useDiscardDocumentMutation();
|
940
937
|
const discard = React.useCallback(
|
941
|
-
async ({ collectionType, model, documentId }) => {
|
938
|
+
async ({ collectionType, model, documentId, params }) => {
|
942
939
|
try {
|
943
940
|
const res = await discardDocument({
|
944
941
|
collectionType,
|
945
942
|
model,
|
946
|
-
documentId
|
943
|
+
documentId,
|
944
|
+
params
|
947
945
|
});
|
948
946
|
if ("error" in res) {
|
949
947
|
toggleNotification({
|
@@ -1005,6 +1003,43 @@ const useDocumentActions = () => {
|
|
1005
1003
|
},
|
1006
1004
|
[trackUsage, publishDocument, toggleNotification, formatMessage, formatAPIError]
|
1007
1005
|
);
|
1006
|
+
const [publishManyDocuments] = usePublishManyDocumentsMutation();
|
1007
|
+
const publishMany = React.useCallback(
|
1008
|
+
async ({ model, documentIds, params }) => {
|
1009
|
+
try {
|
1010
|
+
const res = await publishManyDocuments({
|
1011
|
+
model,
|
1012
|
+
documentIds,
|
1013
|
+
params
|
1014
|
+
});
|
1015
|
+
if ("error" in res) {
|
1016
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1017
|
+
return { error: res.error };
|
1018
|
+
}
|
1019
|
+
toggleNotification({
|
1020
|
+
type: "success",
|
1021
|
+
message: formatMessage({
|
1022
|
+
id: getTranslation("success.record.publish"),
|
1023
|
+
defaultMessage: "Published document"
|
1024
|
+
})
|
1025
|
+
});
|
1026
|
+
return res.data;
|
1027
|
+
} catch (err) {
|
1028
|
+
toggleNotification({
|
1029
|
+
type: "danger",
|
1030
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1031
|
+
});
|
1032
|
+
throw err;
|
1033
|
+
}
|
1034
|
+
},
|
1035
|
+
[
|
1036
|
+
// trackUsage,
|
1037
|
+
publishManyDocuments,
|
1038
|
+
toggleNotification,
|
1039
|
+
formatMessage,
|
1040
|
+
formatAPIError
|
1041
|
+
]
|
1042
|
+
);
|
1008
1043
|
const [updateDocument] = useUpdateDocumentMutation();
|
1009
1044
|
const update = React.useCallback(
|
1010
1045
|
async ({ collectionType, model, documentId, params }, data, trackerProperty) => {
|
@@ -1079,6 +1114,41 @@ const useDocumentActions = () => {
|
|
1079
1114
|
},
|
1080
1115
|
[trackUsage, unpublishDocument, toggleNotification, formatMessage, formatAPIError]
|
1081
1116
|
);
|
1117
|
+
const [unpublishManyDocuments] = useUnpublishManyDocumentsMutation();
|
1118
|
+
const unpublishMany = React.useCallback(
|
1119
|
+
async ({ model, documentIds, params }) => {
|
1120
|
+
try {
|
1121
|
+
trackUsage("willBulkUnpublishEntries");
|
1122
|
+
const res = await unpublishManyDocuments({
|
1123
|
+
model,
|
1124
|
+
documentIds,
|
1125
|
+
params
|
1126
|
+
});
|
1127
|
+
if ("error" in res) {
|
1128
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1129
|
+
return { error: res.error };
|
1130
|
+
}
|
1131
|
+
trackUsage("didBulkUnpublishEntries");
|
1132
|
+
toggleNotification({
|
1133
|
+
type: "success",
|
1134
|
+
title: formatMessage({
|
1135
|
+
id: getTranslation("success.records.unpublish"),
|
1136
|
+
defaultMessage: "Successfully unpublished."
|
1137
|
+
}),
|
1138
|
+
message: ""
|
1139
|
+
});
|
1140
|
+
return res.data;
|
1141
|
+
} catch (err) {
|
1142
|
+
toggleNotification({
|
1143
|
+
type: "danger",
|
1144
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1145
|
+
});
|
1146
|
+
trackUsage("didNotBulkUnpublishEntries");
|
1147
|
+
throw err;
|
1148
|
+
}
|
1149
|
+
},
|
1150
|
+
[trackUsage, unpublishManyDocuments, toggleNotification, formatMessage, formatAPIError]
|
1151
|
+
);
|
1082
1152
|
const [createDocument] = useCreateDocumentMutation();
|
1083
1153
|
const create = React.useCallback(
|
1084
1154
|
async ({ model, params }, data, trackerProperty) => {
|
@@ -1122,7 +1192,6 @@ const useDocumentActions = () => {
|
|
1122
1192
|
sourceId
|
1123
1193
|
});
|
1124
1194
|
if ("error" in res) {
|
1125
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1126
1195
|
return { error: res.error };
|
1127
1196
|
}
|
1128
1197
|
toggleNotification({
|
@@ -1192,15 +1261,18 @@ const useDocumentActions = () => {
|
|
1192
1261
|
clone,
|
1193
1262
|
create,
|
1194
1263
|
delete: _delete,
|
1264
|
+
deleteMany,
|
1195
1265
|
discard,
|
1196
1266
|
getDocument,
|
1197
1267
|
publish,
|
1268
|
+
publishMany,
|
1198
1269
|
unpublish,
|
1270
|
+
unpublishMany,
|
1199
1271
|
update
|
1200
1272
|
};
|
1201
1273
|
};
|
1202
1274
|
const ProtectedHistoryPage = lazy(
|
1203
|
-
() => import("./History-
|
1275
|
+
() => import("./History-CKCSQXz_.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1204
1276
|
);
|
1205
1277
|
const routes$1 = [
|
1206
1278
|
{
|
@@ -1213,31 +1285,31 @@ const routes$1 = [
|
|
1213
1285
|
}
|
1214
1286
|
];
|
1215
1287
|
const ProtectedEditViewPage = lazy(
|
1216
|
-
() => import("./EditViewPage-
|
1288
|
+
() => import("./EditViewPage-BVMS5hT-.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1217
1289
|
);
|
1218
1290
|
const ProtectedListViewPage = lazy(
|
1219
|
-
() => import("./ListViewPage-
|
1291
|
+
() => import("./ListViewPage-B7_WJUjG.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1220
1292
|
);
|
1221
1293
|
const ProtectedListConfiguration = lazy(
|
1222
|
-
() => import("./ListConfigurationPage-
|
1294
|
+
() => import("./ListConfigurationPage-CKEC4ttG.mjs").then((mod) => ({
|
1223
1295
|
default: mod.ProtectedListConfiguration
|
1224
1296
|
}))
|
1225
1297
|
);
|
1226
1298
|
const ProtectedEditConfigurationPage = lazy(
|
1227
|
-
() => import("./EditConfigurationPage-
|
1299
|
+
() => import("./EditConfigurationPage-GTp-Ucnw.mjs").then((mod) => ({
|
1228
1300
|
default: mod.ProtectedEditConfigurationPage
|
1229
1301
|
}))
|
1230
1302
|
);
|
1231
1303
|
const ProtectedComponentConfigurationPage = lazy(
|
1232
|
-
() => import("./ComponentConfigurationPage-
|
1304
|
+
() => import("./ComponentConfigurationPage-BWOQWCv2.mjs").then((mod) => ({
|
1233
1305
|
default: mod.ProtectedComponentConfigurationPage
|
1234
1306
|
}))
|
1235
1307
|
);
|
1236
1308
|
const NoPermissions = lazy(
|
1237
|
-
() => import("./NoPermissionsPage-
|
1309
|
+
() => import("./NoPermissionsPage-BO-GEjA4.mjs").then((mod) => ({ default: mod.NoPermissions }))
|
1238
1310
|
);
|
1239
1311
|
const NoContentType = lazy(
|
1240
|
-
() => import("./NoContentTypePage-
|
1312
|
+
() => import("./NoContentTypePage-Ckem6Ll6.mjs").then((mod) => ({ default: mod.NoContentType }))
|
1241
1313
|
);
|
1242
1314
|
const CollectionTypePages = () => {
|
1243
1315
|
const { collectionType } = useParams();
|
@@ -1364,7 +1436,7 @@ const DocumentActionButton = (action) => {
|
|
1364
1436
|
DocumentActionConfirmDialog,
|
1365
1437
|
{
|
1366
1438
|
...action.dialog,
|
1367
|
-
variant: action.variant,
|
1439
|
+
variant: action.dialog?.variant ?? action.variant,
|
1368
1440
|
isOpen: dialogId === action.id,
|
1369
1441
|
onClose: handleClose
|
1370
1442
|
}
|
@@ -1421,13 +1493,13 @@ const DocumentActionsMenu = ({
|
|
1421
1493
|
disabled: isDisabled,
|
1422
1494
|
size: "S",
|
1423
1495
|
endIcon: null,
|
1424
|
-
paddingTop: "
|
1425
|
-
paddingLeft: "
|
1426
|
-
paddingRight: "
|
1496
|
+
paddingTop: "4px",
|
1497
|
+
paddingLeft: "7px",
|
1498
|
+
paddingRight: "7px",
|
1427
1499
|
variant,
|
1428
1500
|
children: [
|
1429
1501
|
/* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
|
1430
|
-
/* @__PURE__ */ jsx(VisuallyHidden, {
|
1502
|
+
/* @__PURE__ */ jsx(VisuallyHidden, { tag: "span", children: label || formatMessage({
|
1431
1503
|
id: "content-manager.containers.edit.panels.default.more-actions",
|
1432
1504
|
defaultMessage: "More document actions"
|
1433
1505
|
}) })
|
@@ -1443,10 +1515,18 @@ const DocumentActionsMenu = ({
|
|
1443
1515
|
onSelect: handleClick(action),
|
1444
1516
|
display: "block",
|
1445
1517
|
children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", gap: 4, children: [
|
1446
|
-
/* @__PURE__ */ jsxs(
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1518
|
+
/* @__PURE__ */ jsxs(
|
1519
|
+
Flex,
|
1520
|
+
{
|
1521
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1522
|
+
gap: 2,
|
1523
|
+
tag: "span",
|
1524
|
+
children: [
|
1525
|
+
/* @__PURE__ */ jsx("span", { children: action.icon }),
|
1526
|
+
action.label
|
1527
|
+
]
|
1528
|
+
}
|
1529
|
+
),
|
1450
1530
|
action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsx(
|
1451
1531
|
Flex,
|
1452
1532
|
{
|
@@ -1527,61 +1607,42 @@ const DocumentActionConfirmDialog = ({
|
|
1527
1607
|
}
|
1528
1608
|
onClose();
|
1529
1609
|
};
|
1530
|
-
return /* @__PURE__ */
|
1531
|
-
/* @__PURE__ */ jsx(
|
1532
|
-
/* @__PURE__ */ jsx(
|
1533
|
-
|
1534
|
-
{
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
1543
|
-
|
1544
|
-
)
|
1545
|
-
] });
|
1610
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
1611
|
+
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
1612
|
+
/* @__PURE__ */ jsx(Dialog.Body, { children: content }),
|
1613
|
+
/* @__PURE__ */ jsxs(Dialog.Footer, { children: [
|
1614
|
+
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", children: formatMessage({
|
1615
|
+
id: "app.components.Button.cancel",
|
1616
|
+
defaultMessage: "Cancel"
|
1617
|
+
}) }) }),
|
1618
|
+
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, children: formatMessage({
|
1619
|
+
id: "app.components.Button.confirm",
|
1620
|
+
defaultMessage: "Confirm"
|
1621
|
+
}) })
|
1622
|
+
] })
|
1623
|
+
] }) });
|
1546
1624
|
};
|
1547
1625
|
const DocumentActionModal = ({
|
1548
1626
|
isOpen,
|
1549
1627
|
title,
|
1550
1628
|
onClose,
|
1551
1629
|
footer: Footer,
|
1552
|
-
content,
|
1630
|
+
content: Content,
|
1553
1631
|
onModalClose
|
1554
1632
|
}) => {
|
1555
|
-
const id = React.useId();
|
1556
|
-
if (!isOpen) {
|
1557
|
-
return null;
|
1558
|
-
}
|
1559
1633
|
const handleClose = () => {
|
1560
1634
|
if (onClose) {
|
1561
1635
|
onClose();
|
1562
1636
|
}
|
1563
1637
|
onModalClose();
|
1564
1638
|
};
|
1565
|
-
return /* @__PURE__ */
|
1566
|
-
/* @__PURE__ */ jsx(
|
1567
|
-
/* @__PURE__ */ jsx(
|
1568
|
-
/* @__PURE__ */ jsx(
|
1569
|
-
|
1570
|
-
{
|
1571
|
-
paddingTop: 4,
|
1572
|
-
paddingBottom: 4,
|
1573
|
-
paddingLeft: 5,
|
1574
|
-
paddingRight: 5,
|
1575
|
-
borderWidth: "1px 0 0 0",
|
1576
|
-
borderStyle: "solid",
|
1577
|
-
borderColor: "neutral150",
|
1578
|
-
background: "neutral100",
|
1579
|
-
children: typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
|
1580
|
-
}
|
1581
|
-
)
|
1582
|
-
] });
|
1639
|
+
return /* @__PURE__ */ jsx(Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
|
1640
|
+
/* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: title }) }),
|
1641
|
+
typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsx(Modal.Body, { children: Content }),
|
1642
|
+
typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
|
1643
|
+
] }) });
|
1583
1644
|
};
|
1584
|
-
const PublishAction = ({
|
1645
|
+
const PublishAction$1 = ({
|
1585
1646
|
activeTab,
|
1586
1647
|
documentId,
|
1587
1648
|
model,
|
@@ -1600,6 +1661,12 @@ const PublishAction = ({
|
|
1600
1661
|
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1601
1662
|
);
|
1602
1663
|
const { publish } = useDocumentActions();
|
1664
|
+
const [
|
1665
|
+
countDraftRelations,
|
1666
|
+
{ isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
|
1667
|
+
] = useLazyGetDraftRelationCountQuery();
|
1668
|
+
const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React.useState(0);
|
1669
|
+
const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React.useState(0);
|
1603
1670
|
const [{ query, rawQuery }] = useQueryParams();
|
1604
1671
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
1605
1672
|
const modified = useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
@@ -1608,65 +1675,146 @@ const PublishAction = ({
|
|
1608
1675
|
const validate = useForm("PublishAction", (state) => state.validate);
|
1609
1676
|
const setErrors = useForm("PublishAction", (state) => state.setErrors);
|
1610
1677
|
const formValues = useForm("PublishAction", ({ values }) => values);
|
1611
|
-
|
1612
|
-
|
1613
|
-
|
1614
|
-
|
1615
|
-
|
1616
|
-
|
1617
|
-
|
1618
|
-
|
1619
|
-
|
1620
|
-
|
1621
|
-
|
1622
|
-
|
1623
|
-
|
1624
|
-
|
1625
|
-
|
1626
|
-
|
1627
|
-
|
1628
|
-
|
1678
|
+
React.useEffect(() => {
|
1679
|
+
if (isErrorDraftRelations) {
|
1680
|
+
toggleNotification({
|
1681
|
+
type: "danger",
|
1682
|
+
message: formatMessage({
|
1683
|
+
id: getTranslation("error.records.fetch-draft-relatons"),
|
1684
|
+
defaultMessage: "An error occurred while fetching draft relations on this document."
|
1685
|
+
})
|
1686
|
+
});
|
1687
|
+
}
|
1688
|
+
}, [isErrorDraftRelations, toggleNotification, formatMessage]);
|
1689
|
+
React.useEffect(() => {
|
1690
|
+
const localDraftRelations = /* @__PURE__ */ new Set();
|
1691
|
+
const extractDraftRelations = (data) => {
|
1692
|
+
const relations = data.connect || [];
|
1693
|
+
relations.forEach((relation) => {
|
1694
|
+
if (relation.status === "draft") {
|
1695
|
+
localDraftRelations.add(relation.id);
|
1696
|
+
}
|
1697
|
+
});
|
1698
|
+
};
|
1699
|
+
const traverseAndExtract = (data) => {
|
1700
|
+
Object.entries(data).forEach(([key, value]) => {
|
1701
|
+
if (key === "connect" && Array.isArray(value)) {
|
1702
|
+
extractDraftRelations({ connect: value });
|
1703
|
+
} else if (typeof value === "object" && value !== null) {
|
1704
|
+
traverseAndExtract(value);
|
1705
|
+
}
|
1706
|
+
});
|
1707
|
+
};
|
1708
|
+
if (!documentId || modified) {
|
1709
|
+
traverseAndExtract(formValues);
|
1710
|
+
setLocalCountOfDraftRelations(localDraftRelations.size);
|
1711
|
+
}
|
1712
|
+
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
1713
|
+
React.useEffect(() => {
|
1714
|
+
if (documentId) {
|
1715
|
+
const fetchDraftRelationsCount = async () => {
|
1716
|
+
const { data, error } = await countDraftRelations({
|
1717
|
+
collectionType,
|
1718
|
+
model,
|
1719
|
+
documentId,
|
1720
|
+
params
|
1721
|
+
});
|
1722
|
+
if (error) {
|
1723
|
+
throw error;
|
1724
|
+
}
|
1725
|
+
if (data) {
|
1726
|
+
setServerCountOfDraftRelations(data.data);
|
1727
|
+
}
|
1728
|
+
};
|
1729
|
+
fetchDraftRelationsCount();
|
1730
|
+
}
|
1731
|
+
}, [documentId, countDraftRelations, collectionType, model, params]);
|
1732
|
+
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
1733
|
+
if (!schema?.options?.draftAndPublish) {
|
1734
|
+
return null;
|
1735
|
+
}
|
1736
|
+
const performPublish = async () => {
|
1737
|
+
setSubmitting(true);
|
1738
|
+
try {
|
1739
|
+
const { errors } = await validate();
|
1740
|
+
if (errors) {
|
1741
|
+
toggleNotification({
|
1742
|
+
type: "danger",
|
1743
|
+
message: formatMessage({
|
1744
|
+
id: "content-manager.validation.error",
|
1745
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
1746
|
+
})
|
1747
|
+
});
|
1748
|
+
return;
|
1749
|
+
}
|
1750
|
+
const res = await publish(
|
1751
|
+
{
|
1752
|
+
collectionType,
|
1753
|
+
model,
|
1754
|
+
documentId,
|
1755
|
+
params
|
1756
|
+
},
|
1757
|
+
formValues
|
1758
|
+
);
|
1759
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1760
|
+
navigate({
|
1761
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1762
|
+
search: rawQuery
|
1763
|
+
});
|
1764
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1765
|
+
setErrors(formatValidationErrors(res.error));
|
1766
|
+
}
|
1767
|
+
} finally {
|
1768
|
+
setSubmitting(false);
|
1769
|
+
}
|
1770
|
+
};
|
1771
|
+
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
1772
|
+
const hasDraftRelations = totalDraftRelations > 0;
|
1773
|
+
return {
|
1774
|
+
/**
|
1775
|
+
* Disabled when:
|
1776
|
+
* - currently if you're cloning a document we don't support publish & clone at the same time.
|
1777
|
+
* - the form is submitting
|
1778
|
+
* - the active tab is the published tab
|
1779
|
+
* - the document is already published & not modified
|
1780
|
+
* - the document is being created & not modified
|
1781
|
+
* - the user doesn't have the permission to publish
|
1782
|
+
*/
|
1783
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
1784
|
+
label: formatMessage({
|
1629
1785
|
id: "app.utils.publish",
|
1630
1786
|
defaultMessage: "Publish"
|
1631
1787
|
}),
|
1632
1788
|
onClick: async () => {
|
1633
|
-
|
1634
|
-
|
1635
|
-
|
1636
|
-
|
1637
|
-
|
1638
|
-
|
1639
|
-
|
1640
|
-
|
1641
|
-
|
1642
|
-
|
1643
|
-
|
1644
|
-
|
1645
|
-
|
1646
|
-
|
1647
|
-
|
1648
|
-
|
1649
|
-
|
1650
|
-
|
1651
|
-
|
1652
|
-
|
1653
|
-
formValues
|
1654
|
-
);
|
1655
|
-
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1656
|
-
navigate({
|
1657
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1658
|
-
search: rawQuery
|
1659
|
-
});
|
1660
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1661
|
-
setErrors(formatValidationErrors(res.error));
|
1789
|
+
if (hasDraftRelations) {
|
1790
|
+
return;
|
1791
|
+
}
|
1792
|
+
await performPublish();
|
1793
|
+
},
|
1794
|
+
dialog: hasDraftRelations ? {
|
1795
|
+
type: "dialog",
|
1796
|
+
variant: "danger",
|
1797
|
+
footer: null,
|
1798
|
+
title: formatMessage({
|
1799
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
|
1800
|
+
defaultMessage: "Confirmation"
|
1801
|
+
}),
|
1802
|
+
content: formatMessage(
|
1803
|
+
{
|
1804
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
1805
|
+
defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
|
1806
|
+
},
|
1807
|
+
{
|
1808
|
+
count: totalDraftRelations
|
1662
1809
|
}
|
1663
|
-
|
1664
|
-
|
1810
|
+
),
|
1811
|
+
onConfirm: async () => {
|
1812
|
+
await performPublish();
|
1665
1813
|
}
|
1666
|
-
}
|
1814
|
+
} : void 0
|
1667
1815
|
};
|
1668
1816
|
};
|
1669
|
-
PublishAction.type = "publish";
|
1817
|
+
PublishAction$1.type = "publish";
|
1670
1818
|
const UpdateAction = ({
|
1671
1819
|
activeTab,
|
1672
1820
|
documentId,
|
@@ -1679,7 +1827,7 @@ const UpdateAction = ({
|
|
1679
1827
|
const cloneMatch = useMatch(CLONE_PATH);
|
1680
1828
|
const isCloning = cloneMatch !== null;
|
1681
1829
|
const { formatMessage } = useIntl();
|
1682
|
-
|
1830
|
+
useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1683
1831
|
canCreate: canCreate2,
|
1684
1832
|
canUpdate: canUpdate2
|
1685
1833
|
}));
|
@@ -1699,10 +1847,8 @@ const UpdateAction = ({
|
|
1699
1847
|
* - the form is submitting
|
1700
1848
|
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
1701
1849
|
* - the active tab is the published tab
|
1702
|
-
* - the user doesn't have the permission to create a new document
|
1703
|
-
* - the user doesn't have the permission to update the document
|
1704
1850
|
*/
|
1705
|
-
disabled: isSubmitting || !modified && !isCloning || activeTab === "published"
|
1851
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1706
1852
|
label: formatMessage({
|
1707
1853
|
id: "content-manager.containers.Edit.save",
|
1708
1854
|
defaultMessage: "Save"
|
@@ -1731,10 +1877,13 @@ const UpdateAction = ({
|
|
1731
1877
|
document
|
1732
1878
|
);
|
1733
1879
|
if ("data" in res) {
|
1734
|
-
navigate(
|
1735
|
-
|
1736
|
-
|
1737
|
-
|
1880
|
+
navigate(
|
1881
|
+
{
|
1882
|
+
pathname: `../${res.data.documentId}`,
|
1883
|
+
search: rawQuery
|
1884
|
+
},
|
1885
|
+
{ relative: "path" }
|
1886
|
+
);
|
1738
1887
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1739
1888
|
setErrors(formatValidationErrors(res.error));
|
1740
1889
|
}
|
@@ -1762,10 +1911,13 @@ const UpdateAction = ({
|
|
1762
1911
|
document
|
1763
1912
|
);
|
1764
1913
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1765
|
-
navigate(
|
1766
|
-
|
1767
|
-
|
1768
|
-
|
1914
|
+
navigate(
|
1915
|
+
{
|
1916
|
+
pathname: `../${res.data.documentId}`,
|
1917
|
+
search: rawQuery
|
1918
|
+
},
|
1919
|
+
{ replace: true, relative: "path" }
|
1920
|
+
);
|
1769
1921
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1770
1922
|
setErrors(formatValidationErrors(res.error));
|
1771
1923
|
}
|
@@ -1781,7 +1933,7 @@ const UNPUBLISH_DRAFT_OPTIONS = {
|
|
1781
1933
|
KEEP: "keep",
|
1782
1934
|
DISCARD: "discard"
|
1783
1935
|
};
|
1784
|
-
const UnpublishAction = ({
|
1936
|
+
const UnpublishAction$1 = ({
|
1785
1937
|
activeTab,
|
1786
1938
|
documentId,
|
1787
1939
|
model,
|
@@ -1797,10 +1949,8 @@ const UnpublishAction = ({
|
|
1797
1949
|
const { toggleNotification } = useNotification();
|
1798
1950
|
const [shouldKeepDraft, setShouldKeepDraft] = React.useState(true);
|
1799
1951
|
const isDocumentModified = document?.status === "modified";
|
1800
|
-
const handleChange = (
|
1801
|
-
|
1802
|
-
setShouldKeepDraft(e.target.value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1803
|
-
}
|
1952
|
+
const handleChange = (value) => {
|
1953
|
+
setShouldKeepDraft(value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1804
1954
|
};
|
1805
1955
|
if (!schema?.options?.draftAndPublish) {
|
1806
1956
|
return null;
|
@@ -1844,45 +1994,30 @@ const UnpublishAction = ({
|
|
1844
1994
|
content: /* @__PURE__ */ jsxs(Flex, { alignItems: "flex-start", direction: "column", gap: 6, children: [
|
1845
1995
|
/* @__PURE__ */ jsxs(Flex, { width: "100%", direction: "column", gap: 2, children: [
|
1846
1996
|
/* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
1847
|
-
/* @__PURE__ */ jsx(Typography, {
|
1997
|
+
/* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
1848
1998
|
id: "content-manager.actions.unpublish.dialog.body",
|
1849
1999
|
defaultMessage: "Are you sure?"
|
1850
2000
|
}) })
|
1851
2001
|
] }),
|
1852
2002
|
/* @__PURE__ */ jsxs(
|
1853
|
-
|
2003
|
+
Radio.Group,
|
1854
2004
|
{
|
1855
|
-
|
1856
|
-
|
1857
|
-
|
1858
|
-
|
1859
|
-
|
2005
|
+
defaultValue: UNPUBLISH_DRAFT_OPTIONS.KEEP,
|
2006
|
+
name: "discard-options",
|
2007
|
+
"aria-label": formatMessage({
|
2008
|
+
id: "content-manager.actions.unpublish.dialog.radio-label",
|
2009
|
+
defaultMessage: "Choose an option to unpublish the document."
|
2010
|
+
}),
|
2011
|
+
onValueChange: handleChange,
|
1860
2012
|
children: [
|
1861
|
-
/* @__PURE__ */ jsx(
|
1862
|
-
|
1863
|
-
|
1864
|
-
|
1865
|
-
|
1866
|
-
|
1867
|
-
|
1868
|
-
|
1869
|
-
id: "content-manager.actions.unpublish.dialog.option.keep-draft",
|
1870
|
-
defaultMessage: "Keep draft"
|
1871
|
-
})
|
1872
|
-
}
|
1873
|
-
),
|
1874
|
-
/* @__PURE__ */ jsx(
|
1875
|
-
Radio,
|
1876
|
-
{
|
1877
|
-
checked: !shouldKeepDraft,
|
1878
|
-
value: UNPUBLISH_DRAFT_OPTIONS.DISCARD,
|
1879
|
-
name: "discard-options",
|
1880
|
-
children: formatMessage({
|
1881
|
-
id: "content-manager.actions.unpublish.dialog.option.replace-draft",
|
1882
|
-
defaultMessage: "Replace draft"
|
1883
|
-
})
|
1884
|
-
}
|
1885
|
-
)
|
2013
|
+
/* @__PURE__ */ jsx(Radio.Item, { checked: shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.KEEP, children: formatMessage({
|
2014
|
+
id: "content-manager.actions.unpublish.dialog.option.keep-draft",
|
2015
|
+
defaultMessage: "Keep draft"
|
2016
|
+
}) }),
|
2017
|
+
/* @__PURE__ */ jsx(Radio.Item, { checked: !shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.DISCARD, children: formatMessage({
|
2018
|
+
id: "content-manager.actions.unpublish.dialog.option.replace-draft",
|
2019
|
+
defaultMessage: "Replace draft"
|
2020
|
+
}) })
|
1886
2021
|
]
|
1887
2022
|
}
|
1888
2023
|
)
|
@@ -1915,7 +2050,7 @@ const UnpublishAction = ({
|
|
1915
2050
|
position: ["panel", "table-row"]
|
1916
2051
|
};
|
1917
2052
|
};
|
1918
|
-
UnpublishAction.type = "unpublish";
|
2053
|
+
UnpublishAction$1.type = "unpublish";
|
1919
2054
|
const DiscardAction = ({
|
1920
2055
|
activeTab,
|
1921
2056
|
documentId,
|
@@ -1949,7 +2084,7 @@ const DiscardAction = ({
|
|
1949
2084
|
}),
|
1950
2085
|
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
|
1951
2086
|
/* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
1952
|
-
/* @__PURE__ */ jsx(Typography, {
|
2087
|
+
/* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
1953
2088
|
id: "content-manager.actions.discard.dialog.body",
|
1954
2089
|
defaultMessage: "Are you sure?"
|
1955
2090
|
}) })
|
@@ -1971,7 +2106,7 @@ const StyledCrossCircle = styled(CrossCircle)`
|
|
1971
2106
|
fill: currentColor;
|
1972
2107
|
}
|
1973
2108
|
`;
|
1974
|
-
const DEFAULT_ACTIONS = [PublishAction, UpdateAction, UnpublishAction, DiscardAction];
|
2109
|
+
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
1975
2110
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
1976
2111
|
const RelativeTime = React.forwardRef(
|
1977
2112
|
({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {
|
@@ -2019,7 +2154,7 @@ const getDisplayName = ({
|
|
2019
2154
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2020
2155
|
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2021
2156
|
const statusVariant = status === "draft" ? "primary" : status === "published" ? "success" : "alternative";
|
2022
|
-
return /* @__PURE__ */ jsx(Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsx(Typography, {
|
2157
|
+
return /* @__PURE__ */ jsx(Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: capitalise(status) }) });
|
2023
2158
|
};
|
2024
2159
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
2025
2160
|
const { formatMessage } = useIntl();
|
@@ -2028,23 +2163,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
|
2028
2163
|
id: "content-manager.containers.edit.title.new",
|
2029
2164
|
defaultMessage: "Create an entry"
|
2030
2165
|
}) : documentTitle;
|
2031
|
-
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop:
|
2166
|
+
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2032
2167
|
/* @__PURE__ */ jsx(BackButton, {}),
|
2033
|
-
/* @__PURE__ */ jsxs(
|
2034
|
-
|
2035
|
-
{
|
2036
|
-
|
2037
|
-
|
2038
|
-
paddingTop: 1,
|
2039
|
-
gap: "80px",
|
2040
|
-
alignItems: "flex-start",
|
2041
|
-
children: [
|
2042
|
-
/* @__PURE__ */ jsx(Typography, { variant: "alpha", as: "h1", children: title }),
|
2043
|
-
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
2044
|
-
]
|
2045
|
-
}
|
2046
|
-
),
|
2047
|
-
status ? /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) : null
|
2168
|
+
/* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2169
|
+
/* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
|
2170
|
+
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
2171
|
+
] }),
|
2172
|
+
status ? /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
|
2048
2173
|
] });
|
2049
2174
|
};
|
2050
2175
|
const HeaderToolbar = () => {
|
@@ -2196,7 +2321,7 @@ const Information = ({ activeTab }) => {
|
|
2196
2321
|
borderColor: "neutral150",
|
2197
2322
|
direction: "column",
|
2198
2323
|
marginTop: 2,
|
2199
|
-
|
2324
|
+
tag: "dl",
|
2200
2325
|
padding: 5,
|
2201
2326
|
gap: 3,
|
2202
2327
|
alignItems: "flex-start",
|
@@ -2204,8 +2329,8 @@ const Information = ({ activeTab }) => {
|
|
2204
2329
|
marginRight: "-0.4rem",
|
2205
2330
|
width: "calc(100% + 8px)",
|
2206
2331
|
children: information.map((info) => /* @__PURE__ */ jsxs(Flex, { gap: 1, direction: "column", alignItems: "flex-start", children: [
|
2207
|
-
/* @__PURE__ */ jsx(Typography, {
|
2208
|
-
/* @__PURE__ */ jsx(Typography, {
|
2332
|
+
/* @__PURE__ */ jsx(Typography, { tag: "dt", variant: "pi", fontWeight: "bold", children: info.label }),
|
2333
|
+
/* @__PURE__ */ jsx(Typography, { tag: "dd", variant: "pi", textColor: "neutral600", children: info.value })
|
2209
2334
|
] }, info.label))
|
2210
2335
|
}
|
2211
2336
|
);
|
@@ -2238,7 +2363,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2238
2363
|
id: "app.links.configure-view",
|
2239
2364
|
defaultMessage: "Configure the view"
|
2240
2365
|
}),
|
2241
|
-
icon: /* @__PURE__ */ jsx(
|
2366
|
+
icon: /* @__PURE__ */ jsx(ListPlus, {}),
|
2242
2367
|
onClick: () => {
|
2243
2368
|
navigate(`../${collectionType}/${model}/configurations/edit`);
|
2244
2369
|
},
|
@@ -2246,11 +2371,6 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2246
2371
|
};
|
2247
2372
|
};
|
2248
2373
|
ConfigureTheViewAction.type = "configure-the-view";
|
2249
|
-
const StyledCog = styled(Cog)`
|
2250
|
-
path {
|
2251
|
-
fill: currentColor;
|
2252
|
-
}
|
2253
|
-
`;
|
2254
2374
|
const EditTheModelAction = ({ model }) => {
|
2255
2375
|
const navigate = useNavigate();
|
2256
2376
|
const { formatMessage } = useIntl();
|
@@ -2259,7 +2379,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2259
2379
|
id: "content-manager.link-to-ctb",
|
2260
2380
|
defaultMessage: "Edit the model"
|
2261
2381
|
}),
|
2262
|
-
icon: /* @__PURE__ */ jsx(
|
2382
|
+
icon: /* @__PURE__ */ jsx(Pencil, {}),
|
2263
2383
|
onClick: () => {
|
2264
2384
|
navigate(`/plugins/content-type-builder/content-types/${model}`);
|
2265
2385
|
},
|
@@ -2267,12 +2387,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2267
2387
|
};
|
2268
2388
|
};
|
2269
2389
|
EditTheModelAction.type = "edit-the-model";
|
2270
|
-
const
|
2271
|
-
path {
|
2272
|
-
fill: currentColor;
|
2273
|
-
}
|
2274
|
-
`;
|
2275
|
-
const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
2390
|
+
const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
2276
2391
|
const navigate = useNavigate();
|
2277
2392
|
const { formatMessage } = useIntl();
|
2278
2393
|
const listViewPathMatch = useMatch(LIST_PATH);
|
@@ -2286,7 +2401,7 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
|
2286
2401
|
id: "content-manager.actions.delete.label",
|
2287
2402
|
defaultMessage: "Delete document"
|
2288
2403
|
}),
|
2289
|
-
icon: /* @__PURE__ */ jsx(
|
2404
|
+
icon: /* @__PURE__ */ jsx(Trash, {}),
|
2290
2405
|
dialog: {
|
2291
2406
|
type: "dialog",
|
2292
2407
|
title: formatMessage({
|
@@ -2295,7 +2410,7 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
|
2295
2410
|
}),
|
2296
2411
|
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
|
2297
2412
|
/* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
2298
|
-
/* @__PURE__ */ jsx(Typography, {
|
2413
|
+
/* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
2299
2414
|
id: "content-manager.actions.delete.dialog.body",
|
2300
2415
|
defaultMessage: "Are you sure?"
|
2301
2416
|
}) })
|
@@ -2340,13 +2455,8 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
|
2340
2455
|
position: ["header", "table-row"]
|
2341
2456
|
};
|
2342
2457
|
};
|
2343
|
-
DeleteAction.type = "delete";
|
2344
|
-
const
|
2345
|
-
path {
|
2346
|
-
fill: currentColor;
|
2347
|
-
}
|
2348
|
-
`;
|
2349
|
-
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction];
|
2458
|
+
DeleteAction$1.type = "delete";
|
2459
|
+
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2350
2460
|
const Panels = () => {
|
2351
2461
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
2352
2462
|
const [
|
@@ -2420,7 +2530,7 @@ const Panel = React.forwardRef(({ children, title }, ref) => {
|
|
2420
2530
|
Flex,
|
2421
2531
|
{
|
2422
2532
|
ref,
|
2423
|
-
|
2533
|
+
tag: "aside",
|
2424
2534
|
"aria-labelledby": "additional-information",
|
2425
2535
|
background: "neutral0",
|
2426
2536
|
borderColor: "neutral150",
|
@@ -2435,116 +2545,995 @@ const Panel = React.forwardRef(({ children, title }, ref) => {
|
|
2435
2545
|
justifyContent: "stretch",
|
2436
2546
|
alignItems: "flex-start",
|
2437
2547
|
children: [
|
2438
|
-
/* @__PURE__ */ jsx(Typography, {
|
2548
|
+
/* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2439
2549
|
children
|
2440
2550
|
]
|
2441
2551
|
}
|
2442
2552
|
);
|
2443
2553
|
});
|
2444
|
-
const
|
2445
|
-
|
2446
|
-
|
2447
|
-
|
2448
|
-
|
2449
|
-
|
2450
|
-
|
2451
|
-
|
2452
|
-
|
2453
|
-
|
2454
|
-
|
2455
|
-
|
2456
|
-
|
2457
|
-
|
2458
|
-
|
2459
|
-
|
2460
|
-
|
2461
|
-
|
2462
|
-
|
2463
|
-
|
2464
|
-
|
2465
|
-
|
2466
|
-
|
2467
|
-
|
2468
|
-
|
2469
|
-
direction: "column",
|
2470
|
-
gap: 2,
|
2471
|
-
alignItems: "flex-start",
|
2472
|
-
borderColor: "neutral200",
|
2473
|
-
hasRadius: true,
|
2474
|
-
padding: 6,
|
2475
|
-
children: [
|
2476
|
-
/* @__PURE__ */ jsx(Flex, { direction: "row", as: "ol", children: fieldPath.map((pathSegment, index2) => /* @__PURE__ */ jsxs(Typography, { fontWeight: "semiBold", as: "li", children: [
|
2477
|
-
pathSegment,
|
2478
|
-
index2 !== fieldPath.length - 1 && /* @__PURE__ */ jsx(
|
2479
|
-
ChevronRight,
|
2480
|
-
{
|
2481
|
-
fill: "neutral500",
|
2482
|
-
height: "0.8rem",
|
2483
|
-
width: "0.8rem",
|
2484
|
-
style: { margin: "0 0.8rem" }
|
2485
|
-
}
|
2486
|
-
)
|
2487
|
-
] }, index2)) }),
|
2488
|
-
/* @__PURE__ */ jsx(Typography, { as: "p", textColor: "neutral600", children: formatMessage({
|
2489
|
-
id: getTranslation(`containers.list.autoCloneModal.error.${reason}`),
|
2490
|
-
defaultMessage: getDefaultErrorMessage(reason)
|
2491
|
-
}) })
|
2492
|
-
]
|
2493
|
-
},
|
2494
|
-
fieldPath.join()
|
2495
|
-
)) })
|
2496
|
-
] });
|
2497
|
-
};
|
2498
|
-
const TableActions = ({ document }) => {
|
2499
|
-
const { formatMessage } = useIntl();
|
2500
|
-
const { model, collectionType } = useDoc();
|
2501
|
-
const plugins = useStrapiApp("TableActions", (state) => state.plugins);
|
2502
|
-
const props = {
|
2503
|
-
activeTab: null,
|
2504
|
-
model,
|
2505
|
-
documentId: document.documentId,
|
2506
|
-
collectionType,
|
2507
|
-
document
|
2508
|
-
};
|
2509
|
-
return /* @__PURE__ */ jsx(
|
2510
|
-
DescriptionComponentRenderer,
|
2511
|
-
{
|
2512
|
-
props,
|
2513
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2514
|
-
children: (actions2) => {
|
2515
|
-
const tableRowActions = actions2.filter((action) => {
|
2516
|
-
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
2517
|
-
return positions.includes("table-row");
|
2518
|
-
});
|
2519
|
-
return /* @__PURE__ */ jsx(
|
2520
|
-
DocumentActionsMenu,
|
2521
|
-
{
|
2522
|
-
actions: tableRowActions,
|
2523
|
-
label: formatMessage({
|
2524
|
-
id: "content-manager.containers.list.table.row-actions",
|
2525
|
-
defaultMessage: "Row action"
|
2526
|
-
}),
|
2527
|
-
variant: "ghost"
|
2528
|
-
}
|
2529
|
-
);
|
2530
|
-
}
|
2531
|
-
}
|
2532
|
-
);
|
2554
|
+
const HOOKS = {
|
2555
|
+
/**
|
2556
|
+
* Hook that allows to mutate the displayed headers of the list view table
|
2557
|
+
* @constant
|
2558
|
+
* @type {string}
|
2559
|
+
*/
|
2560
|
+
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2561
|
+
/**
|
2562
|
+
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2563
|
+
* @constant
|
2564
|
+
* @type {string}
|
2565
|
+
*/
|
2566
|
+
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2567
|
+
/**
|
2568
|
+
* Hook that allows to mutate the CM's edit view layout
|
2569
|
+
* @constant
|
2570
|
+
* @type {string}
|
2571
|
+
*/
|
2572
|
+
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2573
|
+
/**
|
2574
|
+
* Hook that allows to mutate the CM's single types links pre-set filters
|
2575
|
+
* @constant
|
2576
|
+
* @type {string}
|
2577
|
+
*/
|
2578
|
+
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2533
2579
|
};
|
2534
|
-
const
|
2535
|
-
|
2536
|
-
|
2537
|
-
|
2538
|
-
|
2539
|
-
|
2540
|
-
|
2541
|
-
|
2542
|
-
|
2543
|
-
|
2544
|
-
|
2545
|
-
|
2546
|
-
}),
|
2547
|
-
|
2580
|
+
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2581
|
+
endpoints: (builder) => ({
|
2582
|
+
getContentTypeConfiguration: builder.query({
|
2583
|
+
query: (uid) => ({
|
2584
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
2585
|
+
method: "GET"
|
2586
|
+
}),
|
2587
|
+
transformResponse: (response) => response.data,
|
2588
|
+
providesTags: (_result, _error, uid) => [
|
2589
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
2590
|
+
{ type: "ContentTypeSettings", id: "LIST" }
|
2591
|
+
]
|
2592
|
+
}),
|
2593
|
+
getAllContentTypeSettings: builder.query({
|
2594
|
+
query: () => "/content-manager/content-types-settings",
|
2595
|
+
transformResponse: (response) => response.data,
|
2596
|
+
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2597
|
+
}),
|
2598
|
+
updateContentTypeConfiguration: builder.mutation({
|
2599
|
+
query: ({ uid, ...body }) => ({
|
2600
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
2601
|
+
method: "PUT",
|
2602
|
+
data: body
|
2603
|
+
}),
|
2604
|
+
transformResponse: (response) => response.data,
|
2605
|
+
invalidatesTags: (_result, _error, { uid }) => [
|
2606
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
2607
|
+
{ type: "ContentTypeSettings", id: "LIST" },
|
2608
|
+
// Is this necessary?
|
2609
|
+
{ type: "InitialData" }
|
2610
|
+
]
|
2611
|
+
})
|
2612
|
+
})
|
2613
|
+
});
|
2614
|
+
const {
|
2615
|
+
useGetContentTypeConfigurationQuery,
|
2616
|
+
useGetAllContentTypeSettingsQuery,
|
2617
|
+
useUpdateContentTypeConfigurationMutation
|
2618
|
+
} = contentTypesApi;
|
2619
|
+
const checkIfAttributeIsDisplayable = (attribute) => {
|
2620
|
+
const { type } = attribute;
|
2621
|
+
if (type === "relation") {
|
2622
|
+
return !attribute.relation.toLowerCase().includes("morph");
|
2623
|
+
}
|
2624
|
+
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2625
|
+
};
|
2626
|
+
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2627
|
+
if (!mainFieldName) {
|
2628
|
+
return void 0;
|
2629
|
+
}
|
2630
|
+
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2631
|
+
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2632
|
+
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2633
|
+
);
|
2634
|
+
return {
|
2635
|
+
name: mainFieldName,
|
2636
|
+
type: mainFieldType ?? "string"
|
2637
|
+
};
|
2638
|
+
};
|
2639
|
+
const DEFAULT_SETTINGS = {
|
2640
|
+
bulkable: false,
|
2641
|
+
filterable: false,
|
2642
|
+
searchable: false,
|
2643
|
+
pagination: false,
|
2644
|
+
defaultSortBy: "",
|
2645
|
+
defaultSortOrder: "asc",
|
2646
|
+
mainField: "id",
|
2647
|
+
pageSize: 10
|
2648
|
+
};
|
2649
|
+
const useDocumentLayout = (model) => {
|
2650
|
+
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2651
|
+
const [{ query }] = useQueryParams();
|
2652
|
+
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2653
|
+
const { toggleNotification } = useNotification();
|
2654
|
+
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
2655
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2656
|
+
const {
|
2657
|
+
data,
|
2658
|
+
isLoading: isLoadingConfigs,
|
2659
|
+
error,
|
2660
|
+
isFetching: isFetchingConfigs
|
2661
|
+
} = useGetContentTypeConfigurationQuery(model);
|
2662
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2663
|
+
React.useEffect(() => {
|
2664
|
+
if (error) {
|
2665
|
+
toggleNotification({
|
2666
|
+
type: "danger",
|
2667
|
+
message: formatAPIError(error)
|
2668
|
+
});
|
2669
|
+
}
|
2670
|
+
}, [error, formatAPIError, toggleNotification]);
|
2671
|
+
const editLayout = React.useMemo(
|
2672
|
+
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2673
|
+
layout: [],
|
2674
|
+
components: {},
|
2675
|
+
metadatas: {},
|
2676
|
+
options: {},
|
2677
|
+
settings: DEFAULT_SETTINGS
|
2678
|
+
},
|
2679
|
+
[data, isLoading, schemas, schema, components]
|
2680
|
+
);
|
2681
|
+
const listLayout = React.useMemo(() => {
|
2682
|
+
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2683
|
+
layout: [],
|
2684
|
+
metadatas: {},
|
2685
|
+
options: {},
|
2686
|
+
settings: DEFAULT_SETTINGS
|
2687
|
+
};
|
2688
|
+
}, [data, isLoading, schemas, schema, components]);
|
2689
|
+
const { layout: edit } = React.useMemo(
|
2690
|
+
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2691
|
+
layout: editLayout,
|
2692
|
+
query
|
2693
|
+
}),
|
2694
|
+
[editLayout, query, runHookWaterfall]
|
2695
|
+
);
|
2696
|
+
return {
|
2697
|
+
error,
|
2698
|
+
isLoading,
|
2699
|
+
edit,
|
2700
|
+
list: listLayout
|
2701
|
+
};
|
2702
|
+
};
|
2703
|
+
const useDocLayout = () => {
|
2704
|
+
const { model } = useDoc();
|
2705
|
+
return useDocumentLayout(model);
|
2706
|
+
};
|
2707
|
+
const formatEditLayout = (data, {
|
2708
|
+
schemas,
|
2709
|
+
schema,
|
2710
|
+
components
|
2711
|
+
}) => {
|
2712
|
+
let currentPanelIndex = 0;
|
2713
|
+
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2714
|
+
data.contentType.layouts.edit,
|
2715
|
+
schema?.attributes,
|
2716
|
+
data.contentType.metadatas,
|
2717
|
+
{ configurations: data.components, schemas: components },
|
2718
|
+
schemas
|
2719
|
+
).reduce((panels, row) => {
|
2720
|
+
if (row.some((field) => field.type === "dynamiczone")) {
|
2721
|
+
panels.push([row]);
|
2722
|
+
currentPanelIndex += 2;
|
2723
|
+
} else {
|
2724
|
+
if (!panels[currentPanelIndex]) {
|
2725
|
+
panels.push([]);
|
2726
|
+
}
|
2727
|
+
panels[currentPanelIndex].push(row);
|
2728
|
+
}
|
2729
|
+
return panels;
|
2730
|
+
}, []);
|
2731
|
+
const componentEditAttributes = Object.entries(data.components).reduce(
|
2732
|
+
(acc, [uid, configuration]) => {
|
2733
|
+
acc[uid] = {
|
2734
|
+
layout: convertEditLayoutToFieldLayouts(
|
2735
|
+
configuration.layouts.edit,
|
2736
|
+
components[uid].attributes,
|
2737
|
+
configuration.metadatas
|
2738
|
+
),
|
2739
|
+
settings: {
|
2740
|
+
...configuration.settings,
|
2741
|
+
icon: components[uid].info.icon,
|
2742
|
+
displayName: components[uid].info.displayName
|
2743
|
+
}
|
2744
|
+
};
|
2745
|
+
return acc;
|
2746
|
+
},
|
2747
|
+
{}
|
2748
|
+
);
|
2749
|
+
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2750
|
+
(acc, [attribute, metadata]) => {
|
2751
|
+
return {
|
2752
|
+
...acc,
|
2753
|
+
[attribute]: metadata.edit
|
2754
|
+
};
|
2755
|
+
},
|
2756
|
+
{}
|
2757
|
+
);
|
2758
|
+
return {
|
2759
|
+
layout: panelledEditAttributes,
|
2760
|
+
components: componentEditAttributes,
|
2761
|
+
metadatas: editMetadatas,
|
2762
|
+
settings: {
|
2763
|
+
...data.contentType.settings,
|
2764
|
+
displayName: schema?.info.displayName
|
2765
|
+
},
|
2766
|
+
options: {
|
2767
|
+
...schema?.options,
|
2768
|
+
...schema?.pluginOptions,
|
2769
|
+
...data.contentType.options
|
2770
|
+
}
|
2771
|
+
};
|
2772
|
+
};
|
2773
|
+
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
2774
|
+
return rows.map(
|
2775
|
+
(row) => row.map((field) => {
|
2776
|
+
const attribute = attributes[field.name];
|
2777
|
+
if (!attribute) {
|
2778
|
+
return null;
|
2779
|
+
}
|
2780
|
+
const { edit: metadata } = metadatas[field.name];
|
2781
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
2782
|
+
return {
|
2783
|
+
attribute,
|
2784
|
+
disabled: !metadata.editable,
|
2785
|
+
hint: metadata.description,
|
2786
|
+
label: metadata.label ?? "",
|
2787
|
+
name: field.name,
|
2788
|
+
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
2789
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
2790
|
+
schemas,
|
2791
|
+
components: components?.schemas ?? {}
|
2792
|
+
}),
|
2793
|
+
placeholder: metadata.placeholder ?? "",
|
2794
|
+
required: attribute.required ?? false,
|
2795
|
+
size: field.size,
|
2796
|
+
unique: "unique" in attribute ? attribute.unique : false,
|
2797
|
+
visible: metadata.visible ?? true,
|
2798
|
+
type: attribute.type
|
2799
|
+
};
|
2800
|
+
}).filter((field) => field !== null)
|
2801
|
+
);
|
2802
|
+
};
|
2803
|
+
const formatListLayout = (data, {
|
2804
|
+
schemas,
|
2805
|
+
schema,
|
2806
|
+
components
|
2807
|
+
}) => {
|
2808
|
+
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2809
|
+
(acc, [attribute, metadata]) => {
|
2810
|
+
return {
|
2811
|
+
...acc,
|
2812
|
+
[attribute]: metadata.list
|
2813
|
+
};
|
2814
|
+
},
|
2815
|
+
{}
|
2816
|
+
);
|
2817
|
+
const listAttributes = convertListLayoutToFieldLayouts(
|
2818
|
+
data.contentType.layouts.list,
|
2819
|
+
schema?.attributes,
|
2820
|
+
listMetadatas,
|
2821
|
+
{ configurations: data.components, schemas: components },
|
2822
|
+
schemas
|
2823
|
+
);
|
2824
|
+
return {
|
2825
|
+
layout: listAttributes,
|
2826
|
+
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
2827
|
+
metadatas: listMetadatas,
|
2828
|
+
options: {
|
2829
|
+
...schema?.options,
|
2830
|
+
...schema?.pluginOptions,
|
2831
|
+
...data.contentType.options
|
2832
|
+
}
|
2833
|
+
};
|
2834
|
+
};
|
2835
|
+
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
2836
|
+
return columns.map((name) => {
|
2837
|
+
const attribute = attributes[name];
|
2838
|
+
if (!attribute) {
|
2839
|
+
return null;
|
2840
|
+
}
|
2841
|
+
const metadata = metadatas[name];
|
2842
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
2843
|
+
return {
|
2844
|
+
attribute,
|
2845
|
+
label: metadata.label ?? "",
|
2846
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
2847
|
+
schemas,
|
2848
|
+
components: components?.schemas ?? {}
|
2849
|
+
}),
|
2850
|
+
name,
|
2851
|
+
searchable: metadata.searchable ?? true,
|
2852
|
+
sortable: metadata.sortable ?? true
|
2853
|
+
};
|
2854
|
+
}).filter((field) => field !== null);
|
2855
|
+
};
|
2856
|
+
const ConfirmBulkActionDialog = ({
|
2857
|
+
onToggleDialog,
|
2858
|
+
isOpen = false,
|
2859
|
+
dialogBody,
|
2860
|
+
endAction
|
2861
|
+
}) => {
|
2862
|
+
const { formatMessage } = useIntl();
|
2863
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
2864
|
+
/* @__PURE__ */ jsx(Dialog.Header, { children: formatMessage({
|
2865
|
+
id: "app.components.ConfirmDialog.title",
|
2866
|
+
defaultMessage: "Confirmation"
|
2867
|
+
}) }),
|
2868
|
+
/* @__PURE__ */ jsx(Dialog.Body, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
2869
|
+
/* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
2870
|
+
dialogBody
|
2871
|
+
] }) }),
|
2872
|
+
/* @__PURE__ */ jsxs(Dialog.Footer, { children: [
|
2873
|
+
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { fullWidth: true, onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
|
2874
|
+
id: "app.components.Button.cancel",
|
2875
|
+
defaultMessage: "Cancel"
|
2876
|
+
}) }) }),
|
2877
|
+
endAction
|
2878
|
+
] })
|
2879
|
+
] }) });
|
2880
|
+
};
|
2881
|
+
const BoldChunk$1 = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
|
2882
|
+
const ConfirmDialogPublishAll = ({
|
2883
|
+
isOpen,
|
2884
|
+
onToggleDialog,
|
2885
|
+
isConfirmButtonLoading = false,
|
2886
|
+
onConfirm
|
2887
|
+
}) => {
|
2888
|
+
const { formatMessage } = useIntl();
|
2889
|
+
const selectedEntries = useTable("ConfirmDialogPublishAll", (state) => state.selectedRows);
|
2890
|
+
const { toggleNotification } = useNotification();
|
2891
|
+
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(getTranslation);
|
2892
|
+
const { model, schema } = useDoc();
|
2893
|
+
const [{ query }] = useQueryParams();
|
2894
|
+
const {
|
2895
|
+
data: countDraftRelations = 0,
|
2896
|
+
isLoading,
|
2897
|
+
error
|
2898
|
+
} = useGetManyDraftRelationCountQuery(
|
2899
|
+
{
|
2900
|
+
model,
|
2901
|
+
documentIds: selectedEntries.map((entry) => entry.documentId),
|
2902
|
+
locale: query?.plugins?.i18n?.locale
|
2903
|
+
},
|
2904
|
+
{
|
2905
|
+
skip: selectedEntries.length === 0
|
2906
|
+
}
|
2907
|
+
);
|
2908
|
+
React.useEffect(() => {
|
2909
|
+
if (error) {
|
2910
|
+
toggleNotification({ type: "danger", message: formatAPIError(error) });
|
2911
|
+
}
|
2912
|
+
}, [error, formatAPIError, toggleNotification]);
|
2913
|
+
if (error) {
|
2914
|
+
return null;
|
2915
|
+
}
|
2916
|
+
return /* @__PURE__ */ jsx(
|
2917
|
+
ConfirmBulkActionDialog,
|
2918
|
+
{
|
2919
|
+
isOpen: isOpen && !isLoading,
|
2920
|
+
onToggleDialog,
|
2921
|
+
dialogBody: /* @__PURE__ */ jsxs(Fragment, { children: [
|
2922
|
+
/* @__PURE__ */ jsxs(Typography, { id: "confirm-description", textAlign: "center", children: [
|
2923
|
+
countDraftRelations > 0 && formatMessage(
|
2924
|
+
{
|
2925
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
2926
|
+
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. "
|
2927
|
+
},
|
2928
|
+
{
|
2929
|
+
b: BoldChunk$1,
|
2930
|
+
count: countDraftRelations,
|
2931
|
+
entities: selectedEntries.length
|
2932
|
+
}
|
2933
|
+
),
|
2934
|
+
formatMessage({
|
2935
|
+
id: getTranslation("popUpWarning.bodyMessage.contentType.publish.all"),
|
2936
|
+
defaultMessage: "Are you sure you want to publish these entries?"
|
2937
|
+
})
|
2938
|
+
] }),
|
2939
|
+
schema?.pluginOptions && "i18n" in schema.pluginOptions && schema?.pluginOptions.i18n && /* @__PURE__ */ jsx(Typography, { textColor: "danger500", textAlign: "center", children: formatMessage(
|
2940
|
+
{
|
2941
|
+
id: getTranslation("Settings.list.actions.publishAdditionalInfos"),
|
2942
|
+
defaultMessage: "This will publish the active locale versions <em>(from Internationalization)</em>"
|
2943
|
+
},
|
2944
|
+
{
|
2945
|
+
em: Emphasis
|
2946
|
+
}
|
2947
|
+
) })
|
2948
|
+
] }),
|
2949
|
+
endAction: /* @__PURE__ */ jsx(
|
2950
|
+
Button,
|
2951
|
+
{
|
2952
|
+
onClick: onConfirm,
|
2953
|
+
variant: "secondary",
|
2954
|
+
startIcon: /* @__PURE__ */ jsx(Check, {}),
|
2955
|
+
loading: isConfirmButtonLoading,
|
2956
|
+
children: formatMessage({
|
2957
|
+
id: "app.utils.publish",
|
2958
|
+
defaultMessage: "Publish"
|
2959
|
+
})
|
2960
|
+
}
|
2961
|
+
)
|
2962
|
+
}
|
2963
|
+
);
|
2964
|
+
};
|
2965
|
+
const TypographyMaxWidth = styled(Typography)`
|
2966
|
+
max-width: 300px;
|
2967
|
+
`;
|
2968
|
+
const formatErrorMessages = (errors, parentKey, formatMessage) => {
|
2969
|
+
const messages = [];
|
2970
|
+
Object.entries(errors).forEach(([key, value]) => {
|
2971
|
+
const currentKey = parentKey ? `${parentKey}.${key}` : key;
|
2972
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
2973
|
+
if ("id" in value && "defaultMessage" in value) {
|
2974
|
+
messages.push(
|
2975
|
+
formatMessage(
|
2976
|
+
{
|
2977
|
+
id: `${value.id}.withField`,
|
2978
|
+
defaultMessage: value.defaultMessage
|
2979
|
+
},
|
2980
|
+
{ field: currentKey }
|
2981
|
+
)
|
2982
|
+
);
|
2983
|
+
} else {
|
2984
|
+
messages.push(
|
2985
|
+
...formatErrorMessages(
|
2986
|
+
// @ts-expect-error TODO: check why value is not compatible with FormErrors
|
2987
|
+
value,
|
2988
|
+
currentKey,
|
2989
|
+
formatMessage
|
2990
|
+
)
|
2991
|
+
);
|
2992
|
+
}
|
2993
|
+
} else {
|
2994
|
+
messages.push(
|
2995
|
+
formatMessage(
|
2996
|
+
{
|
2997
|
+
id: `${value}.withField`,
|
2998
|
+
defaultMessage: value
|
2999
|
+
},
|
3000
|
+
{ field: currentKey }
|
3001
|
+
)
|
3002
|
+
);
|
3003
|
+
}
|
3004
|
+
});
|
3005
|
+
return messages;
|
3006
|
+
};
|
3007
|
+
const EntryValidationText = ({ validationErrors, status }) => {
|
3008
|
+
const { formatMessage } = useIntl();
|
3009
|
+
if (validationErrors) {
|
3010
|
+
const validationErrorsMessages = formatErrorMessages(validationErrors, "", formatMessage).join(
|
3011
|
+
" "
|
3012
|
+
);
|
3013
|
+
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
3014
|
+
/* @__PURE__ */ jsx(CrossCircle, { fill: "danger600" }),
|
3015
|
+
/* @__PURE__ */ jsx(Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsx(TypographyMaxWidth, { textColor: "danger600", variant: "omega", fontWeight: "semiBold", ellipsis: true, children: validationErrorsMessages }) })
|
3016
|
+
] });
|
3017
|
+
}
|
3018
|
+
if (status === "published") {
|
3019
|
+
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
3020
|
+
/* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
3021
|
+
/* @__PURE__ */ jsx(Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
|
3022
|
+
id: "content-manager.bulk-publish.already-published",
|
3023
|
+
defaultMessage: "Already Published"
|
3024
|
+
}) })
|
3025
|
+
] });
|
3026
|
+
}
|
3027
|
+
if (status === "modified") {
|
3028
|
+
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
3029
|
+
/* @__PURE__ */ jsx(ArrowsCounterClockwise, { fill: "alternative600" }),
|
3030
|
+
/* @__PURE__ */ jsx(Typography, { children: formatMessage({
|
3031
|
+
id: "content-manager.bulk-publish.modified",
|
3032
|
+
defaultMessage: "Ready to publish changes"
|
3033
|
+
}) })
|
3034
|
+
] });
|
3035
|
+
}
|
3036
|
+
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
3037
|
+
/* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
3038
|
+
/* @__PURE__ */ jsx(Typography, { children: formatMessage({
|
3039
|
+
id: "app.utils.ready-to-publish",
|
3040
|
+
defaultMessage: "Ready to publish"
|
3041
|
+
}) })
|
3042
|
+
] });
|
3043
|
+
};
|
3044
|
+
const TABLE_HEADERS = [
|
3045
|
+
{ name: "id", label: "id" },
|
3046
|
+
{ name: "name", label: "name" },
|
3047
|
+
{ name: "status", label: "status" },
|
3048
|
+
{ name: "publicationStatus", label: "Publication status" }
|
3049
|
+
];
|
3050
|
+
const SelectedEntriesTableContent = ({
|
3051
|
+
isPublishing,
|
3052
|
+
rowsToDisplay = [],
|
3053
|
+
entriesToPublish = [],
|
3054
|
+
validationErrors = {}
|
3055
|
+
}) => {
|
3056
|
+
const { pathname } = useLocation();
|
3057
|
+
const { formatMessage } = useIntl();
|
3058
|
+
const {
|
3059
|
+
list: {
|
3060
|
+
settings: { mainField }
|
3061
|
+
}
|
3062
|
+
} = useDocLayout();
|
3063
|
+
const shouldDisplayMainField = mainField != null && mainField !== "id";
|
3064
|
+
return /* @__PURE__ */ jsxs(Table.Content, { children: [
|
3065
|
+
/* @__PURE__ */ jsxs(Table.Head, { children: [
|
3066
|
+
/* @__PURE__ */ jsx(Table.HeaderCheckboxCell, {}),
|
3067
|
+
TABLE_HEADERS.filter((head) => head.name !== "name" || shouldDisplayMainField).map(
|
3068
|
+
(head) => /* @__PURE__ */ jsx(Table.HeaderCell, { ...head }, head.name)
|
3069
|
+
)
|
3070
|
+
] }),
|
3071
|
+
/* @__PURE__ */ jsx(Table.Loading, {}),
|
3072
|
+
/* @__PURE__ */ jsx(Table.Body, { children: rowsToDisplay.map((row, index2) => /* @__PURE__ */ jsxs(Table.Row, { children: [
|
3073
|
+
/* @__PURE__ */ jsx(Table.CheckboxCell, { id: row.id }),
|
3074
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Typography, { children: row.id }) }),
|
3075
|
+
shouldDisplayMainField && /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Typography, { children: row[mainField] }) }),
|
3076
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(DocumentStatus, { status: row.status, maxWidth: "min-content" }) }),
|
3077
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: isPublishing && entriesToPublish.includes(row.documentId) ? /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
3078
|
+
/* @__PURE__ */ jsx(Typography, { children: formatMessage({
|
3079
|
+
id: "content-manager.success.record.publishing",
|
3080
|
+
defaultMessage: "Publishing..."
|
3081
|
+
}) }),
|
3082
|
+
/* @__PURE__ */ jsx(Loader, { small: true })
|
3083
|
+
] }) : /* @__PURE__ */ jsx(
|
3084
|
+
EntryValidationText,
|
3085
|
+
{
|
3086
|
+
validationErrors: validationErrors[row.documentId],
|
3087
|
+
status: row.status
|
3088
|
+
}
|
3089
|
+
) }),
|
3090
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(
|
3091
|
+
IconButton,
|
3092
|
+
{
|
3093
|
+
tag: Link,
|
3094
|
+
to: {
|
3095
|
+
pathname: `${pathname}/${row.documentId}`,
|
3096
|
+
search: row.locale && `?plugins[i18n][locale]=${row.locale}`
|
3097
|
+
},
|
3098
|
+
state: { from: pathname },
|
3099
|
+
label: formatMessage(
|
3100
|
+
{ id: "app.component.HelperPluginTable.edit", defaultMessage: "Edit {target}" },
|
3101
|
+
{
|
3102
|
+
target: formatMessage(
|
3103
|
+
{
|
3104
|
+
id: "content-manager.components.ListViewHelperPluginTable.row-line",
|
3105
|
+
defaultMessage: "item line {number}"
|
3106
|
+
},
|
3107
|
+
{ number: index2 + 1 }
|
3108
|
+
)
|
3109
|
+
}
|
3110
|
+
),
|
3111
|
+
target: "_blank",
|
3112
|
+
marginLeft: "auto",
|
3113
|
+
children: /* @__PURE__ */ jsx(Pencil, {})
|
3114
|
+
}
|
3115
|
+
) })
|
3116
|
+
] }, row.id)) })
|
3117
|
+
] });
|
3118
|
+
};
|
3119
|
+
const BoldChunk = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
|
3120
|
+
const SelectedEntriesModalContent = ({
|
3121
|
+
listViewSelectedEntries,
|
3122
|
+
toggleModal,
|
3123
|
+
setListViewSelectedDocuments,
|
3124
|
+
model
|
3125
|
+
}) => {
|
3126
|
+
const { formatMessage } = useIntl();
|
3127
|
+
const { schema, components } = useContentTypeSchema(model);
|
3128
|
+
const documentIds = listViewSelectedEntries.map(({ documentId }) => documentId);
|
3129
|
+
const [{ query }] = useQueryParams();
|
3130
|
+
const params = React.useMemo(() => buildValidParams(query), [query]);
|
3131
|
+
const { data, isLoading, isFetching, refetch } = useGetAllDocumentsQuery(
|
3132
|
+
{
|
3133
|
+
model,
|
3134
|
+
params: {
|
3135
|
+
page: "1",
|
3136
|
+
pageSize: documentIds.length.toString(),
|
3137
|
+
sort: query.sort,
|
3138
|
+
filters: {
|
3139
|
+
documentId: {
|
3140
|
+
$in: documentIds
|
3141
|
+
}
|
3142
|
+
},
|
3143
|
+
locale: query.plugins?.i18n?.locale
|
3144
|
+
}
|
3145
|
+
},
|
3146
|
+
{
|
3147
|
+
selectFromResult: ({ data: data2, ...restRes }) => ({ data: data2?.results ?? [], ...restRes })
|
3148
|
+
}
|
3149
|
+
);
|
3150
|
+
const { rows, validationErrors } = React.useMemo(() => {
|
3151
|
+
if (data.length > 0 && schema) {
|
3152
|
+
const validate = createYupSchema(schema.attributes, components);
|
3153
|
+
const validationErrors2 = {};
|
3154
|
+
const rows2 = data.map((entry) => {
|
3155
|
+
try {
|
3156
|
+
validate.validateSync(entry, { abortEarly: false });
|
3157
|
+
return entry;
|
3158
|
+
} catch (e) {
|
3159
|
+
if (e instanceof ValidationError) {
|
3160
|
+
validationErrors2[entry.documentId] = getYupValidationErrors(e);
|
3161
|
+
}
|
3162
|
+
return entry;
|
3163
|
+
}
|
3164
|
+
});
|
3165
|
+
return { rows: rows2, validationErrors: validationErrors2 };
|
3166
|
+
}
|
3167
|
+
return {
|
3168
|
+
rows: [],
|
3169
|
+
validationErrors: {}
|
3170
|
+
};
|
3171
|
+
}, [components, data, schema]);
|
3172
|
+
const [publishedCount, setPublishedCount] = React.useState(0);
|
3173
|
+
const [isDialogOpen, setIsDialogOpen] = React.useState(false);
|
3174
|
+
const { publishMany: bulkPublishAction } = useDocumentActions();
|
3175
|
+
const [, { isLoading: isSubmittingForm }] = usePublishManyDocumentsMutation();
|
3176
|
+
const selectedRows = useTable("publishAction", (state) => state.selectedRows);
|
3177
|
+
const selectedEntries = rows.filter(
|
3178
|
+
(entry) => selectedRows.some((selectedEntry) => selectedEntry.documentId === entry.documentId)
|
3179
|
+
);
|
3180
|
+
const entriesToPublish = selectedEntries.filter((entry) => !validationErrors[entry.documentId]).map((entry) => entry.documentId);
|
3181
|
+
const selectedEntriesWithErrorsCount = selectedEntries.filter(
|
3182
|
+
({ documentId }) => validationErrors[documentId]
|
3183
|
+
).length;
|
3184
|
+
const selectedEntriesPublished = selectedEntries.filter(
|
3185
|
+
({ status }) => status === "published"
|
3186
|
+
).length;
|
3187
|
+
const selectedEntriesWithNoErrorsCount = selectedEntries.length - selectedEntriesWithErrorsCount - selectedEntriesPublished;
|
3188
|
+
const toggleDialog = () => setIsDialogOpen((prev) => !prev);
|
3189
|
+
const handleConfirmBulkPublish = async () => {
|
3190
|
+
toggleDialog();
|
3191
|
+
const res = await bulkPublishAction({ model, documentIds: entriesToPublish, params });
|
3192
|
+
if (!("error" in res)) {
|
3193
|
+
setPublishedCount(res.count);
|
3194
|
+
const unpublishedEntries = rows.filter((row) => {
|
3195
|
+
return !entriesToPublish.includes(row.documentId);
|
3196
|
+
});
|
3197
|
+
setListViewSelectedDocuments(unpublishedEntries);
|
3198
|
+
}
|
3199
|
+
};
|
3200
|
+
const getFormattedCountMessage = () => {
|
3201
|
+
if (publishedCount) {
|
3202
|
+
return formatMessage(
|
3203
|
+
{
|
3204
|
+
id: getTranslation("containers.list.selectedEntriesModal.publishedCount"),
|
3205
|
+
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."
|
3206
|
+
},
|
3207
|
+
{
|
3208
|
+
publishedCount,
|
3209
|
+
withErrorsCount: selectedEntriesWithErrorsCount,
|
3210
|
+
b: BoldChunk
|
3211
|
+
}
|
3212
|
+
);
|
3213
|
+
}
|
3214
|
+
return formatMessage(
|
3215
|
+
{
|
3216
|
+
id: getTranslation("containers.list.selectedEntriesModal.selectedCount"),
|
3217
|
+
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."
|
3218
|
+
},
|
3219
|
+
{
|
3220
|
+
readyToPublishCount: selectedEntriesWithNoErrorsCount,
|
3221
|
+
withErrorsCount: selectedEntriesWithErrorsCount,
|
3222
|
+
alreadyPublishedCount: selectedEntriesPublished,
|
3223
|
+
b: BoldChunk
|
3224
|
+
}
|
3225
|
+
);
|
3226
|
+
};
|
3227
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
3228
|
+
/* @__PURE__ */ jsxs(Modal.Body, { children: [
|
3229
|
+
/* @__PURE__ */ jsx(Typography, { children: getFormattedCountMessage() }),
|
3230
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 5, children: /* @__PURE__ */ jsx(
|
3231
|
+
SelectedEntriesTableContent,
|
3232
|
+
{
|
3233
|
+
isPublishing: isSubmittingForm,
|
3234
|
+
rowsToDisplay: rows,
|
3235
|
+
entriesToPublish,
|
3236
|
+
validationErrors
|
3237
|
+
}
|
3238
|
+
) })
|
3239
|
+
] }),
|
3240
|
+
/* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
3241
|
+
/* @__PURE__ */ jsx(Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
|
3242
|
+
id: "app.components.Button.cancel",
|
3243
|
+
defaultMessage: "Cancel"
|
3244
|
+
}) }),
|
3245
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
3246
|
+
/* @__PURE__ */ jsx(Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
|
3247
|
+
/* @__PURE__ */ jsx(
|
3248
|
+
Button,
|
3249
|
+
{
|
3250
|
+
onClick: toggleDialog,
|
3251
|
+
disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
|
3252
|
+
loading: isSubmittingForm,
|
3253
|
+
children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
|
3254
|
+
}
|
3255
|
+
)
|
3256
|
+
] })
|
3257
|
+
] }),
|
3258
|
+
/* @__PURE__ */ jsx(
|
3259
|
+
ConfirmDialogPublishAll,
|
3260
|
+
{
|
3261
|
+
isOpen: isDialogOpen,
|
3262
|
+
onToggleDialog: toggleDialog,
|
3263
|
+
isConfirmButtonLoading: isSubmittingForm,
|
3264
|
+
onConfirm: handleConfirmBulkPublish
|
3265
|
+
}
|
3266
|
+
)
|
3267
|
+
] });
|
3268
|
+
};
|
3269
|
+
const PublishAction = ({ documents, model }) => {
|
3270
|
+
const { formatMessage } = useIntl();
|
3271
|
+
const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
|
3272
|
+
const showPublishButton = hasPublishPermission && documents.some(({ status }) => status !== "published");
|
3273
|
+
const setListViewSelectedDocuments = useTable("publishAction", (state) => state.selectRow);
|
3274
|
+
const refetchList = () => {
|
3275
|
+
contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
|
3276
|
+
};
|
3277
|
+
if (!showPublishButton)
|
3278
|
+
return null;
|
3279
|
+
return {
|
3280
|
+
actionType: "publish",
|
3281
|
+
variant: "tertiary",
|
3282
|
+
label: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" }),
|
3283
|
+
dialog: {
|
3284
|
+
type: "modal",
|
3285
|
+
title: formatMessage({
|
3286
|
+
id: getTranslation("containers.ListPage.selectedEntriesModal.title"),
|
3287
|
+
defaultMessage: "Publish entries"
|
3288
|
+
}),
|
3289
|
+
content: ({ onClose }) => {
|
3290
|
+
return /* @__PURE__ */ jsx(Table.Root, { rows: documents, defaultSelectedRows: documents, headers: TABLE_HEADERS, children: /* @__PURE__ */ jsx(
|
3291
|
+
SelectedEntriesModalContent,
|
3292
|
+
{
|
3293
|
+
listViewSelectedEntries: documents,
|
3294
|
+
toggleModal: () => {
|
3295
|
+
onClose();
|
3296
|
+
refetchList();
|
3297
|
+
},
|
3298
|
+
setListViewSelectedDocuments,
|
3299
|
+
model
|
3300
|
+
}
|
3301
|
+
) });
|
3302
|
+
},
|
3303
|
+
onClose: () => {
|
3304
|
+
refetchList();
|
3305
|
+
}
|
3306
|
+
}
|
3307
|
+
};
|
3308
|
+
};
|
3309
|
+
const BulkActionsRenderer = () => {
|
3310
|
+
const plugins = useStrapiApp("BulkActionsRenderer", (state) => state.plugins);
|
3311
|
+
const { model, collectionType } = useDoc();
|
3312
|
+
const { selectedRows } = useTable("BulkActionsRenderer", (state) => state);
|
3313
|
+
return /* @__PURE__ */ jsx(Flex, { gap: 2, children: /* @__PURE__ */ jsx(
|
3314
|
+
DescriptionComponentRenderer,
|
3315
|
+
{
|
3316
|
+
props: {
|
3317
|
+
model,
|
3318
|
+
collectionType,
|
3319
|
+
documents: selectedRows
|
3320
|
+
},
|
3321
|
+
descriptions: plugins["content-manager"].apis.getBulkActions(),
|
3322
|
+
children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsx(DocumentActionButton, { ...action }, action.id))
|
3323
|
+
}
|
3324
|
+
) });
|
3325
|
+
};
|
3326
|
+
const DeleteAction = ({ documents, model }) => {
|
3327
|
+
const { formatMessage } = useIntl();
|
3328
|
+
const { schema: contentType } = useDoc();
|
3329
|
+
const selectRow = useTable("DeleteAction", (state) => state.selectRow);
|
3330
|
+
const hasI18nEnabled = Boolean(contentType?.pluginOptions?.i18n);
|
3331
|
+
const [{ query }] = useQueryParams();
|
3332
|
+
const params = React.useMemo(() => buildValidParams(query), [query]);
|
3333
|
+
const hasDeletePermission = useDocumentRBAC("deleteAction", (state) => state.canDelete);
|
3334
|
+
const { deleteMany: bulkDeleteAction } = useDocumentActions();
|
3335
|
+
const documentIds = documents.map(({ documentId }) => documentId);
|
3336
|
+
const handleConfirmBulkDelete = async () => {
|
3337
|
+
const res = await bulkDeleteAction({
|
3338
|
+
documentIds,
|
3339
|
+
model,
|
3340
|
+
params
|
3341
|
+
});
|
3342
|
+
if (!("error" in res)) {
|
3343
|
+
selectRow([]);
|
3344
|
+
}
|
3345
|
+
};
|
3346
|
+
if (!hasDeletePermission)
|
3347
|
+
return null;
|
3348
|
+
return {
|
3349
|
+
variant: "danger-light",
|
3350
|
+
label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
|
3351
|
+
dialog: {
|
3352
|
+
type: "dialog",
|
3353
|
+
title: formatMessage({
|
3354
|
+
id: "app.components.ConfirmDialog.title",
|
3355
|
+
defaultMessage: "Confirmation"
|
3356
|
+
}),
|
3357
|
+
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3358
|
+
/* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3359
|
+
/* @__PURE__ */ jsx(Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
|
3360
|
+
id: "popUpWarning.bodyMessage.contentType.delete.all",
|
3361
|
+
defaultMessage: "Are you sure you want to delete these entries?"
|
3362
|
+
}) }),
|
3363
|
+
hasI18nEnabled && /* @__PURE__ */ jsx(Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsx(Typography, { textColor: "danger500", children: formatMessage(
|
3364
|
+
{
|
3365
|
+
id: getTranslation("Settings.list.actions.deleteAdditionalInfos"),
|
3366
|
+
defaultMessage: "This will delete the active locale versions <em>(from Internationalization)</em>"
|
3367
|
+
},
|
3368
|
+
{
|
3369
|
+
em: Emphasis
|
3370
|
+
}
|
3371
|
+
) }) })
|
3372
|
+
] }),
|
3373
|
+
onConfirm: handleConfirmBulkDelete
|
3374
|
+
}
|
3375
|
+
};
|
3376
|
+
};
|
3377
|
+
DeleteAction.type = "delete";
|
3378
|
+
const UnpublishAction = ({ documents, model }) => {
|
3379
|
+
const { formatMessage } = useIntl();
|
3380
|
+
const { schema } = useDoc();
|
3381
|
+
const selectRow = useTable("UnpublishAction", (state) => state.selectRow);
|
3382
|
+
const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
|
3383
|
+
const hasI18nEnabled = Boolean(schema?.pluginOptions?.i18n);
|
3384
|
+
const hasDraftAndPublishEnabled = Boolean(schema?.options?.draftAndPublish);
|
3385
|
+
const { unpublishMany: bulkUnpublishAction } = useDocumentActions();
|
3386
|
+
const documentIds = documents.map(({ documentId }) => documentId);
|
3387
|
+
const [{ query }] = useQueryParams();
|
3388
|
+
const params = React.useMemo(() => buildValidParams(query), [query]);
|
3389
|
+
const handleConfirmBulkUnpublish = async () => {
|
3390
|
+
const data = await bulkUnpublishAction({ documentIds, model, params });
|
3391
|
+
if (!("error" in data)) {
|
3392
|
+
selectRow([]);
|
3393
|
+
}
|
3394
|
+
};
|
3395
|
+
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
|
3396
|
+
if (!showUnpublishButton)
|
3397
|
+
return null;
|
3398
|
+
return {
|
3399
|
+
variant: "tertiary",
|
3400
|
+
label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
|
3401
|
+
dialog: {
|
3402
|
+
type: "dialog",
|
3403
|
+
title: formatMessage({
|
3404
|
+
id: "app.components.ConfirmDialog.title",
|
3405
|
+
defaultMessage: "Confirmation"
|
3406
|
+
}),
|
3407
|
+
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3408
|
+
/* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3409
|
+
/* @__PURE__ */ jsx(Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
|
3410
|
+
id: "popUpWarning.bodyMessage.contentType.unpublish.all",
|
3411
|
+
defaultMessage: "Are you sure you want to unpublish these entries?"
|
3412
|
+
}) }),
|
3413
|
+
hasI18nEnabled && /* @__PURE__ */ jsx(Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsx(Typography, { textColor: "danger500", children: formatMessage(
|
3414
|
+
{
|
3415
|
+
id: getTranslation("Settings.list.actions.unpublishAdditionalInfos"),
|
3416
|
+
defaultMessage: "This will unpublish the active locale versions <em>(from Internationalization)</em>"
|
3417
|
+
},
|
3418
|
+
{
|
3419
|
+
em: Emphasis
|
3420
|
+
}
|
3421
|
+
) }) })
|
3422
|
+
] }),
|
3423
|
+
confirmButton: formatMessage({
|
3424
|
+
id: "app.utils.unpublish",
|
3425
|
+
defaultMessage: "Unpublish"
|
3426
|
+
}),
|
3427
|
+
onConfirm: handleConfirmBulkUnpublish
|
3428
|
+
}
|
3429
|
+
};
|
3430
|
+
};
|
3431
|
+
UnpublishAction.type = "unpublish";
|
3432
|
+
const Emphasis = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold", textColor: "danger500", children: chunks });
|
3433
|
+
const DEFAULT_BULK_ACTIONS = [PublishAction, UnpublishAction, DeleteAction];
|
3434
|
+
const AutoCloneFailureModalBody = ({ prohibitedFields }) => {
|
3435
|
+
const { formatMessage } = useIntl();
|
3436
|
+
const getDefaultErrorMessage = (reason) => {
|
3437
|
+
switch (reason) {
|
3438
|
+
case "relation":
|
3439
|
+
return "Duplicating the relation could remove it from the original entry.";
|
3440
|
+
case "unique":
|
3441
|
+
return "Identical values in a unique field are not allowed";
|
3442
|
+
default:
|
3443
|
+
return reason;
|
3444
|
+
}
|
3445
|
+
};
|
3446
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
3447
|
+
/* @__PURE__ */ jsx(Typography, { variant: "beta", children: formatMessage({
|
3448
|
+
id: getTranslation("containers.list.autoCloneModal.title"),
|
3449
|
+
defaultMessage: "This entry can't be duplicated directly."
|
3450
|
+
}) }),
|
3451
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 2, children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: formatMessage({
|
3452
|
+
id: getTranslation("containers.list.autoCloneModal.description"),
|
3453
|
+
defaultMessage: "A new entry will be created with the same content, but you'll have to change the following fields to save it."
|
3454
|
+
}) }) }),
|
3455
|
+
/* @__PURE__ */ jsx(Flex, { marginTop: 6, gap: 2, direction: "column", alignItems: "stretch", children: prohibitedFields.map(([fieldPath, reason]) => /* @__PURE__ */ jsxs(
|
3456
|
+
Flex,
|
3457
|
+
{
|
3458
|
+
direction: "column",
|
3459
|
+
gap: 2,
|
3460
|
+
alignItems: "flex-start",
|
3461
|
+
borderColor: "neutral200",
|
3462
|
+
hasRadius: true,
|
3463
|
+
padding: 6,
|
3464
|
+
children: [
|
3465
|
+
/* @__PURE__ */ jsx(Flex, { direction: "row", tag: "ol", children: fieldPath.map((pathSegment, index2) => /* @__PURE__ */ jsxs(Typography, { fontWeight: "semiBold", tag: "li", children: [
|
3466
|
+
pathSegment,
|
3467
|
+
index2 !== fieldPath.length - 1 && /* @__PURE__ */ jsx(
|
3468
|
+
ChevronRight,
|
3469
|
+
{
|
3470
|
+
fill: "neutral500",
|
3471
|
+
height: "0.8rem",
|
3472
|
+
width: "0.8rem",
|
3473
|
+
style: { margin: "0 0.8rem" }
|
3474
|
+
}
|
3475
|
+
)
|
3476
|
+
] }, index2)) }),
|
3477
|
+
/* @__PURE__ */ jsx(Typography, { tag: "p", textColor: "neutral600", children: formatMessage({
|
3478
|
+
id: getTranslation(`containers.list.autoCloneModal.error.${reason}`),
|
3479
|
+
defaultMessage: getDefaultErrorMessage(reason)
|
3480
|
+
}) })
|
3481
|
+
]
|
3482
|
+
},
|
3483
|
+
fieldPath.join()
|
3484
|
+
)) })
|
3485
|
+
] });
|
3486
|
+
};
|
3487
|
+
const TableActions = ({ document }) => {
|
3488
|
+
const { formatMessage } = useIntl();
|
3489
|
+
const { model, collectionType } = useDoc();
|
3490
|
+
const plugins = useStrapiApp("TableActions", (state) => state.plugins);
|
3491
|
+
const props = {
|
3492
|
+
activeTab: null,
|
3493
|
+
model,
|
3494
|
+
documentId: document.documentId,
|
3495
|
+
collectionType,
|
3496
|
+
document
|
3497
|
+
};
|
3498
|
+
return /* @__PURE__ */ jsx(
|
3499
|
+
DescriptionComponentRenderer,
|
3500
|
+
{
|
3501
|
+
props,
|
3502
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3503
|
+
children: (actions2) => {
|
3504
|
+
const tableRowActions = actions2.filter((action) => {
|
3505
|
+
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
3506
|
+
return positions.includes("table-row");
|
3507
|
+
});
|
3508
|
+
return /* @__PURE__ */ jsx(
|
3509
|
+
DocumentActionsMenu,
|
3510
|
+
{
|
3511
|
+
actions: tableRowActions,
|
3512
|
+
label: formatMessage({
|
3513
|
+
id: "content-manager.containers.list.table.row-actions",
|
3514
|
+
defaultMessage: "Row action"
|
3515
|
+
}),
|
3516
|
+
variant: "ghost"
|
3517
|
+
}
|
3518
|
+
);
|
3519
|
+
}
|
3520
|
+
}
|
3521
|
+
);
|
3522
|
+
};
|
3523
|
+
const EditAction = ({ documentId }) => {
|
3524
|
+
const navigate = useNavigate();
|
3525
|
+
const { formatMessage } = useIntl();
|
3526
|
+
const { canRead } = useDocumentRBAC("EditAction", ({ canRead: canRead2 }) => ({ canRead: canRead2 }));
|
3527
|
+
const { toggleNotification } = useNotification();
|
3528
|
+
const [{ query }] = useQueryParams();
|
3529
|
+
return {
|
3530
|
+
disabled: !canRead,
|
3531
|
+
icon: /* @__PURE__ */ jsx(StyledPencil, {}),
|
3532
|
+
label: formatMessage({
|
3533
|
+
id: "content-manager.actions.edit.label",
|
3534
|
+
defaultMessage: "Edit"
|
3535
|
+
}),
|
3536
|
+
position: "table-row",
|
2548
3537
|
onClick: async () => {
|
2549
3538
|
if (!documentId) {
|
2550
3539
|
console.error(
|
@@ -2629,7 +3618,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
2629
3618
|
/* @__PURE__ */ jsx(
|
2630
3619
|
LinkButton,
|
2631
3620
|
{
|
2632
|
-
|
3621
|
+
tag: NavLink,
|
2633
3622
|
to: {
|
2634
3623
|
pathname: `clone/${documentId}`
|
2635
3624
|
},
|
@@ -2662,442 +3651,183 @@ class ContentManagerPlugin {
|
|
2662
3651
|
documentActions = [
|
2663
3652
|
...DEFAULT_ACTIONS,
|
2664
3653
|
...DEFAULT_TABLE_ROW_ACTIONS,
|
2665
|
-
...DEFAULT_HEADER_ACTIONS
|
2666
|
-
HistoryAction
|
3654
|
+
...DEFAULT_HEADER_ACTIONS
|
2667
3655
|
];
|
2668
3656
|
editViewSidePanels = [ActionsPanel];
|
2669
3657
|
headerActions = [];
|
2670
3658
|
constructor() {
|
2671
3659
|
}
|
2672
|
-
addEditViewSidePanel(panels) {
|
2673
|
-
if (Array.isArray(panels)) {
|
2674
|
-
this.editViewSidePanels = [...this.editViewSidePanels, ...panels];
|
2675
|
-
} else if (typeof panels === "function") {
|
2676
|
-
this.editViewSidePanels = panels(this.editViewSidePanels);
|
2677
|
-
} else {
|
2678
|
-
throw new Error(
|
2679
|
-
`Expected the \`panels\` passed to \`addEditViewSidePanel\` to be an array or a function, but received ${getPrintableType(
|
2680
|
-
panels
|
2681
|
-
)}`
|
2682
|
-
);
|
2683
|
-
}
|
2684
|
-
}
|
2685
|
-
addDocumentAction(actions2) {
|
2686
|
-
if (Array.isArray(actions2)) {
|
2687
|
-
this.documentActions = [...this.documentActions, ...actions2];
|
2688
|
-
} else if (typeof actions2 === "function") {
|
2689
|
-
this.documentActions = actions2(this.documentActions);
|
2690
|
-
} else {
|
2691
|
-
throw new Error(
|
2692
|
-
`Expected the \`actions\` passed to \`addDocumentAction\` to be an array or a function, but received ${getPrintableType(
|
2693
|
-
actions2
|
2694
|
-
)}`
|
2695
|
-
);
|
2696
|
-
}
|
2697
|
-
}
|
2698
|
-
addDocumentHeaderAction(actions2) {
|
2699
|
-
if (Array.isArray(actions2)) {
|
2700
|
-
this.headerActions = [...this.headerActions, ...actions2];
|
2701
|
-
} else if (typeof actions2 === "function") {
|
2702
|
-
this.headerActions = actions2(this.headerActions);
|
3660
|
+
addEditViewSidePanel(panels) {
|
3661
|
+
if (Array.isArray(panels)) {
|
3662
|
+
this.editViewSidePanels = [...this.editViewSidePanels, ...panels];
|
3663
|
+
} else if (typeof panels === "function") {
|
3664
|
+
this.editViewSidePanels = panels(this.editViewSidePanels);
|
2703
3665
|
} else {
|
2704
3666
|
throw new Error(
|
2705
|
-
`Expected the \`
|
2706
|
-
|
3667
|
+
`Expected the \`panels\` passed to \`addEditViewSidePanel\` to be an array or a function, but received ${getPrintableType(
|
3668
|
+
panels
|
2707
3669
|
)}`
|
2708
3670
|
);
|
2709
3671
|
}
|
2710
3672
|
}
|
2711
|
-
|
3673
|
+
addDocumentAction(actions2) {
|
2712
3674
|
if (Array.isArray(actions2)) {
|
2713
|
-
this.
|
3675
|
+
this.documentActions = [...this.documentActions, ...actions2];
|
2714
3676
|
} else if (typeof actions2 === "function") {
|
2715
|
-
this.
|
3677
|
+
this.documentActions = actions2(this.documentActions);
|
2716
3678
|
} else {
|
2717
3679
|
throw new Error(
|
2718
|
-
`Expected the \`actions\` passed to \`
|
3680
|
+
`Expected the \`actions\` passed to \`addDocumentAction\` to be an array or a function, but received ${getPrintableType(
|
2719
3681
|
actions2
|
2720
3682
|
)}`
|
2721
|
-
);
|
2722
|
-
}
|
2723
|
-
}
|
2724
|
-
|
2725
|
-
|
2726
|
-
|
2727
|
-
|
2728
|
-
|
2729
|
-
apis: {
|
2730
|
-
addBulkAction: this.addBulkAction.bind(this),
|
2731
|
-
addDocumentAction: this.addDocumentAction.bind(this),
|
2732
|
-
addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
|
2733
|
-
addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
|
2734
|
-
getBulkActions: () => this.bulkActions,
|
2735
|
-
getDocumentActions: () => this.documentActions,
|
2736
|
-
getEditViewSidePanels: () => this.editViewSidePanels,
|
2737
|
-
getHeaderActions: () => this.headerActions
|
2738
|
-
}
|
2739
|
-
};
|
2740
|
-
}
|
2741
|
-
}
|
2742
|
-
const getPrintableType = (value) => {
|
2743
|
-
const nativeType = typeof value;
|
2744
|
-
if (nativeType === "object") {
|
2745
|
-
if (value === null)
|
2746
|
-
return "null";
|
2747
|
-
if (Array.isArray(value))
|
2748
|
-
return "array";
|
2749
|
-
if (value instanceof Object && value.constructor.name !== "Object") {
|
2750
|
-
return value.constructor.name;
|
2751
|
-
}
|
2752
|
-
}
|
2753
|
-
return nativeType;
|
2754
|
-
};
|
2755
|
-
const initialState = {
|
2756
|
-
collectionTypeLinks: [],
|
2757
|
-
components: [],
|
2758
|
-
fieldSizes: {},
|
2759
|
-
models: [],
|
2760
|
-
singleTypeLinks: [],
|
2761
|
-
isLoading: true
|
2762
|
-
};
|
2763
|
-
const appSlice = createSlice({
|
2764
|
-
name: "app",
|
2765
|
-
initialState,
|
2766
|
-
reducers: {
|
2767
|
-
setInitialData(state, action) {
|
2768
|
-
const {
|
2769
|
-
authorizedCollectionTypeLinks,
|
2770
|
-
authorizedSingleTypeLinks,
|
2771
|
-
components,
|
2772
|
-
contentTypeSchemas,
|
2773
|
-
fieldSizes
|
2774
|
-
} = action.payload;
|
2775
|
-
state.collectionTypeLinks = authorizedCollectionTypeLinks.filter(
|
2776
|
-
({ isDisplayed }) => isDisplayed
|
2777
|
-
);
|
2778
|
-
state.singleTypeLinks = authorizedSingleTypeLinks.filter(({ isDisplayed }) => isDisplayed);
|
2779
|
-
state.components = components;
|
2780
|
-
state.models = contentTypeSchemas;
|
2781
|
-
state.fieldSizes = fieldSizes;
|
2782
|
-
state.isLoading = false;
|
2783
|
-
}
|
2784
|
-
}
|
2785
|
-
});
|
2786
|
-
const { actions, reducer: reducer$1 } = appSlice;
|
2787
|
-
const { setInitialData } = actions;
|
2788
|
-
const reducer = combineReducers({
|
2789
|
-
app: reducer$1
|
2790
|
-
});
|
2791
|
-
const HOOKS = {
|
2792
|
-
/**
|
2793
|
-
* Hook that allows to mutate the displayed headers of the list view table
|
2794
|
-
* @constant
|
2795
|
-
* @type {string}
|
2796
|
-
*/
|
2797
|
-
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2798
|
-
/**
|
2799
|
-
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2800
|
-
* @constant
|
2801
|
-
* @type {string}
|
2802
|
-
*/
|
2803
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2804
|
-
/**
|
2805
|
-
* Hook that allows to mutate the CM's edit view layout
|
2806
|
-
* @constant
|
2807
|
-
* @type {string}
|
2808
|
-
*/
|
2809
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2810
|
-
/**
|
2811
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
2812
|
-
* @constant
|
2813
|
-
* @type {string}
|
2814
|
-
*/
|
2815
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2816
|
-
};
|
2817
|
-
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2818
|
-
endpoints: (builder) => ({
|
2819
|
-
getContentTypeConfiguration: builder.query({
|
2820
|
-
query: (uid) => ({
|
2821
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2822
|
-
method: "GET"
|
2823
|
-
}),
|
2824
|
-
transformResponse: (response) => response.data,
|
2825
|
-
providesTags: (_result, _error, uid) => [
|
2826
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2827
|
-
{ type: "ContentTypeSettings", id: "LIST" }
|
2828
|
-
]
|
2829
|
-
}),
|
2830
|
-
getAllContentTypeSettings: builder.query({
|
2831
|
-
query: () => "/content-manager/content-types-settings",
|
2832
|
-
transformResponse: (response) => response.data,
|
2833
|
-
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2834
|
-
}),
|
2835
|
-
updateContentTypeConfiguration: builder.mutation({
|
2836
|
-
query: ({ uid, ...body }) => ({
|
2837
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2838
|
-
method: "PUT",
|
2839
|
-
data: body
|
2840
|
-
}),
|
2841
|
-
transformResponse: (response) => response.data,
|
2842
|
-
invalidatesTags: (_result, _error, { uid }) => [
|
2843
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2844
|
-
{ type: "ContentTypeSettings", id: "LIST" },
|
2845
|
-
// Is this necessary?
|
2846
|
-
{ type: "InitialData" }
|
2847
|
-
]
|
2848
|
-
})
|
2849
|
-
})
|
2850
|
-
});
|
2851
|
-
const {
|
2852
|
-
useGetContentTypeConfigurationQuery,
|
2853
|
-
useGetAllContentTypeSettingsQuery,
|
2854
|
-
useUpdateContentTypeConfigurationMutation
|
2855
|
-
} = contentTypesApi;
|
2856
|
-
const checkIfAttributeIsDisplayable = (attribute) => {
|
2857
|
-
const { type } = attribute;
|
2858
|
-
if (type === "relation") {
|
2859
|
-
return !attribute.relation.toLowerCase().includes("morph");
|
2860
|
-
}
|
2861
|
-
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2862
|
-
};
|
2863
|
-
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2864
|
-
if (!mainFieldName) {
|
2865
|
-
return void 0;
|
2866
|
-
}
|
2867
|
-
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2868
|
-
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2869
|
-
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2870
|
-
);
|
2871
|
-
return {
|
2872
|
-
name: mainFieldName,
|
2873
|
-
type: mainFieldType ?? "string"
|
2874
|
-
};
|
2875
|
-
};
|
2876
|
-
const DEFAULT_SETTINGS = {
|
2877
|
-
bulkable: false,
|
2878
|
-
filterable: false,
|
2879
|
-
searchable: false,
|
2880
|
-
pagination: false,
|
2881
|
-
defaultSortBy: "",
|
2882
|
-
defaultSortOrder: "asc",
|
2883
|
-
mainField: "id",
|
2884
|
-
pageSize: 10
|
2885
|
-
};
|
2886
|
-
const useDocumentLayout = (model) => {
|
2887
|
-
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2888
|
-
const [{ query }] = useQueryParams();
|
2889
|
-
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2890
|
-
const { toggleNotification } = useNotification();
|
2891
|
-
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
2892
|
-
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2893
|
-
const {
|
2894
|
-
data,
|
2895
|
-
isLoading: isLoadingConfigs,
|
2896
|
-
error,
|
2897
|
-
isFetching: isFetchingConfigs
|
2898
|
-
} = useGetContentTypeConfigurationQuery(model);
|
2899
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2900
|
-
React.useEffect(() => {
|
2901
|
-
if (error) {
|
2902
|
-
toggleNotification({
|
2903
|
-
type: "danger",
|
2904
|
-
message: formatAPIError(error)
|
2905
|
-
});
|
2906
|
-
}
|
2907
|
-
}, [error, formatAPIError, toggleNotification]);
|
2908
|
-
const editLayout = React.useMemo(
|
2909
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2910
|
-
layout: [],
|
2911
|
-
components: {},
|
2912
|
-
metadatas: {},
|
2913
|
-
options: {},
|
2914
|
-
settings: DEFAULT_SETTINGS
|
2915
|
-
},
|
2916
|
-
[data, isLoading, schemas, schema, components]
|
2917
|
-
);
|
2918
|
-
const listLayout = React.useMemo(() => {
|
2919
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2920
|
-
layout: [],
|
2921
|
-
metadatas: {},
|
2922
|
-
options: {},
|
2923
|
-
settings: DEFAULT_SETTINGS
|
2924
|
-
};
|
2925
|
-
}, [data, isLoading, schemas, schema, components]);
|
2926
|
-
const { layout: edit } = React.useMemo(
|
2927
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2928
|
-
layout: editLayout,
|
2929
|
-
query
|
2930
|
-
}),
|
2931
|
-
[editLayout, query, runHookWaterfall]
|
2932
|
-
);
|
2933
|
-
return {
|
2934
|
-
error,
|
2935
|
-
isLoading,
|
2936
|
-
edit,
|
2937
|
-
list: listLayout
|
2938
|
-
};
|
2939
|
-
};
|
2940
|
-
const useDocLayout = () => {
|
2941
|
-
const { model } = useDoc();
|
2942
|
-
return useDocumentLayout(model);
|
2943
|
-
};
|
2944
|
-
const formatEditLayout = (data, {
|
2945
|
-
schemas,
|
2946
|
-
schema,
|
2947
|
-
components
|
2948
|
-
}) => {
|
2949
|
-
let currentPanelIndex = 0;
|
2950
|
-
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2951
|
-
data.contentType.layouts.edit,
|
2952
|
-
schema?.attributes,
|
2953
|
-
data.contentType.metadatas,
|
2954
|
-
{ configurations: data.components, schemas: components },
|
2955
|
-
schemas
|
2956
|
-
).reduce((panels, row) => {
|
2957
|
-
if (row.some((field) => field.type === "dynamiczone")) {
|
2958
|
-
panels.push([row]);
|
2959
|
-
currentPanelIndex += 2;
|
3683
|
+
);
|
3684
|
+
}
|
3685
|
+
}
|
3686
|
+
addDocumentHeaderAction(actions2) {
|
3687
|
+
if (Array.isArray(actions2)) {
|
3688
|
+
this.headerActions = [...this.headerActions, ...actions2];
|
3689
|
+
} else if (typeof actions2 === "function") {
|
3690
|
+
this.headerActions = actions2(this.headerActions);
|
2960
3691
|
} else {
|
2961
|
-
|
2962
|
-
|
2963
|
-
|
2964
|
-
|
3692
|
+
throw new Error(
|
3693
|
+
`Expected the \`actions\` passed to \`addDocumentHeaderAction\` to be an array or a function, but received ${getPrintableType(
|
3694
|
+
actions2
|
3695
|
+
)}`
|
3696
|
+
);
|
2965
3697
|
}
|
2966
|
-
|
2967
|
-
|
2968
|
-
|
2969
|
-
|
2970
|
-
|
2971
|
-
|
2972
|
-
|
2973
|
-
|
2974
|
-
|
2975
|
-
|
2976
|
-
|
2977
|
-
|
2978
|
-
icon: components[uid].info.icon,
|
2979
|
-
displayName: components[uid].info.displayName
|
2980
|
-
}
|
2981
|
-
};
|
2982
|
-
return acc;
|
2983
|
-
},
|
2984
|
-
{}
|
2985
|
-
);
|
2986
|
-
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2987
|
-
(acc, [attribute, metadata]) => {
|
2988
|
-
return {
|
2989
|
-
...acc,
|
2990
|
-
[attribute]: metadata.edit
|
2991
|
-
};
|
2992
|
-
},
|
2993
|
-
{}
|
2994
|
-
);
|
2995
|
-
return {
|
2996
|
-
layout: panelledEditAttributes,
|
2997
|
-
components: componentEditAttributes,
|
2998
|
-
metadatas: editMetadatas,
|
2999
|
-
settings: {
|
3000
|
-
...data.contentType.settings,
|
3001
|
-
displayName: schema?.info.displayName
|
3002
|
-
},
|
3003
|
-
options: {
|
3004
|
-
...schema?.options,
|
3005
|
-
...schema?.pluginOptions,
|
3006
|
-
...data.contentType.options
|
3698
|
+
}
|
3699
|
+
addBulkAction(actions2) {
|
3700
|
+
if (Array.isArray(actions2)) {
|
3701
|
+
this.bulkActions = [...this.bulkActions, ...actions2];
|
3702
|
+
} else if (typeof actions2 === "function") {
|
3703
|
+
this.bulkActions = actions2(this.bulkActions);
|
3704
|
+
} else {
|
3705
|
+
throw new Error(
|
3706
|
+
`Expected the \`actions\` passed to \`addBulkAction\` to be an array or a function, but received ${getPrintableType(
|
3707
|
+
actions2
|
3708
|
+
)}`
|
3709
|
+
);
|
3007
3710
|
}
|
3008
|
-
}
|
3009
|
-
|
3010
|
-
|
3011
|
-
|
3012
|
-
|
3013
|
-
|
3014
|
-
|
3015
|
-
|
3711
|
+
}
|
3712
|
+
get config() {
|
3713
|
+
return {
|
3714
|
+
id: PLUGIN_ID,
|
3715
|
+
name: "Content Manager",
|
3716
|
+
injectionZones: INJECTION_ZONES,
|
3717
|
+
apis: {
|
3718
|
+
addBulkAction: this.addBulkAction.bind(this),
|
3719
|
+
addDocumentAction: this.addDocumentAction.bind(this),
|
3720
|
+
addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
|
3721
|
+
addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
|
3722
|
+
getBulkActions: () => this.bulkActions,
|
3723
|
+
getDocumentActions: () => this.documentActions,
|
3724
|
+
getEditViewSidePanels: () => this.editViewSidePanels,
|
3725
|
+
getHeaderActions: () => this.headerActions
|
3016
3726
|
}
|
3017
|
-
|
3018
|
-
|
3019
|
-
|
3020
|
-
|
3021
|
-
|
3022
|
-
|
3023
|
-
|
3024
|
-
|
3025
|
-
|
3026
|
-
|
3027
|
-
|
3028
|
-
|
3029
|
-
|
3030
|
-
|
3031
|
-
|
3032
|
-
size: field.size,
|
3033
|
-
unique: "unique" in attribute ? attribute.unique : false,
|
3034
|
-
visible: metadata.visible ?? true,
|
3035
|
-
type: attribute.type
|
3036
|
-
};
|
3037
|
-
}).filter((field) => field !== null)
|
3038
|
-
);
|
3727
|
+
};
|
3728
|
+
}
|
3729
|
+
}
|
3730
|
+
const getPrintableType = (value) => {
|
3731
|
+
const nativeType = typeof value;
|
3732
|
+
if (nativeType === "object") {
|
3733
|
+
if (value === null)
|
3734
|
+
return "null";
|
3735
|
+
if (Array.isArray(value))
|
3736
|
+
return "array";
|
3737
|
+
if (value instanceof Object && value.constructor.name !== "Object") {
|
3738
|
+
return value.constructor.name;
|
3739
|
+
}
|
3740
|
+
}
|
3741
|
+
return nativeType;
|
3039
3742
|
};
|
3040
|
-
const
|
3041
|
-
|
3042
|
-
|
3043
|
-
|
3044
|
-
}
|
3045
|
-
|
3046
|
-
|
3047
|
-
|
3048
|
-
...acc,
|
3049
|
-
[attribute]: metadata.list
|
3050
|
-
};
|
3051
|
-
},
|
3052
|
-
{}
|
3053
|
-
);
|
3054
|
-
const listAttributes = convertListLayoutToFieldLayouts(
|
3055
|
-
data.contentType.layouts.list,
|
3056
|
-
schema?.attributes,
|
3057
|
-
listMetadatas,
|
3058
|
-
{ configurations: data.components, schemas: components },
|
3059
|
-
schemas
|
3060
|
-
);
|
3743
|
+
const HistoryAction = ({ model, document }) => {
|
3744
|
+
const { formatMessage } = useIntl();
|
3745
|
+
const [{ query }] = useQueryParams();
|
3746
|
+
const navigate = useNavigate();
|
3747
|
+
const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
|
3748
|
+
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3749
|
+
return null;
|
3750
|
+
}
|
3061
3751
|
return {
|
3062
|
-
|
3063
|
-
|
3064
|
-
|
3065
|
-
|
3066
|
-
|
3067
|
-
|
3068
|
-
|
3069
|
-
|
3752
|
+
icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
|
3753
|
+
label: formatMessage({
|
3754
|
+
id: "content-manager.history.document-action",
|
3755
|
+
defaultMessage: "Content History"
|
3756
|
+
}),
|
3757
|
+
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
3758
|
+
disabled: (
|
3759
|
+
/**
|
3760
|
+
* The user is creating a new document.
|
3761
|
+
* It hasn't been saved yet, so there's no history to go to
|
3762
|
+
*/
|
3763
|
+
!document || /**
|
3764
|
+
* The document has been created but the current dimension has never been saved.
|
3765
|
+
* For example, the user is creating a new locale in an existing document,
|
3766
|
+
* so there's no history for the document in that locale
|
3767
|
+
*/
|
3768
|
+
!document.id || /**
|
3769
|
+
* History is only available for content types created by the user.
|
3770
|
+
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
3771
|
+
* which start with `admin::` or `plugin::`
|
3772
|
+
*/
|
3773
|
+
!model.startsWith("api::")
|
3774
|
+
),
|
3775
|
+
position: "header"
|
3070
3776
|
};
|
3071
3777
|
};
|
3072
|
-
|
3073
|
-
|
3074
|
-
|
3075
|
-
|
3076
|
-
|
3077
|
-
|
3078
|
-
|
3079
|
-
|
3080
|
-
|
3081
|
-
|
3082
|
-
|
3083
|
-
|
3084
|
-
|
3085
|
-
|
3086
|
-
|
3087
|
-
|
3088
|
-
|
3089
|
-
|
3090
|
-
};
|
3091
|
-
}).filter((field) => field !== null);
|
3778
|
+
HistoryAction.type = "history";
|
3779
|
+
const historyAdmin = {
|
3780
|
+
bootstrap(app) {
|
3781
|
+
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
3782
|
+
addDocumentAction((actions2) => {
|
3783
|
+
const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
|
3784
|
+
actions2.splice(indexOfDeleteAction, 0, HistoryAction);
|
3785
|
+
return actions2;
|
3786
|
+
});
|
3787
|
+
}
|
3788
|
+
};
|
3789
|
+
const initialState = {
|
3790
|
+
collectionTypeLinks: [],
|
3791
|
+
components: [],
|
3792
|
+
fieldSizes: {},
|
3793
|
+
models: [],
|
3794
|
+
singleTypeLinks: [],
|
3795
|
+
isLoading: true
|
3092
3796
|
};
|
3797
|
+
const appSlice = createSlice({
|
3798
|
+
name: "app",
|
3799
|
+
initialState,
|
3800
|
+
reducers: {
|
3801
|
+
setInitialData(state, action) {
|
3802
|
+
const {
|
3803
|
+
authorizedCollectionTypeLinks,
|
3804
|
+
authorizedSingleTypeLinks,
|
3805
|
+
components,
|
3806
|
+
contentTypeSchemas,
|
3807
|
+
fieldSizes
|
3808
|
+
} = action.payload;
|
3809
|
+
state.collectionTypeLinks = authorizedCollectionTypeLinks.filter(
|
3810
|
+
({ isDisplayed }) => isDisplayed
|
3811
|
+
);
|
3812
|
+
state.singleTypeLinks = authorizedSingleTypeLinks.filter(({ isDisplayed }) => isDisplayed);
|
3813
|
+
state.components = components;
|
3814
|
+
state.models = contentTypeSchemas;
|
3815
|
+
state.fieldSizes = fieldSizes;
|
3816
|
+
state.isLoading = false;
|
3817
|
+
}
|
3818
|
+
}
|
3819
|
+
});
|
3820
|
+
const { actions, reducer: reducer$1 } = appSlice;
|
3821
|
+
const { setInitialData } = actions;
|
3822
|
+
const reducer = combineReducers({
|
3823
|
+
app: reducer$1
|
3824
|
+
});
|
3093
3825
|
const index = {
|
3094
3826
|
register(app) {
|
3095
3827
|
const cm = new ContentManagerPlugin();
|
3096
3828
|
app.addReducers({
|
3097
|
-
[contentManagerApi.reducerPath]: contentManagerApi.reducer,
|
3098
3829
|
[PLUGIN_ID]: reducer
|
3099
3830
|
});
|
3100
|
-
app.addMiddlewares([() => contentManagerApi.middleware]);
|
3101
3831
|
app.addMenuLink({
|
3102
3832
|
to: PLUGIN_ID,
|
3103
3833
|
icon: Feather,
|
@@ -3106,14 +3836,29 @@ const index = {
|
|
3106
3836
|
defaultMessage: "Content Manager"
|
3107
3837
|
},
|
3108
3838
|
permissions: [],
|
3109
|
-
|
3839
|
+
position: 1
|
3840
|
+
});
|
3841
|
+
app.router.addRoute({
|
3842
|
+
path: "content-manager/*",
|
3843
|
+
lazy: async () => {
|
3844
|
+
const { Layout } = await import("./layout-B3ez7kvr.mjs");
|
3845
|
+
return {
|
3846
|
+
Component: Layout
|
3847
|
+
};
|
3848
|
+
},
|
3849
|
+
children: routes
|
3110
3850
|
});
|
3111
3851
|
app.registerPlugin(cm.config);
|
3112
3852
|
},
|
3853
|
+
bootstrap(app) {
|
3854
|
+
if (typeof historyAdmin.bootstrap === "function") {
|
3855
|
+
historyAdmin.bootstrap(app);
|
3856
|
+
}
|
3857
|
+
},
|
3113
3858
|
async registerTrads({ locales }) {
|
3114
3859
|
const importedTrads = await Promise.all(
|
3115
3860
|
locales.map((locale) => {
|
3116
|
-
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-
|
3861
|
+
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-BrCTWlZv.mjs"), "./translations/es.json": () => import("./es-CeXiYflN.mjs"), "./translations/eu.json": () => import("./eu-CdALomew.mjs"), "./translations/fr.json": () => import("./fr-CD9VFbPM.mjs"), "./translations/gu.json": () => import("./gu-CNpaMDpH.mjs"), "./translations/hi.json": () => import("./hi-Dwvd04m3.mjs"), "./translations/hu.json": () => import("./hu-CeYvaaO0.mjs"), "./translations/id.json": () => import("./id-BtwA9WJT.mjs"), "./translations/it.json": () => import("./it-BrVPqaf1.mjs"), "./translations/ja.json": () => import("./ja-CtsUxOvk.mjs"), "./translations/ko.json": () => import("./ko-HVQRlfUI.mjs"), "./translations/ml.json": () => import("./ml-BihZwQit.mjs"), "./translations/ms.json": () => import("./ms-m_WjyWx7.mjs"), "./translations/nl.json": () => import("./nl-D4R9gHx5.mjs"), "./translations/pl.json": () => import("./pl-sbx9mSt_.mjs"), "./translations/pt-BR.json": () => import("./pt-BR-C71iDxnh.mjs"), "./translations/pt.json": () => import("./pt-BsaFvS8-.mjs"), "./translations/ru.json": () => import("./ru-BE6A4Exp.mjs"), "./translations/sa.json": () => import("./sa-Dag0k-Z8.mjs"), "./translations/sk.json": () => import("./sk-BFg-R8qJ.mjs"), "./translations/sv.json": () => import("./sv-CUnfWGsh.mjs"), "./translations/th.json": () => import("./th-BqbI8lIT.mjs"), "./translations/tr.json": () => import("./tr-CgeK3wJM.mjs"), "./translations/uk.json": () => import("./uk-CR-zDhAY.mjs"), "./translations/vi.json": () => import("./vi-DUXIk_fw.mjs"), "./translations/zh-Hans.json": () => import("./zh-Hans-BPQcRIyH.mjs"), "./translations/zh.json": () => import("./zh-BWZspA60.mjs") }), `./translations/${locale}.json`).then(({ default: data }) => {
|
3117
3862
|
return {
|
3118
3863
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3119
3864
|
locale
|
@@ -3131,7 +3876,7 @@ const index = {
|
|
3131
3876
|
};
|
3132
3877
|
export {
|
3133
3878
|
ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD as A,
|
3134
|
-
|
3879
|
+
BulkActionsRenderer as B,
|
3135
3880
|
COLLECTION_TYPES as C,
|
3136
3881
|
DocumentStatus as D,
|
3137
3882
|
DEFAULT_SETTINGS as E,
|
@@ -3145,31 +3890,31 @@ export {
|
|
3145
3890
|
RelativeTime as R,
|
3146
3891
|
SINGLE_TYPES as S,
|
3147
3892
|
TableActions as T,
|
3148
|
-
|
3149
|
-
|
3150
|
-
|
3151
|
-
|
3152
|
-
|
3153
|
-
|
3893
|
+
useGetInitialDataQuery as a,
|
3894
|
+
useGetAllContentTypeSettingsQuery as b,
|
3895
|
+
useDoc as c,
|
3896
|
+
buildValidParams as d,
|
3897
|
+
contentManagerApi as e,
|
3898
|
+
useDocumentRBAC as f,
|
3154
3899
|
getTranslation as g,
|
3155
|
-
|
3156
|
-
|
3157
|
-
|
3158
|
-
|
3159
|
-
|
3160
|
-
|
3161
|
-
|
3900
|
+
useDocumentLayout as h,
|
3901
|
+
createYupSchema as i,
|
3902
|
+
Header as j,
|
3903
|
+
PERMISSIONS as k,
|
3904
|
+
DocumentRBAC as l,
|
3905
|
+
DOCUMENT_META_FIELDS as m,
|
3906
|
+
useDocLayout as n,
|
3162
3907
|
useGetContentTypeConfigurationQuery as o,
|
3163
3908
|
CREATOR_FIELDS as p,
|
3164
3909
|
getMainField as q,
|
3165
|
-
|
3910
|
+
getDisplayName as r,
|
3166
3911
|
setInitialData as s,
|
3167
|
-
|
3168
|
-
|
3169
|
-
|
3170
|
-
|
3171
|
-
|
3172
|
-
|
3173
|
-
|
3174
|
-
};
|
3175
|
-
//# sourceMappingURL=index-
|
3912
|
+
checkIfAttributeIsDisplayable as t,
|
3913
|
+
useContentTypeSchema as u,
|
3914
|
+
useGetAllDocumentsQuery as v,
|
3915
|
+
convertListLayoutToFieldLayouts as w,
|
3916
|
+
capitalise as x,
|
3917
|
+
useUpdateContentTypeConfigurationMutation as y,
|
3918
|
+
extractContentTypeComponents as z
|
3919
|
+
};
|
3920
|
+
//# sourceMappingURL=index-DrNe6ctw.mjs.map
|