@strapi/content-manager 0.0.0-experimental.7afdc9b682bc83a53ce599c4fb7c9e4506b31fff → 0.0.0-experimental.81dfdf02b1367004c7deed9e01afa9d3a15d0fa5
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-DJcn1DrO.js → ComponentConfigurationPage-D_M8iBw5.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-DJcn1DrO.js.map → ComponentConfigurationPage-D_M8iBw5.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-CR5XdR33.mjs → ComponentConfigurationPage-qemkOlnj.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-CR5XdR33.mjs.map → ComponentConfigurationPage-qemkOlnj.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-tDtWj7R2.js → EditConfigurationPage-BePwPuHy.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-tDtWj7R2.js.map → EditConfigurationPage-BePwPuHy.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-DmCIb4kD.mjs → EditConfigurationPage-CjUrEewK.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-DmCIb4kD.mjs.map → EditConfigurationPage-CjUrEewK.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-CoQEnFlC.js → EditViewPage-B-RJeiJD.js} +57 -46
- package/dist/_chunks/EditViewPage-B-RJeiJD.js.map +1 -0
- package/dist/_chunks/{EditViewPage-DvaV7U9b.mjs → EditViewPage-De8GyU8P.mjs} +58 -47
- package/dist/_chunks/EditViewPage-De8GyU8P.mjs.map +1 -0
- package/dist/_chunks/{Field-ZdrmmQ4Y.js → Field-dq8Tg1M_.js} +514 -168
- package/dist/_chunks/Field-dq8Tg1M_.js.map +1 -0
- package/dist/_chunks/{Field-Cz_J9551.mjs → Field-pb2o8uBe.mjs} +516 -170
- package/dist/_chunks/Field-pb2o8uBe.mjs.map +1 -0
- package/dist/_chunks/{Form-Bpig5rch.js → Form-DGIf4jQU.js} +38 -28
- package/dist/_chunks/Form-DGIf4jQU.js.map +1 -0
- package/dist/_chunks/{Form-Dxmihyw8.mjs → Form-DJn0Dxha.mjs} +40 -30
- package/dist/_chunks/Form-DJn0Dxha.mjs.map +1 -0
- package/dist/_chunks/{History-BZP8n7KT.mjs → History-BowL3JKP.mjs} +141 -37
- package/dist/_chunks/History-BowL3JKP.mjs.map +1 -0
- package/dist/_chunks/{History-BfX6XmZK.js → History-Dh2NEHnR.js} +140 -36
- package/dist/_chunks/History-Dh2NEHnR.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DxKuVkKz.mjs → ListConfigurationPage-BpVOB-hn.mjs} +58 -48
- package/dist/_chunks/ListConfigurationPage-BpVOB-hn.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-B3CXj8PY.js → ListConfigurationPage-BxYCWz9e.js} +57 -46
- package/dist/_chunks/ListConfigurationPage-BxYCWz9e.js.map +1 -0
- package/dist/_chunks/{ListViewPage-Bk9VO__I.js → ListViewPage-4XsciqHZ.js} +65 -68
- package/dist/_chunks/ListViewPage-4XsciqHZ.js.map +1 -0
- package/dist/_chunks/{ListViewPage-D5D3tVPq.mjs → ListViewPage-CXFUjZQC.mjs} +67 -70
- package/dist/_chunks/ListViewPage-CXFUjZQC.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DsB2F7Z1.js → NoContentTypePage-C8OpoHeU.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-DsB2F7Z1.js.map → NoContentTypePage-C8OpoHeU.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-DnMeuQCj.mjs → NoContentTypePage-DuhOTp3x.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-DnMeuQCj.mjs.map → NoContentTypePage-DuhOTp3x.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-OyoME_Tf.mjs → NoPermissionsPage-DVz3mzDz.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-OyoME_Tf.mjs.map → NoPermissionsPage-DVz3mzDz.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-BQDM64_b.js → NoPermissionsPage-y_r7DVA2.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-BQDM64_b.js.map → NoPermissionsPage-y_r7DVA2.js.map} +1 -1
- package/dist/_chunks/{Relations-BOYZmuWy.mjs → Relations-CVNLrn1Y.mjs} +4 -4
- package/dist/_chunks/Relations-CVNLrn1Y.mjs.map +1 -0
- package/dist/_chunks/{Relations-B6B3A3mb.js → Relations-DPFCAa7b.js} +4 -4
- package/dist/_chunks/Relations-DPFCAa7b.js.map +1 -0
- package/dist/_chunks/{en-Dzv55oQw.mjs → en-BrCTWlZv.mjs} +8 -4
- package/dist/_chunks/{en-Dzv55oQw.mjs.map → en-BrCTWlZv.mjs.map} +1 -1
- package/dist/_chunks/{en-BN1bvFK7.js → en-uOUIxfcQ.js} +8 -4
- package/dist/_chunks/{en-BN1bvFK7.js.map → en-uOUIxfcQ.js.map} +1 -1
- package/dist/_chunks/{index-DzN3kBgx.js → index-C3fJE-1-.js} +491 -431
- package/dist/_chunks/index-C3fJE-1-.js.map +1 -0
- package/dist/_chunks/{index-VHviNMeW.mjs → index-DiMrfcfy.mjs} +511 -451
- package/dist/_chunks/index-DiMrfcfy.mjs.map +1 -0
- package/dist/_chunks/{layout-b91XRlD2.js → layout-C788OmNr.js} +37 -20
- package/dist/_chunks/layout-C788OmNr.js.map +1 -0
- package/dist/_chunks/{layout-CPn1PM6x.mjs → layout-ls3gxfpH.mjs} +39 -22
- package/dist/_chunks/layout-ls3gxfpH.mjs.map +1 -0
- package/dist/_chunks/{relations-BsqxS6tR.mjs → relations-CLcOmGO0.mjs} +2 -2
- package/dist/_chunks/{relations-BsqxS6tR.mjs.map → relations-CLcOmGO0.mjs.map} +1 -1
- package/dist/_chunks/{relations-CA7IYmcP.js → relations-DYeotliT.js} +2 -2
- package/dist/_chunks/{relations-CA7IYmcP.js.map → relations-DYeotliT.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 +12 -32
- 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 +16 -16
- package/dist/admin/src/services/init.d.ts +1 -1
- package/dist/admin/src/services/relations.d.ts +2 -2
- package/dist/admin/src/services/uid.d.ts +3 -3
- package/dist/admin/src/utils/validation.d.ts +4 -1
- package/dist/server/index.js +164 -103
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +165 -104
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/controllers/relations.d.ts.map +1 -1
- package/dist/server/src/controllers/uid.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/dimensions.d.ts +4 -2
- package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
- package/dist/server/src/history/services/utils.d.ts +1 -1
- package/dist/server/src/history/services/utils.d.ts.map +1 -1
- package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/permission-checker.d.ts.map +1 -1
- package/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/package.json +8 -8
- package/dist/_chunks/EditViewPage-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 { CrossCircle, More, WarningCircle, ListPlus, Pencil, Trash, Check, CheckCircle, ArrowsCounterClockwise, ChevronRight, Duplicate, ClockCounterClockwise, Feather } from "@strapi/icons";
|
2
2
|
import { jsx, Fragment, jsxs } from "react/jsx-runtime";
|
3
|
-
import { useStrapiApp,
|
4
|
-
import { stringify } from "qs";
|
5
|
-
import { useIntl } from "react-intl";
|
6
|
-
import { useNavigate, useParams, Navigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
|
3
|
+
import { useStrapiApp, createContext, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, getYupValidationErrors, useQueryParams, useTracking, useForm, BackButton, DescriptionComponentRenderer, useTable, Table } from "@strapi/admin/strapi-admin";
|
7
4
|
import * as React from "react";
|
8
5
|
import { lazy } from "react";
|
9
|
-
import { Menu, VisuallyHidden, Flex, Typography, Dialog,
|
6
|
+
import { Menu, Button, VisuallyHidden, Flex, Typography, Dialog, Modal, Radio, Status, Box, SingleSelect, SingleSelectOption, Loader, IconButton, Tooltip, LinkButton } from "@strapi/design-system";
|
7
|
+
import { useIntl } from "react-intl";
|
8
|
+
import { useParams, useNavigate, Navigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
|
10
9
|
import { styled } from "styled-components";
|
11
10
|
import * as yup from "yup";
|
12
11
|
import { ValidationError } from "yup";
|
13
12
|
import pipe from "lodash/fp/pipe";
|
14
13
|
import { intervalToDuration, isPast } from "date-fns";
|
14
|
+
import { stringify } from "qs";
|
15
15
|
import { createSlice, combineReducers } from "@reduxjs/toolkit";
|
16
16
|
const __variableDynamicImportRuntimeHelper = (glob, path) => {
|
17
17
|
const v = glob[path];
|
@@ -49,42 +49,6 @@ const useInjectionZone = (area) => {
|
|
49
49
|
const [page, position] = area.split(".");
|
50
50
|
return contentManagerPlugin.getInjectedComponents(page, position);
|
51
51
|
};
|
52
|
-
const HistoryAction = ({ model, document }) => {
|
53
|
-
const { formatMessage } = useIntl();
|
54
|
-
const [{ query }] = useQueryParams();
|
55
|
-
const navigate = useNavigate();
|
56
|
-
const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
|
57
|
-
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
58
|
-
return null;
|
59
|
-
}
|
60
|
-
return {
|
61
|
-
icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
|
62
|
-
label: formatMessage({
|
63
|
-
id: "content-manager.history.document-action",
|
64
|
-
defaultMessage: "Content History"
|
65
|
-
}),
|
66
|
-
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
67
|
-
disabled: (
|
68
|
-
/**
|
69
|
-
* The user is creating a new document.
|
70
|
-
* It hasn't been saved yet, so there's no history to go to
|
71
|
-
*/
|
72
|
-
!document || /**
|
73
|
-
* The document has been created but the current dimension has never been saved.
|
74
|
-
* For example, the user is creating a new locale in an existing document,
|
75
|
-
* so there's no history for the document in that locale
|
76
|
-
*/
|
77
|
-
!document.id || /**
|
78
|
-
* History is only available for content types created by the user.
|
79
|
-
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
80
|
-
* which start with `admin::` or `plugin::`
|
81
|
-
*/
|
82
|
-
!model.startsWith("api::")
|
83
|
-
),
|
84
|
-
position: "header"
|
85
|
-
};
|
86
|
-
};
|
87
|
-
HistoryAction.type = "history";
|
88
52
|
const ID = "id";
|
89
53
|
const CREATED_BY_ATTRIBUTE_NAME = "createdBy";
|
90
54
|
const UPDATED_BY_ATTRIBUTE_NAME = "updatedBy";
|
@@ -194,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-BowL3JKP.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-De8GyU8P.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1281
1320
|
);
|
1282
1321
|
const ProtectedListViewPage = lazy(
|
1283
|
-
() => import("./ListViewPage-
|
1322
|
+
() => import("./ListViewPage-CXFUjZQC.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1284
1323
|
);
|
1285
1324
|
const ProtectedListConfiguration = lazy(
|
1286
|
-
() => import("./ListConfigurationPage-
|
1325
|
+
() => import("./ListConfigurationPage-BpVOB-hn.mjs").then((mod) => ({
|
1287
1326
|
default: mod.ProtectedListConfiguration
|
1288
1327
|
}))
|
1289
1328
|
);
|
1290
1329
|
const ProtectedEditConfigurationPage = lazy(
|
1291
|
-
() => import("./EditConfigurationPage-
|
1330
|
+
() => import("./EditConfigurationPage-CjUrEewK.mjs").then((mod) => ({
|
1292
1331
|
default: mod.ProtectedEditConfigurationPage
|
1293
1332
|
}))
|
1294
1333
|
);
|
1295
1334
|
const ProtectedComponentConfigurationPage = lazy(
|
1296
|
-
() => import("./ComponentConfigurationPage-
|
1335
|
+
() => import("./ComponentConfigurationPage-qemkOlnj.mjs").then((mod) => ({
|
1297
1336
|
default: mod.ProtectedComponentConfigurationPage
|
1298
1337
|
}))
|
1299
1338
|
);
|
1300
1339
|
const NoPermissions = lazy(
|
1301
|
-
() => import("./NoPermissionsPage-
|
1340
|
+
() => import("./NoPermissionsPage-DVz3mzDz.mjs").then((mod) => ({ default: mod.NoPermissions }))
|
1302
1341
|
);
|
1303
1342
|
const NoContentType = lazy(
|
1304
|
-
() => import("./NoContentTypePage-
|
1343
|
+
() => import("./NoContentTypePage-DuhOTp3x.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
|
}
|
@@ -1480,14 +1521,14 @@ const DocumentActionsMenu = ({
|
|
1480
1521
|
};
|
1481
1522
|
return /* @__PURE__ */ jsxs(Menu.Root, { open: isOpen, onOpenChange: setIsOpen, children: [
|
1482
1523
|
/* @__PURE__ */ jsxs(
|
1483
|
-
|
1524
|
+
StyledMoreButton,
|
1484
1525
|
{
|
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,23 @@ 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
|
+
};
|
1640
|
+
const StyledMoreButton = styled(Menu.Trigger)`
|
1641
|
+
& > span {
|
1642
|
+
display: flex;
|
1643
|
+
}
|
1644
|
+
`;
|
1572
1645
|
const DocumentActionConfirmDialog = ({
|
1573
1646
|
onClose,
|
1574
1647
|
onCancel,
|
@@ -1591,22 +1664,20 @@ const DocumentActionConfirmDialog = ({
|
|
1591
1664
|
}
|
1592
1665
|
onClose();
|
1593
1666
|
};
|
1594
|
-
return /* @__PURE__ */
|
1595
|
-
/* @__PURE__ */ jsx(
|
1596
|
-
/* @__PURE__ */ jsx(
|
1597
|
-
|
1598
|
-
{
|
1599
|
-
|
1600
|
-
|
1601
|
-
|
1602
|
-
|
1603
|
-
|
1604
|
-
|
1605
|
-
|
1606
|
-
|
1607
|
-
|
1608
|
-
)
|
1609
|
-
] });
|
1667
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
1668
|
+
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
1669
|
+
/* @__PURE__ */ jsx(Dialog.Body, { children: content }),
|
1670
|
+
/* @__PURE__ */ jsxs(Dialog.Footer, { children: [
|
1671
|
+
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", children: formatMessage({
|
1672
|
+
id: "app.components.Button.cancel",
|
1673
|
+
defaultMessage: "Cancel"
|
1674
|
+
}) }) }),
|
1675
|
+
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, children: formatMessage({
|
1676
|
+
id: "app.components.Button.confirm",
|
1677
|
+
defaultMessage: "Confirm"
|
1678
|
+
}) })
|
1679
|
+
] })
|
1680
|
+
] }) });
|
1610
1681
|
};
|
1611
1682
|
const DocumentActionModal = ({
|
1612
1683
|
isOpen,
|
@@ -1616,34 +1687,17 @@ const DocumentActionModal = ({
|
|
1616
1687
|
content: Content,
|
1617
1688
|
onModalClose
|
1618
1689
|
}) => {
|
1619
|
-
const id = React.useId();
|
1620
|
-
if (!isOpen) {
|
1621
|
-
return null;
|
1622
|
-
}
|
1623
1690
|
const handleClose = () => {
|
1624
1691
|
if (onClose) {
|
1625
1692
|
onClose();
|
1626
1693
|
}
|
1627
1694
|
onModalClose();
|
1628
1695
|
};
|
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
|
-
] });
|
1696
|
+
return /* @__PURE__ */ jsx(Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
|
1697
|
+
/* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: title }) }),
|
1698
|
+
typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsx(Modal.Body, { children: Content }),
|
1699
|
+
typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
|
1700
|
+
] }) });
|
1647
1701
|
};
|
1648
1702
|
const PublishAction$1 = ({
|
1649
1703
|
activeTab,
|
@@ -1657,13 +1711,17 @@ const PublishAction$1 = ({
|
|
1657
1711
|
const navigate = useNavigate();
|
1658
1712
|
const { toggleNotification } = useNotification();
|
1659
1713
|
const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
|
1714
|
+
const isListView = useMatch(LIST_PATH) !== null;
|
1660
1715
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
1661
1716
|
const { formatMessage } = useIntl();
|
1662
|
-
const { canPublish
|
1663
|
-
"PublishAction",
|
1664
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1665
|
-
);
|
1717
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1666
1718
|
const { publish } = useDocumentActions();
|
1719
|
+
const [
|
1720
|
+
countDraftRelations,
|
1721
|
+
{ isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
|
1722
|
+
] = useLazyGetDraftRelationCountQuery();
|
1723
|
+
const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React.useState(0);
|
1724
|
+
const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React.useState(0);
|
1667
1725
|
const [{ query, rawQuery }] = useQueryParams();
|
1668
1726
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
1669
1727
|
const modified = useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
@@ -1672,10 +1730,101 @@ const PublishAction$1 = ({
|
|
1672
1730
|
const validate = useForm("PublishAction", (state) => state.validate);
|
1673
1731
|
const setErrors = useForm("PublishAction", (state) => state.setErrors);
|
1674
1732
|
const formValues = useForm("PublishAction", ({ values }) => values);
|
1733
|
+
React.useEffect(() => {
|
1734
|
+
if (isErrorDraftRelations) {
|
1735
|
+
toggleNotification({
|
1736
|
+
type: "danger",
|
1737
|
+
message: formatMessage({
|
1738
|
+
id: getTranslation("error.records.fetch-draft-relatons"),
|
1739
|
+
defaultMessage: "An error occurred while fetching draft relations on this document."
|
1740
|
+
})
|
1741
|
+
});
|
1742
|
+
}
|
1743
|
+
}, [isErrorDraftRelations, toggleNotification, formatMessage]);
|
1744
|
+
React.useEffect(() => {
|
1745
|
+
const localDraftRelations = /* @__PURE__ */ new Set();
|
1746
|
+
const extractDraftRelations = (data) => {
|
1747
|
+
const relations = data.connect || [];
|
1748
|
+
relations.forEach((relation) => {
|
1749
|
+
if (relation.status === "draft") {
|
1750
|
+
localDraftRelations.add(relation.id);
|
1751
|
+
}
|
1752
|
+
});
|
1753
|
+
};
|
1754
|
+
const traverseAndExtract = (data) => {
|
1755
|
+
Object.entries(data).forEach(([key, value]) => {
|
1756
|
+
if (key === "connect" && Array.isArray(value)) {
|
1757
|
+
extractDraftRelations({ connect: value });
|
1758
|
+
} else if (typeof value === "object" && value !== null) {
|
1759
|
+
traverseAndExtract(value);
|
1760
|
+
}
|
1761
|
+
});
|
1762
|
+
};
|
1763
|
+
if (!documentId || modified) {
|
1764
|
+
traverseAndExtract(formValues);
|
1765
|
+
setLocalCountOfDraftRelations(localDraftRelations.size);
|
1766
|
+
}
|
1767
|
+
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
1768
|
+
React.useEffect(() => {
|
1769
|
+
if (documentId && !isListView) {
|
1770
|
+
const fetchDraftRelationsCount = async () => {
|
1771
|
+
const { data, error } = await countDraftRelations({
|
1772
|
+
collectionType,
|
1773
|
+
model,
|
1774
|
+
documentId,
|
1775
|
+
params
|
1776
|
+
});
|
1777
|
+
if (error) {
|
1778
|
+
throw error;
|
1779
|
+
}
|
1780
|
+
if (data) {
|
1781
|
+
setServerCountOfDraftRelations(data.data);
|
1782
|
+
}
|
1783
|
+
};
|
1784
|
+
fetchDraftRelationsCount();
|
1785
|
+
}
|
1786
|
+
}, [isListView, documentId, countDraftRelations, collectionType, model, params]);
|
1675
1787
|
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
1676
1788
|
if (!schema?.options?.draftAndPublish) {
|
1677
1789
|
return null;
|
1678
1790
|
}
|
1791
|
+
const performPublish = async () => {
|
1792
|
+
setSubmitting(true);
|
1793
|
+
try {
|
1794
|
+
const { errors } = await validate();
|
1795
|
+
if (errors) {
|
1796
|
+
toggleNotification({
|
1797
|
+
type: "danger",
|
1798
|
+
message: formatMessage({
|
1799
|
+
id: "content-manager.validation.error",
|
1800
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
1801
|
+
})
|
1802
|
+
});
|
1803
|
+
return;
|
1804
|
+
}
|
1805
|
+
const res = await publish(
|
1806
|
+
{
|
1807
|
+
collectionType,
|
1808
|
+
model,
|
1809
|
+
documentId,
|
1810
|
+
params
|
1811
|
+
},
|
1812
|
+
formValues
|
1813
|
+
);
|
1814
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1815
|
+
navigate({
|
1816
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1817
|
+
search: rawQuery
|
1818
|
+
});
|
1819
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1820
|
+
setErrors(formatValidationErrors(res.error));
|
1821
|
+
}
|
1822
|
+
} finally {
|
1823
|
+
setSubmitting(false);
|
1824
|
+
}
|
1825
|
+
};
|
1826
|
+
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
1827
|
+
const hasDraftRelations = totalDraftRelations > 0;
|
1679
1828
|
return {
|
1680
1829
|
/**
|
1681
1830
|
* Disabled when:
|
@@ -1685,49 +1834,39 @@ const PublishAction$1 = ({
|
|
1685
1834
|
* - the document is already published & not modified
|
1686
1835
|
* - the document is being created & not modified
|
1687
1836
|
* - 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
1837
|
*/
|
1691
|
-
disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish
|
1838
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
1692
1839
|
label: formatMessage({
|
1693
1840
|
id: "app.utils.publish",
|
1694
1841
|
defaultMessage: "Publish"
|
1695
1842
|
}),
|
1696
1843
|
onClick: async () => {
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
|
1713
|
-
|
1714
|
-
|
1715
|
-
|
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));
|
1844
|
+
if (hasDraftRelations) {
|
1845
|
+
return;
|
1846
|
+
}
|
1847
|
+
await performPublish();
|
1848
|
+
},
|
1849
|
+
dialog: hasDraftRelations ? {
|
1850
|
+
type: "dialog",
|
1851
|
+
variant: "danger",
|
1852
|
+
footer: null,
|
1853
|
+
title: formatMessage({
|
1854
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
|
1855
|
+
defaultMessage: "Confirmation"
|
1856
|
+
}),
|
1857
|
+
content: formatMessage(
|
1858
|
+
{
|
1859
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
1860
|
+
defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
|
1861
|
+
},
|
1862
|
+
{
|
1863
|
+
count: totalDraftRelations
|
1726
1864
|
}
|
1727
|
-
|
1728
|
-
|
1865
|
+
),
|
1866
|
+
onConfirm: async () => {
|
1867
|
+
await performPublish();
|
1729
1868
|
}
|
1730
|
-
}
|
1869
|
+
} : void 0
|
1731
1870
|
};
|
1732
1871
|
};
|
1733
1872
|
PublishAction$1.type = "publish";
|
@@ -1743,10 +1882,6 @@ const UpdateAction = ({
|
|
1743
1882
|
const cloneMatch = useMatch(CLONE_PATH);
|
1744
1883
|
const isCloning = cloneMatch !== null;
|
1745
1884
|
const { formatMessage } = useIntl();
|
1746
|
-
const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1747
|
-
canCreate: canCreate2,
|
1748
|
-
canUpdate: canUpdate2
|
1749
|
-
}));
|
1750
1885
|
const { create, update, clone } = useDocumentActions();
|
1751
1886
|
const [{ query, rawQuery }] = useQueryParams();
|
1752
1887
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
@@ -1763,10 +1898,8 @@ const UpdateAction = ({
|
|
1763
1898
|
* - the form is submitting
|
1764
1899
|
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
1765
1900
|
* - 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
1901
|
*/
|
1769
|
-
disabled: isSubmitting || !modified && !isCloning || activeTab === "published"
|
1902
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1770
1903
|
label: formatMessage({
|
1771
1904
|
id: "content-manager.containers.Edit.save",
|
1772
1905
|
defaultMessage: "Save"
|
@@ -1774,16 +1907,18 @@ const UpdateAction = ({
|
|
1774
1907
|
onClick: async () => {
|
1775
1908
|
setSubmitting(true);
|
1776
1909
|
try {
|
1777
|
-
|
1778
|
-
|
1779
|
-
|
1780
|
-
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
-
|
1785
|
-
|
1786
|
-
|
1910
|
+
if (activeTab !== "draft") {
|
1911
|
+
const { errors } = await validate();
|
1912
|
+
if (errors) {
|
1913
|
+
toggleNotification({
|
1914
|
+
type: "danger",
|
1915
|
+
message: formatMessage({
|
1916
|
+
id: "content-manager.validation.error",
|
1917
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
1918
|
+
})
|
1919
|
+
});
|
1920
|
+
return;
|
1921
|
+
}
|
1787
1922
|
}
|
1788
1923
|
if (isCloning) {
|
1789
1924
|
const res = await clone(
|
@@ -1795,10 +1930,13 @@ const UpdateAction = ({
|
|
1795
1930
|
document
|
1796
1931
|
);
|
1797
1932
|
if ("data" in res) {
|
1798
|
-
navigate(
|
1799
|
-
|
1800
|
-
|
1801
|
-
|
1933
|
+
navigate(
|
1934
|
+
{
|
1935
|
+
pathname: `../${res.data.documentId}`,
|
1936
|
+
search: rawQuery
|
1937
|
+
},
|
1938
|
+
{ relative: "path" }
|
1939
|
+
);
|
1802
1940
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1803
1941
|
setErrors(formatValidationErrors(res.error));
|
1804
1942
|
}
|
@@ -1826,10 +1964,13 @@ const UpdateAction = ({
|
|
1826
1964
|
document
|
1827
1965
|
);
|
1828
1966
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1829
|
-
navigate(
|
1830
|
-
|
1831
|
-
|
1832
|
-
|
1967
|
+
navigate(
|
1968
|
+
{
|
1969
|
+
pathname: `../${res.data.documentId}`,
|
1970
|
+
search: rawQuery
|
1971
|
+
},
|
1972
|
+
{ replace: true, relative: "path" }
|
1973
|
+
);
|
1833
1974
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1834
1975
|
setErrors(formatValidationErrors(res.error));
|
1835
1976
|
}
|
@@ -1861,10 +2002,8 @@ const UnpublishAction$1 = ({
|
|
1861
2002
|
const { toggleNotification } = useNotification();
|
1862
2003
|
const [shouldKeepDraft, setShouldKeepDraft] = React.useState(true);
|
1863
2004
|
const isDocumentModified = document?.status === "modified";
|
1864
|
-
const handleChange = (
|
1865
|
-
|
1866
|
-
setShouldKeepDraft(e.target.value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1867
|
-
}
|
2005
|
+
const handleChange = (value) => {
|
2006
|
+
setShouldKeepDraft(value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1868
2007
|
};
|
1869
2008
|
if (!schema?.options?.draftAndPublish) {
|
1870
2009
|
return null;
|
@@ -1914,40 +2053,24 @@ const UnpublishAction$1 = ({
|
|
1914
2053
|
}) })
|
1915
2054
|
] }),
|
1916
2055
|
/* @__PURE__ */ jsxs(
|
1917
|
-
|
2056
|
+
Radio.Group,
|
1918
2057
|
{
|
1919
|
-
|
1920
|
-
|
1921
|
-
|
1922
|
-
|
1923
|
-
|
1924
|
-
|
2058
|
+
defaultValue: UNPUBLISH_DRAFT_OPTIONS.KEEP,
|
2059
|
+
name: "discard-options",
|
2060
|
+
"aria-label": formatMessage({
|
2061
|
+
id: "content-manager.actions.unpublish.dialog.radio-label",
|
2062
|
+
defaultMessage: "Choose an option to unpublish the document."
|
2063
|
+
}),
|
2064
|
+
onValueChange: handleChange,
|
1925
2065
|
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
|
-
)
|
2066
|
+
/* @__PURE__ */ jsx(Radio.Item, { checked: shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.KEEP, children: formatMessage({
|
2067
|
+
id: "content-manager.actions.unpublish.dialog.option.keep-draft",
|
2068
|
+
defaultMessage: "Keep draft"
|
2069
|
+
}) }),
|
2070
|
+
/* @__PURE__ */ jsx(Radio.Item, { checked: !shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.DISCARD, children: formatMessage({
|
2071
|
+
id: "content-manager.actions.unpublish.dialog.option.replace-draft",
|
2072
|
+
defaultMessage: "Replace draft"
|
2073
|
+
}) })
|
1951
2074
|
]
|
1952
2075
|
}
|
1953
2076
|
)
|
@@ -2093,23 +2216,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
|
2093
2216
|
id: "content-manager.containers.edit.title.new",
|
2094
2217
|
defaultMessage: "Create an entry"
|
2095
2218
|
}) : documentTitle;
|
2096
|
-
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop:
|
2219
|
+
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2097
2220
|
/* @__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
|
2221
|
+
/* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2222
|
+
/* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
|
2223
|
+
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
2224
|
+
] }),
|
2225
|
+
status ? /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
|
2113
2226
|
] });
|
2114
2227
|
};
|
2115
2228
|
const HeaderToolbar = () => {
|
@@ -2800,30 +2913,23 @@ const ConfirmBulkActionDialog = ({
|
|
2800
2913
|
endAction
|
2801
2914
|
}) => {
|
2802
2915
|
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
|
-
);
|
2916
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
2917
|
+
/* @__PURE__ */ jsx(Dialog.Header, { children: formatMessage({
|
2918
|
+
id: "app.components.ConfirmDialog.title",
|
2919
|
+
defaultMessage: "Confirmation"
|
2920
|
+
}) }),
|
2921
|
+
/* @__PURE__ */ jsx(Dialog.Body, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
2922
|
+
/* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
2923
|
+
dialogBody
|
2924
|
+
] }) }),
|
2925
|
+
/* @__PURE__ */ jsxs(Dialog.Footer, { children: [
|
2926
|
+
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { fullWidth: true, onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
|
2927
|
+
id: "app.components.Button.cancel",
|
2928
|
+
defaultMessage: "Cancel"
|
2929
|
+
}) }) }),
|
2930
|
+
endAction
|
2931
|
+
] })
|
2932
|
+
] }) });
|
2827
2933
|
};
|
2828
2934
|
const BoldChunk$1 = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
|
2829
2935
|
const ConfirmDialogPublishAll = ({
|
@@ -2928,16 +3034,30 @@ const formatErrorMessages = (errors, parentKey, formatMessage) => {
|
|
2928
3034
|
)
|
2929
3035
|
);
|
2930
3036
|
} else {
|
2931
|
-
messages.push(
|
3037
|
+
messages.push(
|
3038
|
+
...formatErrorMessages(
|
3039
|
+
// @ts-expect-error TODO: check why value is not compatible with FormErrors
|
3040
|
+
value,
|
3041
|
+
currentKey,
|
3042
|
+
formatMessage
|
3043
|
+
)
|
3044
|
+
);
|
2932
3045
|
}
|
3046
|
+
} else {
|
3047
|
+
messages.push(
|
3048
|
+
formatMessage(
|
3049
|
+
{
|
3050
|
+
id: `${value}.withField`,
|
3051
|
+
defaultMessage: value
|
3052
|
+
},
|
3053
|
+
{ field: currentKey }
|
3054
|
+
)
|
3055
|
+
);
|
2933
3056
|
}
|
2934
3057
|
});
|
2935
3058
|
return messages;
|
2936
3059
|
};
|
2937
|
-
const EntryValidationText = ({
|
2938
|
-
validationErrors,
|
2939
|
-
isPublished = false
|
2940
|
-
}) => {
|
3060
|
+
const EntryValidationText = ({ validationErrors, status }) => {
|
2941
3061
|
const { formatMessage } = useIntl();
|
2942
3062
|
if (validationErrors) {
|
2943
3063
|
const validationErrorsMessages = formatErrorMessages(validationErrors, "", formatMessage).join(
|
@@ -2948,7 +3068,7 @@ const EntryValidationText = ({
|
|
2948
3068
|
/* @__PURE__ */ jsx(Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsx(TypographyMaxWidth, { textColor: "danger600", variant: "omega", fontWeight: "semiBold", ellipsis: true, children: validationErrorsMessages }) })
|
2949
3069
|
] });
|
2950
3070
|
}
|
2951
|
-
if (
|
3071
|
+
if (status === "published") {
|
2952
3072
|
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
2953
3073
|
/* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
2954
3074
|
/* @__PURE__ */ jsx(Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
|
@@ -2957,6 +3077,15 @@ const EntryValidationText = ({
|
|
2957
3077
|
}) })
|
2958
3078
|
] });
|
2959
3079
|
}
|
3080
|
+
if (status === "modified") {
|
3081
|
+
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
3082
|
+
/* @__PURE__ */ jsx(ArrowsCounterClockwise, { fill: "alternative600" }),
|
3083
|
+
/* @__PURE__ */ jsx(Typography, { children: formatMessage({
|
3084
|
+
id: "content-manager.bulk-publish.modified",
|
3085
|
+
defaultMessage: "Ready to publish changes"
|
3086
|
+
}) })
|
3087
|
+
] });
|
3088
|
+
}
|
2960
3089
|
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
2961
3090
|
/* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
2962
3091
|
/* @__PURE__ */ jsx(Typography, { children: formatMessage({
|
@@ -3008,7 +3137,7 @@ const SelectedEntriesTableContent = ({
|
|
3008
3137
|
EntryValidationText,
|
3009
3138
|
{
|
3010
3139
|
validationErrors: validationErrors[row.documentId],
|
3011
|
-
|
3140
|
+
status: row.status
|
3012
3141
|
}
|
3013
3142
|
) }),
|
3014
3143
|
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(
|
@@ -3073,7 +3202,13 @@ const SelectedEntriesModalContent = ({
|
|
3073
3202
|
);
|
3074
3203
|
const { rows, validationErrors } = React.useMemo(() => {
|
3075
3204
|
if (data.length > 0 && schema) {
|
3076
|
-
const validate = createYupSchema(
|
3205
|
+
const validate = createYupSchema(
|
3206
|
+
schema.attributes,
|
3207
|
+
components,
|
3208
|
+
// Since this is the "Publish" action, the validation
|
3209
|
+
// schema must enforce the rules for published entities
|
3210
|
+
{ status: "published" }
|
3211
|
+
);
|
3077
3212
|
const validationErrors2 = {};
|
3078
3213
|
const rows2 = data.map((entry) => {
|
3079
3214
|
try {
|
@@ -3149,7 +3284,7 @@ const SelectedEntriesModalContent = ({
|
|
3149
3284
|
);
|
3150
3285
|
};
|
3151
3286
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
3152
|
-
/* @__PURE__ */ jsxs(
|
3287
|
+
/* @__PURE__ */ jsxs(Modal.Body, { children: [
|
3153
3288
|
/* @__PURE__ */ jsx(Typography, { children: getFormattedCountMessage() }),
|
3154
3289
|
/* @__PURE__ */ jsx(Box, { marginTop: 5, children: /* @__PURE__ */ jsx(
|
3155
3290
|
SelectedEntriesTableContent,
|
@@ -3161,27 +3296,24 @@ const SelectedEntriesModalContent = ({
|
|
3161
3296
|
}
|
3162
3297
|
) })
|
3163
3298
|
] }),
|
3164
|
-
/* @__PURE__ */
|
3165
|
-
|
3166
|
-
|
3167
|
-
|
3168
|
-
|
3169
|
-
|
3170
|
-
}) }),
|
3171
|
-
|
3172
|
-
|
3173
|
-
|
3174
|
-
|
3175
|
-
|
3176
|
-
|
3177
|
-
|
3178
|
-
|
3179
|
-
|
3180
|
-
|
3181
|
-
|
3182
|
-
] })
|
3183
|
-
}
|
3184
|
-
),
|
3299
|
+
/* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
3300
|
+
/* @__PURE__ */ jsx(Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
|
3301
|
+
id: "app.components.Button.cancel",
|
3302
|
+
defaultMessage: "Cancel"
|
3303
|
+
}) }),
|
3304
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
3305
|
+
/* @__PURE__ */ jsx(Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
|
3306
|
+
/* @__PURE__ */ jsx(
|
3307
|
+
Button,
|
3308
|
+
{
|
3309
|
+
onClick: toggleDialog,
|
3310
|
+
disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
|
3311
|
+
loading: isSubmittingForm,
|
3312
|
+
children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
|
3313
|
+
}
|
3314
|
+
)
|
3315
|
+
] })
|
3316
|
+
] }),
|
3185
3317
|
/* @__PURE__ */ jsx(
|
3186
3318
|
ConfirmDialogPublishAll,
|
3187
3319
|
{
|
@@ -3246,143 +3378,10 @@ const BulkActionsRenderer = () => {
|
|
3246
3378
|
documents: selectedRows
|
3247
3379
|
},
|
3248
3380
|
descriptions: plugins["content-manager"].apis.getBulkActions(),
|
3249
|
-
children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsx(
|
3381
|
+
children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsx(DocumentActionButton, { ...action }, action.id))
|
3250
3382
|
}
|
3251
3383
|
) });
|
3252
3384
|
};
|
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
3385
|
const DeleteAction = ({ documents, model }) => {
|
3387
3386
|
const { formatMessage } = useIntl();
|
3388
3387
|
const { schema: contentType } = useDoc();
|
@@ -3415,6 +3414,7 @@ const DeleteAction = ({ documents, model }) => {
|
|
3415
3414
|
defaultMessage: "Confirmation"
|
3416
3415
|
}),
|
3417
3416
|
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3417
|
+
/* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3418
3418
|
/* @__PURE__ */ jsx(Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
|
3419
3419
|
id: "popUpWarning.bodyMessage.contentType.delete.all",
|
3420
3420
|
defaultMessage: "Are you sure you want to delete these entries?"
|
@@ -3451,7 +3451,7 @@ const UnpublishAction = ({ documents, model }) => {
|
|
3451
3451
|
selectRow([]);
|
3452
3452
|
}
|
3453
3453
|
};
|
3454
|
-
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published");
|
3454
|
+
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
|
3455
3455
|
if (!showUnpublishButton)
|
3456
3456
|
return null;
|
3457
3457
|
return {
|
@@ -3464,6 +3464,7 @@ const UnpublishAction = ({ documents, model }) => {
|
|
3464
3464
|
defaultMessage: "Confirmation"
|
3465
3465
|
}),
|
3466
3466
|
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3467
|
+
/* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3467
3468
|
/* @__PURE__ */ jsx(Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
|
3468
3469
|
id: "popUpWarning.bodyMessage.contentType.unpublish.all",
|
3469
3470
|
defaultMessage: "Are you sure you want to unpublish these entries?"
|
@@ -3557,7 +3558,7 @@ const TableActions = ({ document }) => {
|
|
3557
3558
|
DescriptionComponentRenderer,
|
3558
3559
|
{
|
3559
3560
|
props,
|
3560
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3561
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
3561
3562
|
children: (actions2) => {
|
3562
3563
|
const tableRowActions = actions2.filter((action) => {
|
3563
3564
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3668,7 +3669,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3668
3669
|
}),
|
3669
3670
|
content: /* @__PURE__ */ jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
3670
3671
|
footer: ({ onClose }) => {
|
3671
|
-
return /* @__PURE__ */ jsxs(
|
3672
|
+
return /* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
3672
3673
|
/* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
3673
3674
|
id: "cancel",
|
3674
3675
|
defaultMessage: "Cancel"
|
@@ -3709,8 +3710,7 @@ class ContentManagerPlugin {
|
|
3709
3710
|
documentActions = [
|
3710
3711
|
...DEFAULT_ACTIONS,
|
3711
3712
|
...DEFAULT_TABLE_ROW_ACTIONS,
|
3712
|
-
...DEFAULT_HEADER_ACTIONS
|
3713
|
-
HistoryAction
|
3713
|
+
...DEFAULT_HEADER_ACTIONS
|
3714
3714
|
];
|
3715
3715
|
editViewSidePanels = [ActionsPanel];
|
3716
3716
|
headerActions = [];
|
@@ -3799,6 +3799,52 @@ const getPrintableType = (value) => {
|
|
3799
3799
|
}
|
3800
3800
|
return nativeType;
|
3801
3801
|
};
|
3802
|
+
const HistoryAction = ({ model, document }) => {
|
3803
|
+
const { formatMessage } = useIntl();
|
3804
|
+
const [{ query }] = useQueryParams();
|
3805
|
+
const navigate = useNavigate();
|
3806
|
+
const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
|
3807
|
+
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3808
|
+
return null;
|
3809
|
+
}
|
3810
|
+
return {
|
3811
|
+
icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
|
3812
|
+
label: formatMessage({
|
3813
|
+
id: "content-manager.history.document-action",
|
3814
|
+
defaultMessage: "Content History"
|
3815
|
+
}),
|
3816
|
+
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
3817
|
+
disabled: (
|
3818
|
+
/**
|
3819
|
+
* The user is creating a new document.
|
3820
|
+
* It hasn't been saved yet, so there's no history to go to
|
3821
|
+
*/
|
3822
|
+
!document || /**
|
3823
|
+
* The document has been created but the current dimension has never been saved.
|
3824
|
+
* For example, the user is creating a new locale in an existing document,
|
3825
|
+
* so there's no history for the document in that locale
|
3826
|
+
*/
|
3827
|
+
!document.id || /**
|
3828
|
+
* History is only available for content types created by the user.
|
3829
|
+
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
3830
|
+
* which start with `admin::` or `plugin::`
|
3831
|
+
*/
|
3832
|
+
!model.startsWith("api::")
|
3833
|
+
),
|
3834
|
+
position: "header"
|
3835
|
+
};
|
3836
|
+
};
|
3837
|
+
HistoryAction.type = "history";
|
3838
|
+
const historyAdmin = {
|
3839
|
+
bootstrap(app) {
|
3840
|
+
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
3841
|
+
addDocumentAction((actions2) => {
|
3842
|
+
const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
|
3843
|
+
actions2.splice(indexOfDeleteAction, 0, HistoryAction);
|
3844
|
+
return actions2;
|
3845
|
+
});
|
3846
|
+
}
|
3847
|
+
};
|
3802
3848
|
const initialState = {
|
3803
3849
|
collectionTypeLinks: [],
|
3804
3850
|
components: [],
|
@@ -3849,15 +3895,29 @@ const index = {
|
|
3849
3895
|
defaultMessage: "Content Manager"
|
3850
3896
|
},
|
3851
3897
|
permissions: [],
|
3852
|
-
Component: () => import("./layout-CPn1PM6x.mjs").then((mod) => ({ default: mod.Layout })),
|
3853
3898
|
position: 1
|
3854
3899
|
});
|
3900
|
+
app.router.addRoute({
|
3901
|
+
path: "content-manager/*",
|
3902
|
+
lazy: async () => {
|
3903
|
+
const { Layout } = await import("./layout-ls3gxfpH.mjs");
|
3904
|
+
return {
|
3905
|
+
Component: Layout
|
3906
|
+
};
|
3907
|
+
},
|
3908
|
+
children: routes
|
3909
|
+
});
|
3855
3910
|
app.registerPlugin(cm.config);
|
3856
3911
|
},
|
3912
|
+
bootstrap(app) {
|
3913
|
+
if (typeof historyAdmin.bootstrap === "function") {
|
3914
|
+
historyAdmin.bootstrap(app);
|
3915
|
+
}
|
3916
|
+
},
|
3857
3917
|
async registerTrads({ locales }) {
|
3858
3918
|
const importedTrads = await Promise.all(
|
3859
3919
|
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-
|
3920
|
+
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-BrCTWlZv.mjs"), "./translations/es.json": () => import("./es-CeXiYflN.mjs"), "./translations/eu.json": () => import("./eu-CdALomew.mjs"), "./translations/fr.json": () => import("./fr-CD9VFbPM.mjs"), "./translations/gu.json": () => import("./gu-CNpaMDpH.mjs"), "./translations/hi.json": () => import("./hi-Dwvd04m3.mjs"), "./translations/hu.json": () => import("./hu-CeYvaaO0.mjs"), "./translations/id.json": () => import("./id-BtwA9WJT.mjs"), "./translations/it.json": () => import("./it-BrVPqaf1.mjs"), "./translations/ja.json": () => import("./ja-CtsUxOvk.mjs"), "./translations/ko.json": () => import("./ko-HVQRlfUI.mjs"), "./translations/ml.json": () => import("./ml-BihZwQit.mjs"), "./translations/ms.json": () => import("./ms-m_WjyWx7.mjs"), "./translations/nl.json": () => import("./nl-D4R9gHx5.mjs"), "./translations/pl.json": () => import("./pl-sbx9mSt_.mjs"), "./translations/pt-BR.json": () => import("./pt-BR-C71iDxnh.mjs"), "./translations/pt.json": () => import("./pt-BsaFvS8-.mjs"), "./translations/ru.json": () => import("./ru-BE6A4Exp.mjs"), "./translations/sa.json": () => import("./sa-Dag0k-Z8.mjs"), "./translations/sk.json": () => import("./sk-BFg-R8qJ.mjs"), "./translations/sv.json": () => import("./sv-CUnfWGsh.mjs"), "./translations/th.json": () => import("./th-BqbI8lIT.mjs"), "./translations/tr.json": () => import("./tr-CgeK3wJM.mjs"), "./translations/uk.json": () => import("./uk-CR-zDhAY.mjs"), "./translations/vi.json": () => import("./vi-DUXIk_fw.mjs"), "./translations/zh-Hans.json": () => import("./zh-Hans-BPQcRIyH.mjs"), "./translations/zh.json": () => import("./zh-BWZspA60.mjs") }), `./translations/${locale}.json`).then(({ default: data }) => {
|
3861
3921
|
return {
|
3862
3922
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3863
3923
|
locale
|
@@ -3890,31 +3950,31 @@ export {
|
|
3890
3950
|
RelativeTime as R,
|
3891
3951
|
SINGLE_TYPES as S,
|
3892
3952
|
TableActions as T,
|
3893
|
-
|
3894
|
-
|
3895
|
-
|
3896
|
-
|
3897
|
-
|
3898
|
-
|
3953
|
+
useGetInitialDataQuery as a,
|
3954
|
+
useGetAllContentTypeSettingsQuery as b,
|
3955
|
+
useDoc as c,
|
3956
|
+
buildValidParams as d,
|
3957
|
+
contentManagerApi as e,
|
3958
|
+
useDocumentRBAC as f,
|
3899
3959
|
getTranslation as g,
|
3900
|
-
|
3901
|
-
|
3902
|
-
|
3903
|
-
|
3904
|
-
|
3905
|
-
|
3906
|
-
|
3907
|
-
|
3908
|
-
|
3909
|
-
|
3910
|
-
|
3960
|
+
useDocumentLayout as h,
|
3961
|
+
createYupSchema as i,
|
3962
|
+
Header as j,
|
3963
|
+
PERMISSIONS as k,
|
3964
|
+
DocumentRBAC as l,
|
3965
|
+
DOCUMENT_META_FIELDS as m,
|
3966
|
+
CLONE_PATH as n,
|
3967
|
+
useDocLayout as o,
|
3968
|
+
useGetContentTypeConfigurationQuery as p,
|
3969
|
+
CREATOR_FIELDS as q,
|
3970
|
+
getMainField as r,
|
3911
3971
|
setInitialData as s,
|
3912
3972
|
getDisplayName as t,
|
3913
|
-
|
3973
|
+
useContentTypeSchema as u,
|
3914
3974
|
checkIfAttributeIsDisplayable as v,
|
3915
3975
|
useGetAllDocumentsQuery as w,
|
3916
3976
|
convertListLayoutToFieldLayouts as x,
|
3917
3977
|
capitalise as y,
|
3918
3978
|
useUpdateContentTypeConfigurationMutation as z
|
3919
3979
|
};
|
3920
|
-
//# sourceMappingURL=index-
|
3980
|
+
//# sourceMappingURL=index-DiMrfcfy.mjs.map
|