@strapi/content-manager 0.0.0-experimental.e60ec1829240dae21c1e1d29076681c322288813 → 0.0.0-experimental.e9122b401c96877b6707775c4f893660eab93ae3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +18 -3
- package/dist/_chunks/{CardDragPreview-DSVYodBX.js → CardDragPreview-C0QyJgRA.js} +10 -14
- package/dist/_chunks/CardDragPreview-C0QyJgRA.js.map +1 -0
- package/dist/_chunks/{CardDragPreview-ikSG4M46.mjs → CardDragPreview-DOxamsuj.mjs} +7 -9
- package/dist/_chunks/CardDragPreview-DOxamsuj.mjs.map +1 -0
- package/dist/_chunks/{ComponentConfigurationPage-BPvzFjM7.mjs → ComponentConfigurationPage-CpBFh6_r.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-BPvzFjM7.mjs.map → ComponentConfigurationPage-CpBFh6_r.mjs.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-DjWJdz6Y.js → ComponentConfigurationPage-_zF8p6CY.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-DjWJdz6Y.js.map → ComponentConfigurationPage-_zF8p6CY.js.map} +1 -1
- package/dist/_chunks/{ComponentIcon-BBQsYCVn.js → ComponentIcon-BXdiCGQp.js} +8 -2
- package/dist/_chunks/ComponentIcon-BXdiCGQp.js.map +1 -0
- package/dist/_chunks/{ComponentIcon-BOFnK76n.mjs → ComponentIcon-u4bIXTFY.mjs} +9 -3
- package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +1 -0
- package/dist/_chunks/{EditConfigurationPage-DacbqQ_f.mjs → EditConfigurationPage-CE_yavTi.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-DacbqQ_f.mjs.map → EditConfigurationPage-CE_yavTi.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-Dmv83RlS.js → EditConfigurationPage-_aG2DJSU.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-Dmv83RlS.js.map → EditConfigurationPage-_aG2DJSU.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-DDS6H9HO.mjs → EditViewPage-DeTn7rAF.mjs} +59 -48
- package/dist/_chunks/EditViewPage-DeTn7rAF.mjs.map +1 -0
- package/dist/_chunks/{EditViewPage-DvNpQkam.js → EditViewPage-G9uNzwYL.js} +58 -49
- package/dist/_chunks/EditViewPage-G9uNzwYL.js.map +1 -0
- package/dist/_chunks/{Field-6gvGdPBV.mjs → Field-CnCKhI1R.mjs} +995 -795
- package/dist/_chunks/Field-CnCKhI1R.mjs.map +1 -0
- package/dist/_chunks/{Field-DmVKIAOo.js → Field-DDHUWEfV.js} +1041 -842
- package/dist/_chunks/Field-DDHUWEfV.js.map +1 -0
- package/dist/_chunks/{Form-CPZC9vWa.js → Form-DYETaKUX.js} +65 -45
- package/dist/_chunks/Form-DYETaKUX.js.map +1 -0
- package/dist/_chunks/{Form-DW6K1IH-.mjs → Form-IvVVwqRL.mjs} +65 -44
- package/dist/_chunks/Form-IvVVwqRL.mjs.map +1 -0
- package/dist/_chunks/{History-Dmr9fmUA.mjs → History-BMunT-do.mjs} +148 -54
- package/dist/_chunks/History-BMunT-do.mjs.map +1 -0
- package/dist/_chunks/{History-DeAPlvtv.js → History-CnZDctSO.js} +149 -56
- package/dist/_chunks/History-CnZDctSO.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DPCwW5Vr.js → ListConfigurationPage-BynalOp8.js} +67 -58
- package/dist/_chunks/ListConfigurationPage-BynalOp8.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DhwvYcNv.mjs → ListConfigurationPage-CDqkCxgV.mjs} +63 -53
- package/dist/_chunks/ListConfigurationPage-CDqkCxgV.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-5ySZ-VUs.js → ListViewPage-I88Ouzoq.js} +126 -137
- package/dist/_chunks/ListViewPage-I88Ouzoq.js.map +1 -0
- package/dist/_chunks/{ListViewPage-BtAwuYLE.mjs → ListViewPage-_5gS-DOF.mjs} +123 -134
- package/dist/_chunks/ListViewPage-_5gS-DOF.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DOC_yWOf.js → NoContentTypePage-BaWQ7HsA.js} +3 -3
- package/dist/_chunks/NoContentTypePage-BaWQ7HsA.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DSPxnxxp.mjs → NoContentTypePage-Dht-55hr.mjs} +3 -3
- package/dist/_chunks/NoContentTypePage-Dht-55hr.mjs.map +1 -0
- package/dist/_chunks/{NoPermissionsPage-UWDC-1Tw.mjs → NoPermissionsPage-Bs8D5W_v.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-UWDC-1Tw.mjs.map → NoPermissionsPage-Bs8D5W_v.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-Dwu8rRJu.js → NoPermissionsPage-DCVUh5at.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-Dwu8rRJu.js.map → NoPermissionsPage-DCVUh5at.js.map} +1 -1
- package/dist/_chunks/{Relations-CgWtgnPe.js → Relations-BPgFQeGj.js} +71 -62
- package/dist/_chunks/Relations-BPgFQeGj.js.map +1 -0
- package/dist/_chunks/{Relations-J8cscLlR.mjs → Relations-Chdt5qWc.mjs} +67 -57
- package/dist/_chunks/Relations-Chdt5qWc.mjs.map +1 -0
- package/dist/_chunks/{en-C-V1_90f.js → en-BVzUkPxZ.js} +16 -8
- package/dist/_chunks/{en-C-V1_90f.js.map → en-BVzUkPxZ.js.map} +1 -1
- package/dist/_chunks/{en-MBPul9Su.mjs → en-CPTj6CjC.mjs} +16 -8
- package/dist/_chunks/{en-MBPul9Su.mjs.map → en-CPTj6CjC.mjs.map} +1 -1
- package/dist/_chunks/{index-C6AH2hEl.js → index-BhbLFX4l.js} +1752 -903
- package/dist/_chunks/index-BhbLFX4l.js.map +1 -0
- package/dist/_chunks/{index-CwRRo1V9.mjs → index-D4UGPFZC.mjs} +1778 -928
- package/dist/_chunks/index-D4UGPFZC.mjs.map +1 -0
- package/dist/_chunks/{layout-B_SXLhqf.js → layout-CYA7s0qO.js} +45 -29
- package/dist/_chunks/layout-CYA7s0qO.js.map +1 -0
- package/dist/_chunks/{layout-jIDzX0Fp.mjs → layout-D4HI4_PS.mjs} +45 -27
- package/dist/_chunks/layout-D4HI4_PS.mjs.map +1 -0
- package/dist/_chunks/{relations-CuvIgCqI.mjs → relations-1pXaYpBK.mjs} +2 -2
- package/dist/_chunks/{relations-CuvIgCqI.mjs.map → relations-1pXaYpBK.mjs.map} +1 -1
- package/dist/_chunks/{relations-iBMa_OFG.js → relations-DDZ9OxNo.js} +2 -2
- package/dist/_chunks/{relations-iBMa_OFG.js.map → relations-DDZ9OxNo.js.map} +1 -1
- package/dist/_chunks/useDebounce-CtcjDB3L.js +28 -0
- package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs +29 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -0
- package/dist/_chunks/useDragAndDrop-DdHgKsqq.mjs.map +1 -1
- package/dist/_chunks/useDragAndDrop-J0TUUbR6.js.map +1 -1
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +8 -7
- package/dist/admin/src/components/ComponentIcon.d.ts +6 -3
- package/dist/admin/src/content-manager.d.ts +3 -3
- package/dist/admin/src/exports.d.ts +1 -0
- package/dist/admin/src/history/components/VersionInputRenderer.d.ts +1 -1
- package/dist/admin/src/history/index.d.ts +3 -0
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +5 -8
- package/dist/admin/src/hooks/useDocumentActions.d.ts +24 -3
- package/dist/admin/src/hooks/useDocumentLayout.d.ts +2 -2
- package/dist/admin/src/hooks/useDragAndDrop.d.ts +4 -4
- package/dist/admin/src/hooks/useKeyboardDragAndDrop.d.ts +1 -1
- package/dist/admin/src/index.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +11 -4
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.d.ts +3 -3
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +4 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Component/Input.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.d.ts +3 -5
- package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/Field.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +30 -18
- package/dist/admin/src/pages/EditView/components/FormInputs/UID.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +3 -49
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/Field.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +16 -53
- package/dist/admin/src/pages/EditView/components/Header.d.ts +10 -11
- package/dist/admin/src/pages/EditView/components/InputRenderer.d.ts +2 -10
- package/dist/admin/src/pages/ListView/components/BulkActions/Actions.d.ts +3 -30
- package/dist/admin/src/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.d.ts +2 -2
- package/dist/admin/src/pages/ListView/components/BulkActions/PublishAction.d.ts +9 -26
- package/dist/admin/src/services/api.d.ts +2 -3
- package/dist/admin/src/services/components.d.ts +2 -2
- package/dist/admin/src/services/contentTypes.d.ts +5 -5
- package/dist/admin/src/services/documents.d.ts +31 -17
- package/dist/admin/src/services/init.d.ts +2 -2
- package/dist/admin/src/services/relations.d.ts +3 -3
- package/dist/admin/src/services/uid.d.ts +3 -3
- package/dist/admin/src/utils/api.d.ts +4 -18
- package/dist/admin/src/utils/validation.d.ts +5 -7
- package/dist/server/index.js +436 -281
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +444 -289
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/controllers/relations.d.ts.map +1 -1
- package/dist/server/src/controllers/single-types.d.ts.map +1 -1
- package/dist/server/src/controllers/uid.d.ts.map +1 -1
- package/dist/server/src/controllers/utils/metadata.d.ts +8 -0
- package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -0
- package/dist/server/src/controllers/validation/dimensions.d.ts +11 -0
- package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -0
- package/dist/server/src/controllers/validation/index.d.ts +1 -1
- package/dist/server/src/history/services/history.d.ts.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
- package/dist/server/src/history/services/utils.d.ts +2 -1
- package/dist/server/src/history/services/utils.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +18 -39
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts +13 -12
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts +8 -29
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +18 -39
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/permission-checker.d.ts.map +1 -1
- package/dist/server/src/services/utils/populate.d.ts +8 -1
- package/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/dist/shared/contracts/collection-types.d.ts +17 -7
- package/dist/shared/contracts/collection-types.d.ts.map +1 -1
- package/dist/shared/contracts/relations.d.ts +2 -2
- package/dist/shared/contracts/relations.d.ts.map +1 -1
- package/package.json +14 -15
- package/dist/_chunks/CardDragPreview-DSVYodBX.js.map +0 -1
- package/dist/_chunks/CardDragPreview-ikSG4M46.mjs.map +0 -1
- package/dist/_chunks/ComponentIcon-BBQsYCVn.js.map +0 -1
- package/dist/_chunks/ComponentIcon-BOFnK76n.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-DDS6H9HO.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-DvNpQkam.js.map +0 -1
- package/dist/_chunks/Field-6gvGdPBV.mjs.map +0 -1
- package/dist/_chunks/Field-DmVKIAOo.js.map +0 -1
- package/dist/_chunks/Form-CPZC9vWa.js.map +0 -1
- package/dist/_chunks/Form-DW6K1IH-.mjs.map +0 -1
- package/dist/_chunks/History-DeAPlvtv.js.map +0 -1
- package/dist/_chunks/History-Dmr9fmUA.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DPCwW5Vr.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DhwvYcNv.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-5ySZ-VUs.js.map +0 -1
- package/dist/_chunks/ListViewPage-BtAwuYLE.mjs.map +0 -1
- package/dist/_chunks/NoContentTypePage-DOC_yWOf.js.map +0 -1
- package/dist/_chunks/NoContentTypePage-DSPxnxxp.mjs.map +0 -1
- package/dist/_chunks/Relations-CgWtgnPe.js.map +0 -1
- package/dist/_chunks/Relations-J8cscLlR.mjs.map +0 -1
- package/dist/_chunks/index-C6AH2hEl.js.map +0 -1
- package/dist/_chunks/index-CwRRo1V9.mjs.map +0 -1
- package/dist/_chunks/layout-B_SXLhqf.js.map +0 -1
- package/dist/_chunks/layout-jIDzX0Fp.mjs.map +0 -1
- package/dist/_chunks/urls-CbOsUOoW.mjs +0 -7
- package/dist/_chunks/urls-CbOsUOoW.mjs.map +0 -1
- package/dist/_chunks/urls-DzZya_gm.js +0 -6
- package/dist/_chunks/urls-DzZya_gm.js.map +0 -1
- package/dist/server/src/controllers/utils/dimensions.d.ts +0 -5
- package/dist/server/src/controllers/utils/dimensions.d.ts.map +0 -1
@@ -1,19 +1,17 @@
|
|
1
|
-
import {
|
1
|
+
import { More, Cross, WarningCircle, ListPlus, Pencil, Trash, Check, CrossCircle, 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, IconButton, Loader, Tooltip, LinkButton } from "@strapi/design-system";
|
7
|
+
import { useIntl } from "react-intl";
|
8
|
+
import { useParams, useNavigate, Navigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
|
11
9
|
import * as yup from "yup";
|
12
10
|
import { ValidationError } from "yup";
|
13
|
-
import { createApi } from "@reduxjs/toolkit/query/react";
|
14
|
-
import { isAxiosError } from "axios";
|
15
11
|
import pipe from "lodash/fp/pipe";
|
16
12
|
import { intervalToDuration, isPast } from "date-fns";
|
13
|
+
import { styled } from "styled-components";
|
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,89 +150,20 @@ 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",
|
267
158
|
"Document",
|
268
159
|
"InitialData",
|
269
160
|
"HistoryVersion",
|
270
|
-
"Relations"
|
271
|
-
|
272
|
-
|
161
|
+
"Relations",
|
162
|
+
"UidAvailability"
|
163
|
+
]
|
273
164
|
});
|
274
165
|
const documentApi = contentManagerApi.injectEndpoints({
|
166
|
+
overrideExisting: true,
|
275
167
|
endpoints: (builder) => ({
|
276
168
|
autoCloneDocument: builder.mutation({
|
277
169
|
query: ({ model, sourceId, query }) => ({
|
@@ -281,7 +173,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
281
173
|
params: query
|
282
174
|
}
|
283
175
|
}),
|
284
|
-
invalidatesTags: (_result,
|
176
|
+
invalidatesTags: (_result, error, { model }) => {
|
177
|
+
if (error) {
|
178
|
+
return [];
|
179
|
+
}
|
180
|
+
return [{ type: "Document", id: `${model}_LIST` }];
|
181
|
+
}
|
285
182
|
}),
|
286
183
|
cloneDocument: builder.mutation({
|
287
184
|
query: ({ model, sourceId, data, params }) => ({
|
@@ -292,7 +189,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
292
189
|
params
|
293
190
|
}
|
294
191
|
}),
|
295
|
-
invalidatesTags: (_result, _error, { model }) => [
|
192
|
+
invalidatesTags: (_result, _error, { model }) => [
|
193
|
+
{ type: "Document", id: `${model}_LIST` },
|
194
|
+
{ type: "UidAvailability", id: model }
|
195
|
+
]
|
296
196
|
}),
|
297
197
|
/**
|
298
198
|
* Creates a new collection-type document. This should ONLY be used for collection-types.
|
@@ -309,7 +209,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
309
209
|
}),
|
310
210
|
invalidatesTags: (result, _error, { model }) => [
|
311
211
|
{ type: "Document", id: `${model}_LIST` },
|
312
|
-
"Relations"
|
212
|
+
"Relations",
|
213
|
+
{ type: "UidAvailability", id: model }
|
313
214
|
]
|
314
215
|
}),
|
315
216
|
deleteDocument: builder.mutation({
|
@@ -325,12 +226,15 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
325
226
|
]
|
326
227
|
}),
|
327
228
|
deleteManyDocuments: builder.mutation({
|
328
|
-
query: ({ model, ...body }) => ({
|
229
|
+
query: ({ model, params, ...body }) => ({
|
329
230
|
url: `/content-manager/collection-types/${model}/actions/bulkDelete`,
|
330
231
|
method: "POST",
|
331
|
-
data: body
|
232
|
+
data: body,
|
233
|
+
config: {
|
234
|
+
params
|
235
|
+
}
|
332
236
|
}),
|
333
|
-
invalidatesTags: (_res, _error, { model
|
237
|
+
invalidatesTags: (_res, _error, { model }) => [{ type: "Document", id: `${model}_LIST` }]
|
334
238
|
}),
|
335
239
|
discardDocument: builder.mutation({
|
336
240
|
query: ({ collectionType, model, documentId, params }) => ({
|
@@ -347,7 +251,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
347
251
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
348
252
|
},
|
349
253
|
{ type: "Document", id: `${model}_LIST` },
|
350
|
-
"Relations"
|
254
|
+
"Relations",
|
255
|
+
{ type: "UidAvailability", id: model }
|
351
256
|
];
|
352
257
|
}
|
353
258
|
}),
|
@@ -365,6 +270,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
365
270
|
}),
|
366
271
|
providesTags: (result, _error, arg) => {
|
367
272
|
return [
|
273
|
+
{ type: "Document", id: `ALL_LIST` },
|
368
274
|
{ type: "Document", id: `${arg.model}_LIST` },
|
369
275
|
...result?.results.map(({ documentId }) => ({
|
370
276
|
type: "Document",
|
@@ -403,6 +309,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
403
309
|
{
|
404
310
|
type: "Document",
|
405
311
|
id: collectionType !== SINGLE_TYPES ? `${model}_${result && "documentId" in result ? result.documentId : documentId}` : model
|
312
|
+
},
|
313
|
+
// Make it easy to invalidate all individual documents queries for a model
|
314
|
+
{
|
315
|
+
type: "Document",
|
316
|
+
id: `${model}_ALL_ITEMS`
|
406
317
|
}
|
407
318
|
];
|
408
319
|
}
|
@@ -441,10 +352,13 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
441
352
|
}
|
442
353
|
}),
|
443
354
|
publishManyDocuments: builder.mutation({
|
444
|
-
query: ({ model, ...body }) => ({
|
355
|
+
query: ({ model, params, ...body }) => ({
|
445
356
|
url: `/content-manager/collection-types/${model}/actions/bulkPublish`,
|
446
357
|
method: "POST",
|
447
|
-
data: body
|
358
|
+
data: body,
|
359
|
+
config: {
|
360
|
+
params
|
361
|
+
}
|
448
362
|
}),
|
449
363
|
invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
|
450
364
|
}),
|
@@ -463,8 +377,21 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
463
377
|
type: "Document",
|
464
378
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
465
379
|
},
|
466
|
-
"Relations"
|
380
|
+
"Relations",
|
381
|
+
{ type: "UidAvailability", id: model }
|
467
382
|
];
|
383
|
+
},
|
384
|
+
async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
|
385
|
+
const patchResult = dispatch(
|
386
|
+
documentApi.util.updateQueryData("getDocument", patch, (draft) => {
|
387
|
+
Object.assign(draft.data, data);
|
388
|
+
})
|
389
|
+
);
|
390
|
+
try {
|
391
|
+
await queryFulfilled;
|
392
|
+
} catch {
|
393
|
+
patchResult.undo();
|
394
|
+
}
|
468
395
|
}
|
469
396
|
}),
|
470
397
|
unpublishDocument: builder.mutation({
|
@@ -486,10 +413,13 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
486
413
|
}
|
487
414
|
}),
|
488
415
|
unpublishManyDocuments: builder.mutation({
|
489
|
-
query: ({ model, ...body }) => ({
|
416
|
+
query: ({ model, params, ...body }) => ({
|
490
417
|
url: `/content-manager/collection-types/${model}/actions/bulkUnpublish`,
|
491
418
|
method: "POST",
|
492
|
-
data: body
|
419
|
+
data: body,
|
420
|
+
config: {
|
421
|
+
params
|
422
|
+
}
|
493
423
|
}),
|
494
424
|
invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
|
495
425
|
})
|
@@ -513,7 +443,25 @@ const {
|
|
513
443
|
useUnpublishDocumentMutation,
|
514
444
|
useUnpublishManyDocumentsMutation
|
515
445
|
} = documentApi;
|
516
|
-
const
|
446
|
+
const buildValidParams = (query) => {
|
447
|
+
if (!query)
|
448
|
+
return query;
|
449
|
+
const { plugins: _, ...validQueryParams } = {
|
450
|
+
...query,
|
451
|
+
...Object.values(query?.plugins ?? {}).reduce(
|
452
|
+
(acc, current) => Object.assign(acc, current),
|
453
|
+
{}
|
454
|
+
)
|
455
|
+
};
|
456
|
+
if ("_q" in validQueryParams) {
|
457
|
+
validQueryParams._q = encodeURIComponent(validQueryParams._q);
|
458
|
+
}
|
459
|
+
return validQueryParams;
|
460
|
+
};
|
461
|
+
const isBaseQueryError = (error) => {
|
462
|
+
return error.name !== void 0;
|
463
|
+
};
|
464
|
+
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
517
465
|
const createModelSchema = (attributes2) => yup.object().shape(
|
518
466
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
519
467
|
if (DOCUMENT_META_FIELDS.includes(name)) {
|
@@ -526,7 +474,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
526
474
|
addMinValidation,
|
527
475
|
addMaxValidation,
|
528
476
|
addRegexValidation
|
529
|
-
].map((fn) => fn(attribute));
|
477
|
+
].map((fn) => fn(attribute, options));
|
530
478
|
const transformSchema = pipe(...validations);
|
531
479
|
switch (attribute.type) {
|
532
480
|
case "component": {
|
@@ -552,10 +500,14 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
552
500
|
yup.array().of(
|
553
501
|
yup.lazy(
|
554
502
|
(data) => {
|
555
|
-
const
|
556
|
-
|
503
|
+
const attributes3 = components?.[data?.__component]?.attributes;
|
504
|
+
const validation = yup.object().shape({
|
557
505
|
__component: yup.string().required().oneOf(Object.keys(components))
|
558
|
-
}).nullable(false)
|
506
|
+
}).nullable(false);
|
507
|
+
if (!attributes3) {
|
508
|
+
return validation;
|
509
|
+
}
|
510
|
+
return validation.concat(createModelSchema(attributes3));
|
559
511
|
}
|
560
512
|
)
|
561
513
|
)
|
@@ -565,11 +517,25 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
565
517
|
return {
|
566
518
|
...acc,
|
567
519
|
[name]: transformSchema(
|
568
|
-
yup.
|
569
|
-
|
570
|
-
|
571
|
-
})
|
572
|
-
|
520
|
+
yup.lazy((value) => {
|
521
|
+
if (!value) {
|
522
|
+
return yup.mixed().nullable(true);
|
523
|
+
} else if (Array.isArray(value)) {
|
524
|
+
return yup.array().of(
|
525
|
+
yup.object().shape({
|
526
|
+
id: yup.string().required()
|
527
|
+
})
|
528
|
+
);
|
529
|
+
} else if (typeof value === "object") {
|
530
|
+
return yup.object();
|
531
|
+
} else {
|
532
|
+
return yup.mixed().test(
|
533
|
+
"type-error",
|
534
|
+
"Relation values must be either null, an array of objects with {id} or an object.",
|
535
|
+
() => false
|
536
|
+
);
|
537
|
+
}
|
538
|
+
})
|
573
539
|
)
|
574
540
|
};
|
575
541
|
default:
|
@@ -609,6 +575,14 @@ const createAttributeSchema = (attribute) => {
|
|
609
575
|
if (!value || typeof value === "string" && value.length === 0) {
|
610
576
|
return true;
|
611
577
|
}
|
578
|
+
if (typeof value === "object") {
|
579
|
+
try {
|
580
|
+
JSON.stringify(value);
|
581
|
+
return true;
|
582
|
+
} catch (err) {
|
583
|
+
return false;
|
584
|
+
}
|
585
|
+
}
|
612
586
|
try {
|
613
587
|
JSON.parse(value);
|
614
588
|
return true;
|
@@ -627,16 +601,30 @@ const createAttributeSchema = (attribute) => {
|
|
627
601
|
return yup.mixed();
|
628
602
|
}
|
629
603
|
};
|
630
|
-
const
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
604
|
+
const nullableSchema = (schema) => {
|
605
|
+
return schema?.nullable ? schema.nullable() : (
|
606
|
+
// In some cases '.nullable' will not be available on the schema.
|
607
|
+
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
608
|
+
// In these cases we should just return the schema as it is.
|
609
|
+
schema
|
610
|
+
);
|
611
|
+
};
|
612
|
+
const addRequiredValidation = (attribute, options) => (schema) => {
|
613
|
+
if (options.status === "draft") {
|
614
|
+
return nullableSchema(schema);
|
636
615
|
}
|
637
|
-
|
616
|
+
if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
|
617
|
+
return schema.min(1, translatedErrors.required);
|
618
|
+
}
|
619
|
+
if (attribute.required && attribute.type !== "relation") {
|
620
|
+
return schema.required(translatedErrors.required);
|
621
|
+
}
|
622
|
+
return nullableSchema(schema);
|
638
623
|
};
|
639
|
-
const addMinLengthValidation = (attribute) => (schema) => {
|
624
|
+
const addMinLengthValidation = (attribute, options) => (schema) => {
|
625
|
+
if (options.status === "draft") {
|
626
|
+
return schema;
|
627
|
+
}
|
640
628
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
641
629
|
return schema.min(attribute.minLength, {
|
642
630
|
...translatedErrors.minLength,
|
@@ -658,9 +646,31 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
658
646
|
}
|
659
647
|
return schema;
|
660
648
|
};
|
661
|
-
const addMinValidation = (attribute) => (schema) => {
|
649
|
+
const addMinValidation = (attribute, options) => (schema) => {
|
662
650
|
if ("min" in attribute) {
|
663
651
|
const min = toInteger(attribute.min);
|
652
|
+
if (attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") {
|
653
|
+
if (options.status !== "draft" && !attribute.required && "test" in schema && min) {
|
654
|
+
return schema.test(
|
655
|
+
"custom-min",
|
656
|
+
{
|
657
|
+
...translatedErrors.min,
|
658
|
+
values: {
|
659
|
+
min: attribute.min
|
660
|
+
}
|
661
|
+
},
|
662
|
+
(value) => {
|
663
|
+
if (!value) {
|
664
|
+
return true;
|
665
|
+
}
|
666
|
+
if (Array.isArray(value) && value.length === 0) {
|
667
|
+
return true;
|
668
|
+
}
|
669
|
+
return value.length >= min;
|
670
|
+
}
|
671
|
+
);
|
672
|
+
}
|
673
|
+
}
|
664
674
|
if ("min" in schema && min) {
|
665
675
|
return schema.min(min, {
|
666
676
|
...translatedErrors.min,
|
@@ -706,24 +716,6 @@ const addRegexValidation = (attribute) => (schema) => {
|
|
706
716
|
}
|
707
717
|
return schema;
|
708
718
|
};
|
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
719
|
const initApi = contentManagerApi.injectEndpoints({
|
728
720
|
endpoints: (builder) => ({
|
729
721
|
getInitialData: builder.query({
|
@@ -737,27 +729,20 @@ const { useGetInitialDataQuery } = initApi;
|
|
737
729
|
const useContentTypeSchema = (model) => {
|
738
730
|
const { toggleNotification } = useNotification();
|
739
731
|
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
|
-
});
|
732
|
+
const { data, error, isLoading, isFetching } = useGetInitialDataQuery(void 0);
|
733
|
+
const { components, contentType, contentTypes } = React.useMemo(() => {
|
734
|
+
const contentType2 = data?.contentTypes.find((ct) => ct.uid === model);
|
735
|
+
const componentsByKey = data?.components.reduce((acc, component) => {
|
736
|
+
acc[component.uid] = component;
|
737
|
+
return acc;
|
738
|
+
}, {});
|
739
|
+
const components2 = extractContentTypeComponents(contentType2?.attributes, componentsByKey);
|
740
|
+
return {
|
741
|
+
components: Object.keys(components2).length === 0 ? void 0 : components2,
|
742
|
+
contentType: contentType2,
|
743
|
+
contentTypes: data?.contentTypes ?? []
|
744
|
+
};
|
745
|
+
}, [model, data]);
|
761
746
|
React.useEffect(() => {
|
762
747
|
if (error) {
|
763
748
|
toggleNotification({
|
@@ -812,7 +797,10 @@ const useDocument = (args, opts) => {
|
|
812
797
|
isLoading: isLoadingDocument,
|
813
798
|
isFetching: isFetchingDocument,
|
814
799
|
error
|
815
|
-
} = useGetDocumentQuery(args,
|
800
|
+
} = useGetDocumentQuery(args, {
|
801
|
+
...opts,
|
802
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
803
|
+
});
|
816
804
|
const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
|
817
805
|
React.useEffect(() => {
|
818
806
|
if (error) {
|
@@ -840,7 +828,7 @@ const useDocument = (args, opts) => {
|
|
840
828
|
return null;
|
841
829
|
} catch (error2) {
|
842
830
|
if (error2 instanceof ValidationError) {
|
843
|
-
return
|
831
|
+
return getYupValidationErrors(error2);
|
844
832
|
}
|
845
833
|
throw error2;
|
846
834
|
}
|
@@ -898,6 +886,7 @@ const useDocumentActions = () => {
|
|
898
886
|
const { formatMessage } = useIntl();
|
899
887
|
const { trackUsage } = useTracking();
|
900
888
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
889
|
+
const navigate = useNavigate();
|
901
890
|
const [deleteDocument] = useDeleteDocumentMutation();
|
902
891
|
const _delete = React.useCallback(
|
903
892
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -936,14 +925,53 @@ const useDocumentActions = () => {
|
|
936
925
|
},
|
937
926
|
[trackUsage, deleteDocument, toggleNotification, formatMessage, formatAPIError]
|
938
927
|
);
|
928
|
+
const [deleteManyDocuments] = useDeleteManyDocumentsMutation();
|
929
|
+
const deleteMany = React.useCallback(
|
930
|
+
async ({ model, documentIds, params }) => {
|
931
|
+
try {
|
932
|
+
trackUsage("willBulkDeleteEntries");
|
933
|
+
const res = await deleteManyDocuments({
|
934
|
+
model,
|
935
|
+
documentIds,
|
936
|
+
params
|
937
|
+
});
|
938
|
+
if ("error" in res) {
|
939
|
+
toggleNotification({
|
940
|
+
type: "danger",
|
941
|
+
message: formatAPIError(res.error)
|
942
|
+
});
|
943
|
+
return { error: res.error };
|
944
|
+
}
|
945
|
+
toggleNotification({
|
946
|
+
type: "success",
|
947
|
+
title: formatMessage({
|
948
|
+
id: getTranslation("success.records.delete"),
|
949
|
+
defaultMessage: "Successfully deleted."
|
950
|
+
}),
|
951
|
+
message: ""
|
952
|
+
});
|
953
|
+
trackUsage("didBulkDeleteEntries");
|
954
|
+
return res.data;
|
955
|
+
} catch (err) {
|
956
|
+
toggleNotification({
|
957
|
+
type: "danger",
|
958
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
959
|
+
});
|
960
|
+
trackUsage("didNotBulkDeleteEntries");
|
961
|
+
throw err;
|
962
|
+
}
|
963
|
+
},
|
964
|
+
[trackUsage, deleteManyDocuments, toggleNotification, formatMessage, formatAPIError]
|
965
|
+
);
|
939
966
|
const [discardDocument] = useDiscardDocumentMutation();
|
940
967
|
const discard = React.useCallback(
|
941
|
-
async ({ collectionType, model, documentId }) => {
|
968
|
+
async ({ collectionType, model, documentId, params }) => {
|
942
969
|
try {
|
943
970
|
const res = await discardDocument({
|
944
971
|
collectionType,
|
945
972
|
model,
|
946
|
-
documentId
|
973
|
+
documentId,
|
974
|
+
params
|
947
975
|
});
|
948
976
|
if ("error" in res) {
|
949
977
|
toggleNotification({
|
@@ -1005,6 +1033,43 @@ const useDocumentActions = () => {
|
|
1005
1033
|
},
|
1006
1034
|
[trackUsage, publishDocument, toggleNotification, formatMessage, formatAPIError]
|
1007
1035
|
);
|
1036
|
+
const [publishManyDocuments] = usePublishManyDocumentsMutation();
|
1037
|
+
const publishMany = React.useCallback(
|
1038
|
+
async ({ model, documentIds, params }) => {
|
1039
|
+
try {
|
1040
|
+
const res = await publishManyDocuments({
|
1041
|
+
model,
|
1042
|
+
documentIds,
|
1043
|
+
params
|
1044
|
+
});
|
1045
|
+
if ("error" in res) {
|
1046
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1047
|
+
return { error: res.error };
|
1048
|
+
}
|
1049
|
+
toggleNotification({
|
1050
|
+
type: "success",
|
1051
|
+
message: formatMessage({
|
1052
|
+
id: getTranslation("success.record.publish"),
|
1053
|
+
defaultMessage: "Published document"
|
1054
|
+
})
|
1055
|
+
});
|
1056
|
+
return res.data;
|
1057
|
+
} catch (err) {
|
1058
|
+
toggleNotification({
|
1059
|
+
type: "danger",
|
1060
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1061
|
+
});
|
1062
|
+
throw err;
|
1063
|
+
}
|
1064
|
+
},
|
1065
|
+
[
|
1066
|
+
// trackUsage,
|
1067
|
+
publishManyDocuments,
|
1068
|
+
toggleNotification,
|
1069
|
+
formatMessage,
|
1070
|
+
formatAPIError
|
1071
|
+
]
|
1072
|
+
);
|
1008
1073
|
const [updateDocument] = useUpdateDocumentMutation();
|
1009
1074
|
const update = React.useCallback(
|
1010
1075
|
async ({ collectionType, model, documentId, params }, data, trackerProperty) => {
|
@@ -1079,6 +1144,41 @@ const useDocumentActions = () => {
|
|
1079
1144
|
},
|
1080
1145
|
[trackUsage, unpublishDocument, toggleNotification, formatMessage, formatAPIError]
|
1081
1146
|
);
|
1147
|
+
const [unpublishManyDocuments] = useUnpublishManyDocumentsMutation();
|
1148
|
+
const unpublishMany = React.useCallback(
|
1149
|
+
async ({ model, documentIds, params }) => {
|
1150
|
+
try {
|
1151
|
+
trackUsage("willBulkUnpublishEntries");
|
1152
|
+
const res = await unpublishManyDocuments({
|
1153
|
+
model,
|
1154
|
+
documentIds,
|
1155
|
+
params
|
1156
|
+
});
|
1157
|
+
if ("error" in res) {
|
1158
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1159
|
+
return { error: res.error };
|
1160
|
+
}
|
1161
|
+
trackUsage("didBulkUnpublishEntries");
|
1162
|
+
toggleNotification({
|
1163
|
+
type: "success",
|
1164
|
+
title: formatMessage({
|
1165
|
+
id: getTranslation("success.records.unpublish"),
|
1166
|
+
defaultMessage: "Successfully unpublished."
|
1167
|
+
}),
|
1168
|
+
message: ""
|
1169
|
+
});
|
1170
|
+
return res.data;
|
1171
|
+
} catch (err) {
|
1172
|
+
toggleNotification({
|
1173
|
+
type: "danger",
|
1174
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1175
|
+
});
|
1176
|
+
trackUsage("didNotBulkUnpublishEntries");
|
1177
|
+
throw err;
|
1178
|
+
}
|
1179
|
+
},
|
1180
|
+
[trackUsage, unpublishManyDocuments, toggleNotification, formatMessage, formatAPIError]
|
1181
|
+
);
|
1082
1182
|
const [createDocument] = useCreateDocumentMutation();
|
1083
1183
|
const create = React.useCallback(
|
1084
1184
|
async ({ model, params }, data, trackerProperty) => {
|
@@ -1122,7 +1222,6 @@ const useDocumentActions = () => {
|
|
1122
1222
|
sourceId
|
1123
1223
|
});
|
1124
1224
|
if ("error" in res) {
|
1125
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1126
1225
|
return { error: res.error };
|
1127
1226
|
}
|
1128
1227
|
toggleNotification({
|
@@ -1141,7 +1240,7 @@ const useDocumentActions = () => {
|
|
1141
1240
|
throw err;
|
1142
1241
|
}
|
1143
1242
|
},
|
1144
|
-
[autoCloneDocument,
|
1243
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1145
1244
|
);
|
1146
1245
|
const [cloneDocument] = useCloneDocumentMutation();
|
1147
1246
|
const clone = React.useCallback(
|
@@ -1167,6 +1266,7 @@ const useDocumentActions = () => {
|
|
1167
1266
|
defaultMessage: "Cloned document"
|
1168
1267
|
})
|
1169
1268
|
});
|
1269
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1170
1270
|
return res.data;
|
1171
1271
|
} catch (err) {
|
1172
1272
|
toggleNotification({
|
@@ -1177,7 +1277,7 @@ const useDocumentActions = () => {
|
|
1177
1277
|
throw err;
|
1178
1278
|
}
|
1179
1279
|
},
|
1180
|
-
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
|
1280
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1181
1281
|
);
|
1182
1282
|
const [getDoc] = useLazyGetDocumentQuery();
|
1183
1283
|
const getDocument = React.useCallback(
|
@@ -1192,15 +1292,18 @@ const useDocumentActions = () => {
|
|
1192
1292
|
clone,
|
1193
1293
|
create,
|
1194
1294
|
delete: _delete,
|
1295
|
+
deleteMany,
|
1195
1296
|
discard,
|
1196
1297
|
getDocument,
|
1197
1298
|
publish,
|
1299
|
+
publishMany,
|
1198
1300
|
unpublish,
|
1301
|
+
unpublishMany,
|
1199
1302
|
update
|
1200
1303
|
};
|
1201
1304
|
};
|
1202
1305
|
const ProtectedHistoryPage = lazy(
|
1203
|
-
() => import("./History-
|
1306
|
+
() => import("./History-BMunT-do.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1204
1307
|
);
|
1205
1308
|
const routes$1 = [
|
1206
1309
|
{
|
@@ -1213,31 +1316,31 @@ const routes$1 = [
|
|
1213
1316
|
}
|
1214
1317
|
];
|
1215
1318
|
const ProtectedEditViewPage = lazy(
|
1216
|
-
() => import("./EditViewPage-
|
1319
|
+
() => import("./EditViewPage-DeTn7rAF.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1217
1320
|
);
|
1218
1321
|
const ProtectedListViewPage = lazy(
|
1219
|
-
() => import("./ListViewPage-
|
1322
|
+
() => import("./ListViewPage-_5gS-DOF.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1220
1323
|
);
|
1221
1324
|
const ProtectedListConfiguration = lazy(
|
1222
|
-
() => import("./ListConfigurationPage-
|
1325
|
+
() => import("./ListConfigurationPage-CDqkCxgV.mjs").then((mod) => ({
|
1223
1326
|
default: mod.ProtectedListConfiguration
|
1224
1327
|
}))
|
1225
1328
|
);
|
1226
1329
|
const ProtectedEditConfigurationPage = lazy(
|
1227
|
-
() => import("./EditConfigurationPage-
|
1330
|
+
() => import("./EditConfigurationPage-CE_yavTi.mjs").then((mod) => ({
|
1228
1331
|
default: mod.ProtectedEditConfigurationPage
|
1229
1332
|
}))
|
1230
1333
|
);
|
1231
1334
|
const ProtectedComponentConfigurationPage = lazy(
|
1232
|
-
() => import("./ComponentConfigurationPage-
|
1335
|
+
() => import("./ComponentConfigurationPage-CpBFh6_r.mjs").then((mod) => ({
|
1233
1336
|
default: mod.ProtectedComponentConfigurationPage
|
1234
1337
|
}))
|
1235
1338
|
);
|
1236
1339
|
const NoPermissions = lazy(
|
1237
|
-
() => import("./NoPermissionsPage-
|
1340
|
+
() => import("./NoPermissionsPage-Bs8D5W_v.mjs").then((mod) => ({ default: mod.NoPermissions }))
|
1238
1341
|
);
|
1239
1342
|
const NoContentType = lazy(
|
1240
|
-
() => import("./NoContentTypePage-
|
1343
|
+
() => import("./NoContentTypePage-Dht-55hr.mjs").then((mod) => ({ default: mod.NoContentType }))
|
1241
1344
|
);
|
1242
1345
|
const CollectionTypePages = () => {
|
1243
1346
|
const { collectionType } = useParams();
|
@@ -1351,12 +1454,14 @@ const DocumentActionButton = (action) => {
|
|
1351
1454
|
/* @__PURE__ */ jsx(
|
1352
1455
|
Button,
|
1353
1456
|
{
|
1354
|
-
flex:
|
1457
|
+
flex: "auto",
|
1355
1458
|
startIcon: action.icon,
|
1356
1459
|
disabled: action.disabled,
|
1357
1460
|
onClick: handleClick(action),
|
1358
1461
|
justifyContent: "center",
|
1359
1462
|
variant: action.variant || "default",
|
1463
|
+
paddingTop: "7px",
|
1464
|
+
paddingBottom: "7px",
|
1360
1465
|
children: action.label
|
1361
1466
|
}
|
1362
1467
|
),
|
@@ -1364,7 +1469,7 @@ const DocumentActionButton = (action) => {
|
|
1364
1469
|
DocumentActionConfirmDialog,
|
1365
1470
|
{
|
1366
1471
|
...action.dialog,
|
1367
|
-
variant: action.variant,
|
1472
|
+
variant: action.dialog?.variant ?? action.variant,
|
1368
1473
|
isOpen: dialogId === action.id,
|
1369
1474
|
onClose: handleClose
|
1370
1475
|
}
|
@@ -1421,13 +1526,13 @@ const DocumentActionsMenu = ({
|
|
1421
1526
|
disabled: isDisabled,
|
1422
1527
|
size: "S",
|
1423
1528
|
endIcon: null,
|
1424
|
-
paddingTop: "
|
1425
|
-
paddingLeft: "
|
1426
|
-
paddingRight: "
|
1529
|
+
paddingTop: "4px",
|
1530
|
+
paddingLeft: "7px",
|
1531
|
+
paddingRight: "7px",
|
1427
1532
|
variant,
|
1428
1533
|
children: [
|
1429
1534
|
/* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
|
1430
|
-
/* @__PURE__ */ jsx(VisuallyHidden, {
|
1535
|
+
/* @__PURE__ */ jsx(VisuallyHidden, { tag: "span", children: label || formatMessage({
|
1431
1536
|
id: "content-manager.containers.edit.panels.default.more-actions",
|
1432
1537
|
defaultMessage: "More document actions"
|
1433
1538
|
}) })
|
@@ -1443,10 +1548,25 @@ const DocumentActionsMenu = ({
|
|
1443
1548
|
onSelect: handleClick(action),
|
1444
1549
|
display: "block",
|
1445
1550
|
children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", gap: 4, children: [
|
1446
|
-
/* @__PURE__ */ jsxs(
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1551
|
+
/* @__PURE__ */ jsxs(
|
1552
|
+
Flex,
|
1553
|
+
{
|
1554
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1555
|
+
gap: 2,
|
1556
|
+
tag: "span",
|
1557
|
+
children: [
|
1558
|
+
/* @__PURE__ */ jsx(
|
1559
|
+
Flex,
|
1560
|
+
{
|
1561
|
+
tag: "span",
|
1562
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1563
|
+
children: action.icon
|
1564
|
+
}
|
1565
|
+
),
|
1566
|
+
action.label
|
1567
|
+
]
|
1568
|
+
}
|
1569
|
+
),
|
1450
1570
|
action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsx(
|
1451
1571
|
Flex,
|
1452
1572
|
{
|
@@ -1505,6 +1625,18 @@ const convertActionVariantToColor = (variant = "secondary") => {
|
|
1505
1625
|
return "primary600";
|
1506
1626
|
}
|
1507
1627
|
};
|
1628
|
+
const convertActionVariantToIconColor = (variant = "secondary") => {
|
1629
|
+
switch (variant) {
|
1630
|
+
case "danger":
|
1631
|
+
return "danger600";
|
1632
|
+
case "secondary":
|
1633
|
+
return "neutral500";
|
1634
|
+
case "success":
|
1635
|
+
return "success600";
|
1636
|
+
default:
|
1637
|
+
return "primary600";
|
1638
|
+
}
|
1639
|
+
};
|
1508
1640
|
const DocumentActionConfirmDialog = ({
|
1509
1641
|
onClose,
|
1510
1642
|
onCancel,
|
@@ -1527,61 +1659,42 @@ const DocumentActionConfirmDialog = ({
|
|
1527
1659
|
}
|
1528
1660
|
onClose();
|
1529
1661
|
};
|
1530
|
-
return /* @__PURE__ */
|
1531
|
-
/* @__PURE__ */ jsx(
|
1532
|
-
/* @__PURE__ */ jsx(
|
1533
|
-
|
1534
|
-
{
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
1543
|
-
|
1544
|
-
)
|
1545
|
-
] });
|
1662
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
1663
|
+
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
1664
|
+
/* @__PURE__ */ jsx(Dialog.Body, { children: content }),
|
1665
|
+
/* @__PURE__ */ jsxs(Dialog.Footer, { children: [
|
1666
|
+
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", fullWidth: true, children: formatMessage({
|
1667
|
+
id: "app.components.Button.cancel",
|
1668
|
+
defaultMessage: "Cancel"
|
1669
|
+
}) }) }),
|
1670
|
+
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
|
1671
|
+
id: "app.components.Button.confirm",
|
1672
|
+
defaultMessage: "Confirm"
|
1673
|
+
}) })
|
1674
|
+
] })
|
1675
|
+
] }) });
|
1546
1676
|
};
|
1547
1677
|
const DocumentActionModal = ({
|
1548
1678
|
isOpen,
|
1549
1679
|
title,
|
1550
1680
|
onClose,
|
1551
1681
|
footer: Footer,
|
1552
|
-
content,
|
1682
|
+
content: Content,
|
1553
1683
|
onModalClose
|
1554
1684
|
}) => {
|
1555
|
-
const id = React.useId();
|
1556
|
-
if (!isOpen) {
|
1557
|
-
return null;
|
1558
|
-
}
|
1559
1685
|
const handleClose = () => {
|
1560
1686
|
if (onClose) {
|
1561
1687
|
onClose();
|
1562
1688
|
}
|
1563
1689
|
onModalClose();
|
1564
1690
|
};
|
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
|
-
] });
|
1691
|
+
return /* @__PURE__ */ jsx(Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
|
1692
|
+
/* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: title }) }),
|
1693
|
+
typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsx(Modal.Body, { children: Content }),
|
1694
|
+
typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
|
1695
|
+
] }) });
|
1583
1696
|
};
|
1584
|
-
const PublishAction = ({
|
1697
|
+
const PublishAction$1 = ({
|
1585
1698
|
activeTab,
|
1586
1699
|
documentId,
|
1587
1700
|
model,
|
@@ -1593,13 +1706,17 @@ const PublishAction = ({
|
|
1593
1706
|
const navigate = useNavigate();
|
1594
1707
|
const { toggleNotification } = useNotification();
|
1595
1708
|
const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
|
1709
|
+
const isListView = useMatch(LIST_PATH) !== null;
|
1596
1710
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
1597
1711
|
const { formatMessage } = useIntl();
|
1598
|
-
const { canPublish
|
1599
|
-
"PublishAction",
|
1600
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1601
|
-
);
|
1712
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1602
1713
|
const { publish } = useDocumentActions();
|
1714
|
+
const [
|
1715
|
+
countDraftRelations,
|
1716
|
+
{ isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
|
1717
|
+
] = useLazyGetDraftRelationCountQuery();
|
1718
|
+
const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React.useState(0);
|
1719
|
+
const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React.useState(0);
|
1603
1720
|
const [{ query, rawQuery }] = useQueryParams();
|
1604
1721
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
1605
1722
|
const modified = useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
@@ -1608,10 +1725,103 @@ const PublishAction = ({
|
|
1608
1725
|
const validate = useForm("PublishAction", (state) => state.validate);
|
1609
1726
|
const setErrors = useForm("PublishAction", (state) => state.setErrors);
|
1610
1727
|
const formValues = useForm("PublishAction", ({ values }) => values);
|
1728
|
+
React.useEffect(() => {
|
1729
|
+
if (isErrorDraftRelations) {
|
1730
|
+
toggleNotification({
|
1731
|
+
type: "danger",
|
1732
|
+
message: formatMessage({
|
1733
|
+
id: getTranslation("error.records.fetch-draft-relatons"),
|
1734
|
+
defaultMessage: "An error occurred while fetching draft relations on this document."
|
1735
|
+
})
|
1736
|
+
});
|
1737
|
+
}
|
1738
|
+
}, [isErrorDraftRelations, toggleNotification, formatMessage]);
|
1739
|
+
React.useEffect(() => {
|
1740
|
+
const localDraftRelations = /* @__PURE__ */ new Set();
|
1741
|
+
const extractDraftRelations = (data) => {
|
1742
|
+
const relations = data.connect || [];
|
1743
|
+
relations.forEach((relation) => {
|
1744
|
+
if (relation.status === "draft") {
|
1745
|
+
localDraftRelations.add(relation.id);
|
1746
|
+
}
|
1747
|
+
});
|
1748
|
+
};
|
1749
|
+
const traverseAndExtract = (data) => {
|
1750
|
+
Object.entries(data).forEach(([key, value]) => {
|
1751
|
+
if (key === "connect" && Array.isArray(value)) {
|
1752
|
+
extractDraftRelations({ connect: value });
|
1753
|
+
} else if (typeof value === "object" && value !== null) {
|
1754
|
+
traverseAndExtract(value);
|
1755
|
+
}
|
1756
|
+
});
|
1757
|
+
};
|
1758
|
+
if (!documentId || modified) {
|
1759
|
+
traverseAndExtract(formValues);
|
1760
|
+
setLocalCountOfDraftRelations(localDraftRelations.size);
|
1761
|
+
}
|
1762
|
+
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
1763
|
+
React.useEffect(() => {
|
1764
|
+
if (!document || !document.documentId || isListView) {
|
1765
|
+
return;
|
1766
|
+
}
|
1767
|
+
const fetchDraftRelationsCount = async () => {
|
1768
|
+
const { data, error } = await countDraftRelations({
|
1769
|
+
collectionType,
|
1770
|
+
model,
|
1771
|
+
documentId,
|
1772
|
+
params
|
1773
|
+
});
|
1774
|
+
if (error) {
|
1775
|
+
throw error;
|
1776
|
+
}
|
1777
|
+
if (data) {
|
1778
|
+
setServerCountOfDraftRelations(data.data);
|
1779
|
+
}
|
1780
|
+
};
|
1781
|
+
fetchDraftRelationsCount();
|
1782
|
+
}, [isListView, document, documentId, countDraftRelations, collectionType, model, params]);
|
1611
1783
|
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
1612
1784
|
if (!schema?.options?.draftAndPublish) {
|
1613
1785
|
return null;
|
1614
1786
|
}
|
1787
|
+
const performPublish = async () => {
|
1788
|
+
setSubmitting(true);
|
1789
|
+
try {
|
1790
|
+
const { errors } = await validate();
|
1791
|
+
if (errors) {
|
1792
|
+
toggleNotification({
|
1793
|
+
type: "danger",
|
1794
|
+
message: formatMessage({
|
1795
|
+
id: "content-manager.validation.error",
|
1796
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
1797
|
+
})
|
1798
|
+
});
|
1799
|
+
return;
|
1800
|
+
}
|
1801
|
+
const res = await publish(
|
1802
|
+
{
|
1803
|
+
collectionType,
|
1804
|
+
model,
|
1805
|
+
documentId,
|
1806
|
+
params
|
1807
|
+
},
|
1808
|
+
formValues
|
1809
|
+
);
|
1810
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1811
|
+
navigate({
|
1812
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1813
|
+
search: rawQuery
|
1814
|
+
});
|
1815
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1816
|
+
setErrors(formatValidationErrors(res.error));
|
1817
|
+
}
|
1818
|
+
} finally {
|
1819
|
+
setSubmitting(false);
|
1820
|
+
}
|
1821
|
+
};
|
1822
|
+
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
1823
|
+
const enableDraftRelationsCount = false;
|
1824
|
+
const hasDraftRelations = enableDraftRelationsCount;
|
1615
1825
|
return {
|
1616
1826
|
/**
|
1617
1827
|
* Disabled when:
|
@@ -1621,52 +1831,39 @@ const PublishAction = ({
|
|
1621
1831
|
* - the document is already published & not modified
|
1622
1832
|
* - the document is being created & not modified
|
1623
1833
|
* - the user doesn't have the permission to publish
|
1624
|
-
* - the user doesn't have the permission to create a new document
|
1625
|
-
* - the user doesn't have the permission to update the document
|
1626
1834
|
*/
|
1627
|
-
disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish
|
1835
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
1628
1836
|
label: formatMessage({
|
1629
1837
|
id: "app.utils.publish",
|
1630
1838
|
defaultMessage: "Publish"
|
1631
1839
|
}),
|
1632
1840
|
onClick: async () => {
|
1633
|
-
|
1634
|
-
|
1635
|
-
|
1636
|
-
|
1637
|
-
|
1638
|
-
|
1639
|
-
|
1640
|
-
|
1641
|
-
|
1642
|
-
|
1643
|
-
|
1644
|
-
|
1645
|
-
|
1646
|
-
|
1647
|
-
|
1648
|
-
|
1649
|
-
|
1650
|
-
documentId,
|
1651
|
-
params
|
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));
|
1841
|
+
await performPublish();
|
1842
|
+
},
|
1843
|
+
dialog: hasDraftRelations ? {
|
1844
|
+
type: "dialog",
|
1845
|
+
variant: "danger",
|
1846
|
+
footer: null,
|
1847
|
+
title: formatMessage({
|
1848
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
|
1849
|
+
defaultMessage: "Confirmation"
|
1850
|
+
}),
|
1851
|
+
content: formatMessage(
|
1852
|
+
{
|
1853
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
1854
|
+
defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
|
1855
|
+
},
|
1856
|
+
{
|
1857
|
+
count: totalDraftRelations
|
1662
1858
|
}
|
1663
|
-
|
1664
|
-
|
1859
|
+
),
|
1860
|
+
onConfirm: async () => {
|
1861
|
+
await performPublish();
|
1665
1862
|
}
|
1666
|
-
}
|
1863
|
+
} : void 0
|
1667
1864
|
};
|
1668
1865
|
};
|
1669
|
-
PublishAction.type = "publish";
|
1866
|
+
PublishAction$1.type = "publish";
|
1670
1867
|
const UpdateAction = ({
|
1671
1868
|
activeTab,
|
1672
1869
|
documentId,
|
@@ -1679,10 +1876,6 @@ const UpdateAction = ({
|
|
1679
1876
|
const cloneMatch = useMatch(CLONE_PATH);
|
1680
1877
|
const isCloning = cloneMatch !== null;
|
1681
1878
|
const { formatMessage } = useIntl();
|
1682
|
-
const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1683
|
-
canCreate: canCreate2,
|
1684
|
-
canUpdate: canUpdate2
|
1685
|
-
}));
|
1686
1879
|
const { create, update, clone } = useDocumentActions();
|
1687
1880
|
const [{ query, rawQuery }] = useQueryParams();
|
1688
1881
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
@@ -1699,10 +1892,8 @@ const UpdateAction = ({
|
|
1699
1892
|
* - the form is submitting
|
1700
1893
|
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
1701
1894
|
* - 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
1895
|
*/
|
1705
|
-
disabled: isSubmitting || !modified && !isCloning || activeTab === "published"
|
1896
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1706
1897
|
label: formatMessage({
|
1707
1898
|
id: "content-manager.containers.Edit.save",
|
1708
1899
|
defaultMessage: "Save"
|
@@ -1710,16 +1901,18 @@ const UpdateAction = ({
|
|
1710
1901
|
onClick: async () => {
|
1711
1902
|
setSubmitting(true);
|
1712
1903
|
try {
|
1713
|
-
|
1714
|
-
|
1715
|
-
|
1716
|
-
|
1717
|
-
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1904
|
+
if (activeTab !== "draft") {
|
1905
|
+
const { errors } = await validate();
|
1906
|
+
if (errors) {
|
1907
|
+
toggleNotification({
|
1908
|
+
type: "danger",
|
1909
|
+
message: formatMessage({
|
1910
|
+
id: "content-manager.validation.error",
|
1911
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
1912
|
+
})
|
1913
|
+
});
|
1914
|
+
return;
|
1915
|
+
}
|
1723
1916
|
}
|
1724
1917
|
if (isCloning) {
|
1725
1918
|
const res = await clone(
|
@@ -1731,10 +1924,13 @@ const UpdateAction = ({
|
|
1731
1924
|
document
|
1732
1925
|
);
|
1733
1926
|
if ("data" in res) {
|
1734
|
-
navigate(
|
1735
|
-
|
1736
|
-
|
1737
|
-
|
1927
|
+
navigate(
|
1928
|
+
{
|
1929
|
+
pathname: `../${res.data.documentId}`,
|
1930
|
+
search: rawQuery
|
1931
|
+
},
|
1932
|
+
{ relative: "path" }
|
1933
|
+
);
|
1738
1934
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1739
1935
|
setErrors(formatValidationErrors(res.error));
|
1740
1936
|
}
|
@@ -1762,10 +1958,13 @@ const UpdateAction = ({
|
|
1762
1958
|
document
|
1763
1959
|
);
|
1764
1960
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1765
|
-
navigate(
|
1766
|
-
|
1767
|
-
|
1768
|
-
|
1961
|
+
navigate(
|
1962
|
+
{
|
1963
|
+
pathname: `../${res.data.documentId}`,
|
1964
|
+
search: rawQuery
|
1965
|
+
},
|
1966
|
+
{ replace: true, relative: "path" }
|
1967
|
+
);
|
1769
1968
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1770
1969
|
setErrors(formatValidationErrors(res.error));
|
1771
1970
|
}
|
@@ -1781,7 +1980,7 @@ const UNPUBLISH_DRAFT_OPTIONS = {
|
|
1781
1980
|
KEEP: "keep",
|
1782
1981
|
DISCARD: "discard"
|
1783
1982
|
};
|
1784
|
-
const UnpublishAction = ({
|
1983
|
+
const UnpublishAction$1 = ({
|
1785
1984
|
activeTab,
|
1786
1985
|
documentId,
|
1787
1986
|
model,
|
@@ -1797,10 +1996,8 @@ const UnpublishAction = ({
|
|
1797
1996
|
const { toggleNotification } = useNotification();
|
1798
1997
|
const [shouldKeepDraft, setShouldKeepDraft] = React.useState(true);
|
1799
1998
|
const isDocumentModified = document?.status === "modified";
|
1800
|
-
const handleChange = (
|
1801
|
-
|
1802
|
-
setShouldKeepDraft(e.target.value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1803
|
-
}
|
1999
|
+
const handleChange = (value) => {
|
2000
|
+
setShouldKeepDraft(value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1804
2001
|
};
|
1805
2002
|
if (!schema?.options?.draftAndPublish) {
|
1806
2003
|
return null;
|
@@ -1811,7 +2008,7 @@ const UnpublishAction = ({
|
|
1811
2008
|
id: "app.utils.unpublish",
|
1812
2009
|
defaultMessage: "Unpublish"
|
1813
2010
|
}),
|
1814
|
-
icon: /* @__PURE__ */ jsx(
|
2011
|
+
icon: /* @__PURE__ */ jsx(Cross, {}),
|
1815
2012
|
onClick: async () => {
|
1816
2013
|
if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
|
1817
2014
|
if (!documentId) {
|
@@ -1844,45 +2041,30 @@ const UnpublishAction = ({
|
|
1844
2041
|
content: /* @__PURE__ */ jsxs(Flex, { alignItems: "flex-start", direction: "column", gap: 6, children: [
|
1845
2042
|
/* @__PURE__ */ jsxs(Flex, { width: "100%", direction: "column", gap: 2, children: [
|
1846
2043
|
/* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
1847
|
-
/* @__PURE__ */ jsx(Typography, {
|
2044
|
+
/* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
1848
2045
|
id: "content-manager.actions.unpublish.dialog.body",
|
1849
2046
|
defaultMessage: "Are you sure?"
|
1850
2047
|
}) })
|
1851
2048
|
] }),
|
1852
2049
|
/* @__PURE__ */ jsxs(
|
1853
|
-
|
2050
|
+
Radio.Group,
|
1854
2051
|
{
|
1855
|
-
|
1856
|
-
|
1857
|
-
|
1858
|
-
|
1859
|
-
|
2052
|
+
defaultValue: UNPUBLISH_DRAFT_OPTIONS.KEEP,
|
2053
|
+
name: "discard-options",
|
2054
|
+
"aria-label": formatMessage({
|
2055
|
+
id: "content-manager.actions.unpublish.dialog.radio-label",
|
2056
|
+
defaultMessage: "Choose an option to unpublish the document."
|
2057
|
+
}),
|
2058
|
+
onValueChange: handleChange,
|
1860
2059
|
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
|
-
)
|
2060
|
+
/* @__PURE__ */ jsx(Radio.Item, { checked: shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.KEEP, children: formatMessage({
|
2061
|
+
id: "content-manager.actions.unpublish.dialog.option.keep-draft",
|
2062
|
+
defaultMessage: "Keep draft"
|
2063
|
+
}) }),
|
2064
|
+
/* @__PURE__ */ jsx(Radio.Item, { checked: !shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.DISCARD, children: formatMessage({
|
2065
|
+
id: "content-manager.actions.unpublish.dialog.option.replace-draft",
|
2066
|
+
defaultMessage: "Replace draft"
|
2067
|
+
}) })
|
1886
2068
|
]
|
1887
2069
|
}
|
1888
2070
|
)
|
@@ -1915,7 +2097,7 @@ const UnpublishAction = ({
|
|
1915
2097
|
position: ["panel", "table-row"]
|
1916
2098
|
};
|
1917
2099
|
};
|
1918
|
-
UnpublishAction.type = "unpublish";
|
2100
|
+
UnpublishAction$1.type = "unpublish";
|
1919
2101
|
const DiscardAction = ({
|
1920
2102
|
activeTab,
|
1921
2103
|
documentId,
|
@@ -1938,7 +2120,7 @@ const DiscardAction = ({
|
|
1938
2120
|
id: "content-manager.actions.discard.label",
|
1939
2121
|
defaultMessage: "Discard changes"
|
1940
2122
|
}),
|
1941
|
-
icon: /* @__PURE__ */ jsx(
|
2123
|
+
icon: /* @__PURE__ */ jsx(Cross, {}),
|
1942
2124
|
position: ["panel", "table-row"],
|
1943
2125
|
variant: "danger",
|
1944
2126
|
dialog: {
|
@@ -1949,7 +2131,7 @@ const DiscardAction = ({
|
|
1949
2131
|
}),
|
1950
2132
|
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
|
1951
2133
|
/* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
1952
|
-
/* @__PURE__ */ jsx(Typography, {
|
2134
|
+
/* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
1953
2135
|
id: "content-manager.actions.discard.dialog.body",
|
1954
2136
|
defaultMessage: "Are you sure?"
|
1955
2137
|
}) })
|
@@ -1966,12 +2148,7 @@ const DiscardAction = ({
|
|
1966
2148
|
};
|
1967
2149
|
};
|
1968
2150
|
DiscardAction.type = "discard";
|
1969
|
-
const
|
1970
|
-
path {
|
1971
|
-
fill: currentColor;
|
1972
|
-
}
|
1973
|
-
`;
|
1974
|
-
const DEFAULT_ACTIONS = [PublishAction, UpdateAction, UnpublishAction, DiscardAction];
|
2151
|
+
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
1975
2152
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
1976
2153
|
const RelativeTime = React.forwardRef(
|
1977
2154
|
({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {
|
@@ -2018,8 +2195,8 @@ const getDisplayName = ({
|
|
2018
2195
|
};
|
2019
2196
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2020
2197
|
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2021
|
-
const statusVariant = status === "draft" ? "
|
2022
|
-
return /* @__PURE__ */ jsx(Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsx(Typography, {
|
2198
|
+
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2199
|
+
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
2200
|
};
|
2024
2201
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
2025
2202
|
const { formatMessage } = useIntl();
|
@@ -2028,23 +2205,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
|
2028
2205
|
id: "content-manager.containers.edit.title.new",
|
2029
2206
|
defaultMessage: "Create an entry"
|
2030
2207
|
}) : documentTitle;
|
2031
|
-
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop:
|
2208
|
+
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2032
2209
|
/* @__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
|
2210
|
+
/* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2211
|
+
/* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
|
2212
|
+
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
2213
|
+
] }),
|
2214
|
+
status ? /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
|
2048
2215
|
] });
|
2049
2216
|
};
|
2050
2217
|
const HeaderToolbar = () => {
|
@@ -2196,7 +2363,7 @@ const Information = ({ activeTab }) => {
|
|
2196
2363
|
borderColor: "neutral150",
|
2197
2364
|
direction: "column",
|
2198
2365
|
marginTop: 2,
|
2199
|
-
|
2366
|
+
tag: "dl",
|
2200
2367
|
padding: 5,
|
2201
2368
|
gap: 3,
|
2202
2369
|
alignItems: "flex-start",
|
@@ -2204,15 +2371,29 @@ const Information = ({ activeTab }) => {
|
|
2204
2371
|
marginRight: "-0.4rem",
|
2205
2372
|
width: "calc(100% + 8px)",
|
2206
2373
|
children: information.map((info) => /* @__PURE__ */ jsxs(Flex, { gap: 1, direction: "column", alignItems: "flex-start", children: [
|
2207
|
-
/* @__PURE__ */ jsx(Typography, {
|
2208
|
-
/* @__PURE__ */ jsx(Typography, {
|
2374
|
+
/* @__PURE__ */ jsx(Typography, { tag: "dt", variant: "pi", fontWeight: "bold", children: info.label }),
|
2375
|
+
/* @__PURE__ */ jsx(Typography, { tag: "dd", variant: "pi", textColor: "neutral600", children: info.value })
|
2209
2376
|
] }, info.label))
|
2210
2377
|
}
|
2211
2378
|
);
|
2212
2379
|
};
|
2213
2380
|
const HeaderActions = ({ actions: actions2 }) => {
|
2214
|
-
|
2215
|
-
|
2381
|
+
const [dialogId, setDialogId] = React.useState(null);
|
2382
|
+
const handleClick = (action) => async (e) => {
|
2383
|
+
if (!("options" in action)) {
|
2384
|
+
const { onClick = () => false, dialog, id } = action;
|
2385
|
+
const muteDialog = await onClick(e);
|
2386
|
+
if (dialog && !muteDialog) {
|
2387
|
+
e.preventDefault();
|
2388
|
+
setDialogId(id);
|
2389
|
+
}
|
2390
|
+
}
|
2391
|
+
};
|
2392
|
+
const handleClose = () => {
|
2393
|
+
setDialogId(null);
|
2394
|
+
};
|
2395
|
+
return /* @__PURE__ */ jsx(Flex, { gap: 1, children: actions2.map((action) => {
|
2396
|
+
if (action.options) {
|
2216
2397
|
return /* @__PURE__ */ jsx(
|
2217
2398
|
SingleSelect,
|
2218
2399
|
{
|
@@ -2226,10 +2407,49 @@ const HeaderActions = ({ actions: actions2 }) => {
|
|
2226
2407
|
action.id
|
2227
2408
|
);
|
2228
2409
|
} else {
|
2229
|
-
|
2410
|
+
if (action.type === "icon") {
|
2411
|
+
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
2412
|
+
/* @__PURE__ */ jsx(
|
2413
|
+
IconButton,
|
2414
|
+
{
|
2415
|
+
disabled: action.disabled,
|
2416
|
+
label: action.label,
|
2417
|
+
size: "S",
|
2418
|
+
onClick: handleClick(action),
|
2419
|
+
children: action.icon
|
2420
|
+
}
|
2421
|
+
),
|
2422
|
+
action.dialog ? /* @__PURE__ */ jsx(
|
2423
|
+
HeaderActionDialog,
|
2424
|
+
{
|
2425
|
+
...action.dialog,
|
2426
|
+
isOpen: dialogId === action.id,
|
2427
|
+
onClose: handleClose
|
2428
|
+
}
|
2429
|
+
) : null
|
2430
|
+
] }, action.id);
|
2431
|
+
}
|
2230
2432
|
}
|
2231
2433
|
}) });
|
2232
2434
|
};
|
2435
|
+
const HeaderActionDialog = ({
|
2436
|
+
onClose,
|
2437
|
+
onCancel,
|
2438
|
+
title,
|
2439
|
+
content: Content,
|
2440
|
+
isOpen
|
2441
|
+
}) => {
|
2442
|
+
const handleClose = async () => {
|
2443
|
+
if (onCancel) {
|
2444
|
+
await onCancel();
|
2445
|
+
}
|
2446
|
+
onClose();
|
2447
|
+
};
|
2448
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
2449
|
+
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
2450
|
+
typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : Content
|
2451
|
+
] }) });
|
2452
|
+
};
|
2233
2453
|
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
2234
2454
|
const navigate = useNavigate();
|
2235
2455
|
const { formatMessage } = useIntl();
|
@@ -2238,7 +2458,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2238
2458
|
id: "app.links.configure-view",
|
2239
2459
|
defaultMessage: "Configure the view"
|
2240
2460
|
}),
|
2241
|
-
icon: /* @__PURE__ */ jsx(
|
2461
|
+
icon: /* @__PURE__ */ jsx(ListPlus, {}),
|
2242
2462
|
onClick: () => {
|
2243
2463
|
navigate(`../${collectionType}/${model}/configurations/edit`);
|
2244
2464
|
},
|
@@ -2246,11 +2466,6 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2246
2466
|
};
|
2247
2467
|
};
|
2248
2468
|
ConfigureTheViewAction.type = "configure-the-view";
|
2249
|
-
const StyledCog = styled(Cog)`
|
2250
|
-
path {
|
2251
|
-
fill: currentColor;
|
2252
|
-
}
|
2253
|
-
`;
|
2254
2469
|
const EditTheModelAction = ({ model }) => {
|
2255
2470
|
const navigate = useNavigate();
|
2256
2471
|
const { formatMessage } = useIntl();
|
@@ -2259,7 +2474,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2259
2474
|
id: "content-manager.link-to-ctb",
|
2260
2475
|
defaultMessage: "Edit the model"
|
2261
2476
|
}),
|
2262
|
-
icon: /* @__PURE__ */ jsx(
|
2477
|
+
icon: /* @__PURE__ */ jsx(Pencil, {}),
|
2263
2478
|
onClick: () => {
|
2264
2479
|
navigate(`/plugins/content-type-builder/content-types/${model}`);
|
2265
2480
|
},
|
@@ -2267,12 +2482,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2267
2482
|
};
|
2268
2483
|
};
|
2269
2484
|
EditTheModelAction.type = "edit-the-model";
|
2270
|
-
const
|
2271
|
-
path {
|
2272
|
-
fill: currentColor;
|
2273
|
-
}
|
2274
|
-
`;
|
2275
|
-
const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
2485
|
+
const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
2276
2486
|
const navigate = useNavigate();
|
2277
2487
|
const { formatMessage } = useIntl();
|
2278
2488
|
const listViewPathMatch = useMatch(LIST_PATH);
|
@@ -2286,7 +2496,7 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
|
2286
2496
|
id: "content-manager.actions.delete.label",
|
2287
2497
|
defaultMessage: "Delete document"
|
2288
2498
|
}),
|
2289
|
-
icon: /* @__PURE__ */ jsx(
|
2499
|
+
icon: /* @__PURE__ */ jsx(Trash, {}),
|
2290
2500
|
dialog: {
|
2291
2501
|
type: "dialog",
|
2292
2502
|
title: formatMessage({
|
@@ -2295,7 +2505,7 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
|
2295
2505
|
}),
|
2296
2506
|
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
|
2297
2507
|
/* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
2298
|
-
/* @__PURE__ */ jsx(Typography, {
|
2508
|
+
/* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
2299
2509
|
id: "content-manager.actions.delete.dialog.body",
|
2300
2510
|
defaultMessage: "Are you sure?"
|
2301
2511
|
}) })
|
@@ -2340,13 +2550,8 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
|
2340
2550
|
position: ["header", "table-row"]
|
2341
2551
|
};
|
2342
2552
|
};
|
2343
|
-
DeleteAction.type = "delete";
|
2344
|
-
const
|
2345
|
-
path {
|
2346
|
-
fill: currentColor;
|
2347
|
-
}
|
2348
|
-
`;
|
2349
|
-
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction];
|
2553
|
+
DeleteAction$1.type = "delete";
|
2554
|
+
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2350
2555
|
const Panels = () => {
|
2351
2556
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
2352
2557
|
const [
|
@@ -2380,7 +2585,7 @@ const ActionsPanel = () => {
|
|
2380
2585
|
return {
|
2381
2586
|
title: formatMessage({
|
2382
2587
|
id: "content-manager.containers.edit.panels.default.title",
|
2383
|
-
defaultMessage: "
|
2588
|
+
defaultMessage: "Entry"
|
2384
2589
|
}),
|
2385
2590
|
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2386
2591
|
};
|
@@ -2420,7 +2625,7 @@ const Panel = React.forwardRef(({ children, title }, ref) => {
|
|
2420
2625
|
Flex,
|
2421
2626
|
{
|
2422
2627
|
ref,
|
2423
|
-
|
2628
|
+
tag: "aside",
|
2424
2629
|
"aria-labelledby": "additional-information",
|
2425
2630
|
background: "neutral0",
|
2426
2631
|
borderColor: "neutral150",
|
@@ -2435,89 +2640,977 @@ const Panel = React.forwardRef(({ children, title }, ref) => {
|
|
2435
2640
|
justifyContent: "stretch",
|
2436
2641
|
alignItems: "flex-start",
|
2437
2642
|
children: [
|
2438
|
-
/* @__PURE__ */ jsx(Typography, {
|
2643
|
+
/* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2439
2644
|
children
|
2440
2645
|
]
|
2441
2646
|
}
|
2442
2647
|
);
|
2443
2648
|
});
|
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
|
-
] });
|
2649
|
+
const HOOKS = {
|
2650
|
+
/**
|
2651
|
+
* Hook that allows to mutate the displayed headers of the list view table
|
2652
|
+
* @constant
|
2653
|
+
* @type {string}
|
2654
|
+
*/
|
2655
|
+
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2656
|
+
/**
|
2657
|
+
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2658
|
+
* @constant
|
2659
|
+
* @type {string}
|
2660
|
+
*/
|
2661
|
+
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2662
|
+
/**
|
2663
|
+
* Hook that allows to mutate the CM's edit view layout
|
2664
|
+
* @constant
|
2665
|
+
* @type {string}
|
2666
|
+
*/
|
2667
|
+
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2668
|
+
/**
|
2669
|
+
* Hook that allows to mutate the CM's single types links pre-set filters
|
2670
|
+
* @constant
|
2671
|
+
* @type {string}
|
2672
|
+
*/
|
2673
|
+
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2497
2674
|
};
|
2498
|
-
const
|
2499
|
-
|
2500
|
-
|
2501
|
-
|
2502
|
-
|
2503
|
-
|
2504
|
-
|
2505
|
-
|
2506
|
-
|
2507
|
-
|
2508
|
-
|
2509
|
-
|
2510
|
-
|
2511
|
-
{
|
2512
|
-
|
2513
|
-
|
2514
|
-
|
2515
|
-
|
2516
|
-
|
2517
|
-
|
2518
|
-
}
|
2519
|
-
|
2520
|
-
|
2675
|
+
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2676
|
+
endpoints: (builder) => ({
|
2677
|
+
getContentTypeConfiguration: builder.query({
|
2678
|
+
query: (uid) => ({
|
2679
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
2680
|
+
method: "GET"
|
2681
|
+
}),
|
2682
|
+
transformResponse: (response) => response.data,
|
2683
|
+
providesTags: (_result, _error, uid) => [
|
2684
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
2685
|
+
{ type: "ContentTypeSettings", id: "LIST" }
|
2686
|
+
]
|
2687
|
+
}),
|
2688
|
+
getAllContentTypeSettings: builder.query({
|
2689
|
+
query: () => "/content-manager/content-types-settings",
|
2690
|
+
transformResponse: (response) => response.data,
|
2691
|
+
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2692
|
+
}),
|
2693
|
+
updateContentTypeConfiguration: builder.mutation({
|
2694
|
+
query: ({ uid, ...body }) => ({
|
2695
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
2696
|
+
method: "PUT",
|
2697
|
+
data: body
|
2698
|
+
}),
|
2699
|
+
transformResponse: (response) => response.data,
|
2700
|
+
invalidatesTags: (_result, _error, { uid }) => [
|
2701
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
2702
|
+
{ type: "ContentTypeSettings", id: "LIST" },
|
2703
|
+
// Is this necessary?
|
2704
|
+
{ type: "InitialData" }
|
2705
|
+
]
|
2706
|
+
})
|
2707
|
+
})
|
2708
|
+
});
|
2709
|
+
const {
|
2710
|
+
useGetContentTypeConfigurationQuery,
|
2711
|
+
useGetAllContentTypeSettingsQuery,
|
2712
|
+
useUpdateContentTypeConfigurationMutation
|
2713
|
+
} = contentTypesApi;
|
2714
|
+
const checkIfAttributeIsDisplayable = (attribute) => {
|
2715
|
+
const { type } = attribute;
|
2716
|
+
if (type === "relation") {
|
2717
|
+
return !attribute.relation.toLowerCase().includes("morph");
|
2718
|
+
}
|
2719
|
+
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2720
|
+
};
|
2721
|
+
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2722
|
+
if (!mainFieldName) {
|
2723
|
+
return void 0;
|
2724
|
+
}
|
2725
|
+
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2726
|
+
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2727
|
+
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2728
|
+
);
|
2729
|
+
return {
|
2730
|
+
name: mainFieldName,
|
2731
|
+
type: mainFieldType ?? "string"
|
2732
|
+
};
|
2733
|
+
};
|
2734
|
+
const DEFAULT_SETTINGS = {
|
2735
|
+
bulkable: false,
|
2736
|
+
filterable: false,
|
2737
|
+
searchable: false,
|
2738
|
+
pagination: false,
|
2739
|
+
defaultSortBy: "",
|
2740
|
+
defaultSortOrder: "asc",
|
2741
|
+
mainField: "id",
|
2742
|
+
pageSize: 10
|
2743
|
+
};
|
2744
|
+
const useDocumentLayout = (model) => {
|
2745
|
+
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2746
|
+
const [{ query }] = useQueryParams();
|
2747
|
+
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2748
|
+
const { toggleNotification } = useNotification();
|
2749
|
+
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
2750
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2751
|
+
const {
|
2752
|
+
data,
|
2753
|
+
isLoading: isLoadingConfigs,
|
2754
|
+
error,
|
2755
|
+
isFetching: isFetchingConfigs
|
2756
|
+
} = useGetContentTypeConfigurationQuery(model);
|
2757
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2758
|
+
React.useEffect(() => {
|
2759
|
+
if (error) {
|
2760
|
+
toggleNotification({
|
2761
|
+
type: "danger",
|
2762
|
+
message: formatAPIError(error)
|
2763
|
+
});
|
2764
|
+
}
|
2765
|
+
}, [error, formatAPIError, toggleNotification]);
|
2766
|
+
const editLayout = React.useMemo(
|
2767
|
+
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2768
|
+
layout: [],
|
2769
|
+
components: {},
|
2770
|
+
metadatas: {},
|
2771
|
+
options: {},
|
2772
|
+
settings: DEFAULT_SETTINGS
|
2773
|
+
},
|
2774
|
+
[data, isLoading, schemas, schema, components]
|
2775
|
+
);
|
2776
|
+
const listLayout = React.useMemo(() => {
|
2777
|
+
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2778
|
+
layout: [],
|
2779
|
+
metadatas: {},
|
2780
|
+
options: {},
|
2781
|
+
settings: DEFAULT_SETTINGS
|
2782
|
+
};
|
2783
|
+
}, [data, isLoading, schemas, schema, components]);
|
2784
|
+
const { layout: edit } = React.useMemo(
|
2785
|
+
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2786
|
+
layout: editLayout,
|
2787
|
+
query
|
2788
|
+
}),
|
2789
|
+
[editLayout, query, runHookWaterfall]
|
2790
|
+
);
|
2791
|
+
return {
|
2792
|
+
error,
|
2793
|
+
isLoading,
|
2794
|
+
edit,
|
2795
|
+
list: listLayout
|
2796
|
+
};
|
2797
|
+
};
|
2798
|
+
const useDocLayout = () => {
|
2799
|
+
const { model } = useDoc();
|
2800
|
+
return useDocumentLayout(model);
|
2801
|
+
};
|
2802
|
+
const formatEditLayout = (data, {
|
2803
|
+
schemas,
|
2804
|
+
schema,
|
2805
|
+
components
|
2806
|
+
}) => {
|
2807
|
+
let currentPanelIndex = 0;
|
2808
|
+
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2809
|
+
data.contentType.layouts.edit,
|
2810
|
+
schema?.attributes,
|
2811
|
+
data.contentType.metadatas,
|
2812
|
+
{ configurations: data.components, schemas: components },
|
2813
|
+
schemas
|
2814
|
+
).reduce((panels, row) => {
|
2815
|
+
if (row.some((field) => field.type === "dynamiczone")) {
|
2816
|
+
panels.push([row]);
|
2817
|
+
currentPanelIndex += 2;
|
2818
|
+
} else {
|
2819
|
+
if (!panels[currentPanelIndex]) {
|
2820
|
+
panels.push([]);
|
2821
|
+
}
|
2822
|
+
panels[currentPanelIndex].push(row);
|
2823
|
+
}
|
2824
|
+
return panels;
|
2825
|
+
}, []);
|
2826
|
+
const componentEditAttributes = Object.entries(data.components).reduce(
|
2827
|
+
(acc, [uid, configuration]) => {
|
2828
|
+
acc[uid] = {
|
2829
|
+
layout: convertEditLayoutToFieldLayouts(
|
2830
|
+
configuration.layouts.edit,
|
2831
|
+
components[uid].attributes,
|
2832
|
+
configuration.metadatas,
|
2833
|
+
{ configurations: data.components, schemas: components }
|
2834
|
+
),
|
2835
|
+
settings: {
|
2836
|
+
...configuration.settings,
|
2837
|
+
icon: components[uid].info.icon,
|
2838
|
+
displayName: components[uid].info.displayName
|
2839
|
+
}
|
2840
|
+
};
|
2841
|
+
return acc;
|
2842
|
+
},
|
2843
|
+
{}
|
2844
|
+
);
|
2845
|
+
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2846
|
+
(acc, [attribute, metadata]) => {
|
2847
|
+
return {
|
2848
|
+
...acc,
|
2849
|
+
[attribute]: metadata.edit
|
2850
|
+
};
|
2851
|
+
},
|
2852
|
+
{}
|
2853
|
+
);
|
2854
|
+
return {
|
2855
|
+
layout: panelledEditAttributes,
|
2856
|
+
components: componentEditAttributes,
|
2857
|
+
metadatas: editMetadatas,
|
2858
|
+
settings: {
|
2859
|
+
...data.contentType.settings,
|
2860
|
+
displayName: schema?.info.displayName
|
2861
|
+
},
|
2862
|
+
options: {
|
2863
|
+
...schema?.options,
|
2864
|
+
...schema?.pluginOptions,
|
2865
|
+
...data.contentType.options
|
2866
|
+
}
|
2867
|
+
};
|
2868
|
+
};
|
2869
|
+
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
2870
|
+
return rows.map(
|
2871
|
+
(row) => row.map((field) => {
|
2872
|
+
const attribute = attributes[field.name];
|
2873
|
+
if (!attribute) {
|
2874
|
+
return null;
|
2875
|
+
}
|
2876
|
+
const { edit: metadata } = metadatas[field.name];
|
2877
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
2878
|
+
return {
|
2879
|
+
attribute,
|
2880
|
+
disabled: !metadata.editable,
|
2881
|
+
hint: metadata.description,
|
2882
|
+
label: metadata.label ?? "",
|
2883
|
+
name: field.name,
|
2884
|
+
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
2885
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
2886
|
+
schemas,
|
2887
|
+
components: components?.schemas ?? {}
|
2888
|
+
}),
|
2889
|
+
placeholder: metadata.placeholder ?? "",
|
2890
|
+
required: attribute.required ?? false,
|
2891
|
+
size: field.size,
|
2892
|
+
unique: "unique" in attribute ? attribute.unique : false,
|
2893
|
+
visible: metadata.visible ?? true,
|
2894
|
+
type: attribute.type
|
2895
|
+
};
|
2896
|
+
}).filter((field) => field !== null)
|
2897
|
+
);
|
2898
|
+
};
|
2899
|
+
const formatListLayout = (data, {
|
2900
|
+
schemas,
|
2901
|
+
schema,
|
2902
|
+
components
|
2903
|
+
}) => {
|
2904
|
+
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2905
|
+
(acc, [attribute, metadata]) => {
|
2906
|
+
return {
|
2907
|
+
...acc,
|
2908
|
+
[attribute]: metadata.list
|
2909
|
+
};
|
2910
|
+
},
|
2911
|
+
{}
|
2912
|
+
);
|
2913
|
+
const listAttributes = convertListLayoutToFieldLayouts(
|
2914
|
+
data.contentType.layouts.list,
|
2915
|
+
schema?.attributes,
|
2916
|
+
listMetadatas,
|
2917
|
+
{ configurations: data.components, schemas: components },
|
2918
|
+
schemas
|
2919
|
+
);
|
2920
|
+
return {
|
2921
|
+
layout: listAttributes,
|
2922
|
+
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
2923
|
+
metadatas: listMetadatas,
|
2924
|
+
options: {
|
2925
|
+
...schema?.options,
|
2926
|
+
...schema?.pluginOptions,
|
2927
|
+
...data.contentType.options
|
2928
|
+
}
|
2929
|
+
};
|
2930
|
+
};
|
2931
|
+
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
2932
|
+
return columns.map((name) => {
|
2933
|
+
const attribute = attributes[name];
|
2934
|
+
if (!attribute) {
|
2935
|
+
return null;
|
2936
|
+
}
|
2937
|
+
const metadata = metadatas[name];
|
2938
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
2939
|
+
return {
|
2940
|
+
attribute,
|
2941
|
+
label: metadata.label ?? "",
|
2942
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
2943
|
+
schemas,
|
2944
|
+
components: components?.schemas ?? {}
|
2945
|
+
}),
|
2946
|
+
name,
|
2947
|
+
searchable: metadata.searchable ?? true,
|
2948
|
+
sortable: metadata.sortable ?? true
|
2949
|
+
};
|
2950
|
+
}).filter((field) => field !== null);
|
2951
|
+
};
|
2952
|
+
const ConfirmBulkActionDialog = ({
|
2953
|
+
onToggleDialog,
|
2954
|
+
isOpen = false,
|
2955
|
+
dialogBody,
|
2956
|
+
endAction
|
2957
|
+
}) => {
|
2958
|
+
const { formatMessage } = useIntl();
|
2959
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
2960
|
+
/* @__PURE__ */ jsx(Dialog.Header, { children: formatMessage({
|
2961
|
+
id: "app.components.ConfirmDialog.title",
|
2962
|
+
defaultMessage: "Confirmation"
|
2963
|
+
}) }),
|
2964
|
+
/* @__PURE__ */ jsx(Dialog.Body, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
2965
|
+
/* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
2966
|
+
dialogBody
|
2967
|
+
] }) }),
|
2968
|
+
/* @__PURE__ */ jsxs(Dialog.Footer, { children: [
|
2969
|
+
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { fullWidth: true, onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
|
2970
|
+
id: "app.components.Button.cancel",
|
2971
|
+
defaultMessage: "Cancel"
|
2972
|
+
}) }) }),
|
2973
|
+
endAction
|
2974
|
+
] })
|
2975
|
+
] }) });
|
2976
|
+
};
|
2977
|
+
const BoldChunk$1 = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
|
2978
|
+
const ConfirmDialogPublishAll = ({
|
2979
|
+
isOpen,
|
2980
|
+
onToggleDialog,
|
2981
|
+
isConfirmButtonLoading = false,
|
2982
|
+
onConfirm
|
2983
|
+
}) => {
|
2984
|
+
const { formatMessage } = useIntl();
|
2985
|
+
const selectedEntries = useTable("ConfirmDialogPublishAll", (state) => state.selectedRows);
|
2986
|
+
const { toggleNotification } = useNotification();
|
2987
|
+
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(getTranslation);
|
2988
|
+
const { model, schema } = useDoc();
|
2989
|
+
const [{ query }] = useQueryParams();
|
2990
|
+
const enableDraftRelationsCount = false;
|
2991
|
+
const {
|
2992
|
+
data: countDraftRelations = 0,
|
2993
|
+
isLoading,
|
2994
|
+
error
|
2995
|
+
} = useGetManyDraftRelationCountQuery(
|
2996
|
+
{
|
2997
|
+
model,
|
2998
|
+
documentIds: selectedEntries.map((entry) => entry.documentId),
|
2999
|
+
locale: query?.plugins?.i18n?.locale
|
3000
|
+
},
|
3001
|
+
{
|
3002
|
+
skip: !enableDraftRelationsCount
|
3003
|
+
}
|
3004
|
+
);
|
3005
|
+
React.useEffect(() => {
|
3006
|
+
if (error) {
|
3007
|
+
toggleNotification({ type: "danger", message: formatAPIError(error) });
|
3008
|
+
}
|
3009
|
+
}, [error, formatAPIError, toggleNotification]);
|
3010
|
+
if (error) {
|
3011
|
+
return null;
|
3012
|
+
}
|
3013
|
+
return /* @__PURE__ */ jsx(
|
3014
|
+
ConfirmBulkActionDialog,
|
3015
|
+
{
|
3016
|
+
isOpen: isOpen && !isLoading,
|
3017
|
+
onToggleDialog,
|
3018
|
+
dialogBody: /* @__PURE__ */ jsxs(Fragment, { children: [
|
3019
|
+
/* @__PURE__ */ jsxs(Typography, { id: "confirm-description", textAlign: "center", children: [
|
3020
|
+
countDraftRelations > 0 && formatMessage(
|
3021
|
+
{
|
3022
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
3023
|
+
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. "
|
3024
|
+
},
|
3025
|
+
{
|
3026
|
+
b: BoldChunk$1,
|
3027
|
+
count: countDraftRelations,
|
3028
|
+
entities: selectedEntries.length
|
3029
|
+
}
|
3030
|
+
),
|
3031
|
+
formatMessage({
|
3032
|
+
id: getTranslation("popUpWarning.bodyMessage.contentType.publish.all"),
|
3033
|
+
defaultMessage: "Are you sure you want to publish these entries?"
|
3034
|
+
})
|
3035
|
+
] }),
|
3036
|
+
schema?.pluginOptions && "i18n" in schema.pluginOptions && schema?.pluginOptions.i18n && /* @__PURE__ */ jsx(Typography, { textColor: "danger500", textAlign: "center", children: formatMessage(
|
3037
|
+
{
|
3038
|
+
id: getTranslation("Settings.list.actions.publishAdditionalInfos"),
|
3039
|
+
defaultMessage: "This will publish the active locale versions <em>(from Internationalization)</em>"
|
3040
|
+
},
|
3041
|
+
{
|
3042
|
+
em: Emphasis
|
3043
|
+
}
|
3044
|
+
) })
|
3045
|
+
] }),
|
3046
|
+
endAction: /* @__PURE__ */ jsx(
|
3047
|
+
Button,
|
3048
|
+
{
|
3049
|
+
onClick: onConfirm,
|
3050
|
+
variant: "secondary",
|
3051
|
+
startIcon: /* @__PURE__ */ jsx(Check, {}),
|
3052
|
+
loading: isConfirmButtonLoading,
|
3053
|
+
children: formatMessage({
|
3054
|
+
id: "app.utils.publish",
|
3055
|
+
defaultMessage: "Publish"
|
3056
|
+
})
|
3057
|
+
}
|
3058
|
+
)
|
3059
|
+
}
|
3060
|
+
);
|
3061
|
+
};
|
3062
|
+
const TypographyMaxWidth = styled(Typography)`
|
3063
|
+
max-width: 300px;
|
3064
|
+
`;
|
3065
|
+
const formatErrorMessages = (errors, parentKey, formatMessage) => {
|
3066
|
+
const messages = [];
|
3067
|
+
Object.entries(errors).forEach(([key, value]) => {
|
3068
|
+
const currentKey = parentKey ? `${parentKey}.${key}` : key;
|
3069
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
3070
|
+
if ("id" in value && "defaultMessage" in value) {
|
3071
|
+
messages.push(
|
3072
|
+
formatMessage(
|
3073
|
+
{
|
3074
|
+
id: `${value.id}.withField`,
|
3075
|
+
defaultMessage: value.defaultMessage
|
3076
|
+
},
|
3077
|
+
{ field: currentKey }
|
3078
|
+
)
|
3079
|
+
);
|
3080
|
+
} else {
|
3081
|
+
messages.push(
|
3082
|
+
...formatErrorMessages(
|
3083
|
+
// @ts-expect-error TODO: check why value is not compatible with FormErrors
|
3084
|
+
value,
|
3085
|
+
currentKey,
|
3086
|
+
formatMessage
|
3087
|
+
)
|
3088
|
+
);
|
3089
|
+
}
|
3090
|
+
} else {
|
3091
|
+
messages.push(
|
3092
|
+
formatMessage(
|
3093
|
+
{
|
3094
|
+
id: `${value}.withField`,
|
3095
|
+
defaultMessage: value
|
3096
|
+
},
|
3097
|
+
{ field: currentKey }
|
3098
|
+
)
|
3099
|
+
);
|
3100
|
+
}
|
3101
|
+
});
|
3102
|
+
return messages;
|
3103
|
+
};
|
3104
|
+
const EntryValidationText = ({ validationErrors, status }) => {
|
3105
|
+
const { formatMessage } = useIntl();
|
3106
|
+
if (validationErrors) {
|
3107
|
+
const validationErrorsMessages = formatErrorMessages(validationErrors, "", formatMessage).join(
|
3108
|
+
" "
|
3109
|
+
);
|
3110
|
+
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
3111
|
+
/* @__PURE__ */ jsx(CrossCircle, { fill: "danger600" }),
|
3112
|
+
/* @__PURE__ */ jsx(Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsx(TypographyMaxWidth, { textColor: "danger600", variant: "omega", fontWeight: "semiBold", ellipsis: true, children: validationErrorsMessages }) })
|
3113
|
+
] });
|
3114
|
+
}
|
3115
|
+
if (status === "published") {
|
3116
|
+
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
3117
|
+
/* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
3118
|
+
/* @__PURE__ */ jsx(Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
|
3119
|
+
id: "content-manager.bulk-publish.already-published",
|
3120
|
+
defaultMessage: "Already Published"
|
3121
|
+
}) })
|
3122
|
+
] });
|
3123
|
+
}
|
3124
|
+
if (status === "modified") {
|
3125
|
+
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
3126
|
+
/* @__PURE__ */ jsx(ArrowsCounterClockwise, { fill: "alternative600" }),
|
3127
|
+
/* @__PURE__ */ jsx(Typography, { children: formatMessage({
|
3128
|
+
id: "content-manager.bulk-publish.modified",
|
3129
|
+
defaultMessage: "Ready to publish changes"
|
3130
|
+
}) })
|
3131
|
+
] });
|
3132
|
+
}
|
3133
|
+
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
3134
|
+
/* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
3135
|
+
/* @__PURE__ */ jsx(Typography, { children: formatMessage({
|
3136
|
+
id: "app.utils.ready-to-publish",
|
3137
|
+
defaultMessage: "Ready to publish"
|
3138
|
+
}) })
|
3139
|
+
] });
|
3140
|
+
};
|
3141
|
+
const TABLE_HEADERS = [
|
3142
|
+
{ name: "id", label: "id" },
|
3143
|
+
{ name: "name", label: "name" },
|
3144
|
+
{ name: "status", label: "status" },
|
3145
|
+
{ name: "publicationStatus", label: "Publication status" }
|
3146
|
+
];
|
3147
|
+
const SelectedEntriesTableContent = ({
|
3148
|
+
isPublishing,
|
3149
|
+
rowsToDisplay = [],
|
3150
|
+
entriesToPublish = [],
|
3151
|
+
validationErrors = {}
|
3152
|
+
}) => {
|
3153
|
+
const { pathname } = useLocation();
|
3154
|
+
const { formatMessage } = useIntl();
|
3155
|
+
const {
|
3156
|
+
list: {
|
3157
|
+
settings: { mainField }
|
3158
|
+
}
|
3159
|
+
} = useDocLayout();
|
3160
|
+
const shouldDisplayMainField = mainField != null && mainField !== "id";
|
3161
|
+
return /* @__PURE__ */ jsxs(Table.Content, { children: [
|
3162
|
+
/* @__PURE__ */ jsxs(Table.Head, { children: [
|
3163
|
+
/* @__PURE__ */ jsx(Table.HeaderCheckboxCell, {}),
|
3164
|
+
TABLE_HEADERS.filter((head) => head.name !== "name" || shouldDisplayMainField).map(
|
3165
|
+
(head) => /* @__PURE__ */ jsx(Table.HeaderCell, { ...head }, head.name)
|
3166
|
+
)
|
3167
|
+
] }),
|
3168
|
+
/* @__PURE__ */ jsx(Table.Loading, {}),
|
3169
|
+
/* @__PURE__ */ jsx(Table.Body, { children: rowsToDisplay.map((row, index2) => /* @__PURE__ */ jsxs(Table.Row, { children: [
|
3170
|
+
/* @__PURE__ */ jsx(Table.CheckboxCell, { id: row.id }),
|
3171
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Typography, { children: row.id }) }),
|
3172
|
+
shouldDisplayMainField && /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Typography, { children: row[mainField] }) }),
|
3173
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(DocumentStatus, { status: row.status, maxWidth: "min-content" }) }),
|
3174
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: isPublishing && entriesToPublish.includes(row.documentId) ? /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
3175
|
+
/* @__PURE__ */ jsx(Typography, { children: formatMessage({
|
3176
|
+
id: "content-manager.success.record.publishing",
|
3177
|
+
defaultMessage: "Publishing..."
|
3178
|
+
}) }),
|
3179
|
+
/* @__PURE__ */ jsx(Loader, { small: true })
|
3180
|
+
] }) : /* @__PURE__ */ jsx(
|
3181
|
+
EntryValidationText,
|
3182
|
+
{
|
3183
|
+
validationErrors: validationErrors[row.documentId],
|
3184
|
+
status: row.status
|
3185
|
+
}
|
3186
|
+
) }),
|
3187
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
|
3188
|
+
IconButton,
|
3189
|
+
{
|
3190
|
+
tag: Link,
|
3191
|
+
to: {
|
3192
|
+
pathname: `${pathname}/${row.documentId}`,
|
3193
|
+
search: row.locale && `?plugins[i18n][locale]=${row.locale}`
|
3194
|
+
},
|
3195
|
+
state: { from: pathname },
|
3196
|
+
label: formatMessage(
|
3197
|
+
{ id: "app.component.HelperPluginTable.edit", defaultMessage: "Edit {target}" },
|
3198
|
+
{
|
3199
|
+
target: formatMessage(
|
3200
|
+
{
|
3201
|
+
id: "content-manager.components.ListViewHelperPluginTable.row-line",
|
3202
|
+
defaultMessage: "item line {number}"
|
3203
|
+
},
|
3204
|
+
{ number: index2 + 1 }
|
3205
|
+
)
|
3206
|
+
}
|
3207
|
+
),
|
3208
|
+
target: "_blank",
|
3209
|
+
marginLeft: "auto",
|
3210
|
+
variant: "ghost",
|
3211
|
+
children: /* @__PURE__ */ jsx(Pencil, { width: "1.6rem", height: "1.6rem" })
|
3212
|
+
}
|
3213
|
+
) }) })
|
3214
|
+
] }, row.id)) })
|
3215
|
+
] });
|
3216
|
+
};
|
3217
|
+
const BoldChunk = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
|
3218
|
+
const SelectedEntriesModalContent = ({
|
3219
|
+
listViewSelectedEntries,
|
3220
|
+
toggleModal,
|
3221
|
+
setListViewSelectedDocuments,
|
3222
|
+
model
|
3223
|
+
}) => {
|
3224
|
+
const { formatMessage } = useIntl();
|
3225
|
+
const { schema, components } = useContentTypeSchema(model);
|
3226
|
+
const documentIds = listViewSelectedEntries.map(({ documentId }) => documentId);
|
3227
|
+
const [{ query }] = useQueryParams();
|
3228
|
+
const params = React.useMemo(() => buildValidParams(query), [query]);
|
3229
|
+
const { data, isLoading, isFetching, refetch } = useGetAllDocumentsQuery(
|
3230
|
+
{
|
3231
|
+
model,
|
3232
|
+
params: {
|
3233
|
+
page: "1",
|
3234
|
+
pageSize: documentIds.length.toString(),
|
3235
|
+
sort: query.sort,
|
3236
|
+
filters: {
|
3237
|
+
documentId: {
|
3238
|
+
$in: documentIds
|
3239
|
+
}
|
3240
|
+
},
|
3241
|
+
locale: query.plugins?.i18n?.locale
|
3242
|
+
}
|
3243
|
+
},
|
3244
|
+
{
|
3245
|
+
selectFromResult: ({ data: data2, ...restRes }) => ({ data: data2?.results ?? [], ...restRes })
|
3246
|
+
}
|
3247
|
+
);
|
3248
|
+
const { rows, validationErrors } = React.useMemo(() => {
|
3249
|
+
if (data.length > 0 && schema) {
|
3250
|
+
const validate = createYupSchema(
|
3251
|
+
schema.attributes,
|
3252
|
+
components,
|
3253
|
+
// Since this is the "Publish" action, the validation
|
3254
|
+
// schema must enforce the rules for published entities
|
3255
|
+
{ status: "published" }
|
3256
|
+
);
|
3257
|
+
const validationErrors2 = {};
|
3258
|
+
const rows2 = data.map((entry) => {
|
3259
|
+
try {
|
3260
|
+
validate.validateSync(entry, { abortEarly: false });
|
3261
|
+
return entry;
|
3262
|
+
} catch (e) {
|
3263
|
+
if (e instanceof ValidationError) {
|
3264
|
+
validationErrors2[entry.documentId] = getYupValidationErrors(e);
|
3265
|
+
}
|
3266
|
+
return entry;
|
3267
|
+
}
|
3268
|
+
});
|
3269
|
+
return { rows: rows2, validationErrors: validationErrors2 };
|
3270
|
+
}
|
3271
|
+
return {
|
3272
|
+
rows: [],
|
3273
|
+
validationErrors: {}
|
3274
|
+
};
|
3275
|
+
}, [components, data, schema]);
|
3276
|
+
const [publishedCount, setPublishedCount] = React.useState(0);
|
3277
|
+
const [isDialogOpen, setIsDialogOpen] = React.useState(false);
|
3278
|
+
const { publishMany: bulkPublishAction } = useDocumentActions();
|
3279
|
+
const [, { isLoading: isSubmittingForm }] = usePublishManyDocumentsMutation();
|
3280
|
+
const selectedRows = useTable("publishAction", (state) => state.selectedRows);
|
3281
|
+
const selectedEntries = rows.filter(
|
3282
|
+
(entry) => selectedRows.some((selectedEntry) => selectedEntry.documentId === entry.documentId)
|
3283
|
+
);
|
3284
|
+
const entriesToPublish = selectedEntries.filter((entry) => !validationErrors[entry.documentId]).map((entry) => entry.documentId);
|
3285
|
+
const selectedEntriesWithErrorsCount = selectedEntries.filter(
|
3286
|
+
({ documentId }) => validationErrors[documentId]
|
3287
|
+
).length;
|
3288
|
+
const selectedEntriesPublished = selectedEntries.filter(
|
3289
|
+
({ status }) => status === "published"
|
3290
|
+
).length;
|
3291
|
+
const selectedEntriesWithNoErrorsCount = selectedEntries.length - selectedEntriesWithErrorsCount - selectedEntriesPublished;
|
3292
|
+
const toggleDialog = () => setIsDialogOpen((prev) => !prev);
|
3293
|
+
const handleConfirmBulkPublish = async () => {
|
3294
|
+
toggleDialog();
|
3295
|
+
const res = await bulkPublishAction({ model, documentIds: entriesToPublish, params });
|
3296
|
+
if (!("error" in res)) {
|
3297
|
+
setPublishedCount(res.count);
|
3298
|
+
const unpublishedEntries = rows.filter((row) => {
|
3299
|
+
return !entriesToPublish.includes(row.documentId);
|
3300
|
+
});
|
3301
|
+
setListViewSelectedDocuments(unpublishedEntries);
|
3302
|
+
}
|
3303
|
+
};
|
3304
|
+
const getFormattedCountMessage = () => {
|
3305
|
+
if (publishedCount) {
|
3306
|
+
return formatMessage(
|
3307
|
+
{
|
3308
|
+
id: getTranslation("containers.list.selectedEntriesModal.publishedCount"),
|
3309
|
+
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."
|
3310
|
+
},
|
3311
|
+
{
|
3312
|
+
publishedCount,
|
3313
|
+
withErrorsCount: selectedEntriesWithErrorsCount,
|
3314
|
+
b: BoldChunk
|
3315
|
+
}
|
3316
|
+
);
|
3317
|
+
}
|
3318
|
+
return formatMessage(
|
3319
|
+
{
|
3320
|
+
id: getTranslation("containers.list.selectedEntriesModal.selectedCount"),
|
3321
|
+
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."
|
3322
|
+
},
|
3323
|
+
{
|
3324
|
+
readyToPublishCount: selectedEntriesWithNoErrorsCount,
|
3325
|
+
withErrorsCount: selectedEntriesWithErrorsCount,
|
3326
|
+
alreadyPublishedCount: selectedEntriesPublished,
|
3327
|
+
b: BoldChunk
|
3328
|
+
}
|
3329
|
+
);
|
3330
|
+
};
|
3331
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
3332
|
+
/* @__PURE__ */ jsxs(Modal.Body, { children: [
|
3333
|
+
/* @__PURE__ */ jsx(Typography, { children: getFormattedCountMessage() }),
|
3334
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 5, children: /* @__PURE__ */ jsx(
|
3335
|
+
SelectedEntriesTableContent,
|
3336
|
+
{
|
3337
|
+
isPublishing: isSubmittingForm,
|
3338
|
+
rowsToDisplay: rows,
|
3339
|
+
entriesToPublish,
|
3340
|
+
validationErrors
|
3341
|
+
}
|
3342
|
+
) })
|
3343
|
+
] }),
|
3344
|
+
/* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
3345
|
+
/* @__PURE__ */ jsx(Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
|
3346
|
+
id: "app.components.Button.cancel",
|
3347
|
+
defaultMessage: "Cancel"
|
3348
|
+
}) }),
|
3349
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
3350
|
+
/* @__PURE__ */ jsx(Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
|
3351
|
+
/* @__PURE__ */ jsx(
|
3352
|
+
Button,
|
3353
|
+
{
|
3354
|
+
onClick: toggleDialog,
|
3355
|
+
disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
|
3356
|
+
loading: isSubmittingForm,
|
3357
|
+
children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
|
3358
|
+
}
|
3359
|
+
)
|
3360
|
+
] })
|
3361
|
+
] }),
|
3362
|
+
/* @__PURE__ */ jsx(
|
3363
|
+
ConfirmDialogPublishAll,
|
3364
|
+
{
|
3365
|
+
isOpen: isDialogOpen,
|
3366
|
+
onToggleDialog: toggleDialog,
|
3367
|
+
isConfirmButtonLoading: isSubmittingForm,
|
3368
|
+
onConfirm: handleConfirmBulkPublish
|
3369
|
+
}
|
3370
|
+
)
|
3371
|
+
] });
|
3372
|
+
};
|
3373
|
+
const PublishAction = ({ documents, model }) => {
|
3374
|
+
const { formatMessage } = useIntl();
|
3375
|
+
const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
|
3376
|
+
const showPublishButton = hasPublishPermission && documents.some(({ status }) => status !== "published");
|
3377
|
+
const setListViewSelectedDocuments = useTable("publishAction", (state) => state.selectRow);
|
3378
|
+
const refetchList = () => {
|
3379
|
+
contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
|
3380
|
+
};
|
3381
|
+
if (!showPublishButton)
|
3382
|
+
return null;
|
3383
|
+
return {
|
3384
|
+
actionType: "publish",
|
3385
|
+
variant: "tertiary",
|
3386
|
+
label: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" }),
|
3387
|
+
dialog: {
|
3388
|
+
type: "modal",
|
3389
|
+
title: formatMessage({
|
3390
|
+
id: getTranslation("containers.ListPage.selectedEntriesModal.title"),
|
3391
|
+
defaultMessage: "Publish entries"
|
3392
|
+
}),
|
3393
|
+
content: ({ onClose }) => {
|
3394
|
+
return /* @__PURE__ */ jsx(Table.Root, { rows: documents, defaultSelectedRows: documents, headers: TABLE_HEADERS, children: /* @__PURE__ */ jsx(
|
3395
|
+
SelectedEntriesModalContent,
|
3396
|
+
{
|
3397
|
+
listViewSelectedEntries: documents,
|
3398
|
+
toggleModal: () => {
|
3399
|
+
onClose();
|
3400
|
+
refetchList();
|
3401
|
+
},
|
3402
|
+
setListViewSelectedDocuments,
|
3403
|
+
model
|
3404
|
+
}
|
3405
|
+
) });
|
3406
|
+
},
|
3407
|
+
onClose: () => {
|
3408
|
+
refetchList();
|
3409
|
+
}
|
3410
|
+
}
|
3411
|
+
};
|
3412
|
+
};
|
3413
|
+
const BulkActionsRenderer = () => {
|
3414
|
+
const plugins = useStrapiApp("BulkActionsRenderer", (state) => state.plugins);
|
3415
|
+
const { model, collectionType } = useDoc();
|
3416
|
+
const { selectedRows } = useTable("BulkActionsRenderer", (state) => state);
|
3417
|
+
return /* @__PURE__ */ jsx(Flex, { gap: 2, children: /* @__PURE__ */ jsx(
|
3418
|
+
DescriptionComponentRenderer,
|
3419
|
+
{
|
3420
|
+
props: {
|
3421
|
+
model,
|
3422
|
+
collectionType,
|
3423
|
+
documents: selectedRows
|
3424
|
+
},
|
3425
|
+
descriptions: plugins["content-manager"].apis.getBulkActions(),
|
3426
|
+
children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsx(DocumentActionButton, { ...action }, action.id))
|
3427
|
+
}
|
3428
|
+
) });
|
3429
|
+
};
|
3430
|
+
const DeleteAction = ({ documents, model }) => {
|
3431
|
+
const { formatMessage } = useIntl();
|
3432
|
+
const { schema: contentType } = useDoc();
|
3433
|
+
const selectRow = useTable("DeleteAction", (state) => state.selectRow);
|
3434
|
+
const hasI18nEnabled = Boolean(contentType?.pluginOptions?.i18n);
|
3435
|
+
const [{ query }] = useQueryParams();
|
3436
|
+
const params = React.useMemo(() => buildValidParams(query), [query]);
|
3437
|
+
const hasDeletePermission = useDocumentRBAC("deleteAction", (state) => state.canDelete);
|
3438
|
+
const { deleteMany: bulkDeleteAction } = useDocumentActions();
|
3439
|
+
const documentIds = documents.map(({ documentId }) => documentId);
|
3440
|
+
const handleConfirmBulkDelete = async () => {
|
3441
|
+
const res = await bulkDeleteAction({
|
3442
|
+
documentIds,
|
3443
|
+
model,
|
3444
|
+
params
|
3445
|
+
});
|
3446
|
+
if (!("error" in res)) {
|
3447
|
+
selectRow([]);
|
3448
|
+
}
|
3449
|
+
};
|
3450
|
+
if (!hasDeletePermission)
|
3451
|
+
return null;
|
3452
|
+
return {
|
3453
|
+
variant: "danger-light",
|
3454
|
+
label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
|
3455
|
+
dialog: {
|
3456
|
+
type: "dialog",
|
3457
|
+
title: formatMessage({
|
3458
|
+
id: "app.components.ConfirmDialog.title",
|
3459
|
+
defaultMessage: "Confirmation"
|
3460
|
+
}),
|
3461
|
+
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3462
|
+
/* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3463
|
+
/* @__PURE__ */ jsx(Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
|
3464
|
+
id: "popUpWarning.bodyMessage.contentType.delete.all",
|
3465
|
+
defaultMessage: "Are you sure you want to delete these entries?"
|
3466
|
+
}) }),
|
3467
|
+
hasI18nEnabled && /* @__PURE__ */ jsx(Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsx(Typography, { textColor: "danger500", children: formatMessage(
|
3468
|
+
{
|
3469
|
+
id: getTranslation("Settings.list.actions.deleteAdditionalInfos"),
|
3470
|
+
defaultMessage: "This will delete the active locale versions <em>(from Internationalization)</em>"
|
3471
|
+
},
|
3472
|
+
{
|
3473
|
+
em: Emphasis
|
3474
|
+
}
|
3475
|
+
) }) })
|
3476
|
+
] }),
|
3477
|
+
onConfirm: handleConfirmBulkDelete
|
3478
|
+
}
|
3479
|
+
};
|
3480
|
+
};
|
3481
|
+
DeleteAction.type = "delete";
|
3482
|
+
const UnpublishAction = ({ documents, model }) => {
|
3483
|
+
const { formatMessage } = useIntl();
|
3484
|
+
const { schema } = useDoc();
|
3485
|
+
const selectRow = useTable("UnpublishAction", (state) => state.selectRow);
|
3486
|
+
const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
|
3487
|
+
const hasI18nEnabled = Boolean(schema?.pluginOptions?.i18n);
|
3488
|
+
const hasDraftAndPublishEnabled = Boolean(schema?.options?.draftAndPublish);
|
3489
|
+
const { unpublishMany: bulkUnpublishAction } = useDocumentActions();
|
3490
|
+
const documentIds = documents.map(({ documentId }) => documentId);
|
3491
|
+
const [{ query }] = useQueryParams();
|
3492
|
+
const params = React.useMemo(() => buildValidParams(query), [query]);
|
3493
|
+
const handleConfirmBulkUnpublish = async () => {
|
3494
|
+
const data = await bulkUnpublishAction({ documentIds, model, params });
|
3495
|
+
if (!("error" in data)) {
|
3496
|
+
selectRow([]);
|
3497
|
+
}
|
3498
|
+
};
|
3499
|
+
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
|
3500
|
+
if (!showUnpublishButton)
|
3501
|
+
return null;
|
3502
|
+
return {
|
3503
|
+
variant: "tertiary",
|
3504
|
+
label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
|
3505
|
+
dialog: {
|
3506
|
+
type: "dialog",
|
3507
|
+
title: formatMessage({
|
3508
|
+
id: "app.components.ConfirmDialog.title",
|
3509
|
+
defaultMessage: "Confirmation"
|
3510
|
+
}),
|
3511
|
+
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3512
|
+
/* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3513
|
+
/* @__PURE__ */ jsx(Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
|
3514
|
+
id: "popUpWarning.bodyMessage.contentType.unpublish.all",
|
3515
|
+
defaultMessage: "Are you sure you want to unpublish these entries?"
|
3516
|
+
}) }),
|
3517
|
+
hasI18nEnabled && /* @__PURE__ */ jsx(Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsx(Typography, { textColor: "danger500", children: formatMessage(
|
3518
|
+
{
|
3519
|
+
id: getTranslation("Settings.list.actions.unpublishAdditionalInfos"),
|
3520
|
+
defaultMessage: "This will unpublish the active locale versions <em>(from Internationalization)</em>"
|
3521
|
+
},
|
3522
|
+
{
|
3523
|
+
em: Emphasis
|
3524
|
+
}
|
3525
|
+
) }) })
|
3526
|
+
] }),
|
3527
|
+
confirmButton: formatMessage({
|
3528
|
+
id: "app.utils.unpublish",
|
3529
|
+
defaultMessage: "Unpublish"
|
3530
|
+
}),
|
3531
|
+
onConfirm: handleConfirmBulkUnpublish
|
3532
|
+
}
|
3533
|
+
};
|
3534
|
+
};
|
3535
|
+
UnpublishAction.type = "unpublish";
|
3536
|
+
const Emphasis = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold", textColor: "danger500", children: chunks });
|
3537
|
+
const DEFAULT_BULK_ACTIONS = [PublishAction, UnpublishAction, DeleteAction];
|
3538
|
+
const AutoCloneFailureModalBody = ({ prohibitedFields }) => {
|
3539
|
+
const { formatMessage } = useIntl();
|
3540
|
+
const getDefaultErrorMessage = (reason) => {
|
3541
|
+
switch (reason) {
|
3542
|
+
case "relation":
|
3543
|
+
return "Duplicating the relation could remove it from the original entry.";
|
3544
|
+
case "unique":
|
3545
|
+
return "Identical values in a unique field are not allowed";
|
3546
|
+
default:
|
3547
|
+
return reason;
|
3548
|
+
}
|
3549
|
+
};
|
3550
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
3551
|
+
/* @__PURE__ */ jsx(Typography, { variant: "beta", children: formatMessage({
|
3552
|
+
id: getTranslation("containers.list.autoCloneModal.title"),
|
3553
|
+
defaultMessage: "This entry can't be duplicated directly."
|
3554
|
+
}) }),
|
3555
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 2, children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: formatMessage({
|
3556
|
+
id: getTranslation("containers.list.autoCloneModal.description"),
|
3557
|
+
defaultMessage: "A new entry will be created with the same content, but you'll have to change the following fields to save it."
|
3558
|
+
}) }) }),
|
3559
|
+
/* @__PURE__ */ jsx(Flex, { marginTop: 6, gap: 2, direction: "column", alignItems: "stretch", children: prohibitedFields.map(([fieldPath, reason]) => /* @__PURE__ */ jsxs(
|
3560
|
+
Flex,
|
3561
|
+
{
|
3562
|
+
direction: "column",
|
3563
|
+
gap: 2,
|
3564
|
+
alignItems: "flex-start",
|
3565
|
+
borderColor: "neutral200",
|
3566
|
+
hasRadius: true,
|
3567
|
+
padding: 6,
|
3568
|
+
children: [
|
3569
|
+
/* @__PURE__ */ jsx(Flex, { direction: "row", tag: "ol", children: fieldPath.map((pathSegment, index2) => /* @__PURE__ */ jsxs(Typography, { fontWeight: "semiBold", tag: "li", children: [
|
3570
|
+
pathSegment,
|
3571
|
+
index2 !== fieldPath.length - 1 && /* @__PURE__ */ jsx(
|
3572
|
+
ChevronRight,
|
3573
|
+
{
|
3574
|
+
fill: "neutral500",
|
3575
|
+
height: "0.8rem",
|
3576
|
+
width: "0.8rem",
|
3577
|
+
style: { margin: "0 0.8rem" }
|
3578
|
+
}
|
3579
|
+
)
|
3580
|
+
] }, index2)) }),
|
3581
|
+
/* @__PURE__ */ jsx(Typography, { tag: "p", textColor: "neutral600", children: formatMessage({
|
3582
|
+
id: getTranslation(`containers.list.autoCloneModal.error.${reason}`),
|
3583
|
+
defaultMessage: getDefaultErrorMessage(reason)
|
3584
|
+
}) })
|
3585
|
+
]
|
3586
|
+
},
|
3587
|
+
fieldPath.join()
|
3588
|
+
)) })
|
3589
|
+
] });
|
3590
|
+
};
|
3591
|
+
const TableActions = ({ document }) => {
|
3592
|
+
const { formatMessage } = useIntl();
|
3593
|
+
const { model, collectionType } = useDoc();
|
3594
|
+
const plugins = useStrapiApp("TableActions", (state) => state.plugins);
|
3595
|
+
const props = {
|
3596
|
+
activeTab: null,
|
3597
|
+
model,
|
3598
|
+
documentId: document.documentId,
|
3599
|
+
collectionType,
|
3600
|
+
document
|
3601
|
+
};
|
3602
|
+
return /* @__PURE__ */ jsx(
|
3603
|
+
DescriptionComponentRenderer,
|
3604
|
+
{
|
3605
|
+
props,
|
3606
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
3607
|
+
children: (actions2) => {
|
3608
|
+
const tableRowActions = actions2.filter((action) => {
|
3609
|
+
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
3610
|
+
return positions.includes("table-row");
|
3611
|
+
});
|
3612
|
+
return /* @__PURE__ */ jsx(
|
3613
|
+
DocumentActionsMenu,
|
2521
3614
|
{
|
2522
3615
|
actions: tableRowActions,
|
2523
3616
|
label: formatMessage({
|
@@ -2621,7 +3714,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
2621
3714
|
}),
|
2622
3715
|
content: /* @__PURE__ */ jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
2623
3716
|
footer: ({ onClose }) => {
|
2624
|
-
return /* @__PURE__ */ jsxs(
|
3717
|
+
return /* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
2625
3718
|
/* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
2626
3719
|
id: "cancel",
|
2627
3720
|
defaultMessage: "Cancel"
|
@@ -2629,7 +3722,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
2629
3722
|
/* @__PURE__ */ jsx(
|
2630
3723
|
LinkButton,
|
2631
3724
|
{
|
2632
|
-
|
3725
|
+
tag: NavLink,
|
2633
3726
|
to: {
|
2634
3727
|
pathname: `clone/${documentId}`
|
2635
3728
|
},
|
@@ -2662,442 +3755,183 @@ class ContentManagerPlugin {
|
|
2662
3755
|
documentActions = [
|
2663
3756
|
...DEFAULT_ACTIONS,
|
2664
3757
|
...DEFAULT_TABLE_ROW_ACTIONS,
|
2665
|
-
...DEFAULT_HEADER_ACTIONS
|
2666
|
-
HistoryAction
|
3758
|
+
...DEFAULT_HEADER_ACTIONS
|
2667
3759
|
];
|
2668
3760
|
editViewSidePanels = [ActionsPanel];
|
2669
3761
|
headerActions = [];
|
2670
3762
|
constructor() {
|
2671
3763
|
}
|
2672
3764
|
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);
|
3765
|
+
if (Array.isArray(panels)) {
|
3766
|
+
this.editViewSidePanels = [...this.editViewSidePanels, ...panels];
|
3767
|
+
} else if (typeof panels === "function") {
|
3768
|
+
this.editViewSidePanels = panels(this.editViewSidePanels);
|
2703
3769
|
} else {
|
2704
3770
|
throw new Error(
|
2705
|
-
`Expected the \`
|
2706
|
-
|
3771
|
+
`Expected the \`panels\` passed to \`addEditViewSidePanel\` to be an array or a function, but received ${getPrintableType(
|
3772
|
+
panels
|
2707
3773
|
)}`
|
2708
3774
|
);
|
2709
3775
|
}
|
2710
3776
|
}
|
2711
|
-
|
3777
|
+
addDocumentAction(actions2) {
|
2712
3778
|
if (Array.isArray(actions2)) {
|
2713
|
-
this.
|
3779
|
+
this.documentActions = [...this.documentActions, ...actions2];
|
2714
3780
|
} else if (typeof actions2 === "function") {
|
2715
|
-
this.
|
3781
|
+
this.documentActions = actions2(this.documentActions);
|
2716
3782
|
} else {
|
2717
3783
|
throw new Error(
|
2718
|
-
`Expected the \`actions\` passed to \`
|
3784
|
+
`Expected the \`actions\` passed to \`addDocumentAction\` to be an array or a function, but received ${getPrintableType(
|
2719
3785
|
actions2
|
2720
|
-
)}`
|
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;
|
3786
|
+
)}`
|
3787
|
+
);
|
3788
|
+
}
|
3789
|
+
}
|
3790
|
+
addDocumentHeaderAction(actions2) {
|
3791
|
+
if (Array.isArray(actions2)) {
|
3792
|
+
this.headerActions = [...this.headerActions, ...actions2];
|
3793
|
+
} else if (typeof actions2 === "function") {
|
3794
|
+
this.headerActions = actions2(this.headerActions);
|
2960
3795
|
} else {
|
2961
|
-
|
2962
|
-
|
2963
|
-
|
2964
|
-
|
3796
|
+
throw new Error(
|
3797
|
+
`Expected the \`actions\` passed to \`addDocumentHeaderAction\` to be an array or a function, but received ${getPrintableType(
|
3798
|
+
actions2
|
3799
|
+
)}`
|
3800
|
+
);
|
2965
3801
|
}
|
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
|
3802
|
+
}
|
3803
|
+
addBulkAction(actions2) {
|
3804
|
+
if (Array.isArray(actions2)) {
|
3805
|
+
this.bulkActions = [...this.bulkActions, ...actions2];
|
3806
|
+
} else if (typeof actions2 === "function") {
|
3807
|
+
this.bulkActions = actions2(this.bulkActions);
|
3808
|
+
} else {
|
3809
|
+
throw new Error(
|
3810
|
+
`Expected the \`actions\` passed to \`addBulkAction\` to be an array or a function, but received ${getPrintableType(
|
3811
|
+
actions2
|
3812
|
+
)}`
|
3813
|
+
);
|
3007
3814
|
}
|
3008
|
-
}
|
3009
|
-
|
3010
|
-
|
3011
|
-
|
3012
|
-
|
3013
|
-
|
3014
|
-
|
3015
|
-
|
3815
|
+
}
|
3816
|
+
get config() {
|
3817
|
+
return {
|
3818
|
+
id: PLUGIN_ID,
|
3819
|
+
name: "Content Manager",
|
3820
|
+
injectionZones: INJECTION_ZONES,
|
3821
|
+
apis: {
|
3822
|
+
addBulkAction: this.addBulkAction.bind(this),
|
3823
|
+
addDocumentAction: this.addDocumentAction.bind(this),
|
3824
|
+
addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
|
3825
|
+
addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
|
3826
|
+
getBulkActions: () => this.bulkActions,
|
3827
|
+
getDocumentActions: () => this.documentActions,
|
3828
|
+
getEditViewSidePanels: () => this.editViewSidePanels,
|
3829
|
+
getHeaderActions: () => this.headerActions
|
3016
3830
|
}
|
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
|
-
);
|
3831
|
+
};
|
3832
|
+
}
|
3833
|
+
}
|
3834
|
+
const getPrintableType = (value) => {
|
3835
|
+
const nativeType = typeof value;
|
3836
|
+
if (nativeType === "object") {
|
3837
|
+
if (value === null)
|
3838
|
+
return "null";
|
3839
|
+
if (Array.isArray(value))
|
3840
|
+
return "array";
|
3841
|
+
if (value instanceof Object && value.constructor.name !== "Object") {
|
3842
|
+
return value.constructor.name;
|
3843
|
+
}
|
3844
|
+
}
|
3845
|
+
return nativeType;
|
3039
3846
|
};
|
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
|
-
);
|
3847
|
+
const HistoryAction = ({ model, document }) => {
|
3848
|
+
const { formatMessage } = useIntl();
|
3849
|
+
const [{ query }] = useQueryParams();
|
3850
|
+
const navigate = useNavigate();
|
3851
|
+
const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
|
3852
|
+
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3853
|
+
return null;
|
3854
|
+
}
|
3061
3855
|
return {
|
3062
|
-
|
3063
|
-
|
3064
|
-
|
3065
|
-
|
3066
|
-
|
3067
|
-
|
3068
|
-
|
3069
|
-
|
3856
|
+
icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
|
3857
|
+
label: formatMessage({
|
3858
|
+
id: "content-manager.history.document-action",
|
3859
|
+
defaultMessage: "Content History"
|
3860
|
+
}),
|
3861
|
+
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
3862
|
+
disabled: (
|
3863
|
+
/**
|
3864
|
+
* The user is creating a new document.
|
3865
|
+
* It hasn't been saved yet, so there's no history to go to
|
3866
|
+
*/
|
3867
|
+
!document || /**
|
3868
|
+
* The document has been created but the current dimension has never been saved.
|
3869
|
+
* For example, the user is creating a new locale in an existing document,
|
3870
|
+
* so there's no history for the document in that locale
|
3871
|
+
*/
|
3872
|
+
!document.id || /**
|
3873
|
+
* History is only available for content types created by the user.
|
3874
|
+
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
3875
|
+
* which start with `admin::` or `plugin::`
|
3876
|
+
*/
|
3877
|
+
!model.startsWith("api::")
|
3878
|
+
),
|
3879
|
+
position: "header"
|
3070
3880
|
};
|
3071
3881
|
};
|
3072
|
-
|
3073
|
-
|
3074
|
-
|
3075
|
-
|
3076
|
-
|
3077
|
-
|
3078
|
-
|
3079
|
-
|
3080
|
-
|
3081
|
-
|
3082
|
-
|
3083
|
-
|
3084
|
-
|
3085
|
-
|
3086
|
-
|
3087
|
-
|
3088
|
-
|
3089
|
-
|
3090
|
-
};
|
3091
|
-
}).filter((field) => field !== null);
|
3882
|
+
HistoryAction.type = "history";
|
3883
|
+
const historyAdmin = {
|
3884
|
+
bootstrap(app) {
|
3885
|
+
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
3886
|
+
addDocumentAction((actions2) => {
|
3887
|
+
const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
|
3888
|
+
actions2.splice(indexOfDeleteAction, 0, HistoryAction);
|
3889
|
+
return actions2;
|
3890
|
+
});
|
3891
|
+
}
|
3892
|
+
};
|
3893
|
+
const initialState = {
|
3894
|
+
collectionTypeLinks: [],
|
3895
|
+
components: [],
|
3896
|
+
fieldSizes: {},
|
3897
|
+
models: [],
|
3898
|
+
singleTypeLinks: [],
|
3899
|
+
isLoading: true
|
3092
3900
|
};
|
3901
|
+
const appSlice = createSlice({
|
3902
|
+
name: "app",
|
3903
|
+
initialState,
|
3904
|
+
reducers: {
|
3905
|
+
setInitialData(state, action) {
|
3906
|
+
const {
|
3907
|
+
authorizedCollectionTypeLinks,
|
3908
|
+
authorizedSingleTypeLinks,
|
3909
|
+
components,
|
3910
|
+
contentTypeSchemas,
|
3911
|
+
fieldSizes
|
3912
|
+
} = action.payload;
|
3913
|
+
state.collectionTypeLinks = authorizedCollectionTypeLinks.filter(
|
3914
|
+
({ isDisplayed }) => isDisplayed
|
3915
|
+
);
|
3916
|
+
state.singleTypeLinks = authorizedSingleTypeLinks.filter(({ isDisplayed }) => isDisplayed);
|
3917
|
+
state.components = components;
|
3918
|
+
state.models = contentTypeSchemas;
|
3919
|
+
state.fieldSizes = fieldSizes;
|
3920
|
+
state.isLoading = false;
|
3921
|
+
}
|
3922
|
+
}
|
3923
|
+
});
|
3924
|
+
const { actions, reducer: reducer$1 } = appSlice;
|
3925
|
+
const { setInitialData } = actions;
|
3926
|
+
const reducer = combineReducers({
|
3927
|
+
app: reducer$1
|
3928
|
+
});
|
3093
3929
|
const index = {
|
3094
3930
|
register(app) {
|
3095
3931
|
const cm = new ContentManagerPlugin();
|
3096
3932
|
app.addReducers({
|
3097
|
-
[contentManagerApi.reducerPath]: contentManagerApi.reducer,
|
3098
3933
|
[PLUGIN_ID]: reducer
|
3099
3934
|
});
|
3100
|
-
app.addMiddlewares([() => contentManagerApi.middleware]);
|
3101
3935
|
app.addMenuLink({
|
3102
3936
|
to: PLUGIN_ID,
|
3103
3937
|
icon: Feather,
|
@@ -3106,14 +3940,29 @@ const index = {
|
|
3106
3940
|
defaultMessage: "Content Manager"
|
3107
3941
|
},
|
3108
3942
|
permissions: [],
|
3109
|
-
|
3943
|
+
position: 1
|
3944
|
+
});
|
3945
|
+
app.router.addRoute({
|
3946
|
+
path: "content-manager/*",
|
3947
|
+
lazy: async () => {
|
3948
|
+
const { Layout } = await import("./layout-D4HI4_PS.mjs");
|
3949
|
+
return {
|
3950
|
+
Component: Layout
|
3951
|
+
};
|
3952
|
+
},
|
3953
|
+
children: routes
|
3110
3954
|
});
|
3111
3955
|
app.registerPlugin(cm.config);
|
3112
3956
|
},
|
3957
|
+
bootstrap(app) {
|
3958
|
+
if (typeof historyAdmin.bootstrap === "function") {
|
3959
|
+
historyAdmin.bootstrap(app);
|
3960
|
+
}
|
3961
|
+
},
|
3113
3962
|
async registerTrads({ locales }) {
|
3114
3963
|
const importedTrads = await Promise.all(
|
3115
3964
|
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-
|
3965
|
+
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-CPTj6CjC.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
3966
|
return {
|
3118
3967
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3119
3968
|
locale
|
@@ -3131,45 +3980,46 @@ const index = {
|
|
3131
3980
|
};
|
3132
3981
|
export {
|
3133
3982
|
ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD as A,
|
3134
|
-
|
3983
|
+
BulkActionsRenderer as B,
|
3135
3984
|
COLLECTION_TYPES as C,
|
3136
3985
|
DocumentStatus as D,
|
3137
|
-
|
3138
|
-
|
3139
|
-
|
3986
|
+
extractContentTypeComponents as E,
|
3987
|
+
DEFAULT_SETTINGS as F,
|
3988
|
+
convertEditLayoutToFieldLayouts as G,
|
3140
3989
|
HOOKS as H,
|
3141
3990
|
InjectionZone as I,
|
3142
|
-
|
3143
|
-
|
3991
|
+
useDocument as J,
|
3992
|
+
index as K,
|
3993
|
+
useDocumentActions as L,
|
3144
3994
|
Panels as P,
|
3145
3995
|
RelativeTime as R,
|
3146
3996
|
SINGLE_TYPES as S,
|
3147
3997
|
TableActions as T,
|
3148
|
-
|
3149
|
-
|
3150
|
-
|
3151
|
-
|
3152
|
-
|
3153
|
-
|
3998
|
+
useGetInitialDataQuery as a,
|
3999
|
+
useGetAllContentTypeSettingsQuery as b,
|
4000
|
+
useDoc as c,
|
4001
|
+
buildValidParams as d,
|
4002
|
+
contentManagerApi as e,
|
4003
|
+
useDocumentRBAC as f,
|
3154
4004
|
getTranslation as g,
|
3155
|
-
|
3156
|
-
|
3157
|
-
|
3158
|
-
|
3159
|
-
|
3160
|
-
|
3161
|
-
|
3162
|
-
|
3163
|
-
|
3164
|
-
|
3165
|
-
|
4005
|
+
useDocumentLayout as h,
|
4006
|
+
createYupSchema as i,
|
4007
|
+
Header as j,
|
4008
|
+
PERMISSIONS as k,
|
4009
|
+
DocumentRBAC as l,
|
4010
|
+
DOCUMENT_META_FIELDS as m,
|
4011
|
+
CLONE_PATH as n,
|
4012
|
+
useDocLayout as o,
|
4013
|
+
useGetContentTypeConfigurationQuery as p,
|
4014
|
+
CREATOR_FIELDS as q,
|
4015
|
+
getMainField as r,
|
3166
4016
|
setInitialData as s,
|
3167
4017
|
getDisplayName as t,
|
3168
|
-
|
4018
|
+
useContentTypeSchema as u,
|
3169
4019
|
checkIfAttributeIsDisplayable as v,
|
3170
4020
|
useGetAllDocumentsQuery as w,
|
3171
4021
|
convertListLayoutToFieldLayouts as x,
|
3172
4022
|
capitalise as y,
|
3173
4023
|
useUpdateContentTypeConfigurationMutation as z
|
3174
4024
|
};
|
3175
|
-
//# sourceMappingURL=index-
|
4025
|
+
//# sourceMappingURL=index-D4UGPFZC.mjs.map
|