@strapi/content-manager 0.0.0-experimental.2a7cb5ff33df35e8ccde5ef918f9f9a4a3ee9a08 → 0.0.0-experimental.32c4b04580cc12400710050c8198e46b3644cfd4
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-BvHtG7uH.js → ComponentConfigurationPage-5ukroXAh.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-BvHtG7uH.js.map → ComponentConfigurationPage-5ukroXAh.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-DHNM3YBz.mjs → ComponentConfigurationPage-BAgyHiMm.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-DHNM3YBz.mjs.map → ComponentConfigurationPage-BAgyHiMm.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-Cp6HAEzN.mjs → EditConfigurationPage-DmoXawIh.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-Cp6HAEzN.mjs.map → EditConfigurationPage-DmoXawIh.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-DOmfCEMo.js → EditConfigurationPage-Xp7lun0f.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-DOmfCEMo.js.map → EditConfigurationPage-Xp7lun0f.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-BtkEx339.mjs → EditViewPage-BLsjc5F-.mjs} +3 -3
- package/dist/_chunks/{EditViewPage-BtkEx339.mjs.map → EditViewPage-BLsjc5F-.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-BqNpC6hO.js → EditViewPage-C-ukDOB7.js} +3 -3
- package/dist/_chunks/{EditViewPage-BqNpC6hO.js.map → EditViewPage-C-ukDOB7.js.map} +1 -1
- package/dist/_chunks/{Field-lsPFnAmH.js → Field-Bfph5SOd.js} +79 -54
- package/dist/_chunks/Field-Bfph5SOd.js.map +1 -0
- package/dist/_chunks/{Field-R5NbffTB.mjs → Field-Cs7duwWd.mjs} +79 -54
- package/dist/_chunks/Field-Cs7duwWd.mjs.map +1 -0
- package/dist/_chunks/{Form-CcGboku8.js → Form-CPYqIWDG.js} +2 -2
- package/dist/_chunks/{Form-CcGboku8.js.map → Form-CPYqIWDG.js.map} +1 -1
- package/dist/_chunks/{Form-BHmXSfyy.mjs → Form-Dg_GS5TQ.mjs} +2 -2
- package/dist/_chunks/{Form-BHmXSfyy.mjs.map → Form-Dg_GS5TQ.mjs.map} +1 -1
- package/dist/_chunks/{History-Bsud8jwh.js → History-DNQkXANT.js} +28 -18
- package/dist/_chunks/History-DNQkXANT.js.map +1 -0
- package/dist/_chunks/{History-ByUPL3T3.mjs → History-wrnHqf09.mjs} +28 -18
- package/dist/_chunks/History-wrnHqf09.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DiT463qx.js → ListConfigurationPage-CUQxfpjT.js} +8 -6
- package/dist/_chunks/ListConfigurationPage-CUQxfpjT.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-Bm5HACXf.mjs → ListConfigurationPage-DScmJVkW.mjs} +8 -6
- package/dist/_chunks/ListConfigurationPage-DScmJVkW.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-CsrC9L_d.js → ListViewPage-BsLiH2-2.js} +3 -3
- package/dist/_chunks/{ListViewPage-CsrC9L_d.js.map → ListViewPage-BsLiH2-2.js.map} +1 -1
- package/dist/_chunks/{ListViewPage-JSyNAAYu.mjs → ListViewPage-C4IvrMgY.mjs} +3 -3
- package/dist/_chunks/{ListViewPage-JSyNAAYu.mjs.map → ListViewPage-C4IvrMgY.mjs.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-Bsvng4II.js → NoContentTypePage-BZ-PnGAf.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-Bsvng4II.js.map → NoContentTypePage-BZ-PnGAf.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-CsrQUpBE.mjs → NoContentTypePage-Djg8nPlj.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-CsrQUpBE.mjs.map → NoContentTypePage-Djg8nPlj.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-DNmf_pj0.mjs → NoPermissionsPage-DSP7R-hv.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-DNmf_pj0.mjs.map → NoPermissionsPage-DSP7R-hv.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-CdHNJtEf.js → NoPermissionsPage-_lUqjGW3.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-CdHNJtEf.js.map → NoPermissionsPage-_lUqjGW3.js.map} +1 -1
- package/dist/_chunks/{Relations-u8-37jK0.mjs → Relations-BZr8tL0R.mjs} +3 -3
- package/dist/_chunks/Relations-BZr8tL0R.mjs.map +1 -0
- package/dist/_chunks/{Relations-CghaPv2D.js → Relations-CtELXYIK.js} +3 -3
- package/dist/_chunks/Relations-CtELXYIK.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-BOZx6IMg.js → index-OerGjbAN.js} +251 -117
- package/dist/_chunks/index-OerGjbAN.js.map +1 -0
- package/dist/_chunks/{index-CaE6NG4a.mjs → index-c_5DdJi-.mjs} +253 -119
- package/dist/_chunks/index-c_5DdJi-.mjs.map +1 -0
- package/dist/_chunks/{layout-Ciz224q5.js → layout-Ci7qHlFb.js} +4 -4
- package/dist/_chunks/layout-Ci7qHlFb.js.map +1 -0
- package/dist/_chunks/{layout-Bx7svTbY.mjs → layout-oPBiO7RY.mjs} +4 -4
- package/dist/_chunks/layout-oPBiO7RY.mjs.map +1 -0
- package/dist/_chunks/{relations-Cxc1cEv3.mjs → relations-BIdWFjdq.mjs} +2 -2
- package/dist/_chunks/{relations-Cxc1cEv3.mjs.map → relations-BIdWFjdq.mjs.map} +1 -1
- package/dist/_chunks/{relations-CP8sB2YZ.js → relations-COBpStiF.js} +2 -2
- package/dist/_chunks/{relations-CP8sB2YZ.js.map → relations-COBpStiF.js.map} +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/admin/src/history/index.d.ts +3 -0
- 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/server/index.js +33 -28
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +33 -28
- 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/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/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/package.json +6 -6
- package/dist/_chunks/Field-R5NbffTB.mjs.map +0 -1
- package/dist/_chunks/Field-lsPFnAmH.js.map +0 -1
- package/dist/_chunks/History-Bsud8jwh.js.map +0 -1
- package/dist/_chunks/History-ByUPL3T3.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-Bm5HACXf.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DiT463qx.js.map +0 -1
- package/dist/_chunks/Relations-CghaPv2D.js.map +0 -1
- package/dist/_chunks/Relations-u8-37jK0.mjs.map +0 -1
- package/dist/_chunks/index-BOZx6IMg.js.map +0 -1
- package/dist/_chunks/index-CaE6NG4a.mjs.map +0 -1
- package/dist/_chunks/layout-Bx7svTbY.mjs.map +0 -1
- package/dist/_chunks/layout-Ciz224q5.js.map +0 -1
@@ -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
6
|
import { Button, Menu, VisuallyHidden, Flex, Box, Typography, Dialog, Modal, Radio, Status, SingleSelect, SingleSelectOption, Loader, IconButton, Tooltip, LinkButton } from "@strapi/design-system";
|
7
|
+
import { useIntl } from "react-intl";
|
8
|
+
import { useParams, Navigate, useNavigate, 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";
|
@@ -208,7 +172,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
208
172
|
params: query
|
209
173
|
}
|
210
174
|
}),
|
211
|
-
invalidatesTags: (_result,
|
175
|
+
invalidatesTags: (_result, error, { model }) => {
|
176
|
+
if (error) {
|
177
|
+
return [];
|
178
|
+
}
|
179
|
+
return [{ type: "Document", id: `${model}_LIST` }];
|
180
|
+
}
|
212
181
|
}),
|
213
182
|
cloneDocument: builder.mutation({
|
214
183
|
query: ({ model, sourceId, data, params }) => ({
|
@@ -398,6 +367,18 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
398
367
|
},
|
399
368
|
"Relations"
|
400
369
|
];
|
370
|
+
},
|
371
|
+
async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
|
372
|
+
const patchResult = dispatch(
|
373
|
+
documentApi.util.updateQueryData("getDocument", patch, (draft) => {
|
374
|
+
Object.assign(draft.data, data);
|
375
|
+
})
|
376
|
+
);
|
377
|
+
try {
|
378
|
+
await queryFulfilled;
|
379
|
+
} catch {
|
380
|
+
patchResult.undo();
|
381
|
+
}
|
401
382
|
}
|
402
383
|
}),
|
403
384
|
unpublishDocument: builder.mutation({
|
@@ -600,11 +581,11 @@ const createAttributeSchema = (attribute) => {
|
|
600
581
|
}
|
601
582
|
};
|
602
583
|
const addRequiredValidation = (attribute) => (schema) => {
|
584
|
+
if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
|
585
|
+
return schema.min(1, translatedErrors.required);
|
586
|
+
}
|
603
587
|
if (attribute.required && attribute.type !== "relation") {
|
604
|
-
return schema.required(
|
605
|
-
id: translatedErrors.required.id,
|
606
|
-
defaultMessage: "This field is required."
|
607
|
-
});
|
588
|
+
return schema.required(translatedErrors.required);
|
608
589
|
}
|
609
590
|
return schema?.nullable ? schema.nullable() : (
|
610
591
|
// In some cases '.nullable' will not be available on the schema.
|
@@ -638,6 +619,28 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
638
619
|
const addMinValidation = (attribute) => (schema) => {
|
639
620
|
if ("min" in attribute) {
|
640
621
|
const min = toInteger(attribute.min);
|
622
|
+
if (attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") {
|
623
|
+
if (!attribute.required && "test" in schema && min) {
|
624
|
+
return schema.test(
|
625
|
+
"custom-min",
|
626
|
+
{
|
627
|
+
...translatedErrors.min,
|
628
|
+
values: {
|
629
|
+
min: attribute.min
|
630
|
+
}
|
631
|
+
},
|
632
|
+
(value) => {
|
633
|
+
if (!value) {
|
634
|
+
return true;
|
635
|
+
}
|
636
|
+
if (Array.isArray(value) && value.length === 0) {
|
637
|
+
return true;
|
638
|
+
}
|
639
|
+
return value.length >= min;
|
640
|
+
}
|
641
|
+
);
|
642
|
+
}
|
643
|
+
}
|
641
644
|
if ("min" in schema && min) {
|
642
645
|
return schema.min(min, {
|
643
646
|
...translatedErrors.min,
|
@@ -1188,7 +1191,6 @@ const useDocumentActions = () => {
|
|
1188
1191
|
sourceId
|
1189
1192
|
});
|
1190
1193
|
if ("error" in res) {
|
1191
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1192
1194
|
return { error: res.error };
|
1193
1195
|
}
|
1194
1196
|
toggleNotification({
|
@@ -1269,7 +1271,7 @@ const useDocumentActions = () => {
|
|
1269
1271
|
};
|
1270
1272
|
};
|
1271
1273
|
const ProtectedHistoryPage = lazy(
|
1272
|
-
() => import("./History-
|
1274
|
+
() => import("./History-wrnHqf09.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1273
1275
|
);
|
1274
1276
|
const routes$1 = [
|
1275
1277
|
{
|
@@ -1282,31 +1284,31 @@ const routes$1 = [
|
|
1282
1284
|
}
|
1283
1285
|
];
|
1284
1286
|
const ProtectedEditViewPage = lazy(
|
1285
|
-
() => import("./EditViewPage-
|
1287
|
+
() => import("./EditViewPage-BLsjc5F-.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1286
1288
|
);
|
1287
1289
|
const ProtectedListViewPage = lazy(
|
1288
|
-
() => import("./ListViewPage-
|
1290
|
+
() => import("./ListViewPage-C4IvrMgY.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1289
1291
|
);
|
1290
1292
|
const ProtectedListConfiguration = lazy(
|
1291
|
-
() => import("./ListConfigurationPage-
|
1293
|
+
() => import("./ListConfigurationPage-DScmJVkW.mjs").then((mod) => ({
|
1292
1294
|
default: mod.ProtectedListConfiguration
|
1293
1295
|
}))
|
1294
1296
|
);
|
1295
1297
|
const ProtectedEditConfigurationPage = lazy(
|
1296
|
-
() => import("./EditConfigurationPage-
|
1298
|
+
() => import("./EditConfigurationPage-DmoXawIh.mjs").then((mod) => ({
|
1297
1299
|
default: mod.ProtectedEditConfigurationPage
|
1298
1300
|
}))
|
1299
1301
|
);
|
1300
1302
|
const ProtectedComponentConfigurationPage = lazy(
|
1301
|
-
() => import("./ComponentConfigurationPage-
|
1303
|
+
() => import("./ComponentConfigurationPage-BAgyHiMm.mjs").then((mod) => ({
|
1302
1304
|
default: mod.ProtectedComponentConfigurationPage
|
1303
1305
|
}))
|
1304
1306
|
);
|
1305
1307
|
const NoPermissions = lazy(
|
1306
|
-
() => import("./NoPermissionsPage-
|
1308
|
+
() => import("./NoPermissionsPage-DSP7R-hv.mjs").then((mod) => ({ default: mod.NoPermissions }))
|
1307
1309
|
);
|
1308
1310
|
const NoContentType = lazy(
|
1309
|
-
() => import("./NoContentTypePage-
|
1311
|
+
() => import("./NoContentTypePage-Djg8nPlj.mjs").then((mod) => ({ default: mod.NoContentType }))
|
1310
1312
|
);
|
1311
1313
|
const CollectionTypePages = () => {
|
1312
1314
|
const { collectionType } = useParams();
|
@@ -1433,7 +1435,7 @@ const DocumentActionButton = (action) => {
|
|
1433
1435
|
DocumentActionConfirmDialog,
|
1434
1436
|
{
|
1435
1437
|
...action.dialog,
|
1436
|
-
variant: action.variant,
|
1438
|
+
variant: action.dialog?.variant ?? action.variant,
|
1437
1439
|
isOpen: dialogId === action.id,
|
1438
1440
|
onClose: handleClose
|
1439
1441
|
}
|
@@ -1639,8 +1641,8 @@ const DocumentActionModal = ({
|
|
1639
1641
|
};
|
1640
1642
|
return /* @__PURE__ */ jsx(Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
|
1641
1643
|
/* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: title }) }),
|
1642
|
-
|
1643
|
-
|
1644
|
+
typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsx(Modal.Body, { children: Content }),
|
1645
|
+
typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
|
1644
1646
|
] }) });
|
1645
1647
|
};
|
1646
1648
|
const PublishAction$1 = ({
|
@@ -1662,6 +1664,12 @@ const PublishAction$1 = ({
|
|
1662
1664
|
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1663
1665
|
);
|
1664
1666
|
const { publish } = useDocumentActions();
|
1667
|
+
const [
|
1668
|
+
countDraftRelations,
|
1669
|
+
{ isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
|
1670
|
+
] = useLazyGetDraftRelationCountQuery();
|
1671
|
+
const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React.useState(0);
|
1672
|
+
const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React.useState(0);
|
1665
1673
|
const [{ query, rawQuery }] = useQueryParams();
|
1666
1674
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
1667
1675
|
const modified = useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
@@ -1670,10 +1678,101 @@ const PublishAction$1 = ({
|
|
1670
1678
|
const validate = useForm("PublishAction", (state) => state.validate);
|
1671
1679
|
const setErrors = useForm("PublishAction", (state) => state.setErrors);
|
1672
1680
|
const formValues = useForm("PublishAction", ({ values }) => values);
|
1681
|
+
React.useEffect(() => {
|
1682
|
+
if (isErrorDraftRelations) {
|
1683
|
+
toggleNotification({
|
1684
|
+
type: "danger",
|
1685
|
+
message: formatMessage({
|
1686
|
+
id: getTranslation("error.records.fetch-draft-relatons"),
|
1687
|
+
defaultMessage: "An error occurred while fetching draft relations on this document."
|
1688
|
+
})
|
1689
|
+
});
|
1690
|
+
}
|
1691
|
+
}, [isErrorDraftRelations, toggleNotification, formatMessage]);
|
1692
|
+
React.useEffect(() => {
|
1693
|
+
const localDraftRelations = /* @__PURE__ */ new Set();
|
1694
|
+
const extractDraftRelations = (data) => {
|
1695
|
+
const relations = data.connect || [];
|
1696
|
+
relations.forEach((relation) => {
|
1697
|
+
if (relation.status === "draft") {
|
1698
|
+
localDraftRelations.add(relation.id);
|
1699
|
+
}
|
1700
|
+
});
|
1701
|
+
};
|
1702
|
+
const traverseAndExtract = (data) => {
|
1703
|
+
Object.entries(data).forEach(([key, value]) => {
|
1704
|
+
if (key === "connect" && Array.isArray(value)) {
|
1705
|
+
extractDraftRelations({ connect: value });
|
1706
|
+
} else if (typeof value === "object" && value !== null) {
|
1707
|
+
traverseAndExtract(value);
|
1708
|
+
}
|
1709
|
+
});
|
1710
|
+
};
|
1711
|
+
if (!documentId || modified) {
|
1712
|
+
traverseAndExtract(formValues);
|
1713
|
+
setLocalCountOfDraftRelations(localDraftRelations.size);
|
1714
|
+
}
|
1715
|
+
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
1716
|
+
React.useEffect(() => {
|
1717
|
+
if (documentId) {
|
1718
|
+
const fetchDraftRelationsCount = async () => {
|
1719
|
+
const { data, error } = await countDraftRelations({
|
1720
|
+
collectionType,
|
1721
|
+
model,
|
1722
|
+
documentId,
|
1723
|
+
params
|
1724
|
+
});
|
1725
|
+
if (error) {
|
1726
|
+
throw error;
|
1727
|
+
}
|
1728
|
+
if (data) {
|
1729
|
+
setServerCountOfDraftRelations(data.data);
|
1730
|
+
}
|
1731
|
+
};
|
1732
|
+
fetchDraftRelationsCount();
|
1733
|
+
}
|
1734
|
+
}, [documentId, countDraftRelations, collectionType, model, params]);
|
1673
1735
|
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
1674
1736
|
if (!schema?.options?.draftAndPublish) {
|
1675
1737
|
return null;
|
1676
1738
|
}
|
1739
|
+
const performPublish = async () => {
|
1740
|
+
setSubmitting(true);
|
1741
|
+
try {
|
1742
|
+
const { errors } = await validate();
|
1743
|
+
if (errors) {
|
1744
|
+
toggleNotification({
|
1745
|
+
type: "danger",
|
1746
|
+
message: formatMessage({
|
1747
|
+
id: "content-manager.validation.error",
|
1748
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
1749
|
+
})
|
1750
|
+
});
|
1751
|
+
return;
|
1752
|
+
}
|
1753
|
+
const res = await publish(
|
1754
|
+
{
|
1755
|
+
collectionType,
|
1756
|
+
model,
|
1757
|
+
documentId,
|
1758
|
+
params
|
1759
|
+
},
|
1760
|
+
formValues
|
1761
|
+
);
|
1762
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1763
|
+
navigate({
|
1764
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1765
|
+
search: rawQuery
|
1766
|
+
});
|
1767
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1768
|
+
setErrors(formatValidationErrors(res.error));
|
1769
|
+
}
|
1770
|
+
} finally {
|
1771
|
+
setSubmitting(false);
|
1772
|
+
}
|
1773
|
+
};
|
1774
|
+
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
1775
|
+
const hasDraftRelations = totalDraftRelations > 0;
|
1677
1776
|
return {
|
1678
1777
|
/**
|
1679
1778
|
* Disabled when:
|
@@ -1686,46 +1785,38 @@ const PublishAction$1 = ({
|
|
1686
1785
|
* - the user doesn't have the permission to create a new document
|
1687
1786
|
* - the user doesn't have the permission to update the document
|
1688
1787
|
*/
|
1689
|
-
disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish || Boolean(!document?.documentId && !canCreate || document?.documentId && !canUpdate),
|
1788
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish || Boolean(!document?.documentId && !canCreate || document?.documentId && !canUpdate),
|
1690
1789
|
label: formatMessage({
|
1691
1790
|
id: "app.utils.publish",
|
1692
1791
|
defaultMessage: "Publish"
|
1693
1792
|
}),
|
1694
1793
|
onClick: async () => {
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
|
1713
|
-
|
1714
|
-
|
1715
|
-
formValues
|
1716
|
-
);
|
1717
|
-
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1718
|
-
navigate({
|
1719
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1720
|
-
search: rawQuery
|
1721
|
-
});
|
1722
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1723
|
-
setErrors(formatValidationErrors(res.error));
|
1794
|
+
if (hasDraftRelations) {
|
1795
|
+
return;
|
1796
|
+
}
|
1797
|
+
await performPublish();
|
1798
|
+
},
|
1799
|
+
dialog: hasDraftRelations ? {
|
1800
|
+
type: "dialog",
|
1801
|
+
variant: "danger",
|
1802
|
+
footer: null,
|
1803
|
+
title: formatMessage({
|
1804
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
|
1805
|
+
defaultMessage: "Confirmation"
|
1806
|
+
}),
|
1807
|
+
content: formatMessage(
|
1808
|
+
{
|
1809
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
1810
|
+
defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
|
1811
|
+
},
|
1812
|
+
{
|
1813
|
+
count: totalDraftRelations
|
1724
1814
|
}
|
1725
|
-
|
1726
|
-
|
1815
|
+
),
|
1816
|
+
onConfirm: async () => {
|
1817
|
+
await performPublish();
|
1727
1818
|
}
|
1728
|
-
}
|
1819
|
+
} : void 0
|
1729
1820
|
};
|
1730
1821
|
};
|
1731
1822
|
PublishAction$1.type = "publish";
|
@@ -1793,10 +1884,13 @@ const UpdateAction = ({
|
|
1793
1884
|
document
|
1794
1885
|
);
|
1795
1886
|
if ("data" in res) {
|
1796
|
-
navigate(
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
1887
|
+
navigate(
|
1888
|
+
{
|
1889
|
+
pathname: `../${res.data.documentId}`,
|
1890
|
+
search: rawQuery
|
1891
|
+
},
|
1892
|
+
{ relative: "path" }
|
1893
|
+
);
|
1800
1894
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1801
1895
|
setErrors(formatValidationErrors(res.error));
|
1802
1896
|
}
|
@@ -1826,10 +1920,10 @@ const UpdateAction = ({
|
|
1826
1920
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1827
1921
|
navigate(
|
1828
1922
|
{
|
1829
|
-
pathname: `../${
|
1923
|
+
pathname: `../${res.data.documentId}`,
|
1830
1924
|
search: rawQuery
|
1831
1925
|
},
|
1832
|
-
{ replace: true }
|
1926
|
+
{ replace: true, relative: "path" }
|
1833
1927
|
);
|
1834
1928
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1835
1929
|
setErrors(formatValidationErrors(res.error));
|
@@ -2076,23 +2170,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
|
2076
2170
|
id: "content-manager.containers.edit.title.new",
|
2077
2171
|
defaultMessage: "Create an entry"
|
2078
2172
|
}) : documentTitle;
|
2079
|
-
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop:
|
2173
|
+
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2080
2174
|
/* @__PURE__ */ jsx(BackButton, {}),
|
2081
|
-
/* @__PURE__ */ jsxs(
|
2082
|
-
|
2083
|
-
{
|
2084
|
-
|
2085
|
-
|
2086
|
-
paddingTop: 1,
|
2087
|
-
gap: "80px",
|
2088
|
-
alignItems: "flex-start",
|
2089
|
-
children: [
|
2090
|
-
/* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
|
2091
|
-
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
2092
|
-
]
|
2093
|
-
}
|
2094
|
-
),
|
2095
|
-
status ? /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) : null
|
2175
|
+
/* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2176
|
+
/* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
|
2177
|
+
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
2178
|
+
] }),
|
2179
|
+
status ? /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
|
2096
2180
|
] });
|
2097
2181
|
};
|
2098
2182
|
const HeaderToolbar = () => {
|
@@ -2783,7 +2867,7 @@ const ConfirmBulkActionDialog = ({
|
|
2783
2867
|
endAction
|
2784
2868
|
}) => {
|
2785
2869
|
const { formatMessage } = useIntl();
|
2786
|
-
return /* @__PURE__ */ jsx(Dialog.Root, {
|
2870
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
2787
2871
|
/* @__PURE__ */ jsx(Dialog.Header, { children: formatMessage({
|
2788
2872
|
id: "app.components.ConfirmDialog.title",
|
2789
2873
|
defaultMessage: "Confirmation"
|
@@ -3574,8 +3658,7 @@ class ContentManagerPlugin {
|
|
3574
3658
|
documentActions = [
|
3575
3659
|
...DEFAULT_ACTIONS,
|
3576
3660
|
...DEFAULT_TABLE_ROW_ACTIONS,
|
3577
|
-
...DEFAULT_HEADER_ACTIONS
|
3578
|
-
HistoryAction
|
3661
|
+
...DEFAULT_HEADER_ACTIONS
|
3579
3662
|
];
|
3580
3663
|
editViewSidePanels = [ActionsPanel];
|
3581
3664
|
headerActions = [];
|
@@ -3664,6 +3747,52 @@ const getPrintableType = (value) => {
|
|
3664
3747
|
}
|
3665
3748
|
return nativeType;
|
3666
3749
|
};
|
3750
|
+
const HistoryAction = ({ model, document }) => {
|
3751
|
+
const { formatMessage } = useIntl();
|
3752
|
+
const [{ query }] = useQueryParams();
|
3753
|
+
const navigate = useNavigate();
|
3754
|
+
const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
|
3755
|
+
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3756
|
+
return null;
|
3757
|
+
}
|
3758
|
+
return {
|
3759
|
+
icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
|
3760
|
+
label: formatMessage({
|
3761
|
+
id: "content-manager.history.document-action",
|
3762
|
+
defaultMessage: "Content History"
|
3763
|
+
}),
|
3764
|
+
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
3765
|
+
disabled: (
|
3766
|
+
/**
|
3767
|
+
* The user is creating a new document.
|
3768
|
+
* It hasn't been saved yet, so there's no history to go to
|
3769
|
+
*/
|
3770
|
+
!document || /**
|
3771
|
+
* The document has been created but the current dimension has never been saved.
|
3772
|
+
* For example, the user is creating a new locale in an existing document,
|
3773
|
+
* so there's no history for the document in that locale
|
3774
|
+
*/
|
3775
|
+
!document.id || /**
|
3776
|
+
* History is only available for content types created by the user.
|
3777
|
+
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
3778
|
+
* which start with `admin::` or `plugin::`
|
3779
|
+
*/
|
3780
|
+
!model.startsWith("api::")
|
3781
|
+
),
|
3782
|
+
position: "header"
|
3783
|
+
};
|
3784
|
+
};
|
3785
|
+
HistoryAction.type = "history";
|
3786
|
+
const historyAdmin = {
|
3787
|
+
bootstrap(app) {
|
3788
|
+
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
3789
|
+
addDocumentAction((actions2) => {
|
3790
|
+
const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
|
3791
|
+
actions2.splice(indexOfDeleteAction, 0, HistoryAction);
|
3792
|
+
return actions2;
|
3793
|
+
});
|
3794
|
+
}
|
3795
|
+
};
|
3667
3796
|
const initialState = {
|
3668
3797
|
collectionTypeLinks: [],
|
3669
3798
|
components: [],
|
@@ -3719,7 +3848,7 @@ const index = {
|
|
3719
3848
|
app.router.addRoute({
|
3720
3849
|
path: "content-manager/*",
|
3721
3850
|
lazy: async () => {
|
3722
|
-
const { Layout } = await import("./layout-
|
3851
|
+
const { Layout } = await import("./layout-oPBiO7RY.mjs");
|
3723
3852
|
return {
|
3724
3853
|
Component: Layout
|
3725
3854
|
};
|
@@ -3728,10 +3857,15 @@ const index = {
|
|
3728
3857
|
});
|
3729
3858
|
app.registerPlugin(cm.config);
|
3730
3859
|
},
|
3860
|
+
bootstrap(app) {
|
3861
|
+
if (typeof historyAdmin.bootstrap === "function") {
|
3862
|
+
historyAdmin.bootstrap(app);
|
3863
|
+
}
|
3864
|
+
},
|
3731
3865
|
async registerTrads({ locales }) {
|
3732
3866
|
const importedTrads = await Promise.all(
|
3733
3867
|
locales.map((locale) => {
|
3734
|
-
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-
|
3868
|
+
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 }) => {
|
3735
3869
|
return {
|
3736
3870
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3737
3871
|
locale
|
@@ -3790,4 +3924,4 @@ export {
|
|
3790
3924
|
useUpdateContentTypeConfigurationMutation as y,
|
3791
3925
|
extractContentTypeComponents as z
|
3792
3926
|
};
|
3793
|
-
//# sourceMappingURL=index-
|
3927
|
+
//# sourceMappingURL=index-c_5DdJi-.mjs.map
|