@strapi/content-manager 0.0.0-experimental.a53a4b1c8f7981a689823cdd719105671e1c6392 → 0.0.0-experimental.a6728ad43ac70ae19dabb624dbfca1f2d9610a86
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +18 -3
- package/dist/_chunks/{ComponentConfigurationPage-DmwmiFQy.mjs → ComponentConfigurationPage-DJ5voqEK.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-DmwmiFQy.mjs.map → ComponentConfigurationPage-DJ5voqEK.mjs.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-C-49MccQ.js → ComponentConfigurationPage-_6osrv39.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-C-49MccQ.js.map → ComponentConfigurationPage-_6osrv39.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-JT3E7NZy.mjs → EditConfigurationPage-CZofxSLy.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-JT3E7NZy.mjs.map → EditConfigurationPage-CZofxSLy.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-DjFJw56M.js → EditConfigurationPage-ZN3s568V.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-DjFJw56M.js.map → EditConfigurationPage-ZN3s568V.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-zT3fBr4Y.js → EditViewPage-Co2IKQZH.js} +19 -8
- package/dist/_chunks/EditViewPage-Co2IKQZH.js.map +1 -0
- package/dist/_chunks/{EditViewPage-CPj61RMh.mjs → EditViewPage-HYljoEY7.mjs} +19 -8
- package/dist/_chunks/EditViewPage-HYljoEY7.mjs.map +1 -0
- package/dist/_chunks/{Field-dha5VnIQ.mjs → Field-BOPUMZ1u.mjs} +194 -141
- package/dist/_chunks/Field-BOPUMZ1u.mjs.map +1 -0
- package/dist/_chunks/{Field-Boxf9Ajp.js → Field-G9CkFUtP.js} +196 -143
- package/dist/_chunks/Field-G9CkFUtP.js.map +1 -0
- package/dist/_chunks/{Form-DHrru2AV.mjs → Form-CDwNp7pU.mjs} +35 -16
- package/dist/_chunks/Form-CDwNp7pU.mjs.map +1 -0
- package/dist/_chunks/{Form-y5g1SRsh.js → Form-crsbkGxI.js} +35 -16
- package/dist/_chunks/Form-crsbkGxI.js.map +1 -0
- package/dist/_chunks/{History-Bru_KoeP.mjs → History-BDZrgfZ3.mjs} +44 -19
- package/dist/_chunks/History-BDZrgfZ3.mjs.map +1 -0
- package/dist/_chunks/{History-CqN6K7SX.js → History-CWcM9HnW.js} +44 -19
- package/dist/_chunks/History-CWcM9HnW.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-D8wGABj0.mjs → ListConfigurationPage-BZ3ScUna.mjs} +20 -8
- package/dist/_chunks/ListConfigurationPage-BZ3ScUna.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-R_p-SbHZ.js → ListConfigurationPage-DGzoQD_I.js} +20 -8
- package/dist/_chunks/ListConfigurationPage-DGzoQD_I.js.map +1 -0
- package/dist/_chunks/{ListViewPage-pEw_zug9.js → ListViewPage-BBAC9aPu.js} +60 -42
- package/dist/_chunks/ListViewPage-BBAC9aPu.js.map +1 -0
- package/dist/_chunks/{ListViewPage-SID6TRb9.mjs → ListViewPage-CsX7tWx-.mjs} +58 -40
- package/dist/_chunks/ListViewPage-CsX7tWx-.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-C5dcQojD.js → NoContentTypePage-CwVDx_YC.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-C5dcQojD.js.map → NoContentTypePage-CwVDx_YC.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-CJ7UXwrQ.mjs → NoContentTypePage-LClTUPWs.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-CJ7UXwrQ.mjs.map → NoContentTypePage-LClTUPWs.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-BtPrImPP.js → NoPermissionsPage-D2iWw-sn.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-BtPrImPP.js.map → NoPermissionsPage-D2iWw-sn.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-B7syEq5E.mjs → NoPermissionsPage-S4Re3FwO.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-B7syEq5E.mjs.map → NoPermissionsPage-S4Re3FwO.mjs.map} +1 -1
- package/dist/_chunks/{Relations-B9Crnhnn.mjs → Relations-Dmv0Tpe5.mjs} +4 -4
- package/dist/_chunks/Relations-Dmv0Tpe5.mjs.map +1 -0
- package/dist/_chunks/{Relations-DjTQ5kGB.js → Relations-jwuTFGOV.js} +4 -4
- package/dist/_chunks/Relations-jwuTFGOV.js.map +1 -0
- package/dist/_chunks/{en-fbKQxLGn.js → en-BlhnxQfj.js} +11 -9
- package/dist/_chunks/{en-fbKQxLGn.js.map → en-BlhnxQfj.js.map} +1 -1
- package/dist/_chunks/{en-Ux26r5pl.mjs → en-C8YBvRrK.mjs} +11 -9
- package/dist/_chunks/{en-Ux26r5pl.mjs.map → en-C8YBvRrK.mjs.map} +1 -1
- package/dist/_chunks/{index-DJXJw9V5.mjs → index-BmUAydCA.mjs} +977 -680
- package/dist/_chunks/index-BmUAydCA.mjs.map +1 -0
- package/dist/_chunks/{index-DVPWZkbS.js → index-CBX6KyXv.js} +958 -661
- package/dist/_chunks/index-CBX6KyXv.js.map +1 -0
- package/dist/_chunks/{layout-Bau7ZfLV.mjs → layout-ClP-DC72.mjs} +25 -12
- package/dist/_chunks/layout-ClP-DC72.mjs.map +1 -0
- package/dist/_chunks/{layout-Dm6fbiQj.js → layout-CxxkX9jY.js} +24 -11
- package/dist/_chunks/layout-CxxkX9jY.js.map +1 -0
- package/dist/_chunks/{relations-CKnpRgrN.js → relations-DIjTADIu.js} +2 -2
- package/dist/_chunks/{relations-CKnpRgrN.js.map → relations-DIjTADIu.js.map} +1 -1
- package/dist/_chunks/{relations-BH_kBSJ0.mjs → relations-op89RClB.mjs} +2 -2
- package/dist/_chunks/{relations-BH_kBSJ0.mjs.map → relations-op89RClB.mjs.map} +1 -1
- package/dist/_chunks/{usePrev-B9w_-eYc.js → useDebounce-CtcjDB3L.js} +14 -1
- package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs +29 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -0
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +5 -4
- package/dist/admin/src/exports.d.ts +1 -1
- package/dist/admin/src/history/index.d.ts +3 -0
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +30 -1
- package/dist/admin/src/index.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +20 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +4 -48
- package/dist/admin/src/pages/EditView/components/Header.d.ts +10 -11
- package/dist/admin/src/services/api.d.ts +1 -1
- package/dist/admin/src/services/components.d.ts +2 -2
- package/dist/admin/src/services/contentTypes.d.ts +3 -3
- package/dist/admin/src/services/documents.d.ts +19 -17
- package/dist/admin/src/services/init.d.ts +1 -1
- package/dist/admin/src/services/relations.d.ts +2 -2
- package/dist/admin/src/services/uid.d.ts +3 -3
- package/dist/admin/src/utils/validation.d.ts +4 -1
- package/dist/server/index.js +181 -107
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +182 -108
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/controllers/relations.d.ts.map +1 -1
- package/dist/server/src/controllers/uid.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/dimensions.d.ts +4 -2
- package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -1
- package/dist/server/src/history/services/history.d.ts.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
- package/dist/server/src/history/services/utils.d.ts +2 -1
- package/dist/server/src/history/services/utils.d.ts.map +1 -1
- package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/permission-checker.d.ts.map +1 -1
- package/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/dist/shared/contracts/collection-types.d.ts +3 -1
- package/dist/shared/contracts/collection-types.d.ts.map +1 -1
- package/package.json +11 -11
- package/dist/_chunks/EditViewPage-CPj61RMh.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-zT3fBr4Y.js.map +0 -1
- package/dist/_chunks/Field-Boxf9Ajp.js.map +0 -1
- package/dist/_chunks/Field-dha5VnIQ.mjs.map +0 -1
- package/dist/_chunks/Form-DHrru2AV.mjs.map +0 -1
- package/dist/_chunks/Form-y5g1SRsh.js.map +0 -1
- package/dist/_chunks/History-Bru_KoeP.mjs.map +0 -1
- package/dist/_chunks/History-CqN6K7SX.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-D8wGABj0.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-R_p-SbHZ.js.map +0 -1
- package/dist/_chunks/ListViewPage-SID6TRb9.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-pEw_zug9.js.map +0 -1
- package/dist/_chunks/Relations-B9Crnhnn.mjs.map +0 -1
- package/dist/_chunks/Relations-DjTQ5kGB.js.map +0 -1
- package/dist/_chunks/index-DJXJw9V5.mjs.map +0 -1
- package/dist/_chunks/index-DVPWZkbS.js.map +0 -1
- package/dist/_chunks/layout-Bau7ZfLV.mjs.map +0 -1
- package/dist/_chunks/layout-Dm6fbiQj.js.map +0 -1
- package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
- package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
- package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
- package/strapi-server.js +0 -3
@@ -2,15 +2,15 @@
|
|
2
2
|
const Icons = require("@strapi/icons");
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
4
4
|
const strapiAdmin = require("@strapi/admin/strapi-admin");
|
5
|
-
const qs = require("qs");
|
6
|
-
const reactIntl = require("react-intl");
|
7
|
-
const reactRouterDom = require("react-router-dom");
|
8
5
|
const React = require("react");
|
9
6
|
const designSystem = require("@strapi/design-system");
|
10
|
-
const
|
7
|
+
const reactIntl = require("react-intl");
|
8
|
+
const reactRouterDom = require("react-router-dom");
|
11
9
|
const yup = require("yup");
|
12
10
|
const pipe = require("lodash/fp/pipe");
|
13
11
|
const dateFns = require("date-fns");
|
12
|
+
const styledComponents = require("styled-components");
|
13
|
+
const qs = require("qs");
|
14
14
|
const toolkit = require("@reduxjs/toolkit");
|
15
15
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
16
16
|
function _interopNamespace(e) {
|
@@ -70,42 +70,6 @@ const useInjectionZone = (area) => {
|
|
70
70
|
const [page, position] = area.split(".");
|
71
71
|
return contentManagerPlugin.getInjectedComponents(page, position);
|
72
72
|
};
|
73
|
-
const HistoryAction = ({ model, document }) => {
|
74
|
-
const { formatMessage } = reactIntl.useIntl();
|
75
|
-
const [{ query }] = strapiAdmin.useQueryParams();
|
76
|
-
const navigate = reactRouterDom.useNavigate();
|
77
|
-
const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
|
78
|
-
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
79
|
-
return null;
|
80
|
-
}
|
81
|
-
return {
|
82
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
|
83
|
-
label: formatMessage({
|
84
|
-
id: "content-manager.history.document-action",
|
85
|
-
defaultMessage: "Content History"
|
86
|
-
}),
|
87
|
-
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
88
|
-
disabled: (
|
89
|
-
/**
|
90
|
-
* The user is creating a new document.
|
91
|
-
* It hasn't been saved yet, so there's no history to go to
|
92
|
-
*/
|
93
|
-
!document || /**
|
94
|
-
* The document has been created but the current dimension has never been saved.
|
95
|
-
* For example, the user is creating a new locale in an existing document,
|
96
|
-
* so there's no history for the document in that locale
|
97
|
-
*/
|
98
|
-
!document.id || /**
|
99
|
-
* History is only available for content types created by the user.
|
100
|
-
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
101
|
-
* which start with `admin::` or `plugin::`
|
102
|
-
*/
|
103
|
-
!model.startsWith("api::")
|
104
|
-
),
|
105
|
-
position: "header"
|
106
|
-
};
|
107
|
-
};
|
108
|
-
HistoryAction.type = "history";
|
109
73
|
const ID = "id";
|
110
74
|
const CREATED_BY_ATTRIBUTE_NAME = "createdBy";
|
111
75
|
const UPDATED_BY_ATTRIBUTE_NAME = "updatedBy";
|
@@ -215,7 +179,8 @@ const contentManagerApi = strapiAdmin.adminApi.enhanceEndpoints({
|
|
215
179
|
"Document",
|
216
180
|
"InitialData",
|
217
181
|
"HistoryVersion",
|
218
|
-
"Relations"
|
182
|
+
"Relations",
|
183
|
+
"UidAvailability"
|
219
184
|
]
|
220
185
|
});
|
221
186
|
const documentApi = contentManagerApi.injectEndpoints({
|
@@ -229,7 +194,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
229
194
|
params: query
|
230
195
|
}
|
231
196
|
}),
|
232
|
-
invalidatesTags: (_result,
|
197
|
+
invalidatesTags: (_result, error, { model }) => {
|
198
|
+
if (error) {
|
199
|
+
return [];
|
200
|
+
}
|
201
|
+
return [{ type: "Document", id: `${model}_LIST` }];
|
202
|
+
}
|
233
203
|
}),
|
234
204
|
cloneDocument: builder.mutation({
|
235
205
|
query: ({ model, sourceId, data, params }) => ({
|
@@ -240,7 +210,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
240
210
|
params
|
241
211
|
}
|
242
212
|
}),
|
243
|
-
invalidatesTags: (_result, _error, { model }) => [
|
213
|
+
invalidatesTags: (_result, _error, { model }) => [
|
214
|
+
{ type: "Document", id: `${model}_LIST` },
|
215
|
+
{ type: "UidAvailability", id: model }
|
216
|
+
]
|
244
217
|
}),
|
245
218
|
/**
|
246
219
|
* Creates a new collection-type document. This should ONLY be used for collection-types.
|
@@ -257,7 +230,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
257
230
|
}),
|
258
231
|
invalidatesTags: (result, _error, { model }) => [
|
259
232
|
{ type: "Document", id: `${model}_LIST` },
|
260
|
-
"Relations"
|
233
|
+
"Relations",
|
234
|
+
{ type: "UidAvailability", id: model }
|
261
235
|
]
|
262
236
|
}),
|
263
237
|
deleteDocument: builder.mutation({
|
@@ -298,7 +272,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
298
272
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
299
273
|
},
|
300
274
|
{ type: "Document", id: `${model}_LIST` },
|
301
|
-
"Relations"
|
275
|
+
"Relations",
|
276
|
+
{ type: "UidAvailability", id: model }
|
302
277
|
];
|
303
278
|
}
|
304
279
|
}),
|
@@ -316,6 +291,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
316
291
|
}),
|
317
292
|
providesTags: (result, _error, arg) => {
|
318
293
|
return [
|
294
|
+
{ type: "Document", id: `ALL_LIST` },
|
319
295
|
{ type: "Document", id: `${arg.model}_LIST` },
|
320
296
|
...result?.results.map(({ documentId }) => ({
|
321
297
|
type: "Document",
|
@@ -354,6 +330,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
354
330
|
{
|
355
331
|
type: "Document",
|
356
332
|
id: collectionType !== SINGLE_TYPES ? `${model}_${result && "documentId" in result ? result.documentId : documentId}` : model
|
333
|
+
},
|
334
|
+
// Make it easy to invalidate all individual documents queries for a model
|
335
|
+
{
|
336
|
+
type: "Document",
|
337
|
+
id: `${model}_ALL_ITEMS`
|
357
338
|
}
|
358
339
|
];
|
359
340
|
}
|
@@ -417,8 +398,21 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
417
398
|
type: "Document",
|
418
399
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
419
400
|
},
|
420
|
-
"Relations"
|
401
|
+
"Relations",
|
402
|
+
{ type: "UidAvailability", id: model }
|
421
403
|
];
|
404
|
+
},
|
405
|
+
async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
|
406
|
+
const patchResult = dispatch(
|
407
|
+
documentApi.util.updateQueryData("getDocument", patch, (draft) => {
|
408
|
+
Object.assign(draft.data, data);
|
409
|
+
})
|
410
|
+
);
|
411
|
+
try {
|
412
|
+
await queryFulfilled;
|
413
|
+
} catch {
|
414
|
+
patchResult.undo();
|
415
|
+
}
|
422
416
|
}
|
423
417
|
}),
|
424
418
|
unpublishDocument: builder.mutation({
|
@@ -488,7 +482,7 @@ const buildValidParams = (query) => {
|
|
488
482
|
const isBaseQueryError = (error) => {
|
489
483
|
return error.name !== void 0;
|
490
484
|
};
|
491
|
-
const createYupSchema = (attributes = {}, components = {}) => {
|
485
|
+
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
492
486
|
const createModelSchema = (attributes2) => yup__namespace.object().shape(
|
493
487
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
494
488
|
if (DOCUMENT_META_FIELDS.includes(name)) {
|
@@ -501,7 +495,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
501
495
|
addMinValidation,
|
502
496
|
addMaxValidation,
|
503
497
|
addRegexValidation
|
504
|
-
].map((fn) => fn(attribute));
|
498
|
+
].map((fn) => fn(attribute, options));
|
505
499
|
const transformSchema = pipe__default.default(...validations);
|
506
500
|
switch (attribute.type) {
|
507
501
|
case "component": {
|
@@ -602,6 +596,14 @@ const createAttributeSchema = (attribute) => {
|
|
602
596
|
if (!value || typeof value === "string" && value.length === 0) {
|
603
597
|
return true;
|
604
598
|
}
|
599
|
+
if (typeof value === "object") {
|
600
|
+
try {
|
601
|
+
JSON.stringify(value);
|
602
|
+
return true;
|
603
|
+
} catch (err) {
|
604
|
+
return false;
|
605
|
+
}
|
606
|
+
}
|
605
607
|
try {
|
606
608
|
JSON.parse(value);
|
607
609
|
return true;
|
@@ -620,13 +622,7 @@ const createAttributeSchema = (attribute) => {
|
|
620
622
|
return yup__namespace.mixed();
|
621
623
|
}
|
622
624
|
};
|
623
|
-
const
|
624
|
-
if (attribute.required) {
|
625
|
-
return schema.required({
|
626
|
-
id: strapiAdmin.translatedErrors.required.id,
|
627
|
-
defaultMessage: "This field is required."
|
628
|
-
});
|
629
|
-
}
|
625
|
+
const nullableSchema = (schema) => {
|
630
626
|
return schema?.nullable ? schema.nullable() : (
|
631
627
|
// In some cases '.nullable' will not be available on the schema.
|
632
628
|
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
@@ -634,7 +630,22 @@ const addRequiredValidation = (attribute) => (schema) => {
|
|
634
630
|
schema
|
635
631
|
);
|
636
632
|
};
|
637
|
-
const
|
633
|
+
const addRequiredValidation = (attribute, options) => (schema) => {
|
634
|
+
if (options.status === "draft") {
|
635
|
+
return nullableSchema(schema);
|
636
|
+
}
|
637
|
+
if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
|
638
|
+
return schema.min(1, strapiAdmin.translatedErrors.required);
|
639
|
+
}
|
640
|
+
if (attribute.required && attribute.type !== "relation") {
|
641
|
+
return schema.required(strapiAdmin.translatedErrors.required);
|
642
|
+
}
|
643
|
+
return nullableSchema(schema);
|
644
|
+
};
|
645
|
+
const addMinLengthValidation = (attribute, options) => (schema) => {
|
646
|
+
if (options.status === "draft") {
|
647
|
+
return schema;
|
648
|
+
}
|
638
649
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
639
650
|
return schema.min(attribute.minLength, {
|
640
651
|
...strapiAdmin.translatedErrors.minLength,
|
@@ -656,9 +667,31 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
656
667
|
}
|
657
668
|
return schema;
|
658
669
|
};
|
659
|
-
const addMinValidation = (attribute) => (schema) => {
|
670
|
+
const addMinValidation = (attribute, options) => (schema) => {
|
660
671
|
if ("min" in attribute) {
|
661
672
|
const min = toInteger(attribute.min);
|
673
|
+
if (attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") {
|
674
|
+
if (options.status !== "draft" && !attribute.required && "test" in schema && min) {
|
675
|
+
return schema.test(
|
676
|
+
"custom-min",
|
677
|
+
{
|
678
|
+
...strapiAdmin.translatedErrors.min,
|
679
|
+
values: {
|
680
|
+
min: attribute.min
|
681
|
+
}
|
682
|
+
},
|
683
|
+
(value) => {
|
684
|
+
if (!value) {
|
685
|
+
return true;
|
686
|
+
}
|
687
|
+
if (Array.isArray(value) && value.length === 0) {
|
688
|
+
return true;
|
689
|
+
}
|
690
|
+
return value.length >= min;
|
691
|
+
}
|
692
|
+
);
|
693
|
+
}
|
694
|
+
}
|
662
695
|
if ("min" in schema && min) {
|
663
696
|
return schema.min(min, {
|
664
697
|
...strapiAdmin.translatedErrors.min,
|
@@ -777,16 +810,115 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
|
|
777
810
|
}, {});
|
778
811
|
return componentsByKey;
|
779
812
|
};
|
780
|
-
const
|
813
|
+
const HOOKS = {
|
814
|
+
/**
|
815
|
+
* Hook that allows to mutate the displayed headers of the list view table
|
816
|
+
* @constant
|
817
|
+
* @type {string}
|
818
|
+
*/
|
819
|
+
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
820
|
+
/**
|
821
|
+
* Hook that allows to mutate the CM's collection types links pre-set filters
|
822
|
+
* @constant
|
823
|
+
* @type {string}
|
824
|
+
*/
|
825
|
+
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
826
|
+
/**
|
827
|
+
* Hook that allows to mutate the CM's edit view layout
|
828
|
+
* @constant
|
829
|
+
* @type {string}
|
830
|
+
*/
|
831
|
+
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
832
|
+
/**
|
833
|
+
* Hook that allows to mutate the CM's single types links pre-set filters
|
834
|
+
* @constant
|
835
|
+
* @type {string}
|
836
|
+
*/
|
837
|
+
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
838
|
+
};
|
839
|
+
const contentTypesApi = contentManagerApi.injectEndpoints({
|
840
|
+
endpoints: (builder) => ({
|
841
|
+
getContentTypeConfiguration: builder.query({
|
842
|
+
query: (uid) => ({
|
843
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
844
|
+
method: "GET"
|
845
|
+
}),
|
846
|
+
transformResponse: (response) => response.data,
|
847
|
+
providesTags: (_result, _error, uid) => [
|
848
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
849
|
+
{ type: "ContentTypeSettings", id: "LIST" }
|
850
|
+
]
|
851
|
+
}),
|
852
|
+
getAllContentTypeSettings: builder.query({
|
853
|
+
query: () => "/content-manager/content-types-settings",
|
854
|
+
transformResponse: (response) => response.data,
|
855
|
+
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
856
|
+
}),
|
857
|
+
updateContentTypeConfiguration: builder.mutation({
|
858
|
+
query: ({ uid, ...body }) => ({
|
859
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
860
|
+
method: "PUT",
|
861
|
+
data: body
|
862
|
+
}),
|
863
|
+
transformResponse: (response) => response.data,
|
864
|
+
invalidatesTags: (_result, _error, { uid }) => [
|
865
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
866
|
+
{ type: "ContentTypeSettings", id: "LIST" },
|
867
|
+
// Is this necessary?
|
868
|
+
{ type: "InitialData" }
|
869
|
+
]
|
870
|
+
})
|
871
|
+
})
|
872
|
+
});
|
873
|
+
const {
|
874
|
+
useGetContentTypeConfigurationQuery,
|
875
|
+
useGetAllContentTypeSettingsQuery,
|
876
|
+
useUpdateContentTypeConfigurationMutation
|
877
|
+
} = contentTypesApi;
|
878
|
+
const checkIfAttributeIsDisplayable = (attribute) => {
|
879
|
+
const { type } = attribute;
|
880
|
+
if (type === "relation") {
|
881
|
+
return !attribute.relation.toLowerCase().includes("morph");
|
882
|
+
}
|
883
|
+
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
884
|
+
};
|
885
|
+
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
886
|
+
if (!mainFieldName) {
|
887
|
+
return void 0;
|
888
|
+
}
|
889
|
+
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
890
|
+
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
891
|
+
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
892
|
+
);
|
893
|
+
return {
|
894
|
+
name: mainFieldName,
|
895
|
+
type: mainFieldType ?? "string"
|
896
|
+
};
|
897
|
+
};
|
898
|
+
const DEFAULT_SETTINGS = {
|
899
|
+
bulkable: false,
|
900
|
+
filterable: false,
|
901
|
+
searchable: false,
|
902
|
+
pagination: false,
|
903
|
+
defaultSortBy: "",
|
904
|
+
defaultSortOrder: "asc",
|
905
|
+
mainField: "id",
|
906
|
+
pageSize: 10
|
907
|
+
};
|
908
|
+
const useDocumentLayout = (model) => {
|
909
|
+
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
910
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
911
|
+
const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
781
912
|
const { toggleNotification } = strapiAdmin.useNotification();
|
782
913
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
914
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
783
915
|
const {
|
784
|
-
|
785
|
-
isLoading:
|
786
|
-
|
787
|
-
|
788
|
-
} =
|
789
|
-
const
|
916
|
+
data,
|
917
|
+
isLoading: isLoadingConfigs,
|
918
|
+
error,
|
919
|
+
isFetching: isFetchingConfigs
|
920
|
+
} = useGetContentTypeConfigurationQuery(model);
|
921
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
790
922
|
React__namespace.useEffect(() => {
|
791
923
|
if (error) {
|
792
924
|
toggleNotification({
|
@@ -794,54 +926,267 @@ const useDocument = (args, opts) => {
|
|
794
926
|
message: formatAPIError(error)
|
795
927
|
});
|
796
928
|
}
|
797
|
-
}, [
|
798
|
-
const
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
(document) => {
|
806
|
-
if (!validationSchema) {
|
807
|
-
throw new Error(
|
808
|
-
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
809
|
-
);
|
810
|
-
}
|
811
|
-
try {
|
812
|
-
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
813
|
-
return null;
|
814
|
-
} catch (error2) {
|
815
|
-
if (error2 instanceof yup.ValidationError) {
|
816
|
-
return strapiAdmin.getYupValidationErrors(error2);
|
817
|
-
}
|
818
|
-
throw error2;
|
819
|
-
}
|
929
|
+
}, [error, formatAPIError, toggleNotification]);
|
930
|
+
const editLayout = React__namespace.useMemo(
|
931
|
+
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
932
|
+
layout: [],
|
933
|
+
components: {},
|
934
|
+
metadatas: {},
|
935
|
+
options: {},
|
936
|
+
settings: DEFAULT_SETTINGS
|
820
937
|
},
|
821
|
-
[
|
938
|
+
[data, isLoading, schemas, schema, components]
|
939
|
+
);
|
940
|
+
const listLayout = React__namespace.useMemo(() => {
|
941
|
+
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
942
|
+
layout: [],
|
943
|
+
metadatas: {},
|
944
|
+
options: {},
|
945
|
+
settings: DEFAULT_SETTINGS
|
946
|
+
};
|
947
|
+
}, [data, isLoading, schemas, schema, components]);
|
948
|
+
const { layout: edit } = React__namespace.useMemo(
|
949
|
+
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
950
|
+
layout: editLayout,
|
951
|
+
query
|
952
|
+
}),
|
953
|
+
[editLayout, query, runHookWaterfall]
|
822
954
|
);
|
823
|
-
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
824
955
|
return {
|
825
|
-
|
826
|
-
document: data?.data,
|
827
|
-
meta: data?.meta,
|
956
|
+
error,
|
828
957
|
isLoading,
|
829
|
-
|
830
|
-
|
958
|
+
edit,
|
959
|
+
list: listLayout
|
831
960
|
};
|
832
961
|
};
|
833
|
-
const
|
834
|
-
const {
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
962
|
+
const useDocLayout = () => {
|
963
|
+
const { model } = useDoc();
|
964
|
+
return useDocumentLayout(model);
|
965
|
+
};
|
966
|
+
const formatEditLayout = (data, {
|
967
|
+
schemas,
|
968
|
+
schema,
|
969
|
+
components
|
970
|
+
}) => {
|
971
|
+
let currentPanelIndex = 0;
|
972
|
+
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
973
|
+
data.contentType.layouts.edit,
|
974
|
+
schema?.attributes,
|
975
|
+
data.contentType.metadatas,
|
976
|
+
{ configurations: data.components, schemas: components },
|
977
|
+
schemas
|
978
|
+
).reduce((panels, row) => {
|
979
|
+
if (row.some((field) => field.type === "dynamiczone")) {
|
980
|
+
panels.push([row]);
|
981
|
+
currentPanelIndex += 2;
|
982
|
+
} else {
|
983
|
+
if (!panels[currentPanelIndex]) {
|
984
|
+
panels.push([]);
|
985
|
+
}
|
986
|
+
panels[currentPanelIndex].push(row);
|
987
|
+
}
|
988
|
+
return panels;
|
989
|
+
}, []);
|
990
|
+
const componentEditAttributes = Object.entries(data.components).reduce(
|
991
|
+
(acc, [uid, configuration]) => {
|
992
|
+
acc[uid] = {
|
993
|
+
layout: convertEditLayoutToFieldLayouts(
|
994
|
+
configuration.layouts.edit,
|
995
|
+
components[uid].attributes,
|
996
|
+
configuration.metadatas,
|
997
|
+
{ configurations: data.components, schemas: components }
|
998
|
+
),
|
999
|
+
settings: {
|
1000
|
+
...configuration.settings,
|
1001
|
+
icon: components[uid].info.icon,
|
1002
|
+
displayName: components[uid].info.displayName
|
1003
|
+
}
|
1004
|
+
};
|
1005
|
+
return acc;
|
1006
|
+
},
|
1007
|
+
{}
|
1008
|
+
);
|
1009
|
+
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1010
|
+
(acc, [attribute, metadata]) => {
|
1011
|
+
return {
|
1012
|
+
...acc,
|
1013
|
+
[attribute]: metadata.edit
|
1014
|
+
};
|
1015
|
+
},
|
1016
|
+
{}
|
1017
|
+
);
|
1018
|
+
return {
|
1019
|
+
layout: panelledEditAttributes,
|
1020
|
+
components: componentEditAttributes,
|
1021
|
+
metadatas: editMetadatas,
|
1022
|
+
settings: {
|
1023
|
+
...data.contentType.settings,
|
1024
|
+
displayName: schema?.info.displayName
|
1025
|
+
},
|
1026
|
+
options: {
|
1027
|
+
...schema?.options,
|
1028
|
+
...schema?.pluginOptions,
|
1029
|
+
...data.contentType.options
|
1030
|
+
}
|
1031
|
+
};
|
1032
|
+
};
|
1033
|
+
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
1034
|
+
return rows.map(
|
1035
|
+
(row) => row.map((field) => {
|
1036
|
+
const attribute = attributes[field.name];
|
1037
|
+
if (!attribute) {
|
1038
|
+
return null;
|
1039
|
+
}
|
1040
|
+
const { edit: metadata } = metadatas[field.name];
|
1041
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1042
|
+
return {
|
1043
|
+
attribute,
|
1044
|
+
disabled: !metadata.editable,
|
1045
|
+
hint: metadata.description,
|
1046
|
+
label: metadata.label ?? "",
|
1047
|
+
name: field.name,
|
1048
|
+
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
1049
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1050
|
+
schemas,
|
1051
|
+
components: components?.schemas ?? {}
|
1052
|
+
}),
|
1053
|
+
placeholder: metadata.placeholder ?? "",
|
1054
|
+
required: attribute.required ?? false,
|
1055
|
+
size: field.size,
|
1056
|
+
unique: "unique" in attribute ? attribute.unique : false,
|
1057
|
+
visible: metadata.visible ?? true,
|
1058
|
+
type: attribute.type
|
1059
|
+
};
|
1060
|
+
}).filter((field) => field !== null)
|
1061
|
+
);
|
1062
|
+
};
|
1063
|
+
const formatListLayout = (data, {
|
1064
|
+
schemas,
|
1065
|
+
schema,
|
1066
|
+
components
|
1067
|
+
}) => {
|
1068
|
+
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1069
|
+
(acc, [attribute, metadata]) => {
|
1070
|
+
return {
|
1071
|
+
...acc,
|
1072
|
+
[attribute]: metadata.list
|
1073
|
+
};
|
1074
|
+
},
|
1075
|
+
{}
|
1076
|
+
);
|
1077
|
+
const listAttributes = convertListLayoutToFieldLayouts(
|
1078
|
+
data.contentType.layouts.list,
|
1079
|
+
schema?.attributes,
|
1080
|
+
listMetadatas,
|
1081
|
+
{ configurations: data.components, schemas: components },
|
1082
|
+
schemas
|
1083
|
+
);
|
1084
|
+
return {
|
1085
|
+
layout: listAttributes,
|
1086
|
+
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
1087
|
+
metadatas: listMetadatas,
|
1088
|
+
options: {
|
1089
|
+
...schema?.options,
|
1090
|
+
...schema?.pluginOptions,
|
1091
|
+
...data.contentType.options
|
1092
|
+
}
|
1093
|
+
};
|
1094
|
+
};
|
1095
|
+
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
1096
|
+
return columns.map((name) => {
|
1097
|
+
const attribute = attributes[name];
|
1098
|
+
if (!attribute) {
|
1099
|
+
return null;
|
1100
|
+
}
|
1101
|
+
const metadata = metadatas[name];
|
1102
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1103
|
+
return {
|
1104
|
+
attribute,
|
1105
|
+
label: metadata.label ?? "",
|
1106
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1107
|
+
schemas,
|
1108
|
+
components: components?.schemas ?? {}
|
1109
|
+
}),
|
1110
|
+
name,
|
1111
|
+
searchable: metadata.searchable ?? true,
|
1112
|
+
sortable: metadata.sortable ?? true
|
1113
|
+
};
|
1114
|
+
}).filter((field) => field !== null);
|
1115
|
+
};
|
1116
|
+
const useDocument = (args, opts) => {
|
1117
|
+
const { toggleNotification } = strapiAdmin.useNotification();
|
1118
|
+
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
1119
|
+
const {
|
1120
|
+
currentData: data,
|
1121
|
+
isLoading: isLoadingDocument,
|
1122
|
+
isFetching: isFetchingDocument,
|
1123
|
+
error
|
1124
|
+
} = useGetDocumentQuery(args, {
|
1125
|
+
...opts,
|
1126
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
1127
|
+
});
|
1128
|
+
const {
|
1129
|
+
components,
|
1130
|
+
schema,
|
1131
|
+
schemas,
|
1132
|
+
isLoading: isLoadingSchema
|
1133
|
+
} = useContentTypeSchema(args.model);
|
1134
|
+
React__namespace.useEffect(() => {
|
1135
|
+
if (error) {
|
1136
|
+
toggleNotification({
|
1137
|
+
type: "danger",
|
1138
|
+
message: formatAPIError(error)
|
1139
|
+
});
|
1140
|
+
}
|
1141
|
+
}, [toggleNotification, error, formatAPIError, args.collectionType]);
|
1142
|
+
const validationSchema = React__namespace.useMemo(() => {
|
1143
|
+
if (!schema) {
|
1144
|
+
return null;
|
1145
|
+
}
|
1146
|
+
return createYupSchema(schema.attributes, components);
|
1147
|
+
}, [schema, components]);
|
1148
|
+
const validate = React__namespace.useCallback(
|
1149
|
+
(document) => {
|
1150
|
+
if (!validationSchema) {
|
1151
|
+
throw new Error(
|
1152
|
+
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
1153
|
+
);
|
1154
|
+
}
|
1155
|
+
try {
|
1156
|
+
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
1157
|
+
return null;
|
1158
|
+
} catch (error2) {
|
1159
|
+
if (error2 instanceof yup.ValidationError) {
|
1160
|
+
return strapiAdmin.getYupValidationErrors(error2);
|
1161
|
+
}
|
1162
|
+
throw error2;
|
1163
|
+
}
|
1164
|
+
},
|
1165
|
+
[validationSchema]
|
1166
|
+
);
|
1167
|
+
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
1168
|
+
return {
|
1169
|
+
components,
|
1170
|
+
document: data?.data,
|
1171
|
+
meta: data?.meta,
|
1172
|
+
isLoading,
|
1173
|
+
schema,
|
1174
|
+
schemas,
|
1175
|
+
validate
|
1176
|
+
};
|
1177
|
+
};
|
1178
|
+
const useDoc = () => {
|
1179
|
+
const { id, slug, collectionType, origin } = reactRouterDom.useParams();
|
1180
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
1181
|
+
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
1182
|
+
if (!collectionType) {
|
1183
|
+
throw new Error("Could not find collectionType in url params");
|
1184
|
+
}
|
1185
|
+
if (!slug) {
|
1186
|
+
throw new Error("Could not find model in url params");
|
1187
|
+
}
|
1188
|
+
return {
|
1189
|
+
collectionType,
|
845
1190
|
model: slug,
|
846
1191
|
id: origin || id === "create" ? void 0 : id,
|
847
1192
|
...useDocument(
|
@@ -852,6 +1197,45 @@ const useDoc = () => {
|
|
852
1197
|
)
|
853
1198
|
};
|
854
1199
|
};
|
1200
|
+
const useContentManagerContext = () => {
|
1201
|
+
const {
|
1202
|
+
collectionType,
|
1203
|
+
model,
|
1204
|
+
id,
|
1205
|
+
components,
|
1206
|
+
isLoading: isLoadingDoc,
|
1207
|
+
schema,
|
1208
|
+
schemas
|
1209
|
+
} = useDoc();
|
1210
|
+
const layout = useDocumentLayout(model);
|
1211
|
+
const form = strapiAdmin.useForm("useContentManagerContext", (state) => state);
|
1212
|
+
const isSingleType = collectionType === SINGLE_TYPES;
|
1213
|
+
const slug = model;
|
1214
|
+
const isCreatingEntry = id === "create";
|
1215
|
+
useContentTypeSchema();
|
1216
|
+
const isLoading = isLoadingDoc || layout.isLoading;
|
1217
|
+
const error = layout.error;
|
1218
|
+
return {
|
1219
|
+
error,
|
1220
|
+
isLoading,
|
1221
|
+
// Base metadata
|
1222
|
+
model,
|
1223
|
+
collectionType,
|
1224
|
+
id,
|
1225
|
+
slug,
|
1226
|
+
isCreatingEntry,
|
1227
|
+
isSingleType,
|
1228
|
+
hasDraftAndPublish: schema?.options?.draftAndPublish ?? false,
|
1229
|
+
// All schema infos
|
1230
|
+
components,
|
1231
|
+
contentType: schema,
|
1232
|
+
contentTypes: schemas,
|
1233
|
+
// Form state
|
1234
|
+
form,
|
1235
|
+
// layout infos
|
1236
|
+
layout
|
1237
|
+
};
|
1238
|
+
};
|
855
1239
|
const prefixPluginTranslations = (trad, pluginId) => {
|
856
1240
|
if (!pluginId) {
|
857
1241
|
throw new TypeError("pluginId can't be empty");
|
@@ -871,6 +1255,8 @@ const useDocumentActions = () => {
|
|
871
1255
|
const { formatMessage } = reactIntl.useIntl();
|
872
1256
|
const { trackUsage } = strapiAdmin.useTracking();
|
873
1257
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
1258
|
+
const navigate = reactRouterDom.useNavigate();
|
1259
|
+
const setCurrentStep = strapiAdmin.useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
874
1260
|
const [deleteDocument] = useDeleteDocumentMutation();
|
875
1261
|
const _delete = React__namespace.useCallback(
|
876
1262
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -1185,6 +1571,7 @@ const useDocumentActions = () => {
|
|
1185
1571
|
defaultMessage: "Saved document"
|
1186
1572
|
})
|
1187
1573
|
});
|
1574
|
+
setCurrentStep("contentManager.success");
|
1188
1575
|
return res.data;
|
1189
1576
|
} catch (err) {
|
1190
1577
|
toggleNotification({
|
@@ -1206,7 +1593,6 @@ const useDocumentActions = () => {
|
|
1206
1593
|
sourceId
|
1207
1594
|
});
|
1208
1595
|
if ("error" in res) {
|
1209
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1210
1596
|
return { error: res.error };
|
1211
1597
|
}
|
1212
1598
|
toggleNotification({
|
@@ -1225,7 +1611,7 @@ const useDocumentActions = () => {
|
|
1225
1611
|
throw err;
|
1226
1612
|
}
|
1227
1613
|
},
|
1228
|
-
[autoCloneDocument,
|
1614
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1229
1615
|
);
|
1230
1616
|
const [cloneDocument] = useCloneDocumentMutation();
|
1231
1617
|
const clone = React__namespace.useCallback(
|
@@ -1251,6 +1637,7 @@ const useDocumentActions = () => {
|
|
1251
1637
|
defaultMessage: "Cloned document"
|
1252
1638
|
})
|
1253
1639
|
});
|
1640
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1254
1641
|
return res.data;
|
1255
1642
|
} catch (err) {
|
1256
1643
|
toggleNotification({
|
@@ -1261,7 +1648,7 @@ const useDocumentActions = () => {
|
|
1261
1648
|
throw err;
|
1262
1649
|
}
|
1263
1650
|
},
|
1264
|
-
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
|
1651
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1265
1652
|
);
|
1266
1653
|
const [getDoc] = useLazyGetDocumentQuery();
|
1267
1654
|
const getDocument = React__namespace.useCallback(
|
@@ -1287,7 +1674,7 @@ const useDocumentActions = () => {
|
|
1287
1674
|
};
|
1288
1675
|
};
|
1289
1676
|
const ProtectedHistoryPage = React.lazy(
|
1290
|
-
() => Promise.resolve().then(() => require("./History-
|
1677
|
+
() => Promise.resolve().then(() => require("./History-CWcM9HnW.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1291
1678
|
);
|
1292
1679
|
const routes$1 = [
|
1293
1680
|
{
|
@@ -1300,31 +1687,31 @@ const routes$1 = [
|
|
1300
1687
|
}
|
1301
1688
|
];
|
1302
1689
|
const ProtectedEditViewPage = React.lazy(
|
1303
|
-
() => Promise.resolve().then(() => require("./EditViewPage-
|
1690
|
+
() => Promise.resolve().then(() => require("./EditViewPage-Co2IKQZH.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1304
1691
|
);
|
1305
1692
|
const ProtectedListViewPage = React.lazy(
|
1306
|
-
() => Promise.resolve().then(() => require("./ListViewPage-
|
1693
|
+
() => Promise.resolve().then(() => require("./ListViewPage-BBAC9aPu.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1307
1694
|
);
|
1308
1695
|
const ProtectedListConfiguration = React.lazy(
|
1309
|
-
() => Promise.resolve().then(() => require("./ListConfigurationPage-
|
1696
|
+
() => Promise.resolve().then(() => require("./ListConfigurationPage-DGzoQD_I.js")).then((mod) => ({
|
1310
1697
|
default: mod.ProtectedListConfiguration
|
1311
1698
|
}))
|
1312
1699
|
);
|
1313
1700
|
const ProtectedEditConfigurationPage = React.lazy(
|
1314
|
-
() => Promise.resolve().then(() => require("./EditConfigurationPage-
|
1701
|
+
() => Promise.resolve().then(() => require("./EditConfigurationPage-ZN3s568V.js")).then((mod) => ({
|
1315
1702
|
default: mod.ProtectedEditConfigurationPage
|
1316
1703
|
}))
|
1317
1704
|
);
|
1318
1705
|
const ProtectedComponentConfigurationPage = React.lazy(
|
1319
|
-
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-
|
1706
|
+
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-_6osrv39.js")).then((mod) => ({
|
1320
1707
|
default: mod.ProtectedComponentConfigurationPage
|
1321
1708
|
}))
|
1322
1709
|
);
|
1323
1710
|
const NoPermissions = React.lazy(
|
1324
|
-
() => Promise.resolve().then(() => require("./NoPermissionsPage-
|
1711
|
+
() => Promise.resolve().then(() => require("./NoPermissionsPage-D2iWw-sn.js")).then((mod) => ({ default: mod.NoPermissions }))
|
1325
1712
|
);
|
1326
1713
|
const NoContentType = React.lazy(
|
1327
|
-
() => Promise.resolve().then(() => require("./NoContentTypePage-
|
1714
|
+
() => Promise.resolve().then(() => require("./NoContentTypePage-CwVDx_YC.js")).then((mod) => ({ default: mod.NoContentType }))
|
1328
1715
|
);
|
1329
1716
|
const CollectionTypePages = () => {
|
1330
1717
|
const { collectionType } = reactRouterDom.useParams();
|
@@ -1438,12 +1825,14 @@ const DocumentActionButton = (action) => {
|
|
1438
1825
|
/* @__PURE__ */ jsxRuntime.jsx(
|
1439
1826
|
designSystem.Button,
|
1440
1827
|
{
|
1441
|
-
flex:
|
1828
|
+
flex: "auto",
|
1442
1829
|
startIcon: action.icon,
|
1443
1830
|
disabled: action.disabled,
|
1444
1831
|
onClick: handleClick(action),
|
1445
1832
|
justifyContent: "center",
|
1446
1833
|
variant: action.variant || "default",
|
1834
|
+
paddingTop: "7px",
|
1835
|
+
paddingBottom: "7px",
|
1447
1836
|
children: action.label
|
1448
1837
|
}
|
1449
1838
|
),
|
@@ -1451,7 +1840,7 @@ const DocumentActionButton = (action) => {
|
|
1451
1840
|
DocumentActionConfirmDialog,
|
1452
1841
|
{
|
1453
1842
|
...action.dialog,
|
1454
|
-
variant: action.variant,
|
1843
|
+
variant: action.dialog?.variant ?? action.variant,
|
1455
1844
|
isOpen: dialogId === action.id,
|
1456
1845
|
onClose: handleClose
|
1457
1846
|
}
|
@@ -1508,9 +1897,9 @@ const DocumentActionsMenu = ({
|
|
1508
1897
|
disabled: isDisabled,
|
1509
1898
|
size: "S",
|
1510
1899
|
endIcon: null,
|
1511
|
-
paddingTop: "
|
1512
|
-
paddingLeft: "
|
1513
|
-
paddingRight: "
|
1900
|
+
paddingTop: "4px",
|
1901
|
+
paddingLeft: "7px",
|
1902
|
+
paddingRight: "7px",
|
1514
1903
|
variant,
|
1515
1904
|
children: [
|
1516
1905
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.More, { "aria-hidden": true, focusable: false }),
|
@@ -1521,7 +1910,7 @@ const DocumentActionsMenu = ({
|
|
1521
1910
|
]
|
1522
1911
|
}
|
1523
1912
|
),
|
1524
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, {
|
1913
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1525
1914
|
actions2.map((action) => {
|
1526
1915
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
1527
1916
|
designSystem.Menu.Item,
|
@@ -1530,10 +1919,25 @@ const DocumentActionsMenu = ({
|
|
1530
1919
|
onSelect: handleClick(action),
|
1531
1920
|
display: "block",
|
1532
1921
|
children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", gap: 4, children: [
|
1533
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1922
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
1923
|
+
designSystem.Flex,
|
1924
|
+
{
|
1925
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1926
|
+
gap: 2,
|
1927
|
+
tag: "span",
|
1928
|
+
children: [
|
1929
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
1930
|
+
designSystem.Flex,
|
1931
|
+
{
|
1932
|
+
tag: "span",
|
1933
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1934
|
+
children: action.icon
|
1935
|
+
}
|
1936
|
+
),
|
1937
|
+
action.label
|
1938
|
+
]
|
1939
|
+
}
|
1940
|
+
),
|
1537
1941
|
action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsxRuntime.jsx(
|
1538
1942
|
designSystem.Flex,
|
1539
1943
|
{
|
@@ -1630,11 +2034,11 @@ const DocumentActionConfirmDialog = ({
|
|
1630
2034
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
1631
2035
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: content }),
|
1632
2036
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
|
1633
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", children: formatMessage({
|
2037
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", fullWidth: true, children: formatMessage({
|
1634
2038
|
id: "app.components.Button.cancel",
|
1635
2039
|
defaultMessage: "Cancel"
|
1636
2040
|
}) }) }),
|
1637
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, children: formatMessage({
|
2041
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
|
1638
2042
|
id: "app.components.Button.confirm",
|
1639
2043
|
defaultMessage: "Confirm"
|
1640
2044
|
}) })
|
@@ -1673,13 +2077,17 @@ const PublishAction$1 = ({
|
|
1673
2077
|
const navigate = reactRouterDom.useNavigate();
|
1674
2078
|
const { toggleNotification } = strapiAdmin.useNotification();
|
1675
2079
|
const { _unstableFormatValidationErrors: formatValidationErrors } = strapiAdmin.useAPIErrorHandler();
|
2080
|
+
const isListView = reactRouterDom.useMatch(LIST_PATH) !== null;
|
1676
2081
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
1677
2082
|
const { formatMessage } = reactIntl.useIntl();
|
1678
|
-
const { canPublish
|
1679
|
-
"PublishAction",
|
1680
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1681
|
-
);
|
2083
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1682
2084
|
const { publish } = useDocumentActions();
|
2085
|
+
const [
|
2086
|
+
countDraftRelations,
|
2087
|
+
{ isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
|
2088
|
+
] = useLazyGetDraftRelationCountQuery();
|
2089
|
+
const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React__namespace.useState(0);
|
2090
|
+
const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React__namespace.useState(0);
|
1683
2091
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1684
2092
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
1685
2093
|
const modified = strapiAdmin.useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
@@ -1688,62 +2096,142 @@ const PublishAction$1 = ({
|
|
1688
2096
|
const validate = strapiAdmin.useForm("PublishAction", (state) => state.validate);
|
1689
2097
|
const setErrors = strapiAdmin.useForm("PublishAction", (state) => state.setErrors);
|
1690
2098
|
const formValues = strapiAdmin.useForm("PublishAction", ({ values }) => values);
|
1691
|
-
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
2099
|
+
React__namespace.useEffect(() => {
|
2100
|
+
if (isErrorDraftRelations) {
|
2101
|
+
toggleNotification({
|
2102
|
+
type: "danger",
|
2103
|
+
message: formatMessage({
|
2104
|
+
id: getTranslation("error.records.fetch-draft-relatons"),
|
2105
|
+
defaultMessage: "An error occurred while fetching draft relations on this document."
|
2106
|
+
})
|
2107
|
+
});
|
2108
|
+
}
|
2109
|
+
}, [isErrorDraftRelations, toggleNotification, formatMessage]);
|
2110
|
+
React__namespace.useEffect(() => {
|
2111
|
+
const localDraftRelations = /* @__PURE__ */ new Set();
|
2112
|
+
const extractDraftRelations = (data) => {
|
2113
|
+
const relations = data.connect || [];
|
2114
|
+
relations.forEach((relation) => {
|
2115
|
+
if (relation.status === "draft") {
|
2116
|
+
localDraftRelations.add(relation.id);
|
2117
|
+
}
|
2118
|
+
});
|
2119
|
+
};
|
2120
|
+
const traverseAndExtract = (data) => {
|
2121
|
+
Object.entries(data).forEach(([key, value]) => {
|
2122
|
+
if (key === "connect" && Array.isArray(value)) {
|
2123
|
+
extractDraftRelations({ connect: value });
|
2124
|
+
} else if (typeof value === "object" && value !== null) {
|
2125
|
+
traverseAndExtract(value);
|
2126
|
+
}
|
2127
|
+
});
|
2128
|
+
};
|
2129
|
+
if (!documentId || modified) {
|
2130
|
+
traverseAndExtract(formValues);
|
2131
|
+
setLocalCountOfDraftRelations(localDraftRelations.size);
|
2132
|
+
}
|
2133
|
+
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
2134
|
+
React__namespace.useEffect(() => {
|
2135
|
+
if (!document || !document.documentId || isListView) {
|
2136
|
+
return;
|
2137
|
+
}
|
2138
|
+
const fetchDraftRelationsCount = async () => {
|
2139
|
+
const { data, error } = await countDraftRelations({
|
2140
|
+
collectionType,
|
2141
|
+
model,
|
2142
|
+
documentId,
|
2143
|
+
params
|
2144
|
+
});
|
2145
|
+
if (error) {
|
2146
|
+
throw error;
|
2147
|
+
}
|
2148
|
+
if (data) {
|
2149
|
+
setServerCountOfDraftRelations(data.data);
|
2150
|
+
}
|
2151
|
+
};
|
2152
|
+
fetchDraftRelationsCount();
|
2153
|
+
}, [isListView, document, documentId, countDraftRelations, collectionType, model, params]);
|
2154
|
+
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
2155
|
+
if (!schema?.options?.draftAndPublish) {
|
2156
|
+
return null;
|
2157
|
+
}
|
2158
|
+
const performPublish = async () => {
|
2159
|
+
setSubmitting(true);
|
2160
|
+
try {
|
2161
|
+
const { errors } = await validate();
|
2162
|
+
if (errors) {
|
2163
|
+
toggleNotification({
|
2164
|
+
type: "danger",
|
2165
|
+
message: formatMessage({
|
2166
|
+
id: "content-manager.validation.error",
|
2167
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2168
|
+
})
|
2169
|
+
});
|
2170
|
+
return;
|
2171
|
+
}
|
2172
|
+
const res = await publish(
|
2173
|
+
{
|
2174
|
+
collectionType,
|
2175
|
+
model,
|
2176
|
+
documentId,
|
2177
|
+
params
|
2178
|
+
},
|
2179
|
+
formValues
|
2180
|
+
);
|
2181
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
2182
|
+
navigate({
|
2183
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
2184
|
+
search: rawQuery
|
2185
|
+
});
|
2186
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2187
|
+
setErrors(formatValidationErrors(res.error));
|
2188
|
+
}
|
2189
|
+
} finally {
|
2190
|
+
setSubmitting(false);
|
2191
|
+
}
|
2192
|
+
};
|
2193
|
+
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
2194
|
+
const enableDraftRelationsCount = false;
|
2195
|
+
const hasDraftRelations = enableDraftRelationsCount;
|
2196
|
+
return {
|
2197
|
+
/**
|
2198
|
+
* Disabled when:
|
2199
|
+
* - currently if you're cloning a document we don't support publish & clone at the same time.
|
2200
|
+
* - the form is submitting
|
2201
|
+
* - the active tab is the published tab
|
2202
|
+
* - the document is already published & not modified
|
2203
|
+
* - the document is being created & not modified
|
2204
|
+
* - the user doesn't have the permission to publish
|
2205
|
+
*/
|
2206
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
1708
2207
|
label: formatMessage({
|
1709
2208
|
id: "app.utils.publish",
|
1710
2209
|
defaultMessage: "Publish"
|
1711
2210
|
}),
|
1712
2211
|
onClick: async () => {
|
1713
|
-
|
1714
|
-
|
1715
|
-
|
1716
|
-
|
1717
|
-
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
|
1726
|
-
|
1727
|
-
|
1728
|
-
|
1729
|
-
|
1730
|
-
documentId,
|
1731
|
-
params
|
1732
|
-
},
|
1733
|
-
formValues
|
1734
|
-
);
|
1735
|
-
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1736
|
-
navigate({
|
1737
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1738
|
-
search: rawQuery
|
1739
|
-
});
|
1740
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1741
|
-
setErrors(formatValidationErrors(res.error));
|
2212
|
+
await performPublish();
|
2213
|
+
},
|
2214
|
+
dialog: hasDraftRelations ? {
|
2215
|
+
type: "dialog",
|
2216
|
+
variant: "danger",
|
2217
|
+
footer: null,
|
2218
|
+
title: formatMessage({
|
2219
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
|
2220
|
+
defaultMessage: "Confirmation"
|
2221
|
+
}),
|
2222
|
+
content: formatMessage(
|
2223
|
+
{
|
2224
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
2225
|
+
defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
|
2226
|
+
},
|
2227
|
+
{
|
2228
|
+
count: totalDraftRelations
|
1742
2229
|
}
|
1743
|
-
|
1744
|
-
|
2230
|
+
),
|
2231
|
+
onConfirm: async () => {
|
2232
|
+
await performPublish();
|
1745
2233
|
}
|
1746
|
-
}
|
2234
|
+
} : void 0
|
1747
2235
|
};
|
1748
2236
|
};
|
1749
2237
|
PublishAction$1.type = "publish";
|
@@ -1759,10 +2247,6 @@ const UpdateAction = ({
|
|
1759
2247
|
const cloneMatch = reactRouterDom.useMatch(CLONE_PATH);
|
1760
2248
|
const isCloning = cloneMatch !== null;
|
1761
2249
|
const { formatMessage } = reactIntl.useIntl();
|
1762
|
-
const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1763
|
-
canCreate: canCreate2,
|
1764
|
-
canUpdate: canUpdate2
|
1765
|
-
}));
|
1766
2250
|
const { create, update, clone } = useDocumentActions();
|
1767
2251
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1768
2252
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
@@ -1779,10 +2263,8 @@ const UpdateAction = ({
|
|
1779
2263
|
* - the form is submitting
|
1780
2264
|
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
1781
2265
|
* - the active tab is the published tab
|
1782
|
-
* - the user doesn't have the permission to create a new document
|
1783
|
-
* - the user doesn't have the permission to update the document
|
1784
2266
|
*/
|
1785
|
-
disabled: isSubmitting || !modified && !isCloning || activeTab === "published"
|
2267
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1786
2268
|
label: formatMessage({
|
1787
2269
|
id: "content-manager.containers.Edit.save",
|
1788
2270
|
defaultMessage: "Save"
|
@@ -1790,16 +2272,18 @@ const UpdateAction = ({
|
|
1790
2272
|
onClick: async () => {
|
1791
2273
|
setSubmitting(true);
|
1792
2274
|
try {
|
1793
|
-
|
1794
|
-
|
1795
|
-
|
1796
|
-
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
1800
|
-
|
1801
|
-
|
1802
|
-
|
2275
|
+
if (activeTab !== "draft") {
|
2276
|
+
const { errors } = await validate();
|
2277
|
+
if (errors) {
|
2278
|
+
toggleNotification({
|
2279
|
+
type: "danger",
|
2280
|
+
message: formatMessage({
|
2281
|
+
id: "content-manager.validation.error",
|
2282
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2283
|
+
})
|
2284
|
+
});
|
2285
|
+
return;
|
2286
|
+
}
|
1803
2287
|
}
|
1804
2288
|
if (isCloning) {
|
1805
2289
|
const res = await clone(
|
@@ -1811,10 +2295,13 @@ const UpdateAction = ({
|
|
1811
2295
|
document
|
1812
2296
|
);
|
1813
2297
|
if ("data" in res) {
|
1814
|
-
navigate(
|
1815
|
-
|
1816
|
-
|
1817
|
-
|
2298
|
+
navigate(
|
2299
|
+
{
|
2300
|
+
pathname: `../${res.data.documentId}`,
|
2301
|
+
search: rawQuery
|
2302
|
+
},
|
2303
|
+
{ relative: "path" }
|
2304
|
+
);
|
1818
2305
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1819
2306
|
setErrors(formatValidationErrors(res.error));
|
1820
2307
|
}
|
@@ -1842,10 +2329,13 @@ const UpdateAction = ({
|
|
1842
2329
|
document
|
1843
2330
|
);
|
1844
2331
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1845
|
-
navigate(
|
1846
|
-
|
1847
|
-
|
1848
|
-
|
2332
|
+
navigate(
|
2333
|
+
{
|
2334
|
+
pathname: `../${res.data.documentId}`,
|
2335
|
+
search: rawQuery
|
2336
|
+
},
|
2337
|
+
{ replace: true, relative: "path" }
|
2338
|
+
);
|
1849
2339
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1850
2340
|
setErrors(formatValidationErrors(res.error));
|
1851
2341
|
}
|
@@ -1889,7 +2379,7 @@ const UnpublishAction$1 = ({
|
|
1889
2379
|
id: "app.utils.unpublish",
|
1890
2380
|
defaultMessage: "Unpublish"
|
1891
2381
|
}),
|
1892
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2382
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Cross, {}),
|
1893
2383
|
onClick: async () => {
|
1894
2384
|
if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
|
1895
2385
|
if (!documentId) {
|
@@ -2001,7 +2491,7 @@ const DiscardAction = ({
|
|
2001
2491
|
id: "content-manager.actions.discard.label",
|
2002
2492
|
defaultMessage: "Discard changes"
|
2003
2493
|
}),
|
2004
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2494
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Cross, {}),
|
2005
2495
|
position: ["panel", "table-row"],
|
2006
2496
|
variant: "danger",
|
2007
2497
|
dialog: {
|
@@ -2029,11 +2519,6 @@ const DiscardAction = ({
|
|
2029
2519
|
};
|
2030
2520
|
};
|
2031
2521
|
DiscardAction.type = "discard";
|
2032
|
-
const StyledCrossCircle = styledComponents.styled(Icons.CrossCircle)`
|
2033
|
-
path {
|
2034
|
-
fill: currentColor;
|
2035
|
-
}
|
2036
|
-
`;
|
2037
2522
|
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2038
2523
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2039
2524
|
const RelativeTime = React__namespace.forwardRef(
|
@@ -2081,7 +2566,7 @@ const getDisplayName = ({
|
|
2081
2566
|
};
|
2082
2567
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2083
2568
|
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2084
|
-
const statusVariant = status === "draft" ? "
|
2569
|
+
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2085
2570
|
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: capitalise(status) }) });
|
2086
2571
|
};
|
2087
2572
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
@@ -2091,23 +2576,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
|
2091
2576
|
id: "content-manager.containers.edit.title.new",
|
2092
2577
|
defaultMessage: "Create an entry"
|
2093
2578
|
}) : documentTitle;
|
2094
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop:
|
2579
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2095
2580
|
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.BackButton, {}),
|
2096
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
2097
|
-
designSystem.
|
2098
|
-
{
|
2099
|
-
|
2100
|
-
|
2101
|
-
paddingTop: 1,
|
2102
|
-
gap: "80px",
|
2103
|
-
alignItems: "flex-start",
|
2104
|
-
children: [
|
2105
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
|
2106
|
-
/* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
|
2107
|
-
]
|
2108
|
-
}
|
2109
|
-
),
|
2110
|
-
status ? /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: isCloning ? "draft" : status }) : null
|
2581
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2582
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
|
2583
|
+
/* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
|
2584
|
+
] }),
|
2585
|
+
status ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 1, children: /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
|
2111
2586
|
] });
|
2112
2587
|
};
|
2113
2588
|
const HeaderToolbar = () => {
|
@@ -2274,8 +2749,22 @@ const Information = ({ activeTab }) => {
|
|
2274
2749
|
);
|
2275
2750
|
};
|
2276
2751
|
const HeaderActions = ({ actions: actions2 }) => {
|
2277
|
-
|
2278
|
-
|
2752
|
+
const [dialogId, setDialogId] = React__namespace.useState(null);
|
2753
|
+
const handleClick = (action) => async (e) => {
|
2754
|
+
if (!("options" in action)) {
|
2755
|
+
const { onClick = () => false, dialog, id } = action;
|
2756
|
+
const muteDialog = await onClick(e);
|
2757
|
+
if (dialog && !muteDialog) {
|
2758
|
+
e.preventDefault();
|
2759
|
+
setDialogId(id);
|
2760
|
+
}
|
2761
|
+
}
|
2762
|
+
};
|
2763
|
+
const handleClose = () => {
|
2764
|
+
setDialogId(null);
|
2765
|
+
};
|
2766
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 1, children: actions2.map((action) => {
|
2767
|
+
if (action.options) {
|
2279
2768
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
2280
2769
|
designSystem.SingleSelect,
|
2281
2770
|
{
|
@@ -2289,10 +2778,49 @@ const HeaderActions = ({ actions: actions2 }) => {
|
|
2289
2778
|
action.id
|
2290
2779
|
);
|
2291
2780
|
} else {
|
2292
|
-
|
2781
|
+
if (action.type === "icon") {
|
2782
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
|
2783
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
2784
|
+
designSystem.IconButton,
|
2785
|
+
{
|
2786
|
+
disabled: action.disabled,
|
2787
|
+
label: action.label,
|
2788
|
+
size: "S",
|
2789
|
+
onClick: handleClick(action),
|
2790
|
+
children: action.icon
|
2791
|
+
}
|
2792
|
+
),
|
2793
|
+
action.dialog ? /* @__PURE__ */ jsxRuntime.jsx(
|
2794
|
+
HeaderActionDialog,
|
2795
|
+
{
|
2796
|
+
...action.dialog,
|
2797
|
+
isOpen: dialogId === action.id,
|
2798
|
+
onClose: handleClose
|
2799
|
+
}
|
2800
|
+
) : null
|
2801
|
+
] }, action.id);
|
2802
|
+
}
|
2293
2803
|
}
|
2294
2804
|
}) });
|
2295
2805
|
};
|
2806
|
+
const HeaderActionDialog = ({
|
2807
|
+
onClose,
|
2808
|
+
onCancel,
|
2809
|
+
title,
|
2810
|
+
content: Content,
|
2811
|
+
isOpen
|
2812
|
+
}) => {
|
2813
|
+
const handleClose = async () => {
|
2814
|
+
if (onCancel) {
|
2815
|
+
await onCancel();
|
2816
|
+
}
|
2817
|
+
onClose();
|
2818
|
+
};
|
2819
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
2820
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
2821
|
+
typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : Content
|
2822
|
+
] }) });
|
2823
|
+
};
|
2296
2824
|
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
2297
2825
|
const navigate = reactRouterDom.useNavigate();
|
2298
2826
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2333,12 +2861,16 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2333
2861
|
const { delete: deleteAction } = useDocumentActions();
|
2334
2862
|
const { toggleNotification } = strapiAdmin.useNotification();
|
2335
2863
|
const setSubmitting = strapiAdmin.useForm("DeleteAction", (state) => state.setSubmitting);
|
2864
|
+
const isLocalized = document?.locale != null;
|
2336
2865
|
return {
|
2337
2866
|
disabled: !canDelete || !document,
|
2338
|
-
label: formatMessage(
|
2339
|
-
|
2340
|
-
|
2341
|
-
|
2867
|
+
label: formatMessage(
|
2868
|
+
{
|
2869
|
+
id: "content-manager.actions.delete.label",
|
2870
|
+
defaultMessage: "Delete entry{isLocalized, select, true { (all locales)} other {}}"
|
2871
|
+
},
|
2872
|
+
{ isLocalized }
|
2873
|
+
),
|
2342
2874
|
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {}),
|
2343
2875
|
dialog: {
|
2344
2876
|
type: "dialog",
|
@@ -2372,425 +2904,123 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2372
2904
|
return;
|
2373
2905
|
}
|
2374
2906
|
const res = await deleteAction({
|
2375
|
-
documentId,
|
2376
|
-
model,
|
2377
|
-
collectionType,
|
2378
|
-
params: {
|
2379
|
-
locale: "*"
|
2380
|
-
}
|
2381
|
-
});
|
2382
|
-
if (!("error" in res)) {
|
2383
|
-
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
2384
|
-
}
|
2385
|
-
} finally {
|
2386
|
-
if (!listViewPathMatch) {
|
2387
|
-
setSubmitting(false);
|
2388
|
-
}
|
2389
|
-
}
|
2390
|
-
}
|
2391
|
-
},
|
2392
|
-
variant: "danger",
|
2393
|
-
position: ["header", "table-row"]
|
2394
|
-
};
|
2395
|
-
};
|
2396
|
-
DeleteAction$1.type = "delete";
|
2397
|
-
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2398
|
-
const Panels = () => {
|
2399
|
-
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2400
|
-
const [
|
2401
|
-
{
|
2402
|
-
query: { status }
|
2403
|
-
}
|
2404
|
-
] = strapiAdmin.useQueryParams({
|
2405
|
-
status: "draft"
|
2406
|
-
});
|
2407
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2408
|
-
const plugins = strapiAdmin.useStrapiApp("Panels", (state) => state.plugins);
|
2409
|
-
const props = {
|
2410
|
-
activeTab: status,
|
2411
|
-
model,
|
2412
|
-
documentId: id,
|
2413
|
-
document: isCloning ? void 0 : document,
|
2414
|
-
meta: isCloning ? void 0 : meta,
|
2415
|
-
collectionType
|
2416
|
-
};
|
2417
|
-
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
|
2418
|
-
strapiAdmin.DescriptionComponentRenderer,
|
2419
|
-
{
|
2420
|
-
props,
|
2421
|
-
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2422
|
-
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsxRuntime.jsx(Panel, { ...description, children: content }, id2))
|
2423
|
-
}
|
2424
|
-
) });
|
2425
|
-
};
|
2426
|
-
const ActionsPanel = () => {
|
2427
|
-
const { formatMessage } = reactIntl.useIntl();
|
2428
|
-
return {
|
2429
|
-
title: formatMessage({
|
2430
|
-
id: "content-manager.containers.edit.panels.default.title",
|
2431
|
-
defaultMessage: "Document"
|
2432
|
-
}),
|
2433
|
-
content: /* @__PURE__ */ jsxRuntime.jsx(ActionsPanelContent, {})
|
2434
|
-
};
|
2435
|
-
};
|
2436
|
-
ActionsPanel.type = "actions";
|
2437
|
-
const ActionsPanelContent = () => {
|
2438
|
-
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2439
|
-
const [
|
2440
|
-
{
|
2441
|
-
query: { status = "draft" }
|
2442
|
-
}
|
2443
|
-
] = strapiAdmin.useQueryParams();
|
2444
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2445
|
-
const plugins = strapiAdmin.useStrapiApp("ActionsPanel", (state) => state.plugins);
|
2446
|
-
const props = {
|
2447
|
-
activeTab: status,
|
2448
|
-
model,
|
2449
|
-
documentId: id,
|
2450
|
-
document: isCloning ? void 0 : document,
|
2451
|
-
meta: isCloning ? void 0 : meta,
|
2452
|
-
collectionType
|
2453
|
-
};
|
2454
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, width: "100%", children: [
|
2455
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
2456
|
-
strapiAdmin.DescriptionComponentRenderer,
|
2457
|
-
{
|
2458
|
-
props,
|
2459
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2460
|
-
children: (actions2) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActions, { actions: actions2 })
|
2461
|
-
}
|
2462
|
-
),
|
2463
|
-
/* @__PURE__ */ jsxRuntime.jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
2464
|
-
] });
|
2465
|
-
};
|
2466
|
-
const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
2467
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
2468
|
-
designSystem.Flex,
|
2469
|
-
{
|
2470
|
-
ref,
|
2471
|
-
tag: "aside",
|
2472
|
-
"aria-labelledby": "additional-information",
|
2473
|
-
background: "neutral0",
|
2474
|
-
borderColor: "neutral150",
|
2475
|
-
hasRadius: true,
|
2476
|
-
paddingBottom: 4,
|
2477
|
-
paddingLeft: 4,
|
2478
|
-
paddingRight: 4,
|
2479
|
-
paddingTop: 4,
|
2480
|
-
shadow: "tableShadow",
|
2481
|
-
gap: 3,
|
2482
|
-
direction: "column",
|
2483
|
-
justifyContent: "stretch",
|
2484
|
-
alignItems: "flex-start",
|
2485
|
-
children: [
|
2486
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2487
|
-
children
|
2488
|
-
]
|
2489
|
-
}
|
2490
|
-
);
|
2491
|
-
});
|
2492
|
-
const HOOKS = {
|
2493
|
-
/**
|
2494
|
-
* Hook that allows to mutate the displayed headers of the list view table
|
2495
|
-
* @constant
|
2496
|
-
* @type {string}
|
2497
|
-
*/
|
2498
|
-
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2499
|
-
/**
|
2500
|
-
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2501
|
-
* @constant
|
2502
|
-
* @type {string}
|
2503
|
-
*/
|
2504
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2505
|
-
/**
|
2506
|
-
* Hook that allows to mutate the CM's edit view layout
|
2507
|
-
* @constant
|
2508
|
-
* @type {string}
|
2509
|
-
*/
|
2510
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2511
|
-
/**
|
2512
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
2513
|
-
* @constant
|
2514
|
-
* @type {string}
|
2515
|
-
*/
|
2516
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2517
|
-
};
|
2518
|
-
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2519
|
-
endpoints: (builder) => ({
|
2520
|
-
getContentTypeConfiguration: builder.query({
|
2521
|
-
query: (uid) => ({
|
2522
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2523
|
-
method: "GET"
|
2524
|
-
}),
|
2525
|
-
transformResponse: (response) => response.data,
|
2526
|
-
providesTags: (_result, _error, uid) => [
|
2527
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2528
|
-
{ type: "ContentTypeSettings", id: "LIST" }
|
2529
|
-
]
|
2530
|
-
}),
|
2531
|
-
getAllContentTypeSettings: builder.query({
|
2532
|
-
query: () => "/content-manager/content-types-settings",
|
2533
|
-
transformResponse: (response) => response.data,
|
2534
|
-
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2535
|
-
}),
|
2536
|
-
updateContentTypeConfiguration: builder.mutation({
|
2537
|
-
query: ({ uid, ...body }) => ({
|
2538
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2539
|
-
method: "PUT",
|
2540
|
-
data: body
|
2541
|
-
}),
|
2542
|
-
transformResponse: (response) => response.data,
|
2543
|
-
invalidatesTags: (_result, _error, { uid }) => [
|
2544
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2545
|
-
{ type: "ContentTypeSettings", id: "LIST" },
|
2546
|
-
// Is this necessary?
|
2547
|
-
{ type: "InitialData" }
|
2548
|
-
]
|
2549
|
-
})
|
2550
|
-
})
|
2551
|
-
});
|
2552
|
-
const {
|
2553
|
-
useGetContentTypeConfigurationQuery,
|
2554
|
-
useGetAllContentTypeSettingsQuery,
|
2555
|
-
useUpdateContentTypeConfigurationMutation
|
2556
|
-
} = contentTypesApi;
|
2557
|
-
const checkIfAttributeIsDisplayable = (attribute) => {
|
2558
|
-
const { type } = attribute;
|
2559
|
-
if (type === "relation") {
|
2560
|
-
return !attribute.relation.toLowerCase().includes("morph");
|
2561
|
-
}
|
2562
|
-
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2563
|
-
};
|
2564
|
-
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2565
|
-
if (!mainFieldName) {
|
2566
|
-
return void 0;
|
2567
|
-
}
|
2568
|
-
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2569
|
-
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2570
|
-
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2571
|
-
);
|
2572
|
-
return {
|
2573
|
-
name: mainFieldName,
|
2574
|
-
type: mainFieldType ?? "string"
|
2575
|
-
};
|
2576
|
-
};
|
2577
|
-
const DEFAULT_SETTINGS = {
|
2578
|
-
bulkable: false,
|
2579
|
-
filterable: false,
|
2580
|
-
searchable: false,
|
2581
|
-
pagination: false,
|
2582
|
-
defaultSortBy: "",
|
2583
|
-
defaultSortOrder: "asc",
|
2584
|
-
mainField: "id",
|
2585
|
-
pageSize: 10
|
2586
|
-
};
|
2587
|
-
const useDocumentLayout = (model) => {
|
2588
|
-
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2589
|
-
const [{ query }] = strapiAdmin.useQueryParams();
|
2590
|
-
const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2591
|
-
const { toggleNotification } = strapiAdmin.useNotification();
|
2592
|
-
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
2593
|
-
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2594
|
-
const {
|
2595
|
-
data,
|
2596
|
-
isLoading: isLoadingConfigs,
|
2597
|
-
error,
|
2598
|
-
isFetching: isFetchingConfigs
|
2599
|
-
} = useGetContentTypeConfigurationQuery(model);
|
2600
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2601
|
-
React__namespace.useEffect(() => {
|
2602
|
-
if (error) {
|
2603
|
-
toggleNotification({
|
2604
|
-
type: "danger",
|
2605
|
-
message: formatAPIError(error)
|
2606
|
-
});
|
2607
|
-
}
|
2608
|
-
}, [error, formatAPIError, toggleNotification]);
|
2609
|
-
const editLayout = React__namespace.useMemo(
|
2610
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2611
|
-
layout: [],
|
2612
|
-
components: {},
|
2613
|
-
metadatas: {},
|
2614
|
-
options: {},
|
2615
|
-
settings: DEFAULT_SETTINGS
|
2616
|
-
},
|
2617
|
-
[data, isLoading, schemas, schema, components]
|
2618
|
-
);
|
2619
|
-
const listLayout = React__namespace.useMemo(() => {
|
2620
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2621
|
-
layout: [],
|
2622
|
-
metadatas: {},
|
2623
|
-
options: {},
|
2624
|
-
settings: DEFAULT_SETTINGS
|
2625
|
-
};
|
2626
|
-
}, [data, isLoading, schemas, schema, components]);
|
2627
|
-
const { layout: edit } = React__namespace.useMemo(
|
2628
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2629
|
-
layout: editLayout,
|
2630
|
-
query
|
2631
|
-
}),
|
2632
|
-
[editLayout, query, runHookWaterfall]
|
2633
|
-
);
|
2634
|
-
return {
|
2635
|
-
error,
|
2636
|
-
isLoading,
|
2637
|
-
edit,
|
2638
|
-
list: listLayout
|
2639
|
-
};
|
2640
|
-
};
|
2641
|
-
const useDocLayout = () => {
|
2642
|
-
const { model } = useDoc();
|
2643
|
-
return useDocumentLayout(model);
|
2644
|
-
};
|
2645
|
-
const formatEditLayout = (data, {
|
2646
|
-
schemas,
|
2647
|
-
schema,
|
2648
|
-
components
|
2649
|
-
}) => {
|
2650
|
-
let currentPanelIndex = 0;
|
2651
|
-
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2652
|
-
data.contentType.layouts.edit,
|
2653
|
-
schema?.attributes,
|
2654
|
-
data.contentType.metadatas,
|
2655
|
-
{ configurations: data.components, schemas: components },
|
2656
|
-
schemas
|
2657
|
-
).reduce((panels, row) => {
|
2658
|
-
if (row.some((field) => field.type === "dynamiczone")) {
|
2659
|
-
panels.push([row]);
|
2660
|
-
currentPanelIndex += 2;
|
2661
|
-
} else {
|
2662
|
-
if (!panels[currentPanelIndex]) {
|
2663
|
-
panels.push([]);
|
2664
|
-
}
|
2665
|
-
panels[currentPanelIndex].push(row);
|
2666
|
-
}
|
2667
|
-
return panels;
|
2668
|
-
}, []);
|
2669
|
-
const componentEditAttributes = Object.entries(data.components).reduce(
|
2670
|
-
(acc, [uid, configuration]) => {
|
2671
|
-
acc[uid] = {
|
2672
|
-
layout: convertEditLayoutToFieldLayouts(
|
2673
|
-
configuration.layouts.edit,
|
2674
|
-
components[uid].attributes,
|
2675
|
-
configuration.metadatas
|
2676
|
-
),
|
2677
|
-
settings: {
|
2678
|
-
...configuration.settings,
|
2679
|
-
icon: components[uid].info.icon,
|
2680
|
-
displayName: components[uid].info.displayName
|
2907
|
+
documentId,
|
2908
|
+
model,
|
2909
|
+
collectionType,
|
2910
|
+
params: {
|
2911
|
+
locale: "*"
|
2912
|
+
}
|
2913
|
+
});
|
2914
|
+
if (!("error" in res)) {
|
2915
|
+
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
2916
|
+
}
|
2917
|
+
} finally {
|
2918
|
+
if (!listViewPathMatch) {
|
2919
|
+
setSubmitting(false);
|
2920
|
+
}
|
2681
2921
|
}
|
2682
|
-
}
|
2683
|
-
return acc;
|
2684
|
-
},
|
2685
|
-
{}
|
2686
|
-
);
|
2687
|
-
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2688
|
-
(acc, [attribute, metadata]) => {
|
2689
|
-
return {
|
2690
|
-
...acc,
|
2691
|
-
[attribute]: metadata.edit
|
2692
|
-
};
|
2693
|
-
},
|
2694
|
-
{}
|
2695
|
-
);
|
2696
|
-
return {
|
2697
|
-
layout: panelledEditAttributes,
|
2698
|
-
components: componentEditAttributes,
|
2699
|
-
metadatas: editMetadatas,
|
2700
|
-
settings: {
|
2701
|
-
...data.contentType.settings,
|
2702
|
-
displayName: schema?.info.displayName
|
2922
|
+
}
|
2703
2923
|
},
|
2704
|
-
|
2705
|
-
|
2706
|
-
...schema?.pluginOptions,
|
2707
|
-
...data.contentType.options
|
2708
|
-
}
|
2924
|
+
variant: "danger",
|
2925
|
+
position: ["header", "table-row"]
|
2709
2926
|
};
|
2710
2927
|
};
|
2711
|
-
|
2712
|
-
|
2713
|
-
|
2714
|
-
|
2715
|
-
|
2716
|
-
|
2717
|
-
}
|
2718
|
-
|
2719
|
-
|
2720
|
-
|
2721
|
-
|
2722
|
-
|
2723
|
-
|
2724
|
-
|
2725
|
-
|
2726
|
-
|
2727
|
-
|
2728
|
-
|
2729
|
-
|
2730
|
-
|
2731
|
-
|
2732
|
-
|
2733
|
-
|
2734
|
-
|
2735
|
-
|
2736
|
-
|
2737
|
-
}
|
2738
|
-
}
|
2739
|
-
);
|
2928
|
+
DeleteAction$1.type = "delete";
|
2929
|
+
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2930
|
+
const Panels = () => {
|
2931
|
+
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2932
|
+
const [
|
2933
|
+
{
|
2934
|
+
query: { status }
|
2935
|
+
}
|
2936
|
+
] = strapiAdmin.useQueryParams({
|
2937
|
+
status: "draft"
|
2938
|
+
});
|
2939
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
2940
|
+
const plugins = strapiAdmin.useStrapiApp("Panels", (state) => state.plugins);
|
2941
|
+
const props = {
|
2942
|
+
activeTab: status,
|
2943
|
+
model,
|
2944
|
+
documentId: id,
|
2945
|
+
document: isCloning ? void 0 : document,
|
2946
|
+
meta: isCloning ? void 0 : meta,
|
2947
|
+
collectionType
|
2948
|
+
};
|
2949
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
|
2950
|
+
strapiAdmin.DescriptionComponentRenderer,
|
2951
|
+
{
|
2952
|
+
props,
|
2953
|
+
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2954
|
+
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsxRuntime.jsx(Panel, { ...description, children: content }, id2))
|
2955
|
+
}
|
2956
|
+
) });
|
2740
2957
|
};
|
2741
|
-
const
|
2742
|
-
|
2743
|
-
schema,
|
2744
|
-
components
|
2745
|
-
}) => {
|
2746
|
-
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2747
|
-
(acc, [attribute, metadata]) => {
|
2748
|
-
return {
|
2749
|
-
...acc,
|
2750
|
-
[attribute]: metadata.list
|
2751
|
-
};
|
2752
|
-
},
|
2753
|
-
{}
|
2754
|
-
);
|
2755
|
-
const listAttributes = convertListLayoutToFieldLayouts(
|
2756
|
-
data.contentType.layouts.list,
|
2757
|
-
schema?.attributes,
|
2758
|
-
listMetadatas,
|
2759
|
-
{ configurations: data.components, schemas: components },
|
2760
|
-
schemas
|
2761
|
-
);
|
2958
|
+
const ActionsPanel = () => {
|
2959
|
+
const { formatMessage } = reactIntl.useIntl();
|
2762
2960
|
return {
|
2763
|
-
|
2764
|
-
|
2765
|
-
|
2766
|
-
|
2767
|
-
|
2768
|
-
...schema?.pluginOptions,
|
2769
|
-
...data.contentType.options
|
2770
|
-
}
|
2961
|
+
title: formatMessage({
|
2962
|
+
id: "content-manager.containers.edit.panels.default.title",
|
2963
|
+
defaultMessage: "Entry"
|
2964
|
+
}),
|
2965
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(ActionsPanelContent, {})
|
2771
2966
|
};
|
2772
2967
|
};
|
2773
|
-
|
2774
|
-
|
2775
|
-
|
2776
|
-
|
2777
|
-
|
2968
|
+
ActionsPanel.type = "actions";
|
2969
|
+
const ActionsPanelContent = () => {
|
2970
|
+
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2971
|
+
const [
|
2972
|
+
{
|
2973
|
+
query: { status = "draft" }
|
2778
2974
|
}
|
2779
|
-
|
2780
|
-
|
2781
|
-
|
2782
|
-
|
2783
|
-
|
2784
|
-
|
2785
|
-
|
2786
|
-
|
2787
|
-
|
2788
|
-
|
2789
|
-
|
2790
|
-
|
2791
|
-
|
2792
|
-
|
2975
|
+
] = strapiAdmin.useQueryParams();
|
2976
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
2977
|
+
const plugins = strapiAdmin.useStrapiApp("ActionsPanel", (state) => state.plugins);
|
2978
|
+
const props = {
|
2979
|
+
activeTab: status,
|
2980
|
+
model,
|
2981
|
+
documentId: id,
|
2982
|
+
document: isCloning ? void 0 : document,
|
2983
|
+
meta: isCloning ? void 0 : meta,
|
2984
|
+
collectionType
|
2985
|
+
};
|
2986
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, width: "100%", children: [
|
2987
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
2988
|
+
strapiAdmin.DescriptionComponentRenderer,
|
2989
|
+
{
|
2990
|
+
props,
|
2991
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2992
|
+
children: (actions2) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActions, { actions: actions2 })
|
2993
|
+
}
|
2994
|
+
),
|
2995
|
+
/* @__PURE__ */ jsxRuntime.jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
2996
|
+
] });
|
2793
2997
|
};
|
2998
|
+
const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
2999
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
3000
|
+
designSystem.Flex,
|
3001
|
+
{
|
3002
|
+
ref,
|
3003
|
+
tag: "aside",
|
3004
|
+
"aria-labelledby": "additional-information",
|
3005
|
+
background: "neutral0",
|
3006
|
+
borderColor: "neutral150",
|
3007
|
+
hasRadius: true,
|
3008
|
+
paddingBottom: 4,
|
3009
|
+
paddingLeft: 4,
|
3010
|
+
paddingRight: 4,
|
3011
|
+
paddingTop: 4,
|
3012
|
+
shadow: "tableShadow",
|
3013
|
+
gap: 3,
|
3014
|
+
direction: "column",
|
3015
|
+
justifyContent: "stretch",
|
3016
|
+
alignItems: "flex-start",
|
3017
|
+
children: [
|
3018
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
3019
|
+
children
|
3020
|
+
]
|
3021
|
+
}
|
3022
|
+
);
|
3023
|
+
});
|
2794
3024
|
const ConfirmBulkActionDialog = ({
|
2795
3025
|
onToggleDialog,
|
2796
3026
|
isOpen = false,
|
@@ -2798,7 +3028,7 @@ const ConfirmBulkActionDialog = ({
|
|
2798
3028
|
endAction
|
2799
3029
|
}) => {
|
2800
3030
|
const { formatMessage } = reactIntl.useIntl();
|
2801
|
-
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, {
|
3031
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
2802
3032
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: formatMessage({
|
2803
3033
|
id: "app.components.ConfirmDialog.title",
|
2804
3034
|
defaultMessage: "Confirmation"
|
@@ -2829,6 +3059,7 @@ const ConfirmDialogPublishAll = ({
|
|
2829
3059
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler(getTranslation);
|
2830
3060
|
const { model, schema } = useDoc();
|
2831
3061
|
const [{ query }] = strapiAdmin.useQueryParams();
|
3062
|
+
const enableDraftRelationsCount = false;
|
2832
3063
|
const {
|
2833
3064
|
data: countDraftRelations = 0,
|
2834
3065
|
isLoading,
|
@@ -2840,7 +3071,7 @@ const ConfirmDialogPublishAll = ({
|
|
2840
3071
|
locale: query?.plugins?.i18n?.locale
|
2841
3072
|
},
|
2842
3073
|
{
|
2843
|
-
skip:
|
3074
|
+
skip: !enableDraftRelationsCount
|
2844
3075
|
}
|
2845
3076
|
);
|
2846
3077
|
React__namespace.useEffect(() => {
|
@@ -2919,7 +3150,14 @@ const formatErrorMessages = (errors, parentKey, formatMessage) => {
|
|
2919
3150
|
)
|
2920
3151
|
);
|
2921
3152
|
} else {
|
2922
|
-
messages.push(
|
3153
|
+
messages.push(
|
3154
|
+
...formatErrorMessages(
|
3155
|
+
// @ts-expect-error TODO: check why value is not compatible with FormErrors
|
3156
|
+
value,
|
3157
|
+
currentKey,
|
3158
|
+
formatMessage
|
3159
|
+
)
|
3160
|
+
);
|
2923
3161
|
}
|
2924
3162
|
} else {
|
2925
3163
|
messages.push(
|
@@ -3018,7 +3256,7 @@ const SelectedEntriesTableContent = ({
|
|
3018
3256
|
status: row.status
|
3019
3257
|
}
|
3020
3258
|
) }),
|
3021
|
-
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
3259
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
3022
3260
|
designSystem.IconButton,
|
3023
3261
|
{
|
3024
3262
|
tag: reactRouterDom.Link,
|
@@ -3041,9 +3279,10 @@ const SelectedEntriesTableContent = ({
|
|
3041
3279
|
),
|
3042
3280
|
target: "_blank",
|
3043
3281
|
marginLeft: "auto",
|
3044
|
-
|
3282
|
+
variant: "ghost",
|
3283
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, { width: "1.6rem", height: "1.6rem" })
|
3045
3284
|
}
|
3046
|
-
) })
|
3285
|
+
) }) })
|
3047
3286
|
] }, row.id)) })
|
3048
3287
|
] });
|
3049
3288
|
};
|
@@ -3080,7 +3319,13 @@ const SelectedEntriesModalContent = ({
|
|
3080
3319
|
);
|
3081
3320
|
const { rows, validationErrors } = React__namespace.useMemo(() => {
|
3082
3321
|
if (data.length > 0 && schema) {
|
3083
|
-
const validate = createYupSchema(
|
3322
|
+
const validate = createYupSchema(
|
3323
|
+
schema.attributes,
|
3324
|
+
components,
|
3325
|
+
// Since this is the "Publish" action, the validation
|
3326
|
+
// schema must enforce the rules for published entities
|
3327
|
+
{ status: "published" }
|
3328
|
+
);
|
3084
3329
|
const validationErrors2 = {};
|
3085
3330
|
const rows2 = data.map((entry) => {
|
3086
3331
|
try {
|
@@ -3430,7 +3675,7 @@ const TableActions = ({ document }) => {
|
|
3430
3675
|
strapiAdmin.DescriptionComponentRenderer,
|
3431
3676
|
{
|
3432
3677
|
props,
|
3433
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3678
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
3434
3679
|
children: (actions2) => {
|
3435
3680
|
const tableRowActions = actions2.filter((action) => {
|
3436
3681
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3541,7 +3786,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3541
3786
|
}),
|
3542
3787
|
content: /* @__PURE__ */ jsxRuntime.jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
3543
3788
|
footer: ({ onClose }) => {
|
3544
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.
|
3789
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
3545
3790
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
3546
3791
|
id: "cancel",
|
3547
3792
|
defaultMessage: "Cancel"
|
@@ -3582,8 +3827,7 @@ class ContentManagerPlugin {
|
|
3582
3827
|
documentActions = [
|
3583
3828
|
...DEFAULT_ACTIONS,
|
3584
3829
|
...DEFAULT_TABLE_ROW_ACTIONS,
|
3585
|
-
...DEFAULT_HEADER_ACTIONS
|
3586
|
-
HistoryAction
|
3830
|
+
...DEFAULT_HEADER_ACTIONS
|
3587
3831
|
];
|
3588
3832
|
editViewSidePanels = [ActionsPanel];
|
3589
3833
|
headerActions = [];
|
@@ -3672,6 +3916,52 @@ const getPrintableType = (value) => {
|
|
3672
3916
|
}
|
3673
3917
|
return nativeType;
|
3674
3918
|
};
|
3919
|
+
const HistoryAction = ({ model, document }) => {
|
3920
|
+
const { formatMessage } = reactIntl.useIntl();
|
3921
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3922
|
+
const navigate = reactRouterDom.useNavigate();
|
3923
|
+
const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
|
3924
|
+
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3925
|
+
return null;
|
3926
|
+
}
|
3927
|
+
return {
|
3928
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
|
3929
|
+
label: formatMessage({
|
3930
|
+
id: "content-manager.history.document-action",
|
3931
|
+
defaultMessage: "Content History"
|
3932
|
+
}),
|
3933
|
+
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
3934
|
+
disabled: (
|
3935
|
+
/**
|
3936
|
+
* The user is creating a new document.
|
3937
|
+
* It hasn't been saved yet, so there's no history to go to
|
3938
|
+
*/
|
3939
|
+
!document || /**
|
3940
|
+
* The document has been created but the current dimension has never been saved.
|
3941
|
+
* For example, the user is creating a new locale in an existing document,
|
3942
|
+
* so there's no history for the document in that locale
|
3943
|
+
*/
|
3944
|
+
!document.id || /**
|
3945
|
+
* History is only available for content types created by the user.
|
3946
|
+
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
3947
|
+
* which start with `admin::` or `plugin::`
|
3948
|
+
*/
|
3949
|
+
!model.startsWith("api::")
|
3950
|
+
),
|
3951
|
+
position: "header"
|
3952
|
+
};
|
3953
|
+
};
|
3954
|
+
HistoryAction.type = "history";
|
3955
|
+
const historyAdmin = {
|
3956
|
+
bootstrap(app) {
|
3957
|
+
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
3958
|
+
addDocumentAction((actions2) => {
|
3959
|
+
const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
|
3960
|
+
actions2.splice(indexOfDeleteAction, 0, HistoryAction);
|
3961
|
+
return actions2;
|
3962
|
+
});
|
3963
|
+
}
|
3964
|
+
};
|
3675
3965
|
const initialState = {
|
3676
3966
|
collectionTypeLinks: [],
|
3677
3967
|
components: [],
|
@@ -3727,7 +4017,7 @@ const index = {
|
|
3727
4017
|
app.router.addRoute({
|
3728
4018
|
path: "content-manager/*",
|
3729
4019
|
lazy: async () => {
|
3730
|
-
const { Layout } = await Promise.resolve().then(() => require("./layout-
|
4020
|
+
const { Layout } = await Promise.resolve().then(() => require("./layout-CxxkX9jY.js"));
|
3731
4021
|
return {
|
3732
4022
|
Component: Layout
|
3733
4023
|
};
|
@@ -3736,10 +4026,15 @@ const index = {
|
|
3736
4026
|
});
|
3737
4027
|
app.registerPlugin(cm.config);
|
3738
4028
|
},
|
4029
|
+
bootstrap(app) {
|
4030
|
+
if (typeof historyAdmin.bootstrap === "function") {
|
4031
|
+
historyAdmin.bootstrap(app);
|
4032
|
+
}
|
4033
|
+
},
|
3739
4034
|
async registerTrads({ locales }) {
|
3740
4035
|
const importedTrads = await Promise.all(
|
3741
4036
|
locales.map((locale) => {
|
3742
|
-
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => Promise.resolve().then(() => require("./ar-BUUWXIYu.js")), "./translations/ca.json": () => Promise.resolve().then(() => require("./ca-Cmk45QO6.js")), "./translations/cs.json": () => Promise.resolve().then(() => require("./cs-CkJy6B2v.js")), "./translations/de.json": () => Promise.resolve().then(() => require("./de-CCEmbAah.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-
|
4037
|
+
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => Promise.resolve().then(() => require("./ar-BUUWXIYu.js")), "./translations/ca.json": () => Promise.resolve().then(() => require("./ca-Cmk45QO6.js")), "./translations/cs.json": () => Promise.resolve().then(() => require("./cs-CkJy6B2v.js")), "./translations/de.json": () => Promise.resolve().then(() => require("./de-CCEmbAah.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-BlhnxQfj.js")), "./translations/es.json": () => Promise.resolve().then(() => require("./es-EUonQTon.js")), "./translations/eu.json": () => Promise.resolve().then(() => require("./eu-VDH-3ovk.js")), "./translations/fr.json": () => Promise.resolve().then(() => require("./fr-B7kGGg3E.js")), "./translations/gu.json": () => Promise.resolve().then(() => require("./gu-BRmF601H.js")), "./translations/hi.json": () => Promise.resolve().then(() => require("./hi-CCJBptSq.js")), "./translations/hu.json": () => Promise.resolve().then(() => require("./hu-sNV_yLYy.js")), "./translations/id.json": () => Promise.resolve().then(() => require("./id-B5Ser98A.js")), "./translations/it.json": () => Promise.resolve().then(() => require("./it-DkBIs7vD.js")), "./translations/ja.json": () => Promise.resolve().then(() => require("./ja-CcFe8diO.js")), "./translations/ko.json": () => Promise.resolve().then(() => require("./ko-woFZPmLk.js")), "./translations/ml.json": () => Promise.resolve().then(() => require("./ml-C2W8N8k1.js")), "./translations/ms.json": () => Promise.resolve().then(() => require("./ms-BuFotyP_.js")), "./translations/nl.json": () => Promise.resolve().then(() => require("./nl-bbEOHChV.js")), "./translations/pl.json": () => Promise.resolve().then(() => require("./pl-uzwG-hk7.js")), "./translations/pt-BR.json": () => Promise.resolve().then(() => require("./pt-BR-BiOz37D9.js")), "./translations/pt.json": () => Promise.resolve().then(() => require("./pt-CeXQuq50.js")), "./translations/ru.json": () => Promise.resolve().then(() => require("./ru-BT3ybNny.js")), "./translations/sa.json": () => Promise.resolve().then(() => require("./sa-CcvkYInH.js")), "./translations/sk.json": () => Promise.resolve().then(() => require("./sk-CvY09Xjv.js")), "./translations/sv.json": () => Promise.resolve().then(() => require("./sv-MYDuzgvT.js")), "./translations/th.json": () => Promise.resolve().then(() => require("./th-D9_GfAjc.js")), "./translations/tr.json": () => Promise.resolve().then(() => require("./tr-D9UH-O_R.js")), "./translations/uk.json": () => Promise.resolve().then(() => require("./uk-C8EiqJY7.js")), "./translations/vi.json": () => Promise.resolve().then(() => require("./vi-CJlYDheJ.js")), "./translations/zh-Hans.json": () => Promise.resolve().then(() => require("./zh-Hans-9kOncHGw.js")), "./translations/zh.json": () => Promise.resolve().then(() => require("./zh-CQQfszqR.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
|
3743
4038
|
return {
|
3744
4039
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3745
4040
|
locale
|
@@ -3757,6 +4052,7 @@ const index = {
|
|
3757
4052
|
};
|
3758
4053
|
exports.ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD = ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD;
|
3759
4054
|
exports.BulkActionsRenderer = BulkActionsRenderer;
|
4055
|
+
exports.CLONE_PATH = CLONE_PATH;
|
3760
4056
|
exports.COLLECTION_TYPES = COLLECTION_TYPES;
|
3761
4057
|
exports.CREATOR_FIELDS = CREATOR_FIELDS;
|
3762
4058
|
exports.DEFAULT_SETTINGS = DEFAULT_SETTINGS;
|
@@ -3784,6 +4080,7 @@ exports.getMainField = getMainField;
|
|
3784
4080
|
exports.getTranslation = getTranslation;
|
3785
4081
|
exports.index = index;
|
3786
4082
|
exports.setInitialData = setInitialData;
|
4083
|
+
exports.useContentManagerContext = useContentManagerContext;
|
3787
4084
|
exports.useContentTypeSchema = useContentTypeSchema;
|
3788
4085
|
exports.useDoc = useDoc;
|
3789
4086
|
exports.useDocLayout = useDocLayout;
|
@@ -3796,4 +4093,4 @@ exports.useGetAllDocumentsQuery = useGetAllDocumentsQuery;
|
|
3796
4093
|
exports.useGetContentTypeConfigurationQuery = useGetContentTypeConfigurationQuery;
|
3797
4094
|
exports.useGetInitialDataQuery = useGetInitialDataQuery;
|
3798
4095
|
exports.useUpdateContentTypeConfigurationMutation = useUpdateContentTypeConfigurationMutation;
|
3799
|
-
//# sourceMappingURL=index-
|
4096
|
+
//# sourceMappingURL=index-CBX6KyXv.js.map
|