@strapi/content-manager 0.0.0-experimental.a53a4b1c8f7981a689823cdd719105671e1c6392 → 0.0.0-experimental.a6728ad43ac70ae19dabb624dbfca1f2d9610a86
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-DmwmiFQy.mjs → ComponentConfigurationPage-DJ5voqEK.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-DmwmiFQy.mjs.map → ComponentConfigurationPage-DJ5voqEK.mjs.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-C-49MccQ.js → ComponentConfigurationPage-_6osrv39.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-C-49MccQ.js.map → ComponentConfigurationPage-_6osrv39.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-JT3E7NZy.mjs → EditConfigurationPage-CZofxSLy.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-JT3E7NZy.mjs.map → EditConfigurationPage-CZofxSLy.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-DjFJw56M.js → EditConfigurationPage-ZN3s568V.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-DjFJw56M.js.map → EditConfigurationPage-ZN3s568V.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-zT3fBr4Y.js → EditViewPage-Co2IKQZH.js} +19 -8
- package/dist/_chunks/EditViewPage-Co2IKQZH.js.map +1 -0
- package/dist/_chunks/{EditViewPage-CPj61RMh.mjs → EditViewPage-HYljoEY7.mjs} +19 -8
- package/dist/_chunks/EditViewPage-HYljoEY7.mjs.map +1 -0
- package/dist/_chunks/{Field-dha5VnIQ.mjs → Field-BOPUMZ1u.mjs} +194 -141
- package/dist/_chunks/Field-BOPUMZ1u.mjs.map +1 -0
- package/dist/_chunks/{Field-Boxf9Ajp.js → Field-G9CkFUtP.js} +196 -143
- package/dist/_chunks/Field-G9CkFUtP.js.map +1 -0
- package/dist/_chunks/{Form-DHrru2AV.mjs → Form-CDwNp7pU.mjs} +35 -16
- package/dist/_chunks/Form-CDwNp7pU.mjs.map +1 -0
- package/dist/_chunks/{Form-y5g1SRsh.js → Form-crsbkGxI.js} +35 -16
- package/dist/_chunks/Form-crsbkGxI.js.map +1 -0
- package/dist/_chunks/{History-Bru_KoeP.mjs → History-BDZrgfZ3.mjs} +44 -19
- package/dist/_chunks/History-BDZrgfZ3.mjs.map +1 -0
- package/dist/_chunks/{History-CqN6K7SX.js → History-CWcM9HnW.js} +44 -19
- package/dist/_chunks/History-CWcM9HnW.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-D8wGABj0.mjs → ListConfigurationPage-BZ3ScUna.mjs} +20 -8
- package/dist/_chunks/ListConfigurationPage-BZ3ScUna.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-R_p-SbHZ.js → ListConfigurationPage-DGzoQD_I.js} +20 -8
- package/dist/_chunks/ListConfigurationPage-DGzoQD_I.js.map +1 -0
- package/dist/_chunks/{ListViewPage-pEw_zug9.js → ListViewPage-BBAC9aPu.js} +60 -42
- package/dist/_chunks/ListViewPage-BBAC9aPu.js.map +1 -0
- package/dist/_chunks/{ListViewPage-SID6TRb9.mjs → ListViewPage-CsX7tWx-.mjs} +58 -40
- package/dist/_chunks/ListViewPage-CsX7tWx-.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-C5dcQojD.js → NoContentTypePage-CwVDx_YC.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-C5dcQojD.js.map → NoContentTypePage-CwVDx_YC.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-CJ7UXwrQ.mjs → NoContentTypePage-LClTUPWs.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-CJ7UXwrQ.mjs.map → NoContentTypePage-LClTUPWs.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-BtPrImPP.js → NoPermissionsPage-D2iWw-sn.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-BtPrImPP.js.map → NoPermissionsPage-D2iWw-sn.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-B7syEq5E.mjs → NoPermissionsPage-S4Re3FwO.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-B7syEq5E.mjs.map → NoPermissionsPage-S4Re3FwO.mjs.map} +1 -1
- package/dist/_chunks/{Relations-B9Crnhnn.mjs → Relations-Dmv0Tpe5.mjs} +4 -4
- package/dist/_chunks/Relations-Dmv0Tpe5.mjs.map +1 -0
- package/dist/_chunks/{Relations-DjTQ5kGB.js → Relations-jwuTFGOV.js} +4 -4
- package/dist/_chunks/Relations-jwuTFGOV.js.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-DJXJw9V5.mjs → index-BmUAydCA.mjs} +977 -680
- package/dist/_chunks/index-BmUAydCA.mjs.map +1 -0
- package/dist/_chunks/{index-DVPWZkbS.js → index-CBX6KyXv.js} +958 -661
- package/dist/_chunks/index-CBX6KyXv.js.map +1 -0
- package/dist/_chunks/{layout-Bau7ZfLV.mjs → layout-ClP-DC72.mjs} +25 -12
- package/dist/_chunks/layout-ClP-DC72.mjs.map +1 -0
- package/dist/_chunks/{layout-Dm6fbiQj.js → layout-CxxkX9jY.js} +24 -11
- package/dist/_chunks/layout-CxxkX9jY.js.map +1 -0
- package/dist/_chunks/{relations-CKnpRgrN.js → relations-DIjTADIu.js} +2 -2
- package/dist/_chunks/{relations-CKnpRgrN.js.map → relations-DIjTADIu.js.map} +1 -1
- package/dist/_chunks/{relations-BH_kBSJ0.mjs → relations-op89RClB.mjs} +2 -2
- package/dist/_chunks/{relations-BH_kBSJ0.mjs.map → relations-op89RClB.mjs.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 +181 -107
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +182 -108
- 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-CPj61RMh.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-zT3fBr4Y.js.map +0 -1
- package/dist/_chunks/Field-Boxf9Ajp.js.map +0 -1
- package/dist/_chunks/Field-dha5VnIQ.mjs.map +0 -1
- package/dist/_chunks/Form-DHrru2AV.mjs.map +0 -1
- package/dist/_chunks/Form-y5g1SRsh.js.map +0 -1
- package/dist/_chunks/History-Bru_KoeP.mjs.map +0 -1
- package/dist/_chunks/History-CqN6K7SX.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-D8wGABj0.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-R_p-SbHZ.js.map +0 -1
- package/dist/_chunks/ListViewPage-SID6TRb9.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-pEw_zug9.js.map +0 -1
- package/dist/_chunks/Relations-B9Crnhnn.mjs.map +0 -1
- package/dist/_chunks/Relations-DjTQ5kGB.js.map +0 -1
- package/dist/_chunks/index-DJXJw9V5.mjs.map +0 -1
- package/dist/_chunks/index-DVPWZkbS.js.map +0 -1
- package/dist/_chunks/layout-Bau7ZfLV.mjs.map +0 -1
- package/dist/_chunks/layout-Dm6fbiQj.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) {
|
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,16 +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
|
-
const
|
895
|
+
data,
|
896
|
+
isLoading: isLoadingConfigs,
|
897
|
+
error,
|
898
|
+
isFetching: isFetchingConfigs
|
899
|
+
} = useGetContentTypeConfigurationQuery(model);
|
900
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
769
901
|
React.useEffect(() => {
|
770
902
|
if (error) {
|
771
903
|
toggleNotification({
|
@@ -773,56 +905,269 @@ const useDocument = (args, opts) => {
|
|
773
905
|
message: formatAPIError(error)
|
774
906
|
});
|
775
907
|
}
|
776
|
-
}, [
|
777
|
-
const
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
(document) => {
|
785
|
-
if (!validationSchema) {
|
786
|
-
throw new Error(
|
787
|
-
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
788
|
-
);
|
789
|
-
}
|
790
|
-
try {
|
791
|
-
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
792
|
-
return null;
|
793
|
-
} catch (error2) {
|
794
|
-
if (error2 instanceof ValidationError) {
|
795
|
-
return getYupValidationErrors(error2);
|
796
|
-
}
|
797
|
-
throw error2;
|
798
|
-
}
|
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
|
799
916
|
},
|
800
|
-
[
|
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]
|
801
933
|
);
|
802
|
-
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
803
934
|
return {
|
804
|
-
|
805
|
-
document: data?.data,
|
806
|
-
meta: data?.meta,
|
935
|
+
error,
|
807
936
|
isLoading,
|
808
|
-
|
809
|
-
|
937
|
+
edit,
|
938
|
+
list: listLayout
|
810
939
|
};
|
811
940
|
};
|
812
|
-
const
|
813
|
-
const {
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
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) {
|
1165
|
+
throw new Error("Could not find model in url params");
|
1166
|
+
}
|
1167
|
+
return {
|
1168
|
+
collectionType,
|
1169
|
+
model: slug,
|
1170
|
+
id: origin || id === "create" ? void 0 : id,
|
826
1171
|
...useDocument(
|
827
1172
|
{ documentId: origin || id, model: slug, collectionType, params },
|
828
1173
|
{
|
@@ -831,6 +1176,45 @@ const useDoc = () => {
|
|
831
1176
|
)
|
832
1177
|
};
|
833
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
|
+
};
|
834
1218
|
const prefixPluginTranslations = (trad, pluginId) => {
|
835
1219
|
if (!pluginId) {
|
836
1220
|
throw new TypeError("pluginId can't be empty");
|
@@ -850,6 +1234,8 @@ const useDocumentActions = () => {
|
|
850
1234
|
const { formatMessage } = useIntl();
|
851
1235
|
const { trackUsage } = useTracking();
|
852
1236
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1237
|
+
const navigate = useNavigate();
|
1238
|
+
const setCurrentStep = useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
853
1239
|
const [deleteDocument] = useDeleteDocumentMutation();
|
854
1240
|
const _delete = React.useCallback(
|
855
1241
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -1164,6 +1550,7 @@ const useDocumentActions = () => {
|
|
1164
1550
|
defaultMessage: "Saved document"
|
1165
1551
|
})
|
1166
1552
|
});
|
1553
|
+
setCurrentStep("contentManager.success");
|
1167
1554
|
return res.data;
|
1168
1555
|
} catch (err) {
|
1169
1556
|
toggleNotification({
|
@@ -1185,7 +1572,6 @@ const useDocumentActions = () => {
|
|
1185
1572
|
sourceId
|
1186
1573
|
});
|
1187
1574
|
if ("error" in res) {
|
1188
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1189
1575
|
return { error: res.error };
|
1190
1576
|
}
|
1191
1577
|
toggleNotification({
|
@@ -1204,7 +1590,7 @@ const useDocumentActions = () => {
|
|
1204
1590
|
throw err;
|
1205
1591
|
}
|
1206
1592
|
},
|
1207
|
-
[autoCloneDocument,
|
1593
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1208
1594
|
);
|
1209
1595
|
const [cloneDocument] = useCloneDocumentMutation();
|
1210
1596
|
const clone = React.useCallback(
|
@@ -1230,6 +1616,7 @@ const useDocumentActions = () => {
|
|
1230
1616
|
defaultMessage: "Cloned document"
|
1231
1617
|
})
|
1232
1618
|
});
|
1619
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1233
1620
|
return res.data;
|
1234
1621
|
} catch (err) {
|
1235
1622
|
toggleNotification({
|
@@ -1240,7 +1627,7 @@ const useDocumentActions = () => {
|
|
1240
1627
|
throw err;
|
1241
1628
|
}
|
1242
1629
|
},
|
1243
|
-
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
|
1630
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1244
1631
|
);
|
1245
1632
|
const [getDoc] = useLazyGetDocumentQuery();
|
1246
1633
|
const getDocument = React.useCallback(
|
@@ -1266,7 +1653,7 @@ const useDocumentActions = () => {
|
|
1266
1653
|
};
|
1267
1654
|
};
|
1268
1655
|
const ProtectedHistoryPage = lazy(
|
1269
|
-
() => import("./History-
|
1656
|
+
() => import("./History-BDZrgfZ3.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1270
1657
|
);
|
1271
1658
|
const routes$1 = [
|
1272
1659
|
{
|
@@ -1279,31 +1666,31 @@ const routes$1 = [
|
|
1279
1666
|
}
|
1280
1667
|
];
|
1281
1668
|
const ProtectedEditViewPage = lazy(
|
1282
|
-
() => import("./EditViewPage-
|
1669
|
+
() => import("./EditViewPage-HYljoEY7.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1283
1670
|
);
|
1284
1671
|
const ProtectedListViewPage = lazy(
|
1285
|
-
() => import("./ListViewPage-
|
1672
|
+
() => import("./ListViewPage-CsX7tWx-.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1286
1673
|
);
|
1287
1674
|
const ProtectedListConfiguration = lazy(
|
1288
|
-
() => import("./ListConfigurationPage-
|
1675
|
+
() => import("./ListConfigurationPage-BZ3ScUna.mjs").then((mod) => ({
|
1289
1676
|
default: mod.ProtectedListConfiguration
|
1290
1677
|
}))
|
1291
1678
|
);
|
1292
1679
|
const ProtectedEditConfigurationPage = lazy(
|
1293
|
-
() => import("./EditConfigurationPage-
|
1680
|
+
() => import("./EditConfigurationPage-CZofxSLy.mjs").then((mod) => ({
|
1294
1681
|
default: mod.ProtectedEditConfigurationPage
|
1295
1682
|
}))
|
1296
1683
|
);
|
1297
1684
|
const ProtectedComponentConfigurationPage = lazy(
|
1298
|
-
() => import("./ComponentConfigurationPage-
|
1685
|
+
() => import("./ComponentConfigurationPage-DJ5voqEK.mjs").then((mod) => ({
|
1299
1686
|
default: mod.ProtectedComponentConfigurationPage
|
1300
1687
|
}))
|
1301
1688
|
);
|
1302
1689
|
const NoPermissions = lazy(
|
1303
|
-
() => import("./NoPermissionsPage-
|
1690
|
+
() => import("./NoPermissionsPage-S4Re3FwO.mjs").then((mod) => ({ default: mod.NoPermissions }))
|
1304
1691
|
);
|
1305
1692
|
const NoContentType = lazy(
|
1306
|
-
() => import("./NoContentTypePage-
|
1693
|
+
() => import("./NoContentTypePage-LClTUPWs.mjs").then((mod) => ({ default: mod.NoContentType }))
|
1307
1694
|
);
|
1308
1695
|
const CollectionTypePages = () => {
|
1309
1696
|
const { collectionType } = useParams();
|
@@ -1417,12 +1804,14 @@ const DocumentActionButton = (action) => {
|
|
1417
1804
|
/* @__PURE__ */ jsx(
|
1418
1805
|
Button,
|
1419
1806
|
{
|
1420
|
-
flex:
|
1807
|
+
flex: "auto",
|
1421
1808
|
startIcon: action.icon,
|
1422
1809
|
disabled: action.disabled,
|
1423
1810
|
onClick: handleClick(action),
|
1424
1811
|
justifyContent: "center",
|
1425
1812
|
variant: action.variant || "default",
|
1813
|
+
paddingTop: "7px",
|
1814
|
+
paddingBottom: "7px",
|
1426
1815
|
children: action.label
|
1427
1816
|
}
|
1428
1817
|
),
|
@@ -1430,7 +1819,7 @@ const DocumentActionButton = (action) => {
|
|
1430
1819
|
DocumentActionConfirmDialog,
|
1431
1820
|
{
|
1432
1821
|
...action.dialog,
|
1433
|
-
variant: action.variant,
|
1822
|
+
variant: action.dialog?.variant ?? action.variant,
|
1434
1823
|
isOpen: dialogId === action.id,
|
1435
1824
|
onClose: handleClose
|
1436
1825
|
}
|
@@ -1487,9 +1876,9 @@ const DocumentActionsMenu = ({
|
|
1487
1876
|
disabled: isDisabled,
|
1488
1877
|
size: "S",
|
1489
1878
|
endIcon: null,
|
1490
|
-
paddingTop: "
|
1491
|
-
paddingLeft: "
|
1492
|
-
paddingRight: "
|
1879
|
+
paddingTop: "4px",
|
1880
|
+
paddingLeft: "7px",
|
1881
|
+
paddingRight: "7px",
|
1493
1882
|
variant,
|
1494
1883
|
children: [
|
1495
1884
|
/* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
|
@@ -1500,7 +1889,7 @@ const DocumentActionsMenu = ({
|
|
1500
1889
|
]
|
1501
1890
|
}
|
1502
1891
|
),
|
1503
|
-
/* @__PURE__ */ jsxs(Menu.Content, {
|
1892
|
+
/* @__PURE__ */ jsxs(Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1504
1893
|
actions2.map((action) => {
|
1505
1894
|
return /* @__PURE__ */ jsx(
|
1506
1895
|
Menu.Item,
|
@@ -1509,10 +1898,25 @@ const DocumentActionsMenu = ({
|
|
1509
1898
|
onSelect: handleClick(action),
|
1510
1899
|
display: "block",
|
1511
1900
|
children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", gap: 4, children: [
|
1512
|
-
/* @__PURE__ */ jsxs(
|
1513
|
-
|
1514
|
-
|
1515
|
-
|
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
|
+
),
|
1516
1920
|
action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsx(
|
1517
1921
|
Flex,
|
1518
1922
|
{
|
@@ -1609,11 +2013,11 @@ const DocumentActionConfirmDialog = ({
|
|
1609
2013
|
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
1610
2014
|
/* @__PURE__ */ jsx(Dialog.Body, { children: content }),
|
1611
2015
|
/* @__PURE__ */ jsxs(Dialog.Footer, { children: [
|
1612
|
-
/* @__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({
|
1613
2017
|
id: "app.components.Button.cancel",
|
1614
2018
|
defaultMessage: "Cancel"
|
1615
2019
|
}) }) }),
|
1616
|
-
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, children: formatMessage({
|
2020
|
+
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
|
1617
2021
|
id: "app.components.Button.confirm",
|
1618
2022
|
defaultMessage: "Confirm"
|
1619
2023
|
}) })
|
@@ -1652,13 +2056,17 @@ const PublishAction$1 = ({
|
|
1652
2056
|
const navigate = useNavigate();
|
1653
2057
|
const { toggleNotification } = useNotification();
|
1654
2058
|
const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
|
2059
|
+
const isListView = useMatch(LIST_PATH) !== null;
|
1655
2060
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
1656
2061
|
const { formatMessage } = useIntl();
|
1657
|
-
const { canPublish
|
1658
|
-
"PublishAction",
|
1659
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1660
|
-
);
|
2062
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1661
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);
|
1662
2070
|
const [{ query, rawQuery }] = useQueryParams();
|
1663
2071
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
1664
2072
|
const modified = useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
@@ -1667,62 +2075,142 @@ const PublishAction$1 = ({
|
|
1667
2075
|
const validate = useForm("PublishAction", (state) => state.validate);
|
1668
2076
|
const setErrors = useForm("PublishAction", (state) => state.setErrors);
|
1669
2077
|
const formValues = useForm("PublishAction", ({ values }) => values);
|
1670
|
-
|
1671
|
-
|
1672
|
-
|
1673
|
-
|
1674
|
-
|
1675
|
-
|
1676
|
-
|
1677
|
-
|
1678
|
-
|
1679
|
-
|
1680
|
-
|
1681
|
-
|
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
|
1682
2183
|
* - the user doesn't have the permission to publish
|
1683
|
-
* - the user doesn't have the permission to create a new document
|
1684
|
-
* - the user doesn't have the permission to update the document
|
1685
2184
|
*/
|
1686
|
-
disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish
|
2185
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
1687
2186
|
label: formatMessage({
|
1688
2187
|
id: "app.utils.publish",
|
1689
2188
|
defaultMessage: "Publish"
|
1690
2189
|
}),
|
1691
2190
|
onClick: async () => {
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
documentId,
|
1710
|
-
params
|
1711
|
-
},
|
1712
|
-
formValues
|
1713
|
-
);
|
1714
|
-
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1715
|
-
navigate({
|
1716
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1717
|
-
search: rawQuery
|
1718
|
-
});
|
1719
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1720
|
-
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
|
1721
2208
|
}
|
1722
|
-
|
1723
|
-
|
2209
|
+
),
|
2210
|
+
onConfirm: async () => {
|
2211
|
+
await performPublish();
|
1724
2212
|
}
|
1725
|
-
}
|
2213
|
+
} : void 0
|
1726
2214
|
};
|
1727
2215
|
};
|
1728
2216
|
PublishAction$1.type = "publish";
|
@@ -1738,10 +2226,6 @@ const UpdateAction = ({
|
|
1738
2226
|
const cloneMatch = useMatch(CLONE_PATH);
|
1739
2227
|
const isCloning = cloneMatch !== null;
|
1740
2228
|
const { formatMessage } = useIntl();
|
1741
|
-
const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1742
|
-
canCreate: canCreate2,
|
1743
|
-
canUpdate: canUpdate2
|
1744
|
-
}));
|
1745
2229
|
const { create, update, clone } = useDocumentActions();
|
1746
2230
|
const [{ query, rawQuery }] = useQueryParams();
|
1747
2231
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
@@ -1758,10 +2242,8 @@ const UpdateAction = ({
|
|
1758
2242
|
* - the form is submitting
|
1759
2243
|
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
1760
2244
|
* - the active tab is the published tab
|
1761
|
-
* - the user doesn't have the permission to create a new document
|
1762
|
-
* - the user doesn't have the permission to update the document
|
1763
2245
|
*/
|
1764
|
-
disabled: isSubmitting || !modified && !isCloning || activeTab === "published"
|
2246
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1765
2247
|
label: formatMessage({
|
1766
2248
|
id: "content-manager.containers.Edit.save",
|
1767
2249
|
defaultMessage: "Save"
|
@@ -1769,16 +2251,18 @@ const UpdateAction = ({
|
|
1769
2251
|
onClick: async () => {
|
1770
2252
|
setSubmitting(true);
|
1771
2253
|
try {
|
1772
|
-
|
1773
|
-
|
1774
|
-
|
1775
|
-
|
1776
|
-
|
1777
|
-
|
1778
|
-
|
1779
|
-
|
1780
|
-
|
1781
|
-
|
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
|
+
}
|
1782
2266
|
}
|
1783
2267
|
if (isCloning) {
|
1784
2268
|
const res = await clone(
|
@@ -1790,10 +2274,13 @@ const UpdateAction = ({
|
|
1790
2274
|
document
|
1791
2275
|
);
|
1792
2276
|
if ("data" in res) {
|
1793
|
-
navigate(
|
1794
|
-
|
1795
|
-
|
1796
|
-
|
2277
|
+
navigate(
|
2278
|
+
{
|
2279
|
+
pathname: `../${res.data.documentId}`,
|
2280
|
+
search: rawQuery
|
2281
|
+
},
|
2282
|
+
{ relative: "path" }
|
2283
|
+
);
|
1797
2284
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1798
2285
|
setErrors(formatValidationErrors(res.error));
|
1799
2286
|
}
|
@@ -1821,10 +2308,13 @@ const UpdateAction = ({
|
|
1821
2308
|
document
|
1822
2309
|
);
|
1823
2310
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1824
|
-
navigate(
|
1825
|
-
|
1826
|
-
|
1827
|
-
|
2311
|
+
navigate(
|
2312
|
+
{
|
2313
|
+
pathname: `../${res.data.documentId}`,
|
2314
|
+
search: rawQuery
|
2315
|
+
},
|
2316
|
+
{ replace: true, relative: "path" }
|
2317
|
+
);
|
1828
2318
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1829
2319
|
setErrors(formatValidationErrors(res.error));
|
1830
2320
|
}
|
@@ -1868,7 +2358,7 @@ const UnpublishAction$1 = ({
|
|
1868
2358
|
id: "app.utils.unpublish",
|
1869
2359
|
defaultMessage: "Unpublish"
|
1870
2360
|
}),
|
1871
|
-
icon: /* @__PURE__ */ jsx(
|
2361
|
+
icon: /* @__PURE__ */ jsx(Cross, {}),
|
1872
2362
|
onClick: async () => {
|
1873
2363
|
if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
|
1874
2364
|
if (!documentId) {
|
@@ -1980,7 +2470,7 @@ const DiscardAction = ({
|
|
1980
2470
|
id: "content-manager.actions.discard.label",
|
1981
2471
|
defaultMessage: "Discard changes"
|
1982
2472
|
}),
|
1983
|
-
icon: /* @__PURE__ */ jsx(
|
2473
|
+
icon: /* @__PURE__ */ jsx(Cross, {}),
|
1984
2474
|
position: ["panel", "table-row"],
|
1985
2475
|
variant: "danger",
|
1986
2476
|
dialog: {
|
@@ -2008,11 +2498,6 @@ const DiscardAction = ({
|
|
2008
2498
|
};
|
2009
2499
|
};
|
2010
2500
|
DiscardAction.type = "discard";
|
2011
|
-
const StyledCrossCircle = styled(CrossCircle)`
|
2012
|
-
path {
|
2013
|
-
fill: currentColor;
|
2014
|
-
}
|
2015
|
-
`;
|
2016
2501
|
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2017
2502
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2018
2503
|
const RelativeTime = React.forwardRef(
|
@@ -2060,7 +2545,7 @@ const getDisplayName = ({
|
|
2060
2545
|
};
|
2061
2546
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2062
2547
|
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2063
|
-
const statusVariant = status === "draft" ? "
|
2548
|
+
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2064
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) }) });
|
2065
2550
|
};
|
2066
2551
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
@@ -2070,23 +2555,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
|
2070
2555
|
id: "content-manager.containers.edit.title.new",
|
2071
2556
|
defaultMessage: "Create an entry"
|
2072
2557
|
}) : documentTitle;
|
2073
|
-
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: [
|
2074
2559
|
/* @__PURE__ */ jsx(BackButton, {}),
|
2075
|
-
/* @__PURE__ */ jsxs(
|
2076
|
-
|
2077
|
-
{
|
2078
|
-
|
2079
|
-
|
2080
|
-
paddingTop: 1,
|
2081
|
-
gap: "80px",
|
2082
|
-
alignItems: "flex-start",
|
2083
|
-
children: [
|
2084
|
-
/* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
|
2085
|
-
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
2086
|
-
]
|
2087
|
-
}
|
2088
|
-
),
|
2089
|
-
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
|
2090
2565
|
] });
|
2091
2566
|
};
|
2092
2567
|
const HeaderToolbar = () => {
|
@@ -2253,8 +2728,22 @@ const Information = ({ activeTab }) => {
|
|
2253
2728
|
);
|
2254
2729
|
};
|
2255
2730
|
const HeaderActions = ({ actions: actions2 }) => {
|
2256
|
-
|
2257
|
-
|
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) {
|
2258
2747
|
return /* @__PURE__ */ jsx(
|
2259
2748
|
SingleSelect,
|
2260
2749
|
{
|
@@ -2268,10 +2757,49 @@ const HeaderActions = ({ actions: actions2 }) => {
|
|
2268
2757
|
action.id
|
2269
2758
|
);
|
2270
2759
|
} else {
|
2271
|
-
|
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
|
+
}
|
2272
2782
|
}
|
2273
2783
|
}) });
|
2274
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
|
+
};
|
2275
2803
|
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
2276
2804
|
const navigate = useNavigate();
|
2277
2805
|
const { formatMessage } = useIntl();
|
@@ -2312,12 +2840,16 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2312
2840
|
const { delete: deleteAction } = useDocumentActions();
|
2313
2841
|
const { toggleNotification } = useNotification();
|
2314
2842
|
const setSubmitting = useForm("DeleteAction", (state) => state.setSubmitting);
|
2843
|
+
const isLocalized = document?.locale != null;
|
2315
2844
|
return {
|
2316
2845
|
disabled: !canDelete || !document,
|
2317
|
-
label: formatMessage(
|
2318
|
-
|
2319
|
-
|
2320
|
-
|
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
|
+
),
|
2321
2853
|
icon: /* @__PURE__ */ jsx(Trash, {}),
|
2322
2854
|
dialog: {
|
2323
2855
|
type: "dialog",
|
@@ -2351,425 +2883,123 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2351
2883
|
return;
|
2352
2884
|
}
|
2353
2885
|
const res = await deleteAction({
|
2354
|
-
documentId,
|
2355
|
-
model,
|
2356
|
-
collectionType,
|
2357
|
-
params: {
|
2358
|
-
locale: "*"
|
2359
|
-
}
|
2360
|
-
});
|
2361
|
-
if (!("error" in res)) {
|
2362
|
-
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
2363
|
-
}
|
2364
|
-
} finally {
|
2365
|
-
if (!listViewPathMatch) {
|
2366
|
-
setSubmitting(false);
|
2367
|
-
}
|
2368
|
-
}
|
2369
|
-
}
|
2370
|
-
},
|
2371
|
-
variant: "danger",
|
2372
|
-
position: ["header", "table-row"]
|
2373
|
-
};
|
2374
|
-
};
|
2375
|
-
DeleteAction$1.type = "delete";
|
2376
|
-
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2377
|
-
const Panels = () => {
|
2378
|
-
const isCloning = useMatch(CLONE_PATH) !== null;
|
2379
|
-
const [
|
2380
|
-
{
|
2381
|
-
query: { status }
|
2382
|
-
}
|
2383
|
-
] = useQueryParams({
|
2384
|
-
status: "draft"
|
2385
|
-
});
|
2386
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2387
|
-
const plugins = useStrapiApp("Panels", (state) => state.plugins);
|
2388
|
-
const props = {
|
2389
|
-
activeTab: status,
|
2390
|
-
model,
|
2391
|
-
documentId: id,
|
2392
|
-
document: isCloning ? void 0 : document,
|
2393
|
-
meta: isCloning ? void 0 : meta,
|
2394
|
-
collectionType
|
2395
|
-
};
|
2396
|
-
return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsx(
|
2397
|
-
DescriptionComponentRenderer,
|
2398
|
-
{
|
2399
|
-
props,
|
2400
|
-
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2401
|
-
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsx(Panel, { ...description, children: content }, id2))
|
2402
|
-
}
|
2403
|
-
) });
|
2404
|
-
};
|
2405
|
-
const ActionsPanel = () => {
|
2406
|
-
const { formatMessage } = useIntl();
|
2407
|
-
return {
|
2408
|
-
title: formatMessage({
|
2409
|
-
id: "content-manager.containers.edit.panels.default.title",
|
2410
|
-
defaultMessage: "Document"
|
2411
|
-
}),
|
2412
|
-
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2413
|
-
};
|
2414
|
-
};
|
2415
|
-
ActionsPanel.type = "actions";
|
2416
|
-
const ActionsPanelContent = () => {
|
2417
|
-
const isCloning = useMatch(CLONE_PATH) !== null;
|
2418
|
-
const [
|
2419
|
-
{
|
2420
|
-
query: { status = "draft" }
|
2421
|
-
}
|
2422
|
-
] = useQueryParams();
|
2423
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2424
|
-
const plugins = useStrapiApp("ActionsPanel", (state) => state.plugins);
|
2425
|
-
const props = {
|
2426
|
-
activeTab: status,
|
2427
|
-
model,
|
2428
|
-
documentId: id,
|
2429
|
-
document: isCloning ? void 0 : document,
|
2430
|
-
meta: isCloning ? void 0 : meta,
|
2431
|
-
collectionType
|
2432
|
-
};
|
2433
|
-
return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
|
2434
|
-
/* @__PURE__ */ jsx(
|
2435
|
-
DescriptionComponentRenderer,
|
2436
|
-
{
|
2437
|
-
props,
|
2438
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2439
|
-
children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
|
2440
|
-
}
|
2441
|
-
),
|
2442
|
-
/* @__PURE__ */ jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
2443
|
-
] });
|
2444
|
-
};
|
2445
|
-
const Panel = React.forwardRef(({ children, title }, ref) => {
|
2446
|
-
return /* @__PURE__ */ jsxs(
|
2447
|
-
Flex,
|
2448
|
-
{
|
2449
|
-
ref,
|
2450
|
-
tag: "aside",
|
2451
|
-
"aria-labelledby": "additional-information",
|
2452
|
-
background: "neutral0",
|
2453
|
-
borderColor: "neutral150",
|
2454
|
-
hasRadius: true,
|
2455
|
-
paddingBottom: 4,
|
2456
|
-
paddingLeft: 4,
|
2457
|
-
paddingRight: 4,
|
2458
|
-
paddingTop: 4,
|
2459
|
-
shadow: "tableShadow",
|
2460
|
-
gap: 3,
|
2461
|
-
direction: "column",
|
2462
|
-
justifyContent: "stretch",
|
2463
|
-
alignItems: "flex-start",
|
2464
|
-
children: [
|
2465
|
-
/* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2466
|
-
children
|
2467
|
-
]
|
2468
|
-
}
|
2469
|
-
);
|
2470
|
-
});
|
2471
|
-
const HOOKS = {
|
2472
|
-
/**
|
2473
|
-
* Hook that allows to mutate the displayed headers of the list view table
|
2474
|
-
* @constant
|
2475
|
-
* @type {string}
|
2476
|
-
*/
|
2477
|
-
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2478
|
-
/**
|
2479
|
-
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2480
|
-
* @constant
|
2481
|
-
* @type {string}
|
2482
|
-
*/
|
2483
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2484
|
-
/**
|
2485
|
-
* Hook that allows to mutate the CM's edit view layout
|
2486
|
-
* @constant
|
2487
|
-
* @type {string}
|
2488
|
-
*/
|
2489
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2490
|
-
/**
|
2491
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
2492
|
-
* @constant
|
2493
|
-
* @type {string}
|
2494
|
-
*/
|
2495
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2496
|
-
};
|
2497
|
-
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2498
|
-
endpoints: (builder) => ({
|
2499
|
-
getContentTypeConfiguration: builder.query({
|
2500
|
-
query: (uid) => ({
|
2501
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2502
|
-
method: "GET"
|
2503
|
-
}),
|
2504
|
-
transformResponse: (response) => response.data,
|
2505
|
-
providesTags: (_result, _error, uid) => [
|
2506
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2507
|
-
{ type: "ContentTypeSettings", id: "LIST" }
|
2508
|
-
]
|
2509
|
-
}),
|
2510
|
-
getAllContentTypeSettings: builder.query({
|
2511
|
-
query: () => "/content-manager/content-types-settings",
|
2512
|
-
transformResponse: (response) => response.data,
|
2513
|
-
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2514
|
-
}),
|
2515
|
-
updateContentTypeConfiguration: builder.mutation({
|
2516
|
-
query: ({ uid, ...body }) => ({
|
2517
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2518
|
-
method: "PUT",
|
2519
|
-
data: body
|
2520
|
-
}),
|
2521
|
-
transformResponse: (response) => response.data,
|
2522
|
-
invalidatesTags: (_result, _error, { uid }) => [
|
2523
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2524
|
-
{ type: "ContentTypeSettings", id: "LIST" },
|
2525
|
-
// Is this necessary?
|
2526
|
-
{ type: "InitialData" }
|
2527
|
-
]
|
2528
|
-
})
|
2529
|
-
})
|
2530
|
-
});
|
2531
|
-
const {
|
2532
|
-
useGetContentTypeConfigurationQuery,
|
2533
|
-
useGetAllContentTypeSettingsQuery,
|
2534
|
-
useUpdateContentTypeConfigurationMutation
|
2535
|
-
} = contentTypesApi;
|
2536
|
-
const checkIfAttributeIsDisplayable = (attribute) => {
|
2537
|
-
const { type } = attribute;
|
2538
|
-
if (type === "relation") {
|
2539
|
-
return !attribute.relation.toLowerCase().includes("morph");
|
2540
|
-
}
|
2541
|
-
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2542
|
-
};
|
2543
|
-
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2544
|
-
if (!mainFieldName) {
|
2545
|
-
return void 0;
|
2546
|
-
}
|
2547
|
-
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2548
|
-
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2549
|
-
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2550
|
-
);
|
2551
|
-
return {
|
2552
|
-
name: mainFieldName,
|
2553
|
-
type: mainFieldType ?? "string"
|
2554
|
-
};
|
2555
|
-
};
|
2556
|
-
const DEFAULT_SETTINGS = {
|
2557
|
-
bulkable: false,
|
2558
|
-
filterable: false,
|
2559
|
-
searchable: false,
|
2560
|
-
pagination: false,
|
2561
|
-
defaultSortBy: "",
|
2562
|
-
defaultSortOrder: "asc",
|
2563
|
-
mainField: "id",
|
2564
|
-
pageSize: 10
|
2565
|
-
};
|
2566
|
-
const useDocumentLayout = (model) => {
|
2567
|
-
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2568
|
-
const [{ query }] = useQueryParams();
|
2569
|
-
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2570
|
-
const { toggleNotification } = useNotification();
|
2571
|
-
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
2572
|
-
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2573
|
-
const {
|
2574
|
-
data,
|
2575
|
-
isLoading: isLoadingConfigs,
|
2576
|
-
error,
|
2577
|
-
isFetching: isFetchingConfigs
|
2578
|
-
} = useGetContentTypeConfigurationQuery(model);
|
2579
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2580
|
-
React.useEffect(() => {
|
2581
|
-
if (error) {
|
2582
|
-
toggleNotification({
|
2583
|
-
type: "danger",
|
2584
|
-
message: formatAPIError(error)
|
2585
|
-
});
|
2586
|
-
}
|
2587
|
-
}, [error, formatAPIError, toggleNotification]);
|
2588
|
-
const editLayout = React.useMemo(
|
2589
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2590
|
-
layout: [],
|
2591
|
-
components: {},
|
2592
|
-
metadatas: {},
|
2593
|
-
options: {},
|
2594
|
-
settings: DEFAULT_SETTINGS
|
2595
|
-
},
|
2596
|
-
[data, isLoading, schemas, schema, components]
|
2597
|
-
);
|
2598
|
-
const listLayout = React.useMemo(() => {
|
2599
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2600
|
-
layout: [],
|
2601
|
-
metadatas: {},
|
2602
|
-
options: {},
|
2603
|
-
settings: DEFAULT_SETTINGS
|
2604
|
-
};
|
2605
|
-
}, [data, isLoading, schemas, schema, components]);
|
2606
|
-
const { layout: edit } = React.useMemo(
|
2607
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2608
|
-
layout: editLayout,
|
2609
|
-
query
|
2610
|
-
}),
|
2611
|
-
[editLayout, query, runHookWaterfall]
|
2612
|
-
);
|
2613
|
-
return {
|
2614
|
-
error,
|
2615
|
-
isLoading,
|
2616
|
-
edit,
|
2617
|
-
list: listLayout
|
2618
|
-
};
|
2619
|
-
};
|
2620
|
-
const useDocLayout = () => {
|
2621
|
-
const { model } = useDoc();
|
2622
|
-
return useDocumentLayout(model);
|
2623
|
-
};
|
2624
|
-
const formatEditLayout = (data, {
|
2625
|
-
schemas,
|
2626
|
-
schema,
|
2627
|
-
components
|
2628
|
-
}) => {
|
2629
|
-
let currentPanelIndex = 0;
|
2630
|
-
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2631
|
-
data.contentType.layouts.edit,
|
2632
|
-
schema?.attributes,
|
2633
|
-
data.contentType.metadatas,
|
2634
|
-
{ configurations: data.components, schemas: components },
|
2635
|
-
schemas
|
2636
|
-
).reduce((panels, row) => {
|
2637
|
-
if (row.some((field) => field.type === "dynamiczone")) {
|
2638
|
-
panels.push([row]);
|
2639
|
-
currentPanelIndex += 2;
|
2640
|
-
} else {
|
2641
|
-
if (!panels[currentPanelIndex]) {
|
2642
|
-
panels.push([]);
|
2643
|
-
}
|
2644
|
-
panels[currentPanelIndex].push(row);
|
2645
|
-
}
|
2646
|
-
return panels;
|
2647
|
-
}, []);
|
2648
|
-
const componentEditAttributes = Object.entries(data.components).reduce(
|
2649
|
-
(acc, [uid, configuration]) => {
|
2650
|
-
acc[uid] = {
|
2651
|
-
layout: convertEditLayoutToFieldLayouts(
|
2652
|
-
configuration.layouts.edit,
|
2653
|
-
components[uid].attributes,
|
2654
|
-
configuration.metadatas
|
2655
|
-
),
|
2656
|
-
settings: {
|
2657
|
-
...configuration.settings,
|
2658
|
-
icon: components[uid].info.icon,
|
2659
|
-
displayName: components[uid].info.displayName
|
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
|
+
}
|
2660
2900
|
}
|
2661
|
-
}
|
2662
|
-
return acc;
|
2663
|
-
},
|
2664
|
-
{}
|
2665
|
-
);
|
2666
|
-
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2667
|
-
(acc, [attribute, metadata]) => {
|
2668
|
-
return {
|
2669
|
-
...acc,
|
2670
|
-
[attribute]: metadata.edit
|
2671
|
-
};
|
2672
|
-
},
|
2673
|
-
{}
|
2674
|
-
);
|
2675
|
-
return {
|
2676
|
-
layout: panelledEditAttributes,
|
2677
|
-
components: componentEditAttributes,
|
2678
|
-
metadatas: editMetadatas,
|
2679
|
-
settings: {
|
2680
|
-
...data.contentType.settings,
|
2681
|
-
displayName: schema?.info.displayName
|
2901
|
+
}
|
2682
2902
|
},
|
2683
|
-
|
2684
|
-
|
2685
|
-
...schema?.pluginOptions,
|
2686
|
-
...data.contentType.options
|
2687
|
-
}
|
2903
|
+
variant: "danger",
|
2904
|
+
position: ["header", "table-row"]
|
2688
2905
|
};
|
2689
2906
|
};
|
2690
|
-
|
2691
|
-
|
2692
|
-
|
2693
|
-
|
2694
|
-
|
2695
|
-
|
2696
|
-
}
|
2697
|
-
|
2698
|
-
|
2699
|
-
|
2700
|
-
|
2701
|
-
|
2702
|
-
|
2703
|
-
|
2704
|
-
|
2705
|
-
|
2706
|
-
|
2707
|
-
|
2708
|
-
|
2709
|
-
|
2710
|
-
|
2711
|
-
|
2712
|
-
|
2713
|
-
|
2714
|
-
|
2715
|
-
|
2716
|
-
}
|
2717
|
-
}
|
2718
|
-
);
|
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
|
+
) });
|
2719
2936
|
};
|
2720
|
-
const
|
2721
|
-
|
2722
|
-
schema,
|
2723
|
-
components
|
2724
|
-
}) => {
|
2725
|
-
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2726
|
-
(acc, [attribute, metadata]) => {
|
2727
|
-
return {
|
2728
|
-
...acc,
|
2729
|
-
[attribute]: metadata.list
|
2730
|
-
};
|
2731
|
-
},
|
2732
|
-
{}
|
2733
|
-
);
|
2734
|
-
const listAttributes = convertListLayoutToFieldLayouts(
|
2735
|
-
data.contentType.layouts.list,
|
2736
|
-
schema?.attributes,
|
2737
|
-
listMetadatas,
|
2738
|
-
{ configurations: data.components, schemas: components },
|
2739
|
-
schemas
|
2740
|
-
);
|
2937
|
+
const ActionsPanel = () => {
|
2938
|
+
const { formatMessage } = useIntl();
|
2741
2939
|
return {
|
2742
|
-
|
2743
|
-
|
2744
|
-
|
2745
|
-
|
2746
|
-
|
2747
|
-
...schema?.pluginOptions,
|
2748
|
-
...data.contentType.options
|
2749
|
-
}
|
2940
|
+
title: formatMessage({
|
2941
|
+
id: "content-manager.containers.edit.panels.default.title",
|
2942
|
+
defaultMessage: "Entry"
|
2943
|
+
}),
|
2944
|
+
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2750
2945
|
};
|
2751
2946
|
};
|
2752
|
-
|
2753
|
-
|
2754
|
-
|
2755
|
-
|
2756
|
-
|
2947
|
+
ActionsPanel.type = "actions";
|
2948
|
+
const ActionsPanelContent = () => {
|
2949
|
+
const isCloning = useMatch(CLONE_PATH) !== null;
|
2950
|
+
const [
|
2951
|
+
{
|
2952
|
+
query: { status = "draft" }
|
2757
2953
|
}
|
2758
|
-
|
2759
|
-
|
2760
|
-
|
2761
|
-
|
2762
|
-
|
2763
|
-
|
2764
|
-
|
2765
|
-
|
2766
|
-
|
2767
|
-
|
2768
|
-
|
2769
|
-
|
2770
|
-
|
2771
|
-
|
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
|
+
] });
|
2772
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
|
+
});
|
2773
3003
|
const ConfirmBulkActionDialog = ({
|
2774
3004
|
onToggleDialog,
|
2775
3005
|
isOpen = false,
|
@@ -2777,7 +3007,7 @@ const ConfirmBulkActionDialog = ({
|
|
2777
3007
|
endAction
|
2778
3008
|
}) => {
|
2779
3009
|
const { formatMessage } = useIntl();
|
2780
|
-
return /* @__PURE__ */ jsx(Dialog.Root, {
|
3010
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
2781
3011
|
/* @__PURE__ */ jsx(Dialog.Header, { children: formatMessage({
|
2782
3012
|
id: "app.components.ConfirmDialog.title",
|
2783
3013
|
defaultMessage: "Confirmation"
|
@@ -2808,6 +3038,7 @@ const ConfirmDialogPublishAll = ({
|
|
2808
3038
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(getTranslation);
|
2809
3039
|
const { model, schema } = useDoc();
|
2810
3040
|
const [{ query }] = useQueryParams();
|
3041
|
+
const enableDraftRelationsCount = false;
|
2811
3042
|
const {
|
2812
3043
|
data: countDraftRelations = 0,
|
2813
3044
|
isLoading,
|
@@ -2819,7 +3050,7 @@ const ConfirmDialogPublishAll = ({
|
|
2819
3050
|
locale: query?.plugins?.i18n?.locale
|
2820
3051
|
},
|
2821
3052
|
{
|
2822
|
-
skip:
|
3053
|
+
skip: !enableDraftRelationsCount
|
2823
3054
|
}
|
2824
3055
|
);
|
2825
3056
|
React.useEffect(() => {
|
@@ -2898,7 +3129,14 @@ const formatErrorMessages = (errors, parentKey, formatMessage) => {
|
|
2898
3129
|
)
|
2899
3130
|
);
|
2900
3131
|
} else {
|
2901
|
-
messages.push(
|
3132
|
+
messages.push(
|
3133
|
+
...formatErrorMessages(
|
3134
|
+
// @ts-expect-error TODO: check why value is not compatible with FormErrors
|
3135
|
+
value,
|
3136
|
+
currentKey,
|
3137
|
+
formatMessage
|
3138
|
+
)
|
3139
|
+
);
|
2902
3140
|
}
|
2903
3141
|
} else {
|
2904
3142
|
messages.push(
|
@@ -2997,7 +3235,7 @@ const SelectedEntriesTableContent = ({
|
|
2997
3235
|
status: row.status
|
2998
3236
|
}
|
2999
3237
|
) }),
|
3000
|
-
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(
|
3238
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
|
3001
3239
|
IconButton,
|
3002
3240
|
{
|
3003
3241
|
tag: Link,
|
@@ -3020,9 +3258,10 @@ const SelectedEntriesTableContent = ({
|
|
3020
3258
|
),
|
3021
3259
|
target: "_blank",
|
3022
3260
|
marginLeft: "auto",
|
3023
|
-
|
3261
|
+
variant: "ghost",
|
3262
|
+
children: /* @__PURE__ */ jsx(Pencil, { width: "1.6rem", height: "1.6rem" })
|
3024
3263
|
}
|
3025
|
-
) })
|
3264
|
+
) }) })
|
3026
3265
|
] }, row.id)) })
|
3027
3266
|
] });
|
3028
3267
|
};
|
@@ -3059,7 +3298,13 @@ const SelectedEntriesModalContent = ({
|
|
3059
3298
|
);
|
3060
3299
|
const { rows, validationErrors } = React.useMemo(() => {
|
3061
3300
|
if (data.length > 0 && schema) {
|
3062
|
-
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
|
+
);
|
3063
3308
|
const validationErrors2 = {};
|
3064
3309
|
const rows2 = data.map((entry) => {
|
3065
3310
|
try {
|
@@ -3409,7 +3654,7 @@ const TableActions = ({ document }) => {
|
|
3409
3654
|
DescriptionComponentRenderer,
|
3410
3655
|
{
|
3411
3656
|
props,
|
3412
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3657
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
3413
3658
|
children: (actions2) => {
|
3414
3659
|
const tableRowActions = actions2.filter((action) => {
|
3415
3660
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3520,7 +3765,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3520
3765
|
}),
|
3521
3766
|
content: /* @__PURE__ */ jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
3522
3767
|
footer: ({ onClose }) => {
|
3523
|
-
return /* @__PURE__ */ jsxs(
|
3768
|
+
return /* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
3524
3769
|
/* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
3525
3770
|
id: "cancel",
|
3526
3771
|
defaultMessage: "Cancel"
|
@@ -3561,8 +3806,7 @@ class ContentManagerPlugin {
|
|
3561
3806
|
documentActions = [
|
3562
3807
|
...DEFAULT_ACTIONS,
|
3563
3808
|
...DEFAULT_TABLE_ROW_ACTIONS,
|
3564
|
-
...DEFAULT_HEADER_ACTIONS
|
3565
|
-
HistoryAction
|
3809
|
+
...DEFAULT_HEADER_ACTIONS
|
3566
3810
|
];
|
3567
3811
|
editViewSidePanels = [ActionsPanel];
|
3568
3812
|
headerActions = [];
|
@@ -3651,6 +3895,52 @@ const getPrintableType = (value) => {
|
|
3651
3895
|
}
|
3652
3896
|
return nativeType;
|
3653
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
|
+
};
|
3654
3944
|
const initialState = {
|
3655
3945
|
collectionTypeLinks: [],
|
3656
3946
|
components: [],
|
@@ -3706,7 +3996,7 @@ const index = {
|
|
3706
3996
|
app.router.addRoute({
|
3707
3997
|
path: "content-manager/*",
|
3708
3998
|
lazy: async () => {
|
3709
|
-
const { Layout } = await import("./layout-
|
3999
|
+
const { Layout } = await import("./layout-ClP-DC72.mjs");
|
3710
4000
|
return {
|
3711
4001
|
Component: Layout
|
3712
4002
|
};
|
@@ -3715,10 +4005,15 @@ const index = {
|
|
3715
4005
|
});
|
3716
4006
|
app.registerPlugin(cm.config);
|
3717
4007
|
},
|
4008
|
+
bootstrap(app) {
|
4009
|
+
if (typeof historyAdmin.bootstrap === "function") {
|
4010
|
+
historyAdmin.bootstrap(app);
|
4011
|
+
}
|
4012
|
+
},
|
3718
4013
|
async registerTrads({ locales }) {
|
3719
4014
|
const importedTrads = await Promise.all(
|
3720
4015
|
locales.map((locale) => {
|
3721
|
-
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 }) => {
|
3722
4017
|
return {
|
3723
4018
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3724
4019
|
locale
|
@@ -3739,13 +4034,15 @@ export {
|
|
3739
4034
|
BulkActionsRenderer as B,
|
3740
4035
|
COLLECTION_TYPES as C,
|
3741
4036
|
DocumentStatus as D,
|
3742
|
-
|
3743
|
-
|
3744
|
-
|
4037
|
+
extractContentTypeComponents as E,
|
4038
|
+
DEFAULT_SETTINGS as F,
|
4039
|
+
convertEditLayoutToFieldLayouts as G,
|
3745
4040
|
HOOKS as H,
|
3746
4041
|
InjectionZone as I,
|
3747
|
-
|
3748
|
-
|
4042
|
+
useDocument as J,
|
4043
|
+
index as K,
|
4044
|
+
useContentManagerContext as L,
|
4045
|
+
useDocumentActions as M,
|
3749
4046
|
Panels as P,
|
3750
4047
|
RelativeTime as R,
|
3751
4048
|
SINGLE_TYPES as S,
|
@@ -3763,18 +4060,18 @@ export {
|
|
3763
4060
|
PERMISSIONS as k,
|
3764
4061
|
DocumentRBAC as l,
|
3765
4062
|
DOCUMENT_META_FIELDS as m,
|
3766
|
-
|
3767
|
-
|
3768
|
-
|
3769
|
-
|
3770
|
-
|
4063
|
+
CLONE_PATH as n,
|
4064
|
+
useDocLayout as o,
|
4065
|
+
useGetContentTypeConfigurationQuery as p,
|
4066
|
+
CREATOR_FIELDS as q,
|
4067
|
+
getMainField as r,
|
3771
4068
|
setInitialData as s,
|
3772
|
-
|
4069
|
+
getDisplayName as t,
|
3773
4070
|
useContentTypeSchema as u,
|
3774
|
-
|
3775
|
-
|
3776
|
-
|
3777
|
-
|
3778
|
-
|
4071
|
+
checkIfAttributeIsDisplayable as v,
|
4072
|
+
useGetAllDocumentsQuery as w,
|
4073
|
+
convertListLayoutToFieldLayouts as x,
|
4074
|
+
capitalise as y,
|
4075
|
+
useUpdateContentTypeConfigurationMutation as z
|
3779
4076
|
};
|
3780
|
-
//# sourceMappingURL=index-
|
4077
|
+
//# sourceMappingURL=index-BmUAydCA.mjs.map
|