@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
@@ -1,17 +1,17 @@
|
|
1
|
-
import {
|
1
|
+
import { CrossCircle, More, WarningCircle, ListPlus, Pencil, Trash, Check, CheckCircle, ArrowsCounterClockwise, ChevronRight, Duplicate, ClockCounterClockwise, Feather } from "@strapi/icons";
|
2
2
|
import { jsx, Fragment, jsxs } from "react/jsx-runtime";
|
3
|
-
import { useStrapiApp,
|
4
|
-
import { stringify } from "qs";
|
5
|
-
import { useIntl } from "react-intl";
|
6
|
-
import { useNavigate, useParams, Navigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
|
3
|
+
import { useStrapiApp, createContext, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, getYupValidationErrors, useQueryParams, useTracking, useForm, BackButton, DescriptionComponentRenderer, useTable, Table } from "@strapi/admin/strapi-admin";
|
7
4
|
import * as React from "react";
|
8
5
|
import { lazy } from "react";
|
9
|
-
import {
|
6
|
+
import { Menu, Button, VisuallyHidden, Flex, Typography, Dialog, Modal, Radio, Status, Box, SingleSelect, SingleSelectOption, Loader, IconButton, Tooltip, LinkButton } from "@strapi/design-system";
|
7
|
+
import { useIntl } from "react-intl";
|
8
|
+
import { useParams, useNavigate, Navigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
|
10
9
|
import { styled } from "styled-components";
|
11
10
|
import * as yup from "yup";
|
12
11
|
import { ValidationError } from "yup";
|
13
12
|
import pipe from "lodash/fp/pipe";
|
14
13
|
import { intervalToDuration, isPast } from "date-fns";
|
14
|
+
import { stringify } from "qs";
|
15
15
|
import { createSlice, combineReducers } from "@reduxjs/toolkit";
|
16
16
|
const __variableDynamicImportRuntimeHelper = (glob, path) => {
|
17
17
|
const v = glob[path];
|
@@ -49,42 +49,6 @@ const useInjectionZone = (area) => {
|
|
49
49
|
const [page, position] = area.split(".");
|
50
50
|
return contentManagerPlugin.getInjectedComponents(page, position);
|
51
51
|
};
|
52
|
-
const HistoryAction = ({ model, document }) => {
|
53
|
-
const { formatMessage } = useIntl();
|
54
|
-
const [{ query }] = useQueryParams();
|
55
|
-
const navigate = useNavigate();
|
56
|
-
const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
|
57
|
-
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
58
|
-
return null;
|
59
|
-
}
|
60
|
-
return {
|
61
|
-
icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
|
62
|
-
label: formatMessage({
|
63
|
-
id: "content-manager.history.document-action",
|
64
|
-
defaultMessage: "Content History"
|
65
|
-
}),
|
66
|
-
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
67
|
-
disabled: (
|
68
|
-
/**
|
69
|
-
* The user is creating a new document.
|
70
|
-
* It hasn't been saved yet, so there's no history to go to
|
71
|
-
*/
|
72
|
-
!document || /**
|
73
|
-
* The document has been created but the current dimension has never been saved.
|
74
|
-
* For example, the user is creating a new locale in an existing document,
|
75
|
-
* so there's no history for the document in that locale
|
76
|
-
*/
|
77
|
-
!document.id || /**
|
78
|
-
* History is only available for content types created by the user.
|
79
|
-
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
80
|
-
* which start with `admin::` or `plugin::`
|
81
|
-
*/
|
82
|
-
!model.startsWith("api::")
|
83
|
-
),
|
84
|
-
position: "header"
|
85
|
-
};
|
86
|
-
};
|
87
|
-
HistoryAction.type = "history";
|
88
52
|
const ID = "id";
|
89
53
|
const CREATED_BY_ATTRIBUTE_NAME = "createdBy";
|
90
54
|
const UPDATED_BY_ATTRIBUTE_NAME = "updatedBy";
|
@@ -194,7 +158,8 @@ const contentManagerApi = adminApi.enhanceEndpoints({
|
|
194
158
|
"Document",
|
195
159
|
"InitialData",
|
196
160
|
"HistoryVersion",
|
197
|
-
"Relations"
|
161
|
+
"Relations",
|
162
|
+
"UidAvailability"
|
198
163
|
]
|
199
164
|
});
|
200
165
|
const documentApi = contentManagerApi.injectEndpoints({
|
@@ -208,7 +173,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
208
173
|
params: query
|
209
174
|
}
|
210
175
|
}),
|
211
|
-
invalidatesTags: (_result,
|
176
|
+
invalidatesTags: (_result, error, { model }) => {
|
177
|
+
if (error) {
|
178
|
+
return [];
|
179
|
+
}
|
180
|
+
return [{ type: "Document", id: `${model}_LIST` }];
|
181
|
+
}
|
212
182
|
}),
|
213
183
|
cloneDocument: builder.mutation({
|
214
184
|
query: ({ model, sourceId, data, params }) => ({
|
@@ -219,7 +189,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
219
189
|
params
|
220
190
|
}
|
221
191
|
}),
|
222
|
-
invalidatesTags: (_result, _error, { model }) => [
|
192
|
+
invalidatesTags: (_result, _error, { model }) => [
|
193
|
+
{ type: "Document", id: `${model}_LIST` },
|
194
|
+
{ type: "UidAvailability", id: model }
|
195
|
+
]
|
223
196
|
}),
|
224
197
|
/**
|
225
198
|
* Creates a new collection-type document. This should ONLY be used for collection-types.
|
@@ -236,7 +209,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
236
209
|
}),
|
237
210
|
invalidatesTags: (result, _error, { model }) => [
|
238
211
|
{ type: "Document", id: `${model}_LIST` },
|
239
|
-
"Relations"
|
212
|
+
"Relations",
|
213
|
+
{ type: "UidAvailability", id: model }
|
240
214
|
]
|
241
215
|
}),
|
242
216
|
deleteDocument: builder.mutation({
|
@@ -277,7 +251,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
277
251
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
278
252
|
},
|
279
253
|
{ type: "Document", id: `${model}_LIST` },
|
280
|
-
"Relations"
|
254
|
+
"Relations",
|
255
|
+
{ type: "UidAvailability", id: model }
|
281
256
|
];
|
282
257
|
}
|
283
258
|
}),
|
@@ -295,6 +270,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
295
270
|
}),
|
296
271
|
providesTags: (result, _error, arg) => {
|
297
272
|
return [
|
273
|
+
{ type: "Document", id: `ALL_LIST` },
|
298
274
|
{ type: "Document", id: `${arg.model}_LIST` },
|
299
275
|
...result?.results.map(({ documentId }) => ({
|
300
276
|
type: "Document",
|
@@ -333,6 +309,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
333
309
|
{
|
334
310
|
type: "Document",
|
335
311
|
id: collectionType !== SINGLE_TYPES ? `${model}_${result && "documentId" in result ? result.documentId : documentId}` : model
|
312
|
+
},
|
313
|
+
// Make it easy to invalidate all individual documents queries for a model
|
314
|
+
{
|
315
|
+
type: "Document",
|
316
|
+
id: `${model}_ALL_ITEMS`
|
336
317
|
}
|
337
318
|
];
|
338
319
|
}
|
@@ -396,8 +377,21 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
396
377
|
type: "Document",
|
397
378
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
398
379
|
},
|
399
|
-
"Relations"
|
380
|
+
"Relations",
|
381
|
+
{ type: "UidAvailability", id: model }
|
400
382
|
];
|
383
|
+
},
|
384
|
+
async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
|
385
|
+
const patchResult = dispatch(
|
386
|
+
documentApi.util.updateQueryData("getDocument", patch, (draft) => {
|
387
|
+
Object.assign(draft.data, data);
|
388
|
+
})
|
389
|
+
);
|
390
|
+
try {
|
391
|
+
await queryFulfilled;
|
392
|
+
} catch {
|
393
|
+
patchResult.undo();
|
394
|
+
}
|
401
395
|
}
|
402
396
|
}),
|
403
397
|
unpublishDocument: builder.mutation({
|
@@ -467,7 +461,7 @@ const buildValidParams = (query) => {
|
|
467
461
|
const isBaseQueryError = (error) => {
|
468
462
|
return error.name !== void 0;
|
469
463
|
};
|
470
|
-
const createYupSchema = (attributes = {}, components = {}) => {
|
464
|
+
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
471
465
|
const createModelSchema = (attributes2) => yup.object().shape(
|
472
466
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
473
467
|
if (DOCUMENT_META_FIELDS.includes(name)) {
|
@@ -480,7 +474,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
480
474
|
addMinValidation,
|
481
475
|
addMaxValidation,
|
482
476
|
addRegexValidation
|
483
|
-
].map((fn) => fn(attribute));
|
477
|
+
].map((fn) => fn(attribute, options));
|
484
478
|
const transformSchema = pipe(...validations);
|
485
479
|
switch (attribute.type) {
|
486
480
|
case "component": {
|
@@ -581,6 +575,14 @@ const createAttributeSchema = (attribute) => {
|
|
581
575
|
if (!value || typeof value === "string" && value.length === 0) {
|
582
576
|
return true;
|
583
577
|
}
|
578
|
+
if (typeof value === "object") {
|
579
|
+
try {
|
580
|
+
JSON.stringify(value);
|
581
|
+
return true;
|
582
|
+
} catch (err) {
|
583
|
+
return false;
|
584
|
+
}
|
585
|
+
}
|
584
586
|
try {
|
585
587
|
JSON.parse(value);
|
586
588
|
return true;
|
@@ -599,13 +601,7 @@ const createAttributeSchema = (attribute) => {
|
|
599
601
|
return yup.mixed();
|
600
602
|
}
|
601
603
|
};
|
602
|
-
const
|
603
|
-
if (attribute.required) {
|
604
|
-
return schema.required({
|
605
|
-
id: translatedErrors.required.id,
|
606
|
-
defaultMessage: "This field is required."
|
607
|
-
});
|
608
|
-
}
|
604
|
+
const nullableSchema = (schema) => {
|
609
605
|
return schema?.nullable ? schema.nullable() : (
|
610
606
|
// In some cases '.nullable' will not be available on the schema.
|
611
607
|
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
@@ -613,7 +609,22 @@ const addRequiredValidation = (attribute) => (schema) => {
|
|
613
609
|
schema
|
614
610
|
);
|
615
611
|
};
|
616
|
-
const
|
612
|
+
const addRequiredValidation = (attribute, options) => (schema) => {
|
613
|
+
if (options.status === "draft") {
|
614
|
+
return nullableSchema(schema);
|
615
|
+
}
|
616
|
+
if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
|
617
|
+
return schema.min(1, translatedErrors.required);
|
618
|
+
}
|
619
|
+
if (attribute.required && attribute.type !== "relation") {
|
620
|
+
return schema.required(translatedErrors.required);
|
621
|
+
}
|
622
|
+
return nullableSchema(schema);
|
623
|
+
};
|
624
|
+
const addMinLengthValidation = (attribute, options) => (schema) => {
|
625
|
+
if (options.status === "draft") {
|
626
|
+
return schema;
|
627
|
+
}
|
617
628
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
618
629
|
return schema.min(attribute.minLength, {
|
619
630
|
...translatedErrors.minLength,
|
@@ -635,9 +646,31 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
635
646
|
}
|
636
647
|
return schema;
|
637
648
|
};
|
638
|
-
const addMinValidation = (attribute) => (schema) => {
|
649
|
+
const addMinValidation = (attribute, options) => (schema) => {
|
639
650
|
if ("min" in attribute) {
|
640
651
|
const min = toInteger(attribute.min);
|
652
|
+
if (attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") {
|
653
|
+
if (options.status !== "draft" && !attribute.required && "test" in schema && min) {
|
654
|
+
return schema.test(
|
655
|
+
"custom-min",
|
656
|
+
{
|
657
|
+
...translatedErrors.min,
|
658
|
+
values: {
|
659
|
+
min: attribute.min
|
660
|
+
}
|
661
|
+
},
|
662
|
+
(value) => {
|
663
|
+
if (!value) {
|
664
|
+
return true;
|
665
|
+
}
|
666
|
+
if (Array.isArray(value) && value.length === 0) {
|
667
|
+
return true;
|
668
|
+
}
|
669
|
+
return value.length >= min;
|
670
|
+
}
|
671
|
+
);
|
672
|
+
}
|
673
|
+
}
|
641
674
|
if ("min" in schema && min) {
|
642
675
|
return schema.min(min, {
|
643
676
|
...translatedErrors.min,
|
@@ -764,7 +797,10 @@ const useDocument = (args, opts) => {
|
|
764
797
|
isLoading: isLoadingDocument,
|
765
798
|
isFetching: isFetchingDocument,
|
766
799
|
error
|
767
|
-
} = useGetDocumentQuery(args,
|
800
|
+
} = useGetDocumentQuery(args, {
|
801
|
+
...opts,
|
802
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
803
|
+
});
|
768
804
|
const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
|
769
805
|
React.useEffect(() => {
|
770
806
|
if (error) {
|
@@ -850,6 +886,7 @@ const useDocumentActions = () => {
|
|
850
886
|
const { formatMessage } = useIntl();
|
851
887
|
const { trackUsage } = useTracking();
|
852
888
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
889
|
+
const navigate = useNavigate();
|
853
890
|
const [deleteDocument] = useDeleteDocumentMutation();
|
854
891
|
const _delete = React.useCallback(
|
855
892
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -1185,7 +1222,6 @@ const useDocumentActions = () => {
|
|
1185
1222
|
sourceId
|
1186
1223
|
});
|
1187
1224
|
if ("error" in res) {
|
1188
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1189
1225
|
return { error: res.error };
|
1190
1226
|
}
|
1191
1227
|
toggleNotification({
|
@@ -1204,7 +1240,7 @@ const useDocumentActions = () => {
|
|
1204
1240
|
throw err;
|
1205
1241
|
}
|
1206
1242
|
},
|
1207
|
-
[autoCloneDocument,
|
1243
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1208
1244
|
);
|
1209
1245
|
const [cloneDocument] = useCloneDocumentMutation();
|
1210
1246
|
const clone = React.useCallback(
|
@@ -1230,6 +1266,7 @@ const useDocumentActions = () => {
|
|
1230
1266
|
defaultMessage: "Cloned document"
|
1231
1267
|
})
|
1232
1268
|
});
|
1269
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1233
1270
|
return res.data;
|
1234
1271
|
} catch (err) {
|
1235
1272
|
toggleNotification({
|
@@ -1240,7 +1277,7 @@ const useDocumentActions = () => {
|
|
1240
1277
|
throw err;
|
1241
1278
|
}
|
1242
1279
|
},
|
1243
|
-
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
|
1280
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1244
1281
|
);
|
1245
1282
|
const [getDoc] = useLazyGetDocumentQuery();
|
1246
1283
|
const getDocument = React.useCallback(
|
@@ -1266,7 +1303,7 @@ const useDocumentActions = () => {
|
|
1266
1303
|
};
|
1267
1304
|
};
|
1268
1305
|
const ProtectedHistoryPage = lazy(
|
1269
|
-
() => import("./History-
|
1306
|
+
() => import("./History-BowL3JKP.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1270
1307
|
);
|
1271
1308
|
const routes$1 = [
|
1272
1309
|
{
|
@@ -1279,31 +1316,31 @@ const routes$1 = [
|
|
1279
1316
|
}
|
1280
1317
|
];
|
1281
1318
|
const ProtectedEditViewPage = lazy(
|
1282
|
-
() => import("./EditViewPage-
|
1319
|
+
() => import("./EditViewPage-De8GyU8P.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1283
1320
|
);
|
1284
1321
|
const ProtectedListViewPage = lazy(
|
1285
|
-
() => import("./ListViewPage-
|
1322
|
+
() => import("./ListViewPage-CXFUjZQC.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1286
1323
|
);
|
1287
1324
|
const ProtectedListConfiguration = lazy(
|
1288
|
-
() => import("./ListConfigurationPage-
|
1325
|
+
() => import("./ListConfigurationPage-BpVOB-hn.mjs").then((mod) => ({
|
1289
1326
|
default: mod.ProtectedListConfiguration
|
1290
1327
|
}))
|
1291
1328
|
);
|
1292
1329
|
const ProtectedEditConfigurationPage = lazy(
|
1293
|
-
() => import("./EditConfigurationPage-
|
1330
|
+
() => import("./EditConfigurationPage-CjUrEewK.mjs").then((mod) => ({
|
1294
1331
|
default: mod.ProtectedEditConfigurationPage
|
1295
1332
|
}))
|
1296
1333
|
);
|
1297
1334
|
const ProtectedComponentConfigurationPage = lazy(
|
1298
|
-
() => import("./ComponentConfigurationPage-
|
1335
|
+
() => import("./ComponentConfigurationPage-qemkOlnj.mjs").then((mod) => ({
|
1299
1336
|
default: mod.ProtectedComponentConfigurationPage
|
1300
1337
|
}))
|
1301
1338
|
);
|
1302
1339
|
const NoPermissions = lazy(
|
1303
|
-
() => import("./NoPermissionsPage-
|
1340
|
+
() => import("./NoPermissionsPage-DVz3mzDz.mjs").then((mod) => ({ default: mod.NoPermissions }))
|
1304
1341
|
);
|
1305
1342
|
const NoContentType = lazy(
|
1306
|
-
() => import("./NoContentTypePage-
|
1343
|
+
() => import("./NoContentTypePage-DuhOTp3x.mjs").then((mod) => ({ default: mod.NoContentType }))
|
1307
1344
|
);
|
1308
1345
|
const CollectionTypePages = () => {
|
1309
1346
|
const { collectionType } = useParams();
|
@@ -1417,12 +1454,14 @@ const DocumentActionButton = (action) => {
|
|
1417
1454
|
/* @__PURE__ */ jsx(
|
1418
1455
|
Button,
|
1419
1456
|
{
|
1420
|
-
flex:
|
1457
|
+
flex: "auto",
|
1421
1458
|
startIcon: action.icon,
|
1422
1459
|
disabled: action.disabled,
|
1423
1460
|
onClick: handleClick(action),
|
1424
1461
|
justifyContent: "center",
|
1425
1462
|
variant: action.variant || "default",
|
1463
|
+
paddingTop: "7px",
|
1464
|
+
paddingBottom: "7px",
|
1426
1465
|
children: action.label
|
1427
1466
|
}
|
1428
1467
|
),
|
@@ -1430,7 +1469,7 @@ const DocumentActionButton = (action) => {
|
|
1430
1469
|
DocumentActionConfirmDialog,
|
1431
1470
|
{
|
1432
1471
|
...action.dialog,
|
1433
|
-
variant: action.variant,
|
1472
|
+
variant: action.dialog?.variant ?? action.variant,
|
1434
1473
|
isOpen: dialogId === action.id,
|
1435
1474
|
onClose: handleClose
|
1436
1475
|
}
|
@@ -1482,14 +1521,14 @@ const DocumentActionsMenu = ({
|
|
1482
1521
|
};
|
1483
1522
|
return /* @__PURE__ */ jsxs(Menu.Root, { open: isOpen, onOpenChange: setIsOpen, children: [
|
1484
1523
|
/* @__PURE__ */ jsxs(
|
1485
|
-
|
1524
|
+
StyledMoreButton,
|
1486
1525
|
{
|
1487
1526
|
disabled: isDisabled,
|
1488
1527
|
size: "S",
|
1489
1528
|
endIcon: null,
|
1490
|
-
paddingTop: "
|
1491
|
-
paddingLeft: "
|
1492
|
-
paddingRight: "
|
1529
|
+
paddingTop: "4px",
|
1530
|
+
paddingLeft: "7px",
|
1531
|
+
paddingRight: "7px",
|
1493
1532
|
variant,
|
1494
1533
|
children: [
|
1495
1534
|
/* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
|
@@ -1509,10 +1548,25 @@ const DocumentActionsMenu = ({
|
|
1509
1548
|
onSelect: handleClick(action),
|
1510
1549
|
display: "block",
|
1511
1550
|
children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", gap: 4, children: [
|
1512
|
-
/* @__PURE__ */ jsxs(
|
1513
|
-
|
1514
|
-
|
1515
|
-
|
1551
|
+
/* @__PURE__ */ jsxs(
|
1552
|
+
Flex,
|
1553
|
+
{
|
1554
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1555
|
+
gap: 2,
|
1556
|
+
tag: "span",
|
1557
|
+
children: [
|
1558
|
+
/* @__PURE__ */ jsx(
|
1559
|
+
Flex,
|
1560
|
+
{
|
1561
|
+
tag: "span",
|
1562
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1563
|
+
children: action.icon
|
1564
|
+
}
|
1565
|
+
),
|
1566
|
+
action.label
|
1567
|
+
]
|
1568
|
+
}
|
1569
|
+
),
|
1516
1570
|
action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsx(
|
1517
1571
|
Flex,
|
1518
1572
|
{
|
@@ -1583,6 +1637,11 @@ const convertActionVariantToIconColor = (variant = "secondary") => {
|
|
1583
1637
|
return "primary600";
|
1584
1638
|
}
|
1585
1639
|
};
|
1640
|
+
const StyledMoreButton = styled(Menu.Trigger)`
|
1641
|
+
& > span {
|
1642
|
+
display: flex;
|
1643
|
+
}
|
1644
|
+
`;
|
1586
1645
|
const DocumentActionConfirmDialog = ({
|
1587
1646
|
onClose,
|
1588
1647
|
onCancel,
|
@@ -1652,13 +1711,17 @@ const PublishAction$1 = ({
|
|
1652
1711
|
const navigate = useNavigate();
|
1653
1712
|
const { toggleNotification } = useNotification();
|
1654
1713
|
const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
|
1714
|
+
const isListView = useMatch(LIST_PATH) !== null;
|
1655
1715
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
1656
1716
|
const { formatMessage } = useIntl();
|
1657
|
-
const { canPublish
|
1658
|
-
"PublishAction",
|
1659
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1660
|
-
);
|
1717
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1661
1718
|
const { publish } = useDocumentActions();
|
1719
|
+
const [
|
1720
|
+
countDraftRelations,
|
1721
|
+
{ isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
|
1722
|
+
] = useLazyGetDraftRelationCountQuery();
|
1723
|
+
const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React.useState(0);
|
1724
|
+
const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React.useState(0);
|
1662
1725
|
const [{ query, rawQuery }] = useQueryParams();
|
1663
1726
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
1664
1727
|
const modified = useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
@@ -1667,10 +1730,101 @@ const PublishAction$1 = ({
|
|
1667
1730
|
const validate = useForm("PublishAction", (state) => state.validate);
|
1668
1731
|
const setErrors = useForm("PublishAction", (state) => state.setErrors);
|
1669
1732
|
const formValues = useForm("PublishAction", ({ values }) => values);
|
1733
|
+
React.useEffect(() => {
|
1734
|
+
if (isErrorDraftRelations) {
|
1735
|
+
toggleNotification({
|
1736
|
+
type: "danger",
|
1737
|
+
message: formatMessage({
|
1738
|
+
id: getTranslation("error.records.fetch-draft-relatons"),
|
1739
|
+
defaultMessage: "An error occurred while fetching draft relations on this document."
|
1740
|
+
})
|
1741
|
+
});
|
1742
|
+
}
|
1743
|
+
}, [isErrorDraftRelations, toggleNotification, formatMessage]);
|
1744
|
+
React.useEffect(() => {
|
1745
|
+
const localDraftRelations = /* @__PURE__ */ new Set();
|
1746
|
+
const extractDraftRelations = (data) => {
|
1747
|
+
const relations = data.connect || [];
|
1748
|
+
relations.forEach((relation) => {
|
1749
|
+
if (relation.status === "draft") {
|
1750
|
+
localDraftRelations.add(relation.id);
|
1751
|
+
}
|
1752
|
+
});
|
1753
|
+
};
|
1754
|
+
const traverseAndExtract = (data) => {
|
1755
|
+
Object.entries(data).forEach(([key, value]) => {
|
1756
|
+
if (key === "connect" && Array.isArray(value)) {
|
1757
|
+
extractDraftRelations({ connect: value });
|
1758
|
+
} else if (typeof value === "object" && value !== null) {
|
1759
|
+
traverseAndExtract(value);
|
1760
|
+
}
|
1761
|
+
});
|
1762
|
+
};
|
1763
|
+
if (!documentId || modified) {
|
1764
|
+
traverseAndExtract(formValues);
|
1765
|
+
setLocalCountOfDraftRelations(localDraftRelations.size);
|
1766
|
+
}
|
1767
|
+
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
1768
|
+
React.useEffect(() => {
|
1769
|
+
if (documentId && !isListView) {
|
1770
|
+
const fetchDraftRelationsCount = async () => {
|
1771
|
+
const { data, error } = await countDraftRelations({
|
1772
|
+
collectionType,
|
1773
|
+
model,
|
1774
|
+
documentId,
|
1775
|
+
params
|
1776
|
+
});
|
1777
|
+
if (error) {
|
1778
|
+
throw error;
|
1779
|
+
}
|
1780
|
+
if (data) {
|
1781
|
+
setServerCountOfDraftRelations(data.data);
|
1782
|
+
}
|
1783
|
+
};
|
1784
|
+
fetchDraftRelationsCount();
|
1785
|
+
}
|
1786
|
+
}, [isListView, documentId, countDraftRelations, collectionType, model, params]);
|
1670
1787
|
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
1671
1788
|
if (!schema?.options?.draftAndPublish) {
|
1672
1789
|
return null;
|
1673
1790
|
}
|
1791
|
+
const performPublish = async () => {
|
1792
|
+
setSubmitting(true);
|
1793
|
+
try {
|
1794
|
+
const { errors } = await validate();
|
1795
|
+
if (errors) {
|
1796
|
+
toggleNotification({
|
1797
|
+
type: "danger",
|
1798
|
+
message: formatMessage({
|
1799
|
+
id: "content-manager.validation.error",
|
1800
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
1801
|
+
})
|
1802
|
+
});
|
1803
|
+
return;
|
1804
|
+
}
|
1805
|
+
const res = await publish(
|
1806
|
+
{
|
1807
|
+
collectionType,
|
1808
|
+
model,
|
1809
|
+
documentId,
|
1810
|
+
params
|
1811
|
+
},
|
1812
|
+
formValues
|
1813
|
+
);
|
1814
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1815
|
+
navigate({
|
1816
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1817
|
+
search: rawQuery
|
1818
|
+
});
|
1819
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1820
|
+
setErrors(formatValidationErrors(res.error));
|
1821
|
+
}
|
1822
|
+
} finally {
|
1823
|
+
setSubmitting(false);
|
1824
|
+
}
|
1825
|
+
};
|
1826
|
+
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
1827
|
+
const hasDraftRelations = totalDraftRelations > 0;
|
1674
1828
|
return {
|
1675
1829
|
/**
|
1676
1830
|
* Disabled when:
|
@@ -1680,49 +1834,39 @@ const PublishAction$1 = ({
|
|
1680
1834
|
* - the document is already published & not modified
|
1681
1835
|
* - the document is being created & not modified
|
1682
1836
|
* - the user doesn't have the permission to publish
|
1683
|
-
* - the user doesn't have the permission to create a new document
|
1684
|
-
* - the user doesn't have the permission to update the document
|
1685
1837
|
*/
|
1686
|
-
disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish
|
1838
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
1687
1839
|
label: formatMessage({
|
1688
1840
|
id: "app.utils.publish",
|
1689
1841
|
defaultMessage: "Publish"
|
1690
1842
|
}),
|
1691
1843
|
onClick: async () => {
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
formValues
|
1713
|
-
);
|
1714
|
-
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1715
|
-
navigate({
|
1716
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1717
|
-
search: rawQuery
|
1718
|
-
});
|
1719
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1720
|
-
setErrors(formatValidationErrors(res.error));
|
1844
|
+
if (hasDraftRelations) {
|
1845
|
+
return;
|
1846
|
+
}
|
1847
|
+
await performPublish();
|
1848
|
+
},
|
1849
|
+
dialog: hasDraftRelations ? {
|
1850
|
+
type: "dialog",
|
1851
|
+
variant: "danger",
|
1852
|
+
footer: null,
|
1853
|
+
title: formatMessage({
|
1854
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
|
1855
|
+
defaultMessage: "Confirmation"
|
1856
|
+
}),
|
1857
|
+
content: formatMessage(
|
1858
|
+
{
|
1859
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
1860
|
+
defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
|
1861
|
+
},
|
1862
|
+
{
|
1863
|
+
count: totalDraftRelations
|
1721
1864
|
}
|
1722
|
-
|
1723
|
-
|
1865
|
+
),
|
1866
|
+
onConfirm: async () => {
|
1867
|
+
await performPublish();
|
1724
1868
|
}
|
1725
|
-
}
|
1869
|
+
} : void 0
|
1726
1870
|
};
|
1727
1871
|
};
|
1728
1872
|
PublishAction$1.type = "publish";
|
@@ -1738,10 +1882,6 @@ const UpdateAction = ({
|
|
1738
1882
|
const cloneMatch = useMatch(CLONE_PATH);
|
1739
1883
|
const isCloning = cloneMatch !== null;
|
1740
1884
|
const { formatMessage } = useIntl();
|
1741
|
-
const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1742
|
-
canCreate: canCreate2,
|
1743
|
-
canUpdate: canUpdate2
|
1744
|
-
}));
|
1745
1885
|
const { create, update, clone } = useDocumentActions();
|
1746
1886
|
const [{ query, rawQuery }] = useQueryParams();
|
1747
1887
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
@@ -1758,10 +1898,8 @@ const UpdateAction = ({
|
|
1758
1898
|
* - the form is submitting
|
1759
1899
|
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
1760
1900
|
* - the active tab is the published tab
|
1761
|
-
* - the user doesn't have the permission to create a new document
|
1762
|
-
* - the user doesn't have the permission to update the document
|
1763
1901
|
*/
|
1764
|
-
disabled: isSubmitting || !modified && !isCloning || activeTab === "published"
|
1902
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1765
1903
|
label: formatMessage({
|
1766
1904
|
id: "content-manager.containers.Edit.save",
|
1767
1905
|
defaultMessage: "Save"
|
@@ -1769,16 +1907,18 @@ const UpdateAction = ({
|
|
1769
1907
|
onClick: async () => {
|
1770
1908
|
setSubmitting(true);
|
1771
1909
|
try {
|
1772
|
-
|
1773
|
-
|
1774
|
-
|
1775
|
-
|
1776
|
-
|
1777
|
-
|
1778
|
-
|
1779
|
-
|
1780
|
-
|
1781
|
-
|
1910
|
+
if (activeTab !== "draft") {
|
1911
|
+
const { errors } = await validate();
|
1912
|
+
if (errors) {
|
1913
|
+
toggleNotification({
|
1914
|
+
type: "danger",
|
1915
|
+
message: formatMessage({
|
1916
|
+
id: "content-manager.validation.error",
|
1917
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
1918
|
+
})
|
1919
|
+
});
|
1920
|
+
return;
|
1921
|
+
}
|
1782
1922
|
}
|
1783
1923
|
if (isCloning) {
|
1784
1924
|
const res = await clone(
|
@@ -1790,10 +1930,13 @@ const UpdateAction = ({
|
|
1790
1930
|
document
|
1791
1931
|
);
|
1792
1932
|
if ("data" in res) {
|
1793
|
-
navigate(
|
1794
|
-
|
1795
|
-
|
1796
|
-
|
1933
|
+
navigate(
|
1934
|
+
{
|
1935
|
+
pathname: `../${res.data.documentId}`,
|
1936
|
+
search: rawQuery
|
1937
|
+
},
|
1938
|
+
{ relative: "path" }
|
1939
|
+
);
|
1797
1940
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1798
1941
|
setErrors(formatValidationErrors(res.error));
|
1799
1942
|
}
|
@@ -1821,10 +1964,13 @@ const UpdateAction = ({
|
|
1821
1964
|
document
|
1822
1965
|
);
|
1823
1966
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1824
|
-
navigate(
|
1825
|
-
|
1826
|
-
|
1827
|
-
|
1967
|
+
navigate(
|
1968
|
+
{
|
1969
|
+
pathname: `../${res.data.documentId}`,
|
1970
|
+
search: rawQuery
|
1971
|
+
},
|
1972
|
+
{ replace: true, relative: "path" }
|
1973
|
+
);
|
1828
1974
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1829
1975
|
setErrors(formatValidationErrors(res.error));
|
1830
1976
|
}
|
@@ -2070,23 +2216,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
|
2070
2216
|
id: "content-manager.containers.edit.title.new",
|
2071
2217
|
defaultMessage: "Create an entry"
|
2072
2218
|
}) : documentTitle;
|
2073
|
-
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop:
|
2219
|
+
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2074
2220
|
/* @__PURE__ */ jsx(BackButton, {}),
|
2075
|
-
/* @__PURE__ */ jsxs(
|
2076
|
-
|
2077
|
-
{
|
2078
|
-
|
2079
|
-
|
2080
|
-
paddingTop: 1,
|
2081
|
-
gap: "80px",
|
2082
|
-
alignItems: "flex-start",
|
2083
|
-
children: [
|
2084
|
-
/* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
|
2085
|
-
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
2086
|
-
]
|
2087
|
-
}
|
2088
|
-
),
|
2089
|
-
status ? /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) : null
|
2221
|
+
/* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2222
|
+
/* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
|
2223
|
+
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
2224
|
+
] }),
|
2225
|
+
status ? /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
|
2090
2226
|
] });
|
2091
2227
|
};
|
2092
2228
|
const HeaderToolbar = () => {
|
@@ -2777,7 +2913,7 @@ const ConfirmBulkActionDialog = ({
|
|
2777
2913
|
endAction
|
2778
2914
|
}) => {
|
2779
2915
|
const { formatMessage } = useIntl();
|
2780
|
-
return /* @__PURE__ */ jsx(Dialog.Root, {
|
2916
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
2781
2917
|
/* @__PURE__ */ jsx(Dialog.Header, { children: formatMessage({
|
2782
2918
|
id: "app.components.ConfirmDialog.title",
|
2783
2919
|
defaultMessage: "Confirmation"
|
@@ -2898,7 +3034,14 @@ const formatErrorMessages = (errors, parentKey, formatMessage) => {
|
|
2898
3034
|
)
|
2899
3035
|
);
|
2900
3036
|
} else {
|
2901
|
-
messages.push(
|
3037
|
+
messages.push(
|
3038
|
+
...formatErrorMessages(
|
3039
|
+
// @ts-expect-error TODO: check why value is not compatible with FormErrors
|
3040
|
+
value,
|
3041
|
+
currentKey,
|
3042
|
+
formatMessage
|
3043
|
+
)
|
3044
|
+
);
|
2902
3045
|
}
|
2903
3046
|
} else {
|
2904
3047
|
messages.push(
|
@@ -3059,7 +3202,13 @@ const SelectedEntriesModalContent = ({
|
|
3059
3202
|
);
|
3060
3203
|
const { rows, validationErrors } = React.useMemo(() => {
|
3061
3204
|
if (data.length > 0 && schema) {
|
3062
|
-
const validate = createYupSchema(
|
3205
|
+
const validate = createYupSchema(
|
3206
|
+
schema.attributes,
|
3207
|
+
components,
|
3208
|
+
// Since this is the "Publish" action, the validation
|
3209
|
+
// schema must enforce the rules for published entities
|
3210
|
+
{ status: "published" }
|
3211
|
+
);
|
3063
3212
|
const validationErrors2 = {};
|
3064
3213
|
const rows2 = data.map((entry) => {
|
3065
3214
|
try {
|
@@ -3409,7 +3558,7 @@ const TableActions = ({ document }) => {
|
|
3409
3558
|
DescriptionComponentRenderer,
|
3410
3559
|
{
|
3411
3560
|
props,
|
3412
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3561
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
3413
3562
|
children: (actions2) => {
|
3414
3563
|
const tableRowActions = actions2.filter((action) => {
|
3415
3564
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3520,7 +3669,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3520
3669
|
}),
|
3521
3670
|
content: /* @__PURE__ */ jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
3522
3671
|
footer: ({ onClose }) => {
|
3523
|
-
return /* @__PURE__ */ jsxs(
|
3672
|
+
return /* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
3524
3673
|
/* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
3525
3674
|
id: "cancel",
|
3526
3675
|
defaultMessage: "Cancel"
|
@@ -3561,8 +3710,7 @@ class ContentManagerPlugin {
|
|
3561
3710
|
documentActions = [
|
3562
3711
|
...DEFAULT_ACTIONS,
|
3563
3712
|
...DEFAULT_TABLE_ROW_ACTIONS,
|
3564
|
-
...DEFAULT_HEADER_ACTIONS
|
3565
|
-
HistoryAction
|
3713
|
+
...DEFAULT_HEADER_ACTIONS
|
3566
3714
|
];
|
3567
3715
|
editViewSidePanels = [ActionsPanel];
|
3568
3716
|
headerActions = [];
|
@@ -3651,6 +3799,52 @@ const getPrintableType = (value) => {
|
|
3651
3799
|
}
|
3652
3800
|
return nativeType;
|
3653
3801
|
};
|
3802
|
+
const HistoryAction = ({ model, document }) => {
|
3803
|
+
const { formatMessage } = useIntl();
|
3804
|
+
const [{ query }] = useQueryParams();
|
3805
|
+
const navigate = useNavigate();
|
3806
|
+
const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
|
3807
|
+
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3808
|
+
return null;
|
3809
|
+
}
|
3810
|
+
return {
|
3811
|
+
icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
|
3812
|
+
label: formatMessage({
|
3813
|
+
id: "content-manager.history.document-action",
|
3814
|
+
defaultMessage: "Content History"
|
3815
|
+
}),
|
3816
|
+
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
3817
|
+
disabled: (
|
3818
|
+
/**
|
3819
|
+
* The user is creating a new document.
|
3820
|
+
* It hasn't been saved yet, so there's no history to go to
|
3821
|
+
*/
|
3822
|
+
!document || /**
|
3823
|
+
* The document has been created but the current dimension has never been saved.
|
3824
|
+
* For example, the user is creating a new locale in an existing document,
|
3825
|
+
* so there's no history for the document in that locale
|
3826
|
+
*/
|
3827
|
+
!document.id || /**
|
3828
|
+
* History is only available for content types created by the user.
|
3829
|
+
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
3830
|
+
* which start with `admin::` or `plugin::`
|
3831
|
+
*/
|
3832
|
+
!model.startsWith("api::")
|
3833
|
+
),
|
3834
|
+
position: "header"
|
3835
|
+
};
|
3836
|
+
};
|
3837
|
+
HistoryAction.type = "history";
|
3838
|
+
const historyAdmin = {
|
3839
|
+
bootstrap(app) {
|
3840
|
+
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
3841
|
+
addDocumentAction((actions2) => {
|
3842
|
+
const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
|
3843
|
+
actions2.splice(indexOfDeleteAction, 0, HistoryAction);
|
3844
|
+
return actions2;
|
3845
|
+
});
|
3846
|
+
}
|
3847
|
+
};
|
3654
3848
|
const initialState = {
|
3655
3849
|
collectionTypeLinks: [],
|
3656
3850
|
components: [],
|
@@ -3706,7 +3900,7 @@ const index = {
|
|
3706
3900
|
app.router.addRoute({
|
3707
3901
|
path: "content-manager/*",
|
3708
3902
|
lazy: async () => {
|
3709
|
-
const { Layout } = await import("./layout-
|
3903
|
+
const { Layout } = await import("./layout-ls3gxfpH.mjs");
|
3710
3904
|
return {
|
3711
3905
|
Component: Layout
|
3712
3906
|
};
|
@@ -3715,10 +3909,15 @@ const index = {
|
|
3715
3909
|
});
|
3716
3910
|
app.registerPlugin(cm.config);
|
3717
3911
|
},
|
3912
|
+
bootstrap(app) {
|
3913
|
+
if (typeof historyAdmin.bootstrap === "function") {
|
3914
|
+
historyAdmin.bootstrap(app);
|
3915
|
+
}
|
3916
|
+
},
|
3718
3917
|
async registerTrads({ locales }) {
|
3719
3918
|
const importedTrads = await Promise.all(
|
3720
3919
|
locales.map((locale) => {
|
3721
|
-
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-
|
3920
|
+
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-BrCTWlZv.mjs"), "./translations/es.json": () => import("./es-CeXiYflN.mjs"), "./translations/eu.json": () => import("./eu-CdALomew.mjs"), "./translations/fr.json": () => import("./fr-CD9VFbPM.mjs"), "./translations/gu.json": () => import("./gu-CNpaMDpH.mjs"), "./translations/hi.json": () => import("./hi-Dwvd04m3.mjs"), "./translations/hu.json": () => import("./hu-CeYvaaO0.mjs"), "./translations/id.json": () => import("./id-BtwA9WJT.mjs"), "./translations/it.json": () => import("./it-BrVPqaf1.mjs"), "./translations/ja.json": () => import("./ja-CtsUxOvk.mjs"), "./translations/ko.json": () => import("./ko-HVQRlfUI.mjs"), "./translations/ml.json": () => import("./ml-BihZwQit.mjs"), "./translations/ms.json": () => import("./ms-m_WjyWx7.mjs"), "./translations/nl.json": () => import("./nl-D4R9gHx5.mjs"), "./translations/pl.json": () => import("./pl-sbx9mSt_.mjs"), "./translations/pt-BR.json": () => import("./pt-BR-C71iDxnh.mjs"), "./translations/pt.json": () => import("./pt-BsaFvS8-.mjs"), "./translations/ru.json": () => import("./ru-BE6A4Exp.mjs"), "./translations/sa.json": () => import("./sa-Dag0k-Z8.mjs"), "./translations/sk.json": () => import("./sk-BFg-R8qJ.mjs"), "./translations/sv.json": () => import("./sv-CUnfWGsh.mjs"), "./translations/th.json": () => import("./th-BqbI8lIT.mjs"), "./translations/tr.json": () => import("./tr-CgeK3wJM.mjs"), "./translations/uk.json": () => import("./uk-CR-zDhAY.mjs"), "./translations/vi.json": () => import("./vi-DUXIk_fw.mjs"), "./translations/zh-Hans.json": () => import("./zh-Hans-BPQcRIyH.mjs"), "./translations/zh.json": () => import("./zh-BWZspA60.mjs") }), `./translations/${locale}.json`).then(({ default: data }) => {
|
3722
3921
|
return {
|
3723
3922
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3724
3923
|
locale
|
@@ -3739,13 +3938,14 @@ export {
|
|
3739
3938
|
BulkActionsRenderer as B,
|
3740
3939
|
COLLECTION_TYPES as C,
|
3741
3940
|
DocumentStatus as D,
|
3742
|
-
|
3743
|
-
|
3744
|
-
|
3941
|
+
extractContentTypeComponents as E,
|
3942
|
+
DEFAULT_SETTINGS as F,
|
3943
|
+
convertEditLayoutToFieldLayouts as G,
|
3745
3944
|
HOOKS as H,
|
3746
3945
|
InjectionZone as I,
|
3747
|
-
|
3748
|
-
|
3946
|
+
useDocument as J,
|
3947
|
+
index as K,
|
3948
|
+
useDocumentActions as L,
|
3749
3949
|
Panels as P,
|
3750
3950
|
RelativeTime as R,
|
3751
3951
|
SINGLE_TYPES as S,
|
@@ -3763,18 +3963,18 @@ export {
|
|
3763
3963
|
PERMISSIONS as k,
|
3764
3964
|
DocumentRBAC as l,
|
3765
3965
|
DOCUMENT_META_FIELDS as m,
|
3766
|
-
|
3767
|
-
|
3768
|
-
|
3769
|
-
|
3770
|
-
|
3966
|
+
CLONE_PATH as n,
|
3967
|
+
useDocLayout as o,
|
3968
|
+
useGetContentTypeConfigurationQuery as p,
|
3969
|
+
CREATOR_FIELDS as q,
|
3970
|
+
getMainField as r,
|
3771
3971
|
setInitialData as s,
|
3772
|
-
|
3972
|
+
getDisplayName as t,
|
3773
3973
|
useContentTypeSchema as u,
|
3774
|
-
|
3775
|
-
|
3776
|
-
|
3777
|
-
|
3778
|
-
|
3974
|
+
checkIfAttributeIsDisplayable as v,
|
3975
|
+
useGetAllDocumentsQuery as w,
|
3976
|
+
convertListLayoutToFieldLayouts as x,
|
3977
|
+
capitalise as y,
|
3978
|
+
useUpdateContentTypeConfigurationMutation as z
|
3779
3979
|
};
|
3780
|
-
//# sourceMappingURL=index-
|
3980
|
+
//# sourceMappingURL=index-DiMrfcfy.mjs.map
|