@strapi/content-manager 0.0.0-experimental.745741d19e90275ca6f7c928ca19f9bb0fd9d933 → 0.0.0-experimental.78b47df46708173ab4833373f694257729db4b9e
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/dist/_chunks/{ComponentConfigurationPage-DHNM3YBz.mjs → ComponentConfigurationPage-7-qB29e7.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-DHNM3YBz.mjs.map → ComponentConfigurationPage-7-qB29e7.mjs.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-BvHtG7uH.js → ComponentConfigurationPage-DP7AC0UU.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-BvHtG7uH.js.map → ComponentConfigurationPage-DP7AC0UU.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-Cp6HAEzN.mjs → EditConfigurationPage-CI4XoymK.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-Cp6HAEzN.mjs.map → EditConfigurationPage-CI4XoymK.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-DOmfCEMo.js → EditConfigurationPage-DITVliEI.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-DOmfCEMo.js.map → EditConfigurationPage-DITVliEI.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-BqNpC6hO.js → EditViewPage-CUS2EAhB.js} +24 -9
- package/dist/_chunks/EditViewPage-CUS2EAhB.js.map +1 -0
- package/dist/_chunks/{EditViewPage-BtkEx339.mjs → EditViewPage-Dzpno8xI.mjs} +24 -9
- package/dist/_chunks/EditViewPage-Dzpno8xI.mjs.map +1 -0
- package/dist/_chunks/{Field-R5NbffTB.mjs → Field-B_jG_EV9.mjs} +210 -145
- package/dist/_chunks/Field-B_jG_EV9.mjs.map +1 -0
- package/dist/_chunks/{Field-lsPFnAmH.js → Field-CtUU1Fg8.js} +212 -147
- package/dist/_chunks/Field-CtUU1Fg8.js.map +1 -0
- package/dist/_chunks/{Form-BHmXSfyy.mjs → Form-BXHao2mZ.mjs} +35 -16
- package/dist/_chunks/Form-BXHao2mZ.mjs.map +1 -0
- package/dist/_chunks/{Form-CcGboku8.js → Form-DTqO0ymI.js} +35 -16
- package/dist/_chunks/Form-DTqO0ymI.js.map +1 -0
- package/dist/_chunks/{History-ByUPL3T3.mjs → History-2Ah2CQ4T.mjs} +28 -18
- package/dist/_chunks/History-2Ah2CQ4T.mjs.map +1 -0
- package/dist/_chunks/{History-Bsud8jwh.js → History-C_uSGzO5.js} +28 -18
- package/dist/_chunks/History-C_uSGzO5.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-Bm5HACXf.mjs → ListConfigurationPage-BjSJlaoC.mjs} +20 -8
- package/dist/_chunks/ListConfigurationPage-BjSJlaoC.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DiT463qx.js → ListConfigurationPage-nyuP7OSy.js} +20 -8
- package/dist/_chunks/ListConfigurationPage-nyuP7OSy.js.map +1 -0
- package/dist/_chunks/{ListViewPage-JSyNAAYu.mjs → ListViewPage-B75x3nz2.mjs} +47 -38
- package/dist/_chunks/ListViewPage-B75x3nz2.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-CsrC9L_d.js → ListViewPage-DHgHD8Xg.js} +49 -40
- package/dist/_chunks/ListViewPage-DHgHD8Xg.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-Bsvng4II.js → NoContentTypePage-CDUKdZ7d.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-Bsvng4II.js.map → NoContentTypePage-CDUKdZ7d.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-CsrQUpBE.mjs → NoContentTypePage-DUacQSyF.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-CsrQUpBE.mjs.map → NoContentTypePage-DUacQSyF.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-DNmf_pj0.mjs → NoPermissionsPage-SFllMekk.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-DNmf_pj0.mjs.map → NoPermissionsPage-SFllMekk.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-CdHNJtEf.js → NoPermissionsPage-zwIZydDI.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-CdHNJtEf.js.map → NoPermissionsPage-zwIZydDI.js.map} +1 -1
- package/dist/_chunks/{Relations-u8-37jK0.mjs → Relations-D2NRW8fC.mjs} +14 -10
- package/dist/_chunks/Relations-D2NRW8fC.mjs.map +1 -0
- package/dist/_chunks/{Relations-CghaPv2D.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-CaE6NG4a.mjs → index-C9HxCo5R.mjs} +971 -686
- package/dist/_chunks/index-C9HxCo5R.mjs.map +1 -0
- package/dist/_chunks/{index-BOZx6IMg.js → index-ovJRE1FM.js} +952 -667
- package/dist/_chunks/index-ovJRE1FM.js.map +1 -0
- package/dist/_chunks/{layout-Bx7svTbY.mjs → layout-DaUjDiWQ.mjs} +23 -10
- package/dist/_chunks/layout-DaUjDiWQ.mjs.map +1 -0
- package/dist/_chunks/{layout-Ciz224q5.js → layout-UNWstw_s.js} +22 -9
- package/dist/_chunks/layout-UNWstw_s.js.map +1 -0
- package/dist/_chunks/{relations-Cxc1cEv3.mjs → relations-D8iFAeRu.mjs} +2 -2
- package/dist/_chunks/{relations-Cxc1cEv3.mjs.map → relations-D8iFAeRu.mjs.map} +1 -1
- package/dist/_chunks/{relations-CP8sB2YZ.js → relations-NN3coOG5.js} +2 -2
- package/dist/_chunks/{relations-CP8sB2YZ.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 +5 -4
- package/dist/admin/src/exports.d.ts +1 -1
- package/dist/admin/src/history/index.d.ts +3 -0
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +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/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 +184 -108
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +185 -109
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/controllers/relations.d.ts.map +1 -1
- package/dist/server/src/controllers/uid.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/dimensions.d.ts +4 -2
- package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -1
- package/dist/server/src/history/services/history.d.ts.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
- package/dist/server/src/history/services/utils.d.ts +2 -1
- package/dist/server/src/history/services/utils.d.ts.map +1 -1
- package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/permission-checker.d.ts.map +1 -1
- package/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/dist/shared/contracts/collection-types.d.ts +3 -1
- package/dist/shared/contracts/collection-types.d.ts.map +1 -1
- package/package.json +11 -11
- package/dist/_chunks/EditViewPage-BqNpC6hO.js.map +0 -1
- package/dist/_chunks/EditViewPage-BtkEx339.mjs.map +0 -1
- package/dist/_chunks/Field-R5NbffTB.mjs.map +0 -1
- package/dist/_chunks/Field-lsPFnAmH.js.map +0 -1
- package/dist/_chunks/Form-BHmXSfyy.mjs.map +0 -1
- package/dist/_chunks/Form-CcGboku8.js.map +0 -1
- package/dist/_chunks/History-Bsud8jwh.js.map +0 -1
- package/dist/_chunks/History-ByUPL3T3.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-Bm5HACXf.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DiT463qx.js.map +0 -1
- package/dist/_chunks/ListViewPage-CsrC9L_d.js.map +0 -1
- package/dist/_chunks/ListViewPage-JSyNAAYu.mjs.map +0 -1
- package/dist/_chunks/Relations-CghaPv2D.js.map +0 -1
- package/dist/_chunks/Relations-u8-37jK0.mjs.map +0 -1
- package/dist/_chunks/index-BOZx6IMg.js.map +0 -1
- package/dist/_chunks/index-CaE6NG4a.mjs.map +0 -1
- package/dist/_chunks/layout-Bx7svTbY.mjs.map +0 -1
- package/dist/_chunks/layout-Ciz224q5.js.map +0 -1
- package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
- package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
- package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
- package/strapi-server.js +0 -3
@@ -1,17 +1,17 @@
|
|
1
|
-
import {
|
1
|
+
import { More, Cross, WarningCircle, ListPlus, Pencil, Trash, Check, CrossCircle, CheckCircle, ArrowsCounterClockwise, ChevronRight, Duplicate, ClockCounterClockwise, Feather } from "@strapi/icons";
|
2
2
|
import { jsx, Fragment, jsxs } from "react/jsx-runtime";
|
3
|
-
import { useStrapiApp,
|
4
|
-
import { stringify } from "qs";
|
5
|
-
import { useIntl } from "react-intl";
|
6
|
-
import { useNavigate, useParams, Navigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
|
3
|
+
import { useStrapiApp, createContext, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, useQueryParams, getYupValidationErrors, useForm, useTracking, useGuidedTour, BackButton, DescriptionComponentRenderer, useTable, Table } from "@strapi/admin/strapi-admin";
|
7
4
|
import * as React from "react";
|
8
5
|
import { lazy } from "react";
|
9
|
-
import { Button, Menu, VisuallyHidden, Flex,
|
10
|
-
import {
|
6
|
+
import { Button, Menu, VisuallyHidden, Flex, Typography, Dialog, Modal, Radio, Status, Box, SingleSelect, SingleSelectOption, IconButton, Loader, Tooltip, LinkButton } from "@strapi/design-system";
|
7
|
+
import { useIntl } from "react-intl";
|
8
|
+
import { useParams, useNavigate, Navigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
|
11
9
|
import * as yup from "yup";
|
12
10
|
import { ValidationError } from "yup";
|
13
11
|
import pipe from "lodash/fp/pipe";
|
14
12
|
import { intervalToDuration, isPast } from "date-fns";
|
13
|
+
import { styled } from "styled-components";
|
14
|
+
import { stringify } from "qs";
|
15
15
|
import { createSlice, combineReducers } from "@reduxjs/toolkit";
|
16
16
|
const __variableDynamicImportRuntimeHelper = (glob, path) => {
|
17
17
|
const v = glob[path];
|
@@ -49,42 +49,6 @@ const useInjectionZone = (area) => {
|
|
49
49
|
const [page, position] = area.split(".");
|
50
50
|
return contentManagerPlugin.getInjectedComponents(page, position);
|
51
51
|
};
|
52
|
-
const HistoryAction = ({ model, document }) => {
|
53
|
-
const { formatMessage } = useIntl();
|
54
|
-
const [{ query }] = useQueryParams();
|
55
|
-
const navigate = useNavigate();
|
56
|
-
const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
|
57
|
-
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
58
|
-
return null;
|
59
|
-
}
|
60
|
-
return {
|
61
|
-
icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
|
62
|
-
label: formatMessage({
|
63
|
-
id: "content-manager.history.document-action",
|
64
|
-
defaultMessage: "Content History"
|
65
|
-
}),
|
66
|
-
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
67
|
-
disabled: (
|
68
|
-
/**
|
69
|
-
* The user is creating a new document.
|
70
|
-
* It hasn't been saved yet, so there's no history to go to
|
71
|
-
*/
|
72
|
-
!document || /**
|
73
|
-
* The document has been created but the current dimension has never been saved.
|
74
|
-
* For example, the user is creating a new locale in an existing document,
|
75
|
-
* so there's no history for the document in that locale
|
76
|
-
*/
|
77
|
-
!document.id || /**
|
78
|
-
* History is only available for content types created by the user.
|
79
|
-
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
80
|
-
* which start with `admin::` or `plugin::`
|
81
|
-
*/
|
82
|
-
!model.startsWith("api::")
|
83
|
-
),
|
84
|
-
position: "header"
|
85
|
-
};
|
86
|
-
};
|
87
|
-
HistoryAction.type = "history";
|
88
52
|
const ID = "id";
|
89
53
|
const CREATED_BY_ATTRIBUTE_NAME = "createdBy";
|
90
54
|
const UPDATED_BY_ATTRIBUTE_NAME = "updatedBy";
|
@@ -194,7 +158,8 @@ const contentManagerApi = adminApi.enhanceEndpoints({
|
|
194
158
|
"Document",
|
195
159
|
"InitialData",
|
196
160
|
"HistoryVersion",
|
197
|
-
"Relations"
|
161
|
+
"Relations",
|
162
|
+
"UidAvailability"
|
198
163
|
]
|
199
164
|
});
|
200
165
|
const documentApi = contentManagerApi.injectEndpoints({
|
@@ -208,7 +173,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
208
173
|
params: query
|
209
174
|
}
|
210
175
|
}),
|
211
|
-
invalidatesTags: (_result,
|
176
|
+
invalidatesTags: (_result, error, { model }) => {
|
177
|
+
if (error) {
|
178
|
+
return [];
|
179
|
+
}
|
180
|
+
return [{ type: "Document", id: `${model}_LIST` }];
|
181
|
+
}
|
212
182
|
}),
|
213
183
|
cloneDocument: builder.mutation({
|
214
184
|
query: ({ model, sourceId, data, params }) => ({
|
@@ -219,7 +189,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
219
189
|
params
|
220
190
|
}
|
221
191
|
}),
|
222
|
-
invalidatesTags: (_result, _error, { model }) => [
|
192
|
+
invalidatesTags: (_result, _error, { model }) => [
|
193
|
+
{ type: "Document", id: `${model}_LIST` },
|
194
|
+
{ type: "UidAvailability", id: model }
|
195
|
+
]
|
223
196
|
}),
|
224
197
|
/**
|
225
198
|
* Creates a new collection-type document. This should ONLY be used for collection-types.
|
@@ -236,7 +209,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
236
209
|
}),
|
237
210
|
invalidatesTags: (result, _error, { model }) => [
|
238
211
|
{ type: "Document", id: `${model}_LIST` },
|
239
|
-
"Relations"
|
212
|
+
"Relations",
|
213
|
+
{ type: "UidAvailability", id: model }
|
240
214
|
]
|
241
215
|
}),
|
242
216
|
deleteDocument: builder.mutation({
|
@@ -277,7 +251,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
277
251
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
278
252
|
},
|
279
253
|
{ type: "Document", id: `${model}_LIST` },
|
280
|
-
"Relations"
|
254
|
+
"Relations",
|
255
|
+
{ type: "UidAvailability", id: model }
|
281
256
|
];
|
282
257
|
}
|
283
258
|
}),
|
@@ -295,6 +270,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
295
270
|
}),
|
296
271
|
providesTags: (result, _error, arg) => {
|
297
272
|
return [
|
273
|
+
{ type: "Document", id: `ALL_LIST` },
|
298
274
|
{ type: "Document", id: `${arg.model}_LIST` },
|
299
275
|
...result?.results.map(({ documentId }) => ({
|
300
276
|
type: "Document",
|
@@ -333,6 +309,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
333
309
|
{
|
334
310
|
type: "Document",
|
335
311
|
id: collectionType !== SINGLE_TYPES ? `${model}_${result && "documentId" in result ? result.documentId : documentId}` : model
|
312
|
+
},
|
313
|
+
// Make it easy to invalidate all individual documents queries for a model
|
314
|
+
{
|
315
|
+
type: "Document",
|
316
|
+
id: `${model}_ALL_ITEMS`
|
336
317
|
}
|
337
318
|
];
|
338
319
|
}
|
@@ -396,8 +377,21 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
396
377
|
type: "Document",
|
397
378
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
398
379
|
},
|
399
|
-
"Relations"
|
380
|
+
"Relations",
|
381
|
+
{ type: "UidAvailability", id: model }
|
400
382
|
];
|
383
|
+
},
|
384
|
+
async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
|
385
|
+
const patchResult = dispatch(
|
386
|
+
documentApi.util.updateQueryData("getDocument", patch, (draft) => {
|
387
|
+
Object.assign(draft.data, data);
|
388
|
+
})
|
389
|
+
);
|
390
|
+
try {
|
391
|
+
await queryFulfilled;
|
392
|
+
} catch {
|
393
|
+
patchResult.undo();
|
394
|
+
}
|
401
395
|
}
|
402
396
|
}),
|
403
397
|
unpublishDocument: builder.mutation({
|
@@ -467,7 +461,7 @@ const buildValidParams = (query) => {
|
|
467
461
|
const isBaseQueryError = (error) => {
|
468
462
|
return error.name !== void 0;
|
469
463
|
};
|
470
|
-
const createYupSchema = (attributes = {}, components = {}) => {
|
464
|
+
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
471
465
|
const createModelSchema = (attributes2) => yup.object().shape(
|
472
466
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
473
467
|
if (DOCUMENT_META_FIELDS.includes(name)) {
|
@@ -480,7 +474,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
480
474
|
addMinValidation,
|
481
475
|
addMaxValidation,
|
482
476
|
addRegexValidation
|
483
|
-
].map((fn) => fn(attribute));
|
477
|
+
].map((fn) => fn(attribute, options));
|
484
478
|
const transformSchema = pipe(...validations);
|
485
479
|
switch (attribute.type) {
|
486
480
|
case "component": {
|
@@ -529,7 +523,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
529
523
|
} else if (Array.isArray(value)) {
|
530
524
|
return yup.array().of(
|
531
525
|
yup.object().shape({
|
532
|
-
id: yup.
|
526
|
+
id: yup.number().required()
|
533
527
|
})
|
534
528
|
);
|
535
529
|
} else if (typeof value === "object") {
|
@@ -581,6 +575,14 @@ const createAttributeSchema = (attribute) => {
|
|
581
575
|
if (!value || typeof value === "string" && value.length === 0) {
|
582
576
|
return true;
|
583
577
|
}
|
578
|
+
if (typeof value === "object") {
|
579
|
+
try {
|
580
|
+
JSON.stringify(value);
|
581
|
+
return true;
|
582
|
+
} catch (err) {
|
583
|
+
return false;
|
584
|
+
}
|
585
|
+
}
|
584
586
|
try {
|
585
587
|
JSON.parse(value);
|
586
588
|
return true;
|
@@ -599,13 +601,7 @@ const createAttributeSchema = (attribute) => {
|
|
599
601
|
return yup.mixed();
|
600
602
|
}
|
601
603
|
};
|
602
|
-
const
|
603
|
-
if (attribute.required && attribute.type !== "relation") {
|
604
|
-
return schema.required({
|
605
|
-
id: translatedErrors.required.id,
|
606
|
-
defaultMessage: "This field is required."
|
607
|
-
});
|
608
|
-
}
|
604
|
+
const nullableSchema = (schema) => {
|
609
605
|
return schema?.nullable ? schema.nullable() : (
|
610
606
|
// In some cases '.nullable' will not be available on the schema.
|
611
607
|
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
@@ -613,7 +609,22 @@ const addRequiredValidation = (attribute) => (schema) => {
|
|
613
609
|
schema
|
614
610
|
);
|
615
611
|
};
|
616
|
-
const
|
612
|
+
const addRequiredValidation = (attribute, options) => (schema) => {
|
613
|
+
if (options.status === "draft") {
|
614
|
+
return nullableSchema(schema);
|
615
|
+
}
|
616
|
+
if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
|
617
|
+
return schema.min(1, translatedErrors.required);
|
618
|
+
}
|
619
|
+
if (attribute.required && attribute.type !== "relation") {
|
620
|
+
return schema.required(translatedErrors.required);
|
621
|
+
}
|
622
|
+
return nullableSchema(schema);
|
623
|
+
};
|
624
|
+
const addMinLengthValidation = (attribute, options) => (schema) => {
|
625
|
+
if (options.status === "draft") {
|
626
|
+
return schema;
|
627
|
+
}
|
617
628
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
618
629
|
return schema.min(attribute.minLength, {
|
619
630
|
...translatedErrors.minLength,
|
@@ -635,9 +646,31 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
635
646
|
}
|
636
647
|
return schema;
|
637
648
|
};
|
638
|
-
const addMinValidation = (attribute) => (schema) => {
|
649
|
+
const addMinValidation = (attribute, options) => (schema) => {
|
639
650
|
if ("min" in attribute) {
|
640
651
|
const min = toInteger(attribute.min);
|
652
|
+
if (attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") {
|
653
|
+
if (options.status !== "draft" && !attribute.required && "test" in schema && min) {
|
654
|
+
return schema.test(
|
655
|
+
"custom-min",
|
656
|
+
{
|
657
|
+
...translatedErrors.min,
|
658
|
+
values: {
|
659
|
+
min: attribute.min
|
660
|
+
}
|
661
|
+
},
|
662
|
+
(value) => {
|
663
|
+
if (!value) {
|
664
|
+
return true;
|
665
|
+
}
|
666
|
+
if (Array.isArray(value) && value.length === 0) {
|
667
|
+
return true;
|
668
|
+
}
|
669
|
+
return value.length >= min;
|
670
|
+
}
|
671
|
+
);
|
672
|
+
}
|
673
|
+
}
|
641
674
|
if ("min" in schema && min) {
|
642
675
|
return schema.min(min, {
|
643
676
|
...translatedErrors.min,
|
@@ -756,19 +789,115 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
|
|
756
789
|
}, {});
|
757
790
|
return componentsByKey;
|
758
791
|
};
|
759
|
-
const
|
792
|
+
const HOOKS = {
|
793
|
+
/**
|
794
|
+
* Hook that allows to mutate the displayed headers of the list view table
|
795
|
+
* @constant
|
796
|
+
* @type {string}
|
797
|
+
*/
|
798
|
+
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
799
|
+
/**
|
800
|
+
* Hook that allows to mutate the CM's collection types links pre-set filters
|
801
|
+
* @constant
|
802
|
+
* @type {string}
|
803
|
+
*/
|
804
|
+
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
805
|
+
/**
|
806
|
+
* Hook that allows to mutate the CM's edit view layout
|
807
|
+
* @constant
|
808
|
+
* @type {string}
|
809
|
+
*/
|
810
|
+
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
811
|
+
/**
|
812
|
+
* Hook that allows to mutate the CM's single types links pre-set filters
|
813
|
+
* @constant
|
814
|
+
* @type {string}
|
815
|
+
*/
|
816
|
+
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
817
|
+
};
|
818
|
+
const contentTypesApi = contentManagerApi.injectEndpoints({
|
819
|
+
endpoints: (builder) => ({
|
820
|
+
getContentTypeConfiguration: builder.query({
|
821
|
+
query: (uid) => ({
|
822
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
823
|
+
method: "GET"
|
824
|
+
}),
|
825
|
+
transformResponse: (response) => response.data,
|
826
|
+
providesTags: (_result, _error, uid) => [
|
827
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
828
|
+
{ type: "ContentTypeSettings", id: "LIST" }
|
829
|
+
]
|
830
|
+
}),
|
831
|
+
getAllContentTypeSettings: builder.query({
|
832
|
+
query: () => "/content-manager/content-types-settings",
|
833
|
+
transformResponse: (response) => response.data,
|
834
|
+
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
835
|
+
}),
|
836
|
+
updateContentTypeConfiguration: builder.mutation({
|
837
|
+
query: ({ uid, ...body }) => ({
|
838
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
839
|
+
method: "PUT",
|
840
|
+
data: body
|
841
|
+
}),
|
842
|
+
transformResponse: (response) => response.data,
|
843
|
+
invalidatesTags: (_result, _error, { uid }) => [
|
844
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
845
|
+
{ type: "ContentTypeSettings", id: "LIST" },
|
846
|
+
// Is this necessary?
|
847
|
+
{ type: "InitialData" }
|
848
|
+
]
|
849
|
+
})
|
850
|
+
})
|
851
|
+
});
|
852
|
+
const {
|
853
|
+
useGetContentTypeConfigurationQuery,
|
854
|
+
useGetAllContentTypeSettingsQuery,
|
855
|
+
useUpdateContentTypeConfigurationMutation
|
856
|
+
} = contentTypesApi;
|
857
|
+
const checkIfAttributeIsDisplayable = (attribute) => {
|
858
|
+
const { type } = attribute;
|
859
|
+
if (type === "relation") {
|
860
|
+
return !attribute.relation.toLowerCase().includes("morph");
|
861
|
+
}
|
862
|
+
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
863
|
+
};
|
864
|
+
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
865
|
+
if (!mainFieldName) {
|
866
|
+
return void 0;
|
867
|
+
}
|
868
|
+
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
869
|
+
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
870
|
+
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
871
|
+
);
|
872
|
+
return {
|
873
|
+
name: mainFieldName,
|
874
|
+
type: mainFieldType ?? "string"
|
875
|
+
};
|
876
|
+
};
|
877
|
+
const DEFAULT_SETTINGS = {
|
878
|
+
bulkable: false,
|
879
|
+
filterable: false,
|
880
|
+
searchable: false,
|
881
|
+
pagination: false,
|
882
|
+
defaultSortBy: "",
|
883
|
+
defaultSortOrder: "asc",
|
884
|
+
mainField: "id",
|
885
|
+
pageSize: 10
|
886
|
+
};
|
887
|
+
const useDocumentLayout = (model) => {
|
888
|
+
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
889
|
+
const [{ query }] = useQueryParams();
|
890
|
+
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
760
891
|
const { toggleNotification } = useNotification();
|
761
892
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
893
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
762
894
|
const {
|
763
|
-
|
764
|
-
isLoading:
|
765
|
-
|
766
|
-
|
767
|
-
} =
|
768
|
-
|
769
|
-
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
770
|
-
});
|
771
|
-
const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
|
895
|
+
data,
|
896
|
+
isLoading: isLoadingConfigs,
|
897
|
+
error,
|
898
|
+
isFetching: isFetchingConfigs
|
899
|
+
} = useGetContentTypeConfigurationQuery(model);
|
900
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
772
901
|
React.useEffect(() => {
|
773
902
|
if (error) {
|
774
903
|
toggleNotification({
|
@@ -776,50 +905,265 @@ const useDocument = (args, opts) => {
|
|
776
905
|
message: formatAPIError(error)
|
777
906
|
});
|
778
907
|
}
|
779
|
-
}, [
|
780
|
-
const
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
(document) => {
|
788
|
-
if (!validationSchema) {
|
789
|
-
throw new Error(
|
790
|
-
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
791
|
-
);
|
792
|
-
}
|
793
|
-
try {
|
794
|
-
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
795
|
-
return null;
|
796
|
-
} catch (error2) {
|
797
|
-
if (error2 instanceof ValidationError) {
|
798
|
-
return getYupValidationErrors(error2);
|
799
|
-
}
|
800
|
-
throw error2;
|
801
|
-
}
|
908
|
+
}, [error, formatAPIError, toggleNotification]);
|
909
|
+
const editLayout = React.useMemo(
|
910
|
+
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
911
|
+
layout: [],
|
912
|
+
components: {},
|
913
|
+
metadatas: {},
|
914
|
+
options: {},
|
915
|
+
settings: DEFAULT_SETTINGS
|
802
916
|
},
|
803
|
-
[
|
917
|
+
[data, isLoading, schemas, schema, components]
|
918
|
+
);
|
919
|
+
const listLayout = React.useMemo(() => {
|
920
|
+
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
921
|
+
layout: [],
|
922
|
+
metadatas: {},
|
923
|
+
options: {},
|
924
|
+
settings: DEFAULT_SETTINGS
|
925
|
+
};
|
926
|
+
}, [data, isLoading, schemas, schema, components]);
|
927
|
+
const { layout: edit } = React.useMemo(
|
928
|
+
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
929
|
+
layout: editLayout,
|
930
|
+
query
|
931
|
+
}),
|
932
|
+
[editLayout, query, runHookWaterfall]
|
804
933
|
);
|
805
|
-
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
806
934
|
return {
|
807
|
-
|
808
|
-
document: data?.data,
|
809
|
-
meta: data?.meta,
|
935
|
+
error,
|
810
936
|
isLoading,
|
811
|
-
|
812
|
-
|
937
|
+
edit,
|
938
|
+
list: listLayout
|
813
939
|
};
|
814
940
|
};
|
815
|
-
const
|
816
|
-
const {
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
941
|
+
const useDocLayout = () => {
|
942
|
+
const { model } = useDoc();
|
943
|
+
return useDocumentLayout(model);
|
944
|
+
};
|
945
|
+
const formatEditLayout = (data, {
|
946
|
+
schemas,
|
947
|
+
schema,
|
948
|
+
components
|
949
|
+
}) => {
|
950
|
+
let currentPanelIndex = 0;
|
951
|
+
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
952
|
+
data.contentType.layouts.edit,
|
953
|
+
schema?.attributes,
|
954
|
+
data.contentType.metadatas,
|
955
|
+
{ configurations: data.components, schemas: components },
|
956
|
+
schemas
|
957
|
+
).reduce((panels, row) => {
|
958
|
+
if (row.some((field) => field.type === "dynamiczone")) {
|
959
|
+
panels.push([row]);
|
960
|
+
currentPanelIndex += 2;
|
961
|
+
} else {
|
962
|
+
if (!panels[currentPanelIndex]) {
|
963
|
+
panels.push([]);
|
964
|
+
}
|
965
|
+
panels[currentPanelIndex].push(row);
|
966
|
+
}
|
967
|
+
return panels;
|
968
|
+
}, []);
|
969
|
+
const componentEditAttributes = Object.entries(data.components).reduce(
|
970
|
+
(acc, [uid, configuration]) => {
|
971
|
+
acc[uid] = {
|
972
|
+
layout: convertEditLayoutToFieldLayouts(
|
973
|
+
configuration.layouts.edit,
|
974
|
+
components[uid].attributes,
|
975
|
+
configuration.metadatas,
|
976
|
+
{ configurations: data.components, schemas: components }
|
977
|
+
),
|
978
|
+
settings: {
|
979
|
+
...configuration.settings,
|
980
|
+
icon: components[uid].info.icon,
|
981
|
+
displayName: components[uid].info.displayName
|
982
|
+
}
|
983
|
+
};
|
984
|
+
return acc;
|
985
|
+
},
|
986
|
+
{}
|
987
|
+
);
|
988
|
+
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
989
|
+
(acc, [attribute, metadata]) => {
|
990
|
+
return {
|
991
|
+
...acc,
|
992
|
+
[attribute]: metadata.edit
|
993
|
+
};
|
994
|
+
},
|
995
|
+
{}
|
996
|
+
);
|
997
|
+
return {
|
998
|
+
layout: panelledEditAttributes,
|
999
|
+
components: componentEditAttributes,
|
1000
|
+
metadatas: editMetadatas,
|
1001
|
+
settings: {
|
1002
|
+
...data.contentType.settings,
|
1003
|
+
displayName: schema?.info.displayName
|
1004
|
+
},
|
1005
|
+
options: {
|
1006
|
+
...schema?.options,
|
1007
|
+
...schema?.pluginOptions,
|
1008
|
+
...data.contentType.options
|
1009
|
+
}
|
1010
|
+
};
|
1011
|
+
};
|
1012
|
+
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
1013
|
+
return rows.map(
|
1014
|
+
(row) => row.map((field) => {
|
1015
|
+
const attribute = attributes[field.name];
|
1016
|
+
if (!attribute) {
|
1017
|
+
return null;
|
1018
|
+
}
|
1019
|
+
const { edit: metadata } = metadatas[field.name];
|
1020
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1021
|
+
return {
|
1022
|
+
attribute,
|
1023
|
+
disabled: !metadata.editable,
|
1024
|
+
hint: metadata.description,
|
1025
|
+
label: metadata.label ?? "",
|
1026
|
+
name: field.name,
|
1027
|
+
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
1028
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1029
|
+
schemas,
|
1030
|
+
components: components?.schemas ?? {}
|
1031
|
+
}),
|
1032
|
+
placeholder: metadata.placeholder ?? "",
|
1033
|
+
required: attribute.required ?? false,
|
1034
|
+
size: field.size,
|
1035
|
+
unique: "unique" in attribute ? attribute.unique : false,
|
1036
|
+
visible: metadata.visible ?? true,
|
1037
|
+
type: attribute.type
|
1038
|
+
};
|
1039
|
+
}).filter((field) => field !== null)
|
1040
|
+
);
|
1041
|
+
};
|
1042
|
+
const formatListLayout = (data, {
|
1043
|
+
schemas,
|
1044
|
+
schema,
|
1045
|
+
components
|
1046
|
+
}) => {
|
1047
|
+
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1048
|
+
(acc, [attribute, metadata]) => {
|
1049
|
+
return {
|
1050
|
+
...acc,
|
1051
|
+
[attribute]: metadata.list
|
1052
|
+
};
|
1053
|
+
},
|
1054
|
+
{}
|
1055
|
+
);
|
1056
|
+
const listAttributes = convertListLayoutToFieldLayouts(
|
1057
|
+
data.contentType.layouts.list,
|
1058
|
+
schema?.attributes,
|
1059
|
+
listMetadatas,
|
1060
|
+
{ configurations: data.components, schemas: components },
|
1061
|
+
schemas
|
1062
|
+
);
|
1063
|
+
return {
|
1064
|
+
layout: listAttributes,
|
1065
|
+
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
1066
|
+
metadatas: listMetadatas,
|
1067
|
+
options: {
|
1068
|
+
...schema?.options,
|
1069
|
+
...schema?.pluginOptions,
|
1070
|
+
...data.contentType.options
|
1071
|
+
}
|
1072
|
+
};
|
1073
|
+
};
|
1074
|
+
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
1075
|
+
return columns.map((name) => {
|
1076
|
+
const attribute = attributes[name];
|
1077
|
+
if (!attribute) {
|
1078
|
+
return null;
|
1079
|
+
}
|
1080
|
+
const metadata = metadatas[name];
|
1081
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1082
|
+
return {
|
1083
|
+
attribute,
|
1084
|
+
label: metadata.label ?? "",
|
1085
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1086
|
+
schemas,
|
1087
|
+
components: components?.schemas ?? {}
|
1088
|
+
}),
|
1089
|
+
name,
|
1090
|
+
searchable: metadata.searchable ?? true,
|
1091
|
+
sortable: metadata.sortable ?? true
|
1092
|
+
};
|
1093
|
+
}).filter((field) => field !== null);
|
1094
|
+
};
|
1095
|
+
const useDocument = (args, opts) => {
|
1096
|
+
const { toggleNotification } = useNotification();
|
1097
|
+
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1098
|
+
const {
|
1099
|
+
currentData: data,
|
1100
|
+
isLoading: isLoadingDocument,
|
1101
|
+
isFetching: isFetchingDocument,
|
1102
|
+
error
|
1103
|
+
} = useGetDocumentQuery(args, {
|
1104
|
+
...opts,
|
1105
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
1106
|
+
});
|
1107
|
+
const {
|
1108
|
+
components,
|
1109
|
+
schema,
|
1110
|
+
schemas,
|
1111
|
+
isLoading: isLoadingSchema
|
1112
|
+
} = useContentTypeSchema(args.model);
|
1113
|
+
React.useEffect(() => {
|
1114
|
+
if (error) {
|
1115
|
+
toggleNotification({
|
1116
|
+
type: "danger",
|
1117
|
+
message: formatAPIError(error)
|
1118
|
+
});
|
1119
|
+
}
|
1120
|
+
}, [toggleNotification, error, formatAPIError, args.collectionType]);
|
1121
|
+
const validationSchema = React.useMemo(() => {
|
1122
|
+
if (!schema) {
|
1123
|
+
return null;
|
1124
|
+
}
|
1125
|
+
return createYupSchema(schema.attributes, components);
|
1126
|
+
}, [schema, components]);
|
1127
|
+
const validate = React.useCallback(
|
1128
|
+
(document) => {
|
1129
|
+
if (!validationSchema) {
|
1130
|
+
throw new Error(
|
1131
|
+
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
1132
|
+
);
|
1133
|
+
}
|
1134
|
+
try {
|
1135
|
+
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
1136
|
+
return null;
|
1137
|
+
} catch (error2) {
|
1138
|
+
if (error2 instanceof ValidationError) {
|
1139
|
+
return getYupValidationErrors(error2);
|
1140
|
+
}
|
1141
|
+
throw error2;
|
1142
|
+
}
|
1143
|
+
},
|
1144
|
+
[validationSchema]
|
1145
|
+
);
|
1146
|
+
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
1147
|
+
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) {
|
823
1167
|
throw new Error("Could not find model in url params");
|
824
1168
|
}
|
825
1169
|
return {
|
@@ -834,6 +1178,45 @@ const useDoc = () => {
|
|
834
1178
|
)
|
835
1179
|
};
|
836
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
|
+
};
|
837
1220
|
const prefixPluginTranslations = (trad, pluginId) => {
|
838
1221
|
if (!pluginId) {
|
839
1222
|
throw new TypeError("pluginId can't be empty");
|
@@ -853,6 +1236,8 @@ const useDocumentActions = () => {
|
|
853
1236
|
const { formatMessage } = useIntl();
|
854
1237
|
const { trackUsage } = useTracking();
|
855
1238
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1239
|
+
const navigate = useNavigate();
|
1240
|
+
const setCurrentStep = useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
856
1241
|
const [deleteDocument] = useDeleteDocumentMutation();
|
857
1242
|
const _delete = React.useCallback(
|
858
1243
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -1167,6 +1552,7 @@ const useDocumentActions = () => {
|
|
1167
1552
|
defaultMessage: "Saved document"
|
1168
1553
|
})
|
1169
1554
|
});
|
1555
|
+
setCurrentStep("contentManager.success");
|
1170
1556
|
return res.data;
|
1171
1557
|
} catch (err) {
|
1172
1558
|
toggleNotification({
|
@@ -1188,7 +1574,6 @@ const useDocumentActions = () => {
|
|
1188
1574
|
sourceId
|
1189
1575
|
});
|
1190
1576
|
if ("error" in res) {
|
1191
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1192
1577
|
return { error: res.error };
|
1193
1578
|
}
|
1194
1579
|
toggleNotification({
|
@@ -1207,7 +1592,7 @@ const useDocumentActions = () => {
|
|
1207
1592
|
throw err;
|
1208
1593
|
}
|
1209
1594
|
},
|
1210
|
-
[autoCloneDocument,
|
1595
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1211
1596
|
);
|
1212
1597
|
const [cloneDocument] = useCloneDocumentMutation();
|
1213
1598
|
const clone = React.useCallback(
|
@@ -1233,6 +1618,7 @@ const useDocumentActions = () => {
|
|
1233
1618
|
defaultMessage: "Cloned document"
|
1234
1619
|
})
|
1235
1620
|
});
|
1621
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1236
1622
|
return res.data;
|
1237
1623
|
} catch (err) {
|
1238
1624
|
toggleNotification({
|
@@ -1243,7 +1629,7 @@ const useDocumentActions = () => {
|
|
1243
1629
|
throw err;
|
1244
1630
|
}
|
1245
1631
|
},
|
1246
|
-
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
|
1632
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1247
1633
|
);
|
1248
1634
|
const [getDoc] = useLazyGetDocumentQuery();
|
1249
1635
|
const getDocument = React.useCallback(
|
@@ -1269,7 +1655,7 @@ const useDocumentActions = () => {
|
|
1269
1655
|
};
|
1270
1656
|
};
|
1271
1657
|
const ProtectedHistoryPage = lazy(
|
1272
|
-
() => import("./History-
|
1658
|
+
() => import("./History-2Ah2CQ4T.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1273
1659
|
);
|
1274
1660
|
const routes$1 = [
|
1275
1661
|
{
|
@@ -1282,31 +1668,31 @@ const routes$1 = [
|
|
1282
1668
|
}
|
1283
1669
|
];
|
1284
1670
|
const ProtectedEditViewPage = lazy(
|
1285
|
-
() => import("./EditViewPage-
|
1671
|
+
() => import("./EditViewPage-Dzpno8xI.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1286
1672
|
);
|
1287
1673
|
const ProtectedListViewPage = lazy(
|
1288
|
-
() => import("./ListViewPage-
|
1674
|
+
() => import("./ListViewPage-B75x3nz2.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1289
1675
|
);
|
1290
1676
|
const ProtectedListConfiguration = lazy(
|
1291
|
-
() => import("./ListConfigurationPage-
|
1677
|
+
() => import("./ListConfigurationPage-BjSJlaoC.mjs").then((mod) => ({
|
1292
1678
|
default: mod.ProtectedListConfiguration
|
1293
1679
|
}))
|
1294
1680
|
);
|
1295
1681
|
const ProtectedEditConfigurationPage = lazy(
|
1296
|
-
() => import("./EditConfigurationPage-
|
1682
|
+
() => import("./EditConfigurationPage-CI4XoymK.mjs").then((mod) => ({
|
1297
1683
|
default: mod.ProtectedEditConfigurationPage
|
1298
1684
|
}))
|
1299
1685
|
);
|
1300
1686
|
const ProtectedComponentConfigurationPage = lazy(
|
1301
|
-
() => import("./ComponentConfigurationPage-
|
1687
|
+
() => import("./ComponentConfigurationPage-7-qB29e7.mjs").then((mod) => ({
|
1302
1688
|
default: mod.ProtectedComponentConfigurationPage
|
1303
1689
|
}))
|
1304
1690
|
);
|
1305
1691
|
const NoPermissions = lazy(
|
1306
|
-
() => import("./NoPermissionsPage-
|
1692
|
+
() => import("./NoPermissionsPage-SFllMekk.mjs").then((mod) => ({ default: mod.NoPermissions }))
|
1307
1693
|
);
|
1308
1694
|
const NoContentType = lazy(
|
1309
|
-
() => import("./NoContentTypePage-
|
1695
|
+
() => import("./NoContentTypePage-DUacQSyF.mjs").then((mod) => ({ default: mod.NoContentType }))
|
1310
1696
|
);
|
1311
1697
|
const CollectionTypePages = () => {
|
1312
1698
|
const { collectionType } = useParams();
|
@@ -1420,12 +1806,14 @@ const DocumentActionButton = (action) => {
|
|
1420
1806
|
/* @__PURE__ */ jsx(
|
1421
1807
|
Button,
|
1422
1808
|
{
|
1423
|
-
flex:
|
1809
|
+
flex: "auto",
|
1424
1810
|
startIcon: action.icon,
|
1425
1811
|
disabled: action.disabled,
|
1426
1812
|
onClick: handleClick(action),
|
1427
1813
|
justifyContent: "center",
|
1428
1814
|
variant: action.variant || "default",
|
1815
|
+
paddingTop: "7px",
|
1816
|
+
paddingBottom: "7px",
|
1429
1817
|
children: action.label
|
1430
1818
|
}
|
1431
1819
|
),
|
@@ -1433,7 +1821,7 @@ const DocumentActionButton = (action) => {
|
|
1433
1821
|
DocumentActionConfirmDialog,
|
1434
1822
|
{
|
1435
1823
|
...action.dialog,
|
1436
|
-
variant: action.variant,
|
1824
|
+
variant: action.dialog?.variant ?? action.variant,
|
1437
1825
|
isOpen: dialogId === action.id,
|
1438
1826
|
onClose: handleClose
|
1439
1827
|
}
|
@@ -1490,9 +1878,9 @@ const DocumentActionsMenu = ({
|
|
1490
1878
|
disabled: isDisabled,
|
1491
1879
|
size: "S",
|
1492
1880
|
endIcon: null,
|
1493
|
-
paddingTop: "
|
1494
|
-
paddingLeft: "
|
1495
|
-
paddingRight: "
|
1881
|
+
paddingTop: "4px",
|
1882
|
+
paddingLeft: "7px",
|
1883
|
+
paddingRight: "7px",
|
1496
1884
|
variant,
|
1497
1885
|
children: [
|
1498
1886
|
/* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
|
@@ -1503,7 +1891,7 @@ const DocumentActionsMenu = ({
|
|
1503
1891
|
]
|
1504
1892
|
}
|
1505
1893
|
),
|
1506
|
-
/* @__PURE__ */ jsxs(Menu.Content, {
|
1894
|
+
/* @__PURE__ */ jsxs(Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1507
1895
|
actions2.map((action) => {
|
1508
1896
|
return /* @__PURE__ */ jsx(
|
1509
1897
|
Menu.Item,
|
@@ -1512,10 +1900,25 @@ const DocumentActionsMenu = ({
|
|
1512
1900
|
onSelect: handleClick(action),
|
1513
1901
|
display: "block",
|
1514
1902
|
children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", gap: 4, children: [
|
1515
|
-
/* @__PURE__ */ jsxs(
|
1516
|
-
|
1517
|
-
|
1518
|
-
|
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
|
+
),
|
1519
1922
|
action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsx(
|
1520
1923
|
Flex,
|
1521
1924
|
{
|
@@ -1612,11 +2015,11 @@ const DocumentActionConfirmDialog = ({
|
|
1612
2015
|
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
1613
2016
|
/* @__PURE__ */ jsx(Dialog.Body, { children: content }),
|
1614
2017
|
/* @__PURE__ */ jsxs(Dialog.Footer, { children: [
|
1615
|
-
/* @__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({
|
1616
2019
|
id: "app.components.Button.cancel",
|
1617
2020
|
defaultMessage: "Cancel"
|
1618
2021
|
}) }) }),
|
1619
|
-
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, children: formatMessage({
|
2022
|
+
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
|
1620
2023
|
id: "app.components.Button.confirm",
|
1621
2024
|
defaultMessage: "Confirm"
|
1622
2025
|
}) })
|
@@ -1639,8 +2042,8 @@ const DocumentActionModal = ({
|
|
1639
2042
|
};
|
1640
2043
|
return /* @__PURE__ */ jsx(Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
|
1641
2044
|
/* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: title }) }),
|
1642
|
-
|
1643
|
-
|
2045
|
+
typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsx(Modal.Body, { children: Content }),
|
2046
|
+
typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
|
1644
2047
|
] }) });
|
1645
2048
|
};
|
1646
2049
|
const PublishAction$1 = ({
|
@@ -1655,13 +2058,17 @@ const PublishAction$1 = ({
|
|
1655
2058
|
const navigate = useNavigate();
|
1656
2059
|
const { toggleNotification } = useNotification();
|
1657
2060
|
const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
|
2061
|
+
const isListView = useMatch(LIST_PATH) !== null;
|
1658
2062
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
1659
2063
|
const { formatMessage } = useIntl();
|
1660
|
-
const { canPublish
|
1661
|
-
"PublishAction",
|
1662
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1663
|
-
);
|
2064
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1664
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);
|
1665
2072
|
const [{ query, rawQuery }] = useQueryParams();
|
1666
2073
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
1667
2074
|
const modified = useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
@@ -1670,62 +2077,142 @@ const PublishAction$1 = ({
|
|
1670
2077
|
const validate = useForm("PublishAction", (state) => state.validate);
|
1671
2078
|
const setErrors = useForm("PublishAction", (state) => state.setErrors);
|
1672
2079
|
const formValues = useForm("PublishAction", ({ values }) => values);
|
1673
|
-
|
1674
|
-
|
1675
|
-
|
1676
|
-
|
1677
|
-
|
1678
|
-
|
1679
|
-
|
1680
|
-
|
1681
|
-
|
1682
|
-
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
1686
|
-
|
1687
|
-
|
1688
|
-
|
1689
|
-
|
1690
|
-
|
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) {
|
2137
|
+
return null;
|
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;
|
2177
|
+
return {
|
2178
|
+
/**
|
2179
|
+
* Disabled when:
|
2180
|
+
* - currently if you're cloning a document we don't support publish & clone at the same time.
|
2181
|
+
* - the form is submitting
|
2182
|
+
* - the active tab is the published tab
|
2183
|
+
* - the document is already published & not modified
|
2184
|
+
* - the document is being created & not modified
|
2185
|
+
* - the user doesn't have the permission to publish
|
2186
|
+
*/
|
2187
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
2188
|
+
label: formatMessage({
|
1691
2189
|
id: "app.utils.publish",
|
1692
2190
|
defaultMessage: "Publish"
|
1693
2191
|
}),
|
1694
2192
|
onClick: async () => {
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
documentId,
|
1713
|
-
params
|
1714
|
-
},
|
1715
|
-
formValues
|
1716
|
-
);
|
1717
|
-
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1718
|
-
navigate({
|
1719
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1720
|
-
search: rawQuery
|
1721
|
-
});
|
1722
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1723
|
-
setErrors(formatValidationErrors(res.error));
|
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
|
1724
2210
|
}
|
1725
|
-
|
1726
|
-
|
2211
|
+
),
|
2212
|
+
onConfirm: async () => {
|
2213
|
+
await performPublish();
|
1727
2214
|
}
|
1728
|
-
}
|
2215
|
+
} : void 0
|
1729
2216
|
};
|
1730
2217
|
};
|
1731
2218
|
PublishAction$1.type = "publish";
|
@@ -1741,10 +2228,6 @@ const UpdateAction = ({
|
|
1741
2228
|
const cloneMatch = useMatch(CLONE_PATH);
|
1742
2229
|
const isCloning = cloneMatch !== null;
|
1743
2230
|
const { formatMessage } = useIntl();
|
1744
|
-
const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1745
|
-
canCreate: canCreate2,
|
1746
|
-
canUpdate: canUpdate2
|
1747
|
-
}));
|
1748
2231
|
const { create, update, clone } = useDocumentActions();
|
1749
2232
|
const [{ query, rawQuery }] = useQueryParams();
|
1750
2233
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
@@ -1761,10 +2244,8 @@ const UpdateAction = ({
|
|
1761
2244
|
* - the form is submitting
|
1762
2245
|
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
1763
2246
|
* - the active tab is the published tab
|
1764
|
-
* - the user doesn't have the permission to create a new document
|
1765
|
-
* - the user doesn't have the permission to update the document
|
1766
2247
|
*/
|
1767
|
-
disabled: isSubmitting || !modified && !isCloning || activeTab === "published"
|
2248
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1768
2249
|
label: formatMessage({
|
1769
2250
|
id: "content-manager.containers.Edit.save",
|
1770
2251
|
defaultMessage: "Save"
|
@@ -1772,16 +2253,18 @@ const UpdateAction = ({
|
|
1772
2253
|
onClick: async () => {
|
1773
2254
|
setSubmitting(true);
|
1774
2255
|
try {
|
1775
|
-
|
1776
|
-
|
1777
|
-
|
1778
|
-
|
1779
|
-
|
1780
|
-
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
-
|
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
|
+
}
|
1785
2268
|
}
|
1786
2269
|
if (isCloning) {
|
1787
2270
|
const res = await clone(
|
@@ -1793,10 +2276,13 @@ const UpdateAction = ({
|
|
1793
2276
|
document
|
1794
2277
|
);
|
1795
2278
|
if ("data" in res) {
|
1796
|
-
navigate(
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
2279
|
+
navigate(
|
2280
|
+
{
|
2281
|
+
pathname: `../${res.data.documentId}`,
|
2282
|
+
search: rawQuery
|
2283
|
+
},
|
2284
|
+
{ relative: "path" }
|
2285
|
+
);
|
1800
2286
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1801
2287
|
setErrors(formatValidationErrors(res.error));
|
1802
2288
|
}
|
@@ -1826,10 +2312,10 @@ const UpdateAction = ({
|
|
1826
2312
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1827
2313
|
navigate(
|
1828
2314
|
{
|
1829
|
-
pathname: `../${
|
2315
|
+
pathname: `../${res.data.documentId}`,
|
1830
2316
|
search: rawQuery
|
1831
2317
|
},
|
1832
|
-
{ replace: true }
|
2318
|
+
{ replace: true, relative: "path" }
|
1833
2319
|
);
|
1834
2320
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1835
2321
|
setErrors(formatValidationErrors(res.error));
|
@@ -1874,7 +2360,7 @@ const UnpublishAction$1 = ({
|
|
1874
2360
|
id: "app.utils.unpublish",
|
1875
2361
|
defaultMessage: "Unpublish"
|
1876
2362
|
}),
|
1877
|
-
icon: /* @__PURE__ */ jsx(
|
2363
|
+
icon: /* @__PURE__ */ jsx(Cross, {}),
|
1878
2364
|
onClick: async () => {
|
1879
2365
|
if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
|
1880
2366
|
if (!documentId) {
|
@@ -1986,7 +2472,7 @@ const DiscardAction = ({
|
|
1986
2472
|
id: "content-manager.actions.discard.label",
|
1987
2473
|
defaultMessage: "Discard changes"
|
1988
2474
|
}),
|
1989
|
-
icon: /* @__PURE__ */ jsx(
|
2475
|
+
icon: /* @__PURE__ */ jsx(Cross, {}),
|
1990
2476
|
position: ["panel", "table-row"],
|
1991
2477
|
variant: "danger",
|
1992
2478
|
dialog: {
|
@@ -2014,11 +2500,6 @@ const DiscardAction = ({
|
|
2014
2500
|
};
|
2015
2501
|
};
|
2016
2502
|
DiscardAction.type = "discard";
|
2017
|
-
const StyledCrossCircle = styled(CrossCircle)`
|
2018
|
-
path {
|
2019
|
-
fill: currentColor;
|
2020
|
-
}
|
2021
|
-
`;
|
2022
2503
|
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2023
2504
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2024
2505
|
const RelativeTime = React.forwardRef(
|
@@ -2066,7 +2547,7 @@ const getDisplayName = ({
|
|
2066
2547
|
};
|
2067
2548
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2068
2549
|
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2069
|
-
const statusVariant = status === "draft" ? "
|
2550
|
+
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2070
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) }) });
|
2071
2552
|
};
|
2072
2553
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
@@ -2076,23 +2557,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
|
2076
2557
|
id: "content-manager.containers.edit.title.new",
|
2077
2558
|
defaultMessage: "Create an entry"
|
2078
2559
|
}) : documentTitle;
|
2079
|
-
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: [
|
2080
2561
|
/* @__PURE__ */ jsx(BackButton, {}),
|
2081
|
-
/* @__PURE__ */ jsxs(
|
2082
|
-
|
2083
|
-
{
|
2084
|
-
|
2085
|
-
|
2086
|
-
paddingTop: 1,
|
2087
|
-
gap: "80px",
|
2088
|
-
alignItems: "flex-start",
|
2089
|
-
children: [
|
2090
|
-
/* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
|
2091
|
-
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
2092
|
-
]
|
2093
|
-
}
|
2094
|
-
),
|
2095
|
-
status ? /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) : null
|
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
|
2096
2567
|
] });
|
2097
2568
|
};
|
2098
2569
|
const HeaderToolbar = () => {
|
@@ -2259,25 +2730,77 @@ const Information = ({ activeTab }) => {
|
|
2259
2730
|
);
|
2260
2731
|
};
|
2261
2732
|
const HeaderActions = ({ actions: actions2 }) => {
|
2262
|
-
|
2263
|
-
|
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) {
|
2264
2749
|
return /* @__PURE__ */ jsx(
|
2265
2750
|
SingleSelect,
|
2266
2751
|
{
|
2267
2752
|
size: "S",
|
2268
|
-
disabled: action.disabled,
|
2269
|
-
"aria-label": action.label,
|
2270
2753
|
onChange: action.onSelect,
|
2271
|
-
|
2754
|
+
"aria-label": action.label,
|
2755
|
+
...action,
|
2272
2756
|
children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsx(SingleSelectOption, { ...option, children: label }, option.value))
|
2273
2757
|
},
|
2274
2758
|
action.id
|
2275
2759
|
);
|
2276
2760
|
} else {
|
2277
|
-
|
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
|
+
}
|
2278
2783
|
}
|
2279
2784
|
}) });
|
2280
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
|
+
};
|
2281
2804
|
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
2282
2805
|
const navigate = useNavigate();
|
2283
2806
|
const { formatMessage } = useIntl();
|
@@ -2318,12 +2841,16 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2318
2841
|
const { delete: deleteAction } = useDocumentActions();
|
2319
2842
|
const { toggleNotification } = useNotification();
|
2320
2843
|
const setSubmitting = useForm("DeleteAction", (state) => state.setSubmitting);
|
2844
|
+
const isLocalized = document?.locale != null;
|
2321
2845
|
return {
|
2322
2846
|
disabled: !canDelete || !document,
|
2323
|
-
label: formatMessage(
|
2324
|
-
|
2325
|
-
|
2326
|
-
|
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
|
+
),
|
2327
2854
|
icon: /* @__PURE__ */ jsx(Trash, {}),
|
2328
2855
|
dialog: {
|
2329
2856
|
type: "dialog",
|
@@ -2354,428 +2881,126 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2354
2881
|
}),
|
2355
2882
|
type: "danger"
|
2356
2883
|
});
|
2357
|
-
return;
|
2358
|
-
}
|
2359
|
-
const res = await deleteAction({
|
2360
|
-
documentId,
|
2361
|
-
model,
|
2362
|
-
collectionType,
|
2363
|
-
params: {
|
2364
|
-
locale: "*"
|
2365
|
-
}
|
2366
|
-
});
|
2367
|
-
if (!("error" in res)) {
|
2368
|
-
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
2369
|
-
}
|
2370
|
-
} finally {
|
2371
|
-
if (!listViewPathMatch) {
|
2372
|
-
setSubmitting(false);
|
2373
|
-
}
|
2374
|
-
}
|
2375
|
-
}
|
2376
|
-
},
|
2377
|
-
variant: "danger",
|
2378
|
-
position: ["header", "table-row"]
|
2379
|
-
};
|
2380
|
-
};
|
2381
|
-
DeleteAction$1.type = "delete";
|
2382
|
-
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2383
|
-
const Panels = () => {
|
2384
|
-
const isCloning = useMatch(CLONE_PATH) !== null;
|
2385
|
-
const [
|
2386
|
-
{
|
2387
|
-
query: { status }
|
2388
|
-
}
|
2389
|
-
] = useQueryParams({
|
2390
|
-
status: "draft"
|
2391
|
-
});
|
2392
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2393
|
-
const plugins = useStrapiApp("Panels", (state) => state.plugins);
|
2394
|
-
const props = {
|
2395
|
-
activeTab: status,
|
2396
|
-
model,
|
2397
|
-
documentId: id,
|
2398
|
-
document: isCloning ? void 0 : document,
|
2399
|
-
meta: isCloning ? void 0 : meta,
|
2400
|
-
collectionType
|
2401
|
-
};
|
2402
|
-
return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsx(
|
2403
|
-
DescriptionComponentRenderer,
|
2404
|
-
{
|
2405
|
-
props,
|
2406
|
-
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2407
|
-
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsx(Panel, { ...description, children: content }, id2))
|
2408
|
-
}
|
2409
|
-
) });
|
2410
|
-
};
|
2411
|
-
const ActionsPanel = () => {
|
2412
|
-
const { formatMessage } = useIntl();
|
2413
|
-
return {
|
2414
|
-
title: formatMessage({
|
2415
|
-
id: "content-manager.containers.edit.panels.default.title",
|
2416
|
-
defaultMessage: "Document"
|
2417
|
-
}),
|
2418
|
-
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2419
|
-
};
|
2420
|
-
};
|
2421
|
-
ActionsPanel.type = "actions";
|
2422
|
-
const ActionsPanelContent = () => {
|
2423
|
-
const isCloning = useMatch(CLONE_PATH) !== null;
|
2424
|
-
const [
|
2425
|
-
{
|
2426
|
-
query: { status = "draft" }
|
2427
|
-
}
|
2428
|
-
] = useQueryParams();
|
2429
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2430
|
-
const plugins = useStrapiApp("ActionsPanel", (state) => state.plugins);
|
2431
|
-
const props = {
|
2432
|
-
activeTab: status,
|
2433
|
-
model,
|
2434
|
-
documentId: id,
|
2435
|
-
document: isCloning ? void 0 : document,
|
2436
|
-
meta: isCloning ? void 0 : meta,
|
2437
|
-
collectionType
|
2438
|
-
};
|
2439
|
-
return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
|
2440
|
-
/* @__PURE__ */ jsx(
|
2441
|
-
DescriptionComponentRenderer,
|
2442
|
-
{
|
2443
|
-
props,
|
2444
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2445
|
-
children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
|
2446
|
-
}
|
2447
|
-
),
|
2448
|
-
/* @__PURE__ */ jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
2449
|
-
] });
|
2450
|
-
};
|
2451
|
-
const Panel = React.forwardRef(({ children, title }, ref) => {
|
2452
|
-
return /* @__PURE__ */ jsxs(
|
2453
|
-
Flex,
|
2454
|
-
{
|
2455
|
-
ref,
|
2456
|
-
tag: "aside",
|
2457
|
-
"aria-labelledby": "additional-information",
|
2458
|
-
background: "neutral0",
|
2459
|
-
borderColor: "neutral150",
|
2460
|
-
hasRadius: true,
|
2461
|
-
paddingBottom: 4,
|
2462
|
-
paddingLeft: 4,
|
2463
|
-
paddingRight: 4,
|
2464
|
-
paddingTop: 4,
|
2465
|
-
shadow: "tableShadow",
|
2466
|
-
gap: 3,
|
2467
|
-
direction: "column",
|
2468
|
-
justifyContent: "stretch",
|
2469
|
-
alignItems: "flex-start",
|
2470
|
-
children: [
|
2471
|
-
/* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2472
|
-
children
|
2473
|
-
]
|
2474
|
-
}
|
2475
|
-
);
|
2476
|
-
});
|
2477
|
-
const HOOKS = {
|
2478
|
-
/**
|
2479
|
-
* Hook that allows to mutate the displayed headers of the list view table
|
2480
|
-
* @constant
|
2481
|
-
* @type {string}
|
2482
|
-
*/
|
2483
|
-
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2484
|
-
/**
|
2485
|
-
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2486
|
-
* @constant
|
2487
|
-
* @type {string}
|
2488
|
-
*/
|
2489
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2490
|
-
/**
|
2491
|
-
* Hook that allows to mutate the CM's edit view layout
|
2492
|
-
* @constant
|
2493
|
-
* @type {string}
|
2494
|
-
*/
|
2495
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2496
|
-
/**
|
2497
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
2498
|
-
* @constant
|
2499
|
-
* @type {string}
|
2500
|
-
*/
|
2501
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2502
|
-
};
|
2503
|
-
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2504
|
-
endpoints: (builder) => ({
|
2505
|
-
getContentTypeConfiguration: builder.query({
|
2506
|
-
query: (uid) => ({
|
2507
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2508
|
-
method: "GET"
|
2509
|
-
}),
|
2510
|
-
transformResponse: (response) => response.data,
|
2511
|
-
providesTags: (_result, _error, uid) => [
|
2512
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2513
|
-
{ type: "ContentTypeSettings", id: "LIST" }
|
2514
|
-
]
|
2515
|
-
}),
|
2516
|
-
getAllContentTypeSettings: builder.query({
|
2517
|
-
query: () => "/content-manager/content-types-settings",
|
2518
|
-
transformResponse: (response) => response.data,
|
2519
|
-
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2520
|
-
}),
|
2521
|
-
updateContentTypeConfiguration: builder.mutation({
|
2522
|
-
query: ({ uid, ...body }) => ({
|
2523
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2524
|
-
method: "PUT",
|
2525
|
-
data: body
|
2526
|
-
}),
|
2527
|
-
transformResponse: (response) => response.data,
|
2528
|
-
invalidatesTags: (_result, _error, { uid }) => [
|
2529
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2530
|
-
{ type: "ContentTypeSettings", id: "LIST" },
|
2531
|
-
// Is this necessary?
|
2532
|
-
{ type: "InitialData" }
|
2533
|
-
]
|
2534
|
-
})
|
2535
|
-
})
|
2536
|
-
});
|
2537
|
-
const {
|
2538
|
-
useGetContentTypeConfigurationQuery,
|
2539
|
-
useGetAllContentTypeSettingsQuery,
|
2540
|
-
useUpdateContentTypeConfigurationMutation
|
2541
|
-
} = contentTypesApi;
|
2542
|
-
const checkIfAttributeIsDisplayable = (attribute) => {
|
2543
|
-
const { type } = attribute;
|
2544
|
-
if (type === "relation") {
|
2545
|
-
return !attribute.relation.toLowerCase().includes("morph");
|
2546
|
-
}
|
2547
|
-
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2548
|
-
};
|
2549
|
-
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2550
|
-
if (!mainFieldName) {
|
2551
|
-
return void 0;
|
2552
|
-
}
|
2553
|
-
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2554
|
-
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2555
|
-
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2556
|
-
);
|
2557
|
-
return {
|
2558
|
-
name: mainFieldName,
|
2559
|
-
type: mainFieldType ?? "string"
|
2560
|
-
};
|
2561
|
-
};
|
2562
|
-
const DEFAULT_SETTINGS = {
|
2563
|
-
bulkable: false,
|
2564
|
-
filterable: false,
|
2565
|
-
searchable: false,
|
2566
|
-
pagination: false,
|
2567
|
-
defaultSortBy: "",
|
2568
|
-
defaultSortOrder: "asc",
|
2569
|
-
mainField: "id",
|
2570
|
-
pageSize: 10
|
2571
|
-
};
|
2572
|
-
const useDocumentLayout = (model) => {
|
2573
|
-
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2574
|
-
const [{ query }] = useQueryParams();
|
2575
|
-
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2576
|
-
const { toggleNotification } = useNotification();
|
2577
|
-
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
2578
|
-
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2579
|
-
const {
|
2580
|
-
data,
|
2581
|
-
isLoading: isLoadingConfigs,
|
2582
|
-
error,
|
2583
|
-
isFetching: isFetchingConfigs
|
2584
|
-
} = useGetContentTypeConfigurationQuery(model);
|
2585
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2586
|
-
React.useEffect(() => {
|
2587
|
-
if (error) {
|
2588
|
-
toggleNotification({
|
2589
|
-
type: "danger",
|
2590
|
-
message: formatAPIError(error)
|
2591
|
-
});
|
2592
|
-
}
|
2593
|
-
}, [error, formatAPIError, toggleNotification]);
|
2594
|
-
const editLayout = React.useMemo(
|
2595
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2596
|
-
layout: [],
|
2597
|
-
components: {},
|
2598
|
-
metadatas: {},
|
2599
|
-
options: {},
|
2600
|
-
settings: DEFAULT_SETTINGS
|
2601
|
-
},
|
2602
|
-
[data, isLoading, schemas, schema, components]
|
2603
|
-
);
|
2604
|
-
const listLayout = React.useMemo(() => {
|
2605
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2606
|
-
layout: [],
|
2607
|
-
metadatas: {},
|
2608
|
-
options: {},
|
2609
|
-
settings: DEFAULT_SETTINGS
|
2610
|
-
};
|
2611
|
-
}, [data, isLoading, schemas, schema, components]);
|
2612
|
-
const { layout: edit } = React.useMemo(
|
2613
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2614
|
-
layout: editLayout,
|
2615
|
-
query
|
2616
|
-
}),
|
2617
|
-
[editLayout, query, runHookWaterfall]
|
2618
|
-
);
|
2619
|
-
return {
|
2620
|
-
error,
|
2621
|
-
isLoading,
|
2622
|
-
edit,
|
2623
|
-
list: listLayout
|
2624
|
-
};
|
2625
|
-
};
|
2626
|
-
const useDocLayout = () => {
|
2627
|
-
const { model } = useDoc();
|
2628
|
-
return useDocumentLayout(model);
|
2629
|
-
};
|
2630
|
-
const formatEditLayout = (data, {
|
2631
|
-
schemas,
|
2632
|
-
schema,
|
2633
|
-
components
|
2634
|
-
}) => {
|
2635
|
-
let currentPanelIndex = 0;
|
2636
|
-
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2637
|
-
data.contentType.layouts.edit,
|
2638
|
-
schema?.attributes,
|
2639
|
-
data.contentType.metadatas,
|
2640
|
-
{ configurations: data.components, schemas: components },
|
2641
|
-
schemas
|
2642
|
-
).reduce((panels, row) => {
|
2643
|
-
if (row.some((field) => field.type === "dynamiczone")) {
|
2644
|
-
panels.push([row]);
|
2645
|
-
currentPanelIndex += 2;
|
2646
|
-
} else {
|
2647
|
-
if (!panels[currentPanelIndex]) {
|
2648
|
-
panels.push([]);
|
2649
|
-
}
|
2650
|
-
panels[currentPanelIndex].push(row);
|
2651
|
-
}
|
2652
|
-
return panels;
|
2653
|
-
}, []);
|
2654
|
-
const componentEditAttributes = Object.entries(data.components).reduce(
|
2655
|
-
(acc, [uid, configuration]) => {
|
2656
|
-
acc[uid] = {
|
2657
|
-
layout: convertEditLayoutToFieldLayouts(
|
2658
|
-
configuration.layouts.edit,
|
2659
|
-
components[uid].attributes,
|
2660
|
-
configuration.metadatas
|
2661
|
-
),
|
2662
|
-
settings: {
|
2663
|
-
...configuration.settings,
|
2664
|
-
icon: components[uid].info.icon,
|
2665
|
-
displayName: components[uid].info.displayName
|
2884
|
+
return;
|
2885
|
+
}
|
2886
|
+
const res = await deleteAction({
|
2887
|
+
documentId,
|
2888
|
+
model,
|
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
|
+
}
|
2666
2901
|
}
|
2667
|
-
}
|
2668
|
-
return acc;
|
2669
|
-
},
|
2670
|
-
{}
|
2671
|
-
);
|
2672
|
-
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2673
|
-
(acc, [attribute, metadata]) => {
|
2674
|
-
return {
|
2675
|
-
...acc,
|
2676
|
-
[attribute]: metadata.edit
|
2677
|
-
};
|
2678
|
-
},
|
2679
|
-
{}
|
2680
|
-
);
|
2681
|
-
return {
|
2682
|
-
layout: panelledEditAttributes,
|
2683
|
-
components: componentEditAttributes,
|
2684
|
-
metadatas: editMetadatas,
|
2685
|
-
settings: {
|
2686
|
-
...data.contentType.settings,
|
2687
|
-
displayName: schema?.info.displayName
|
2902
|
+
}
|
2688
2903
|
},
|
2689
|
-
|
2690
|
-
|
2691
|
-
...schema?.pluginOptions,
|
2692
|
-
...data.contentType.options
|
2693
|
-
}
|
2904
|
+
variant: "danger",
|
2905
|
+
position: ["header", "table-row"]
|
2694
2906
|
};
|
2695
2907
|
};
|
2696
|
-
|
2697
|
-
|
2698
|
-
|
2699
|
-
|
2700
|
-
|
2701
|
-
|
2702
|
-
}
|
2703
|
-
|
2704
|
-
|
2705
|
-
|
2706
|
-
|
2707
|
-
|
2708
|
-
|
2709
|
-
|
2710
|
-
|
2711
|
-
|
2712
|
-
|
2713
|
-
|
2714
|
-
|
2715
|
-
|
2716
|
-
|
2717
|
-
|
2718
|
-
|
2719
|
-
|
2720
|
-
|
2721
|
-
|
2722
|
-
}
|
2723
|
-
}
|
2724
|
-
);
|
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
|
+
) });
|
2725
2937
|
};
|
2726
|
-
const
|
2727
|
-
|
2728
|
-
schema,
|
2729
|
-
components
|
2730
|
-
}) => {
|
2731
|
-
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2732
|
-
(acc, [attribute, metadata]) => {
|
2733
|
-
return {
|
2734
|
-
...acc,
|
2735
|
-
[attribute]: metadata.list
|
2736
|
-
};
|
2737
|
-
},
|
2738
|
-
{}
|
2739
|
-
);
|
2740
|
-
const listAttributes = convertListLayoutToFieldLayouts(
|
2741
|
-
data.contentType.layouts.list,
|
2742
|
-
schema?.attributes,
|
2743
|
-
listMetadatas,
|
2744
|
-
{ configurations: data.components, schemas: components },
|
2745
|
-
schemas
|
2746
|
-
);
|
2938
|
+
const ActionsPanel = () => {
|
2939
|
+
const { formatMessage } = useIntl();
|
2747
2940
|
return {
|
2748
|
-
|
2749
|
-
|
2750
|
-
|
2751
|
-
|
2752
|
-
|
2753
|
-
...schema?.pluginOptions,
|
2754
|
-
...data.contentType.options
|
2755
|
-
}
|
2941
|
+
title: formatMessage({
|
2942
|
+
id: "content-manager.containers.edit.panels.default.title",
|
2943
|
+
defaultMessage: "Entry"
|
2944
|
+
}),
|
2945
|
+
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2756
2946
|
};
|
2757
2947
|
};
|
2758
|
-
|
2759
|
-
|
2760
|
-
|
2761
|
-
|
2762
|
-
|
2948
|
+
ActionsPanel.type = "actions";
|
2949
|
+
const ActionsPanelContent = () => {
|
2950
|
+
const isCloning = useMatch(CLONE_PATH) !== null;
|
2951
|
+
const [
|
2952
|
+
{
|
2953
|
+
query: { status = "draft" }
|
2763
2954
|
}
|
2764
|
-
|
2765
|
-
|
2766
|
-
|
2767
|
-
|
2768
|
-
|
2769
|
-
|
2770
|
-
|
2771
|
-
|
2772
|
-
|
2773
|
-
|
2774
|
-
|
2775
|
-
|
2776
|
-
|
2777
|
-
|
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
|
+
] });
|
2778
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
|
+
});
|
2779
3004
|
const ConfirmBulkActionDialog = ({
|
2780
3005
|
onToggleDialog,
|
2781
3006
|
isOpen = false,
|
@@ -2783,7 +3008,7 @@ const ConfirmBulkActionDialog = ({
|
|
2783
3008
|
endAction
|
2784
3009
|
}) => {
|
2785
3010
|
const { formatMessage } = useIntl();
|
2786
|
-
return /* @__PURE__ */ jsx(Dialog.Root, {
|
3011
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
2787
3012
|
/* @__PURE__ */ jsx(Dialog.Header, { children: formatMessage({
|
2788
3013
|
id: "app.components.ConfirmDialog.title",
|
2789
3014
|
defaultMessage: "Confirmation"
|
@@ -2814,6 +3039,7 @@ const ConfirmDialogPublishAll = ({
|
|
2814
3039
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(getTranslation);
|
2815
3040
|
const { model, schema } = useDoc();
|
2816
3041
|
const [{ query }] = useQueryParams();
|
3042
|
+
const enableDraftRelationsCount = false;
|
2817
3043
|
const {
|
2818
3044
|
data: countDraftRelations = 0,
|
2819
3045
|
isLoading,
|
@@ -2825,7 +3051,7 @@ const ConfirmDialogPublishAll = ({
|
|
2825
3051
|
locale: query?.plugins?.i18n?.locale
|
2826
3052
|
},
|
2827
3053
|
{
|
2828
|
-
skip:
|
3054
|
+
skip: !enableDraftRelationsCount
|
2829
3055
|
}
|
2830
3056
|
);
|
2831
3057
|
React.useEffect(() => {
|
@@ -3010,7 +3236,7 @@ const SelectedEntriesTableContent = ({
|
|
3010
3236
|
status: row.status
|
3011
3237
|
}
|
3012
3238
|
) }),
|
3013
|
-
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(
|
3239
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
|
3014
3240
|
IconButton,
|
3015
3241
|
{
|
3016
3242
|
tag: Link,
|
@@ -3033,9 +3259,10 @@ const SelectedEntriesTableContent = ({
|
|
3033
3259
|
),
|
3034
3260
|
target: "_blank",
|
3035
3261
|
marginLeft: "auto",
|
3036
|
-
|
3262
|
+
variant: "ghost",
|
3263
|
+
children: /* @__PURE__ */ jsx(Pencil, { width: "1.6rem", height: "1.6rem" })
|
3037
3264
|
}
|
3038
|
-
) })
|
3265
|
+
) }) })
|
3039
3266
|
] }, row.id)) })
|
3040
3267
|
] });
|
3041
3268
|
};
|
@@ -3072,7 +3299,13 @@ const SelectedEntriesModalContent = ({
|
|
3072
3299
|
);
|
3073
3300
|
const { rows, validationErrors } = React.useMemo(() => {
|
3074
3301
|
if (data.length > 0 && schema) {
|
3075
|
-
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
|
+
);
|
3076
3309
|
const validationErrors2 = {};
|
3077
3310
|
const rows2 = data.map((entry) => {
|
3078
3311
|
try {
|
@@ -3422,7 +3655,7 @@ const TableActions = ({ document }) => {
|
|
3422
3655
|
DescriptionComponentRenderer,
|
3423
3656
|
{
|
3424
3657
|
props,
|
3425
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3658
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
3426
3659
|
children: (actions2) => {
|
3427
3660
|
const tableRowActions = actions2.filter((action) => {
|
3428
3661
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3533,7 +3766,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3533
3766
|
}),
|
3534
3767
|
content: /* @__PURE__ */ jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
3535
3768
|
footer: ({ onClose }) => {
|
3536
|
-
return /* @__PURE__ */ jsxs(
|
3769
|
+
return /* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
3537
3770
|
/* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
3538
3771
|
id: "cancel",
|
3539
3772
|
defaultMessage: "Cancel"
|
@@ -3574,8 +3807,7 @@ class ContentManagerPlugin {
|
|
3574
3807
|
documentActions = [
|
3575
3808
|
...DEFAULT_ACTIONS,
|
3576
3809
|
...DEFAULT_TABLE_ROW_ACTIONS,
|
3577
|
-
...DEFAULT_HEADER_ACTIONS
|
3578
|
-
HistoryAction
|
3810
|
+
...DEFAULT_HEADER_ACTIONS
|
3579
3811
|
];
|
3580
3812
|
editViewSidePanels = [ActionsPanel];
|
3581
3813
|
headerActions = [];
|
@@ -3664,6 +3896,52 @@ const getPrintableType = (value) => {
|
|
3664
3896
|
}
|
3665
3897
|
return nativeType;
|
3666
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
|
+
};
|
3667
3945
|
const initialState = {
|
3668
3946
|
collectionTypeLinks: [],
|
3669
3947
|
components: [],
|
@@ -3719,7 +3997,7 @@ const index = {
|
|
3719
3997
|
app.router.addRoute({
|
3720
3998
|
path: "content-manager/*",
|
3721
3999
|
lazy: async () => {
|
3722
|
-
const { Layout } = await import("./layout-
|
4000
|
+
const { Layout } = await import("./layout-DaUjDiWQ.mjs");
|
3723
4001
|
return {
|
3724
4002
|
Component: Layout
|
3725
4003
|
};
|
@@ -3728,10 +4006,15 @@ const index = {
|
|
3728
4006
|
});
|
3729
4007
|
app.registerPlugin(cm.config);
|
3730
4008
|
},
|
4009
|
+
bootstrap(app) {
|
4010
|
+
if (typeof historyAdmin.bootstrap === "function") {
|
4011
|
+
historyAdmin.bootstrap(app);
|
4012
|
+
}
|
4013
|
+
},
|
3731
4014
|
async registerTrads({ locales }) {
|
3732
4015
|
const importedTrads = await Promise.all(
|
3733
4016
|
locales.map((locale) => {
|
3734
|
-
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-
|
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 }) => {
|
3735
4018
|
return {
|
3736
4019
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3737
4020
|
locale
|
@@ -3752,13 +4035,15 @@ export {
|
|
3752
4035
|
BulkActionsRenderer as B,
|
3753
4036
|
COLLECTION_TYPES as C,
|
3754
4037
|
DocumentStatus as D,
|
3755
|
-
|
3756
|
-
|
3757
|
-
|
4038
|
+
extractContentTypeComponents as E,
|
4039
|
+
DEFAULT_SETTINGS as F,
|
4040
|
+
convertEditLayoutToFieldLayouts as G,
|
3758
4041
|
HOOKS as H,
|
3759
4042
|
InjectionZone as I,
|
3760
|
-
|
3761
|
-
|
4043
|
+
useDocument as J,
|
4044
|
+
index as K,
|
4045
|
+
useContentManagerContext as L,
|
4046
|
+
useDocumentActions as M,
|
3762
4047
|
Panels as P,
|
3763
4048
|
RelativeTime as R,
|
3764
4049
|
SINGLE_TYPES as S,
|
@@ -3776,18 +4061,18 @@ export {
|
|
3776
4061
|
PERMISSIONS as k,
|
3777
4062
|
DocumentRBAC as l,
|
3778
4063
|
DOCUMENT_META_FIELDS as m,
|
3779
|
-
|
3780
|
-
|
3781
|
-
|
3782
|
-
|
3783
|
-
|
4064
|
+
CLONE_PATH as n,
|
4065
|
+
useDocLayout as o,
|
4066
|
+
useGetContentTypeConfigurationQuery as p,
|
4067
|
+
CREATOR_FIELDS as q,
|
4068
|
+
getMainField as r,
|
3784
4069
|
setInitialData as s,
|
3785
|
-
|
4070
|
+
getDisplayName as t,
|
3786
4071
|
useContentTypeSchema as u,
|
3787
|
-
|
3788
|
-
|
3789
|
-
|
3790
|
-
|
3791
|
-
|
4072
|
+
checkIfAttributeIsDisplayable as v,
|
4073
|
+
useGetAllDocumentsQuery as w,
|
4074
|
+
convertListLayoutToFieldLayouts as x,
|
4075
|
+
capitalise as y,
|
4076
|
+
useUpdateContentTypeConfigurationMutation as z
|
3792
4077
|
};
|
3793
|
-
//# sourceMappingURL=index-
|
4078
|
+
//# sourceMappingURL=index-C9HxCo5R.mjs.map
|