@strapi/content-manager 0.0.0-experimental.826f263c58b6886b849d3f03b81f7a530bc51c91 → 0.0.0-experimental.93181c8b900e97a04bf10785b368657101ec98d8
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-CR5XdR33.mjs → ComponentConfigurationPage-DJEJ49QD.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-CR5XdR33.mjs.map → ComponentConfigurationPage-DJEJ49QD.mjs.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-DJcn1DrO.js → ComponentConfigurationPage-D_g11bYV.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-DJcn1DrO.js.map → ComponentConfigurationPage-D_g11bYV.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-tDtWj7R2.js → EditConfigurationPage-CeL712KW.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-tDtWj7R2.js.map → EditConfigurationPage-CeL712KW.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-DmCIb4kD.mjs → EditConfigurationPage-QBZdUYyG.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-DmCIb4kD.mjs.map → EditConfigurationPage-QBZdUYyG.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-DvaV7U9b.mjs → EditViewPage-CvRUUpVh.mjs} +58 -47
- package/dist/_chunks/EditViewPage-CvRUUpVh.mjs.map +1 -0
- package/dist/_chunks/{EditViewPage-CoQEnFlC.js → EditViewPage-g5TwrgRY.js} +57 -46
- package/dist/_chunks/EditViewPage-g5TwrgRY.js.map +1 -0
- package/dist/_chunks/{Field-ZdrmmQ4Y.js → Field-ncdInvxS.js} +521 -203
- package/dist/_chunks/Field-ncdInvxS.js.map +1 -0
- package/dist/_chunks/{Field-Cz_J9551.mjs → Field-reyvfnop.mjs} +523 -205
- package/dist/_chunks/Field-reyvfnop.mjs.map +1 -0
- package/dist/_chunks/{Form-Bpig5rch.js → Form-BJ7bYiUx.js} +40 -28
- package/dist/_chunks/Form-BJ7bYiUx.js.map +1 -0
- package/dist/_chunks/{Form-Dxmihyw8.mjs → Form-DoMGsYxH.mjs} +42 -30
- package/dist/_chunks/Form-DoMGsYxH.mjs.map +1 -0
- package/dist/_chunks/{History-BZP8n7KT.mjs → History-BseDJOrj.mjs} +141 -37
- package/dist/_chunks/History-BseDJOrj.mjs.map +1 -0
- package/dist/_chunks/{History-BfX6XmZK.js → History-pbhkxIrf.js} +140 -36
- package/dist/_chunks/History-pbhkxIrf.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-B3CXj8PY.js → ListConfigurationPage-Bna8zfjr.js} +57 -46
- package/dist/_chunks/ListConfigurationPage-Bna8zfjr.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DxKuVkKz.mjs → ListConfigurationPage-DWE_fr5B.mjs} +58 -48
- package/dist/_chunks/ListConfigurationPage-DWE_fr5B.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-Bk9VO__I.js → ListViewPage-Dymsvnv6.js} +82 -93
- package/dist/_chunks/ListViewPage-Dymsvnv6.js.map +1 -0
- package/dist/_chunks/{ListViewPage-D5D3tVPq.mjs → ListViewPage-lQ-VLV2G.mjs} +84 -95
- package/dist/_chunks/ListViewPage-lQ-VLV2G.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DsB2F7Z1.js → NoContentTypePage-B4t_OsDR.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-DsB2F7Z1.js.map → NoContentTypePage-B4t_OsDR.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-DnMeuQCj.mjs → NoContentTypePage-VCQOMwlf.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-DnMeuQCj.mjs.map → NoContentTypePage-VCQOMwlf.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-BQDM64_b.js → NoPermissionsPage-BOwB6hki.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-BQDM64_b.js.map → NoPermissionsPage-BOwB6hki.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-OyoME_Tf.mjs → NoPermissionsPage-TV830k4P.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-OyoME_Tf.mjs.map → NoPermissionsPage-TV830k4P.mjs.map} +1 -1
- package/dist/_chunks/{Relations-BOYZmuWy.mjs → Relations-D6NAlnsl.mjs} +4 -4
- package/dist/_chunks/Relations-D6NAlnsl.mjs.map +1 -0
- package/dist/_chunks/{Relations-B6B3A3mb.js → Relations-DdlstXTu.js} +4 -4
- package/dist/_chunks/Relations-DdlstXTu.js.map +1 -0
- package/dist/_chunks/{en-BN1bvFK7.js → en-Cf41pH5f.js} +12 -7
- package/dist/_chunks/{en-BN1bvFK7.js.map → en-Cf41pH5f.js.map} +1 -1
- package/dist/_chunks/{en-Dzv55oQw.mjs → en-DCszE74t.mjs} +12 -7
- package/dist/_chunks/{en-Dzv55oQw.mjs.map → en-DCszE74t.mjs.map} +1 -1
- package/dist/_chunks/{index-VHviNMeW.mjs → index-BYSWwHBJ.mjs} +515 -463
- package/dist/_chunks/index-BYSWwHBJ.mjs.map +1 -0
- package/dist/_chunks/{index-DzN3kBgx.js → index-CQos-KS0.js} +495 -443
- package/dist/_chunks/index-CQos-KS0.js.map +1 -0
- package/dist/_chunks/{layout-CPn1PM6x.mjs → layout-0TY7UtKO.mjs} +39 -22
- package/dist/_chunks/layout-0TY7UtKO.mjs.map +1 -0
- package/dist/_chunks/{layout-b91XRlD2.js → layout-B4XAqu1v.js} +37 -20
- package/dist/_chunks/layout-B4XAqu1v.js.map +1 -0
- package/dist/_chunks/{relations-BsqxS6tR.mjs → relations-DFDWfa0s.mjs} +2 -2
- package/dist/_chunks/{relations-BsqxS6tR.mjs.map → relations-DFDWfa0s.mjs.map} +1 -1
- package/dist/_chunks/{relations-CA7IYmcP.js → relations-xZ2tMj1G.js} +2 -2
- package/dist/_chunks/{relations-CA7IYmcP.js.map → relations-xZ2tMj1G.js.map} +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +5 -5
- package/dist/admin/src/history/components/VersionInputRenderer.d.ts +1 -1
- package/dist/admin/src/history/index.d.ts +3 -0
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/index.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +8 -3
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +4 -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 +6 -58
- package/dist/admin/src/pages/ListView/components/BulkActions/Actions.d.ts +3 -30
- package/dist/admin/src/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.d.ts +2 -2
- package/dist/admin/src/services/api.d.ts +1 -1
- package/dist/admin/src/services/components.d.ts +2 -2
- package/dist/admin/src/services/contentTypes.d.ts +3 -3
- package/dist/admin/src/services/documents.d.ts +19 -17
- package/dist/admin/src/services/init.d.ts +1 -1
- package/dist/admin/src/services/relations.d.ts +2 -2
- package/dist/admin/src/services/uid.d.ts +3 -3
- package/dist/admin/src/utils/validation.d.ts +4 -1
- package/dist/server/index.js +180 -106
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +181 -107
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/controllers/relations.d.ts.map +1 -1
- package/dist/server/src/controllers/uid.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/dimensions.d.ts +4 -2
- package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -1
- package/dist/server/src/history/services/history.d.ts.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
- package/dist/server/src/history/services/utils.d.ts +2 -1
- package/dist/server/src/history/services/utils.d.ts.map +1 -1
- package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/permission-checker.d.ts.map +1 -1
- package/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/dist/shared/contracts/collection-types.d.ts +3 -1
- package/dist/shared/contracts/collection-types.d.ts.map +1 -1
- package/package.json +8 -8
- package/dist/_chunks/EditViewPage-CoQEnFlC.js.map +0 -1
- package/dist/_chunks/EditViewPage-DvaV7U9b.mjs.map +0 -1
- package/dist/_chunks/Field-Cz_J9551.mjs.map +0 -1
- package/dist/_chunks/Field-ZdrmmQ4Y.js.map +0 -1
- package/dist/_chunks/Form-Bpig5rch.js.map +0 -1
- package/dist/_chunks/Form-Dxmihyw8.mjs.map +0 -1
- package/dist/_chunks/History-BZP8n7KT.mjs.map +0 -1
- package/dist/_chunks/History-BfX6XmZK.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-B3CXj8PY.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DxKuVkKz.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-Bk9VO__I.js.map +0 -1
- package/dist/_chunks/ListViewPage-D5D3tVPq.mjs.map +0 -1
- package/dist/_chunks/Relations-B6B3A3mb.js.map +0 -1
- package/dist/_chunks/Relations-BOYZmuWy.mjs.map +0 -1
- package/dist/_chunks/index-DzN3kBgx.js.map +0 -1
- package/dist/_chunks/index-VHviNMeW.mjs.map +0 -1
- package/dist/_chunks/layout-CPn1PM6x.mjs.map +0 -1
- package/dist/_chunks/layout-b91XRlD2.js.map +0 -1
@@ -1,17 +1,17 @@
|
|
1
|
-
import {
|
1
|
+
import { More, Cross, WarningCircle, ListPlus, Pencil, Trash, Check, CrossCircle, CheckCircle, ArrowsCounterClockwise, ChevronRight, Duplicate, ClockCounterClockwise, Feather } from "@strapi/icons";
|
2
2
|
import { jsx, Fragment, jsxs } from "react/jsx-runtime";
|
3
|
-
import { useStrapiApp,
|
4
|
-
import { stringify } from "qs";
|
5
|
-
import { useIntl } from "react-intl";
|
6
|
-
import { useNavigate, useParams, Navigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
|
3
|
+
import { useStrapiApp, createContext, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, 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 { Menu, VisuallyHidden, Flex, Typography, Dialog,
|
10
|
-
import {
|
6
|
+
import { Button, Menu, 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";
|
11
9
|
import * as yup from "yup";
|
12
10
|
import { ValidationError } from "yup";
|
13
11
|
import pipe from "lodash/fp/pipe";
|
14
12
|
import { intervalToDuration, isPast } from "date-fns";
|
13
|
+
import { styled } from "styled-components";
|
14
|
+
import { stringify } from "qs";
|
15
15
|
import { createSlice, combineReducers } from "@reduxjs/toolkit";
|
16
16
|
const __variableDynamicImportRuntimeHelper = (glob, path) => {
|
17
17
|
const v = glob[path];
|
@@ -49,42 +49,6 @@ const useInjectionZone = (area) => {
|
|
49
49
|
const [page, position] = area.split(".");
|
50
50
|
return contentManagerPlugin.getInjectedComponents(page, position);
|
51
51
|
};
|
52
|
-
const HistoryAction = ({ model, document }) => {
|
53
|
-
const { formatMessage } = useIntl();
|
54
|
-
const [{ query }] = useQueryParams();
|
55
|
-
const navigate = useNavigate();
|
56
|
-
const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
|
57
|
-
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
58
|
-
return null;
|
59
|
-
}
|
60
|
-
return {
|
61
|
-
icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
|
62
|
-
label: formatMessage({
|
63
|
-
id: "content-manager.history.document-action",
|
64
|
-
defaultMessage: "Content History"
|
65
|
-
}),
|
66
|
-
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
67
|
-
disabled: (
|
68
|
-
/**
|
69
|
-
* The user is creating a new document.
|
70
|
-
* It hasn't been saved yet, so there's no history to go to
|
71
|
-
*/
|
72
|
-
!document || /**
|
73
|
-
* The document has been created but the current dimension has never been saved.
|
74
|
-
* For example, the user is creating a new locale in an existing document,
|
75
|
-
* so there's no history for the document in that locale
|
76
|
-
*/
|
77
|
-
!document.id || /**
|
78
|
-
* History is only available for content types created by the user.
|
79
|
-
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
80
|
-
* which start with `admin::` or `plugin::`
|
81
|
-
*/
|
82
|
-
!model.startsWith("api::")
|
83
|
-
),
|
84
|
-
position: "header"
|
85
|
-
};
|
86
|
-
};
|
87
|
-
HistoryAction.type = "history";
|
88
52
|
const ID = "id";
|
89
53
|
const CREATED_BY_ATTRIBUTE_NAME = "createdBy";
|
90
54
|
const UPDATED_BY_ATTRIBUTE_NAME = "updatedBy";
|
@@ -194,10 +158,12 @@ 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({
|
166
|
+
overrideExisting: true,
|
201
167
|
endpoints: (builder) => ({
|
202
168
|
autoCloneDocument: builder.mutation({
|
203
169
|
query: ({ model, sourceId, query }) => ({
|
@@ -207,7 +173,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
207
173
|
params: query
|
208
174
|
}
|
209
175
|
}),
|
210
|
-
invalidatesTags: (_result,
|
176
|
+
invalidatesTags: (_result, error, { model }) => {
|
177
|
+
if (error) {
|
178
|
+
return [];
|
179
|
+
}
|
180
|
+
return [{ type: "Document", id: `${model}_LIST` }];
|
181
|
+
}
|
211
182
|
}),
|
212
183
|
cloneDocument: builder.mutation({
|
213
184
|
query: ({ model, sourceId, data, params }) => ({
|
@@ -218,7 +189,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
218
189
|
params
|
219
190
|
}
|
220
191
|
}),
|
221
|
-
invalidatesTags: (_result, _error, { model }) => [
|
192
|
+
invalidatesTags: (_result, _error, { model }) => [
|
193
|
+
{ type: "Document", id: `${model}_LIST` },
|
194
|
+
{ type: "UidAvailability", id: model }
|
195
|
+
]
|
222
196
|
}),
|
223
197
|
/**
|
224
198
|
* Creates a new collection-type document. This should ONLY be used for collection-types.
|
@@ -235,7 +209,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
235
209
|
}),
|
236
210
|
invalidatesTags: (result, _error, { model }) => [
|
237
211
|
{ type: "Document", id: `${model}_LIST` },
|
238
|
-
"Relations"
|
212
|
+
"Relations",
|
213
|
+
{ type: "UidAvailability", id: model }
|
239
214
|
]
|
240
215
|
}),
|
241
216
|
deleteDocument: builder.mutation({
|
@@ -276,7 +251,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
276
251
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
277
252
|
},
|
278
253
|
{ type: "Document", id: `${model}_LIST` },
|
279
|
-
"Relations"
|
254
|
+
"Relations",
|
255
|
+
{ type: "UidAvailability", id: model }
|
280
256
|
];
|
281
257
|
}
|
282
258
|
}),
|
@@ -294,6 +270,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
294
270
|
}),
|
295
271
|
providesTags: (result, _error, arg) => {
|
296
272
|
return [
|
273
|
+
{ type: "Document", id: `ALL_LIST` },
|
297
274
|
{ type: "Document", id: `${arg.model}_LIST` },
|
298
275
|
...result?.results.map(({ documentId }) => ({
|
299
276
|
type: "Document",
|
@@ -332,6 +309,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
332
309
|
{
|
333
310
|
type: "Document",
|
334
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`
|
335
317
|
}
|
336
318
|
];
|
337
319
|
}
|
@@ -395,8 +377,21 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
395
377
|
type: "Document",
|
396
378
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
397
379
|
},
|
398
|
-
"Relations"
|
380
|
+
"Relations",
|
381
|
+
{ type: "UidAvailability", id: model }
|
399
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
|
+
}
|
400
395
|
}
|
401
396
|
}),
|
402
397
|
unpublishDocument: builder.mutation({
|
@@ -466,7 +461,7 @@ const buildValidParams = (query) => {
|
|
466
461
|
const isBaseQueryError = (error) => {
|
467
462
|
return error.name !== void 0;
|
468
463
|
};
|
469
|
-
const createYupSchema = (attributes = {}, components = {}) => {
|
464
|
+
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
470
465
|
const createModelSchema = (attributes2) => yup.object().shape(
|
471
466
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
472
467
|
if (DOCUMENT_META_FIELDS.includes(name)) {
|
@@ -479,7 +474,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
479
474
|
addMinValidation,
|
480
475
|
addMaxValidation,
|
481
476
|
addRegexValidation
|
482
|
-
].map((fn) => fn(attribute));
|
477
|
+
].map((fn) => fn(attribute, options));
|
483
478
|
const transformSchema = pipe(...validations);
|
484
479
|
switch (attribute.type) {
|
485
480
|
case "component": {
|
@@ -580,6 +575,14 @@ const createAttributeSchema = (attribute) => {
|
|
580
575
|
if (!value || typeof value === "string" && value.length === 0) {
|
581
576
|
return true;
|
582
577
|
}
|
578
|
+
if (typeof value === "object") {
|
579
|
+
try {
|
580
|
+
JSON.stringify(value);
|
581
|
+
return true;
|
582
|
+
} catch (err) {
|
583
|
+
return false;
|
584
|
+
}
|
585
|
+
}
|
583
586
|
try {
|
584
587
|
JSON.parse(value);
|
585
588
|
return true;
|
@@ -598,13 +601,7 @@ const createAttributeSchema = (attribute) => {
|
|
598
601
|
return yup.mixed();
|
599
602
|
}
|
600
603
|
};
|
601
|
-
const
|
602
|
-
if (attribute.required) {
|
603
|
-
return schema.required({
|
604
|
-
id: translatedErrors.required.id,
|
605
|
-
defaultMessage: "This field is required."
|
606
|
-
});
|
607
|
-
}
|
604
|
+
const nullableSchema = (schema) => {
|
608
605
|
return schema?.nullable ? schema.nullable() : (
|
609
606
|
// In some cases '.nullable' will not be available on the schema.
|
610
607
|
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
@@ -612,7 +609,22 @@ const addRequiredValidation = (attribute) => (schema) => {
|
|
612
609
|
schema
|
613
610
|
);
|
614
611
|
};
|
615
|
-
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
|
+
}
|
616
628
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
617
629
|
return schema.min(attribute.minLength, {
|
618
630
|
...translatedErrors.minLength,
|
@@ -634,9 +646,31 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
634
646
|
}
|
635
647
|
return schema;
|
636
648
|
};
|
637
|
-
const addMinValidation = (attribute) => (schema) => {
|
649
|
+
const addMinValidation = (attribute, options) => (schema) => {
|
638
650
|
if ("min" in attribute) {
|
639
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
|
+
}
|
640
674
|
if ("min" in schema && min) {
|
641
675
|
return schema.min(min, {
|
642
676
|
...translatedErrors.min,
|
@@ -763,7 +797,10 @@ const useDocument = (args, opts) => {
|
|
763
797
|
isLoading: isLoadingDocument,
|
764
798
|
isFetching: isFetchingDocument,
|
765
799
|
error
|
766
|
-
} = useGetDocumentQuery(args,
|
800
|
+
} = useGetDocumentQuery(args, {
|
801
|
+
...opts,
|
802
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
803
|
+
});
|
767
804
|
const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
|
768
805
|
React.useEffect(() => {
|
769
806
|
if (error) {
|
@@ -849,6 +886,7 @@ const useDocumentActions = () => {
|
|
849
886
|
const { formatMessage } = useIntl();
|
850
887
|
const { trackUsage } = useTracking();
|
851
888
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
889
|
+
const navigate = useNavigate();
|
852
890
|
const [deleteDocument] = useDeleteDocumentMutation();
|
853
891
|
const _delete = React.useCallback(
|
854
892
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -927,12 +965,13 @@ const useDocumentActions = () => {
|
|
927
965
|
);
|
928
966
|
const [discardDocument] = useDiscardDocumentMutation();
|
929
967
|
const discard = React.useCallback(
|
930
|
-
async ({ collectionType, model, documentId }) => {
|
968
|
+
async ({ collectionType, model, documentId, params }) => {
|
931
969
|
try {
|
932
970
|
const res = await discardDocument({
|
933
971
|
collectionType,
|
934
972
|
model,
|
935
|
-
documentId
|
973
|
+
documentId,
|
974
|
+
params
|
936
975
|
});
|
937
976
|
if ("error" in res) {
|
938
977
|
toggleNotification({
|
@@ -1183,7 +1222,6 @@ const useDocumentActions = () => {
|
|
1183
1222
|
sourceId
|
1184
1223
|
});
|
1185
1224
|
if ("error" in res) {
|
1186
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1187
1225
|
return { error: res.error };
|
1188
1226
|
}
|
1189
1227
|
toggleNotification({
|
@@ -1202,7 +1240,7 @@ const useDocumentActions = () => {
|
|
1202
1240
|
throw err;
|
1203
1241
|
}
|
1204
1242
|
},
|
1205
|
-
[autoCloneDocument,
|
1243
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1206
1244
|
);
|
1207
1245
|
const [cloneDocument] = useCloneDocumentMutation();
|
1208
1246
|
const clone = React.useCallback(
|
@@ -1228,6 +1266,7 @@ const useDocumentActions = () => {
|
|
1228
1266
|
defaultMessage: "Cloned document"
|
1229
1267
|
})
|
1230
1268
|
});
|
1269
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1231
1270
|
return res.data;
|
1232
1271
|
} catch (err) {
|
1233
1272
|
toggleNotification({
|
@@ -1238,7 +1277,7 @@ const useDocumentActions = () => {
|
|
1238
1277
|
throw err;
|
1239
1278
|
}
|
1240
1279
|
},
|
1241
|
-
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
|
1280
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1242
1281
|
);
|
1243
1282
|
const [getDoc] = useLazyGetDocumentQuery();
|
1244
1283
|
const getDocument = React.useCallback(
|
@@ -1264,7 +1303,7 @@ const useDocumentActions = () => {
|
|
1264
1303
|
};
|
1265
1304
|
};
|
1266
1305
|
const ProtectedHistoryPage = lazy(
|
1267
|
-
() => import("./History-
|
1306
|
+
() => import("./History-BseDJOrj.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1268
1307
|
);
|
1269
1308
|
const routes$1 = [
|
1270
1309
|
{
|
@@ -1277,31 +1316,31 @@ const routes$1 = [
|
|
1277
1316
|
}
|
1278
1317
|
];
|
1279
1318
|
const ProtectedEditViewPage = lazy(
|
1280
|
-
() => import("./EditViewPage-
|
1319
|
+
() => import("./EditViewPage-CvRUUpVh.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1281
1320
|
);
|
1282
1321
|
const ProtectedListViewPage = lazy(
|
1283
|
-
() => import("./ListViewPage-
|
1322
|
+
() => import("./ListViewPage-lQ-VLV2G.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1284
1323
|
);
|
1285
1324
|
const ProtectedListConfiguration = lazy(
|
1286
|
-
() => import("./ListConfigurationPage-
|
1325
|
+
() => import("./ListConfigurationPage-DWE_fr5B.mjs").then((mod) => ({
|
1287
1326
|
default: mod.ProtectedListConfiguration
|
1288
1327
|
}))
|
1289
1328
|
);
|
1290
1329
|
const ProtectedEditConfigurationPage = lazy(
|
1291
|
-
() => import("./EditConfigurationPage-
|
1330
|
+
() => import("./EditConfigurationPage-QBZdUYyG.mjs").then((mod) => ({
|
1292
1331
|
default: mod.ProtectedEditConfigurationPage
|
1293
1332
|
}))
|
1294
1333
|
);
|
1295
1334
|
const ProtectedComponentConfigurationPage = lazy(
|
1296
|
-
() => import("./ComponentConfigurationPage-
|
1335
|
+
() => import("./ComponentConfigurationPage-DJEJ49QD.mjs").then((mod) => ({
|
1297
1336
|
default: mod.ProtectedComponentConfigurationPage
|
1298
1337
|
}))
|
1299
1338
|
);
|
1300
1339
|
const NoPermissions = lazy(
|
1301
|
-
() => import("./NoPermissionsPage-
|
1340
|
+
() => import("./NoPermissionsPage-TV830k4P.mjs").then((mod) => ({ default: mod.NoPermissions }))
|
1302
1341
|
);
|
1303
1342
|
const NoContentType = lazy(
|
1304
|
-
() => import("./NoContentTypePage-
|
1343
|
+
() => import("./NoContentTypePage-VCQOMwlf.mjs").then((mod) => ({ default: mod.NoContentType }))
|
1305
1344
|
);
|
1306
1345
|
const CollectionTypePages = () => {
|
1307
1346
|
const { collectionType } = useParams();
|
@@ -1415,12 +1454,14 @@ const DocumentActionButton = (action) => {
|
|
1415
1454
|
/* @__PURE__ */ jsx(
|
1416
1455
|
Button,
|
1417
1456
|
{
|
1418
|
-
flex:
|
1457
|
+
flex: "auto",
|
1419
1458
|
startIcon: action.icon,
|
1420
1459
|
disabled: action.disabled,
|
1421
1460
|
onClick: handleClick(action),
|
1422
1461
|
justifyContent: "center",
|
1423
1462
|
variant: action.variant || "default",
|
1463
|
+
paddingTop: "7px",
|
1464
|
+
paddingBottom: "7px",
|
1424
1465
|
children: action.label
|
1425
1466
|
}
|
1426
1467
|
),
|
@@ -1428,7 +1469,7 @@ const DocumentActionButton = (action) => {
|
|
1428
1469
|
DocumentActionConfirmDialog,
|
1429
1470
|
{
|
1430
1471
|
...action.dialog,
|
1431
|
-
variant: action.variant,
|
1472
|
+
variant: action.dialog?.variant ?? action.variant,
|
1432
1473
|
isOpen: dialogId === action.id,
|
1433
1474
|
onClose: handleClose
|
1434
1475
|
}
|
@@ -1485,9 +1526,9 @@ const DocumentActionsMenu = ({
|
|
1485
1526
|
disabled: isDisabled,
|
1486
1527
|
size: "S",
|
1487
1528
|
endIcon: null,
|
1488
|
-
paddingTop: "
|
1489
|
-
paddingLeft: "
|
1490
|
-
paddingRight: "
|
1529
|
+
paddingTop: "4px",
|
1530
|
+
paddingLeft: "7px",
|
1531
|
+
paddingRight: "7px",
|
1491
1532
|
variant,
|
1492
1533
|
children: [
|
1493
1534
|
/* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
|
@@ -1507,10 +1548,25 @@ const DocumentActionsMenu = ({
|
|
1507
1548
|
onSelect: handleClick(action),
|
1508
1549
|
display: "block",
|
1509
1550
|
children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", gap: 4, children: [
|
1510
|
-
/* @__PURE__ */ jsxs(
|
1511
|
-
|
1512
|
-
|
1513
|
-
|
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
|
+
),
|
1514
1570
|
action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsx(
|
1515
1571
|
Flex,
|
1516
1572
|
{
|
@@ -1569,6 +1625,18 @@ const convertActionVariantToColor = (variant = "secondary") => {
|
|
1569
1625
|
return "primary600";
|
1570
1626
|
}
|
1571
1627
|
};
|
1628
|
+
const convertActionVariantToIconColor = (variant = "secondary") => {
|
1629
|
+
switch (variant) {
|
1630
|
+
case "danger":
|
1631
|
+
return "danger600";
|
1632
|
+
case "secondary":
|
1633
|
+
return "neutral500";
|
1634
|
+
case "success":
|
1635
|
+
return "success600";
|
1636
|
+
default:
|
1637
|
+
return "primary600";
|
1638
|
+
}
|
1639
|
+
};
|
1572
1640
|
const DocumentActionConfirmDialog = ({
|
1573
1641
|
onClose,
|
1574
1642
|
onCancel,
|
@@ -1591,22 +1659,20 @@ const DocumentActionConfirmDialog = ({
|
|
1591
1659
|
}
|
1592
1660
|
onClose();
|
1593
1661
|
};
|
1594
|
-
return /* @__PURE__ */
|
1595
|
-
/* @__PURE__ */ jsx(
|
1596
|
-
/* @__PURE__ */ jsx(
|
1597
|
-
|
1598
|
-
{
|
1599
|
-
|
1600
|
-
|
1601
|
-
|
1602
|
-
|
1603
|
-
|
1604
|
-
|
1605
|
-
|
1606
|
-
|
1607
|
-
|
1608
|
-
)
|
1609
|
-
] });
|
1662
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
1663
|
+
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
1664
|
+
/* @__PURE__ */ jsx(Dialog.Body, { children: content }),
|
1665
|
+
/* @__PURE__ */ jsxs(Dialog.Footer, { children: [
|
1666
|
+
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", children: formatMessage({
|
1667
|
+
id: "app.components.Button.cancel",
|
1668
|
+
defaultMessage: "Cancel"
|
1669
|
+
}) }) }),
|
1670
|
+
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, children: formatMessage({
|
1671
|
+
id: "app.components.Button.confirm",
|
1672
|
+
defaultMessage: "Confirm"
|
1673
|
+
}) })
|
1674
|
+
] })
|
1675
|
+
] }) });
|
1610
1676
|
};
|
1611
1677
|
const DocumentActionModal = ({
|
1612
1678
|
isOpen,
|
@@ -1616,34 +1682,17 @@ const DocumentActionModal = ({
|
|
1616
1682
|
content: Content,
|
1617
1683
|
onModalClose
|
1618
1684
|
}) => {
|
1619
|
-
const id = React.useId();
|
1620
|
-
if (!isOpen) {
|
1621
|
-
return null;
|
1622
|
-
}
|
1623
1685
|
const handleClose = () => {
|
1624
1686
|
if (onClose) {
|
1625
1687
|
onClose();
|
1626
1688
|
}
|
1627
1689
|
onModalClose();
|
1628
1690
|
};
|
1629
|
-
return /* @__PURE__ */
|
1630
|
-
/* @__PURE__ */ jsx(
|
1631
|
-
|
1632
|
-
/* @__PURE__ */ jsx(
|
1633
|
-
|
1634
|
-
{
|
1635
|
-
paddingTop: 4,
|
1636
|
-
paddingBottom: 4,
|
1637
|
-
paddingLeft: 5,
|
1638
|
-
paddingRight: 5,
|
1639
|
-
borderWidth: "1px 0 0 0",
|
1640
|
-
borderStyle: "solid",
|
1641
|
-
borderColor: "neutral150",
|
1642
|
-
background: "neutral100",
|
1643
|
-
children: typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
|
1644
|
-
}
|
1645
|
-
)
|
1646
|
-
] });
|
1691
|
+
return /* @__PURE__ */ jsx(Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
|
1692
|
+
/* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: title }) }),
|
1693
|
+
typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsx(Modal.Body, { children: Content }),
|
1694
|
+
typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
|
1695
|
+
] }) });
|
1647
1696
|
};
|
1648
1697
|
const PublishAction$1 = ({
|
1649
1698
|
activeTab,
|
@@ -1657,13 +1706,17 @@ const PublishAction$1 = ({
|
|
1657
1706
|
const navigate = useNavigate();
|
1658
1707
|
const { toggleNotification } = useNotification();
|
1659
1708
|
const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
|
1709
|
+
const isListView = useMatch(LIST_PATH) !== null;
|
1660
1710
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
1661
1711
|
const { formatMessage } = useIntl();
|
1662
|
-
const { canPublish
|
1663
|
-
"PublishAction",
|
1664
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1665
|
-
);
|
1712
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1666
1713
|
const { publish } = useDocumentActions();
|
1714
|
+
const [
|
1715
|
+
countDraftRelations,
|
1716
|
+
{ isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
|
1717
|
+
] = useLazyGetDraftRelationCountQuery();
|
1718
|
+
const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React.useState(0);
|
1719
|
+
const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React.useState(0);
|
1667
1720
|
const [{ query, rawQuery }] = useQueryParams();
|
1668
1721
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
1669
1722
|
const modified = useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
@@ -1672,10 +1725,103 @@ const PublishAction$1 = ({
|
|
1672
1725
|
const validate = useForm("PublishAction", (state) => state.validate);
|
1673
1726
|
const setErrors = useForm("PublishAction", (state) => state.setErrors);
|
1674
1727
|
const formValues = useForm("PublishAction", ({ values }) => values);
|
1728
|
+
React.useEffect(() => {
|
1729
|
+
if (isErrorDraftRelations) {
|
1730
|
+
toggleNotification({
|
1731
|
+
type: "danger",
|
1732
|
+
message: formatMessage({
|
1733
|
+
id: getTranslation("error.records.fetch-draft-relatons"),
|
1734
|
+
defaultMessage: "An error occurred while fetching draft relations on this document."
|
1735
|
+
})
|
1736
|
+
});
|
1737
|
+
}
|
1738
|
+
}, [isErrorDraftRelations, toggleNotification, formatMessage]);
|
1739
|
+
React.useEffect(() => {
|
1740
|
+
const localDraftRelations = /* @__PURE__ */ new Set();
|
1741
|
+
const extractDraftRelations = (data) => {
|
1742
|
+
const relations = data.connect || [];
|
1743
|
+
relations.forEach((relation) => {
|
1744
|
+
if (relation.status === "draft") {
|
1745
|
+
localDraftRelations.add(relation.id);
|
1746
|
+
}
|
1747
|
+
});
|
1748
|
+
};
|
1749
|
+
const traverseAndExtract = (data) => {
|
1750
|
+
Object.entries(data).forEach(([key, value]) => {
|
1751
|
+
if (key === "connect" && Array.isArray(value)) {
|
1752
|
+
extractDraftRelations({ connect: value });
|
1753
|
+
} else if (typeof value === "object" && value !== null) {
|
1754
|
+
traverseAndExtract(value);
|
1755
|
+
}
|
1756
|
+
});
|
1757
|
+
};
|
1758
|
+
if (!documentId || modified) {
|
1759
|
+
traverseAndExtract(formValues);
|
1760
|
+
setLocalCountOfDraftRelations(localDraftRelations.size);
|
1761
|
+
}
|
1762
|
+
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
1763
|
+
React.useEffect(() => {
|
1764
|
+
if (!document || !document.documentId || isListView) {
|
1765
|
+
return;
|
1766
|
+
}
|
1767
|
+
const fetchDraftRelationsCount = async () => {
|
1768
|
+
const { data, error } = await countDraftRelations({
|
1769
|
+
collectionType,
|
1770
|
+
model,
|
1771
|
+
documentId,
|
1772
|
+
params
|
1773
|
+
});
|
1774
|
+
if (error) {
|
1775
|
+
throw error;
|
1776
|
+
}
|
1777
|
+
if (data) {
|
1778
|
+
setServerCountOfDraftRelations(data.data);
|
1779
|
+
}
|
1780
|
+
};
|
1781
|
+
fetchDraftRelationsCount();
|
1782
|
+
}, [isListView, document, documentId, countDraftRelations, collectionType, model, params]);
|
1675
1783
|
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
1676
1784
|
if (!schema?.options?.draftAndPublish) {
|
1677
1785
|
return null;
|
1678
1786
|
}
|
1787
|
+
const performPublish = async () => {
|
1788
|
+
setSubmitting(true);
|
1789
|
+
try {
|
1790
|
+
const { errors } = await validate();
|
1791
|
+
if (errors) {
|
1792
|
+
toggleNotification({
|
1793
|
+
type: "danger",
|
1794
|
+
message: formatMessage({
|
1795
|
+
id: "content-manager.validation.error",
|
1796
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
1797
|
+
})
|
1798
|
+
});
|
1799
|
+
return;
|
1800
|
+
}
|
1801
|
+
const res = await publish(
|
1802
|
+
{
|
1803
|
+
collectionType,
|
1804
|
+
model,
|
1805
|
+
documentId,
|
1806
|
+
params
|
1807
|
+
},
|
1808
|
+
formValues
|
1809
|
+
);
|
1810
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1811
|
+
navigate({
|
1812
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1813
|
+
search: rawQuery
|
1814
|
+
});
|
1815
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1816
|
+
setErrors(formatValidationErrors(res.error));
|
1817
|
+
}
|
1818
|
+
} finally {
|
1819
|
+
setSubmitting(false);
|
1820
|
+
}
|
1821
|
+
};
|
1822
|
+
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
1823
|
+
const enableDraftRelationsCount = false;
|
1824
|
+
const hasDraftRelations = enableDraftRelationsCount;
|
1679
1825
|
return {
|
1680
1826
|
/**
|
1681
1827
|
* Disabled when:
|
@@ -1685,49 +1831,36 @@ const PublishAction$1 = ({
|
|
1685
1831
|
* - the document is already published & not modified
|
1686
1832
|
* - the document is being created & not modified
|
1687
1833
|
* - the user doesn't have the permission to publish
|
1688
|
-
* - the user doesn't have the permission to create a new document
|
1689
|
-
* - the user doesn't have the permission to update the document
|
1690
1834
|
*/
|
1691
|
-
disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish
|
1835
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
1692
1836
|
label: formatMessage({
|
1693
1837
|
id: "app.utils.publish",
|
1694
1838
|
defaultMessage: "Publish"
|
1695
1839
|
}),
|
1696
1840
|
onClick: async () => {
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
|
1713
|
-
|
1714
|
-
documentId,
|
1715
|
-
params
|
1716
|
-
},
|
1717
|
-
formValues
|
1718
|
-
);
|
1719
|
-
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1720
|
-
navigate({
|
1721
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1722
|
-
search: rawQuery
|
1723
|
-
});
|
1724
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1725
|
-
setErrors(formatValidationErrors(res.error));
|
1841
|
+
await performPublish();
|
1842
|
+
},
|
1843
|
+
dialog: hasDraftRelations ? {
|
1844
|
+
type: "dialog",
|
1845
|
+
variant: "danger",
|
1846
|
+
footer: null,
|
1847
|
+
title: formatMessage({
|
1848
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
|
1849
|
+
defaultMessage: "Confirmation"
|
1850
|
+
}),
|
1851
|
+
content: formatMessage(
|
1852
|
+
{
|
1853
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
1854
|
+
defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
|
1855
|
+
},
|
1856
|
+
{
|
1857
|
+
count: totalDraftRelations
|
1726
1858
|
}
|
1727
|
-
|
1728
|
-
|
1859
|
+
),
|
1860
|
+
onConfirm: async () => {
|
1861
|
+
await performPublish();
|
1729
1862
|
}
|
1730
|
-
}
|
1863
|
+
} : void 0
|
1731
1864
|
};
|
1732
1865
|
};
|
1733
1866
|
PublishAction$1.type = "publish";
|
@@ -1743,10 +1876,6 @@ const UpdateAction = ({
|
|
1743
1876
|
const cloneMatch = useMatch(CLONE_PATH);
|
1744
1877
|
const isCloning = cloneMatch !== null;
|
1745
1878
|
const { formatMessage } = useIntl();
|
1746
|
-
const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1747
|
-
canCreate: canCreate2,
|
1748
|
-
canUpdate: canUpdate2
|
1749
|
-
}));
|
1750
1879
|
const { create, update, clone } = useDocumentActions();
|
1751
1880
|
const [{ query, rawQuery }] = useQueryParams();
|
1752
1881
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
@@ -1763,10 +1892,8 @@ const UpdateAction = ({
|
|
1763
1892
|
* - the form is submitting
|
1764
1893
|
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
1765
1894
|
* - the active tab is the published tab
|
1766
|
-
* - the user doesn't have the permission to create a new document
|
1767
|
-
* - the user doesn't have the permission to update the document
|
1768
1895
|
*/
|
1769
|
-
disabled: isSubmitting || !modified && !isCloning || activeTab === "published"
|
1896
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1770
1897
|
label: formatMessage({
|
1771
1898
|
id: "content-manager.containers.Edit.save",
|
1772
1899
|
defaultMessage: "Save"
|
@@ -1774,16 +1901,18 @@ const UpdateAction = ({
|
|
1774
1901
|
onClick: async () => {
|
1775
1902
|
setSubmitting(true);
|
1776
1903
|
try {
|
1777
|
-
|
1778
|
-
|
1779
|
-
|
1780
|
-
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
-
|
1785
|
-
|
1786
|
-
|
1904
|
+
if (activeTab !== "draft") {
|
1905
|
+
const { errors } = await validate();
|
1906
|
+
if (errors) {
|
1907
|
+
toggleNotification({
|
1908
|
+
type: "danger",
|
1909
|
+
message: formatMessage({
|
1910
|
+
id: "content-manager.validation.error",
|
1911
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
1912
|
+
})
|
1913
|
+
});
|
1914
|
+
return;
|
1915
|
+
}
|
1787
1916
|
}
|
1788
1917
|
if (isCloning) {
|
1789
1918
|
const res = await clone(
|
@@ -1795,10 +1924,13 @@ const UpdateAction = ({
|
|
1795
1924
|
document
|
1796
1925
|
);
|
1797
1926
|
if ("data" in res) {
|
1798
|
-
navigate(
|
1799
|
-
|
1800
|
-
|
1801
|
-
|
1927
|
+
navigate(
|
1928
|
+
{
|
1929
|
+
pathname: `../${res.data.documentId}`,
|
1930
|
+
search: rawQuery
|
1931
|
+
},
|
1932
|
+
{ relative: "path" }
|
1933
|
+
);
|
1802
1934
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1803
1935
|
setErrors(formatValidationErrors(res.error));
|
1804
1936
|
}
|
@@ -1826,10 +1958,13 @@ const UpdateAction = ({
|
|
1826
1958
|
document
|
1827
1959
|
);
|
1828
1960
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1829
|
-
navigate(
|
1830
|
-
|
1831
|
-
|
1832
|
-
|
1961
|
+
navigate(
|
1962
|
+
{
|
1963
|
+
pathname: `../${res.data.documentId}`,
|
1964
|
+
search: rawQuery
|
1965
|
+
},
|
1966
|
+
{ replace: true, relative: "path" }
|
1967
|
+
);
|
1833
1968
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1834
1969
|
setErrors(formatValidationErrors(res.error));
|
1835
1970
|
}
|
@@ -1861,10 +1996,8 @@ const UnpublishAction$1 = ({
|
|
1861
1996
|
const { toggleNotification } = useNotification();
|
1862
1997
|
const [shouldKeepDraft, setShouldKeepDraft] = React.useState(true);
|
1863
1998
|
const isDocumentModified = document?.status === "modified";
|
1864
|
-
const handleChange = (
|
1865
|
-
|
1866
|
-
setShouldKeepDraft(e.target.value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1867
|
-
}
|
1999
|
+
const handleChange = (value) => {
|
2000
|
+
setShouldKeepDraft(value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1868
2001
|
};
|
1869
2002
|
if (!schema?.options?.draftAndPublish) {
|
1870
2003
|
return null;
|
@@ -1875,7 +2008,7 @@ const UnpublishAction$1 = ({
|
|
1875
2008
|
id: "app.utils.unpublish",
|
1876
2009
|
defaultMessage: "Unpublish"
|
1877
2010
|
}),
|
1878
|
-
icon: /* @__PURE__ */ jsx(
|
2011
|
+
icon: /* @__PURE__ */ jsx(Cross, {}),
|
1879
2012
|
onClick: async () => {
|
1880
2013
|
if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
|
1881
2014
|
if (!documentId) {
|
@@ -1914,40 +2047,24 @@ const UnpublishAction$1 = ({
|
|
1914
2047
|
}) })
|
1915
2048
|
] }),
|
1916
2049
|
/* @__PURE__ */ jsxs(
|
1917
|
-
|
2050
|
+
Radio.Group,
|
1918
2051
|
{
|
1919
|
-
|
1920
|
-
|
1921
|
-
|
1922
|
-
|
1923
|
-
|
1924
|
-
|
2052
|
+
defaultValue: UNPUBLISH_DRAFT_OPTIONS.KEEP,
|
2053
|
+
name: "discard-options",
|
2054
|
+
"aria-label": formatMessage({
|
2055
|
+
id: "content-manager.actions.unpublish.dialog.radio-label",
|
2056
|
+
defaultMessage: "Choose an option to unpublish the document."
|
2057
|
+
}),
|
2058
|
+
onValueChange: handleChange,
|
1925
2059
|
children: [
|
1926
|
-
/* @__PURE__ */ jsx(
|
1927
|
-
|
1928
|
-
|
1929
|
-
|
1930
|
-
|
1931
|
-
|
1932
|
-
|
1933
|
-
|
1934
|
-
id: "content-manager.actions.unpublish.dialog.option.keep-draft",
|
1935
|
-
defaultMessage: "Keep draft"
|
1936
|
-
})
|
1937
|
-
}
|
1938
|
-
),
|
1939
|
-
/* @__PURE__ */ jsx(
|
1940
|
-
Radio,
|
1941
|
-
{
|
1942
|
-
checked: !shouldKeepDraft,
|
1943
|
-
value: UNPUBLISH_DRAFT_OPTIONS.DISCARD,
|
1944
|
-
name: "discard-options",
|
1945
|
-
children: formatMessage({
|
1946
|
-
id: "content-manager.actions.unpublish.dialog.option.replace-draft",
|
1947
|
-
defaultMessage: "Replace draft"
|
1948
|
-
})
|
1949
|
-
}
|
1950
|
-
)
|
2060
|
+
/* @__PURE__ */ jsx(Radio.Item, { checked: shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.KEEP, children: formatMessage({
|
2061
|
+
id: "content-manager.actions.unpublish.dialog.option.keep-draft",
|
2062
|
+
defaultMessage: "Keep draft"
|
2063
|
+
}) }),
|
2064
|
+
/* @__PURE__ */ jsx(Radio.Item, { checked: !shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.DISCARD, children: formatMessage({
|
2065
|
+
id: "content-manager.actions.unpublish.dialog.option.replace-draft",
|
2066
|
+
defaultMessage: "Replace draft"
|
2067
|
+
}) })
|
1951
2068
|
]
|
1952
2069
|
}
|
1953
2070
|
)
|
@@ -2003,7 +2120,7 @@ const DiscardAction = ({
|
|
2003
2120
|
id: "content-manager.actions.discard.label",
|
2004
2121
|
defaultMessage: "Discard changes"
|
2005
2122
|
}),
|
2006
|
-
icon: /* @__PURE__ */ jsx(
|
2123
|
+
icon: /* @__PURE__ */ jsx(Cross, {}),
|
2007
2124
|
position: ["panel", "table-row"],
|
2008
2125
|
variant: "danger",
|
2009
2126
|
dialog: {
|
@@ -2031,11 +2148,6 @@ const DiscardAction = ({
|
|
2031
2148
|
};
|
2032
2149
|
};
|
2033
2150
|
DiscardAction.type = "discard";
|
2034
|
-
const StyledCrossCircle = styled(CrossCircle)`
|
2035
|
-
path {
|
2036
|
-
fill: currentColor;
|
2037
|
-
}
|
2038
|
-
`;
|
2039
2151
|
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2040
2152
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2041
2153
|
const RelativeTime = React.forwardRef(
|
@@ -2093,23 +2205,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
|
2093
2205
|
id: "content-manager.containers.edit.title.new",
|
2094
2206
|
defaultMessage: "Create an entry"
|
2095
2207
|
}) : documentTitle;
|
2096
|
-
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop:
|
2208
|
+
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2097
2209
|
/* @__PURE__ */ jsx(BackButton, {}),
|
2098
|
-
/* @__PURE__ */ jsxs(
|
2099
|
-
|
2100
|
-
{
|
2101
|
-
|
2102
|
-
|
2103
|
-
paddingTop: 1,
|
2104
|
-
gap: "80px",
|
2105
|
-
alignItems: "flex-start",
|
2106
|
-
children: [
|
2107
|
-
/* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
|
2108
|
-
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
2109
|
-
]
|
2110
|
-
}
|
2111
|
-
),
|
2112
|
-
status ? /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) : null
|
2210
|
+
/* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2211
|
+
/* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
|
2212
|
+
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
2213
|
+
] }),
|
2214
|
+
status ? /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
|
2113
2215
|
] });
|
2114
2216
|
};
|
2115
2217
|
const HeaderToolbar = () => {
|
@@ -2674,7 +2776,8 @@ const formatEditLayout = (data, {
|
|
2674
2776
|
layout: convertEditLayoutToFieldLayouts(
|
2675
2777
|
configuration.layouts.edit,
|
2676
2778
|
components[uid].attributes,
|
2677
|
-
configuration.metadatas
|
2779
|
+
configuration.metadatas,
|
2780
|
+
{ configurations: data.components, schemas: components }
|
2678
2781
|
),
|
2679
2782
|
settings: {
|
2680
2783
|
...configuration.settings,
|
@@ -2800,30 +2903,23 @@ const ConfirmBulkActionDialog = ({
|
|
2800
2903
|
endAction
|
2801
2904
|
}) => {
|
2802
2905
|
const { formatMessage } = useIntl();
|
2803
|
-
return /* @__PURE__ */ jsxs(
|
2804
|
-
Dialog,
|
2805
|
-
|
2806
|
-
|
2807
|
-
|
2808
|
-
|
2809
|
-
|
2810
|
-
|
2811
|
-
|
2812
|
-
|
2813
|
-
|
2814
|
-
|
2815
|
-
|
2816
|
-
|
2817
|
-
|
2818
|
-
|
2819
|
-
|
2820
|
-
}) }),
|
2821
|
-
endAction
|
2822
|
-
}
|
2823
|
-
)
|
2824
|
-
]
|
2825
|
-
}
|
2826
|
-
);
|
2906
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
2907
|
+
/* @__PURE__ */ jsx(Dialog.Header, { children: formatMessage({
|
2908
|
+
id: "app.components.ConfirmDialog.title",
|
2909
|
+
defaultMessage: "Confirmation"
|
2910
|
+
}) }),
|
2911
|
+
/* @__PURE__ */ jsx(Dialog.Body, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
2912
|
+
/* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
2913
|
+
dialogBody
|
2914
|
+
] }) }),
|
2915
|
+
/* @__PURE__ */ jsxs(Dialog.Footer, { children: [
|
2916
|
+
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { fullWidth: true, onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
|
2917
|
+
id: "app.components.Button.cancel",
|
2918
|
+
defaultMessage: "Cancel"
|
2919
|
+
}) }) }),
|
2920
|
+
endAction
|
2921
|
+
] })
|
2922
|
+
] }) });
|
2827
2923
|
};
|
2828
2924
|
const BoldChunk$1 = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
|
2829
2925
|
const ConfirmDialogPublishAll = ({
|
@@ -2838,6 +2934,7 @@ const ConfirmDialogPublishAll = ({
|
|
2838
2934
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(getTranslation);
|
2839
2935
|
const { model, schema } = useDoc();
|
2840
2936
|
const [{ query }] = useQueryParams();
|
2937
|
+
const enableDraftRelationsCount = false;
|
2841
2938
|
const {
|
2842
2939
|
data: countDraftRelations = 0,
|
2843
2940
|
isLoading,
|
@@ -2849,7 +2946,7 @@ const ConfirmDialogPublishAll = ({
|
|
2849
2946
|
locale: query?.plugins?.i18n?.locale
|
2850
2947
|
},
|
2851
2948
|
{
|
2852
|
-
skip:
|
2949
|
+
skip: !enableDraftRelationsCount
|
2853
2950
|
}
|
2854
2951
|
);
|
2855
2952
|
React.useEffect(() => {
|
@@ -2928,16 +3025,30 @@ const formatErrorMessages = (errors, parentKey, formatMessage) => {
|
|
2928
3025
|
)
|
2929
3026
|
);
|
2930
3027
|
} else {
|
2931
|
-
messages.push(
|
3028
|
+
messages.push(
|
3029
|
+
...formatErrorMessages(
|
3030
|
+
// @ts-expect-error TODO: check why value is not compatible with FormErrors
|
3031
|
+
value,
|
3032
|
+
currentKey,
|
3033
|
+
formatMessage
|
3034
|
+
)
|
3035
|
+
);
|
2932
3036
|
}
|
3037
|
+
} else {
|
3038
|
+
messages.push(
|
3039
|
+
formatMessage(
|
3040
|
+
{
|
3041
|
+
id: `${value}.withField`,
|
3042
|
+
defaultMessage: value
|
3043
|
+
},
|
3044
|
+
{ field: currentKey }
|
3045
|
+
)
|
3046
|
+
);
|
2933
3047
|
}
|
2934
3048
|
});
|
2935
3049
|
return messages;
|
2936
3050
|
};
|
2937
|
-
const EntryValidationText = ({
|
2938
|
-
validationErrors,
|
2939
|
-
isPublished = false
|
2940
|
-
}) => {
|
3051
|
+
const EntryValidationText = ({ validationErrors, status }) => {
|
2941
3052
|
const { formatMessage } = useIntl();
|
2942
3053
|
if (validationErrors) {
|
2943
3054
|
const validationErrorsMessages = formatErrorMessages(validationErrors, "", formatMessage).join(
|
@@ -2948,7 +3059,7 @@ const EntryValidationText = ({
|
|
2948
3059
|
/* @__PURE__ */ jsx(Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsx(TypographyMaxWidth, { textColor: "danger600", variant: "omega", fontWeight: "semiBold", ellipsis: true, children: validationErrorsMessages }) })
|
2949
3060
|
] });
|
2950
3061
|
}
|
2951
|
-
if (
|
3062
|
+
if (status === "published") {
|
2952
3063
|
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
2953
3064
|
/* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
2954
3065
|
/* @__PURE__ */ jsx(Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
|
@@ -2957,6 +3068,15 @@ const EntryValidationText = ({
|
|
2957
3068
|
}) })
|
2958
3069
|
] });
|
2959
3070
|
}
|
3071
|
+
if (status === "modified") {
|
3072
|
+
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
3073
|
+
/* @__PURE__ */ jsx(ArrowsCounterClockwise, { fill: "alternative600" }),
|
3074
|
+
/* @__PURE__ */ jsx(Typography, { children: formatMessage({
|
3075
|
+
id: "content-manager.bulk-publish.modified",
|
3076
|
+
defaultMessage: "Ready to publish changes"
|
3077
|
+
}) })
|
3078
|
+
] });
|
3079
|
+
}
|
2960
3080
|
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
2961
3081
|
/* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
2962
3082
|
/* @__PURE__ */ jsx(Typography, { children: formatMessage({
|
@@ -3008,10 +3128,10 @@ const SelectedEntriesTableContent = ({
|
|
3008
3128
|
EntryValidationText,
|
3009
3129
|
{
|
3010
3130
|
validationErrors: validationErrors[row.documentId],
|
3011
|
-
|
3131
|
+
status: row.status
|
3012
3132
|
}
|
3013
3133
|
) }),
|
3014
|
-
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(
|
3134
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
|
3015
3135
|
IconButton,
|
3016
3136
|
{
|
3017
3137
|
tag: Link,
|
@@ -3034,9 +3154,10 @@ const SelectedEntriesTableContent = ({
|
|
3034
3154
|
),
|
3035
3155
|
target: "_blank",
|
3036
3156
|
marginLeft: "auto",
|
3037
|
-
|
3157
|
+
variant: "ghost",
|
3158
|
+
children: /* @__PURE__ */ jsx(Pencil, { width: "1.6rem", height: "1.6rem" })
|
3038
3159
|
}
|
3039
|
-
) })
|
3160
|
+
) }) })
|
3040
3161
|
] }, row.id)) })
|
3041
3162
|
] });
|
3042
3163
|
};
|
@@ -3073,7 +3194,13 @@ const SelectedEntriesModalContent = ({
|
|
3073
3194
|
);
|
3074
3195
|
const { rows, validationErrors } = React.useMemo(() => {
|
3075
3196
|
if (data.length > 0 && schema) {
|
3076
|
-
const validate = createYupSchema(
|
3197
|
+
const validate = createYupSchema(
|
3198
|
+
schema.attributes,
|
3199
|
+
components,
|
3200
|
+
// Since this is the "Publish" action, the validation
|
3201
|
+
// schema must enforce the rules for published entities
|
3202
|
+
{ status: "published" }
|
3203
|
+
);
|
3077
3204
|
const validationErrors2 = {};
|
3078
3205
|
const rows2 = data.map((entry) => {
|
3079
3206
|
try {
|
@@ -3149,7 +3276,7 @@ const SelectedEntriesModalContent = ({
|
|
3149
3276
|
);
|
3150
3277
|
};
|
3151
3278
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
3152
|
-
/* @__PURE__ */ jsxs(
|
3279
|
+
/* @__PURE__ */ jsxs(Modal.Body, { children: [
|
3153
3280
|
/* @__PURE__ */ jsx(Typography, { children: getFormattedCountMessage() }),
|
3154
3281
|
/* @__PURE__ */ jsx(Box, { marginTop: 5, children: /* @__PURE__ */ jsx(
|
3155
3282
|
SelectedEntriesTableContent,
|
@@ -3161,27 +3288,24 @@ const SelectedEntriesModalContent = ({
|
|
3161
3288
|
}
|
3162
3289
|
) })
|
3163
3290
|
] }),
|
3164
|
-
/* @__PURE__ */
|
3165
|
-
|
3166
|
-
|
3167
|
-
|
3168
|
-
|
3169
|
-
|
3170
|
-
}) }),
|
3171
|
-
|
3172
|
-
|
3173
|
-
|
3174
|
-
|
3175
|
-
|
3176
|
-
|
3177
|
-
|
3178
|
-
|
3179
|
-
|
3180
|
-
|
3181
|
-
|
3182
|
-
] })
|
3183
|
-
}
|
3184
|
-
),
|
3291
|
+
/* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
3292
|
+
/* @__PURE__ */ jsx(Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
|
3293
|
+
id: "app.components.Button.cancel",
|
3294
|
+
defaultMessage: "Cancel"
|
3295
|
+
}) }),
|
3296
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
3297
|
+
/* @__PURE__ */ jsx(Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
|
3298
|
+
/* @__PURE__ */ jsx(
|
3299
|
+
Button,
|
3300
|
+
{
|
3301
|
+
onClick: toggleDialog,
|
3302
|
+
disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
|
3303
|
+
loading: isSubmittingForm,
|
3304
|
+
children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
|
3305
|
+
}
|
3306
|
+
)
|
3307
|
+
] })
|
3308
|
+
] }),
|
3185
3309
|
/* @__PURE__ */ jsx(
|
3186
3310
|
ConfirmDialogPublishAll,
|
3187
3311
|
{
|
@@ -3246,143 +3370,10 @@ const BulkActionsRenderer = () => {
|
|
3246
3370
|
documents: selectedRows
|
3247
3371
|
},
|
3248
3372
|
descriptions: plugins["content-manager"].apis.getBulkActions(),
|
3249
|
-
children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsx(
|
3373
|
+
children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsx(DocumentActionButton, { ...action }, action.id))
|
3250
3374
|
}
|
3251
3375
|
) });
|
3252
3376
|
};
|
3253
|
-
const BulkActionAction = (action) => {
|
3254
|
-
const [dialogId, setDialogId] = React.useState(null);
|
3255
|
-
const { toggleNotification } = useNotification();
|
3256
|
-
const handleClick = (action2) => (e) => {
|
3257
|
-
const { onClick, dialog, id } = action2;
|
3258
|
-
if (onClick) {
|
3259
|
-
onClick(e);
|
3260
|
-
}
|
3261
|
-
if (dialog) {
|
3262
|
-
switch (dialog.type) {
|
3263
|
-
case "notification":
|
3264
|
-
toggleNotification({
|
3265
|
-
title: dialog.title,
|
3266
|
-
message: dialog.content,
|
3267
|
-
type: dialog.status,
|
3268
|
-
timeout: dialog.timeout,
|
3269
|
-
onClose: dialog.onClose
|
3270
|
-
});
|
3271
|
-
break;
|
3272
|
-
case "dialog":
|
3273
|
-
case "modal": {
|
3274
|
-
e.preventDefault();
|
3275
|
-
setDialogId(id);
|
3276
|
-
}
|
3277
|
-
}
|
3278
|
-
}
|
3279
|
-
};
|
3280
|
-
const handleClose = () => {
|
3281
|
-
setDialogId(null);
|
3282
|
-
if (action.dialog?.type === "modal" && action.dialog?.onClose) {
|
3283
|
-
action.dialog.onClose();
|
3284
|
-
}
|
3285
|
-
};
|
3286
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
3287
|
-
/* @__PURE__ */ jsx(
|
3288
|
-
Button,
|
3289
|
-
{
|
3290
|
-
disabled: action.disabled,
|
3291
|
-
startIcon: action.icon,
|
3292
|
-
variant: action.variant,
|
3293
|
-
onClick: handleClick(action),
|
3294
|
-
children: action.label
|
3295
|
-
}
|
3296
|
-
),
|
3297
|
-
action.dialog?.type === "dialog" ? /* @__PURE__ */ jsx(
|
3298
|
-
BulkActionConfirmDialog,
|
3299
|
-
{
|
3300
|
-
...action.dialog,
|
3301
|
-
variant: action.variant,
|
3302
|
-
isOpen: dialogId === action.id,
|
3303
|
-
onClose: handleClose
|
3304
|
-
}
|
3305
|
-
) : null,
|
3306
|
-
action.dialog?.type === "modal" ? /* @__PURE__ */ jsx(
|
3307
|
-
BulkActionModal,
|
3308
|
-
{
|
3309
|
-
...action.dialog,
|
3310
|
-
onModalClose: handleClose,
|
3311
|
-
isOpen: dialogId === action.id
|
3312
|
-
}
|
3313
|
-
) : null
|
3314
|
-
] });
|
3315
|
-
};
|
3316
|
-
const BulkActionConfirmDialog = ({
|
3317
|
-
onClose,
|
3318
|
-
onCancel,
|
3319
|
-
onConfirm,
|
3320
|
-
title,
|
3321
|
-
content,
|
3322
|
-
confirmButton,
|
3323
|
-
isOpen,
|
3324
|
-
variant = "secondary"
|
3325
|
-
}) => {
|
3326
|
-
const { formatMessage } = useIntl();
|
3327
|
-
const handleClose = async () => {
|
3328
|
-
if (onCancel) {
|
3329
|
-
await onCancel();
|
3330
|
-
}
|
3331
|
-
onClose();
|
3332
|
-
};
|
3333
|
-
const handleConfirm = async () => {
|
3334
|
-
if (onConfirm) {
|
3335
|
-
await onConfirm();
|
3336
|
-
}
|
3337
|
-
onClose();
|
3338
|
-
};
|
3339
|
-
return /* @__PURE__ */ jsxs(Dialog, { isOpen, title, onClose: handleClose, children: [
|
3340
|
-
/* @__PURE__ */ jsx(DialogBody, { icon: /* @__PURE__ */ jsx(WarningCircle, {}), children: content }),
|
3341
|
-
/* @__PURE__ */ jsx(
|
3342
|
-
DialogFooter,
|
3343
|
-
{
|
3344
|
-
startAction: /* @__PURE__ */ jsx(Button, { onClick: handleClose, variant: "tertiary", children: formatMessage({
|
3345
|
-
id: "app.components.Button.cancel",
|
3346
|
-
defaultMessage: "Cancel"
|
3347
|
-
}) }),
|
3348
|
-
endAction: /* @__PURE__ */ jsx(
|
3349
|
-
Button,
|
3350
|
-
{
|
3351
|
-
onClick: handleConfirm,
|
3352
|
-
variant: variant === "danger-light" ? variant : "secondary",
|
3353
|
-
startIcon: variant === "danger-light" ? /* @__PURE__ */ jsx(Trash, {}) : /* @__PURE__ */ jsx(Check, {}),
|
3354
|
-
children: confirmButton ? confirmButton : formatMessage({
|
3355
|
-
id: "app.components.Button.confirm",
|
3356
|
-
defaultMessage: "Confirm"
|
3357
|
-
})
|
3358
|
-
}
|
3359
|
-
)
|
3360
|
-
}
|
3361
|
-
)
|
3362
|
-
] });
|
3363
|
-
};
|
3364
|
-
const BulkActionModal = ({
|
3365
|
-
isOpen,
|
3366
|
-
title,
|
3367
|
-
onClose,
|
3368
|
-
content: Content,
|
3369
|
-
onModalClose
|
3370
|
-
}) => {
|
3371
|
-
const id = React.useId();
|
3372
|
-
if (!isOpen) {
|
3373
|
-
return null;
|
3374
|
-
}
|
3375
|
-
const handleClose = () => {
|
3376
|
-
if (onClose) {
|
3377
|
-
onClose();
|
3378
|
-
}
|
3379
|
-
onModalClose();
|
3380
|
-
};
|
3381
|
-
return /* @__PURE__ */ jsxs(ModalLayout, { borderRadius: "4px", overflow: "hidden", onClose: handleClose, labelledBy: id, children: [
|
3382
|
-
/* @__PURE__ */ jsx(ModalHeader, { children: /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", textColor: "neutral800", tag: "h2", id, children: title }) }),
|
3383
|
-
/* @__PURE__ */ jsx(Content, { onClose: handleClose })
|
3384
|
-
] });
|
3385
|
-
};
|
3386
3377
|
const DeleteAction = ({ documents, model }) => {
|
3387
3378
|
const { formatMessage } = useIntl();
|
3388
3379
|
const { schema: contentType } = useDoc();
|
@@ -3415,6 +3406,7 @@ const DeleteAction = ({ documents, model }) => {
|
|
3415
3406
|
defaultMessage: "Confirmation"
|
3416
3407
|
}),
|
3417
3408
|
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3409
|
+
/* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3418
3410
|
/* @__PURE__ */ jsx(Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
|
3419
3411
|
id: "popUpWarning.bodyMessage.contentType.delete.all",
|
3420
3412
|
defaultMessage: "Are you sure you want to delete these entries?"
|
@@ -3451,7 +3443,7 @@ const UnpublishAction = ({ documents, model }) => {
|
|
3451
3443
|
selectRow([]);
|
3452
3444
|
}
|
3453
3445
|
};
|
3454
|
-
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published");
|
3446
|
+
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
|
3455
3447
|
if (!showUnpublishButton)
|
3456
3448
|
return null;
|
3457
3449
|
return {
|
@@ -3464,6 +3456,7 @@ const UnpublishAction = ({ documents, model }) => {
|
|
3464
3456
|
defaultMessage: "Confirmation"
|
3465
3457
|
}),
|
3466
3458
|
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3459
|
+
/* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3467
3460
|
/* @__PURE__ */ jsx(Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
|
3468
3461
|
id: "popUpWarning.bodyMessage.contentType.unpublish.all",
|
3469
3462
|
defaultMessage: "Are you sure you want to unpublish these entries?"
|
@@ -3557,7 +3550,7 @@ const TableActions = ({ document }) => {
|
|
3557
3550
|
DescriptionComponentRenderer,
|
3558
3551
|
{
|
3559
3552
|
props,
|
3560
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3553
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
3561
3554
|
children: (actions2) => {
|
3562
3555
|
const tableRowActions = actions2.filter((action) => {
|
3563
3556
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3668,7 +3661,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3668
3661
|
}),
|
3669
3662
|
content: /* @__PURE__ */ jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
3670
3663
|
footer: ({ onClose }) => {
|
3671
|
-
return /* @__PURE__ */ jsxs(
|
3664
|
+
return /* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
3672
3665
|
/* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
3673
3666
|
id: "cancel",
|
3674
3667
|
defaultMessage: "Cancel"
|
@@ -3709,8 +3702,7 @@ class ContentManagerPlugin {
|
|
3709
3702
|
documentActions = [
|
3710
3703
|
...DEFAULT_ACTIONS,
|
3711
3704
|
...DEFAULT_TABLE_ROW_ACTIONS,
|
3712
|
-
...DEFAULT_HEADER_ACTIONS
|
3713
|
-
HistoryAction
|
3705
|
+
...DEFAULT_HEADER_ACTIONS
|
3714
3706
|
];
|
3715
3707
|
editViewSidePanels = [ActionsPanel];
|
3716
3708
|
headerActions = [];
|
@@ -3799,6 +3791,52 @@ const getPrintableType = (value) => {
|
|
3799
3791
|
}
|
3800
3792
|
return nativeType;
|
3801
3793
|
};
|
3794
|
+
const HistoryAction = ({ model, document }) => {
|
3795
|
+
const { formatMessage } = useIntl();
|
3796
|
+
const [{ query }] = useQueryParams();
|
3797
|
+
const navigate = useNavigate();
|
3798
|
+
const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
|
3799
|
+
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3800
|
+
return null;
|
3801
|
+
}
|
3802
|
+
return {
|
3803
|
+
icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
|
3804
|
+
label: formatMessage({
|
3805
|
+
id: "content-manager.history.document-action",
|
3806
|
+
defaultMessage: "Content History"
|
3807
|
+
}),
|
3808
|
+
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
3809
|
+
disabled: (
|
3810
|
+
/**
|
3811
|
+
* The user is creating a new document.
|
3812
|
+
* It hasn't been saved yet, so there's no history to go to
|
3813
|
+
*/
|
3814
|
+
!document || /**
|
3815
|
+
* The document has been created but the current dimension has never been saved.
|
3816
|
+
* For example, the user is creating a new locale in an existing document,
|
3817
|
+
* so there's no history for the document in that locale
|
3818
|
+
*/
|
3819
|
+
!document.id || /**
|
3820
|
+
* History is only available for content types created by the user.
|
3821
|
+
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
3822
|
+
* which start with `admin::` or `plugin::`
|
3823
|
+
*/
|
3824
|
+
!model.startsWith("api::")
|
3825
|
+
),
|
3826
|
+
position: "header"
|
3827
|
+
};
|
3828
|
+
};
|
3829
|
+
HistoryAction.type = "history";
|
3830
|
+
const historyAdmin = {
|
3831
|
+
bootstrap(app) {
|
3832
|
+
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
3833
|
+
addDocumentAction((actions2) => {
|
3834
|
+
const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
|
3835
|
+
actions2.splice(indexOfDeleteAction, 0, HistoryAction);
|
3836
|
+
return actions2;
|
3837
|
+
});
|
3838
|
+
}
|
3839
|
+
};
|
3802
3840
|
const initialState = {
|
3803
3841
|
collectionTypeLinks: [],
|
3804
3842
|
components: [],
|
@@ -3849,15 +3887,29 @@ const index = {
|
|
3849
3887
|
defaultMessage: "Content Manager"
|
3850
3888
|
},
|
3851
3889
|
permissions: [],
|
3852
|
-
Component: () => import("./layout-CPn1PM6x.mjs").then((mod) => ({ default: mod.Layout })),
|
3853
3890
|
position: 1
|
3854
3891
|
});
|
3892
|
+
app.router.addRoute({
|
3893
|
+
path: "content-manager/*",
|
3894
|
+
lazy: async () => {
|
3895
|
+
const { Layout } = await import("./layout-0TY7UtKO.mjs");
|
3896
|
+
return {
|
3897
|
+
Component: Layout
|
3898
|
+
};
|
3899
|
+
},
|
3900
|
+
children: routes
|
3901
|
+
});
|
3855
3902
|
app.registerPlugin(cm.config);
|
3856
3903
|
},
|
3904
|
+
bootstrap(app) {
|
3905
|
+
if (typeof historyAdmin.bootstrap === "function") {
|
3906
|
+
historyAdmin.bootstrap(app);
|
3907
|
+
}
|
3908
|
+
},
|
3857
3909
|
async registerTrads({ locales }) {
|
3858
3910
|
const importedTrads = await Promise.all(
|
3859
3911
|
locales.map((locale) => {
|
3860
|
-
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-
|
3912
|
+
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-DCszE74t.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 }) => {
|
3861
3913
|
return {
|
3862
3914
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3863
3915
|
locale
|
@@ -3890,31 +3942,31 @@ export {
|
|
3890
3942
|
RelativeTime as R,
|
3891
3943
|
SINGLE_TYPES as S,
|
3892
3944
|
TableActions as T,
|
3893
|
-
|
3894
|
-
|
3895
|
-
|
3896
|
-
|
3897
|
-
|
3898
|
-
|
3945
|
+
useGetInitialDataQuery as a,
|
3946
|
+
useGetAllContentTypeSettingsQuery as b,
|
3947
|
+
useDoc as c,
|
3948
|
+
buildValidParams as d,
|
3949
|
+
contentManagerApi as e,
|
3950
|
+
useDocumentRBAC as f,
|
3899
3951
|
getTranslation as g,
|
3900
|
-
|
3901
|
-
|
3902
|
-
|
3903
|
-
|
3904
|
-
|
3905
|
-
|
3906
|
-
|
3907
|
-
|
3908
|
-
|
3909
|
-
|
3910
|
-
|
3952
|
+
useDocumentLayout as h,
|
3953
|
+
createYupSchema as i,
|
3954
|
+
Header as j,
|
3955
|
+
PERMISSIONS as k,
|
3956
|
+
DocumentRBAC as l,
|
3957
|
+
DOCUMENT_META_FIELDS as m,
|
3958
|
+
CLONE_PATH as n,
|
3959
|
+
useDocLayout as o,
|
3960
|
+
useGetContentTypeConfigurationQuery as p,
|
3961
|
+
CREATOR_FIELDS as q,
|
3962
|
+
getMainField as r,
|
3911
3963
|
setInitialData as s,
|
3912
3964
|
getDisplayName as t,
|
3913
|
-
|
3965
|
+
useContentTypeSchema as u,
|
3914
3966
|
checkIfAttributeIsDisplayable as v,
|
3915
3967
|
useGetAllDocumentsQuery as w,
|
3916
3968
|
convertListLayoutToFieldLayouts as x,
|
3917
3969
|
capitalise as y,
|
3918
3970
|
useUpdateContentTypeConfigurationMutation as z
|
3919
3971
|
};
|
3920
|
-
//# sourceMappingURL=index-
|
3972
|
+
//# sourceMappingURL=index-BYSWwHBJ.mjs.map
|