@strapi/content-manager 0.0.0-experimental.25e22c6cc9bc6b35392bb55d09f641a0a65e7403 → 0.0.0-experimental.2bad311ac375d1115d085a9cee4fdbe11a455caf
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-gdUj_t-O.mjs → ComponentConfigurationPage-7-qB29e7.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-gdUj_t-O.mjs.map → ComponentConfigurationPage-7-qB29e7.mjs.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-WRPUXGd6.js → ComponentConfigurationPage-DP7AC0UU.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-WRPUXGd6.js.map → ComponentConfigurationPage-DP7AC0UU.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-BwuIPOJG.mjs → EditConfigurationPage-CI4XoymK.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-BwuIPOJG.mjs.map → EditConfigurationPage-CI4XoymK.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-C1vjMBgy.js → EditConfigurationPage-DITVliEI.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-C1vjMBgy.js.map → EditConfigurationPage-DITVliEI.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-DbcGfyqK.js → EditViewPage-CUS2EAhB.js} +24 -9
- package/dist/_chunks/EditViewPage-CUS2EAhB.js.map +1 -0
- package/dist/_chunks/{EditViewPage-0MiFkXa8.mjs → EditViewPage-Dzpno8xI.mjs} +24 -9
- package/dist/_chunks/EditViewPage-Dzpno8xI.mjs.map +1 -0
- package/dist/_chunks/{Field-BDMSCcy5.mjs → Field-B_jG_EV9.mjs} +479 -147
- package/dist/_chunks/Field-B_jG_EV9.mjs.map +1 -0
- package/dist/_chunks/{Field-BG1xu38N.js → Field-CtUU1Fg8.js} +481 -149
- package/dist/_chunks/Field-CtUU1Fg8.js.map +1 -0
- package/dist/_chunks/{Form-CPVWavB8.mjs → Form-BXHao2mZ.mjs} +39 -17
- package/dist/_chunks/Form-BXHao2mZ.mjs.map +1 -0
- package/dist/_chunks/{Form-9BnFyUjy.js → Form-DTqO0ymI.js} +39 -17
- package/dist/_chunks/Form-DTqO0ymI.js.map +1 -0
- package/dist/_chunks/{History-BVpd8LP3.mjs → History-2Ah2CQ4T.mjs} +44 -19
- package/dist/_chunks/History-2Ah2CQ4T.mjs.map +1 -0
- package/dist/_chunks/{History-BWWxLt2Z.js → History-C_uSGzO5.js} +44 -19
- package/dist/_chunks/History-C_uSGzO5.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DozVMKcR.mjs → ListConfigurationPage-BjSJlaoC.mjs} +20 -8
- package/dist/_chunks/ListConfigurationPage-BjSJlaoC.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-6swzjdAZ.js → ListConfigurationPage-nyuP7OSy.js} +20 -8
- package/dist/_chunks/ListConfigurationPage-nyuP7OSy.js.map +1 -0
- package/dist/_chunks/{ListViewPage-Ds0ulgfG.mjs → ListViewPage-B75x3nz2.mjs} +59 -41
- package/dist/_chunks/ListViewPage-B75x3nz2.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-BlzfjS2Q.js → ListViewPage-DHgHD8Xg.js} +61 -43
- package/dist/_chunks/ListViewPage-DHgHD8Xg.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-D2nCCWEl.js → NoContentTypePage-CDUKdZ7d.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-D2nCCWEl.js.map → NoContentTypePage-CDUKdZ7d.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-BH11kaKt.mjs → NoContentTypePage-DUacQSyF.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-BH11kaKt.mjs.map → NoContentTypePage-DUacQSyF.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-BT2Tn0D_.mjs → NoPermissionsPage-SFllMekk.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-BT2Tn0D_.mjs.map → NoPermissionsPage-SFllMekk.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-DN_JlsU2.js → NoPermissionsPage-zwIZydDI.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-DN_JlsU2.js.map → NoPermissionsPage-zwIZydDI.js.map} +1 -1
- package/dist/_chunks/{Relations-Dnag3fhV.mjs → Relations-D2NRW8fC.mjs} +14 -10
- package/dist/_chunks/Relations-D2NRW8fC.mjs.map +1 -0
- package/dist/_chunks/{Relations-CcgFTcWo.js → Relations-NFLaRNPr.js} +14 -10
- package/dist/_chunks/Relations-NFLaRNPr.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-JNNNKUHs.mjs → index-C9HxCo5R.mjs} +981 -662
- package/dist/_chunks/index-C9HxCo5R.mjs.map +1 -0
- package/dist/_chunks/{index-CWpLBSt0.js → index-ovJRE1FM.js} +973 -654
- package/dist/_chunks/index-ovJRE1FM.js.map +1 -0
- package/dist/_chunks/{layout-DC503LnF.mjs → layout-DaUjDiWQ.mjs} +27 -14
- package/dist/_chunks/layout-DaUjDiWQ.mjs.map +1 -0
- package/dist/_chunks/{layout--iHdZzRk.js → layout-UNWstw_s.js} +25 -12
- package/dist/_chunks/layout-UNWstw_s.js.map +1 -0
- package/dist/_chunks/{relations-CTje5t-a.mjs → relations-D8iFAeRu.mjs} +2 -2
- package/dist/_chunks/{relations-CTje5t-a.mjs.map → relations-D8iFAeRu.mjs.map} +1 -1
- package/dist/_chunks/{relations-BbHizA5K.js → relations-NN3coOG5.js} +2 -2
- package/dist/_chunks/{relations-BbHizA5K.js.map → relations-NN3coOG5.js.map} +1 -1
- package/dist/_chunks/{usePrev-B9w_-eYc.js → useDebounce-CtcjDB3L.js} +14 -1
- package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs +29 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -0
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +3 -2
- 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 +32 -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/BlocksInput/utils/constants.d.ts +4 -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 +11 -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 +191 -113
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +192 -114
- 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-0MiFkXa8.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-DbcGfyqK.js.map +0 -1
- package/dist/_chunks/Field-BDMSCcy5.mjs.map +0 -1
- package/dist/_chunks/Field-BG1xu38N.js.map +0 -1
- package/dist/_chunks/Form-9BnFyUjy.js.map +0 -1
- package/dist/_chunks/Form-CPVWavB8.mjs.map +0 -1
- package/dist/_chunks/History-BVpd8LP3.mjs.map +0 -1
- package/dist/_chunks/History-BWWxLt2Z.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-6swzjdAZ.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DozVMKcR.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-BlzfjS2Q.js.map +0 -1
- package/dist/_chunks/ListViewPage-Ds0ulgfG.mjs.map +0 -1
- package/dist/_chunks/Relations-CcgFTcWo.js.map +0 -1
- package/dist/_chunks/Relations-Dnag3fhV.mjs.map +0 -1
- package/dist/_chunks/index-CWpLBSt0.js.map +0 -1
- package/dist/_chunks/index-JNNNKUHs.mjs.map +0 -1
- package/dist/_chunks/layout--iHdZzRk.js.map +0 -1
- package/dist/_chunks/layout-DC503LnF.mjs.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, Typography, Dialog, Modal, Radio, Status, SingleSelect, SingleSelectOption,
|
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,10 +158,12 @@ 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({
|
166
|
+
overrideExisting: true,
|
201
167
|
endpoints: (builder) => ({
|
202
168
|
autoCloneDocument: builder.mutation({
|
203
169
|
query: ({ model, sourceId, query }) => ({
|
@@ -207,7 +173,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
207
173
|
params: query
|
208
174
|
}
|
209
175
|
}),
|
210
|
-
invalidatesTags: (_result,
|
176
|
+
invalidatesTags: (_result, error, { model }) => {
|
177
|
+
if (error) {
|
178
|
+
return [];
|
179
|
+
}
|
180
|
+
return [{ type: "Document", id: `${model}_LIST` }];
|
181
|
+
}
|
211
182
|
}),
|
212
183
|
cloneDocument: builder.mutation({
|
213
184
|
query: ({ model, sourceId, data, params }) => ({
|
@@ -218,7 +189,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
218
189
|
params
|
219
190
|
}
|
220
191
|
}),
|
221
|
-
invalidatesTags: (_result, _error, { model }) => [
|
192
|
+
invalidatesTags: (_result, _error, { model }) => [
|
193
|
+
{ type: "Document", id: `${model}_LIST` },
|
194
|
+
{ type: "UidAvailability", id: model }
|
195
|
+
]
|
222
196
|
}),
|
223
197
|
/**
|
224
198
|
* Creates a new collection-type document. This should ONLY be used for collection-types.
|
@@ -235,7 +209,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
235
209
|
}),
|
236
210
|
invalidatesTags: (result, _error, { model }) => [
|
237
211
|
{ type: "Document", id: `${model}_LIST` },
|
238
|
-
"Relations"
|
212
|
+
"Relations",
|
213
|
+
{ type: "UidAvailability", id: model }
|
239
214
|
]
|
240
215
|
}),
|
241
216
|
deleteDocument: builder.mutation({
|
@@ -276,7 +251,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
276
251
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
277
252
|
},
|
278
253
|
{ type: "Document", id: `${model}_LIST` },
|
279
|
-
"Relations"
|
254
|
+
"Relations",
|
255
|
+
{ type: "UidAvailability", id: model }
|
280
256
|
];
|
281
257
|
}
|
282
258
|
}),
|
@@ -294,6 +270,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
294
270
|
}),
|
295
271
|
providesTags: (result, _error, arg) => {
|
296
272
|
return [
|
273
|
+
{ type: "Document", id: `ALL_LIST` },
|
297
274
|
{ type: "Document", id: `${arg.model}_LIST` },
|
298
275
|
...result?.results.map(({ documentId }) => ({
|
299
276
|
type: "Document",
|
@@ -332,6 +309,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
332
309
|
{
|
333
310
|
type: "Document",
|
334
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`
|
335
317
|
}
|
336
318
|
];
|
337
319
|
}
|
@@ -395,8 +377,21 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
395
377
|
type: "Document",
|
396
378
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
397
379
|
},
|
398
|
-
"Relations"
|
380
|
+
"Relations",
|
381
|
+
{ type: "UidAvailability", id: model }
|
399
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
|
+
}
|
400
395
|
}
|
401
396
|
}),
|
402
397
|
unpublishDocument: builder.mutation({
|
@@ -466,7 +461,7 @@ const buildValidParams = (query) => {
|
|
466
461
|
const isBaseQueryError = (error) => {
|
467
462
|
return error.name !== void 0;
|
468
463
|
};
|
469
|
-
const createYupSchema = (attributes = {}, components = {}) => {
|
464
|
+
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
470
465
|
const createModelSchema = (attributes2) => yup.object().shape(
|
471
466
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
472
467
|
if (DOCUMENT_META_FIELDS.includes(name)) {
|
@@ -479,7 +474,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
479
474
|
addMinValidation,
|
480
475
|
addMaxValidation,
|
481
476
|
addRegexValidation
|
482
|
-
].map((fn) => fn(attribute));
|
477
|
+
].map((fn) => fn(attribute, options));
|
483
478
|
const transformSchema = pipe(...validations);
|
484
479
|
switch (attribute.type) {
|
485
480
|
case "component": {
|
@@ -528,7 +523,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
528
523
|
} else if (Array.isArray(value)) {
|
529
524
|
return yup.array().of(
|
530
525
|
yup.object().shape({
|
531
|
-
id: yup.
|
526
|
+
id: yup.number().required()
|
532
527
|
})
|
533
528
|
);
|
534
529
|
} else if (typeof value === "object") {
|
@@ -580,6 +575,14 @@ const createAttributeSchema = (attribute) => {
|
|
580
575
|
if (!value || typeof value === "string" && value.length === 0) {
|
581
576
|
return true;
|
582
577
|
}
|
578
|
+
if (typeof value === "object") {
|
579
|
+
try {
|
580
|
+
JSON.stringify(value);
|
581
|
+
return true;
|
582
|
+
} catch (err) {
|
583
|
+
return false;
|
584
|
+
}
|
585
|
+
}
|
583
586
|
try {
|
584
587
|
JSON.parse(value);
|
585
588
|
return true;
|
@@ -598,13 +601,7 @@ const createAttributeSchema = (attribute) => {
|
|
598
601
|
return yup.mixed();
|
599
602
|
}
|
600
603
|
};
|
601
|
-
const
|
602
|
-
if (attribute.required) {
|
603
|
-
return schema.required({
|
604
|
-
id: translatedErrors.required.id,
|
605
|
-
defaultMessage: "This field is required."
|
606
|
-
});
|
607
|
-
}
|
604
|
+
const nullableSchema = (schema) => {
|
608
605
|
return schema?.nullable ? schema.nullable() : (
|
609
606
|
// In some cases '.nullable' will not be available on the schema.
|
610
607
|
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
@@ -612,7 +609,22 @@ const addRequiredValidation = (attribute) => (schema) => {
|
|
612
609
|
schema
|
613
610
|
);
|
614
611
|
};
|
615
|
-
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
|
+
}
|
616
628
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
617
629
|
return schema.min(attribute.minLength, {
|
618
630
|
...translatedErrors.minLength,
|
@@ -634,9 +646,31 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
634
646
|
}
|
635
647
|
return schema;
|
636
648
|
};
|
637
|
-
const addMinValidation = (attribute) => (schema) => {
|
649
|
+
const addMinValidation = (attribute, options) => (schema) => {
|
638
650
|
if ("min" in attribute) {
|
639
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
|
+
}
|
640
674
|
if ("min" in schema && min) {
|
641
675
|
return schema.min(min, {
|
642
676
|
...translatedErrors.min,
|
@@ -755,16 +789,115 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
|
|
755
789
|
}, {});
|
756
790
|
return componentsByKey;
|
757
791
|
};
|
758
|
-
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);
|
759
891
|
const { toggleNotification } = useNotification();
|
760
892
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
893
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
761
894
|
const {
|
762
|
-
|
763
|
-
isLoading:
|
764
|
-
|
765
|
-
|
766
|
-
} =
|
767
|
-
const
|
895
|
+
data,
|
896
|
+
isLoading: isLoadingConfigs,
|
897
|
+
error,
|
898
|
+
isFetching: isFetchingConfigs
|
899
|
+
} = useGetContentTypeConfigurationQuery(model);
|
900
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
768
901
|
React.useEffect(() => {
|
769
902
|
if (error) {
|
770
903
|
toggleNotification({
|
@@ -772,56 +905,271 @@ const useDocument = (args, opts) => {
|
|
772
905
|
message: formatAPIError(error)
|
773
906
|
});
|
774
907
|
}
|
775
|
-
}, [
|
776
|
-
const
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
(document) => {
|
784
|
-
if (!validationSchema) {
|
785
|
-
throw new Error(
|
786
|
-
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
787
|
-
);
|
788
|
-
}
|
789
|
-
try {
|
790
|
-
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
791
|
-
return null;
|
792
|
-
} catch (error2) {
|
793
|
-
if (error2 instanceof ValidationError) {
|
794
|
-
return getYupValidationErrors(error2);
|
795
|
-
}
|
796
|
-
throw error2;
|
797
|
-
}
|
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
|
798
916
|
},
|
799
|
-
[
|
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]
|
800
933
|
);
|
801
|
-
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
802
934
|
return {
|
803
|
-
|
804
|
-
document: data?.data,
|
805
|
-
meta: data?.meta,
|
935
|
+
error,
|
806
936
|
isLoading,
|
807
|
-
|
808
|
-
|
937
|
+
edit,
|
938
|
+
list: listLayout
|
809
939
|
};
|
810
940
|
};
|
811
|
-
const
|
812
|
-
const {
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
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
|
+
const hasError = !!error;
|
1148
|
+
return {
|
1149
|
+
components,
|
1150
|
+
document: data?.data,
|
1151
|
+
meta: data?.meta,
|
1152
|
+
isLoading,
|
1153
|
+
hasError,
|
1154
|
+
schema,
|
1155
|
+
schemas,
|
1156
|
+
validate
|
1157
|
+
};
|
1158
|
+
};
|
1159
|
+
const useDoc = () => {
|
1160
|
+
const { id, slug, collectionType, origin } = useParams();
|
1161
|
+
const [{ query }] = useQueryParams();
|
1162
|
+
const params = React.useMemo(() => buildValidParams(query), [query]);
|
1163
|
+
if (!collectionType) {
|
1164
|
+
throw new Error("Could not find collectionType in url params");
|
1165
|
+
}
|
1166
|
+
if (!slug) {
|
1167
|
+
throw new Error("Could not find model in url params");
|
1168
|
+
}
|
1169
|
+
return {
|
1170
|
+
collectionType,
|
1171
|
+
model: slug,
|
1172
|
+
id: origin || id === "create" ? void 0 : id,
|
825
1173
|
...useDocument(
|
826
1174
|
{ documentId: origin || id, model: slug, collectionType, params },
|
827
1175
|
{
|
@@ -830,6 +1178,45 @@ const useDoc = () => {
|
|
830
1178
|
)
|
831
1179
|
};
|
832
1180
|
};
|
1181
|
+
const useContentManagerContext = () => {
|
1182
|
+
const {
|
1183
|
+
collectionType,
|
1184
|
+
model,
|
1185
|
+
id,
|
1186
|
+
components,
|
1187
|
+
isLoading: isLoadingDoc,
|
1188
|
+
schema,
|
1189
|
+
schemas
|
1190
|
+
} = useDoc();
|
1191
|
+
const layout = useDocumentLayout(model);
|
1192
|
+
const form = useForm("useContentManagerContext", (state) => state);
|
1193
|
+
const isSingleType = collectionType === SINGLE_TYPES;
|
1194
|
+
const slug = model;
|
1195
|
+
const isCreatingEntry = id === "create";
|
1196
|
+
useContentTypeSchema();
|
1197
|
+
const isLoading = isLoadingDoc || layout.isLoading;
|
1198
|
+
const error = layout.error;
|
1199
|
+
return {
|
1200
|
+
error,
|
1201
|
+
isLoading,
|
1202
|
+
// Base metadata
|
1203
|
+
model,
|
1204
|
+
collectionType,
|
1205
|
+
id,
|
1206
|
+
slug,
|
1207
|
+
isCreatingEntry,
|
1208
|
+
isSingleType,
|
1209
|
+
hasDraftAndPublish: schema?.options?.draftAndPublish ?? false,
|
1210
|
+
// All schema infos
|
1211
|
+
components,
|
1212
|
+
contentType: schema,
|
1213
|
+
contentTypes: schemas,
|
1214
|
+
// Form state
|
1215
|
+
form,
|
1216
|
+
// layout infos
|
1217
|
+
layout
|
1218
|
+
};
|
1219
|
+
};
|
833
1220
|
const prefixPluginTranslations = (trad, pluginId) => {
|
834
1221
|
if (!pluginId) {
|
835
1222
|
throw new TypeError("pluginId can't be empty");
|
@@ -849,6 +1236,8 @@ const useDocumentActions = () => {
|
|
849
1236
|
const { formatMessage } = useIntl();
|
850
1237
|
const { trackUsage } = useTracking();
|
851
1238
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1239
|
+
const navigate = useNavigate();
|
1240
|
+
const setCurrentStep = useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
852
1241
|
const [deleteDocument] = useDeleteDocumentMutation();
|
853
1242
|
const _delete = React.useCallback(
|
854
1243
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -1163,6 +1552,7 @@ const useDocumentActions = () => {
|
|
1163
1552
|
defaultMessage: "Saved document"
|
1164
1553
|
})
|
1165
1554
|
});
|
1555
|
+
setCurrentStep("contentManager.success");
|
1166
1556
|
return res.data;
|
1167
1557
|
} catch (err) {
|
1168
1558
|
toggleNotification({
|
@@ -1184,7 +1574,6 @@ const useDocumentActions = () => {
|
|
1184
1574
|
sourceId
|
1185
1575
|
});
|
1186
1576
|
if ("error" in res) {
|
1187
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1188
1577
|
return { error: res.error };
|
1189
1578
|
}
|
1190
1579
|
toggleNotification({
|
@@ -1203,7 +1592,7 @@ const useDocumentActions = () => {
|
|
1203
1592
|
throw err;
|
1204
1593
|
}
|
1205
1594
|
},
|
1206
|
-
[autoCloneDocument,
|
1595
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1207
1596
|
);
|
1208
1597
|
const [cloneDocument] = useCloneDocumentMutation();
|
1209
1598
|
const clone = React.useCallback(
|
@@ -1229,6 +1618,7 @@ const useDocumentActions = () => {
|
|
1229
1618
|
defaultMessage: "Cloned document"
|
1230
1619
|
})
|
1231
1620
|
});
|
1621
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1232
1622
|
return res.data;
|
1233
1623
|
} catch (err) {
|
1234
1624
|
toggleNotification({
|
@@ -1239,7 +1629,7 @@ const useDocumentActions = () => {
|
|
1239
1629
|
throw err;
|
1240
1630
|
}
|
1241
1631
|
},
|
1242
|
-
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
|
1632
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1243
1633
|
);
|
1244
1634
|
const [getDoc] = useLazyGetDocumentQuery();
|
1245
1635
|
const getDocument = React.useCallback(
|
@@ -1265,7 +1655,7 @@ const useDocumentActions = () => {
|
|
1265
1655
|
};
|
1266
1656
|
};
|
1267
1657
|
const ProtectedHistoryPage = lazy(
|
1268
|
-
() => import("./History-
|
1658
|
+
() => import("./History-2Ah2CQ4T.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1269
1659
|
);
|
1270
1660
|
const routes$1 = [
|
1271
1661
|
{
|
@@ -1278,31 +1668,31 @@ const routes$1 = [
|
|
1278
1668
|
}
|
1279
1669
|
];
|
1280
1670
|
const ProtectedEditViewPage = lazy(
|
1281
|
-
() => import("./EditViewPage-
|
1671
|
+
() => import("./EditViewPage-Dzpno8xI.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1282
1672
|
);
|
1283
1673
|
const ProtectedListViewPage = lazy(
|
1284
|
-
() => import("./ListViewPage-
|
1674
|
+
() => import("./ListViewPage-B75x3nz2.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1285
1675
|
);
|
1286
1676
|
const ProtectedListConfiguration = lazy(
|
1287
|
-
() => import("./ListConfigurationPage-
|
1677
|
+
() => import("./ListConfigurationPage-BjSJlaoC.mjs").then((mod) => ({
|
1288
1678
|
default: mod.ProtectedListConfiguration
|
1289
1679
|
}))
|
1290
1680
|
);
|
1291
1681
|
const ProtectedEditConfigurationPage = lazy(
|
1292
|
-
() => import("./EditConfigurationPage-
|
1682
|
+
() => import("./EditConfigurationPage-CI4XoymK.mjs").then((mod) => ({
|
1293
1683
|
default: mod.ProtectedEditConfigurationPage
|
1294
1684
|
}))
|
1295
1685
|
);
|
1296
1686
|
const ProtectedComponentConfigurationPage = lazy(
|
1297
|
-
() => import("./ComponentConfigurationPage-
|
1687
|
+
() => import("./ComponentConfigurationPage-7-qB29e7.mjs").then((mod) => ({
|
1298
1688
|
default: mod.ProtectedComponentConfigurationPage
|
1299
1689
|
}))
|
1300
1690
|
);
|
1301
1691
|
const NoPermissions = lazy(
|
1302
|
-
() => import("./NoPermissionsPage-
|
1692
|
+
() => import("./NoPermissionsPage-SFllMekk.mjs").then((mod) => ({ default: mod.NoPermissions }))
|
1303
1693
|
);
|
1304
1694
|
const NoContentType = lazy(
|
1305
|
-
() => import("./NoContentTypePage-
|
1695
|
+
() => import("./NoContentTypePage-DUacQSyF.mjs").then((mod) => ({ default: mod.NoContentType }))
|
1306
1696
|
);
|
1307
1697
|
const CollectionTypePages = () => {
|
1308
1698
|
const { collectionType } = useParams();
|
@@ -1416,12 +1806,14 @@ const DocumentActionButton = (action) => {
|
|
1416
1806
|
/* @__PURE__ */ jsx(
|
1417
1807
|
Button,
|
1418
1808
|
{
|
1419
|
-
flex:
|
1809
|
+
flex: "auto",
|
1420
1810
|
startIcon: action.icon,
|
1421
1811
|
disabled: action.disabled,
|
1422
1812
|
onClick: handleClick(action),
|
1423
1813
|
justifyContent: "center",
|
1424
1814
|
variant: action.variant || "default",
|
1815
|
+
paddingTop: "7px",
|
1816
|
+
paddingBottom: "7px",
|
1425
1817
|
children: action.label
|
1426
1818
|
}
|
1427
1819
|
),
|
@@ -1429,7 +1821,7 @@ const DocumentActionButton = (action) => {
|
|
1429
1821
|
DocumentActionConfirmDialog,
|
1430
1822
|
{
|
1431
1823
|
...action.dialog,
|
1432
|
-
variant: action.variant,
|
1824
|
+
variant: action.dialog?.variant ?? action.variant,
|
1433
1825
|
isOpen: dialogId === action.id,
|
1434
1826
|
onClose: handleClose
|
1435
1827
|
}
|
@@ -1486,9 +1878,9 @@ const DocumentActionsMenu = ({
|
|
1486
1878
|
disabled: isDisabled,
|
1487
1879
|
size: "S",
|
1488
1880
|
endIcon: null,
|
1489
|
-
paddingTop: "
|
1490
|
-
paddingLeft: "
|
1491
|
-
paddingRight: "
|
1881
|
+
paddingTop: "4px",
|
1882
|
+
paddingLeft: "7px",
|
1883
|
+
paddingRight: "7px",
|
1492
1884
|
variant,
|
1493
1885
|
children: [
|
1494
1886
|
/* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
|
@@ -1499,7 +1891,7 @@ const DocumentActionsMenu = ({
|
|
1499
1891
|
]
|
1500
1892
|
}
|
1501
1893
|
),
|
1502
|
-
/* @__PURE__ */ jsxs(Menu.Content, {
|
1894
|
+
/* @__PURE__ */ jsxs(Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1503
1895
|
actions2.map((action) => {
|
1504
1896
|
return /* @__PURE__ */ jsx(
|
1505
1897
|
Menu.Item,
|
@@ -1508,10 +1900,25 @@ const DocumentActionsMenu = ({
|
|
1508
1900
|
onSelect: handleClick(action),
|
1509
1901
|
display: "block",
|
1510
1902
|
children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", gap: 4, children: [
|
1511
|
-
/* @__PURE__ */ jsxs(
|
1512
|
-
|
1513
|
-
|
1514
|
-
|
1903
|
+
/* @__PURE__ */ jsxs(
|
1904
|
+
Flex,
|
1905
|
+
{
|
1906
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1907
|
+
gap: 2,
|
1908
|
+
tag: "span",
|
1909
|
+
children: [
|
1910
|
+
/* @__PURE__ */ jsx(
|
1911
|
+
Flex,
|
1912
|
+
{
|
1913
|
+
tag: "span",
|
1914
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1915
|
+
children: action.icon
|
1916
|
+
}
|
1917
|
+
),
|
1918
|
+
action.label
|
1919
|
+
]
|
1920
|
+
}
|
1921
|
+
),
|
1515
1922
|
action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsx(
|
1516
1923
|
Flex,
|
1517
1924
|
{
|
@@ -1570,6 +1977,18 @@ const convertActionVariantToColor = (variant = "secondary") => {
|
|
1570
1977
|
return "primary600";
|
1571
1978
|
}
|
1572
1979
|
};
|
1980
|
+
const convertActionVariantToIconColor = (variant = "secondary") => {
|
1981
|
+
switch (variant) {
|
1982
|
+
case "danger":
|
1983
|
+
return "danger600";
|
1984
|
+
case "secondary":
|
1985
|
+
return "neutral500";
|
1986
|
+
case "success":
|
1987
|
+
return "success600";
|
1988
|
+
default:
|
1989
|
+
return "primary600";
|
1990
|
+
}
|
1991
|
+
};
|
1573
1992
|
const DocumentActionConfirmDialog = ({
|
1574
1993
|
onClose,
|
1575
1994
|
onCancel,
|
@@ -1596,11 +2015,11 @@ const DocumentActionConfirmDialog = ({
|
|
1596
2015
|
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
1597
2016
|
/* @__PURE__ */ jsx(Dialog.Body, { children: content }),
|
1598
2017
|
/* @__PURE__ */ jsxs(Dialog.Footer, { children: [
|
1599
|
-
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", children: formatMessage({
|
2018
|
+
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", fullWidth: true, children: formatMessage({
|
1600
2019
|
id: "app.components.Button.cancel",
|
1601
2020
|
defaultMessage: "Cancel"
|
1602
2021
|
}) }) }),
|
1603
|
-
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, children: formatMessage({
|
2022
|
+
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
|
1604
2023
|
id: "app.components.Button.confirm",
|
1605
2024
|
defaultMessage: "Confirm"
|
1606
2025
|
}) })
|
@@ -1639,13 +2058,17 @@ const PublishAction$1 = ({
|
|
1639
2058
|
const navigate = useNavigate();
|
1640
2059
|
const { toggleNotification } = useNotification();
|
1641
2060
|
const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
|
2061
|
+
const isListView = useMatch(LIST_PATH) !== null;
|
1642
2062
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
1643
2063
|
const { formatMessage } = useIntl();
|
1644
|
-
const { canPublish
|
1645
|
-
"PublishAction",
|
1646
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1647
|
-
);
|
2064
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1648
2065
|
const { publish } = useDocumentActions();
|
2066
|
+
const [
|
2067
|
+
countDraftRelations,
|
2068
|
+
{ isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
|
2069
|
+
] = useLazyGetDraftRelationCountQuery();
|
2070
|
+
const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React.useState(0);
|
2071
|
+
const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React.useState(0);
|
1649
2072
|
const [{ query, rawQuery }] = useQueryParams();
|
1650
2073
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
1651
2074
|
const modified = useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
@@ -1654,10 +2077,103 @@ const PublishAction$1 = ({
|
|
1654
2077
|
const validate = useForm("PublishAction", (state) => state.validate);
|
1655
2078
|
const setErrors = useForm("PublishAction", (state) => state.setErrors);
|
1656
2079
|
const formValues = useForm("PublishAction", ({ values }) => values);
|
1657
|
-
|
1658
|
-
|
2080
|
+
React.useEffect(() => {
|
2081
|
+
if (isErrorDraftRelations) {
|
2082
|
+
toggleNotification({
|
2083
|
+
type: "danger",
|
2084
|
+
message: formatMessage({
|
2085
|
+
id: getTranslation("error.records.fetch-draft-relatons"),
|
2086
|
+
defaultMessage: "An error occurred while fetching draft relations on this document."
|
2087
|
+
})
|
2088
|
+
});
|
2089
|
+
}
|
2090
|
+
}, [isErrorDraftRelations, toggleNotification, formatMessage]);
|
2091
|
+
React.useEffect(() => {
|
2092
|
+
const localDraftRelations = /* @__PURE__ */ new Set();
|
2093
|
+
const extractDraftRelations = (data) => {
|
2094
|
+
const relations = data.connect || [];
|
2095
|
+
relations.forEach((relation) => {
|
2096
|
+
if (relation.status === "draft") {
|
2097
|
+
localDraftRelations.add(relation.id);
|
2098
|
+
}
|
2099
|
+
});
|
2100
|
+
};
|
2101
|
+
const traverseAndExtract = (data) => {
|
2102
|
+
Object.entries(data).forEach(([key, value]) => {
|
2103
|
+
if (key === "connect" && Array.isArray(value)) {
|
2104
|
+
extractDraftRelations({ connect: value });
|
2105
|
+
} else if (typeof value === "object" && value !== null) {
|
2106
|
+
traverseAndExtract(value);
|
2107
|
+
}
|
2108
|
+
});
|
2109
|
+
};
|
2110
|
+
if (!documentId || modified) {
|
2111
|
+
traverseAndExtract(formValues);
|
2112
|
+
setLocalCountOfDraftRelations(localDraftRelations.size);
|
2113
|
+
}
|
2114
|
+
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
2115
|
+
React.useEffect(() => {
|
2116
|
+
if (!document || !document.documentId || isListView) {
|
2117
|
+
return;
|
2118
|
+
}
|
2119
|
+
const fetchDraftRelationsCount = async () => {
|
2120
|
+
const { data, error } = await countDraftRelations({
|
2121
|
+
collectionType,
|
2122
|
+
model,
|
2123
|
+
documentId,
|
2124
|
+
params
|
2125
|
+
});
|
2126
|
+
if (error) {
|
2127
|
+
throw error;
|
2128
|
+
}
|
2129
|
+
if (data) {
|
2130
|
+
setServerCountOfDraftRelations(data.data);
|
2131
|
+
}
|
2132
|
+
};
|
2133
|
+
fetchDraftRelationsCount();
|
2134
|
+
}, [isListView, document, documentId, countDraftRelations, collectionType, model, params]);
|
2135
|
+
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
2136
|
+
if (!schema?.options?.draftAndPublish) {
|
1659
2137
|
return null;
|
1660
2138
|
}
|
2139
|
+
const performPublish = async () => {
|
2140
|
+
setSubmitting(true);
|
2141
|
+
try {
|
2142
|
+
const { errors } = await validate();
|
2143
|
+
if (errors) {
|
2144
|
+
toggleNotification({
|
2145
|
+
type: "danger",
|
2146
|
+
message: formatMessage({
|
2147
|
+
id: "content-manager.validation.error",
|
2148
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2149
|
+
})
|
2150
|
+
});
|
2151
|
+
return;
|
2152
|
+
}
|
2153
|
+
const res = await publish(
|
2154
|
+
{
|
2155
|
+
collectionType,
|
2156
|
+
model,
|
2157
|
+
documentId,
|
2158
|
+
params
|
2159
|
+
},
|
2160
|
+
formValues
|
2161
|
+
);
|
2162
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
2163
|
+
navigate({
|
2164
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
2165
|
+
search: rawQuery
|
2166
|
+
});
|
2167
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2168
|
+
setErrors(formatValidationErrors(res.error));
|
2169
|
+
}
|
2170
|
+
} finally {
|
2171
|
+
setSubmitting(false);
|
2172
|
+
}
|
2173
|
+
};
|
2174
|
+
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
2175
|
+
const enableDraftRelationsCount = false;
|
2176
|
+
const hasDraftRelations = enableDraftRelationsCount;
|
1661
2177
|
return {
|
1662
2178
|
/**
|
1663
2179
|
* Disabled when:
|
@@ -1667,49 +2183,36 @@ const PublishAction$1 = ({
|
|
1667
2183
|
* - the document is already published & not modified
|
1668
2184
|
* - the document is being created & not modified
|
1669
2185
|
* - the user doesn't have the permission to publish
|
1670
|
-
* - the user doesn't have the permission to create a new document
|
1671
|
-
* - the user doesn't have the permission to update the document
|
1672
2186
|
*/
|
1673
|
-
disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish
|
2187
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
1674
2188
|
label: formatMessage({
|
1675
2189
|
id: "app.utils.publish",
|
1676
2190
|
defaultMessage: "Publish"
|
1677
2191
|
}),
|
1678
2192
|
onClick: async () => {
|
1679
|
-
|
1680
|
-
|
1681
|
-
|
1682
|
-
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
1686
|
-
|
1687
|
-
|
1688
|
-
|
1689
|
-
|
1690
|
-
|
1691
|
-
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
documentId,
|
1697
|
-
params
|
1698
|
-
},
|
1699
|
-
formValues
|
1700
|
-
);
|
1701
|
-
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1702
|
-
navigate({
|
1703
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1704
|
-
search: rawQuery
|
1705
|
-
});
|
1706
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1707
|
-
setErrors(formatValidationErrors(res.error));
|
2193
|
+
await performPublish();
|
2194
|
+
},
|
2195
|
+
dialog: hasDraftRelations ? {
|
2196
|
+
type: "dialog",
|
2197
|
+
variant: "danger",
|
2198
|
+
footer: null,
|
2199
|
+
title: formatMessage({
|
2200
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
|
2201
|
+
defaultMessage: "Confirmation"
|
2202
|
+
}),
|
2203
|
+
content: formatMessage(
|
2204
|
+
{
|
2205
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
2206
|
+
defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
|
2207
|
+
},
|
2208
|
+
{
|
2209
|
+
count: totalDraftRelations
|
1708
2210
|
}
|
1709
|
-
|
1710
|
-
|
2211
|
+
),
|
2212
|
+
onConfirm: async () => {
|
2213
|
+
await performPublish();
|
1711
2214
|
}
|
1712
|
-
}
|
2215
|
+
} : void 0
|
1713
2216
|
};
|
1714
2217
|
};
|
1715
2218
|
PublishAction$1.type = "publish";
|
@@ -1725,10 +2228,6 @@ const UpdateAction = ({
|
|
1725
2228
|
const cloneMatch = useMatch(CLONE_PATH);
|
1726
2229
|
const isCloning = cloneMatch !== null;
|
1727
2230
|
const { formatMessage } = useIntl();
|
1728
|
-
const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1729
|
-
canCreate: canCreate2,
|
1730
|
-
canUpdate: canUpdate2
|
1731
|
-
}));
|
1732
2231
|
const { create, update, clone } = useDocumentActions();
|
1733
2232
|
const [{ query, rawQuery }] = useQueryParams();
|
1734
2233
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
@@ -1745,10 +2244,8 @@ const UpdateAction = ({
|
|
1745
2244
|
* - the form is submitting
|
1746
2245
|
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
1747
2246
|
* - the active tab is the published tab
|
1748
|
-
* - the user doesn't have the permission to create a new document
|
1749
|
-
* - the user doesn't have the permission to update the document
|
1750
2247
|
*/
|
1751
|
-
disabled: isSubmitting || !modified && !isCloning || activeTab === "published"
|
2248
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1752
2249
|
label: formatMessage({
|
1753
2250
|
id: "content-manager.containers.Edit.save",
|
1754
2251
|
defaultMessage: "Save"
|
@@ -1756,16 +2253,18 @@ const UpdateAction = ({
|
|
1756
2253
|
onClick: async () => {
|
1757
2254
|
setSubmitting(true);
|
1758
2255
|
try {
|
1759
|
-
|
1760
|
-
|
1761
|
-
|
1762
|
-
|
1763
|
-
|
1764
|
-
|
1765
|
-
|
1766
|
-
|
1767
|
-
|
1768
|
-
|
2256
|
+
if (activeTab !== "draft") {
|
2257
|
+
const { errors } = await validate();
|
2258
|
+
if (errors) {
|
2259
|
+
toggleNotification({
|
2260
|
+
type: "danger",
|
2261
|
+
message: formatMessage({
|
2262
|
+
id: "content-manager.validation.error",
|
2263
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2264
|
+
})
|
2265
|
+
});
|
2266
|
+
return;
|
2267
|
+
}
|
1769
2268
|
}
|
1770
2269
|
if (isCloning) {
|
1771
2270
|
const res = await clone(
|
@@ -1777,10 +2276,13 @@ const UpdateAction = ({
|
|
1777
2276
|
document
|
1778
2277
|
);
|
1779
2278
|
if ("data" in res) {
|
1780
|
-
navigate(
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
2279
|
+
navigate(
|
2280
|
+
{
|
2281
|
+
pathname: `../${res.data.documentId}`,
|
2282
|
+
search: rawQuery
|
2283
|
+
},
|
2284
|
+
{ relative: "path" }
|
2285
|
+
);
|
1784
2286
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1785
2287
|
setErrors(formatValidationErrors(res.error));
|
1786
2288
|
}
|
@@ -1808,10 +2310,13 @@ const UpdateAction = ({
|
|
1808
2310
|
document
|
1809
2311
|
);
|
1810
2312
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1811
|
-
navigate(
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
2313
|
+
navigate(
|
2314
|
+
{
|
2315
|
+
pathname: `../${res.data.documentId}`,
|
2316
|
+
search: rawQuery
|
2317
|
+
},
|
2318
|
+
{ replace: true, relative: "path" }
|
2319
|
+
);
|
1815
2320
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1816
2321
|
setErrors(formatValidationErrors(res.error));
|
1817
2322
|
}
|
@@ -1855,7 +2360,7 @@ const UnpublishAction$1 = ({
|
|
1855
2360
|
id: "app.utils.unpublish",
|
1856
2361
|
defaultMessage: "Unpublish"
|
1857
2362
|
}),
|
1858
|
-
icon: /* @__PURE__ */ jsx(
|
2363
|
+
icon: /* @__PURE__ */ jsx(Cross, {}),
|
1859
2364
|
onClick: async () => {
|
1860
2365
|
if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
|
1861
2366
|
if (!documentId) {
|
@@ -1967,7 +2472,7 @@ const DiscardAction = ({
|
|
1967
2472
|
id: "content-manager.actions.discard.label",
|
1968
2473
|
defaultMessage: "Discard changes"
|
1969
2474
|
}),
|
1970
|
-
icon: /* @__PURE__ */ jsx(
|
2475
|
+
icon: /* @__PURE__ */ jsx(Cross, {}),
|
1971
2476
|
position: ["panel", "table-row"],
|
1972
2477
|
variant: "danger",
|
1973
2478
|
dialog: {
|
@@ -1995,11 +2500,6 @@ const DiscardAction = ({
|
|
1995
2500
|
};
|
1996
2501
|
};
|
1997
2502
|
DiscardAction.type = "discard";
|
1998
|
-
const StyledCrossCircle = styled(CrossCircle)`
|
1999
|
-
path {
|
2000
|
-
fill: currentColor;
|
2001
|
-
}
|
2002
|
-
`;
|
2003
2503
|
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2004
2504
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2005
2505
|
const RelativeTime = React.forwardRef(
|
@@ -2047,7 +2547,7 @@ const getDisplayName = ({
|
|
2047
2547
|
};
|
2048
2548
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2049
2549
|
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2050
|
-
const statusVariant = status === "draft" ? "
|
2550
|
+
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2051
2551
|
return /* @__PURE__ */ jsx(Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: capitalise(status) }) });
|
2052
2552
|
};
|
2053
2553
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
@@ -2057,23 +2557,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
|
2057
2557
|
id: "content-manager.containers.edit.title.new",
|
2058
2558
|
defaultMessage: "Create an entry"
|
2059
2559
|
}) : documentTitle;
|
2060
|
-
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop:
|
2560
|
+
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2061
2561
|
/* @__PURE__ */ jsx(BackButton, {}),
|
2062
|
-
/* @__PURE__ */ jsxs(
|
2063
|
-
|
2064
|
-
{
|
2065
|
-
|
2066
|
-
|
2067
|
-
paddingTop: 1,
|
2068
|
-
gap: "80px",
|
2069
|
-
alignItems: "flex-start",
|
2070
|
-
children: [
|
2071
|
-
/* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
|
2072
|
-
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
2073
|
-
]
|
2074
|
-
}
|
2075
|
-
),
|
2076
|
-
status ? /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) : null
|
2562
|
+
/* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2563
|
+
/* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
|
2564
|
+
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
2565
|
+
] }),
|
2566
|
+
status ? /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
|
2077
2567
|
] });
|
2078
2568
|
};
|
2079
2569
|
const HeaderToolbar = () => {
|
@@ -2240,25 +2730,77 @@ const Information = ({ activeTab }) => {
|
|
2240
2730
|
);
|
2241
2731
|
};
|
2242
2732
|
const HeaderActions = ({ actions: actions2 }) => {
|
2243
|
-
|
2244
|
-
|
2733
|
+
const [dialogId, setDialogId] = React.useState(null);
|
2734
|
+
const handleClick = (action) => async (e) => {
|
2735
|
+
if (!("options" in action)) {
|
2736
|
+
const { onClick = () => false, dialog, id } = action;
|
2737
|
+
const muteDialog = await onClick(e);
|
2738
|
+
if (dialog && !muteDialog) {
|
2739
|
+
e.preventDefault();
|
2740
|
+
setDialogId(id);
|
2741
|
+
}
|
2742
|
+
}
|
2743
|
+
};
|
2744
|
+
const handleClose = () => {
|
2745
|
+
setDialogId(null);
|
2746
|
+
};
|
2747
|
+
return /* @__PURE__ */ jsx(Flex, { gap: 1, children: actions2.map((action) => {
|
2748
|
+
if (action.options) {
|
2245
2749
|
return /* @__PURE__ */ jsx(
|
2246
2750
|
SingleSelect,
|
2247
2751
|
{
|
2248
2752
|
size: "S",
|
2249
|
-
disabled: action.disabled,
|
2250
|
-
"aria-label": action.label,
|
2251
2753
|
onChange: action.onSelect,
|
2252
|
-
|
2754
|
+
"aria-label": action.label,
|
2755
|
+
...action,
|
2253
2756
|
children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsx(SingleSelectOption, { ...option, children: label }, option.value))
|
2254
2757
|
},
|
2255
2758
|
action.id
|
2256
2759
|
);
|
2257
2760
|
} else {
|
2258
|
-
|
2761
|
+
if (action.type === "icon") {
|
2762
|
+
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
2763
|
+
/* @__PURE__ */ jsx(
|
2764
|
+
IconButton,
|
2765
|
+
{
|
2766
|
+
disabled: action.disabled,
|
2767
|
+
label: action.label,
|
2768
|
+
size: "S",
|
2769
|
+
onClick: handleClick(action),
|
2770
|
+
children: action.icon
|
2771
|
+
}
|
2772
|
+
),
|
2773
|
+
action.dialog ? /* @__PURE__ */ jsx(
|
2774
|
+
HeaderActionDialog,
|
2775
|
+
{
|
2776
|
+
...action.dialog,
|
2777
|
+
isOpen: dialogId === action.id,
|
2778
|
+
onClose: handleClose
|
2779
|
+
}
|
2780
|
+
) : null
|
2781
|
+
] }, action.id);
|
2782
|
+
}
|
2259
2783
|
}
|
2260
2784
|
}) });
|
2261
2785
|
};
|
2786
|
+
const HeaderActionDialog = ({
|
2787
|
+
onClose,
|
2788
|
+
onCancel,
|
2789
|
+
title,
|
2790
|
+
content: Content,
|
2791
|
+
isOpen
|
2792
|
+
}) => {
|
2793
|
+
const handleClose = async () => {
|
2794
|
+
if (onCancel) {
|
2795
|
+
await onCancel();
|
2796
|
+
}
|
2797
|
+
onClose();
|
2798
|
+
};
|
2799
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
2800
|
+
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
2801
|
+
typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : Content
|
2802
|
+
] }) });
|
2803
|
+
};
|
2262
2804
|
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
2263
2805
|
const navigate = useNavigate();
|
2264
2806
|
const { formatMessage } = useIntl();
|
@@ -2299,12 +2841,16 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2299
2841
|
const { delete: deleteAction } = useDocumentActions();
|
2300
2842
|
const { toggleNotification } = useNotification();
|
2301
2843
|
const setSubmitting = useForm("DeleteAction", (state) => state.setSubmitting);
|
2844
|
+
const isLocalized = document?.locale != null;
|
2302
2845
|
return {
|
2303
2846
|
disabled: !canDelete || !document,
|
2304
|
-
label: formatMessage(
|
2305
|
-
|
2306
|
-
|
2307
|
-
|
2847
|
+
label: formatMessage(
|
2848
|
+
{
|
2849
|
+
id: "content-manager.actions.delete.label",
|
2850
|
+
defaultMessage: "Delete entry{isLocalized, select, true { (all locales)} other {}}"
|
2851
|
+
},
|
2852
|
+
{ isLocalized }
|
2853
|
+
),
|
2308
2854
|
icon: /* @__PURE__ */ jsx(Trash, {}),
|
2309
2855
|
dialog: {
|
2310
2856
|
type: "dialog",
|
@@ -2340,423 +2886,121 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2340
2886
|
const res = await deleteAction({
|
2341
2887
|
documentId,
|
2342
2888
|
model,
|
2343
|
-
collectionType,
|
2344
|
-
params: {
|
2345
|
-
locale: "*"
|
2346
|
-
}
|
2347
|
-
});
|
2348
|
-
if (!("error" in res)) {
|
2349
|
-
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
2350
|
-
}
|
2351
|
-
} finally {
|
2352
|
-
if (!listViewPathMatch) {
|
2353
|
-
setSubmitting(false);
|
2354
|
-
}
|
2355
|
-
}
|
2356
|
-
}
|
2357
|
-
},
|
2358
|
-
variant: "danger",
|
2359
|
-
position: ["header", "table-row"]
|
2360
|
-
};
|
2361
|
-
};
|
2362
|
-
DeleteAction$1.type = "delete";
|
2363
|
-
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2364
|
-
const Panels = () => {
|
2365
|
-
const isCloning = useMatch(CLONE_PATH) !== null;
|
2366
|
-
const [
|
2367
|
-
{
|
2368
|
-
query: { status }
|
2369
|
-
}
|
2370
|
-
] = useQueryParams({
|
2371
|
-
status: "draft"
|
2372
|
-
});
|
2373
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2374
|
-
const plugins = useStrapiApp("Panels", (state) => state.plugins);
|
2375
|
-
const props = {
|
2376
|
-
activeTab: status,
|
2377
|
-
model,
|
2378
|
-
documentId: id,
|
2379
|
-
document: isCloning ? void 0 : document,
|
2380
|
-
meta: isCloning ? void 0 : meta,
|
2381
|
-
collectionType
|
2382
|
-
};
|
2383
|
-
return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsx(
|
2384
|
-
DescriptionComponentRenderer,
|
2385
|
-
{
|
2386
|
-
props,
|
2387
|
-
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2388
|
-
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsx(Panel, { ...description, children: content }, id2))
|
2389
|
-
}
|
2390
|
-
) });
|
2391
|
-
};
|
2392
|
-
const ActionsPanel = () => {
|
2393
|
-
const { formatMessage } = useIntl();
|
2394
|
-
return {
|
2395
|
-
title: formatMessage({
|
2396
|
-
id: "content-manager.containers.edit.panels.default.title",
|
2397
|
-
defaultMessage: "Document"
|
2398
|
-
}),
|
2399
|
-
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2400
|
-
};
|
2401
|
-
};
|
2402
|
-
ActionsPanel.type = "actions";
|
2403
|
-
const ActionsPanelContent = () => {
|
2404
|
-
const isCloning = useMatch(CLONE_PATH) !== null;
|
2405
|
-
const [
|
2406
|
-
{
|
2407
|
-
query: { status = "draft" }
|
2408
|
-
}
|
2409
|
-
] = useQueryParams();
|
2410
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2411
|
-
const plugins = useStrapiApp("ActionsPanel", (state) => state.plugins);
|
2412
|
-
const props = {
|
2413
|
-
activeTab: status,
|
2414
|
-
model,
|
2415
|
-
documentId: id,
|
2416
|
-
document: isCloning ? void 0 : document,
|
2417
|
-
meta: isCloning ? void 0 : meta,
|
2418
|
-
collectionType
|
2419
|
-
};
|
2420
|
-
return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
|
2421
|
-
/* @__PURE__ */ jsx(
|
2422
|
-
DescriptionComponentRenderer,
|
2423
|
-
{
|
2424
|
-
props,
|
2425
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2426
|
-
children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
|
2427
|
-
}
|
2428
|
-
),
|
2429
|
-
/* @__PURE__ */ jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
2430
|
-
] });
|
2431
|
-
};
|
2432
|
-
const Panel = React.forwardRef(({ children, title }, ref) => {
|
2433
|
-
return /* @__PURE__ */ jsxs(
|
2434
|
-
Flex,
|
2435
|
-
{
|
2436
|
-
ref,
|
2437
|
-
tag: "aside",
|
2438
|
-
"aria-labelledby": "additional-information",
|
2439
|
-
background: "neutral0",
|
2440
|
-
borderColor: "neutral150",
|
2441
|
-
hasRadius: true,
|
2442
|
-
paddingBottom: 4,
|
2443
|
-
paddingLeft: 4,
|
2444
|
-
paddingRight: 4,
|
2445
|
-
paddingTop: 4,
|
2446
|
-
shadow: "tableShadow",
|
2447
|
-
gap: 3,
|
2448
|
-
direction: "column",
|
2449
|
-
justifyContent: "stretch",
|
2450
|
-
alignItems: "flex-start",
|
2451
|
-
children: [
|
2452
|
-
/* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2453
|
-
children
|
2454
|
-
]
|
2455
|
-
}
|
2456
|
-
);
|
2457
|
-
});
|
2458
|
-
const HOOKS = {
|
2459
|
-
/**
|
2460
|
-
* Hook that allows to mutate the displayed headers of the list view table
|
2461
|
-
* @constant
|
2462
|
-
* @type {string}
|
2463
|
-
*/
|
2464
|
-
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2465
|
-
/**
|
2466
|
-
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2467
|
-
* @constant
|
2468
|
-
* @type {string}
|
2469
|
-
*/
|
2470
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2471
|
-
/**
|
2472
|
-
* Hook that allows to mutate the CM's edit view layout
|
2473
|
-
* @constant
|
2474
|
-
* @type {string}
|
2475
|
-
*/
|
2476
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2477
|
-
/**
|
2478
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
2479
|
-
* @constant
|
2480
|
-
* @type {string}
|
2481
|
-
*/
|
2482
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2483
|
-
};
|
2484
|
-
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2485
|
-
endpoints: (builder) => ({
|
2486
|
-
getContentTypeConfiguration: builder.query({
|
2487
|
-
query: (uid) => ({
|
2488
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2489
|
-
method: "GET"
|
2490
|
-
}),
|
2491
|
-
transformResponse: (response) => response.data,
|
2492
|
-
providesTags: (_result, _error, uid) => [
|
2493
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2494
|
-
{ type: "ContentTypeSettings", id: "LIST" }
|
2495
|
-
]
|
2496
|
-
}),
|
2497
|
-
getAllContentTypeSettings: builder.query({
|
2498
|
-
query: () => "/content-manager/content-types-settings",
|
2499
|
-
transformResponse: (response) => response.data,
|
2500
|
-
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2501
|
-
}),
|
2502
|
-
updateContentTypeConfiguration: builder.mutation({
|
2503
|
-
query: ({ uid, ...body }) => ({
|
2504
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2505
|
-
method: "PUT",
|
2506
|
-
data: body
|
2507
|
-
}),
|
2508
|
-
transformResponse: (response) => response.data,
|
2509
|
-
invalidatesTags: (_result, _error, { uid }) => [
|
2510
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2511
|
-
{ type: "ContentTypeSettings", id: "LIST" },
|
2512
|
-
// Is this necessary?
|
2513
|
-
{ type: "InitialData" }
|
2514
|
-
]
|
2515
|
-
})
|
2516
|
-
})
|
2517
|
-
});
|
2518
|
-
const {
|
2519
|
-
useGetContentTypeConfigurationQuery,
|
2520
|
-
useGetAllContentTypeSettingsQuery,
|
2521
|
-
useUpdateContentTypeConfigurationMutation
|
2522
|
-
} = contentTypesApi;
|
2523
|
-
const checkIfAttributeIsDisplayable = (attribute) => {
|
2524
|
-
const { type } = attribute;
|
2525
|
-
if (type === "relation") {
|
2526
|
-
return !attribute.relation.toLowerCase().includes("morph");
|
2527
|
-
}
|
2528
|
-
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2529
|
-
};
|
2530
|
-
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2531
|
-
if (!mainFieldName) {
|
2532
|
-
return void 0;
|
2533
|
-
}
|
2534
|
-
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2535
|
-
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2536
|
-
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2537
|
-
);
|
2538
|
-
return {
|
2539
|
-
name: mainFieldName,
|
2540
|
-
type: mainFieldType ?? "string"
|
2541
|
-
};
|
2542
|
-
};
|
2543
|
-
const DEFAULT_SETTINGS = {
|
2544
|
-
bulkable: false,
|
2545
|
-
filterable: false,
|
2546
|
-
searchable: false,
|
2547
|
-
pagination: false,
|
2548
|
-
defaultSortBy: "",
|
2549
|
-
defaultSortOrder: "asc",
|
2550
|
-
mainField: "id",
|
2551
|
-
pageSize: 10
|
2552
|
-
};
|
2553
|
-
const useDocumentLayout = (model) => {
|
2554
|
-
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2555
|
-
const [{ query }] = useQueryParams();
|
2556
|
-
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2557
|
-
const { toggleNotification } = useNotification();
|
2558
|
-
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
2559
|
-
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2560
|
-
const {
|
2561
|
-
data,
|
2562
|
-
isLoading: isLoadingConfigs,
|
2563
|
-
error,
|
2564
|
-
isFetching: isFetchingConfigs
|
2565
|
-
} = useGetContentTypeConfigurationQuery(model);
|
2566
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2567
|
-
React.useEffect(() => {
|
2568
|
-
if (error) {
|
2569
|
-
toggleNotification({
|
2570
|
-
type: "danger",
|
2571
|
-
message: formatAPIError(error)
|
2572
|
-
});
|
2573
|
-
}
|
2574
|
-
}, [error, formatAPIError, toggleNotification]);
|
2575
|
-
const editLayout = React.useMemo(
|
2576
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2577
|
-
layout: [],
|
2578
|
-
components: {},
|
2579
|
-
metadatas: {},
|
2580
|
-
options: {},
|
2581
|
-
settings: DEFAULT_SETTINGS
|
2582
|
-
},
|
2583
|
-
[data, isLoading, schemas, schema, components]
|
2584
|
-
);
|
2585
|
-
const listLayout = React.useMemo(() => {
|
2586
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2587
|
-
layout: [],
|
2588
|
-
metadatas: {},
|
2589
|
-
options: {},
|
2590
|
-
settings: DEFAULT_SETTINGS
|
2591
|
-
};
|
2592
|
-
}, [data, isLoading, schemas, schema, components]);
|
2593
|
-
const { layout: edit } = React.useMemo(
|
2594
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2595
|
-
layout: editLayout,
|
2596
|
-
query
|
2597
|
-
}),
|
2598
|
-
[editLayout, query, runHookWaterfall]
|
2599
|
-
);
|
2600
|
-
return {
|
2601
|
-
error,
|
2602
|
-
isLoading,
|
2603
|
-
edit,
|
2604
|
-
list: listLayout
|
2605
|
-
};
|
2606
|
-
};
|
2607
|
-
const useDocLayout = () => {
|
2608
|
-
const { model } = useDoc();
|
2609
|
-
return useDocumentLayout(model);
|
2610
|
-
};
|
2611
|
-
const formatEditLayout = (data, {
|
2612
|
-
schemas,
|
2613
|
-
schema,
|
2614
|
-
components
|
2615
|
-
}) => {
|
2616
|
-
let currentPanelIndex = 0;
|
2617
|
-
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2618
|
-
data.contentType.layouts.edit,
|
2619
|
-
schema?.attributes,
|
2620
|
-
data.contentType.metadatas,
|
2621
|
-
{ configurations: data.components, schemas: components },
|
2622
|
-
schemas
|
2623
|
-
).reduce((panels, row) => {
|
2624
|
-
if (row.some((field) => field.type === "dynamiczone")) {
|
2625
|
-
panels.push([row]);
|
2626
|
-
currentPanelIndex += 2;
|
2627
|
-
} else {
|
2628
|
-
if (!panels[currentPanelIndex]) {
|
2629
|
-
panels.push([]);
|
2630
|
-
}
|
2631
|
-
panels[currentPanelIndex].push(row);
|
2632
|
-
}
|
2633
|
-
return panels;
|
2634
|
-
}, []);
|
2635
|
-
const componentEditAttributes = Object.entries(data.components).reduce(
|
2636
|
-
(acc, [uid, configuration]) => {
|
2637
|
-
acc[uid] = {
|
2638
|
-
layout: convertEditLayoutToFieldLayouts(
|
2639
|
-
configuration.layouts.edit,
|
2640
|
-
components[uid].attributes,
|
2641
|
-
configuration.metadatas
|
2642
|
-
),
|
2643
|
-
settings: {
|
2644
|
-
...configuration.settings,
|
2645
|
-
icon: components[uid].info.icon,
|
2646
|
-
displayName: components[uid].info.displayName
|
2889
|
+
collectionType,
|
2890
|
+
params: {
|
2891
|
+
locale: "*"
|
2892
|
+
}
|
2893
|
+
});
|
2894
|
+
if (!("error" in res)) {
|
2895
|
+
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
2896
|
+
}
|
2897
|
+
} finally {
|
2898
|
+
if (!listViewPathMatch) {
|
2899
|
+
setSubmitting(false);
|
2900
|
+
}
|
2647
2901
|
}
|
2648
|
-
}
|
2649
|
-
return acc;
|
2650
|
-
},
|
2651
|
-
{}
|
2652
|
-
);
|
2653
|
-
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2654
|
-
(acc, [attribute, metadata]) => {
|
2655
|
-
return {
|
2656
|
-
...acc,
|
2657
|
-
[attribute]: metadata.edit
|
2658
|
-
};
|
2659
|
-
},
|
2660
|
-
{}
|
2661
|
-
);
|
2662
|
-
return {
|
2663
|
-
layout: panelledEditAttributes,
|
2664
|
-
components: componentEditAttributes,
|
2665
|
-
metadatas: editMetadatas,
|
2666
|
-
settings: {
|
2667
|
-
...data.contentType.settings,
|
2668
|
-
displayName: schema?.info.displayName
|
2902
|
+
}
|
2669
2903
|
},
|
2670
|
-
|
2671
|
-
|
2672
|
-
...schema?.pluginOptions,
|
2673
|
-
...data.contentType.options
|
2674
|
-
}
|
2904
|
+
variant: "danger",
|
2905
|
+
position: ["header", "table-row"]
|
2675
2906
|
};
|
2676
2907
|
};
|
2677
|
-
|
2678
|
-
|
2679
|
-
|
2680
|
-
|
2681
|
-
|
2682
|
-
|
2683
|
-
}
|
2684
|
-
|
2685
|
-
|
2686
|
-
|
2687
|
-
|
2688
|
-
|
2689
|
-
|
2690
|
-
|
2691
|
-
|
2692
|
-
|
2693
|
-
|
2694
|
-
|
2695
|
-
|
2696
|
-
|
2697
|
-
|
2698
|
-
|
2699
|
-
|
2700
|
-
|
2701
|
-
|
2702
|
-
|
2703
|
-
}
|
2704
|
-
}
|
2705
|
-
);
|
2908
|
+
DeleteAction$1.type = "delete";
|
2909
|
+
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2910
|
+
const Panels = () => {
|
2911
|
+
const isCloning = useMatch(CLONE_PATH) !== null;
|
2912
|
+
const [
|
2913
|
+
{
|
2914
|
+
query: { status }
|
2915
|
+
}
|
2916
|
+
] = useQueryParams({
|
2917
|
+
status: "draft"
|
2918
|
+
});
|
2919
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
2920
|
+
const plugins = useStrapiApp("Panels", (state) => state.plugins);
|
2921
|
+
const props = {
|
2922
|
+
activeTab: status,
|
2923
|
+
model,
|
2924
|
+
documentId: id,
|
2925
|
+
document: isCloning ? void 0 : document,
|
2926
|
+
meta: isCloning ? void 0 : meta,
|
2927
|
+
collectionType
|
2928
|
+
};
|
2929
|
+
return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsx(
|
2930
|
+
DescriptionComponentRenderer,
|
2931
|
+
{
|
2932
|
+
props,
|
2933
|
+
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2934
|
+
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsx(Panel, { ...description, children: content }, id2))
|
2935
|
+
}
|
2936
|
+
) });
|
2706
2937
|
};
|
2707
|
-
const
|
2708
|
-
|
2709
|
-
schema,
|
2710
|
-
components
|
2711
|
-
}) => {
|
2712
|
-
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2713
|
-
(acc, [attribute, metadata]) => {
|
2714
|
-
return {
|
2715
|
-
...acc,
|
2716
|
-
[attribute]: metadata.list
|
2717
|
-
};
|
2718
|
-
},
|
2719
|
-
{}
|
2720
|
-
);
|
2721
|
-
const listAttributes = convertListLayoutToFieldLayouts(
|
2722
|
-
data.contentType.layouts.list,
|
2723
|
-
schema?.attributes,
|
2724
|
-
listMetadatas,
|
2725
|
-
{ configurations: data.components, schemas: components },
|
2726
|
-
schemas
|
2727
|
-
);
|
2938
|
+
const ActionsPanel = () => {
|
2939
|
+
const { formatMessage } = useIntl();
|
2728
2940
|
return {
|
2729
|
-
|
2730
|
-
|
2731
|
-
|
2732
|
-
|
2733
|
-
|
2734
|
-
...schema?.pluginOptions,
|
2735
|
-
...data.contentType.options
|
2736
|
-
}
|
2941
|
+
title: formatMessage({
|
2942
|
+
id: "content-manager.containers.edit.panels.default.title",
|
2943
|
+
defaultMessage: "Entry"
|
2944
|
+
}),
|
2945
|
+
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2737
2946
|
};
|
2738
2947
|
};
|
2739
|
-
|
2740
|
-
|
2741
|
-
|
2742
|
-
|
2743
|
-
|
2948
|
+
ActionsPanel.type = "actions";
|
2949
|
+
const ActionsPanelContent = () => {
|
2950
|
+
const isCloning = useMatch(CLONE_PATH) !== null;
|
2951
|
+
const [
|
2952
|
+
{
|
2953
|
+
query: { status = "draft" }
|
2744
2954
|
}
|
2745
|
-
|
2746
|
-
|
2747
|
-
|
2748
|
-
|
2749
|
-
|
2750
|
-
|
2751
|
-
|
2752
|
-
|
2753
|
-
|
2754
|
-
|
2755
|
-
|
2756
|
-
|
2757
|
-
|
2758
|
-
|
2955
|
+
] = useQueryParams();
|
2956
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
2957
|
+
const plugins = useStrapiApp("ActionsPanel", (state) => state.plugins);
|
2958
|
+
const props = {
|
2959
|
+
activeTab: status,
|
2960
|
+
model,
|
2961
|
+
documentId: id,
|
2962
|
+
document: isCloning ? void 0 : document,
|
2963
|
+
meta: isCloning ? void 0 : meta,
|
2964
|
+
collectionType
|
2965
|
+
};
|
2966
|
+
return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
|
2967
|
+
/* @__PURE__ */ jsx(
|
2968
|
+
DescriptionComponentRenderer,
|
2969
|
+
{
|
2970
|
+
props,
|
2971
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2972
|
+
children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
|
2973
|
+
}
|
2974
|
+
),
|
2975
|
+
/* @__PURE__ */ jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
2976
|
+
] });
|
2759
2977
|
};
|
2978
|
+
const Panel = React.forwardRef(({ children, title }, ref) => {
|
2979
|
+
return /* @__PURE__ */ jsxs(
|
2980
|
+
Flex,
|
2981
|
+
{
|
2982
|
+
ref,
|
2983
|
+
tag: "aside",
|
2984
|
+
"aria-labelledby": "additional-information",
|
2985
|
+
background: "neutral0",
|
2986
|
+
borderColor: "neutral150",
|
2987
|
+
hasRadius: true,
|
2988
|
+
paddingBottom: 4,
|
2989
|
+
paddingLeft: 4,
|
2990
|
+
paddingRight: 4,
|
2991
|
+
paddingTop: 4,
|
2992
|
+
shadow: "tableShadow",
|
2993
|
+
gap: 3,
|
2994
|
+
direction: "column",
|
2995
|
+
justifyContent: "stretch",
|
2996
|
+
alignItems: "flex-start",
|
2997
|
+
children: [
|
2998
|
+
/* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2999
|
+
children
|
3000
|
+
]
|
3001
|
+
}
|
3002
|
+
);
|
3003
|
+
});
|
2760
3004
|
const ConfirmBulkActionDialog = ({
|
2761
3005
|
onToggleDialog,
|
2762
3006
|
isOpen = false,
|
@@ -2764,7 +3008,7 @@ const ConfirmBulkActionDialog = ({
|
|
2764
3008
|
endAction
|
2765
3009
|
}) => {
|
2766
3010
|
const { formatMessage } = useIntl();
|
2767
|
-
return /* @__PURE__ */ jsx(Dialog.Root, {
|
3011
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
2768
3012
|
/* @__PURE__ */ jsx(Dialog.Header, { children: formatMessage({
|
2769
3013
|
id: "app.components.ConfirmDialog.title",
|
2770
3014
|
defaultMessage: "Confirmation"
|
@@ -2795,6 +3039,7 @@ const ConfirmDialogPublishAll = ({
|
|
2795
3039
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(getTranslation);
|
2796
3040
|
const { model, schema } = useDoc();
|
2797
3041
|
const [{ query }] = useQueryParams();
|
3042
|
+
const enableDraftRelationsCount = false;
|
2798
3043
|
const {
|
2799
3044
|
data: countDraftRelations = 0,
|
2800
3045
|
isLoading,
|
@@ -2806,7 +3051,7 @@ const ConfirmDialogPublishAll = ({
|
|
2806
3051
|
locale: query?.plugins?.i18n?.locale
|
2807
3052
|
},
|
2808
3053
|
{
|
2809
|
-
skip:
|
3054
|
+
skip: !enableDraftRelationsCount
|
2810
3055
|
}
|
2811
3056
|
);
|
2812
3057
|
React.useEffect(() => {
|
@@ -2885,7 +3130,14 @@ const formatErrorMessages = (errors, parentKey, formatMessage) => {
|
|
2885
3130
|
)
|
2886
3131
|
);
|
2887
3132
|
} else {
|
2888
|
-
messages.push(
|
3133
|
+
messages.push(
|
3134
|
+
...formatErrorMessages(
|
3135
|
+
// @ts-expect-error TODO: check why value is not compatible with FormErrors
|
3136
|
+
value,
|
3137
|
+
currentKey,
|
3138
|
+
formatMessage
|
3139
|
+
)
|
3140
|
+
);
|
2889
3141
|
}
|
2890
3142
|
} else {
|
2891
3143
|
messages.push(
|
@@ -2984,7 +3236,7 @@ const SelectedEntriesTableContent = ({
|
|
2984
3236
|
status: row.status
|
2985
3237
|
}
|
2986
3238
|
) }),
|
2987
|
-
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(
|
3239
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
|
2988
3240
|
IconButton,
|
2989
3241
|
{
|
2990
3242
|
tag: Link,
|
@@ -3007,9 +3259,10 @@ const SelectedEntriesTableContent = ({
|
|
3007
3259
|
),
|
3008
3260
|
target: "_blank",
|
3009
3261
|
marginLeft: "auto",
|
3010
|
-
|
3262
|
+
variant: "ghost",
|
3263
|
+
children: /* @__PURE__ */ jsx(Pencil, { width: "1.6rem", height: "1.6rem" })
|
3011
3264
|
}
|
3012
|
-
) })
|
3265
|
+
) }) })
|
3013
3266
|
] }, row.id)) })
|
3014
3267
|
] });
|
3015
3268
|
};
|
@@ -3046,7 +3299,13 @@ const SelectedEntriesModalContent = ({
|
|
3046
3299
|
);
|
3047
3300
|
const { rows, validationErrors } = React.useMemo(() => {
|
3048
3301
|
if (data.length > 0 && schema) {
|
3049
|
-
const validate = createYupSchema(
|
3302
|
+
const validate = createYupSchema(
|
3303
|
+
schema.attributes,
|
3304
|
+
components,
|
3305
|
+
// Since this is the "Publish" action, the validation
|
3306
|
+
// schema must enforce the rules for published entities
|
3307
|
+
{ status: "published" }
|
3308
|
+
);
|
3050
3309
|
const validationErrors2 = {};
|
3051
3310
|
const rows2 = data.map((entry) => {
|
3052
3311
|
try {
|
@@ -3396,7 +3655,7 @@ const TableActions = ({ document }) => {
|
|
3396
3655
|
DescriptionComponentRenderer,
|
3397
3656
|
{
|
3398
3657
|
props,
|
3399
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3658
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
3400
3659
|
children: (actions2) => {
|
3401
3660
|
const tableRowActions = actions2.filter((action) => {
|
3402
3661
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3507,7 +3766,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3507
3766
|
}),
|
3508
3767
|
content: /* @__PURE__ */ jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
3509
3768
|
footer: ({ onClose }) => {
|
3510
|
-
return /* @__PURE__ */ jsxs(
|
3769
|
+
return /* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
3511
3770
|
/* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
3512
3771
|
id: "cancel",
|
3513
3772
|
defaultMessage: "Cancel"
|
@@ -3548,8 +3807,7 @@ class ContentManagerPlugin {
|
|
3548
3807
|
documentActions = [
|
3549
3808
|
...DEFAULT_ACTIONS,
|
3550
3809
|
...DEFAULT_TABLE_ROW_ACTIONS,
|
3551
|
-
...DEFAULT_HEADER_ACTIONS
|
3552
|
-
HistoryAction
|
3810
|
+
...DEFAULT_HEADER_ACTIONS
|
3553
3811
|
];
|
3554
3812
|
editViewSidePanels = [ActionsPanel];
|
3555
3813
|
headerActions = [];
|
@@ -3638,6 +3896,52 @@ const getPrintableType = (value) => {
|
|
3638
3896
|
}
|
3639
3897
|
return nativeType;
|
3640
3898
|
};
|
3899
|
+
const HistoryAction = ({ model, document }) => {
|
3900
|
+
const { formatMessage } = useIntl();
|
3901
|
+
const [{ query }] = useQueryParams();
|
3902
|
+
const navigate = useNavigate();
|
3903
|
+
const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
|
3904
|
+
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3905
|
+
return null;
|
3906
|
+
}
|
3907
|
+
return {
|
3908
|
+
icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
|
3909
|
+
label: formatMessage({
|
3910
|
+
id: "content-manager.history.document-action",
|
3911
|
+
defaultMessage: "Content History"
|
3912
|
+
}),
|
3913
|
+
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
3914
|
+
disabled: (
|
3915
|
+
/**
|
3916
|
+
* The user is creating a new document.
|
3917
|
+
* It hasn't been saved yet, so there's no history to go to
|
3918
|
+
*/
|
3919
|
+
!document || /**
|
3920
|
+
* The document has been created but the current dimension has never been saved.
|
3921
|
+
* For example, the user is creating a new locale in an existing document,
|
3922
|
+
* so there's no history for the document in that locale
|
3923
|
+
*/
|
3924
|
+
!document.id || /**
|
3925
|
+
* History is only available for content types created by the user.
|
3926
|
+
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
3927
|
+
* which start with `admin::` or `plugin::`
|
3928
|
+
*/
|
3929
|
+
!model.startsWith("api::")
|
3930
|
+
),
|
3931
|
+
position: "header"
|
3932
|
+
};
|
3933
|
+
};
|
3934
|
+
HistoryAction.type = "history";
|
3935
|
+
const historyAdmin = {
|
3936
|
+
bootstrap(app) {
|
3937
|
+
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
3938
|
+
addDocumentAction((actions2) => {
|
3939
|
+
const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
|
3940
|
+
actions2.splice(indexOfDeleteAction, 0, HistoryAction);
|
3941
|
+
return actions2;
|
3942
|
+
});
|
3943
|
+
}
|
3944
|
+
};
|
3641
3945
|
const initialState = {
|
3642
3946
|
collectionTypeLinks: [],
|
3643
3947
|
components: [],
|
@@ -3688,15 +3992,29 @@ const index = {
|
|
3688
3992
|
defaultMessage: "Content Manager"
|
3689
3993
|
},
|
3690
3994
|
permissions: [],
|
3691
|
-
Component: () => import("./layout-DC503LnF.mjs").then((mod) => ({ default: mod.Layout })),
|
3692
3995
|
position: 1
|
3693
3996
|
});
|
3997
|
+
app.router.addRoute({
|
3998
|
+
path: "content-manager/*",
|
3999
|
+
lazy: async () => {
|
4000
|
+
const { Layout } = await import("./layout-DaUjDiWQ.mjs");
|
4001
|
+
return {
|
4002
|
+
Component: Layout
|
4003
|
+
};
|
4004
|
+
},
|
4005
|
+
children: routes
|
4006
|
+
});
|
3694
4007
|
app.registerPlugin(cm.config);
|
3695
4008
|
},
|
4009
|
+
bootstrap(app) {
|
4010
|
+
if (typeof historyAdmin.bootstrap === "function") {
|
4011
|
+
historyAdmin.bootstrap(app);
|
4012
|
+
}
|
4013
|
+
},
|
3696
4014
|
async registerTrads({ locales }) {
|
3697
4015
|
const importedTrads = await Promise.all(
|
3698
4016
|
locales.map((locale) => {
|
3699
|
-
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-
|
4017
|
+
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 }) => {
|
3700
4018
|
return {
|
3701
4019
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3702
4020
|
locale
|
@@ -3724,7 +4042,8 @@ export {
|
|
3724
4042
|
InjectionZone as I,
|
3725
4043
|
useDocument as J,
|
3726
4044
|
index as K,
|
3727
|
-
|
4045
|
+
useContentManagerContext as L,
|
4046
|
+
useDocumentActions as M,
|
3728
4047
|
Panels as P,
|
3729
4048
|
RelativeTime as R,
|
3730
4049
|
SINGLE_TYPES as S,
|
@@ -3742,11 +4061,11 @@ export {
|
|
3742
4061
|
PERMISSIONS as k,
|
3743
4062
|
DocumentRBAC as l,
|
3744
4063
|
DOCUMENT_META_FIELDS as m,
|
3745
|
-
|
3746
|
-
|
3747
|
-
|
3748
|
-
|
3749
|
-
|
4064
|
+
CLONE_PATH as n,
|
4065
|
+
useDocLayout as o,
|
4066
|
+
useGetContentTypeConfigurationQuery as p,
|
4067
|
+
CREATOR_FIELDS as q,
|
4068
|
+
getMainField as r,
|
3750
4069
|
setInitialData as s,
|
3751
4070
|
getDisplayName as t,
|
3752
4071
|
useContentTypeSchema as u,
|
@@ -3756,4 +4075,4 @@ export {
|
|
3756
4075
|
capitalise as y,
|
3757
4076
|
useUpdateContentTypeConfigurationMutation as z
|
3758
4077
|
};
|
3759
|
-
//# sourceMappingURL=index-
|
4078
|
+
//# sourceMappingURL=index-C9HxCo5R.mjs.map
|