@strapi/content-manager 0.0.0-experimental.2a7cb5ff33df35e8ccde5ef918f9f9a4a3ee9a08 → 0.0.0-experimental.2cfaca2410c03f1dee31ca18c06aedfb313e0fb4
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/{ComponentConfigurationPage-BvHtG7uH.js → ComponentConfigurationPage-DnnZJc1F.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-BvHtG7uH.js.map → ComponentConfigurationPage-DnnZJc1F.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-DHNM3YBz.mjs → ComponentConfigurationPage-hLMNf7KI.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-DHNM3YBz.mjs.map → ComponentConfigurationPage-hLMNf7KI.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-DOmfCEMo.js → EditConfigurationPage-CpLj5gYZ.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-DOmfCEMo.js.map → EditConfigurationPage-CpLj5gYZ.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-Cp6HAEzN.mjs → EditConfigurationPage-Dh6sq-G4.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-Cp6HAEzN.mjs.map → EditConfigurationPage-Dh6sq-G4.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-BtkEx339.mjs → EditViewPage-BU1ugeVi.mjs} +19 -8
- package/dist/_chunks/EditViewPage-BU1ugeVi.mjs.map +1 -0
- package/dist/_chunks/{EditViewPage-BqNpC6hO.js → EditViewPage-D2QVRr_2.js} +19 -8
- package/dist/_chunks/EditViewPage-D2QVRr_2.js.map +1 -0
- package/dist/_chunks/{Field-lsPFnAmH.js → Field-BEDX9i_V.js} +196 -143
- package/dist/_chunks/Field-BEDX9i_V.js.map +1 -0
- package/dist/_chunks/{Field-R5NbffTB.mjs → Field-VSPY6uzs.mjs} +194 -141
- package/dist/_chunks/Field-VSPY6uzs.mjs.map +1 -0
- package/dist/_chunks/{Form-BHmXSfyy.mjs → Form-05Oaes1N.mjs} +35 -16
- package/dist/_chunks/Form-05Oaes1N.mjs.map +1 -0
- package/dist/_chunks/{Form-CcGboku8.js → Form-DCaY8xBX.js} +35 -16
- package/dist/_chunks/Form-DCaY8xBX.js.map +1 -0
- package/dist/_chunks/{History-ByUPL3T3.mjs → History-BqO2G3MV.mjs} +28 -18
- package/dist/_chunks/History-BqO2G3MV.mjs.map +1 -0
- package/dist/_chunks/{History-Bsud8jwh.js → History-BrJ1tUvt.js} +28 -18
- package/dist/_chunks/History-BrJ1tUvt.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-Bm5HACXf.mjs → ListConfigurationPage-C6rsFlme.mjs} +20 -8
- package/dist/_chunks/ListConfigurationPage-C6rsFlme.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DiT463qx.js → ListConfigurationPage-Eane5LKE.js} +20 -8
- package/dist/_chunks/ListConfigurationPage-Eane5LKE.js.map +1 -0
- package/dist/_chunks/{ListViewPage-CsrC9L_d.js → ListViewPage-Coj-RPsx.js} +49 -40
- package/dist/_chunks/ListViewPage-Coj-RPsx.js.map +1 -0
- package/dist/_chunks/{ListViewPage-JSyNAAYu.mjs → ListViewPage-yE_zYhcI.mjs} +47 -38
- package/dist/_chunks/ListViewPage-yE_zYhcI.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-Bsvng4II.js → NoContentTypePage-BDJ0dshy.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-Bsvng4II.js.map → NoContentTypePage-BDJ0dshy.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-CsrQUpBE.mjs → NoContentTypePage-NW_FSVdY.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-CsrQUpBE.mjs.map → NoContentTypePage-NW_FSVdY.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-CdHNJtEf.js → NoPermissionsPage-BOtb5FTM.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-CdHNJtEf.js.map → NoPermissionsPage-BOtb5FTM.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-DNmf_pj0.mjs → NoPermissionsPage-h0I3ImsX.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-DNmf_pj0.mjs.map → NoPermissionsPage-h0I3ImsX.mjs.map} +1 -1
- package/dist/_chunks/{Relations-CghaPv2D.js → Relations-CVh0DOKv.js} +4 -4
- package/dist/_chunks/Relations-CVh0DOKv.js.map +1 -0
- package/dist/_chunks/{Relations-u8-37jK0.mjs → Relations-FP0uWpBz.mjs} +4 -4
- package/dist/_chunks/Relations-FP0uWpBz.mjs.map +1 -0
- package/dist/_chunks/{en-fbKQxLGn.js → en-BlhnxQfj.js} +11 -9
- package/dist/_chunks/{en-fbKQxLGn.js.map → en-BlhnxQfj.js.map} +1 -1
- package/dist/_chunks/{en-Ux26r5pl.mjs → en-C8YBvRrK.mjs} +11 -9
- package/dist/_chunks/{en-Ux26r5pl.mjs.map → en-C8YBvRrK.mjs.map} +1 -1
- package/dist/_chunks/{index-CaE6NG4a.mjs → index-CPCHQ3X_.mjs} +966 -682
- package/dist/_chunks/index-CPCHQ3X_.mjs.map +1 -0
- package/dist/_chunks/{index-BOZx6IMg.js → index-DTKVhcla.js} +947 -663
- package/dist/_chunks/index-DTKVhcla.js.map +1 -0
- package/dist/_chunks/{layout-Bx7svTbY.mjs → layout-B4UhJ8MJ.mjs} +23 -10
- package/dist/_chunks/layout-B4UhJ8MJ.mjs.map +1 -0
- package/dist/_chunks/{layout-Ciz224q5.js → layout-CWgZzMYf.js} +22 -9
- package/dist/_chunks/layout-CWgZzMYf.js.map +1 -0
- package/dist/_chunks/{relations-Cxc1cEv3.mjs → relations-B83Ge9a7.mjs} +2 -2
- package/dist/_chunks/{relations-Cxc1cEv3.mjs.map → relations-B83Ge9a7.mjs.map} +1 -1
- package/dist/_chunks/{relations-CP8sB2YZ.js → relations-D81a_2zw.js} +2 -2
- package/dist/_chunks/{relations-CP8sB2YZ.js.map → relations-D81a_2zw.js.map} +1 -1
- package/dist/_chunks/{usePrev-B9w_-eYc.js → useDebounce-CtcjDB3L.js} +14 -1
- 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/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +5 -4
- package/dist/admin/src/exports.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 +30 -1
- package/dist/admin/src/index.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +20 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.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 +4 -48
- package/dist/admin/src/pages/EditView/components/Header.d.ts +10 -11
- package/dist/admin/src/services/api.d.ts +1 -1
- package/dist/admin/src/services/components.d.ts +2 -2
- package/dist/admin/src/services/contentTypes.d.ts +3 -3
- package/dist/admin/src/services/documents.d.ts +19 -17
- package/dist/admin/src/services/init.d.ts +1 -1
- package/dist/admin/src/services/relations.d.ts +2 -2
- package/dist/admin/src/services/uid.d.ts +3 -3
- package/dist/admin/src/utils/validation.d.ts +4 -1
- package/dist/server/index.js +178 -108
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +179 -109
- 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/uid.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/dimensions.d.ts +4 -2
- package/dist/server/src/controllers/validation/dimensions.d.ts.map +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/policies/hasPermissions.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.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.map +1 -1
- package/dist/shared/contracts/collection-types.d.ts +3 -1
- package/dist/shared/contracts/collection-types.d.ts.map +1 -1
- package/package.json +11 -11
- package/dist/_chunks/EditViewPage-BqNpC6hO.js.map +0 -1
- package/dist/_chunks/EditViewPage-BtkEx339.mjs.map +0 -1
- package/dist/_chunks/Field-R5NbffTB.mjs.map +0 -1
- package/dist/_chunks/Field-lsPFnAmH.js.map +0 -1
- package/dist/_chunks/Form-BHmXSfyy.mjs.map +0 -1
- package/dist/_chunks/Form-CcGboku8.js.map +0 -1
- package/dist/_chunks/History-Bsud8jwh.js.map +0 -1
- package/dist/_chunks/History-ByUPL3T3.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-Bm5HACXf.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DiT463qx.js.map +0 -1
- package/dist/_chunks/ListViewPage-CsrC9L_d.js.map +0 -1
- package/dist/_chunks/ListViewPage-JSyNAAYu.mjs.map +0 -1
- package/dist/_chunks/Relations-CghaPv2D.js.map +0 -1
- package/dist/_chunks/Relations-u8-37jK0.mjs.map +0 -1
- package/dist/_chunks/index-BOZx6IMg.js.map +0 -1
- package/dist/_chunks/index-CaE6NG4a.mjs.map +0 -1
- package/dist/_chunks/layout-Bx7svTbY.mjs.map +0 -1
- package/dist/_chunks/layout-Ciz224q5.js.map +0 -1
- package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
- package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
- package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
- package/strapi-server.js +0 -3
@@ -1,17 +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, useLocation, Link, NavLink } from "react-router-dom";
|
3
|
+
import { useStrapiApp, createContext, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, useQueryParams, getYupValidationErrors, useForm, useTracking, useGuidedTour, BackButton, DescriptionComponentRenderer, useTable, Table } from "@strapi/admin/strapi-admin";
|
7
4
|
import * as React from "react";
|
8
5
|
import { lazy } from "react";
|
9
|
-
import { Button, Menu, VisuallyHidden, Flex,
|
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
11
|
import pipe from "lodash/fp/pipe";
|
14
12
|
import { intervalToDuration, isPast } from "date-fns";
|
13
|
+
import { styled } from "styled-components";
|
14
|
+
import { stringify } from "qs";
|
15
15
|
import { createSlice, combineReducers } from "@reduxjs/toolkit";
|
16
16
|
const __variableDynamicImportRuntimeHelper = (glob, path) => {
|
17
17
|
const v = glob[path];
|
@@ -49,42 +49,6 @@ const useInjectionZone = (area) => {
|
|
49
49
|
const [page, position] = area.split(".");
|
50
50
|
return contentManagerPlugin.getInjectedComponents(page, position);
|
51
51
|
};
|
52
|
-
const HistoryAction = ({ model, document }) => {
|
53
|
-
const { formatMessage } = useIntl();
|
54
|
-
const [{ query }] = useQueryParams();
|
55
|
-
const navigate = useNavigate();
|
56
|
-
const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
|
57
|
-
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
58
|
-
return null;
|
59
|
-
}
|
60
|
-
return {
|
61
|
-
icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
|
62
|
-
label: formatMessage({
|
63
|
-
id: "content-manager.history.document-action",
|
64
|
-
defaultMessage: "Content History"
|
65
|
-
}),
|
66
|
-
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
67
|
-
disabled: (
|
68
|
-
/**
|
69
|
-
* The user is creating a new document.
|
70
|
-
* It hasn't been saved yet, so there's no history to go to
|
71
|
-
*/
|
72
|
-
!document || /**
|
73
|
-
* The document has been created but the current dimension has never been saved.
|
74
|
-
* For example, the user is creating a new locale in an existing document,
|
75
|
-
* so there's no history for the document in that locale
|
76
|
-
*/
|
77
|
-
!document.id || /**
|
78
|
-
* History is only available for content types created by the user.
|
79
|
-
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
80
|
-
* which start with `admin::` or `plugin::`
|
81
|
-
*/
|
82
|
-
!model.startsWith("api::")
|
83
|
-
),
|
84
|
-
position: "header"
|
85
|
-
};
|
86
|
-
};
|
87
|
-
HistoryAction.type = "history";
|
88
52
|
const ID = "id";
|
89
53
|
const CREATED_BY_ATTRIBUTE_NAME = "createdBy";
|
90
54
|
const UPDATED_BY_ATTRIBUTE_NAME = "updatedBy";
|
@@ -194,7 +158,8 @@ const contentManagerApi = adminApi.enhanceEndpoints({
|
|
194
158
|
"Document",
|
195
159
|
"InitialData",
|
196
160
|
"HistoryVersion",
|
197
|
-
"Relations"
|
161
|
+
"Relations",
|
162
|
+
"UidAvailability"
|
198
163
|
]
|
199
164
|
});
|
200
165
|
const documentApi = contentManagerApi.injectEndpoints({
|
@@ -208,7 +173,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
208
173
|
params: query
|
209
174
|
}
|
210
175
|
}),
|
211
|
-
invalidatesTags: (_result,
|
176
|
+
invalidatesTags: (_result, error, { model }) => {
|
177
|
+
if (error) {
|
178
|
+
return [];
|
179
|
+
}
|
180
|
+
return [{ type: "Document", id: `${model}_LIST` }];
|
181
|
+
}
|
212
182
|
}),
|
213
183
|
cloneDocument: builder.mutation({
|
214
184
|
query: ({ model, sourceId, data, params }) => ({
|
@@ -219,7 +189,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
219
189
|
params
|
220
190
|
}
|
221
191
|
}),
|
222
|
-
invalidatesTags: (_result, _error, { model }) => [
|
192
|
+
invalidatesTags: (_result, _error, { model }) => [
|
193
|
+
{ type: "Document", id: `${model}_LIST` },
|
194
|
+
{ type: "UidAvailability", id: model }
|
195
|
+
]
|
223
196
|
}),
|
224
197
|
/**
|
225
198
|
* Creates a new collection-type document. This should ONLY be used for collection-types.
|
@@ -236,7 +209,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
236
209
|
}),
|
237
210
|
invalidatesTags: (result, _error, { model }) => [
|
238
211
|
{ type: "Document", id: `${model}_LIST` },
|
239
|
-
"Relations"
|
212
|
+
"Relations",
|
213
|
+
{ type: "UidAvailability", id: model }
|
240
214
|
]
|
241
215
|
}),
|
242
216
|
deleteDocument: builder.mutation({
|
@@ -277,7 +251,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
277
251
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
278
252
|
},
|
279
253
|
{ type: "Document", id: `${model}_LIST` },
|
280
|
-
"Relations"
|
254
|
+
"Relations",
|
255
|
+
{ type: "UidAvailability", id: model }
|
281
256
|
];
|
282
257
|
}
|
283
258
|
}),
|
@@ -295,6 +270,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
295
270
|
}),
|
296
271
|
providesTags: (result, _error, arg) => {
|
297
272
|
return [
|
273
|
+
{ type: "Document", id: `ALL_LIST` },
|
298
274
|
{ type: "Document", id: `${arg.model}_LIST` },
|
299
275
|
...result?.results.map(({ documentId }) => ({
|
300
276
|
type: "Document",
|
@@ -333,6 +309,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
333
309
|
{
|
334
310
|
type: "Document",
|
335
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`
|
336
317
|
}
|
337
318
|
];
|
338
319
|
}
|
@@ -396,8 +377,21 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
396
377
|
type: "Document",
|
397
378
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
398
379
|
},
|
399
|
-
"Relations"
|
380
|
+
"Relations",
|
381
|
+
{ type: "UidAvailability", id: model }
|
400
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
|
+
}
|
401
395
|
}
|
402
396
|
}),
|
403
397
|
unpublishDocument: builder.mutation({
|
@@ -467,7 +461,7 @@ const buildValidParams = (query) => {
|
|
467
461
|
const isBaseQueryError = (error) => {
|
468
462
|
return error.name !== void 0;
|
469
463
|
};
|
470
|
-
const createYupSchema = (attributes = {}, components = {}) => {
|
464
|
+
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
471
465
|
const createModelSchema = (attributes2) => yup.object().shape(
|
472
466
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
473
467
|
if (DOCUMENT_META_FIELDS.includes(name)) {
|
@@ -480,7 +474,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
480
474
|
addMinValidation,
|
481
475
|
addMaxValidation,
|
482
476
|
addRegexValidation
|
483
|
-
].map((fn) => fn(attribute));
|
477
|
+
].map((fn) => fn(attribute, options));
|
484
478
|
const transformSchema = pipe(...validations);
|
485
479
|
switch (attribute.type) {
|
486
480
|
case "component": {
|
@@ -581,6 +575,14 @@ const createAttributeSchema = (attribute) => {
|
|
581
575
|
if (!value || typeof value === "string" && value.length === 0) {
|
582
576
|
return true;
|
583
577
|
}
|
578
|
+
if (typeof value === "object") {
|
579
|
+
try {
|
580
|
+
JSON.stringify(value);
|
581
|
+
return true;
|
582
|
+
} catch (err) {
|
583
|
+
return false;
|
584
|
+
}
|
585
|
+
}
|
584
586
|
try {
|
585
587
|
JSON.parse(value);
|
586
588
|
return true;
|
@@ -599,13 +601,7 @@ const createAttributeSchema = (attribute) => {
|
|
599
601
|
return yup.mixed();
|
600
602
|
}
|
601
603
|
};
|
602
|
-
const
|
603
|
-
if (attribute.required && attribute.type !== "relation") {
|
604
|
-
return schema.required({
|
605
|
-
id: translatedErrors.required.id,
|
606
|
-
defaultMessage: "This field is required."
|
607
|
-
});
|
608
|
-
}
|
604
|
+
const nullableSchema = (schema) => {
|
609
605
|
return schema?.nullable ? schema.nullable() : (
|
610
606
|
// In some cases '.nullable' will not be available on the schema.
|
611
607
|
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
@@ -613,7 +609,22 @@ const addRequiredValidation = (attribute) => (schema) => {
|
|
613
609
|
schema
|
614
610
|
);
|
615
611
|
};
|
616
|
-
const
|
612
|
+
const addRequiredValidation = (attribute, options) => (schema) => {
|
613
|
+
if (options.status === "draft") {
|
614
|
+
return nullableSchema(schema);
|
615
|
+
}
|
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);
|
623
|
+
};
|
624
|
+
const addMinLengthValidation = (attribute, options) => (schema) => {
|
625
|
+
if (options.status === "draft") {
|
626
|
+
return schema;
|
627
|
+
}
|
617
628
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
618
629
|
return schema.min(attribute.minLength, {
|
619
630
|
...translatedErrors.minLength,
|
@@ -635,9 +646,31 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
635
646
|
}
|
636
647
|
return schema;
|
637
648
|
};
|
638
|
-
const addMinValidation = (attribute) => (schema) => {
|
649
|
+
const addMinValidation = (attribute, options) => (schema) => {
|
639
650
|
if ("min" in attribute) {
|
640
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
|
+
}
|
641
674
|
if ("min" in schema && min) {
|
642
675
|
return schema.min(min, {
|
643
676
|
...translatedErrors.min,
|
@@ -756,19 +789,115 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
|
|
756
789
|
}, {});
|
757
790
|
return componentsByKey;
|
758
791
|
};
|
759
|
-
const
|
792
|
+
const HOOKS = {
|
793
|
+
/**
|
794
|
+
* Hook that allows to mutate the displayed headers of the list view table
|
795
|
+
* @constant
|
796
|
+
* @type {string}
|
797
|
+
*/
|
798
|
+
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
799
|
+
/**
|
800
|
+
* Hook that allows to mutate the CM's collection types links pre-set filters
|
801
|
+
* @constant
|
802
|
+
* @type {string}
|
803
|
+
*/
|
804
|
+
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
805
|
+
/**
|
806
|
+
* Hook that allows to mutate the CM's edit view layout
|
807
|
+
* @constant
|
808
|
+
* @type {string}
|
809
|
+
*/
|
810
|
+
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
811
|
+
/**
|
812
|
+
* Hook that allows to mutate the CM's single types links pre-set filters
|
813
|
+
* @constant
|
814
|
+
* @type {string}
|
815
|
+
*/
|
816
|
+
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
817
|
+
};
|
818
|
+
const contentTypesApi = contentManagerApi.injectEndpoints({
|
819
|
+
endpoints: (builder) => ({
|
820
|
+
getContentTypeConfiguration: builder.query({
|
821
|
+
query: (uid) => ({
|
822
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
823
|
+
method: "GET"
|
824
|
+
}),
|
825
|
+
transformResponse: (response) => response.data,
|
826
|
+
providesTags: (_result, _error, uid) => [
|
827
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
828
|
+
{ type: "ContentTypeSettings", id: "LIST" }
|
829
|
+
]
|
830
|
+
}),
|
831
|
+
getAllContentTypeSettings: builder.query({
|
832
|
+
query: () => "/content-manager/content-types-settings",
|
833
|
+
transformResponse: (response) => response.data,
|
834
|
+
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
835
|
+
}),
|
836
|
+
updateContentTypeConfiguration: builder.mutation({
|
837
|
+
query: ({ uid, ...body }) => ({
|
838
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
839
|
+
method: "PUT",
|
840
|
+
data: body
|
841
|
+
}),
|
842
|
+
transformResponse: (response) => response.data,
|
843
|
+
invalidatesTags: (_result, _error, { uid }) => [
|
844
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
845
|
+
{ type: "ContentTypeSettings", id: "LIST" },
|
846
|
+
// Is this necessary?
|
847
|
+
{ type: "InitialData" }
|
848
|
+
]
|
849
|
+
})
|
850
|
+
})
|
851
|
+
});
|
852
|
+
const {
|
853
|
+
useGetContentTypeConfigurationQuery,
|
854
|
+
useGetAllContentTypeSettingsQuery,
|
855
|
+
useUpdateContentTypeConfigurationMutation
|
856
|
+
} = contentTypesApi;
|
857
|
+
const checkIfAttributeIsDisplayable = (attribute) => {
|
858
|
+
const { type } = attribute;
|
859
|
+
if (type === "relation") {
|
860
|
+
return !attribute.relation.toLowerCase().includes("morph");
|
861
|
+
}
|
862
|
+
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
863
|
+
};
|
864
|
+
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
865
|
+
if (!mainFieldName) {
|
866
|
+
return void 0;
|
867
|
+
}
|
868
|
+
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
869
|
+
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
870
|
+
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
871
|
+
);
|
872
|
+
return {
|
873
|
+
name: mainFieldName,
|
874
|
+
type: mainFieldType ?? "string"
|
875
|
+
};
|
876
|
+
};
|
877
|
+
const DEFAULT_SETTINGS = {
|
878
|
+
bulkable: false,
|
879
|
+
filterable: false,
|
880
|
+
searchable: false,
|
881
|
+
pagination: false,
|
882
|
+
defaultSortBy: "",
|
883
|
+
defaultSortOrder: "asc",
|
884
|
+
mainField: "id",
|
885
|
+
pageSize: 10
|
886
|
+
};
|
887
|
+
const useDocumentLayout = (model) => {
|
888
|
+
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
889
|
+
const [{ query }] = useQueryParams();
|
890
|
+
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
760
891
|
const { toggleNotification } = useNotification();
|
761
892
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
893
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
762
894
|
const {
|
763
|
-
|
764
|
-
isLoading:
|
765
|
-
|
766
|
-
|
767
|
-
} =
|
768
|
-
|
769
|
-
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
770
|
-
});
|
771
|
-
const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
|
895
|
+
data,
|
896
|
+
isLoading: isLoadingConfigs,
|
897
|
+
error,
|
898
|
+
isFetching: isFetchingConfigs
|
899
|
+
} = useGetContentTypeConfigurationQuery(model);
|
900
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
772
901
|
React.useEffect(() => {
|
773
902
|
if (error) {
|
774
903
|
toggleNotification({
|
@@ -776,50 +905,263 @@ const useDocument = (args, opts) => {
|
|
776
905
|
message: formatAPIError(error)
|
777
906
|
});
|
778
907
|
}
|
779
|
-
}, [
|
780
|
-
const
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
(document) => {
|
788
|
-
if (!validationSchema) {
|
789
|
-
throw new Error(
|
790
|
-
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
791
|
-
);
|
792
|
-
}
|
793
|
-
try {
|
794
|
-
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
795
|
-
return null;
|
796
|
-
} catch (error2) {
|
797
|
-
if (error2 instanceof ValidationError) {
|
798
|
-
return getYupValidationErrors(error2);
|
799
|
-
}
|
800
|
-
throw error2;
|
801
|
-
}
|
908
|
+
}, [error, formatAPIError, toggleNotification]);
|
909
|
+
const editLayout = React.useMemo(
|
910
|
+
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
911
|
+
layout: [],
|
912
|
+
components: {},
|
913
|
+
metadatas: {},
|
914
|
+
options: {},
|
915
|
+
settings: DEFAULT_SETTINGS
|
802
916
|
},
|
803
|
-
[
|
917
|
+
[data, isLoading, schemas, schema, components]
|
918
|
+
);
|
919
|
+
const listLayout = React.useMemo(() => {
|
920
|
+
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
921
|
+
layout: [],
|
922
|
+
metadatas: {},
|
923
|
+
options: {},
|
924
|
+
settings: DEFAULT_SETTINGS
|
925
|
+
};
|
926
|
+
}, [data, isLoading, schemas, schema, components]);
|
927
|
+
const { layout: edit } = React.useMemo(
|
928
|
+
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
929
|
+
layout: editLayout,
|
930
|
+
query
|
931
|
+
}),
|
932
|
+
[editLayout, query, runHookWaterfall]
|
804
933
|
);
|
805
|
-
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
806
934
|
return {
|
807
|
-
|
808
|
-
document: data?.data,
|
809
|
-
meta: data?.meta,
|
935
|
+
error,
|
810
936
|
isLoading,
|
811
|
-
|
812
|
-
|
937
|
+
edit,
|
938
|
+
list: listLayout
|
813
939
|
};
|
814
940
|
};
|
815
|
-
const
|
816
|
-
const {
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
941
|
+
const useDocLayout = () => {
|
942
|
+
const { model } = useDoc();
|
943
|
+
return useDocumentLayout(model);
|
944
|
+
};
|
945
|
+
const formatEditLayout = (data, {
|
946
|
+
schemas,
|
947
|
+
schema,
|
948
|
+
components
|
949
|
+
}) => {
|
950
|
+
let currentPanelIndex = 0;
|
951
|
+
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
952
|
+
data.contentType.layouts.edit,
|
953
|
+
schema?.attributes,
|
954
|
+
data.contentType.metadatas,
|
955
|
+
{ configurations: data.components, schemas: components },
|
956
|
+
schemas
|
957
|
+
).reduce((panels, row) => {
|
958
|
+
if (row.some((field) => field.type === "dynamiczone")) {
|
959
|
+
panels.push([row]);
|
960
|
+
currentPanelIndex += 2;
|
961
|
+
} else {
|
962
|
+
if (!panels[currentPanelIndex]) {
|
963
|
+
panels.push([]);
|
964
|
+
}
|
965
|
+
panels[currentPanelIndex].push(row);
|
966
|
+
}
|
967
|
+
return panels;
|
968
|
+
}, []);
|
969
|
+
const componentEditAttributes = Object.entries(data.components).reduce(
|
970
|
+
(acc, [uid, configuration]) => {
|
971
|
+
acc[uid] = {
|
972
|
+
layout: convertEditLayoutToFieldLayouts(
|
973
|
+
configuration.layouts.edit,
|
974
|
+
components[uid].attributes,
|
975
|
+
configuration.metadatas,
|
976
|
+
{ configurations: data.components, schemas: components }
|
977
|
+
),
|
978
|
+
settings: {
|
979
|
+
...configuration.settings,
|
980
|
+
icon: components[uid].info.icon,
|
981
|
+
displayName: components[uid].info.displayName
|
982
|
+
}
|
983
|
+
};
|
984
|
+
return acc;
|
985
|
+
},
|
986
|
+
{}
|
987
|
+
);
|
988
|
+
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
989
|
+
(acc, [attribute, metadata]) => {
|
990
|
+
return {
|
991
|
+
...acc,
|
992
|
+
[attribute]: metadata.edit
|
993
|
+
};
|
994
|
+
},
|
995
|
+
{}
|
996
|
+
);
|
997
|
+
return {
|
998
|
+
layout: panelledEditAttributes,
|
999
|
+
components: componentEditAttributes,
|
1000
|
+
metadatas: editMetadatas,
|
1001
|
+
settings: {
|
1002
|
+
...data.contentType.settings,
|
1003
|
+
displayName: schema?.info.displayName
|
1004
|
+
},
|
1005
|
+
options: {
|
1006
|
+
...schema?.options,
|
1007
|
+
...schema?.pluginOptions,
|
1008
|
+
...data.contentType.options
|
1009
|
+
}
|
1010
|
+
};
|
1011
|
+
};
|
1012
|
+
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
1013
|
+
return rows.map(
|
1014
|
+
(row) => row.map((field) => {
|
1015
|
+
const attribute = attributes[field.name];
|
1016
|
+
if (!attribute) {
|
1017
|
+
return null;
|
1018
|
+
}
|
1019
|
+
const { edit: metadata } = metadatas[field.name];
|
1020
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1021
|
+
return {
|
1022
|
+
attribute,
|
1023
|
+
disabled: !metadata.editable,
|
1024
|
+
hint: metadata.description,
|
1025
|
+
label: metadata.label ?? "",
|
1026
|
+
name: field.name,
|
1027
|
+
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
1028
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1029
|
+
schemas,
|
1030
|
+
components: components?.schemas ?? {}
|
1031
|
+
}),
|
1032
|
+
placeholder: metadata.placeholder ?? "",
|
1033
|
+
required: attribute.required ?? false,
|
1034
|
+
size: field.size,
|
1035
|
+
unique: "unique" in attribute ? attribute.unique : false,
|
1036
|
+
visible: metadata.visible ?? true,
|
1037
|
+
type: attribute.type
|
1038
|
+
};
|
1039
|
+
}).filter((field) => field !== null)
|
1040
|
+
);
|
1041
|
+
};
|
1042
|
+
const formatListLayout = (data, {
|
1043
|
+
schemas,
|
1044
|
+
schema,
|
1045
|
+
components
|
1046
|
+
}) => {
|
1047
|
+
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1048
|
+
(acc, [attribute, metadata]) => {
|
1049
|
+
return {
|
1050
|
+
...acc,
|
1051
|
+
[attribute]: metadata.list
|
1052
|
+
};
|
1053
|
+
},
|
1054
|
+
{}
|
1055
|
+
);
|
1056
|
+
const listAttributes = convertListLayoutToFieldLayouts(
|
1057
|
+
data.contentType.layouts.list,
|
1058
|
+
schema?.attributes,
|
1059
|
+
listMetadatas,
|
1060
|
+
{ configurations: data.components, schemas: components },
|
1061
|
+
schemas
|
1062
|
+
);
|
1063
|
+
return {
|
1064
|
+
layout: listAttributes,
|
1065
|
+
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
1066
|
+
metadatas: listMetadatas,
|
1067
|
+
options: {
|
1068
|
+
...schema?.options,
|
1069
|
+
...schema?.pluginOptions,
|
1070
|
+
...data.contentType.options
|
1071
|
+
}
|
1072
|
+
};
|
1073
|
+
};
|
1074
|
+
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
1075
|
+
return columns.map((name) => {
|
1076
|
+
const attribute = attributes[name];
|
1077
|
+
if (!attribute) {
|
1078
|
+
return null;
|
1079
|
+
}
|
1080
|
+
const metadata = metadatas[name];
|
1081
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1082
|
+
return {
|
1083
|
+
attribute,
|
1084
|
+
label: metadata.label ?? "",
|
1085
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1086
|
+
schemas,
|
1087
|
+
components: components?.schemas ?? {}
|
1088
|
+
}),
|
1089
|
+
name,
|
1090
|
+
searchable: metadata.searchable ?? true,
|
1091
|
+
sortable: metadata.sortable ?? true
|
1092
|
+
};
|
1093
|
+
}).filter((field) => field !== null);
|
1094
|
+
};
|
1095
|
+
const useDocument = (args, opts) => {
|
1096
|
+
const { toggleNotification } = useNotification();
|
1097
|
+
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1098
|
+
const {
|
1099
|
+
currentData: data,
|
1100
|
+
isLoading: isLoadingDocument,
|
1101
|
+
isFetching: isFetchingDocument,
|
1102
|
+
error
|
1103
|
+
} = useGetDocumentQuery(args, {
|
1104
|
+
...opts,
|
1105
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
1106
|
+
});
|
1107
|
+
const {
|
1108
|
+
components,
|
1109
|
+
schema,
|
1110
|
+
schemas,
|
1111
|
+
isLoading: isLoadingSchema
|
1112
|
+
} = useContentTypeSchema(args.model);
|
1113
|
+
React.useEffect(() => {
|
1114
|
+
if (error) {
|
1115
|
+
toggleNotification({
|
1116
|
+
type: "danger",
|
1117
|
+
message: formatAPIError(error)
|
1118
|
+
});
|
1119
|
+
}
|
1120
|
+
}, [toggleNotification, error, formatAPIError, args.collectionType]);
|
1121
|
+
const validationSchema = React.useMemo(() => {
|
1122
|
+
if (!schema) {
|
1123
|
+
return null;
|
1124
|
+
}
|
1125
|
+
return createYupSchema(schema.attributes, components);
|
1126
|
+
}, [schema, components]);
|
1127
|
+
const validate = React.useCallback(
|
1128
|
+
(document) => {
|
1129
|
+
if (!validationSchema) {
|
1130
|
+
throw new Error(
|
1131
|
+
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
1132
|
+
);
|
1133
|
+
}
|
1134
|
+
try {
|
1135
|
+
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
1136
|
+
return null;
|
1137
|
+
} catch (error2) {
|
1138
|
+
if (error2 instanceof ValidationError) {
|
1139
|
+
return getYupValidationErrors(error2);
|
1140
|
+
}
|
1141
|
+
throw error2;
|
1142
|
+
}
|
1143
|
+
},
|
1144
|
+
[validationSchema]
|
1145
|
+
);
|
1146
|
+
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
1147
|
+
return {
|
1148
|
+
components,
|
1149
|
+
document: data?.data,
|
1150
|
+
meta: data?.meta,
|
1151
|
+
isLoading,
|
1152
|
+
schema,
|
1153
|
+
schemas,
|
1154
|
+
validate
|
1155
|
+
};
|
1156
|
+
};
|
1157
|
+
const useDoc = () => {
|
1158
|
+
const { id, slug, collectionType, origin } = useParams();
|
1159
|
+
const [{ query }] = useQueryParams();
|
1160
|
+
const params = React.useMemo(() => buildValidParams(query), [query]);
|
1161
|
+
if (!collectionType) {
|
1162
|
+
throw new Error("Could not find collectionType in url params");
|
1163
|
+
}
|
1164
|
+
if (!slug) {
|
823
1165
|
throw new Error("Could not find model in url params");
|
824
1166
|
}
|
825
1167
|
return {
|
@@ -834,6 +1176,45 @@ const useDoc = () => {
|
|
834
1176
|
)
|
835
1177
|
};
|
836
1178
|
};
|
1179
|
+
const useContentManagerContext = () => {
|
1180
|
+
const {
|
1181
|
+
collectionType,
|
1182
|
+
model,
|
1183
|
+
id,
|
1184
|
+
components,
|
1185
|
+
isLoading: isLoadingDoc,
|
1186
|
+
schema,
|
1187
|
+
schemas
|
1188
|
+
} = useDoc();
|
1189
|
+
const layout = useDocumentLayout(model);
|
1190
|
+
const form = useForm("useContentManagerContext", (state) => state);
|
1191
|
+
const isSingleType = collectionType === SINGLE_TYPES;
|
1192
|
+
const slug = model;
|
1193
|
+
const isCreatingEntry = id === "create";
|
1194
|
+
useContentTypeSchema();
|
1195
|
+
const isLoading = isLoadingDoc || layout.isLoading;
|
1196
|
+
const error = layout.error;
|
1197
|
+
return {
|
1198
|
+
error,
|
1199
|
+
isLoading,
|
1200
|
+
// Base metadata
|
1201
|
+
model,
|
1202
|
+
collectionType,
|
1203
|
+
id,
|
1204
|
+
slug,
|
1205
|
+
isCreatingEntry,
|
1206
|
+
isSingleType,
|
1207
|
+
hasDraftAndPublish: schema?.options?.draftAndPublish ?? false,
|
1208
|
+
// All schema infos
|
1209
|
+
components,
|
1210
|
+
contentType: schema,
|
1211
|
+
contentTypes: schemas,
|
1212
|
+
// Form state
|
1213
|
+
form,
|
1214
|
+
// layout infos
|
1215
|
+
layout
|
1216
|
+
};
|
1217
|
+
};
|
837
1218
|
const prefixPluginTranslations = (trad, pluginId) => {
|
838
1219
|
if (!pluginId) {
|
839
1220
|
throw new TypeError("pluginId can't be empty");
|
@@ -853,6 +1234,8 @@ const useDocumentActions = () => {
|
|
853
1234
|
const { formatMessage } = useIntl();
|
854
1235
|
const { trackUsage } = useTracking();
|
855
1236
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1237
|
+
const navigate = useNavigate();
|
1238
|
+
const setCurrentStep = useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
856
1239
|
const [deleteDocument] = useDeleteDocumentMutation();
|
857
1240
|
const _delete = React.useCallback(
|
858
1241
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -1167,6 +1550,7 @@ const useDocumentActions = () => {
|
|
1167
1550
|
defaultMessage: "Saved document"
|
1168
1551
|
})
|
1169
1552
|
});
|
1553
|
+
setCurrentStep("contentManager.success");
|
1170
1554
|
return res.data;
|
1171
1555
|
} catch (err) {
|
1172
1556
|
toggleNotification({
|
@@ -1188,7 +1572,6 @@ const useDocumentActions = () => {
|
|
1188
1572
|
sourceId
|
1189
1573
|
});
|
1190
1574
|
if ("error" in res) {
|
1191
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1192
1575
|
return { error: res.error };
|
1193
1576
|
}
|
1194
1577
|
toggleNotification({
|
@@ -1207,7 +1590,7 @@ const useDocumentActions = () => {
|
|
1207
1590
|
throw err;
|
1208
1591
|
}
|
1209
1592
|
},
|
1210
|
-
[autoCloneDocument,
|
1593
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1211
1594
|
);
|
1212
1595
|
const [cloneDocument] = useCloneDocumentMutation();
|
1213
1596
|
const clone = React.useCallback(
|
@@ -1233,6 +1616,7 @@ const useDocumentActions = () => {
|
|
1233
1616
|
defaultMessage: "Cloned document"
|
1234
1617
|
})
|
1235
1618
|
});
|
1619
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1236
1620
|
return res.data;
|
1237
1621
|
} catch (err) {
|
1238
1622
|
toggleNotification({
|
@@ -1243,7 +1627,7 @@ const useDocumentActions = () => {
|
|
1243
1627
|
throw err;
|
1244
1628
|
}
|
1245
1629
|
},
|
1246
|
-
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
|
1630
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1247
1631
|
);
|
1248
1632
|
const [getDoc] = useLazyGetDocumentQuery();
|
1249
1633
|
const getDocument = React.useCallback(
|
@@ -1269,7 +1653,7 @@ const useDocumentActions = () => {
|
|
1269
1653
|
};
|
1270
1654
|
};
|
1271
1655
|
const ProtectedHistoryPage = lazy(
|
1272
|
-
() => import("./History-
|
1656
|
+
() => import("./History-BqO2G3MV.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1273
1657
|
);
|
1274
1658
|
const routes$1 = [
|
1275
1659
|
{
|
@@ -1282,31 +1666,31 @@ const routes$1 = [
|
|
1282
1666
|
}
|
1283
1667
|
];
|
1284
1668
|
const ProtectedEditViewPage = lazy(
|
1285
|
-
() => import("./EditViewPage-
|
1669
|
+
() => import("./EditViewPage-BU1ugeVi.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1286
1670
|
);
|
1287
1671
|
const ProtectedListViewPage = lazy(
|
1288
|
-
() => import("./ListViewPage-
|
1672
|
+
() => import("./ListViewPage-yE_zYhcI.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1289
1673
|
);
|
1290
1674
|
const ProtectedListConfiguration = lazy(
|
1291
|
-
() => import("./ListConfigurationPage-
|
1675
|
+
() => import("./ListConfigurationPage-C6rsFlme.mjs").then((mod) => ({
|
1292
1676
|
default: mod.ProtectedListConfiguration
|
1293
1677
|
}))
|
1294
1678
|
);
|
1295
1679
|
const ProtectedEditConfigurationPage = lazy(
|
1296
|
-
() => import("./EditConfigurationPage-
|
1680
|
+
() => import("./EditConfigurationPage-Dh6sq-G4.mjs").then((mod) => ({
|
1297
1681
|
default: mod.ProtectedEditConfigurationPage
|
1298
1682
|
}))
|
1299
1683
|
);
|
1300
1684
|
const ProtectedComponentConfigurationPage = lazy(
|
1301
|
-
() => import("./ComponentConfigurationPage-
|
1685
|
+
() => import("./ComponentConfigurationPage-hLMNf7KI.mjs").then((mod) => ({
|
1302
1686
|
default: mod.ProtectedComponentConfigurationPage
|
1303
1687
|
}))
|
1304
1688
|
);
|
1305
1689
|
const NoPermissions = lazy(
|
1306
|
-
() => import("./NoPermissionsPage-
|
1690
|
+
() => import("./NoPermissionsPage-h0I3ImsX.mjs").then((mod) => ({ default: mod.NoPermissions }))
|
1307
1691
|
);
|
1308
1692
|
const NoContentType = lazy(
|
1309
|
-
() => import("./NoContentTypePage-
|
1693
|
+
() => import("./NoContentTypePage-NW_FSVdY.mjs").then((mod) => ({ default: mod.NoContentType }))
|
1310
1694
|
);
|
1311
1695
|
const CollectionTypePages = () => {
|
1312
1696
|
const { collectionType } = useParams();
|
@@ -1420,12 +1804,14 @@ const DocumentActionButton = (action) => {
|
|
1420
1804
|
/* @__PURE__ */ jsx(
|
1421
1805
|
Button,
|
1422
1806
|
{
|
1423
|
-
flex:
|
1807
|
+
flex: "auto",
|
1424
1808
|
startIcon: action.icon,
|
1425
1809
|
disabled: action.disabled,
|
1426
1810
|
onClick: handleClick(action),
|
1427
1811
|
justifyContent: "center",
|
1428
1812
|
variant: action.variant || "default",
|
1813
|
+
paddingTop: "7px",
|
1814
|
+
paddingBottom: "7px",
|
1429
1815
|
children: action.label
|
1430
1816
|
}
|
1431
1817
|
),
|
@@ -1433,7 +1819,7 @@ const DocumentActionButton = (action) => {
|
|
1433
1819
|
DocumentActionConfirmDialog,
|
1434
1820
|
{
|
1435
1821
|
...action.dialog,
|
1436
|
-
variant: action.variant,
|
1822
|
+
variant: action.dialog?.variant ?? action.variant,
|
1437
1823
|
isOpen: dialogId === action.id,
|
1438
1824
|
onClose: handleClose
|
1439
1825
|
}
|
@@ -1490,9 +1876,9 @@ const DocumentActionsMenu = ({
|
|
1490
1876
|
disabled: isDisabled,
|
1491
1877
|
size: "S",
|
1492
1878
|
endIcon: null,
|
1493
|
-
paddingTop: "
|
1494
|
-
paddingLeft: "
|
1495
|
-
paddingRight: "
|
1879
|
+
paddingTop: "4px",
|
1880
|
+
paddingLeft: "7px",
|
1881
|
+
paddingRight: "7px",
|
1496
1882
|
variant,
|
1497
1883
|
children: [
|
1498
1884
|
/* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
|
@@ -1503,7 +1889,7 @@ const DocumentActionsMenu = ({
|
|
1503
1889
|
]
|
1504
1890
|
}
|
1505
1891
|
),
|
1506
|
-
/* @__PURE__ */ jsxs(Menu.Content, {
|
1892
|
+
/* @__PURE__ */ jsxs(Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1507
1893
|
actions2.map((action) => {
|
1508
1894
|
return /* @__PURE__ */ jsx(
|
1509
1895
|
Menu.Item,
|
@@ -1512,10 +1898,25 @@ const DocumentActionsMenu = ({
|
|
1512
1898
|
onSelect: handleClick(action),
|
1513
1899
|
display: "block",
|
1514
1900
|
children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", gap: 4, children: [
|
1515
|
-
/* @__PURE__ */ jsxs(
|
1516
|
-
|
1517
|
-
|
1518
|
-
|
1901
|
+
/* @__PURE__ */ jsxs(
|
1902
|
+
Flex,
|
1903
|
+
{
|
1904
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1905
|
+
gap: 2,
|
1906
|
+
tag: "span",
|
1907
|
+
children: [
|
1908
|
+
/* @__PURE__ */ jsx(
|
1909
|
+
Flex,
|
1910
|
+
{
|
1911
|
+
tag: "span",
|
1912
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1913
|
+
children: action.icon
|
1914
|
+
}
|
1915
|
+
),
|
1916
|
+
action.label
|
1917
|
+
]
|
1918
|
+
}
|
1919
|
+
),
|
1519
1920
|
action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsx(
|
1520
1921
|
Flex,
|
1521
1922
|
{
|
@@ -1612,11 +2013,11 @@ const DocumentActionConfirmDialog = ({
|
|
1612
2013
|
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
1613
2014
|
/* @__PURE__ */ jsx(Dialog.Body, { children: content }),
|
1614
2015
|
/* @__PURE__ */ jsxs(Dialog.Footer, { children: [
|
1615
|
-
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", children: formatMessage({
|
2016
|
+
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", fullWidth: true, children: formatMessage({
|
1616
2017
|
id: "app.components.Button.cancel",
|
1617
2018
|
defaultMessage: "Cancel"
|
1618
2019
|
}) }) }),
|
1619
|
-
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, children: formatMessage({
|
2020
|
+
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
|
1620
2021
|
id: "app.components.Button.confirm",
|
1621
2022
|
defaultMessage: "Confirm"
|
1622
2023
|
}) })
|
@@ -1639,8 +2040,8 @@ const DocumentActionModal = ({
|
|
1639
2040
|
};
|
1640
2041
|
return /* @__PURE__ */ jsx(Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
|
1641
2042
|
/* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: title }) }),
|
1642
|
-
|
1643
|
-
|
2043
|
+
typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsx(Modal.Body, { children: Content }),
|
2044
|
+
typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
|
1644
2045
|
] }) });
|
1645
2046
|
};
|
1646
2047
|
const PublishAction$1 = ({
|
@@ -1655,13 +2056,17 @@ const PublishAction$1 = ({
|
|
1655
2056
|
const navigate = useNavigate();
|
1656
2057
|
const { toggleNotification } = useNotification();
|
1657
2058
|
const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
|
2059
|
+
const isListView = useMatch(LIST_PATH) !== null;
|
1658
2060
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
1659
2061
|
const { formatMessage } = useIntl();
|
1660
|
-
const { canPublish
|
1661
|
-
"PublishAction",
|
1662
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1663
|
-
);
|
2062
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1664
2063
|
const { publish } = useDocumentActions();
|
2064
|
+
const [
|
2065
|
+
countDraftRelations,
|
2066
|
+
{ isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
|
2067
|
+
] = useLazyGetDraftRelationCountQuery();
|
2068
|
+
const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React.useState(0);
|
2069
|
+
const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React.useState(0);
|
1665
2070
|
const [{ query, rawQuery }] = useQueryParams();
|
1666
2071
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
1667
2072
|
const modified = useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
@@ -1670,62 +2075,142 @@ const PublishAction$1 = ({
|
|
1670
2075
|
const validate = useForm("PublishAction", (state) => state.validate);
|
1671
2076
|
const setErrors = useForm("PublishAction", (state) => state.setErrors);
|
1672
2077
|
const formValues = useForm("PublishAction", ({ values }) => values);
|
1673
|
-
|
1674
|
-
|
1675
|
-
|
1676
|
-
|
1677
|
-
|
1678
|
-
|
1679
|
-
|
1680
|
-
|
1681
|
-
|
1682
|
-
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
1686
|
-
|
1687
|
-
|
1688
|
-
|
1689
|
-
|
1690
|
-
|
2078
|
+
React.useEffect(() => {
|
2079
|
+
if (isErrorDraftRelations) {
|
2080
|
+
toggleNotification({
|
2081
|
+
type: "danger",
|
2082
|
+
message: formatMessage({
|
2083
|
+
id: getTranslation("error.records.fetch-draft-relatons"),
|
2084
|
+
defaultMessage: "An error occurred while fetching draft relations on this document."
|
2085
|
+
})
|
2086
|
+
});
|
2087
|
+
}
|
2088
|
+
}, [isErrorDraftRelations, toggleNotification, formatMessage]);
|
2089
|
+
React.useEffect(() => {
|
2090
|
+
const localDraftRelations = /* @__PURE__ */ new Set();
|
2091
|
+
const extractDraftRelations = (data) => {
|
2092
|
+
const relations = data.connect || [];
|
2093
|
+
relations.forEach((relation) => {
|
2094
|
+
if (relation.status === "draft") {
|
2095
|
+
localDraftRelations.add(relation.id);
|
2096
|
+
}
|
2097
|
+
});
|
2098
|
+
};
|
2099
|
+
const traverseAndExtract = (data) => {
|
2100
|
+
Object.entries(data).forEach(([key, value]) => {
|
2101
|
+
if (key === "connect" && Array.isArray(value)) {
|
2102
|
+
extractDraftRelations({ connect: value });
|
2103
|
+
} else if (typeof value === "object" && value !== null) {
|
2104
|
+
traverseAndExtract(value);
|
2105
|
+
}
|
2106
|
+
});
|
2107
|
+
};
|
2108
|
+
if (!documentId || modified) {
|
2109
|
+
traverseAndExtract(formValues);
|
2110
|
+
setLocalCountOfDraftRelations(localDraftRelations.size);
|
2111
|
+
}
|
2112
|
+
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
2113
|
+
React.useEffect(() => {
|
2114
|
+
if (!document || !document.documentId || isListView) {
|
2115
|
+
return;
|
2116
|
+
}
|
2117
|
+
const fetchDraftRelationsCount = async () => {
|
2118
|
+
const { data, error } = await countDraftRelations({
|
2119
|
+
collectionType,
|
2120
|
+
model,
|
2121
|
+
documentId,
|
2122
|
+
params
|
2123
|
+
});
|
2124
|
+
if (error) {
|
2125
|
+
throw error;
|
2126
|
+
}
|
2127
|
+
if (data) {
|
2128
|
+
setServerCountOfDraftRelations(data.data);
|
2129
|
+
}
|
2130
|
+
};
|
2131
|
+
fetchDraftRelationsCount();
|
2132
|
+
}, [isListView, document, documentId, countDraftRelations, collectionType, model, params]);
|
2133
|
+
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
2134
|
+
if (!schema?.options?.draftAndPublish) {
|
2135
|
+
return null;
|
2136
|
+
}
|
2137
|
+
const performPublish = async () => {
|
2138
|
+
setSubmitting(true);
|
2139
|
+
try {
|
2140
|
+
const { errors } = await validate();
|
2141
|
+
if (errors) {
|
2142
|
+
toggleNotification({
|
2143
|
+
type: "danger",
|
2144
|
+
message: formatMessage({
|
2145
|
+
id: "content-manager.validation.error",
|
2146
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2147
|
+
})
|
2148
|
+
});
|
2149
|
+
return;
|
2150
|
+
}
|
2151
|
+
const res = await publish(
|
2152
|
+
{
|
2153
|
+
collectionType,
|
2154
|
+
model,
|
2155
|
+
documentId,
|
2156
|
+
params
|
2157
|
+
},
|
2158
|
+
formValues
|
2159
|
+
);
|
2160
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
2161
|
+
navigate({
|
2162
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
2163
|
+
search: rawQuery
|
2164
|
+
});
|
2165
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2166
|
+
setErrors(formatValidationErrors(res.error));
|
2167
|
+
}
|
2168
|
+
} finally {
|
2169
|
+
setSubmitting(false);
|
2170
|
+
}
|
2171
|
+
};
|
2172
|
+
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
2173
|
+
const enableDraftRelationsCount = false;
|
2174
|
+
const hasDraftRelations = enableDraftRelationsCount;
|
2175
|
+
return {
|
2176
|
+
/**
|
2177
|
+
* Disabled when:
|
2178
|
+
* - currently if you're cloning a document we don't support publish & clone at the same time.
|
2179
|
+
* - the form is submitting
|
2180
|
+
* - the active tab is the published tab
|
2181
|
+
* - the document is already published & not modified
|
2182
|
+
* - the document is being created & not modified
|
2183
|
+
* - the user doesn't have the permission to publish
|
2184
|
+
*/
|
2185
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
2186
|
+
label: formatMessage({
|
1691
2187
|
id: "app.utils.publish",
|
1692
2188
|
defaultMessage: "Publish"
|
1693
2189
|
}),
|
1694
2190
|
onClick: async () => {
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
documentId,
|
1713
|
-
params
|
1714
|
-
},
|
1715
|
-
formValues
|
1716
|
-
);
|
1717
|
-
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1718
|
-
navigate({
|
1719
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1720
|
-
search: rawQuery
|
1721
|
-
});
|
1722
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1723
|
-
setErrors(formatValidationErrors(res.error));
|
2191
|
+
await performPublish();
|
2192
|
+
},
|
2193
|
+
dialog: hasDraftRelations ? {
|
2194
|
+
type: "dialog",
|
2195
|
+
variant: "danger",
|
2196
|
+
footer: null,
|
2197
|
+
title: formatMessage({
|
2198
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
|
2199
|
+
defaultMessage: "Confirmation"
|
2200
|
+
}),
|
2201
|
+
content: formatMessage(
|
2202
|
+
{
|
2203
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
2204
|
+
defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
|
2205
|
+
},
|
2206
|
+
{
|
2207
|
+
count: totalDraftRelations
|
1724
2208
|
}
|
1725
|
-
|
1726
|
-
|
2209
|
+
),
|
2210
|
+
onConfirm: async () => {
|
2211
|
+
await performPublish();
|
1727
2212
|
}
|
1728
|
-
}
|
2213
|
+
} : void 0
|
1729
2214
|
};
|
1730
2215
|
};
|
1731
2216
|
PublishAction$1.type = "publish";
|
@@ -1741,10 +2226,6 @@ const UpdateAction = ({
|
|
1741
2226
|
const cloneMatch = useMatch(CLONE_PATH);
|
1742
2227
|
const isCloning = cloneMatch !== null;
|
1743
2228
|
const { formatMessage } = useIntl();
|
1744
|
-
const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1745
|
-
canCreate: canCreate2,
|
1746
|
-
canUpdate: canUpdate2
|
1747
|
-
}));
|
1748
2229
|
const { create, update, clone } = useDocumentActions();
|
1749
2230
|
const [{ query, rawQuery }] = useQueryParams();
|
1750
2231
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
@@ -1761,10 +2242,8 @@ const UpdateAction = ({
|
|
1761
2242
|
* - the form is submitting
|
1762
2243
|
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
1763
2244
|
* - the active tab is the published tab
|
1764
|
-
* - the user doesn't have the permission to create a new document
|
1765
|
-
* - the user doesn't have the permission to update the document
|
1766
2245
|
*/
|
1767
|
-
disabled: isSubmitting || !modified && !isCloning || activeTab === "published"
|
2246
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1768
2247
|
label: formatMessage({
|
1769
2248
|
id: "content-manager.containers.Edit.save",
|
1770
2249
|
defaultMessage: "Save"
|
@@ -1772,16 +2251,18 @@ const UpdateAction = ({
|
|
1772
2251
|
onClick: async () => {
|
1773
2252
|
setSubmitting(true);
|
1774
2253
|
try {
|
1775
|
-
|
1776
|
-
|
1777
|
-
|
1778
|
-
|
1779
|
-
|
1780
|
-
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
-
|
2254
|
+
if (activeTab !== "draft") {
|
2255
|
+
const { errors } = await validate();
|
2256
|
+
if (errors) {
|
2257
|
+
toggleNotification({
|
2258
|
+
type: "danger",
|
2259
|
+
message: formatMessage({
|
2260
|
+
id: "content-manager.validation.error",
|
2261
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2262
|
+
})
|
2263
|
+
});
|
2264
|
+
return;
|
2265
|
+
}
|
1785
2266
|
}
|
1786
2267
|
if (isCloning) {
|
1787
2268
|
const res = await clone(
|
@@ -1793,10 +2274,13 @@ const UpdateAction = ({
|
|
1793
2274
|
document
|
1794
2275
|
);
|
1795
2276
|
if ("data" in res) {
|
1796
|
-
navigate(
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
2277
|
+
navigate(
|
2278
|
+
{
|
2279
|
+
pathname: `../${res.data.documentId}`,
|
2280
|
+
search: rawQuery
|
2281
|
+
},
|
2282
|
+
{ relative: "path" }
|
2283
|
+
);
|
1800
2284
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1801
2285
|
setErrors(formatValidationErrors(res.error));
|
1802
2286
|
}
|
@@ -1826,10 +2310,10 @@ const UpdateAction = ({
|
|
1826
2310
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1827
2311
|
navigate(
|
1828
2312
|
{
|
1829
|
-
pathname: `../${
|
2313
|
+
pathname: `../${res.data.documentId}`,
|
1830
2314
|
search: rawQuery
|
1831
2315
|
},
|
1832
|
-
{ replace: true }
|
2316
|
+
{ replace: true, relative: "path" }
|
1833
2317
|
);
|
1834
2318
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1835
2319
|
setErrors(formatValidationErrors(res.error));
|
@@ -1874,7 +2358,7 @@ const UnpublishAction$1 = ({
|
|
1874
2358
|
id: "app.utils.unpublish",
|
1875
2359
|
defaultMessage: "Unpublish"
|
1876
2360
|
}),
|
1877
|
-
icon: /* @__PURE__ */ jsx(
|
2361
|
+
icon: /* @__PURE__ */ jsx(Cross, {}),
|
1878
2362
|
onClick: async () => {
|
1879
2363
|
if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
|
1880
2364
|
if (!documentId) {
|
@@ -1986,7 +2470,7 @@ const DiscardAction = ({
|
|
1986
2470
|
id: "content-manager.actions.discard.label",
|
1987
2471
|
defaultMessage: "Discard changes"
|
1988
2472
|
}),
|
1989
|
-
icon: /* @__PURE__ */ jsx(
|
2473
|
+
icon: /* @__PURE__ */ jsx(Cross, {}),
|
1990
2474
|
position: ["panel", "table-row"],
|
1991
2475
|
variant: "danger",
|
1992
2476
|
dialog: {
|
@@ -2014,11 +2498,6 @@ const DiscardAction = ({
|
|
2014
2498
|
};
|
2015
2499
|
};
|
2016
2500
|
DiscardAction.type = "discard";
|
2017
|
-
const StyledCrossCircle = styled(CrossCircle)`
|
2018
|
-
path {
|
2019
|
-
fill: currentColor;
|
2020
|
-
}
|
2021
|
-
`;
|
2022
2501
|
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2023
2502
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2024
2503
|
const RelativeTime = React.forwardRef(
|
@@ -2066,7 +2545,7 @@ const getDisplayName = ({
|
|
2066
2545
|
};
|
2067
2546
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2068
2547
|
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2069
|
-
const statusVariant = status === "draft" ? "
|
2548
|
+
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2070
2549
|
return /* @__PURE__ */ jsx(Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: capitalise(status) }) });
|
2071
2550
|
};
|
2072
2551
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
@@ -2076,23 +2555,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
|
2076
2555
|
id: "content-manager.containers.edit.title.new",
|
2077
2556
|
defaultMessage: "Create an entry"
|
2078
2557
|
}) : documentTitle;
|
2079
|
-
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop:
|
2558
|
+
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2080
2559
|
/* @__PURE__ */ jsx(BackButton, {}),
|
2081
|
-
/* @__PURE__ */ jsxs(
|
2082
|
-
|
2083
|
-
{
|
2084
|
-
|
2085
|
-
|
2086
|
-
paddingTop: 1,
|
2087
|
-
gap: "80px",
|
2088
|
-
alignItems: "flex-start",
|
2089
|
-
children: [
|
2090
|
-
/* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
|
2091
|
-
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
2092
|
-
]
|
2093
|
-
}
|
2094
|
-
),
|
2095
|
-
status ? /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) : null
|
2560
|
+
/* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2561
|
+
/* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
|
2562
|
+
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
2563
|
+
] }),
|
2564
|
+
status ? /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
|
2096
2565
|
] });
|
2097
2566
|
};
|
2098
2567
|
const HeaderToolbar = () => {
|
@@ -2259,8 +2728,22 @@ const Information = ({ activeTab }) => {
|
|
2259
2728
|
);
|
2260
2729
|
};
|
2261
2730
|
const HeaderActions = ({ actions: actions2 }) => {
|
2262
|
-
|
2263
|
-
|
2731
|
+
const [dialogId, setDialogId] = React.useState(null);
|
2732
|
+
const handleClick = (action) => async (e) => {
|
2733
|
+
if (!("options" in action)) {
|
2734
|
+
const { onClick = () => false, dialog, id } = action;
|
2735
|
+
const muteDialog = await onClick(e);
|
2736
|
+
if (dialog && !muteDialog) {
|
2737
|
+
e.preventDefault();
|
2738
|
+
setDialogId(id);
|
2739
|
+
}
|
2740
|
+
}
|
2741
|
+
};
|
2742
|
+
const handleClose = () => {
|
2743
|
+
setDialogId(null);
|
2744
|
+
};
|
2745
|
+
return /* @__PURE__ */ jsx(Flex, { gap: 1, children: actions2.map((action) => {
|
2746
|
+
if (action.options) {
|
2264
2747
|
return /* @__PURE__ */ jsx(
|
2265
2748
|
SingleSelect,
|
2266
2749
|
{
|
@@ -2274,10 +2757,49 @@ const HeaderActions = ({ actions: actions2 }) => {
|
|
2274
2757
|
action.id
|
2275
2758
|
);
|
2276
2759
|
} else {
|
2277
|
-
|
2760
|
+
if (action.type === "icon") {
|
2761
|
+
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
2762
|
+
/* @__PURE__ */ jsx(
|
2763
|
+
IconButton,
|
2764
|
+
{
|
2765
|
+
disabled: action.disabled,
|
2766
|
+
label: action.label,
|
2767
|
+
size: "S",
|
2768
|
+
onClick: handleClick(action),
|
2769
|
+
children: action.icon
|
2770
|
+
}
|
2771
|
+
),
|
2772
|
+
action.dialog ? /* @__PURE__ */ jsx(
|
2773
|
+
HeaderActionDialog,
|
2774
|
+
{
|
2775
|
+
...action.dialog,
|
2776
|
+
isOpen: dialogId === action.id,
|
2777
|
+
onClose: handleClose
|
2778
|
+
}
|
2779
|
+
) : null
|
2780
|
+
] }, action.id);
|
2781
|
+
}
|
2278
2782
|
}
|
2279
2783
|
}) });
|
2280
2784
|
};
|
2785
|
+
const HeaderActionDialog = ({
|
2786
|
+
onClose,
|
2787
|
+
onCancel,
|
2788
|
+
title,
|
2789
|
+
content: Content,
|
2790
|
+
isOpen
|
2791
|
+
}) => {
|
2792
|
+
const handleClose = async () => {
|
2793
|
+
if (onCancel) {
|
2794
|
+
await onCancel();
|
2795
|
+
}
|
2796
|
+
onClose();
|
2797
|
+
};
|
2798
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
2799
|
+
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
2800
|
+
typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : Content
|
2801
|
+
] }) });
|
2802
|
+
};
|
2281
2803
|
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
2282
2804
|
const navigate = useNavigate();
|
2283
2805
|
const { formatMessage } = useIntl();
|
@@ -2318,12 +2840,16 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2318
2840
|
const { delete: deleteAction } = useDocumentActions();
|
2319
2841
|
const { toggleNotification } = useNotification();
|
2320
2842
|
const setSubmitting = useForm("DeleteAction", (state) => state.setSubmitting);
|
2843
|
+
const isLocalized = document?.locale != null;
|
2321
2844
|
return {
|
2322
2845
|
disabled: !canDelete || !document,
|
2323
|
-
label: formatMessage(
|
2324
|
-
|
2325
|
-
|
2326
|
-
|
2846
|
+
label: formatMessage(
|
2847
|
+
{
|
2848
|
+
id: "content-manager.actions.delete.label",
|
2849
|
+
defaultMessage: "Delete entry{isLocalized, select, true { (all locales)} other {}}"
|
2850
|
+
},
|
2851
|
+
{ isLocalized }
|
2852
|
+
),
|
2327
2853
|
icon: /* @__PURE__ */ jsx(Trash, {}),
|
2328
2854
|
dialog: {
|
2329
2855
|
type: "dialog",
|
@@ -2354,428 +2880,126 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2354
2880
|
}),
|
2355
2881
|
type: "danger"
|
2356
2882
|
});
|
2357
|
-
return;
|
2358
|
-
}
|
2359
|
-
const res = await deleteAction({
|
2360
|
-
documentId,
|
2361
|
-
model,
|
2362
|
-
collectionType,
|
2363
|
-
params: {
|
2364
|
-
locale: "*"
|
2365
|
-
}
|
2366
|
-
});
|
2367
|
-
if (!("error" in res)) {
|
2368
|
-
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
2369
|
-
}
|
2370
|
-
} finally {
|
2371
|
-
if (!listViewPathMatch) {
|
2372
|
-
setSubmitting(false);
|
2373
|
-
}
|
2374
|
-
}
|
2375
|
-
}
|
2376
|
-
},
|
2377
|
-
variant: "danger",
|
2378
|
-
position: ["header", "table-row"]
|
2379
|
-
};
|
2380
|
-
};
|
2381
|
-
DeleteAction$1.type = "delete";
|
2382
|
-
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2383
|
-
const Panels = () => {
|
2384
|
-
const isCloning = useMatch(CLONE_PATH) !== null;
|
2385
|
-
const [
|
2386
|
-
{
|
2387
|
-
query: { status }
|
2388
|
-
}
|
2389
|
-
] = useQueryParams({
|
2390
|
-
status: "draft"
|
2391
|
-
});
|
2392
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2393
|
-
const plugins = useStrapiApp("Panels", (state) => state.plugins);
|
2394
|
-
const props = {
|
2395
|
-
activeTab: status,
|
2396
|
-
model,
|
2397
|
-
documentId: id,
|
2398
|
-
document: isCloning ? void 0 : document,
|
2399
|
-
meta: isCloning ? void 0 : meta,
|
2400
|
-
collectionType
|
2401
|
-
};
|
2402
|
-
return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsx(
|
2403
|
-
DescriptionComponentRenderer,
|
2404
|
-
{
|
2405
|
-
props,
|
2406
|
-
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2407
|
-
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsx(Panel, { ...description, children: content }, id2))
|
2408
|
-
}
|
2409
|
-
) });
|
2410
|
-
};
|
2411
|
-
const ActionsPanel = () => {
|
2412
|
-
const { formatMessage } = useIntl();
|
2413
|
-
return {
|
2414
|
-
title: formatMessage({
|
2415
|
-
id: "content-manager.containers.edit.panels.default.title",
|
2416
|
-
defaultMessage: "Document"
|
2417
|
-
}),
|
2418
|
-
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2419
|
-
};
|
2420
|
-
};
|
2421
|
-
ActionsPanel.type = "actions";
|
2422
|
-
const ActionsPanelContent = () => {
|
2423
|
-
const isCloning = useMatch(CLONE_PATH) !== null;
|
2424
|
-
const [
|
2425
|
-
{
|
2426
|
-
query: { status = "draft" }
|
2427
|
-
}
|
2428
|
-
] = useQueryParams();
|
2429
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2430
|
-
const plugins = useStrapiApp("ActionsPanel", (state) => state.plugins);
|
2431
|
-
const props = {
|
2432
|
-
activeTab: status,
|
2433
|
-
model,
|
2434
|
-
documentId: id,
|
2435
|
-
document: isCloning ? void 0 : document,
|
2436
|
-
meta: isCloning ? void 0 : meta,
|
2437
|
-
collectionType
|
2438
|
-
};
|
2439
|
-
return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
|
2440
|
-
/* @__PURE__ */ jsx(
|
2441
|
-
DescriptionComponentRenderer,
|
2442
|
-
{
|
2443
|
-
props,
|
2444
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2445
|
-
children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
|
2446
|
-
}
|
2447
|
-
),
|
2448
|
-
/* @__PURE__ */ jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
2449
|
-
] });
|
2450
|
-
};
|
2451
|
-
const Panel = React.forwardRef(({ children, title }, ref) => {
|
2452
|
-
return /* @__PURE__ */ jsxs(
|
2453
|
-
Flex,
|
2454
|
-
{
|
2455
|
-
ref,
|
2456
|
-
tag: "aside",
|
2457
|
-
"aria-labelledby": "additional-information",
|
2458
|
-
background: "neutral0",
|
2459
|
-
borderColor: "neutral150",
|
2460
|
-
hasRadius: true,
|
2461
|
-
paddingBottom: 4,
|
2462
|
-
paddingLeft: 4,
|
2463
|
-
paddingRight: 4,
|
2464
|
-
paddingTop: 4,
|
2465
|
-
shadow: "tableShadow",
|
2466
|
-
gap: 3,
|
2467
|
-
direction: "column",
|
2468
|
-
justifyContent: "stretch",
|
2469
|
-
alignItems: "flex-start",
|
2470
|
-
children: [
|
2471
|
-
/* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2472
|
-
children
|
2473
|
-
]
|
2474
|
-
}
|
2475
|
-
);
|
2476
|
-
});
|
2477
|
-
const HOOKS = {
|
2478
|
-
/**
|
2479
|
-
* Hook that allows to mutate the displayed headers of the list view table
|
2480
|
-
* @constant
|
2481
|
-
* @type {string}
|
2482
|
-
*/
|
2483
|
-
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2484
|
-
/**
|
2485
|
-
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2486
|
-
* @constant
|
2487
|
-
* @type {string}
|
2488
|
-
*/
|
2489
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2490
|
-
/**
|
2491
|
-
* Hook that allows to mutate the CM's edit view layout
|
2492
|
-
* @constant
|
2493
|
-
* @type {string}
|
2494
|
-
*/
|
2495
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2496
|
-
/**
|
2497
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
2498
|
-
* @constant
|
2499
|
-
* @type {string}
|
2500
|
-
*/
|
2501
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2502
|
-
};
|
2503
|
-
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2504
|
-
endpoints: (builder) => ({
|
2505
|
-
getContentTypeConfiguration: builder.query({
|
2506
|
-
query: (uid) => ({
|
2507
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2508
|
-
method: "GET"
|
2509
|
-
}),
|
2510
|
-
transformResponse: (response) => response.data,
|
2511
|
-
providesTags: (_result, _error, uid) => [
|
2512
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2513
|
-
{ type: "ContentTypeSettings", id: "LIST" }
|
2514
|
-
]
|
2515
|
-
}),
|
2516
|
-
getAllContentTypeSettings: builder.query({
|
2517
|
-
query: () => "/content-manager/content-types-settings",
|
2518
|
-
transformResponse: (response) => response.data,
|
2519
|
-
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2520
|
-
}),
|
2521
|
-
updateContentTypeConfiguration: builder.mutation({
|
2522
|
-
query: ({ uid, ...body }) => ({
|
2523
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2524
|
-
method: "PUT",
|
2525
|
-
data: body
|
2526
|
-
}),
|
2527
|
-
transformResponse: (response) => response.data,
|
2528
|
-
invalidatesTags: (_result, _error, { uid }) => [
|
2529
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2530
|
-
{ type: "ContentTypeSettings", id: "LIST" },
|
2531
|
-
// Is this necessary?
|
2532
|
-
{ type: "InitialData" }
|
2533
|
-
]
|
2534
|
-
})
|
2535
|
-
})
|
2536
|
-
});
|
2537
|
-
const {
|
2538
|
-
useGetContentTypeConfigurationQuery,
|
2539
|
-
useGetAllContentTypeSettingsQuery,
|
2540
|
-
useUpdateContentTypeConfigurationMutation
|
2541
|
-
} = contentTypesApi;
|
2542
|
-
const checkIfAttributeIsDisplayable = (attribute) => {
|
2543
|
-
const { type } = attribute;
|
2544
|
-
if (type === "relation") {
|
2545
|
-
return !attribute.relation.toLowerCase().includes("morph");
|
2546
|
-
}
|
2547
|
-
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2548
|
-
};
|
2549
|
-
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2550
|
-
if (!mainFieldName) {
|
2551
|
-
return void 0;
|
2552
|
-
}
|
2553
|
-
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2554
|
-
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2555
|
-
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2556
|
-
);
|
2557
|
-
return {
|
2558
|
-
name: mainFieldName,
|
2559
|
-
type: mainFieldType ?? "string"
|
2560
|
-
};
|
2561
|
-
};
|
2562
|
-
const DEFAULT_SETTINGS = {
|
2563
|
-
bulkable: false,
|
2564
|
-
filterable: false,
|
2565
|
-
searchable: false,
|
2566
|
-
pagination: false,
|
2567
|
-
defaultSortBy: "",
|
2568
|
-
defaultSortOrder: "asc",
|
2569
|
-
mainField: "id",
|
2570
|
-
pageSize: 10
|
2571
|
-
};
|
2572
|
-
const useDocumentLayout = (model) => {
|
2573
|
-
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2574
|
-
const [{ query }] = useQueryParams();
|
2575
|
-
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2576
|
-
const { toggleNotification } = useNotification();
|
2577
|
-
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
2578
|
-
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2579
|
-
const {
|
2580
|
-
data,
|
2581
|
-
isLoading: isLoadingConfigs,
|
2582
|
-
error,
|
2583
|
-
isFetching: isFetchingConfigs
|
2584
|
-
} = useGetContentTypeConfigurationQuery(model);
|
2585
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2586
|
-
React.useEffect(() => {
|
2587
|
-
if (error) {
|
2588
|
-
toggleNotification({
|
2589
|
-
type: "danger",
|
2590
|
-
message: formatAPIError(error)
|
2591
|
-
});
|
2592
|
-
}
|
2593
|
-
}, [error, formatAPIError, toggleNotification]);
|
2594
|
-
const editLayout = React.useMemo(
|
2595
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2596
|
-
layout: [],
|
2597
|
-
components: {},
|
2598
|
-
metadatas: {},
|
2599
|
-
options: {},
|
2600
|
-
settings: DEFAULT_SETTINGS
|
2601
|
-
},
|
2602
|
-
[data, isLoading, schemas, schema, components]
|
2603
|
-
);
|
2604
|
-
const listLayout = React.useMemo(() => {
|
2605
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2606
|
-
layout: [],
|
2607
|
-
metadatas: {},
|
2608
|
-
options: {},
|
2609
|
-
settings: DEFAULT_SETTINGS
|
2610
|
-
};
|
2611
|
-
}, [data, isLoading, schemas, schema, components]);
|
2612
|
-
const { layout: edit } = React.useMemo(
|
2613
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2614
|
-
layout: editLayout,
|
2615
|
-
query
|
2616
|
-
}),
|
2617
|
-
[editLayout, query, runHookWaterfall]
|
2618
|
-
);
|
2619
|
-
return {
|
2620
|
-
error,
|
2621
|
-
isLoading,
|
2622
|
-
edit,
|
2623
|
-
list: listLayout
|
2624
|
-
};
|
2625
|
-
};
|
2626
|
-
const useDocLayout = () => {
|
2627
|
-
const { model } = useDoc();
|
2628
|
-
return useDocumentLayout(model);
|
2629
|
-
};
|
2630
|
-
const formatEditLayout = (data, {
|
2631
|
-
schemas,
|
2632
|
-
schema,
|
2633
|
-
components
|
2634
|
-
}) => {
|
2635
|
-
let currentPanelIndex = 0;
|
2636
|
-
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2637
|
-
data.contentType.layouts.edit,
|
2638
|
-
schema?.attributes,
|
2639
|
-
data.contentType.metadatas,
|
2640
|
-
{ configurations: data.components, schemas: components },
|
2641
|
-
schemas
|
2642
|
-
).reduce((panels, row) => {
|
2643
|
-
if (row.some((field) => field.type === "dynamiczone")) {
|
2644
|
-
panels.push([row]);
|
2645
|
-
currentPanelIndex += 2;
|
2646
|
-
} else {
|
2647
|
-
if (!panels[currentPanelIndex]) {
|
2648
|
-
panels.push([]);
|
2649
|
-
}
|
2650
|
-
panels[currentPanelIndex].push(row);
|
2651
|
-
}
|
2652
|
-
return panels;
|
2653
|
-
}, []);
|
2654
|
-
const componentEditAttributes = Object.entries(data.components).reduce(
|
2655
|
-
(acc, [uid, configuration]) => {
|
2656
|
-
acc[uid] = {
|
2657
|
-
layout: convertEditLayoutToFieldLayouts(
|
2658
|
-
configuration.layouts.edit,
|
2659
|
-
components[uid].attributes,
|
2660
|
-
configuration.metadatas
|
2661
|
-
),
|
2662
|
-
settings: {
|
2663
|
-
...configuration.settings,
|
2664
|
-
icon: components[uid].info.icon,
|
2665
|
-
displayName: components[uid].info.displayName
|
2883
|
+
return;
|
2884
|
+
}
|
2885
|
+
const res = await deleteAction({
|
2886
|
+
documentId,
|
2887
|
+
model,
|
2888
|
+
collectionType,
|
2889
|
+
params: {
|
2890
|
+
locale: "*"
|
2891
|
+
}
|
2892
|
+
});
|
2893
|
+
if (!("error" in res)) {
|
2894
|
+
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
2895
|
+
}
|
2896
|
+
} finally {
|
2897
|
+
if (!listViewPathMatch) {
|
2898
|
+
setSubmitting(false);
|
2899
|
+
}
|
2666
2900
|
}
|
2667
|
-
}
|
2668
|
-
return acc;
|
2669
|
-
},
|
2670
|
-
{}
|
2671
|
-
);
|
2672
|
-
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2673
|
-
(acc, [attribute, metadata]) => {
|
2674
|
-
return {
|
2675
|
-
...acc,
|
2676
|
-
[attribute]: metadata.edit
|
2677
|
-
};
|
2678
|
-
},
|
2679
|
-
{}
|
2680
|
-
);
|
2681
|
-
return {
|
2682
|
-
layout: panelledEditAttributes,
|
2683
|
-
components: componentEditAttributes,
|
2684
|
-
metadatas: editMetadatas,
|
2685
|
-
settings: {
|
2686
|
-
...data.contentType.settings,
|
2687
|
-
displayName: schema?.info.displayName
|
2901
|
+
}
|
2688
2902
|
},
|
2689
|
-
|
2690
|
-
|
2691
|
-
...schema?.pluginOptions,
|
2692
|
-
...data.contentType.options
|
2693
|
-
}
|
2903
|
+
variant: "danger",
|
2904
|
+
position: ["header", "table-row"]
|
2694
2905
|
};
|
2695
2906
|
};
|
2696
|
-
|
2697
|
-
|
2698
|
-
|
2699
|
-
|
2700
|
-
|
2701
|
-
|
2702
|
-
}
|
2703
|
-
|
2704
|
-
|
2705
|
-
|
2706
|
-
|
2707
|
-
|
2708
|
-
|
2709
|
-
|
2710
|
-
|
2711
|
-
|
2712
|
-
|
2713
|
-
|
2714
|
-
|
2715
|
-
|
2716
|
-
|
2717
|
-
|
2718
|
-
|
2719
|
-
|
2720
|
-
|
2721
|
-
|
2722
|
-
}
|
2723
|
-
}
|
2724
|
-
);
|
2907
|
+
DeleteAction$1.type = "delete";
|
2908
|
+
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2909
|
+
const Panels = () => {
|
2910
|
+
const isCloning = useMatch(CLONE_PATH) !== null;
|
2911
|
+
const [
|
2912
|
+
{
|
2913
|
+
query: { status }
|
2914
|
+
}
|
2915
|
+
] = useQueryParams({
|
2916
|
+
status: "draft"
|
2917
|
+
});
|
2918
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
2919
|
+
const plugins = useStrapiApp("Panels", (state) => state.plugins);
|
2920
|
+
const props = {
|
2921
|
+
activeTab: status,
|
2922
|
+
model,
|
2923
|
+
documentId: id,
|
2924
|
+
document: isCloning ? void 0 : document,
|
2925
|
+
meta: isCloning ? void 0 : meta,
|
2926
|
+
collectionType
|
2927
|
+
};
|
2928
|
+
return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsx(
|
2929
|
+
DescriptionComponentRenderer,
|
2930
|
+
{
|
2931
|
+
props,
|
2932
|
+
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2933
|
+
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsx(Panel, { ...description, children: content }, id2))
|
2934
|
+
}
|
2935
|
+
) });
|
2725
2936
|
};
|
2726
|
-
const
|
2727
|
-
|
2728
|
-
schema,
|
2729
|
-
components
|
2730
|
-
}) => {
|
2731
|
-
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2732
|
-
(acc, [attribute, metadata]) => {
|
2733
|
-
return {
|
2734
|
-
...acc,
|
2735
|
-
[attribute]: metadata.list
|
2736
|
-
};
|
2737
|
-
},
|
2738
|
-
{}
|
2739
|
-
);
|
2740
|
-
const listAttributes = convertListLayoutToFieldLayouts(
|
2741
|
-
data.contentType.layouts.list,
|
2742
|
-
schema?.attributes,
|
2743
|
-
listMetadatas,
|
2744
|
-
{ configurations: data.components, schemas: components },
|
2745
|
-
schemas
|
2746
|
-
);
|
2937
|
+
const ActionsPanel = () => {
|
2938
|
+
const { formatMessage } = useIntl();
|
2747
2939
|
return {
|
2748
|
-
|
2749
|
-
|
2750
|
-
|
2751
|
-
|
2752
|
-
|
2753
|
-
...schema?.pluginOptions,
|
2754
|
-
...data.contentType.options
|
2755
|
-
}
|
2940
|
+
title: formatMessage({
|
2941
|
+
id: "content-manager.containers.edit.panels.default.title",
|
2942
|
+
defaultMessage: "Entry"
|
2943
|
+
}),
|
2944
|
+
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2756
2945
|
};
|
2757
2946
|
};
|
2758
|
-
|
2759
|
-
|
2760
|
-
|
2761
|
-
|
2762
|
-
|
2947
|
+
ActionsPanel.type = "actions";
|
2948
|
+
const ActionsPanelContent = () => {
|
2949
|
+
const isCloning = useMatch(CLONE_PATH) !== null;
|
2950
|
+
const [
|
2951
|
+
{
|
2952
|
+
query: { status = "draft" }
|
2763
2953
|
}
|
2764
|
-
|
2765
|
-
|
2766
|
-
|
2767
|
-
|
2768
|
-
|
2769
|
-
|
2770
|
-
|
2771
|
-
|
2772
|
-
|
2773
|
-
|
2774
|
-
|
2775
|
-
|
2776
|
-
|
2777
|
-
|
2954
|
+
] = useQueryParams();
|
2955
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
2956
|
+
const plugins = useStrapiApp("ActionsPanel", (state) => state.plugins);
|
2957
|
+
const props = {
|
2958
|
+
activeTab: status,
|
2959
|
+
model,
|
2960
|
+
documentId: id,
|
2961
|
+
document: isCloning ? void 0 : document,
|
2962
|
+
meta: isCloning ? void 0 : meta,
|
2963
|
+
collectionType
|
2964
|
+
};
|
2965
|
+
return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
|
2966
|
+
/* @__PURE__ */ jsx(
|
2967
|
+
DescriptionComponentRenderer,
|
2968
|
+
{
|
2969
|
+
props,
|
2970
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2971
|
+
children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
|
2972
|
+
}
|
2973
|
+
),
|
2974
|
+
/* @__PURE__ */ jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
2975
|
+
] });
|
2778
2976
|
};
|
2977
|
+
const Panel = React.forwardRef(({ children, title }, ref) => {
|
2978
|
+
return /* @__PURE__ */ jsxs(
|
2979
|
+
Flex,
|
2980
|
+
{
|
2981
|
+
ref,
|
2982
|
+
tag: "aside",
|
2983
|
+
"aria-labelledby": "additional-information",
|
2984
|
+
background: "neutral0",
|
2985
|
+
borderColor: "neutral150",
|
2986
|
+
hasRadius: true,
|
2987
|
+
paddingBottom: 4,
|
2988
|
+
paddingLeft: 4,
|
2989
|
+
paddingRight: 4,
|
2990
|
+
paddingTop: 4,
|
2991
|
+
shadow: "tableShadow",
|
2992
|
+
gap: 3,
|
2993
|
+
direction: "column",
|
2994
|
+
justifyContent: "stretch",
|
2995
|
+
alignItems: "flex-start",
|
2996
|
+
children: [
|
2997
|
+
/* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2998
|
+
children
|
2999
|
+
]
|
3000
|
+
}
|
3001
|
+
);
|
3002
|
+
});
|
2779
3003
|
const ConfirmBulkActionDialog = ({
|
2780
3004
|
onToggleDialog,
|
2781
3005
|
isOpen = false,
|
@@ -2783,7 +3007,7 @@ const ConfirmBulkActionDialog = ({
|
|
2783
3007
|
endAction
|
2784
3008
|
}) => {
|
2785
3009
|
const { formatMessage } = useIntl();
|
2786
|
-
return /* @__PURE__ */ jsx(Dialog.Root, {
|
3010
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
2787
3011
|
/* @__PURE__ */ jsx(Dialog.Header, { children: formatMessage({
|
2788
3012
|
id: "app.components.ConfirmDialog.title",
|
2789
3013
|
defaultMessage: "Confirmation"
|
@@ -2814,6 +3038,7 @@ const ConfirmDialogPublishAll = ({
|
|
2814
3038
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(getTranslation);
|
2815
3039
|
const { model, schema } = useDoc();
|
2816
3040
|
const [{ query }] = useQueryParams();
|
3041
|
+
const enableDraftRelationsCount = false;
|
2817
3042
|
const {
|
2818
3043
|
data: countDraftRelations = 0,
|
2819
3044
|
isLoading,
|
@@ -2825,7 +3050,7 @@ const ConfirmDialogPublishAll = ({
|
|
2825
3050
|
locale: query?.plugins?.i18n?.locale
|
2826
3051
|
},
|
2827
3052
|
{
|
2828
|
-
skip:
|
3053
|
+
skip: !enableDraftRelationsCount
|
2829
3054
|
}
|
2830
3055
|
);
|
2831
3056
|
React.useEffect(() => {
|
@@ -3010,7 +3235,7 @@ const SelectedEntriesTableContent = ({
|
|
3010
3235
|
status: row.status
|
3011
3236
|
}
|
3012
3237
|
) }),
|
3013
|
-
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(
|
3238
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
|
3014
3239
|
IconButton,
|
3015
3240
|
{
|
3016
3241
|
tag: Link,
|
@@ -3033,9 +3258,10 @@ const SelectedEntriesTableContent = ({
|
|
3033
3258
|
),
|
3034
3259
|
target: "_blank",
|
3035
3260
|
marginLeft: "auto",
|
3036
|
-
|
3261
|
+
variant: "ghost",
|
3262
|
+
children: /* @__PURE__ */ jsx(Pencil, { width: "1.6rem", height: "1.6rem" })
|
3037
3263
|
}
|
3038
|
-
) })
|
3264
|
+
) }) })
|
3039
3265
|
] }, row.id)) })
|
3040
3266
|
] });
|
3041
3267
|
};
|
@@ -3072,7 +3298,13 @@ const SelectedEntriesModalContent = ({
|
|
3072
3298
|
);
|
3073
3299
|
const { rows, validationErrors } = React.useMemo(() => {
|
3074
3300
|
if (data.length > 0 && schema) {
|
3075
|
-
const validate = createYupSchema(
|
3301
|
+
const validate = createYupSchema(
|
3302
|
+
schema.attributes,
|
3303
|
+
components,
|
3304
|
+
// Since this is the "Publish" action, the validation
|
3305
|
+
// schema must enforce the rules for published entities
|
3306
|
+
{ status: "published" }
|
3307
|
+
);
|
3076
3308
|
const validationErrors2 = {};
|
3077
3309
|
const rows2 = data.map((entry) => {
|
3078
3310
|
try {
|
@@ -3422,7 +3654,7 @@ const TableActions = ({ document }) => {
|
|
3422
3654
|
DescriptionComponentRenderer,
|
3423
3655
|
{
|
3424
3656
|
props,
|
3425
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3657
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
3426
3658
|
children: (actions2) => {
|
3427
3659
|
const tableRowActions = actions2.filter((action) => {
|
3428
3660
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3533,7 +3765,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3533
3765
|
}),
|
3534
3766
|
content: /* @__PURE__ */ jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
3535
3767
|
footer: ({ onClose }) => {
|
3536
|
-
return /* @__PURE__ */ jsxs(
|
3768
|
+
return /* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
3537
3769
|
/* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
3538
3770
|
id: "cancel",
|
3539
3771
|
defaultMessage: "Cancel"
|
@@ -3574,8 +3806,7 @@ class ContentManagerPlugin {
|
|
3574
3806
|
documentActions = [
|
3575
3807
|
...DEFAULT_ACTIONS,
|
3576
3808
|
...DEFAULT_TABLE_ROW_ACTIONS,
|
3577
|
-
...DEFAULT_HEADER_ACTIONS
|
3578
|
-
HistoryAction
|
3809
|
+
...DEFAULT_HEADER_ACTIONS
|
3579
3810
|
];
|
3580
3811
|
editViewSidePanels = [ActionsPanel];
|
3581
3812
|
headerActions = [];
|
@@ -3664,6 +3895,52 @@ const getPrintableType = (value) => {
|
|
3664
3895
|
}
|
3665
3896
|
return nativeType;
|
3666
3897
|
};
|
3898
|
+
const HistoryAction = ({ model, document }) => {
|
3899
|
+
const { formatMessage } = useIntl();
|
3900
|
+
const [{ query }] = useQueryParams();
|
3901
|
+
const navigate = useNavigate();
|
3902
|
+
const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
|
3903
|
+
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3904
|
+
return null;
|
3905
|
+
}
|
3906
|
+
return {
|
3907
|
+
icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
|
3908
|
+
label: formatMessage({
|
3909
|
+
id: "content-manager.history.document-action",
|
3910
|
+
defaultMessage: "Content History"
|
3911
|
+
}),
|
3912
|
+
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
3913
|
+
disabled: (
|
3914
|
+
/**
|
3915
|
+
* The user is creating a new document.
|
3916
|
+
* It hasn't been saved yet, so there's no history to go to
|
3917
|
+
*/
|
3918
|
+
!document || /**
|
3919
|
+
* The document has been created but the current dimension has never been saved.
|
3920
|
+
* For example, the user is creating a new locale in an existing document,
|
3921
|
+
* so there's no history for the document in that locale
|
3922
|
+
*/
|
3923
|
+
!document.id || /**
|
3924
|
+
* History is only available for content types created by the user.
|
3925
|
+
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
3926
|
+
* which start with `admin::` or `plugin::`
|
3927
|
+
*/
|
3928
|
+
!model.startsWith("api::")
|
3929
|
+
),
|
3930
|
+
position: "header"
|
3931
|
+
};
|
3932
|
+
};
|
3933
|
+
HistoryAction.type = "history";
|
3934
|
+
const historyAdmin = {
|
3935
|
+
bootstrap(app) {
|
3936
|
+
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
3937
|
+
addDocumentAction((actions2) => {
|
3938
|
+
const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
|
3939
|
+
actions2.splice(indexOfDeleteAction, 0, HistoryAction);
|
3940
|
+
return actions2;
|
3941
|
+
});
|
3942
|
+
}
|
3943
|
+
};
|
3667
3944
|
const initialState = {
|
3668
3945
|
collectionTypeLinks: [],
|
3669
3946
|
components: [],
|
@@ -3719,7 +3996,7 @@ const index = {
|
|
3719
3996
|
app.router.addRoute({
|
3720
3997
|
path: "content-manager/*",
|
3721
3998
|
lazy: async () => {
|
3722
|
-
const { Layout } = await import("./layout-
|
3999
|
+
const { Layout } = await import("./layout-B4UhJ8MJ.mjs");
|
3723
4000
|
return {
|
3724
4001
|
Component: Layout
|
3725
4002
|
};
|
@@ -3728,10 +4005,15 @@ const index = {
|
|
3728
4005
|
});
|
3729
4006
|
app.registerPlugin(cm.config);
|
3730
4007
|
},
|
4008
|
+
bootstrap(app) {
|
4009
|
+
if (typeof historyAdmin.bootstrap === "function") {
|
4010
|
+
historyAdmin.bootstrap(app);
|
4011
|
+
}
|
4012
|
+
},
|
3731
4013
|
async registerTrads({ locales }) {
|
3732
4014
|
const importedTrads = await Promise.all(
|
3733
4015
|
locales.map((locale) => {
|
3734
|
-
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-
|
4016
|
+
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-C8YBvRrK.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 }) => {
|
3735
4017
|
return {
|
3736
4018
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3737
4019
|
locale
|
@@ -3752,13 +4034,15 @@ export {
|
|
3752
4034
|
BulkActionsRenderer as B,
|
3753
4035
|
COLLECTION_TYPES as C,
|
3754
4036
|
DocumentStatus as D,
|
3755
|
-
|
3756
|
-
|
3757
|
-
|
4037
|
+
extractContentTypeComponents as E,
|
4038
|
+
DEFAULT_SETTINGS as F,
|
4039
|
+
convertEditLayoutToFieldLayouts as G,
|
3758
4040
|
HOOKS as H,
|
3759
4041
|
InjectionZone as I,
|
3760
|
-
|
3761
|
-
|
4042
|
+
useDocument as J,
|
4043
|
+
index as K,
|
4044
|
+
useContentManagerContext as L,
|
4045
|
+
useDocumentActions as M,
|
3762
4046
|
Panels as P,
|
3763
4047
|
RelativeTime as R,
|
3764
4048
|
SINGLE_TYPES as S,
|
@@ -3776,18 +4060,18 @@ export {
|
|
3776
4060
|
PERMISSIONS as k,
|
3777
4061
|
DocumentRBAC as l,
|
3778
4062
|
DOCUMENT_META_FIELDS as m,
|
3779
|
-
|
3780
|
-
|
3781
|
-
|
3782
|
-
|
3783
|
-
|
4063
|
+
CLONE_PATH as n,
|
4064
|
+
useDocLayout as o,
|
4065
|
+
useGetContentTypeConfigurationQuery as p,
|
4066
|
+
CREATOR_FIELDS as q,
|
4067
|
+
getMainField as r,
|
3784
4068
|
setInitialData as s,
|
3785
|
-
|
4069
|
+
getDisplayName as t,
|
3786
4070
|
useContentTypeSchema as u,
|
3787
|
-
|
3788
|
-
|
3789
|
-
|
3790
|
-
|
3791
|
-
|
4071
|
+
checkIfAttributeIsDisplayable as v,
|
4072
|
+
useGetAllDocumentsQuery as w,
|
4073
|
+
convertListLayoutToFieldLayouts as x,
|
4074
|
+
capitalise as y,
|
4075
|
+
useUpdateContentTypeConfigurationMutation as z
|
3792
4076
|
};
|
3793
|
-
//# sourceMappingURL=index-
|
4077
|
+
//# sourceMappingURL=index-CPCHQ3X_.mjs.map
|