@strapi/content-manager 0.0.0-experimental.d53e940834bf72ddc725f1d2fd36dac9abec30cb → 0.0.0-experimental.d834c9e658d1fb037e6da1105150593521c667cc
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-C-49MccQ.js → ComponentConfigurationPage-D_M8iBw5.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-C-49MccQ.js.map → ComponentConfigurationPage-D_M8iBw5.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-DmwmiFQy.mjs → ComponentConfigurationPage-qemkOlnj.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-DmwmiFQy.mjs.map → ComponentConfigurationPage-qemkOlnj.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-DjFJw56M.js → EditConfigurationPage-BePwPuHy.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-DjFJw56M.js.map → EditConfigurationPage-BePwPuHy.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-JT3E7NZy.mjs → EditConfigurationPage-CjUrEewK.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-JT3E7NZy.mjs.map → EditConfigurationPage-CjUrEewK.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-zT3fBr4Y.js → EditViewPage-B-RJeiJD.js} +19 -8
- package/dist/_chunks/EditViewPage-B-RJeiJD.js.map +1 -0
- package/dist/_chunks/{EditViewPage-CPj61RMh.mjs → EditViewPage-De8GyU8P.mjs} +19 -8
- package/dist/_chunks/EditViewPage-De8GyU8P.mjs.map +1 -0
- package/dist/_chunks/{Field-Boxf9Ajp.js → Field-dq8Tg1M_.js} +175 -84
- package/dist/_chunks/Field-dq8Tg1M_.js.map +1 -0
- package/dist/_chunks/{Field-dha5VnIQ.mjs → Field-pb2o8uBe.mjs} +177 -86
- package/dist/_chunks/Field-pb2o8uBe.mjs.map +1 -0
- package/dist/_chunks/{Form-y5g1SRsh.js → Form-DGIf4jQU.js} +22 -11
- package/dist/_chunks/Form-DGIf4jQU.js.map +1 -0
- package/dist/_chunks/{Form-DHrru2AV.mjs → Form-DJn0Dxha.mjs} +22 -11
- package/dist/_chunks/Form-DJn0Dxha.mjs.map +1 -0
- package/dist/_chunks/{History-Bru_KoeP.mjs → History-BowL3JKP.mjs} +44 -19
- package/dist/_chunks/History-BowL3JKP.mjs.map +1 -0
- package/dist/_chunks/{History-CqN6K7SX.js → History-Dh2NEHnR.js} +44 -19
- package/dist/_chunks/History-Dh2NEHnR.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-D8wGABj0.mjs → ListConfigurationPage-BpVOB-hn.mjs} +20 -8
- package/dist/_chunks/ListConfigurationPage-BpVOB-hn.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-R_p-SbHZ.js → ListConfigurationPage-BxYCWz9e.js} +20 -8
- package/dist/_chunks/ListConfigurationPage-BxYCWz9e.js.map +1 -0
- package/dist/_chunks/{ListViewPage-pEw_zug9.js → ListViewPage-4XsciqHZ.js} +21 -7
- package/dist/_chunks/ListViewPage-4XsciqHZ.js.map +1 -0
- package/dist/_chunks/{ListViewPage-SID6TRb9.mjs → ListViewPage-CXFUjZQC.mjs} +22 -8
- package/dist/_chunks/ListViewPage-CXFUjZQC.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-C5dcQojD.js → NoContentTypePage-C8OpoHeU.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-C5dcQojD.js.map → NoContentTypePage-C8OpoHeU.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-CJ7UXwrQ.mjs → NoContentTypePage-DuhOTp3x.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-CJ7UXwrQ.mjs.map → NoContentTypePage-DuhOTp3x.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-B7syEq5E.mjs → NoPermissionsPage-DVz3mzDz.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-B7syEq5E.mjs.map → NoPermissionsPage-DVz3mzDz.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-BtPrImPP.js → NoPermissionsPage-y_r7DVA2.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-BtPrImPP.js.map → NoPermissionsPage-y_r7DVA2.js.map} +1 -1
- package/dist/_chunks/{Relations-B9Crnhnn.mjs → Relations-CVNLrn1Y.mjs} +4 -4
- package/dist/_chunks/Relations-CVNLrn1Y.mjs.map +1 -0
- package/dist/_chunks/{Relations-DjTQ5kGB.js → Relations-DPFCAa7b.js} +4 -4
- package/dist/_chunks/Relations-DPFCAa7b.js.map +1 -0
- package/dist/_chunks/{en-Ux26r5pl.mjs → en-BrCTWlZv.mjs} +5 -4
- package/dist/_chunks/{en-Ux26r5pl.mjs.map → en-BrCTWlZv.mjs.map} +1 -1
- package/dist/_chunks/{en-fbKQxLGn.js → en-uOUIxfcQ.js} +5 -4
- package/dist/_chunks/{en-fbKQxLGn.js.map → en-uOUIxfcQ.js.map} +1 -1
- package/dist/_chunks/{index-DVPWZkbS.js → index-C3fJE-1-.js} +368 -168
- package/dist/_chunks/index-C3fJE-1-.js.map +1 -0
- package/dist/_chunks/{index-DJXJw9V5.mjs → index-DiMrfcfy.mjs} +387 -187
- package/dist/_chunks/index-DiMrfcfy.mjs.map +1 -0
- package/dist/_chunks/{layout-Dm6fbiQj.js → layout-C788OmNr.js} +22 -10
- package/dist/_chunks/layout-C788OmNr.js.map +1 -0
- package/dist/_chunks/{layout-Bau7ZfLV.mjs → layout-ls3gxfpH.mjs} +23 -11
- package/dist/_chunks/layout-ls3gxfpH.mjs.map +1 -0
- package/dist/_chunks/{relations-BH_kBSJ0.mjs → relations-CLcOmGO0.mjs} +2 -2
- package/dist/_chunks/{relations-BH_kBSJ0.mjs.map → relations-CLcOmGO0.mjs.map} +1 -1
- package/dist/_chunks/{relations-CKnpRgrN.js → relations-DYeotliT.js} +2 -2
- package/dist/_chunks/{relations-CKnpRgrN.js.map → relations-DYeotliT.js.map} +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +4 -4
- 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/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 +10 -22
- 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 +16 -16
- 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 +165 -105
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +166 -106
- 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/lifecycles.d.ts.map +1 -1
- package/dist/server/src/history/services/utils.d.ts +1 -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/package.json +8 -8
- 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
@@ -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");
|
7
|
+
const reactIntl = require("react-intl");
|
8
|
+
const reactRouterDom = require("react-router-dom");
|
10
9
|
const styledComponents = require("styled-components");
|
11
10
|
const yup = require("yup");
|
12
11
|
const pipe = require("lodash/fp/pipe");
|
13
12
|
const dateFns = require("date-fns");
|
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,
|
@@ -785,7 +818,10 @@ const useDocument = (args, opts) => {
|
|
785
818
|
isLoading: isLoadingDocument,
|
786
819
|
isFetching: isFetchingDocument,
|
787
820
|
error
|
788
|
-
} = useGetDocumentQuery(args,
|
821
|
+
} = useGetDocumentQuery(args, {
|
822
|
+
...opts,
|
823
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
824
|
+
});
|
789
825
|
const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
|
790
826
|
React__namespace.useEffect(() => {
|
791
827
|
if (error) {
|
@@ -871,6 +907,7 @@ const useDocumentActions = () => {
|
|
871
907
|
const { formatMessage } = reactIntl.useIntl();
|
872
908
|
const { trackUsage } = strapiAdmin.useTracking();
|
873
909
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
910
|
+
const navigate = reactRouterDom.useNavigate();
|
874
911
|
const [deleteDocument] = useDeleteDocumentMutation();
|
875
912
|
const _delete = React__namespace.useCallback(
|
876
913
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -1206,7 +1243,6 @@ const useDocumentActions = () => {
|
|
1206
1243
|
sourceId
|
1207
1244
|
});
|
1208
1245
|
if ("error" in res) {
|
1209
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1210
1246
|
return { error: res.error };
|
1211
1247
|
}
|
1212
1248
|
toggleNotification({
|
@@ -1225,7 +1261,7 @@ const useDocumentActions = () => {
|
|
1225
1261
|
throw err;
|
1226
1262
|
}
|
1227
1263
|
},
|
1228
|
-
[autoCloneDocument,
|
1264
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1229
1265
|
);
|
1230
1266
|
const [cloneDocument] = useCloneDocumentMutation();
|
1231
1267
|
const clone = React__namespace.useCallback(
|
@@ -1251,6 +1287,7 @@ const useDocumentActions = () => {
|
|
1251
1287
|
defaultMessage: "Cloned document"
|
1252
1288
|
})
|
1253
1289
|
});
|
1290
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1254
1291
|
return res.data;
|
1255
1292
|
} catch (err) {
|
1256
1293
|
toggleNotification({
|
@@ -1261,7 +1298,7 @@ const useDocumentActions = () => {
|
|
1261
1298
|
throw err;
|
1262
1299
|
}
|
1263
1300
|
},
|
1264
|
-
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
|
1301
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1265
1302
|
);
|
1266
1303
|
const [getDoc] = useLazyGetDocumentQuery();
|
1267
1304
|
const getDocument = React__namespace.useCallback(
|
@@ -1287,7 +1324,7 @@ const useDocumentActions = () => {
|
|
1287
1324
|
};
|
1288
1325
|
};
|
1289
1326
|
const ProtectedHistoryPage = React.lazy(
|
1290
|
-
() => Promise.resolve().then(() => require("./History-
|
1327
|
+
() => Promise.resolve().then(() => require("./History-Dh2NEHnR.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1291
1328
|
);
|
1292
1329
|
const routes$1 = [
|
1293
1330
|
{
|
@@ -1300,31 +1337,31 @@ const routes$1 = [
|
|
1300
1337
|
}
|
1301
1338
|
];
|
1302
1339
|
const ProtectedEditViewPage = React.lazy(
|
1303
|
-
() => Promise.resolve().then(() => require("./EditViewPage-
|
1340
|
+
() => Promise.resolve().then(() => require("./EditViewPage-B-RJeiJD.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1304
1341
|
);
|
1305
1342
|
const ProtectedListViewPage = React.lazy(
|
1306
|
-
() => Promise.resolve().then(() => require("./ListViewPage-
|
1343
|
+
() => Promise.resolve().then(() => require("./ListViewPage-4XsciqHZ.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1307
1344
|
);
|
1308
1345
|
const ProtectedListConfiguration = React.lazy(
|
1309
|
-
() => Promise.resolve().then(() => require("./ListConfigurationPage-
|
1346
|
+
() => Promise.resolve().then(() => require("./ListConfigurationPage-BxYCWz9e.js")).then((mod) => ({
|
1310
1347
|
default: mod.ProtectedListConfiguration
|
1311
1348
|
}))
|
1312
1349
|
);
|
1313
1350
|
const ProtectedEditConfigurationPage = React.lazy(
|
1314
|
-
() => Promise.resolve().then(() => require("./EditConfigurationPage-
|
1351
|
+
() => Promise.resolve().then(() => require("./EditConfigurationPage-BePwPuHy.js")).then((mod) => ({
|
1315
1352
|
default: mod.ProtectedEditConfigurationPage
|
1316
1353
|
}))
|
1317
1354
|
);
|
1318
1355
|
const ProtectedComponentConfigurationPage = React.lazy(
|
1319
|
-
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-
|
1356
|
+
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-D_M8iBw5.js")).then((mod) => ({
|
1320
1357
|
default: mod.ProtectedComponentConfigurationPage
|
1321
1358
|
}))
|
1322
1359
|
);
|
1323
1360
|
const NoPermissions = React.lazy(
|
1324
|
-
() => Promise.resolve().then(() => require("./NoPermissionsPage-
|
1361
|
+
() => Promise.resolve().then(() => require("./NoPermissionsPage-y_r7DVA2.js")).then((mod) => ({ default: mod.NoPermissions }))
|
1325
1362
|
);
|
1326
1363
|
const NoContentType = React.lazy(
|
1327
|
-
() => Promise.resolve().then(() => require("./NoContentTypePage-
|
1364
|
+
() => Promise.resolve().then(() => require("./NoContentTypePage-C8OpoHeU.js")).then((mod) => ({ default: mod.NoContentType }))
|
1328
1365
|
);
|
1329
1366
|
const CollectionTypePages = () => {
|
1330
1367
|
const { collectionType } = reactRouterDom.useParams();
|
@@ -1438,12 +1475,14 @@ const DocumentActionButton = (action) => {
|
|
1438
1475
|
/* @__PURE__ */ jsxRuntime.jsx(
|
1439
1476
|
designSystem.Button,
|
1440
1477
|
{
|
1441
|
-
flex:
|
1478
|
+
flex: "auto",
|
1442
1479
|
startIcon: action.icon,
|
1443
1480
|
disabled: action.disabled,
|
1444
1481
|
onClick: handleClick(action),
|
1445
1482
|
justifyContent: "center",
|
1446
1483
|
variant: action.variant || "default",
|
1484
|
+
paddingTop: "7px",
|
1485
|
+
paddingBottom: "7px",
|
1447
1486
|
children: action.label
|
1448
1487
|
}
|
1449
1488
|
),
|
@@ -1451,7 +1490,7 @@ const DocumentActionButton = (action) => {
|
|
1451
1490
|
DocumentActionConfirmDialog,
|
1452
1491
|
{
|
1453
1492
|
...action.dialog,
|
1454
|
-
variant: action.variant,
|
1493
|
+
variant: action.dialog?.variant ?? action.variant,
|
1455
1494
|
isOpen: dialogId === action.id,
|
1456
1495
|
onClose: handleClose
|
1457
1496
|
}
|
@@ -1503,14 +1542,14 @@ const DocumentActionsMenu = ({
|
|
1503
1542
|
};
|
1504
1543
|
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Root, { open: isOpen, onOpenChange: setIsOpen, children: [
|
1505
1544
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
1506
|
-
|
1545
|
+
StyledMoreButton,
|
1507
1546
|
{
|
1508
1547
|
disabled: isDisabled,
|
1509
1548
|
size: "S",
|
1510
1549
|
endIcon: null,
|
1511
|
-
paddingTop: "
|
1512
|
-
paddingLeft: "
|
1513
|
-
paddingRight: "
|
1550
|
+
paddingTop: "4px",
|
1551
|
+
paddingLeft: "7px",
|
1552
|
+
paddingRight: "7px",
|
1514
1553
|
variant,
|
1515
1554
|
children: [
|
1516
1555
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.More, { "aria-hidden": true, focusable: false }),
|
@@ -1530,10 +1569,25 @@ const DocumentActionsMenu = ({
|
|
1530
1569
|
onSelect: handleClick(action),
|
1531
1570
|
display: "block",
|
1532
1571
|
children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", gap: 4, children: [
|
1533
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1572
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
1573
|
+
designSystem.Flex,
|
1574
|
+
{
|
1575
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1576
|
+
gap: 2,
|
1577
|
+
tag: "span",
|
1578
|
+
children: [
|
1579
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
1580
|
+
designSystem.Flex,
|
1581
|
+
{
|
1582
|
+
tag: "span",
|
1583
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1584
|
+
children: action.icon
|
1585
|
+
}
|
1586
|
+
),
|
1587
|
+
action.label
|
1588
|
+
]
|
1589
|
+
}
|
1590
|
+
),
|
1537
1591
|
action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsxRuntime.jsx(
|
1538
1592
|
designSystem.Flex,
|
1539
1593
|
{
|
@@ -1604,6 +1658,11 @@ const convertActionVariantToIconColor = (variant = "secondary") => {
|
|
1604
1658
|
return "primary600";
|
1605
1659
|
}
|
1606
1660
|
};
|
1661
|
+
const StyledMoreButton = styledComponents.styled(designSystem.Menu.Trigger)`
|
1662
|
+
& > span {
|
1663
|
+
display: flex;
|
1664
|
+
}
|
1665
|
+
`;
|
1607
1666
|
const DocumentActionConfirmDialog = ({
|
1608
1667
|
onClose,
|
1609
1668
|
onCancel,
|
@@ -1673,13 +1732,17 @@ const PublishAction$1 = ({
|
|
1673
1732
|
const navigate = reactRouterDom.useNavigate();
|
1674
1733
|
const { toggleNotification } = strapiAdmin.useNotification();
|
1675
1734
|
const { _unstableFormatValidationErrors: formatValidationErrors } = strapiAdmin.useAPIErrorHandler();
|
1735
|
+
const isListView = reactRouterDom.useMatch(LIST_PATH) !== null;
|
1676
1736
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
1677
1737
|
const { formatMessage } = reactIntl.useIntl();
|
1678
|
-
const { canPublish
|
1679
|
-
"PublishAction",
|
1680
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1681
|
-
);
|
1738
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1682
1739
|
const { publish } = useDocumentActions();
|
1740
|
+
const [
|
1741
|
+
countDraftRelations,
|
1742
|
+
{ isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
|
1743
|
+
] = useLazyGetDraftRelationCountQuery();
|
1744
|
+
const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React__namespace.useState(0);
|
1745
|
+
const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React__namespace.useState(0);
|
1683
1746
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1684
1747
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
1685
1748
|
const modified = strapiAdmin.useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
@@ -1688,10 +1751,101 @@ const PublishAction$1 = ({
|
|
1688
1751
|
const validate = strapiAdmin.useForm("PublishAction", (state) => state.validate);
|
1689
1752
|
const setErrors = strapiAdmin.useForm("PublishAction", (state) => state.setErrors);
|
1690
1753
|
const formValues = strapiAdmin.useForm("PublishAction", ({ values }) => values);
|
1754
|
+
React__namespace.useEffect(() => {
|
1755
|
+
if (isErrorDraftRelations) {
|
1756
|
+
toggleNotification({
|
1757
|
+
type: "danger",
|
1758
|
+
message: formatMessage({
|
1759
|
+
id: getTranslation("error.records.fetch-draft-relatons"),
|
1760
|
+
defaultMessage: "An error occurred while fetching draft relations on this document."
|
1761
|
+
})
|
1762
|
+
});
|
1763
|
+
}
|
1764
|
+
}, [isErrorDraftRelations, toggleNotification, formatMessage]);
|
1765
|
+
React__namespace.useEffect(() => {
|
1766
|
+
const localDraftRelations = /* @__PURE__ */ new Set();
|
1767
|
+
const extractDraftRelations = (data) => {
|
1768
|
+
const relations = data.connect || [];
|
1769
|
+
relations.forEach((relation) => {
|
1770
|
+
if (relation.status === "draft") {
|
1771
|
+
localDraftRelations.add(relation.id);
|
1772
|
+
}
|
1773
|
+
});
|
1774
|
+
};
|
1775
|
+
const traverseAndExtract = (data) => {
|
1776
|
+
Object.entries(data).forEach(([key, value]) => {
|
1777
|
+
if (key === "connect" && Array.isArray(value)) {
|
1778
|
+
extractDraftRelations({ connect: value });
|
1779
|
+
} else if (typeof value === "object" && value !== null) {
|
1780
|
+
traverseAndExtract(value);
|
1781
|
+
}
|
1782
|
+
});
|
1783
|
+
};
|
1784
|
+
if (!documentId || modified) {
|
1785
|
+
traverseAndExtract(formValues);
|
1786
|
+
setLocalCountOfDraftRelations(localDraftRelations.size);
|
1787
|
+
}
|
1788
|
+
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
1789
|
+
React__namespace.useEffect(() => {
|
1790
|
+
if (documentId && !isListView) {
|
1791
|
+
const fetchDraftRelationsCount = async () => {
|
1792
|
+
const { data, error } = await countDraftRelations({
|
1793
|
+
collectionType,
|
1794
|
+
model,
|
1795
|
+
documentId,
|
1796
|
+
params
|
1797
|
+
});
|
1798
|
+
if (error) {
|
1799
|
+
throw error;
|
1800
|
+
}
|
1801
|
+
if (data) {
|
1802
|
+
setServerCountOfDraftRelations(data.data);
|
1803
|
+
}
|
1804
|
+
};
|
1805
|
+
fetchDraftRelationsCount();
|
1806
|
+
}
|
1807
|
+
}, [isListView, documentId, countDraftRelations, collectionType, model, params]);
|
1691
1808
|
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
1692
1809
|
if (!schema?.options?.draftAndPublish) {
|
1693
1810
|
return null;
|
1694
1811
|
}
|
1812
|
+
const performPublish = async () => {
|
1813
|
+
setSubmitting(true);
|
1814
|
+
try {
|
1815
|
+
const { errors } = await validate();
|
1816
|
+
if (errors) {
|
1817
|
+
toggleNotification({
|
1818
|
+
type: "danger",
|
1819
|
+
message: formatMessage({
|
1820
|
+
id: "content-manager.validation.error",
|
1821
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
1822
|
+
})
|
1823
|
+
});
|
1824
|
+
return;
|
1825
|
+
}
|
1826
|
+
const res = await publish(
|
1827
|
+
{
|
1828
|
+
collectionType,
|
1829
|
+
model,
|
1830
|
+
documentId,
|
1831
|
+
params
|
1832
|
+
},
|
1833
|
+
formValues
|
1834
|
+
);
|
1835
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1836
|
+
navigate({
|
1837
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1838
|
+
search: rawQuery
|
1839
|
+
});
|
1840
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1841
|
+
setErrors(formatValidationErrors(res.error));
|
1842
|
+
}
|
1843
|
+
} finally {
|
1844
|
+
setSubmitting(false);
|
1845
|
+
}
|
1846
|
+
};
|
1847
|
+
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
1848
|
+
const hasDraftRelations = totalDraftRelations > 0;
|
1695
1849
|
return {
|
1696
1850
|
/**
|
1697
1851
|
* Disabled when:
|
@@ -1701,49 +1855,39 @@ const PublishAction$1 = ({
|
|
1701
1855
|
* - the document is already published & not modified
|
1702
1856
|
* - the document is being created & not modified
|
1703
1857
|
* - the user doesn't have the permission to publish
|
1704
|
-
* - the user doesn't have the permission to create a new document
|
1705
|
-
* - the user doesn't have the permission to update the document
|
1706
1858
|
*/
|
1707
|
-
disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish
|
1859
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
1708
1860
|
label: formatMessage({
|
1709
1861
|
id: "app.utils.publish",
|
1710
1862
|
defaultMessage: "Publish"
|
1711
1863
|
}),
|
1712
1864
|
onClick: async () => {
|
1713
|
-
|
1714
|
-
|
1715
|
-
|
1716
|
-
|
1717
|
-
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
|
1726
|
-
|
1727
|
-
|
1728
|
-
|
1729
|
-
|
1730
|
-
|
1731
|
-
|
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));
|
1865
|
+
if (hasDraftRelations) {
|
1866
|
+
return;
|
1867
|
+
}
|
1868
|
+
await performPublish();
|
1869
|
+
},
|
1870
|
+
dialog: hasDraftRelations ? {
|
1871
|
+
type: "dialog",
|
1872
|
+
variant: "danger",
|
1873
|
+
footer: null,
|
1874
|
+
title: formatMessage({
|
1875
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
|
1876
|
+
defaultMessage: "Confirmation"
|
1877
|
+
}),
|
1878
|
+
content: formatMessage(
|
1879
|
+
{
|
1880
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
1881
|
+
defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
|
1882
|
+
},
|
1883
|
+
{
|
1884
|
+
count: totalDraftRelations
|
1742
1885
|
}
|
1743
|
-
|
1744
|
-
|
1886
|
+
),
|
1887
|
+
onConfirm: async () => {
|
1888
|
+
await performPublish();
|
1745
1889
|
}
|
1746
|
-
}
|
1890
|
+
} : void 0
|
1747
1891
|
};
|
1748
1892
|
};
|
1749
1893
|
PublishAction$1.type = "publish";
|
@@ -1759,10 +1903,6 @@ const UpdateAction = ({
|
|
1759
1903
|
const cloneMatch = reactRouterDom.useMatch(CLONE_PATH);
|
1760
1904
|
const isCloning = cloneMatch !== null;
|
1761
1905
|
const { formatMessage } = reactIntl.useIntl();
|
1762
|
-
const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1763
|
-
canCreate: canCreate2,
|
1764
|
-
canUpdate: canUpdate2
|
1765
|
-
}));
|
1766
1906
|
const { create, update, clone } = useDocumentActions();
|
1767
1907
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1768
1908
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
@@ -1779,10 +1919,8 @@ const UpdateAction = ({
|
|
1779
1919
|
* - the form is submitting
|
1780
1920
|
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
1781
1921
|
* - 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
1922
|
*/
|
1785
|
-
disabled: isSubmitting || !modified && !isCloning || activeTab === "published"
|
1923
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1786
1924
|
label: formatMessage({
|
1787
1925
|
id: "content-manager.containers.Edit.save",
|
1788
1926
|
defaultMessage: "Save"
|
@@ -1790,16 +1928,18 @@ const UpdateAction = ({
|
|
1790
1928
|
onClick: async () => {
|
1791
1929
|
setSubmitting(true);
|
1792
1930
|
try {
|
1793
|
-
|
1794
|
-
|
1795
|
-
|
1796
|
-
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
1800
|
-
|
1801
|
-
|
1802
|
-
|
1931
|
+
if (activeTab !== "draft") {
|
1932
|
+
const { errors } = await validate();
|
1933
|
+
if (errors) {
|
1934
|
+
toggleNotification({
|
1935
|
+
type: "danger",
|
1936
|
+
message: formatMessage({
|
1937
|
+
id: "content-manager.validation.error",
|
1938
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
1939
|
+
})
|
1940
|
+
});
|
1941
|
+
return;
|
1942
|
+
}
|
1803
1943
|
}
|
1804
1944
|
if (isCloning) {
|
1805
1945
|
const res = await clone(
|
@@ -1811,10 +1951,13 @@ const UpdateAction = ({
|
|
1811
1951
|
document
|
1812
1952
|
);
|
1813
1953
|
if ("data" in res) {
|
1814
|
-
navigate(
|
1815
|
-
|
1816
|
-
|
1817
|
-
|
1954
|
+
navigate(
|
1955
|
+
{
|
1956
|
+
pathname: `../${res.data.documentId}`,
|
1957
|
+
search: rawQuery
|
1958
|
+
},
|
1959
|
+
{ relative: "path" }
|
1960
|
+
);
|
1818
1961
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1819
1962
|
setErrors(formatValidationErrors(res.error));
|
1820
1963
|
}
|
@@ -1842,10 +1985,13 @@ const UpdateAction = ({
|
|
1842
1985
|
document
|
1843
1986
|
);
|
1844
1987
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1845
|
-
navigate(
|
1846
|
-
|
1847
|
-
|
1848
|
-
|
1988
|
+
navigate(
|
1989
|
+
{
|
1990
|
+
pathname: `../${res.data.documentId}`,
|
1991
|
+
search: rawQuery
|
1992
|
+
},
|
1993
|
+
{ replace: true, relative: "path" }
|
1994
|
+
);
|
1849
1995
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1850
1996
|
setErrors(formatValidationErrors(res.error));
|
1851
1997
|
}
|
@@ -2091,23 +2237,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
|
2091
2237
|
id: "content-manager.containers.edit.title.new",
|
2092
2238
|
defaultMessage: "Create an entry"
|
2093
2239
|
}) : documentTitle;
|
2094
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop:
|
2240
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2095
2241
|
/* @__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
|
2242
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2243
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
|
2244
|
+
/* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
|
2245
|
+
] }),
|
2246
|
+
status ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 1, children: /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
|
2111
2247
|
] });
|
2112
2248
|
};
|
2113
2249
|
const HeaderToolbar = () => {
|
@@ -2798,7 +2934,7 @@ const ConfirmBulkActionDialog = ({
|
|
2798
2934
|
endAction
|
2799
2935
|
}) => {
|
2800
2936
|
const { formatMessage } = reactIntl.useIntl();
|
2801
|
-
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, {
|
2937
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
2802
2938
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: formatMessage({
|
2803
2939
|
id: "app.components.ConfirmDialog.title",
|
2804
2940
|
defaultMessage: "Confirmation"
|
@@ -2919,7 +3055,14 @@ const formatErrorMessages = (errors, parentKey, formatMessage) => {
|
|
2919
3055
|
)
|
2920
3056
|
);
|
2921
3057
|
} else {
|
2922
|
-
messages.push(
|
3058
|
+
messages.push(
|
3059
|
+
...formatErrorMessages(
|
3060
|
+
// @ts-expect-error TODO: check why value is not compatible with FormErrors
|
3061
|
+
value,
|
3062
|
+
currentKey,
|
3063
|
+
formatMessage
|
3064
|
+
)
|
3065
|
+
);
|
2923
3066
|
}
|
2924
3067
|
} else {
|
2925
3068
|
messages.push(
|
@@ -3080,7 +3223,13 @@ const SelectedEntriesModalContent = ({
|
|
3080
3223
|
);
|
3081
3224
|
const { rows, validationErrors } = React__namespace.useMemo(() => {
|
3082
3225
|
if (data.length > 0 && schema) {
|
3083
|
-
const validate = createYupSchema(
|
3226
|
+
const validate = createYupSchema(
|
3227
|
+
schema.attributes,
|
3228
|
+
components,
|
3229
|
+
// Since this is the "Publish" action, the validation
|
3230
|
+
// schema must enforce the rules for published entities
|
3231
|
+
{ status: "published" }
|
3232
|
+
);
|
3084
3233
|
const validationErrors2 = {};
|
3085
3234
|
const rows2 = data.map((entry) => {
|
3086
3235
|
try {
|
@@ -3430,7 +3579,7 @@ const TableActions = ({ document }) => {
|
|
3430
3579
|
strapiAdmin.DescriptionComponentRenderer,
|
3431
3580
|
{
|
3432
3581
|
props,
|
3433
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3582
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
3434
3583
|
children: (actions2) => {
|
3435
3584
|
const tableRowActions = actions2.filter((action) => {
|
3436
3585
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3541,7 +3690,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3541
3690
|
}),
|
3542
3691
|
content: /* @__PURE__ */ jsxRuntime.jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
3543
3692
|
footer: ({ onClose }) => {
|
3544
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.
|
3693
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
3545
3694
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
3546
3695
|
id: "cancel",
|
3547
3696
|
defaultMessage: "Cancel"
|
@@ -3582,8 +3731,7 @@ class ContentManagerPlugin {
|
|
3582
3731
|
documentActions = [
|
3583
3732
|
...DEFAULT_ACTIONS,
|
3584
3733
|
...DEFAULT_TABLE_ROW_ACTIONS,
|
3585
|
-
...DEFAULT_HEADER_ACTIONS
|
3586
|
-
HistoryAction
|
3734
|
+
...DEFAULT_HEADER_ACTIONS
|
3587
3735
|
];
|
3588
3736
|
editViewSidePanels = [ActionsPanel];
|
3589
3737
|
headerActions = [];
|
@@ -3672,6 +3820,52 @@ const getPrintableType = (value) => {
|
|
3672
3820
|
}
|
3673
3821
|
return nativeType;
|
3674
3822
|
};
|
3823
|
+
const HistoryAction = ({ model, document }) => {
|
3824
|
+
const { formatMessage } = reactIntl.useIntl();
|
3825
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3826
|
+
const navigate = reactRouterDom.useNavigate();
|
3827
|
+
const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
|
3828
|
+
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3829
|
+
return null;
|
3830
|
+
}
|
3831
|
+
return {
|
3832
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
|
3833
|
+
label: formatMessage({
|
3834
|
+
id: "content-manager.history.document-action",
|
3835
|
+
defaultMessage: "Content History"
|
3836
|
+
}),
|
3837
|
+
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
3838
|
+
disabled: (
|
3839
|
+
/**
|
3840
|
+
* The user is creating a new document.
|
3841
|
+
* It hasn't been saved yet, so there's no history to go to
|
3842
|
+
*/
|
3843
|
+
!document || /**
|
3844
|
+
* The document has been created but the current dimension has never been saved.
|
3845
|
+
* For example, the user is creating a new locale in an existing document,
|
3846
|
+
* so there's no history for the document in that locale
|
3847
|
+
*/
|
3848
|
+
!document.id || /**
|
3849
|
+
* History is only available for content types created by the user.
|
3850
|
+
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
3851
|
+
* which start with `admin::` or `plugin::`
|
3852
|
+
*/
|
3853
|
+
!model.startsWith("api::")
|
3854
|
+
),
|
3855
|
+
position: "header"
|
3856
|
+
};
|
3857
|
+
};
|
3858
|
+
HistoryAction.type = "history";
|
3859
|
+
const historyAdmin = {
|
3860
|
+
bootstrap(app) {
|
3861
|
+
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
3862
|
+
addDocumentAction((actions2) => {
|
3863
|
+
const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
|
3864
|
+
actions2.splice(indexOfDeleteAction, 0, HistoryAction);
|
3865
|
+
return actions2;
|
3866
|
+
});
|
3867
|
+
}
|
3868
|
+
};
|
3675
3869
|
const initialState = {
|
3676
3870
|
collectionTypeLinks: [],
|
3677
3871
|
components: [],
|
@@ -3727,7 +3921,7 @@ const index = {
|
|
3727
3921
|
app.router.addRoute({
|
3728
3922
|
path: "content-manager/*",
|
3729
3923
|
lazy: async () => {
|
3730
|
-
const { Layout } = await Promise.resolve().then(() => require("./layout-
|
3924
|
+
const { Layout } = await Promise.resolve().then(() => require("./layout-C788OmNr.js"));
|
3731
3925
|
return {
|
3732
3926
|
Component: Layout
|
3733
3927
|
};
|
@@ -3736,10 +3930,15 @@ const index = {
|
|
3736
3930
|
});
|
3737
3931
|
app.registerPlugin(cm.config);
|
3738
3932
|
},
|
3933
|
+
bootstrap(app) {
|
3934
|
+
if (typeof historyAdmin.bootstrap === "function") {
|
3935
|
+
historyAdmin.bootstrap(app);
|
3936
|
+
}
|
3937
|
+
},
|
3739
3938
|
async registerTrads({ locales }) {
|
3740
3939
|
const importedTrads = await Promise.all(
|
3741
3940
|
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-
|
3941
|
+
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-uOUIxfcQ.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
3942
|
return {
|
3744
3943
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3745
3944
|
locale
|
@@ -3757,6 +3956,7 @@ const index = {
|
|
3757
3956
|
};
|
3758
3957
|
exports.ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD = ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD;
|
3759
3958
|
exports.BulkActionsRenderer = BulkActionsRenderer;
|
3959
|
+
exports.CLONE_PATH = CLONE_PATH;
|
3760
3960
|
exports.COLLECTION_TYPES = COLLECTION_TYPES;
|
3761
3961
|
exports.CREATOR_FIELDS = CREATOR_FIELDS;
|
3762
3962
|
exports.DEFAULT_SETTINGS = DEFAULT_SETTINGS;
|
@@ -3796,4 +3996,4 @@ exports.useGetAllDocumentsQuery = useGetAllDocumentsQuery;
|
|
3796
3996
|
exports.useGetContentTypeConfigurationQuery = useGetContentTypeConfigurationQuery;
|
3797
3997
|
exports.useGetInitialDataQuery = useGetInitialDataQuery;
|
3798
3998
|
exports.useUpdateContentTypeConfigurationMutation = useUpdateContentTypeConfigurationMutation;
|
3799
|
-
//# sourceMappingURL=index-
|
3999
|
+
//# sourceMappingURL=index-C3fJE-1-.js.map
|