@strapi/content-manager 0.0.0-experimental.fb442e5e12dd3f611303691bf85a249520ba348b → 0.0.0-experimental.fed75ee8e64c57dbed0b670b25ef026b69baab10
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/dist/_chunks/{ComponentConfigurationPage-B3yDbeU1.mjs → ComponentConfigurationPage-BVM7LScS.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-B3yDbeU1.mjs.map → ComponentConfigurationPage-BVM7LScS.mjs.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-KXSuLnQD.js → ComponentConfigurationPage-DNRPa10q.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-KXSuLnQD.js.map → ComponentConfigurationPage-DNRPa10q.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-D7PrLO8j.mjs → EditConfigurationPage-BWq-9Zhk.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-D7PrLO8j.mjs.map → EditConfigurationPage-BWq-9Zhk.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-BQ17--5R.js → EditConfigurationPage-BrG0mEfF.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-BQ17--5R.js.map → EditConfigurationPage-BrG0mEfF.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-BgjdnGz2.js → EditViewPage-BbY0bNNE.js} +15 -5
- package/dist/_chunks/EditViewPage-BbY0bNNE.js.map +1 -0
- package/dist/_chunks/{EditViewPage-B7VgwJaG.mjs → EditViewPage-Dx0QnTxn.mjs} +15 -5
- package/dist/_chunks/EditViewPage-Dx0QnTxn.mjs.map +1 -0
- package/dist/_chunks/{Field-CdK7ZLmv.js → Field-CglKum3X.js} +100 -87
- package/dist/_chunks/Field-CglKum3X.js.map +1 -0
- package/dist/_chunks/{Field-tHCw4lGA.mjs → Field-DVZSGAon.mjs} +97 -84
- package/dist/_chunks/Field-DVZSGAon.mjs.map +1 -0
- package/dist/_chunks/{Form-C_0KTVvV.js → Form-B7nYNIUm.js} +16 -8
- package/dist/_chunks/Form-B7nYNIUm.js.map +1 -0
- package/dist/_chunks/{Form-BJxdTv3Q.mjs → Form-BQwxPqu3.mjs} +16 -8
- package/dist/_chunks/Form-BQwxPqu3.mjs.map +1 -0
- package/dist/_chunks/{History-nuEzM5qm.js → History-3JN4BIS1.js} +23 -10
- package/dist/_chunks/History-3JN4BIS1.js.map +1 -0
- package/dist/_chunks/{History-DR2txJLE.mjs → History-Bmu6tx6s.mjs} +24 -11
- package/dist/_chunks/History-Bmu6tx6s.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-CnB86Psm.js → ListConfigurationPage-BcC28SV0.js} +2 -2
- package/dist/_chunks/{ListConfigurationPage-CnB86Psm.js.map → ListConfigurationPage-BcC28SV0.js.map} +1 -1
- package/dist/_chunks/{ListConfigurationPage-voFVtXu6.mjs → ListConfigurationPage-DwijcJ17.mjs} +2 -2
- package/dist/_chunks/{ListConfigurationPage-voFVtXu6.mjs.map → ListConfigurationPage-DwijcJ17.mjs.map} +1 -1
- package/dist/_chunks/{ListViewPage-B_GaWgRH.mjs → ListViewPage-DzhuS3CW.mjs} +40 -36
- package/dist/_chunks/ListViewPage-DzhuS3CW.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-SXIXm-RM.js → ListViewPage-ZPNQ6jWC.js} +43 -39
- package/dist/_chunks/ListViewPage-ZPNQ6jWC.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-CYiGpsbj.mjs → NoContentTypePage-BKMgOyd3.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-CYiGpsbj.mjs.map → NoContentTypePage-BKMgOyd3.mjs.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-BzsQ3hLZ.js → NoContentTypePage-DzwJNXvn.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-BzsQ3hLZ.js.map → NoContentTypePage-DzwJNXvn.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-B5baIHal.mjs → NoPermissionsPage-DBbGJqL9.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-B5baIHal.mjs.map → NoPermissionsPage-DBbGJqL9.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-IGkId4C5.js → NoPermissionsPage-GaweP-NG.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-IGkId4C5.js.map → NoPermissionsPage-GaweP-NG.js.map} +1 -1
- package/dist/_chunks/{Relations-CIYDdKU-.mjs → Relations-B7VtRA3g.mjs} +33 -23
- package/dist/_chunks/Relations-B7VtRA3g.mjs.map +1 -0
- package/dist/_chunks/{Relations-Dhuurpx2.js → Relations-BHXq_cKF.js} +33 -23
- package/dist/_chunks/Relations-BHXq_cKF.js.map +1 -0
- package/dist/_chunks/{en-uOUIxfcQ.js → en-Bm0D0IWz.js} +13 -12
- package/dist/_chunks/{en-uOUIxfcQ.js.map → en-Bm0D0IWz.js.map} +1 -1
- package/dist/_chunks/{en-BrCTWlZv.mjs → en-DKV44jRb.mjs} +13 -12
- package/dist/_chunks/{en-BrCTWlZv.mjs.map → en-DKV44jRb.mjs.map} +1 -1
- package/dist/_chunks/{index-CdT0kHZ8.js → index-DcA8_tJw.js} +2052 -1891
- package/dist/_chunks/index-DcA8_tJw.js.map +1 -0
- package/dist/_chunks/{index-C9TJPyni.mjs → index-TaRzG09p.mjs} +2072 -1911
- package/dist/_chunks/index-TaRzG09p.mjs.map +1 -0
- package/dist/_chunks/{layout-C6dxWYT7.js → layout-CrgXpOxT.js} +5 -4
- package/dist/_chunks/{layout-C6dxWYT7.js.map → layout-CrgXpOxT.js.map} +1 -1
- package/dist/_chunks/{layout-BNqvLR_b.mjs → layout-aX-RJhd5.mjs} +5 -4
- package/dist/_chunks/{layout-BNqvLR_b.mjs.map → layout-aX-RJhd5.mjs.map} +1 -1
- package/dist/_chunks/{relations-CkKqKw65.mjs → relations-D3Hlx6QX.mjs} +2 -2
- package/dist/_chunks/{relations-CkKqKw65.mjs.map → relations-D3Hlx6QX.mjs.map} +1 -1
- package/dist/_chunks/{relations-DtFaDnP1.js → relations-Z6RA1sBS.js} +2 -2
- package/dist/_chunks/{relations-DtFaDnP1.js.map → relations-Z6RA1sBS.js.map} +1 -1
- package/dist/_chunks/{usePrev-B9w_-eYc.js → useDebounce-CtcjDB3L.js} +14 -1
- package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs +29 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -0
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +5 -4
- package/dist/admin/src/exports.d.ts +1 -1
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +32 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +0 -32
- package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
- 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 +77 -39
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +77 -39
- 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/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 +1 -0
- 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/permission-checker.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 +12 -12
- package/dist/_chunks/EditViewPage-B7VgwJaG.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-BgjdnGz2.js.map +0 -1
- package/dist/_chunks/Field-CdK7ZLmv.js.map +0 -1
- package/dist/_chunks/Field-tHCw4lGA.mjs.map +0 -1
- package/dist/_chunks/Form-BJxdTv3Q.mjs.map +0 -1
- package/dist/_chunks/Form-C_0KTVvV.js.map +0 -1
- package/dist/_chunks/History-DR2txJLE.mjs.map +0 -1
- package/dist/_chunks/History-nuEzM5qm.js.map +0 -1
- package/dist/_chunks/ListViewPage-B_GaWgRH.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-SXIXm-RM.js.map +0 -1
- package/dist/_chunks/Relations-CIYDdKU-.mjs.map +0 -1
- package/dist/_chunks/Relations-Dhuurpx2.js.map +0 -1
- package/dist/_chunks/index-C9TJPyni.mjs.map +0 -1
- package/dist/_chunks/index-CdT0kHZ8.js.map +0 -1
- package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
- package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
- package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
- package/strapi-server.js +0 -3
@@ -1,16 +1,16 @@
|
|
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, createContext, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, getYupValidationErrors,
|
3
|
+
import { useStrapiApp, createContext, useQueryParams, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, getYupValidationErrors, useForm, useTracking, useGuidedTour, BackButton, DescriptionComponentRenderer, useTable, Table } from "@strapi/admin/strapi-admin";
|
4
4
|
import * as React from "react";
|
5
5
|
import { lazy } from "react";
|
6
|
-
import {
|
6
|
+
import { Button, Menu, VisuallyHidden, Flex, Typography, Dialog, Modal, Radio, Status, Box, SingleSelect, SingleSelectOption, IconButton, Loader, Tooltip, LinkButton } from "@strapi/design-system";
|
7
7
|
import { useIntl } from "react-intl";
|
8
|
-
import { useParams,
|
9
|
-
import { styled } from "styled-components";
|
8
|
+
import { useParams, useNavigate, Navigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
|
10
9
|
import * as yup from "yup";
|
11
10
|
import { ValidationError } from "yup";
|
12
11
|
import pipe from "lodash/fp/pipe";
|
13
12
|
import { intervalToDuration, isPast } from "date-fns";
|
13
|
+
import { styled } from "styled-components";
|
14
14
|
import { stringify } from "qs";
|
15
15
|
import { createSlice, combineReducers } from "@reduxjs/toolkit";
|
16
16
|
const __variableDynamicImportRuntimeHelper = (glob, path) => {
|
@@ -100,6 +100,7 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
100
100
|
if (!slug) {
|
101
101
|
throw new Error("Cannot find the slug param in the URL");
|
102
102
|
}
|
103
|
+
const [{ rawQuery }] = useQueryParams();
|
103
104
|
const userPermissions = useAuth("DocumentRBAC", (state) => state.permissions);
|
104
105
|
const contentTypePermissions = React.useMemo(() => {
|
105
106
|
const contentTypePermissions2 = userPermissions.filter(
|
@@ -110,7 +111,14 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
110
111
|
return { ...acc, [action]: [permission] };
|
111
112
|
}, {});
|
112
113
|
}, [slug, userPermissions]);
|
113
|
-
const { isLoading, allowedActions } = useRBAC(
|
114
|
+
const { isLoading, allowedActions } = useRBAC(
|
115
|
+
contentTypePermissions,
|
116
|
+
permissions ?? void 0,
|
117
|
+
// TODO: useRBAC context should be typed and built differently
|
118
|
+
// We are passing raw query as context to the hook so that it can
|
119
|
+
// rely on the locale provided from DocumentRBAC for its permission calculations.
|
120
|
+
rawQuery
|
121
|
+
);
|
114
122
|
const canCreateFields = !isLoading && allowedActions.canCreate ? extractAndDedupeFields(contentTypePermissions.create) : [];
|
115
123
|
const canReadFields = !isLoading && allowedActions.canRead ? extractAndDedupeFields(contentTypePermissions.read) : [];
|
116
124
|
const canUpdateFields = !isLoading && allowedActions.canUpdate ? extractAndDedupeFields(contentTypePermissions.update) : [];
|
@@ -158,7 +166,8 @@ const contentManagerApi = adminApi.enhanceEndpoints({
|
|
158
166
|
"Document",
|
159
167
|
"InitialData",
|
160
168
|
"HistoryVersion",
|
161
|
-
"Relations"
|
169
|
+
"Relations",
|
170
|
+
"UidAvailability"
|
162
171
|
]
|
163
172
|
});
|
164
173
|
const documentApi = contentManagerApi.injectEndpoints({
|
@@ -188,7 +197,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
188
197
|
params
|
189
198
|
}
|
190
199
|
}),
|
191
|
-
invalidatesTags: (_result, _error, { model }) => [
|
200
|
+
invalidatesTags: (_result, _error, { model }) => [
|
201
|
+
{ type: "Document", id: `${model}_LIST` },
|
202
|
+
{ type: "UidAvailability", id: model }
|
203
|
+
]
|
192
204
|
}),
|
193
205
|
/**
|
194
206
|
* Creates a new collection-type document. This should ONLY be used for collection-types.
|
@@ -205,7 +217,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
205
217
|
}),
|
206
218
|
invalidatesTags: (result, _error, { model }) => [
|
207
219
|
{ type: "Document", id: `${model}_LIST` },
|
208
|
-
"Relations"
|
220
|
+
"Relations",
|
221
|
+
{ type: "UidAvailability", id: model }
|
209
222
|
]
|
210
223
|
}),
|
211
224
|
deleteDocument: builder.mutation({
|
@@ -246,7 +259,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
246
259
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
247
260
|
},
|
248
261
|
{ type: "Document", id: `${model}_LIST` },
|
249
|
-
"Relations"
|
262
|
+
"Relations",
|
263
|
+
{ type: "UidAvailability", id: model }
|
250
264
|
];
|
251
265
|
}
|
252
266
|
}),
|
@@ -371,7 +385,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
371
385
|
type: "Document",
|
372
386
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
373
387
|
},
|
374
|
-
"Relations"
|
388
|
+
"Relations",
|
389
|
+
{ type: "UidAvailability", id: model }
|
375
390
|
];
|
376
391
|
},
|
377
392
|
async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
|
@@ -454,20 +469,39 @@ const buildValidParams = (query) => {
|
|
454
469
|
const isBaseQueryError = (error) => {
|
455
470
|
return error.name !== void 0;
|
456
471
|
};
|
457
|
-
const
|
472
|
+
const arrayValidator = (attribute, options) => ({
|
473
|
+
message: translatedErrors.required,
|
474
|
+
test(value) {
|
475
|
+
if (options.status === "draft") {
|
476
|
+
return true;
|
477
|
+
}
|
478
|
+
if (!attribute.required) {
|
479
|
+
return true;
|
480
|
+
}
|
481
|
+
if (!value) {
|
482
|
+
return false;
|
483
|
+
}
|
484
|
+
if (Array.isArray(value) && value.length === 0) {
|
485
|
+
return false;
|
486
|
+
}
|
487
|
+
return true;
|
488
|
+
}
|
489
|
+
});
|
490
|
+
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
458
491
|
const createModelSchema = (attributes2) => yup.object().shape(
|
459
492
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
460
493
|
if (DOCUMENT_META_FIELDS.includes(name)) {
|
461
494
|
return acc;
|
462
495
|
}
|
463
496
|
const validations = [
|
497
|
+
addNullableValidation,
|
464
498
|
addRequiredValidation,
|
465
499
|
addMinLengthValidation,
|
466
500
|
addMaxLengthValidation,
|
467
501
|
addMinValidation,
|
468
502
|
addMaxValidation,
|
469
503
|
addRegexValidation
|
470
|
-
].map((fn) => fn(attribute));
|
504
|
+
].map((fn) => fn(attribute, options));
|
471
505
|
const transformSchema = pipe(...validations);
|
472
506
|
switch (attribute.type) {
|
473
507
|
case "component": {
|
@@ -477,12 +511,12 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
477
511
|
...acc,
|
478
512
|
[name]: transformSchema(
|
479
513
|
yup.array().of(createModelSchema(attributes3).nullable(false))
|
480
|
-
)
|
514
|
+
).test(arrayValidator(attribute, options))
|
481
515
|
};
|
482
516
|
} else {
|
483
517
|
return {
|
484
518
|
...acc,
|
485
|
-
[name]: transformSchema(createModelSchema(attributes3))
|
519
|
+
[name]: transformSchema(createModelSchema(attributes3).nullable())
|
486
520
|
};
|
487
521
|
}
|
488
522
|
}
|
@@ -504,7 +538,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
504
538
|
}
|
505
539
|
)
|
506
540
|
)
|
507
|
-
)
|
541
|
+
).test(arrayValidator(attribute, options))
|
508
542
|
};
|
509
543
|
case "relation":
|
510
544
|
return {
|
@@ -516,7 +550,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
516
550
|
} else if (Array.isArray(value)) {
|
517
551
|
return yup.array().of(
|
518
552
|
yup.object().shape({
|
519
|
-
id: yup.
|
553
|
+
id: yup.number().required()
|
520
554
|
})
|
521
555
|
);
|
522
556
|
} else if (typeof value === "object") {
|
@@ -594,13 +628,7 @@ const createAttributeSchema = (attribute) => {
|
|
594
628
|
return yup.mixed();
|
595
629
|
}
|
596
630
|
};
|
597
|
-
const
|
598
|
-
if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
|
599
|
-
return schema.min(1, translatedErrors.required);
|
600
|
-
}
|
601
|
-
if (attribute.required && attribute.type !== "relation") {
|
602
|
-
return schema.required(translatedErrors.required);
|
603
|
-
}
|
631
|
+
const nullableSchema = (schema) => {
|
604
632
|
return schema?.nullable ? schema.nullable() : (
|
605
633
|
// In some cases '.nullable' will not be available on the schema.
|
606
634
|
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
@@ -608,7 +636,22 @@ const addRequiredValidation = (attribute) => (schema) => {
|
|
608
636
|
schema
|
609
637
|
);
|
610
638
|
};
|
611
|
-
const
|
639
|
+
const addNullableValidation = () => (schema) => {
|
640
|
+
return nullableSchema(schema);
|
641
|
+
};
|
642
|
+
const addRequiredValidation = (attribute, options) => (schema) => {
|
643
|
+
if (options.status === "draft" || !attribute.required) {
|
644
|
+
return schema;
|
645
|
+
}
|
646
|
+
if (attribute.required && "required" in schema) {
|
647
|
+
return schema.required(translatedErrors.required);
|
648
|
+
}
|
649
|
+
return schema;
|
650
|
+
};
|
651
|
+
const addMinLengthValidation = (attribute, options) => (schema) => {
|
652
|
+
if (options.status === "draft") {
|
653
|
+
return schema;
|
654
|
+
}
|
612
655
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
613
656
|
return schema.min(attribute.minLength, {
|
614
657
|
...translatedErrors.minLength,
|
@@ -630,32 +673,13 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
630
673
|
}
|
631
674
|
return schema;
|
632
675
|
};
|
633
|
-
const addMinValidation = (attribute) => (schema) => {
|
634
|
-
if ("
|
676
|
+
const addMinValidation = (attribute, options) => (schema) => {
|
677
|
+
if (options.status === "draft") {
|
678
|
+
return schema;
|
679
|
+
}
|
680
|
+
if ("min" in attribute && "min" in schema) {
|
635
681
|
const min = toInteger(attribute.min);
|
636
|
-
if (
|
637
|
-
if (!attribute.required && "test" in schema && min) {
|
638
|
-
return schema.test(
|
639
|
-
"custom-min",
|
640
|
-
{
|
641
|
-
...translatedErrors.min,
|
642
|
-
values: {
|
643
|
-
min: attribute.min
|
644
|
-
}
|
645
|
-
},
|
646
|
-
(value) => {
|
647
|
-
if (!value) {
|
648
|
-
return true;
|
649
|
-
}
|
650
|
-
if (Array.isArray(value) && value.length === 0) {
|
651
|
-
return true;
|
652
|
-
}
|
653
|
-
return value.length >= min;
|
654
|
-
}
|
655
|
-
);
|
656
|
-
}
|
657
|
-
}
|
658
|
-
if ("min" in schema && min) {
|
682
|
+
if (min) {
|
659
683
|
return schema.min(min, {
|
660
684
|
...translatedErrors.min,
|
661
685
|
values: {
|
@@ -773,19 +797,115 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
|
|
773
797
|
}, {});
|
774
798
|
return componentsByKey;
|
775
799
|
};
|
776
|
-
const
|
800
|
+
const HOOKS = {
|
801
|
+
/**
|
802
|
+
* Hook that allows to mutate the displayed headers of the list view table
|
803
|
+
* @constant
|
804
|
+
* @type {string}
|
805
|
+
*/
|
806
|
+
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
807
|
+
/**
|
808
|
+
* Hook that allows to mutate the CM's collection types links pre-set filters
|
809
|
+
* @constant
|
810
|
+
* @type {string}
|
811
|
+
*/
|
812
|
+
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
813
|
+
/**
|
814
|
+
* Hook that allows to mutate the CM's edit view layout
|
815
|
+
* @constant
|
816
|
+
* @type {string}
|
817
|
+
*/
|
818
|
+
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
819
|
+
/**
|
820
|
+
* Hook that allows to mutate the CM's single types links pre-set filters
|
821
|
+
* @constant
|
822
|
+
* @type {string}
|
823
|
+
*/
|
824
|
+
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
825
|
+
};
|
826
|
+
const contentTypesApi = contentManagerApi.injectEndpoints({
|
827
|
+
endpoints: (builder) => ({
|
828
|
+
getContentTypeConfiguration: builder.query({
|
829
|
+
query: (uid) => ({
|
830
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
831
|
+
method: "GET"
|
832
|
+
}),
|
833
|
+
transformResponse: (response) => response.data,
|
834
|
+
providesTags: (_result, _error, uid) => [
|
835
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
836
|
+
{ type: "ContentTypeSettings", id: "LIST" }
|
837
|
+
]
|
838
|
+
}),
|
839
|
+
getAllContentTypeSettings: builder.query({
|
840
|
+
query: () => "/content-manager/content-types-settings",
|
841
|
+
transformResponse: (response) => response.data,
|
842
|
+
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
843
|
+
}),
|
844
|
+
updateContentTypeConfiguration: builder.mutation({
|
845
|
+
query: ({ uid, ...body }) => ({
|
846
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
847
|
+
method: "PUT",
|
848
|
+
data: body
|
849
|
+
}),
|
850
|
+
transformResponse: (response) => response.data,
|
851
|
+
invalidatesTags: (_result, _error, { uid }) => [
|
852
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
853
|
+
{ type: "ContentTypeSettings", id: "LIST" },
|
854
|
+
// Is this necessary?
|
855
|
+
{ type: "InitialData" }
|
856
|
+
]
|
857
|
+
})
|
858
|
+
})
|
859
|
+
});
|
860
|
+
const {
|
861
|
+
useGetContentTypeConfigurationQuery,
|
862
|
+
useGetAllContentTypeSettingsQuery,
|
863
|
+
useUpdateContentTypeConfigurationMutation
|
864
|
+
} = contentTypesApi;
|
865
|
+
const checkIfAttributeIsDisplayable = (attribute) => {
|
866
|
+
const { type } = attribute;
|
867
|
+
if (type === "relation") {
|
868
|
+
return !attribute.relation.toLowerCase().includes("morph");
|
869
|
+
}
|
870
|
+
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
871
|
+
};
|
872
|
+
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
873
|
+
if (!mainFieldName) {
|
874
|
+
return void 0;
|
875
|
+
}
|
876
|
+
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
877
|
+
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
878
|
+
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
879
|
+
);
|
880
|
+
return {
|
881
|
+
name: mainFieldName,
|
882
|
+
type: mainFieldType ?? "string"
|
883
|
+
};
|
884
|
+
};
|
885
|
+
const DEFAULT_SETTINGS = {
|
886
|
+
bulkable: false,
|
887
|
+
filterable: false,
|
888
|
+
searchable: false,
|
889
|
+
pagination: false,
|
890
|
+
defaultSortBy: "",
|
891
|
+
defaultSortOrder: "asc",
|
892
|
+
mainField: "id",
|
893
|
+
pageSize: 10
|
894
|
+
};
|
895
|
+
const useDocumentLayout = (model) => {
|
896
|
+
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
897
|
+
const [{ query }] = useQueryParams();
|
898
|
+
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
777
899
|
const { toggleNotification } = useNotification();
|
778
900
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
901
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
779
902
|
const {
|
780
|
-
|
781
|
-
isLoading:
|
782
|
-
|
783
|
-
|
784
|
-
} =
|
785
|
-
|
786
|
-
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
787
|
-
});
|
788
|
-
const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
|
903
|
+
data,
|
904
|
+
isLoading: isLoadingConfigs,
|
905
|
+
error,
|
906
|
+
isFetching: isFetchingConfigs
|
907
|
+
} = useGetContentTypeConfigurationQuery(model);
|
908
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
789
909
|
React.useEffect(() => {
|
790
910
|
if (error) {
|
791
911
|
toggleNotification({
|
@@ -793,362 +913,440 @@ const useDocument = (args, opts) => {
|
|
793
913
|
message: formatAPIError(error)
|
794
914
|
});
|
795
915
|
}
|
796
|
-
}, [
|
797
|
-
const
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
(document) => {
|
805
|
-
if (!validationSchema) {
|
806
|
-
throw new Error(
|
807
|
-
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
808
|
-
);
|
809
|
-
}
|
810
|
-
try {
|
811
|
-
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
812
|
-
return null;
|
813
|
-
} catch (error2) {
|
814
|
-
if (error2 instanceof ValidationError) {
|
815
|
-
return getYupValidationErrors(error2);
|
816
|
-
}
|
817
|
-
throw error2;
|
818
|
-
}
|
916
|
+
}, [error, formatAPIError, toggleNotification]);
|
917
|
+
const editLayout = React.useMemo(
|
918
|
+
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
919
|
+
layout: [],
|
920
|
+
components: {},
|
921
|
+
metadatas: {},
|
922
|
+
options: {},
|
923
|
+
settings: DEFAULT_SETTINGS
|
819
924
|
},
|
820
|
-
[
|
925
|
+
[data, isLoading, schemas, schema, components]
|
926
|
+
);
|
927
|
+
const listLayout = React.useMemo(() => {
|
928
|
+
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
929
|
+
layout: [],
|
930
|
+
metadatas: {},
|
931
|
+
options: {},
|
932
|
+
settings: DEFAULT_SETTINGS
|
933
|
+
};
|
934
|
+
}, [data, isLoading, schemas, schema, components]);
|
935
|
+
const { layout: edit } = React.useMemo(
|
936
|
+
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
937
|
+
layout: editLayout,
|
938
|
+
query
|
939
|
+
}),
|
940
|
+
[editLayout, query, runHookWaterfall]
|
821
941
|
);
|
822
|
-
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
823
942
|
return {
|
824
|
-
|
825
|
-
document: data?.data,
|
826
|
-
meta: data?.meta,
|
943
|
+
error,
|
827
944
|
isLoading,
|
828
|
-
|
829
|
-
|
830
|
-
};
|
831
|
-
};
|
832
|
-
const useDoc = () => {
|
833
|
-
const { id, slug, collectionType, origin } = useParams();
|
834
|
-
const [{ query }] = useQueryParams();
|
835
|
-
const params = React.useMemo(() => buildValidParams(query), [query]);
|
836
|
-
if (!collectionType) {
|
837
|
-
throw new Error("Could not find collectionType in url params");
|
838
|
-
}
|
839
|
-
if (!slug) {
|
840
|
-
throw new Error("Could not find model in url params");
|
841
|
-
}
|
842
|
-
return {
|
843
|
-
collectionType,
|
844
|
-
model: slug,
|
845
|
-
id: origin || id === "create" ? void 0 : id,
|
846
|
-
...useDocument(
|
847
|
-
{ documentId: origin || id, model: slug, collectionType, params },
|
848
|
-
{
|
849
|
-
skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
|
850
|
-
}
|
851
|
-
)
|
945
|
+
edit,
|
946
|
+
list: listLayout
|
852
947
|
};
|
853
948
|
};
|
854
|
-
const
|
855
|
-
|
856
|
-
|
857
|
-
}
|
858
|
-
return Object.keys(trad).reduce((acc, current) => {
|
859
|
-
acc[`${pluginId}.${current}`] = trad[current];
|
860
|
-
return acc;
|
861
|
-
}, {});
|
862
|
-
};
|
863
|
-
const getTranslation = (id) => `content-manager.${id}`;
|
864
|
-
const DEFAULT_UNEXPECTED_ERROR_MSG = {
|
865
|
-
id: "notification.error",
|
866
|
-
defaultMessage: "An error occurred, please try again"
|
949
|
+
const useDocLayout = () => {
|
950
|
+
const { model } = useDoc();
|
951
|
+
return useDocumentLayout(model);
|
867
952
|
};
|
868
|
-
const
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
const
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
message: formatAPIError(res.error)
|
888
|
-
});
|
889
|
-
return { error: res.error };
|
890
|
-
}
|
891
|
-
toggleNotification({
|
892
|
-
type: "success",
|
893
|
-
message: formatMessage({
|
894
|
-
id: getTranslation("success.record.delete"),
|
895
|
-
defaultMessage: "Deleted document"
|
896
|
-
})
|
897
|
-
});
|
898
|
-
trackUsage("didDeleteEntry", trackerProperty);
|
899
|
-
return res.data;
|
900
|
-
} catch (err) {
|
901
|
-
toggleNotification({
|
902
|
-
type: "danger",
|
903
|
-
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
904
|
-
});
|
905
|
-
trackUsage("didNotDeleteEntry", { error: err, ...trackerProperty });
|
906
|
-
throw err;
|
953
|
+
const formatEditLayout = (data, {
|
954
|
+
schemas,
|
955
|
+
schema,
|
956
|
+
components
|
957
|
+
}) => {
|
958
|
+
let currentPanelIndex = 0;
|
959
|
+
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
960
|
+
data.contentType.layouts.edit,
|
961
|
+
schema?.attributes,
|
962
|
+
data.contentType.metadatas,
|
963
|
+
{ configurations: data.components, schemas: components },
|
964
|
+
schemas
|
965
|
+
).reduce((panels, row) => {
|
966
|
+
if (row.some((field) => field.type === "dynamiczone")) {
|
967
|
+
panels.push([row]);
|
968
|
+
currentPanelIndex += 2;
|
969
|
+
} else {
|
970
|
+
if (!panels[currentPanelIndex]) {
|
971
|
+
panels.push([]);
|
907
972
|
}
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
const
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
});
|
926
|
-
return { error: res.error };
|
973
|
+
panels[currentPanelIndex].push(row);
|
974
|
+
}
|
975
|
+
return panels;
|
976
|
+
}, []);
|
977
|
+
const componentEditAttributes = Object.entries(data.components).reduce(
|
978
|
+
(acc, [uid, configuration]) => {
|
979
|
+
acc[uid] = {
|
980
|
+
layout: convertEditLayoutToFieldLayouts(
|
981
|
+
configuration.layouts.edit,
|
982
|
+
components[uid].attributes,
|
983
|
+
configuration.metadatas,
|
984
|
+
{ configurations: data.components, schemas: components }
|
985
|
+
),
|
986
|
+
settings: {
|
987
|
+
...configuration.settings,
|
988
|
+
icon: components[uid].info.icon,
|
989
|
+
displayName: components[uid].info.displayName
|
927
990
|
}
|
928
|
-
|
929
|
-
|
930
|
-
title: formatMessage({
|
931
|
-
id: getTranslation("success.records.delete"),
|
932
|
-
defaultMessage: "Successfully deleted."
|
933
|
-
}),
|
934
|
-
message: ""
|
935
|
-
});
|
936
|
-
trackUsage("didBulkDeleteEntries");
|
937
|
-
return res.data;
|
938
|
-
} catch (err) {
|
939
|
-
toggleNotification({
|
940
|
-
type: "danger",
|
941
|
-
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
942
|
-
});
|
943
|
-
trackUsage("didNotBulkDeleteEntries");
|
944
|
-
throw err;
|
945
|
-
}
|
991
|
+
};
|
992
|
+
return acc;
|
946
993
|
},
|
947
|
-
|
994
|
+
{}
|
948
995
|
);
|
949
|
-
const
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
model,
|
956
|
-
documentId,
|
957
|
-
params
|
958
|
-
});
|
959
|
-
if ("error" in res) {
|
960
|
-
toggleNotification({
|
961
|
-
type: "danger",
|
962
|
-
message: formatAPIError(res.error)
|
963
|
-
});
|
964
|
-
return { error: res.error };
|
965
|
-
}
|
966
|
-
toggleNotification({
|
967
|
-
type: "success",
|
968
|
-
message: formatMessage({
|
969
|
-
id: "content-manager.success.record.discard",
|
970
|
-
defaultMessage: "Changes discarded"
|
971
|
-
})
|
972
|
-
});
|
973
|
-
return res.data;
|
974
|
-
} catch (err) {
|
975
|
-
toggleNotification({
|
976
|
-
type: "danger",
|
977
|
-
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
978
|
-
});
|
979
|
-
throw err;
|
980
|
-
}
|
996
|
+
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
997
|
+
(acc, [attribute, metadata]) => {
|
998
|
+
return {
|
999
|
+
...acc,
|
1000
|
+
[attribute]: metadata.edit
|
1001
|
+
};
|
981
1002
|
},
|
982
|
-
|
1003
|
+
{}
|
983
1004
|
);
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
model,
|
992
|
-
documentId,
|
993
|
-
data,
|
994
|
-
params
|
995
|
-
});
|
996
|
-
if ("error" in res) {
|
997
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
998
|
-
return { error: res.error };
|
999
|
-
}
|
1000
|
-
trackUsage("didPublishEntry");
|
1001
|
-
toggleNotification({
|
1002
|
-
type: "success",
|
1003
|
-
message: formatMessage({
|
1004
|
-
id: getTranslation("success.record.publish"),
|
1005
|
-
defaultMessage: "Published document"
|
1006
|
-
})
|
1007
|
-
});
|
1008
|
-
return res.data;
|
1009
|
-
} catch (err) {
|
1010
|
-
toggleNotification({
|
1011
|
-
type: "danger",
|
1012
|
-
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1013
|
-
});
|
1014
|
-
throw err;
|
1015
|
-
}
|
1005
|
+
return {
|
1006
|
+
layout: panelledEditAttributes,
|
1007
|
+
components: componentEditAttributes,
|
1008
|
+
metadatas: editMetadatas,
|
1009
|
+
settings: {
|
1010
|
+
...data.contentType.settings,
|
1011
|
+
displayName: schema?.info.displayName
|
1016
1012
|
},
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
return { error: res.error };
|
1031
|
-
}
|
1032
|
-
toggleNotification({
|
1033
|
-
type: "success",
|
1034
|
-
message: formatMessage({
|
1035
|
-
id: getTranslation("success.record.publish"),
|
1036
|
-
defaultMessage: "Published document"
|
1037
|
-
})
|
1038
|
-
});
|
1039
|
-
return res.data;
|
1040
|
-
} catch (err) {
|
1041
|
-
toggleNotification({
|
1042
|
-
type: "danger",
|
1043
|
-
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1044
|
-
});
|
1045
|
-
throw err;
|
1013
|
+
options: {
|
1014
|
+
...schema?.options,
|
1015
|
+
...schema?.pluginOptions,
|
1016
|
+
...data.contentType.options
|
1017
|
+
}
|
1018
|
+
};
|
1019
|
+
};
|
1020
|
+
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
1021
|
+
return rows.map(
|
1022
|
+
(row) => row.map((field) => {
|
1023
|
+
const attribute = attributes[field.name];
|
1024
|
+
if (!attribute) {
|
1025
|
+
return null;
|
1046
1026
|
}
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1027
|
+
const { edit: metadata } = metadatas[field.name];
|
1028
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1029
|
+
return {
|
1030
|
+
attribute,
|
1031
|
+
disabled: !metadata.editable,
|
1032
|
+
hint: metadata.description,
|
1033
|
+
label: metadata.label ?? "",
|
1034
|
+
name: field.name,
|
1035
|
+
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
1036
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1037
|
+
schemas,
|
1038
|
+
components: components?.schemas ?? {}
|
1039
|
+
}),
|
1040
|
+
placeholder: metadata.placeholder ?? "",
|
1041
|
+
required: attribute.required ?? false,
|
1042
|
+
size: field.size,
|
1043
|
+
unique: "unique" in attribute ? attribute.unique : false,
|
1044
|
+
visible: metadata.visible ?? true,
|
1045
|
+
type: attribute.type
|
1046
|
+
};
|
1047
|
+
}).filter((field) => field !== null)
|
1055
1048
|
);
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1049
|
+
};
|
1050
|
+
const formatListLayout = (data, {
|
1051
|
+
schemas,
|
1052
|
+
schema,
|
1053
|
+
components
|
1054
|
+
}) => {
|
1055
|
+
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1056
|
+
(acc, [attribute, metadata]) => {
|
1057
|
+
return {
|
1058
|
+
...acc,
|
1059
|
+
[attribute]: metadata.list
|
1060
|
+
};
|
1061
|
+
},
|
1062
|
+
{}
|
1063
|
+
);
|
1064
|
+
const listAttributes = convertListLayoutToFieldLayouts(
|
1065
|
+
data.contentType.layouts.list,
|
1066
|
+
schema?.attributes,
|
1067
|
+
listMetadatas,
|
1068
|
+
{ configurations: data.components, schemas: components },
|
1069
|
+
schemas
|
1070
|
+
);
|
1071
|
+
return {
|
1072
|
+
layout: listAttributes,
|
1073
|
+
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
1074
|
+
metadatas: listMetadatas,
|
1075
|
+
options: {
|
1076
|
+
...schema?.options,
|
1077
|
+
...schema?.pluginOptions,
|
1078
|
+
...data.contentType.options
|
1079
|
+
}
|
1080
|
+
};
|
1081
|
+
};
|
1082
|
+
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
1083
|
+
return columns.map((name) => {
|
1084
|
+
const attribute = attributes[name];
|
1085
|
+
if (!attribute) {
|
1086
|
+
return null;
|
1087
|
+
}
|
1088
|
+
const metadata = metadatas[name];
|
1089
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1090
|
+
return {
|
1091
|
+
attribute,
|
1092
|
+
label: metadata.label ?? "",
|
1093
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1094
|
+
schemas,
|
1095
|
+
components: components?.schemas ?? {}
|
1096
|
+
}),
|
1097
|
+
name,
|
1098
|
+
searchable: metadata.searchable ?? true,
|
1099
|
+
sortable: metadata.sortable ?? true
|
1100
|
+
};
|
1101
|
+
}).filter((field) => field !== null);
|
1102
|
+
};
|
1103
|
+
const useDocument = (args, opts) => {
|
1104
|
+
const { toggleNotification } = useNotification();
|
1105
|
+
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1106
|
+
const {
|
1107
|
+
currentData: data,
|
1108
|
+
isLoading: isLoadingDocument,
|
1109
|
+
isFetching: isFetchingDocument,
|
1110
|
+
error
|
1111
|
+
} = useGetDocumentQuery(args, {
|
1112
|
+
...opts,
|
1113
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
1114
|
+
});
|
1115
|
+
const {
|
1116
|
+
components,
|
1117
|
+
schema,
|
1118
|
+
schemas,
|
1119
|
+
isLoading: isLoadingSchema
|
1120
|
+
} = useContentTypeSchema(args.model);
|
1121
|
+
React.useEffect(() => {
|
1122
|
+
if (error) {
|
1123
|
+
toggleNotification({
|
1124
|
+
type: "danger",
|
1125
|
+
message: formatAPIError(error)
|
1126
|
+
});
|
1127
|
+
}
|
1128
|
+
}, [toggleNotification, error, formatAPIError, args.collectionType]);
|
1129
|
+
const validationSchema = React.useMemo(() => {
|
1130
|
+
if (!schema) {
|
1131
|
+
return null;
|
1132
|
+
}
|
1133
|
+
return createYupSchema(schema.attributes, components);
|
1134
|
+
}, [schema, components]);
|
1135
|
+
const validate = React.useCallback(
|
1136
|
+
(document) => {
|
1137
|
+
if (!validationSchema) {
|
1138
|
+
throw new Error(
|
1139
|
+
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
1140
|
+
);
|
1141
|
+
}
|
1142
|
+
try {
|
1143
|
+
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
1144
|
+
return null;
|
1145
|
+
} catch (error2) {
|
1146
|
+
if (error2 instanceof ValidationError) {
|
1147
|
+
return getYupValidationErrors(error2);
|
1148
|
+
}
|
1149
|
+
throw error2;
|
1150
|
+
}
|
1151
|
+
},
|
1152
|
+
[validationSchema]
|
1153
|
+
);
|
1154
|
+
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
1155
|
+
const hasError = !!error;
|
1156
|
+
return {
|
1157
|
+
components,
|
1158
|
+
document: data?.data,
|
1159
|
+
meta: data?.meta,
|
1160
|
+
isLoading,
|
1161
|
+
hasError,
|
1162
|
+
schema,
|
1163
|
+
schemas,
|
1164
|
+
validate
|
1165
|
+
};
|
1166
|
+
};
|
1167
|
+
const useDoc = () => {
|
1168
|
+
const { id, slug, collectionType, origin } = useParams();
|
1169
|
+
const [{ query }] = useQueryParams();
|
1170
|
+
const params = React.useMemo(() => buildValidParams(query), [query]);
|
1171
|
+
if (!collectionType) {
|
1172
|
+
throw new Error("Could not find collectionType in url params");
|
1173
|
+
}
|
1174
|
+
if (!slug) {
|
1175
|
+
throw new Error("Could not find model in url params");
|
1176
|
+
}
|
1177
|
+
const document = useDocument(
|
1178
|
+
{ documentId: origin || id, model: slug, collectionType, params },
|
1179
|
+
{
|
1180
|
+
skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
|
1181
|
+
}
|
1182
|
+
);
|
1183
|
+
const returnId = origin || id === "create" ? void 0 : id;
|
1184
|
+
return {
|
1185
|
+
collectionType,
|
1186
|
+
model: slug,
|
1187
|
+
id: returnId,
|
1188
|
+
...document
|
1189
|
+
};
|
1190
|
+
};
|
1191
|
+
const useContentManagerContext = () => {
|
1192
|
+
const {
|
1193
|
+
collectionType,
|
1194
|
+
model,
|
1195
|
+
id,
|
1196
|
+
components,
|
1197
|
+
isLoading: isLoadingDoc,
|
1198
|
+
schema,
|
1199
|
+
schemas
|
1200
|
+
} = useDoc();
|
1201
|
+
const layout = useDocumentLayout(model);
|
1202
|
+
const form = useForm("useContentManagerContext", (state) => state);
|
1203
|
+
const isSingleType = collectionType === SINGLE_TYPES;
|
1204
|
+
const slug = model;
|
1205
|
+
const isCreatingEntry = id === "create";
|
1206
|
+
useContentTypeSchema();
|
1207
|
+
const isLoading = isLoadingDoc || layout.isLoading;
|
1208
|
+
const error = layout.error;
|
1209
|
+
return {
|
1210
|
+
error,
|
1211
|
+
isLoading,
|
1212
|
+
// Base metadata
|
1213
|
+
model,
|
1214
|
+
collectionType,
|
1215
|
+
id,
|
1216
|
+
slug,
|
1217
|
+
isCreatingEntry,
|
1218
|
+
isSingleType,
|
1219
|
+
hasDraftAndPublish: schema?.options?.draftAndPublish ?? false,
|
1220
|
+
// All schema infos
|
1221
|
+
components,
|
1222
|
+
contentType: schema,
|
1223
|
+
contentTypes: schemas,
|
1224
|
+
// Form state
|
1225
|
+
form,
|
1226
|
+
// layout infos
|
1227
|
+
layout
|
1228
|
+
};
|
1229
|
+
};
|
1230
|
+
const prefixPluginTranslations = (trad, pluginId) => {
|
1231
|
+
if (!pluginId) {
|
1232
|
+
throw new TypeError("pluginId can't be empty");
|
1233
|
+
}
|
1234
|
+
return Object.keys(trad).reduce((acc, current) => {
|
1235
|
+
acc[`${pluginId}.${current}`] = trad[current];
|
1236
|
+
return acc;
|
1237
|
+
}, {});
|
1238
|
+
};
|
1239
|
+
const getTranslation = (id) => `content-manager.${id}`;
|
1240
|
+
const DEFAULT_UNEXPECTED_ERROR_MSG = {
|
1241
|
+
id: "notification.error",
|
1242
|
+
defaultMessage: "An error occurred, please try again"
|
1243
|
+
};
|
1244
|
+
const useDocumentActions = () => {
|
1245
|
+
const { toggleNotification } = useNotification();
|
1246
|
+
const { formatMessage } = useIntl();
|
1247
|
+
const { trackUsage } = useTracking();
|
1248
|
+
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1249
|
+
const navigate = useNavigate();
|
1250
|
+
const setCurrentStep = useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
1251
|
+
const [deleteDocument] = useDeleteDocumentMutation();
|
1252
|
+
const _delete = React.useCallback(
|
1253
|
+
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
1254
|
+
try {
|
1255
|
+
trackUsage("willDeleteEntry", trackerProperty);
|
1256
|
+
const res = await deleteDocument({
|
1062
1257
|
collectionType,
|
1063
1258
|
model,
|
1064
1259
|
documentId,
|
1065
|
-
data,
|
1066
1260
|
params
|
1067
1261
|
});
|
1068
1262
|
if ("error" in res) {
|
1069
|
-
toggleNotification({
|
1070
|
-
|
1263
|
+
toggleNotification({
|
1264
|
+
type: "danger",
|
1265
|
+
message: formatAPIError(res.error)
|
1266
|
+
});
|
1071
1267
|
return { error: res.error };
|
1072
1268
|
}
|
1073
|
-
trackUsage("didEditEntry", trackerProperty);
|
1074
1269
|
toggleNotification({
|
1075
1270
|
type: "success",
|
1076
1271
|
message: formatMessage({
|
1077
|
-
id: getTranslation("success.record.
|
1078
|
-
defaultMessage: "
|
1272
|
+
id: getTranslation("success.record.delete"),
|
1273
|
+
defaultMessage: "Deleted document"
|
1079
1274
|
})
|
1080
1275
|
});
|
1276
|
+
trackUsage("didDeleteEntry", trackerProperty);
|
1081
1277
|
return res.data;
|
1082
1278
|
} catch (err) {
|
1083
|
-
trackUsage("didNotEditEntry", { error: err, ...trackerProperty });
|
1084
1279
|
toggleNotification({
|
1085
1280
|
type: "danger",
|
1086
1281
|
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1087
1282
|
});
|
1283
|
+
trackUsage("didNotDeleteEntry", { error: err, ...trackerProperty });
|
1088
1284
|
throw err;
|
1089
1285
|
}
|
1090
1286
|
},
|
1091
|
-
[trackUsage,
|
1287
|
+
[trackUsage, deleteDocument, toggleNotification, formatMessage, formatAPIError]
|
1092
1288
|
);
|
1093
|
-
const [
|
1094
|
-
const
|
1095
|
-
async ({
|
1289
|
+
const [deleteManyDocuments] = useDeleteManyDocumentsMutation();
|
1290
|
+
const deleteMany = React.useCallback(
|
1291
|
+
async ({ model, documentIds, params }) => {
|
1096
1292
|
try {
|
1097
|
-
trackUsage("
|
1098
|
-
const res = await
|
1099
|
-
collectionType,
|
1293
|
+
trackUsage("willBulkDeleteEntries");
|
1294
|
+
const res = await deleteManyDocuments({
|
1100
1295
|
model,
|
1101
|
-
|
1102
|
-
params
|
1103
|
-
data: {
|
1104
|
-
discardDraft
|
1105
|
-
}
|
1296
|
+
documentIds,
|
1297
|
+
params
|
1106
1298
|
});
|
1107
1299
|
if ("error" in res) {
|
1108
|
-
toggleNotification({
|
1300
|
+
toggleNotification({
|
1301
|
+
type: "danger",
|
1302
|
+
message: formatAPIError(res.error)
|
1303
|
+
});
|
1109
1304
|
return { error: res.error };
|
1110
1305
|
}
|
1111
|
-
trackUsage("didUnpublishEntry");
|
1112
1306
|
toggleNotification({
|
1113
1307
|
type: "success",
|
1114
|
-
|
1115
|
-
id: getTranslation("success.
|
1116
|
-
defaultMessage: "
|
1117
|
-
})
|
1308
|
+
title: formatMessage({
|
1309
|
+
id: getTranslation("success.records.delete"),
|
1310
|
+
defaultMessage: "Successfully deleted."
|
1311
|
+
}),
|
1312
|
+
message: ""
|
1118
1313
|
});
|
1314
|
+
trackUsage("didBulkDeleteEntries");
|
1119
1315
|
return res.data;
|
1120
1316
|
} catch (err) {
|
1121
1317
|
toggleNotification({
|
1122
1318
|
type: "danger",
|
1123
1319
|
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1124
1320
|
});
|
1321
|
+
trackUsage("didNotBulkDeleteEntries");
|
1125
1322
|
throw err;
|
1126
1323
|
}
|
1127
1324
|
},
|
1128
|
-
[trackUsage,
|
1325
|
+
[trackUsage, deleteManyDocuments, toggleNotification, formatMessage, formatAPIError]
|
1129
1326
|
);
|
1130
|
-
const [
|
1131
|
-
const
|
1132
|
-
async ({ model,
|
1327
|
+
const [discardDocument] = useDiscardDocumentMutation();
|
1328
|
+
const discard = React.useCallback(
|
1329
|
+
async ({ collectionType, model, documentId, params }) => {
|
1133
1330
|
try {
|
1134
|
-
|
1135
|
-
|
1331
|
+
const res = await discardDocument({
|
1332
|
+
collectionType,
|
1136
1333
|
model,
|
1137
|
-
|
1334
|
+
documentId,
|
1138
1335
|
params
|
1139
1336
|
});
|
1140
1337
|
if ("error" in res) {
|
1141
|
-
toggleNotification({
|
1338
|
+
toggleNotification({
|
1339
|
+
type: "danger",
|
1340
|
+
message: formatAPIError(res.error)
|
1341
|
+
});
|
1142
1342
|
return { error: res.error };
|
1143
1343
|
}
|
1144
|
-
trackUsage("didBulkUnpublishEntries");
|
1145
1344
|
toggleNotification({
|
1146
1345
|
type: "success",
|
1147
|
-
|
1148
|
-
id:
|
1149
|
-
defaultMessage: "
|
1150
|
-
})
|
1151
|
-
message: ""
|
1346
|
+
message: formatMessage({
|
1347
|
+
id: "content-manager.success.record.discard",
|
1348
|
+
defaultMessage: "Changes discarded"
|
1349
|
+
})
|
1152
1350
|
});
|
1153
1351
|
return res.data;
|
1154
1352
|
} catch (err) {
|
@@ -1156,32 +1354,33 @@ const useDocumentActions = () => {
|
|
1156
1354
|
type: "danger",
|
1157
1355
|
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1158
1356
|
});
|
1159
|
-
trackUsage("didNotBulkUnpublishEntries");
|
1160
1357
|
throw err;
|
1161
1358
|
}
|
1162
1359
|
},
|
1163
|
-
[
|
1360
|
+
[discardDocument, formatAPIError, formatMessage, toggleNotification]
|
1164
1361
|
);
|
1165
|
-
const [
|
1166
|
-
const
|
1167
|
-
async ({ model, params }, data
|
1362
|
+
const [publishDocument] = usePublishDocumentMutation();
|
1363
|
+
const publish = React.useCallback(
|
1364
|
+
async ({ collectionType, model, documentId, params }, data) => {
|
1168
1365
|
try {
|
1169
|
-
|
1366
|
+
trackUsage("willPublishEntry");
|
1367
|
+
const res = await publishDocument({
|
1368
|
+
collectionType,
|
1170
1369
|
model,
|
1370
|
+
documentId,
|
1171
1371
|
data,
|
1172
1372
|
params
|
1173
1373
|
});
|
1174
1374
|
if ("error" in res) {
|
1175
1375
|
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1176
|
-
trackUsage("didNotCreateEntry", { error: res.error, ...trackerProperty });
|
1177
1376
|
return { error: res.error };
|
1178
1377
|
}
|
1179
|
-
trackUsage("
|
1378
|
+
trackUsage("didPublishEntry");
|
1180
1379
|
toggleNotification({
|
1181
1380
|
type: "success",
|
1182
1381
|
message: formatMessage({
|
1183
|
-
id: getTranslation("success.record.
|
1184
|
-
defaultMessage: "
|
1382
|
+
id: getTranslation("success.record.publish"),
|
1383
|
+
defaultMessage: "Published document"
|
1185
1384
|
})
|
1186
1385
|
});
|
1187
1386
|
return res.data;
|
@@ -1190,28 +1389,29 @@ const useDocumentActions = () => {
|
|
1190
1389
|
type: "danger",
|
1191
1390
|
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1192
1391
|
});
|
1193
|
-
trackUsage("didNotCreateEntry", { error: err, ...trackerProperty });
|
1194
1392
|
throw err;
|
1195
1393
|
}
|
1196
1394
|
},
|
1197
|
-
[
|
1395
|
+
[trackUsage, publishDocument, toggleNotification, formatMessage, formatAPIError]
|
1198
1396
|
);
|
1199
|
-
const [
|
1200
|
-
const
|
1201
|
-
async ({ model,
|
1397
|
+
const [publishManyDocuments] = usePublishManyDocumentsMutation();
|
1398
|
+
const publishMany = React.useCallback(
|
1399
|
+
async ({ model, documentIds, params }) => {
|
1202
1400
|
try {
|
1203
|
-
const res = await
|
1401
|
+
const res = await publishManyDocuments({
|
1204
1402
|
model,
|
1205
|
-
|
1403
|
+
documentIds,
|
1404
|
+
params
|
1206
1405
|
});
|
1207
1406
|
if ("error" in res) {
|
1407
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1208
1408
|
return { error: res.error };
|
1209
1409
|
}
|
1210
1410
|
toggleNotification({
|
1211
1411
|
type: "success",
|
1212
1412
|
message: formatMessage({
|
1213
|
-
id: getTranslation("success.record.
|
1214
|
-
defaultMessage: "
|
1413
|
+
id: getTranslation("success.record.publish"),
|
1414
|
+
defaultMessage: "Published document"
|
1215
1415
|
})
|
1216
1416
|
});
|
1217
1417
|
return res.data;
|
@@ -1223,1224 +1423,1100 @@ const useDocumentActions = () => {
|
|
1223
1423
|
throw err;
|
1224
1424
|
}
|
1225
1425
|
},
|
1226
|
-
[
|
1426
|
+
[
|
1427
|
+
// trackUsage,
|
1428
|
+
publishManyDocuments,
|
1429
|
+
toggleNotification,
|
1430
|
+
formatMessage,
|
1431
|
+
formatAPIError
|
1432
|
+
]
|
1227
1433
|
);
|
1228
|
-
const [
|
1229
|
-
const
|
1230
|
-
async ({ model, documentId, params },
|
1434
|
+
const [updateDocument] = useUpdateDocumentMutation();
|
1435
|
+
const update = React.useCallback(
|
1436
|
+
async ({ collectionType, model, documentId, params }, data, trackerProperty) => {
|
1231
1437
|
try {
|
1232
|
-
|
1233
|
-
const res = await
|
1438
|
+
trackUsage("willEditEntry", trackerProperty);
|
1439
|
+
const res = await updateDocument({
|
1440
|
+
collectionType,
|
1234
1441
|
model,
|
1235
|
-
|
1236
|
-
data
|
1442
|
+
documentId,
|
1443
|
+
data,
|
1237
1444
|
params
|
1238
1445
|
});
|
1239
1446
|
if ("error" in res) {
|
1240
1447
|
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1241
|
-
trackUsage("
|
1448
|
+
trackUsage("didNotEditEntry", { error: res.error, ...trackerProperty });
|
1242
1449
|
return { error: res.error };
|
1243
1450
|
}
|
1244
|
-
trackUsage("
|
1451
|
+
trackUsage("didEditEntry", trackerProperty);
|
1245
1452
|
toggleNotification({
|
1246
1453
|
type: "success",
|
1247
1454
|
message: formatMessage({
|
1248
|
-
id: getTranslation("success.record.
|
1249
|
-
defaultMessage: "
|
1455
|
+
id: getTranslation("success.record.save"),
|
1456
|
+
defaultMessage: "Saved document"
|
1250
1457
|
})
|
1251
1458
|
});
|
1252
1459
|
return res.data;
|
1253
1460
|
} catch (err) {
|
1461
|
+
trackUsage("didNotEditEntry", { error: err, ...trackerProperty });
|
1254
1462
|
toggleNotification({
|
1255
1463
|
type: "danger",
|
1256
1464
|
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1257
1465
|
});
|
1258
|
-
trackUsage("didNotCreateEntry", { error: err, ...trackerProperty });
|
1259
1466
|
throw err;
|
1260
1467
|
}
|
1261
1468
|
},
|
1262
|
-
[
|
1263
|
-
);
|
1264
|
-
const [getDoc] = useLazyGetDocumentQuery();
|
1265
|
-
const getDocument = React.useCallback(
|
1266
|
-
async (args) => {
|
1267
|
-
const { data } = await getDoc(args);
|
1268
|
-
return data;
|
1269
|
-
},
|
1270
|
-
[getDoc]
|
1469
|
+
[trackUsage, updateDocument, toggleNotification, formatMessage, formatAPIError]
|
1271
1470
|
);
|
1272
|
-
|
1273
|
-
|
1274
|
-
|
1275
|
-
|
1276
|
-
|
1277
|
-
|
1278
|
-
|
1279
|
-
|
1280
|
-
|
1281
|
-
|
1282
|
-
|
1283
|
-
|
1284
|
-
|
1285
|
-
|
1286
|
-
|
1287
|
-
|
1288
|
-
|
1289
|
-
);
|
1290
|
-
const routes$1 = [
|
1291
|
-
{
|
1292
|
-
path: ":collectionType/:slug/:id/history",
|
1293
|
-
Component: ProtectedHistoryPage
|
1294
|
-
},
|
1295
|
-
{
|
1296
|
-
path: ":collectionType/:slug/history",
|
1297
|
-
Component: ProtectedHistoryPage
|
1298
|
-
}
|
1299
|
-
];
|
1300
|
-
const ProtectedEditViewPage = lazy(
|
1301
|
-
() => import("./EditViewPage-B7VgwJaG.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1302
|
-
);
|
1303
|
-
const ProtectedListViewPage = lazy(
|
1304
|
-
() => import("./ListViewPage-B_GaWgRH.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1305
|
-
);
|
1306
|
-
const ProtectedListConfiguration = lazy(
|
1307
|
-
() => import("./ListConfigurationPage-voFVtXu6.mjs").then((mod) => ({
|
1308
|
-
default: mod.ProtectedListConfiguration
|
1309
|
-
}))
|
1310
|
-
);
|
1311
|
-
const ProtectedEditConfigurationPage = lazy(
|
1312
|
-
() => import("./EditConfigurationPage-D7PrLO8j.mjs").then((mod) => ({
|
1313
|
-
default: mod.ProtectedEditConfigurationPage
|
1314
|
-
}))
|
1315
|
-
);
|
1316
|
-
const ProtectedComponentConfigurationPage = lazy(
|
1317
|
-
() => import("./ComponentConfigurationPage-B3yDbeU1.mjs").then((mod) => ({
|
1318
|
-
default: mod.ProtectedComponentConfigurationPage
|
1319
|
-
}))
|
1320
|
-
);
|
1321
|
-
const NoPermissions = lazy(
|
1322
|
-
() => import("./NoPermissionsPage-B5baIHal.mjs").then((mod) => ({ default: mod.NoPermissions }))
|
1323
|
-
);
|
1324
|
-
const NoContentType = lazy(
|
1325
|
-
() => import("./NoContentTypePage-CYiGpsbj.mjs").then((mod) => ({ default: mod.NoContentType }))
|
1326
|
-
);
|
1327
|
-
const CollectionTypePages = () => {
|
1328
|
-
const { collectionType } = useParams();
|
1329
|
-
if (collectionType !== COLLECTION_TYPES && collectionType !== SINGLE_TYPES) {
|
1330
|
-
return /* @__PURE__ */ jsx(Navigate, { to: "/404" });
|
1331
|
-
}
|
1332
|
-
return collectionType === COLLECTION_TYPES ? /* @__PURE__ */ jsx(ProtectedListViewPage, {}) : /* @__PURE__ */ jsx(ProtectedEditViewPage, {});
|
1333
|
-
};
|
1334
|
-
const CLONE_RELATIVE_PATH = ":collectionType/:slug/clone/:origin";
|
1335
|
-
const CLONE_PATH = `/content-manager/${CLONE_RELATIVE_PATH}`;
|
1336
|
-
const LIST_RELATIVE_PATH = ":collectionType/:slug";
|
1337
|
-
const LIST_PATH = `/content-manager/${LIST_RELATIVE_PATH}`;
|
1338
|
-
const routes = [
|
1339
|
-
{
|
1340
|
-
path: LIST_RELATIVE_PATH,
|
1341
|
-
element: /* @__PURE__ */ jsx(CollectionTypePages, {})
|
1342
|
-
},
|
1343
|
-
{
|
1344
|
-
path: ":collectionType/:slug/:id",
|
1345
|
-
Component: ProtectedEditViewPage
|
1346
|
-
},
|
1347
|
-
{
|
1348
|
-
path: CLONE_RELATIVE_PATH,
|
1349
|
-
Component: ProtectedEditViewPage
|
1350
|
-
},
|
1351
|
-
{
|
1352
|
-
path: ":collectionType/:slug/configurations/list",
|
1353
|
-
Component: ProtectedListConfiguration
|
1354
|
-
},
|
1355
|
-
{
|
1356
|
-
path: "components/:slug/configurations/edit",
|
1357
|
-
Component: ProtectedComponentConfigurationPage
|
1358
|
-
},
|
1359
|
-
{
|
1360
|
-
path: ":collectionType/:slug/configurations/edit",
|
1361
|
-
Component: ProtectedEditConfigurationPage
|
1362
|
-
},
|
1363
|
-
{
|
1364
|
-
path: "403",
|
1365
|
-
Component: NoPermissions
|
1366
|
-
},
|
1367
|
-
{
|
1368
|
-
path: "no-content-types",
|
1369
|
-
Component: NoContentType
|
1370
|
-
},
|
1371
|
-
...routes$1
|
1372
|
-
];
|
1373
|
-
const DocumentActions = ({ actions: actions2 }) => {
|
1374
|
-
const { formatMessage } = useIntl();
|
1375
|
-
const [primaryAction, secondaryAction, ...restActions] = actions2.filter((action) => {
|
1376
|
-
if (action.position === void 0) {
|
1377
|
-
return true;
|
1378
|
-
}
|
1379
|
-
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
1380
|
-
return positions.includes("panel");
|
1381
|
-
});
|
1382
|
-
if (!primaryAction) {
|
1383
|
-
return null;
|
1384
|
-
}
|
1385
|
-
return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, alignItems: "stretch", width: "100%", children: [
|
1386
|
-
/* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
1387
|
-
/* @__PURE__ */ jsx(DocumentActionButton, { ...primaryAction, variant: primaryAction.variant || "default" }),
|
1388
|
-
restActions.length > 0 ? /* @__PURE__ */ jsx(
|
1389
|
-
DocumentActionsMenu,
|
1390
|
-
{
|
1391
|
-
actions: restActions,
|
1392
|
-
label: formatMessage({
|
1393
|
-
id: "content-manager.containers.edit.panels.default.more-actions",
|
1394
|
-
defaultMessage: "More document actions"
|
1395
|
-
})
|
1471
|
+
const [unpublishDocument] = useUnpublishDocumentMutation();
|
1472
|
+
const unpublish = React.useCallback(
|
1473
|
+
async ({ collectionType, model, documentId, params }, discardDraft = false) => {
|
1474
|
+
try {
|
1475
|
+
trackUsage("willUnpublishEntry");
|
1476
|
+
const res = await unpublishDocument({
|
1477
|
+
collectionType,
|
1478
|
+
model,
|
1479
|
+
documentId,
|
1480
|
+
params,
|
1481
|
+
data: {
|
1482
|
+
discardDraft
|
1483
|
+
}
|
1484
|
+
});
|
1485
|
+
if ("error" in res) {
|
1486
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1487
|
+
return { error: res.error };
|
1396
1488
|
}
|
1397
|
-
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
1402
|
-
|
1403
|
-
|
1489
|
+
trackUsage("didUnpublishEntry");
|
1490
|
+
toggleNotification({
|
1491
|
+
type: "success",
|
1492
|
+
message: formatMessage({
|
1493
|
+
id: getTranslation("success.record.unpublish"),
|
1494
|
+
defaultMessage: "Unpublished document"
|
1495
|
+
})
|
1496
|
+
});
|
1497
|
+
return res.data;
|
1498
|
+
} catch (err) {
|
1499
|
+
toggleNotification({
|
1500
|
+
type: "danger",
|
1501
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1502
|
+
});
|
1503
|
+
throw err;
|
1404
1504
|
}
|
1405
|
-
|
1406
|
-
|
1407
|
-
};
|
1408
|
-
const DocumentActionButton = (action) => {
|
1409
|
-
const [dialogId, setDialogId] = React.useState(null);
|
1410
|
-
const { toggleNotification } = useNotification();
|
1411
|
-
const handleClick = (action2) => async (e) => {
|
1412
|
-
const { onClick = () => false, dialog, id } = action2;
|
1413
|
-
const muteDialog = await onClick(e);
|
1414
|
-
if (dialog && !muteDialog) {
|
1415
|
-
switch (dialog.type) {
|
1416
|
-
case "notification":
|
1417
|
-
toggleNotification({
|
1418
|
-
title: dialog.title,
|
1419
|
-
message: dialog.content,
|
1420
|
-
type: dialog.status,
|
1421
|
-
timeout: dialog.timeout,
|
1422
|
-
onClose: dialog.onClose
|
1423
|
-
});
|
1424
|
-
break;
|
1425
|
-
case "dialog":
|
1426
|
-
case "modal":
|
1427
|
-
e.preventDefault();
|
1428
|
-
setDialogId(id);
|
1429
|
-
}
|
1430
|
-
}
|
1431
|
-
};
|
1432
|
-
const handleClose = () => {
|
1433
|
-
setDialogId(null);
|
1434
|
-
};
|
1435
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
1436
|
-
/* @__PURE__ */ jsx(
|
1437
|
-
Button,
|
1438
|
-
{
|
1439
|
-
flex: "auto",
|
1440
|
-
startIcon: action.icon,
|
1441
|
-
disabled: action.disabled,
|
1442
|
-
onClick: handleClick(action),
|
1443
|
-
justifyContent: "center",
|
1444
|
-
variant: action.variant || "default",
|
1445
|
-
paddingTop: "7px",
|
1446
|
-
paddingBottom: "7px",
|
1447
|
-
children: action.label
|
1448
|
-
}
|
1449
|
-
),
|
1450
|
-
action.dialog?.type === "dialog" ? /* @__PURE__ */ jsx(
|
1451
|
-
DocumentActionConfirmDialog,
|
1452
|
-
{
|
1453
|
-
...action.dialog,
|
1454
|
-
variant: action.dialog?.variant ?? action.variant,
|
1455
|
-
isOpen: dialogId === action.id,
|
1456
|
-
onClose: handleClose
|
1457
|
-
}
|
1458
|
-
) : null,
|
1459
|
-
action.dialog?.type === "modal" ? /* @__PURE__ */ jsx(
|
1460
|
-
DocumentActionModal,
|
1461
|
-
{
|
1462
|
-
...action.dialog,
|
1463
|
-
onModalClose: handleClose,
|
1464
|
-
isOpen: dialogId === action.id
|
1465
|
-
}
|
1466
|
-
) : null
|
1467
|
-
] });
|
1468
|
-
};
|
1469
|
-
const DocumentActionsMenu = ({
|
1470
|
-
actions: actions2,
|
1471
|
-
children,
|
1472
|
-
label,
|
1473
|
-
variant = "tertiary"
|
1474
|
-
}) => {
|
1475
|
-
const [isOpen, setIsOpen] = React.useState(false);
|
1476
|
-
const [dialogId, setDialogId] = React.useState(null);
|
1477
|
-
const { formatMessage } = useIntl();
|
1478
|
-
const { toggleNotification } = useNotification();
|
1479
|
-
const isDisabled = actions2.every((action) => action.disabled) || actions2.length === 0;
|
1480
|
-
const handleClick = (action) => async (e) => {
|
1481
|
-
const { onClick = () => false, dialog, id } = action;
|
1482
|
-
const muteDialog = await onClick(e);
|
1483
|
-
if (dialog && !muteDialog) {
|
1484
|
-
switch (dialog.type) {
|
1485
|
-
case "notification":
|
1486
|
-
toggleNotification({
|
1487
|
-
title: dialog.title,
|
1488
|
-
message: dialog.content,
|
1489
|
-
type: dialog.status,
|
1490
|
-
timeout: dialog.timeout,
|
1491
|
-
onClose: dialog.onClose
|
1492
|
-
});
|
1493
|
-
break;
|
1494
|
-
case "dialog":
|
1495
|
-
case "modal":
|
1496
|
-
setDialogId(id);
|
1497
|
-
}
|
1498
|
-
}
|
1499
|
-
};
|
1500
|
-
const handleClose = () => {
|
1501
|
-
setDialogId(null);
|
1502
|
-
setIsOpen(false);
|
1503
|
-
};
|
1504
|
-
return /* @__PURE__ */ jsxs(Menu.Root, { open: isOpen, onOpenChange: setIsOpen, children: [
|
1505
|
-
/* @__PURE__ */ jsxs(
|
1506
|
-
StyledMoreButton,
|
1507
|
-
{
|
1508
|
-
disabled: isDisabled,
|
1509
|
-
size: "S",
|
1510
|
-
endIcon: null,
|
1511
|
-
paddingTop: "4px",
|
1512
|
-
paddingLeft: "7px",
|
1513
|
-
paddingRight: "7px",
|
1514
|
-
variant,
|
1515
|
-
children: [
|
1516
|
-
/* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
|
1517
|
-
/* @__PURE__ */ jsx(VisuallyHidden, { tag: "span", children: label || formatMessage({
|
1518
|
-
id: "content-manager.containers.edit.panels.default.more-actions",
|
1519
|
-
defaultMessage: "More document actions"
|
1520
|
-
}) })
|
1521
|
-
]
|
1522
|
-
}
|
1523
|
-
),
|
1524
|
-
/* @__PURE__ */ jsxs(Menu.Content, { top: "4px", maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1525
|
-
actions2.map((action) => {
|
1526
|
-
return /* @__PURE__ */ jsx(
|
1527
|
-
Menu.Item,
|
1528
|
-
{
|
1529
|
-
disabled: action.disabled,
|
1530
|
-
onSelect: handleClick(action),
|
1531
|
-
display: "block",
|
1532
|
-
children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", gap: 4, children: [
|
1533
|
-
/* @__PURE__ */ jsxs(
|
1534
|
-
Flex,
|
1535
|
-
{
|
1536
|
-
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1537
|
-
gap: 2,
|
1538
|
-
tag: "span",
|
1539
|
-
children: [
|
1540
|
-
/* @__PURE__ */ jsx(
|
1541
|
-
Flex,
|
1542
|
-
{
|
1543
|
-
tag: "span",
|
1544
|
-
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1545
|
-
children: action.icon
|
1546
|
-
}
|
1547
|
-
),
|
1548
|
-
action.label
|
1549
|
-
]
|
1550
|
-
}
|
1551
|
-
),
|
1552
|
-
action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsx(
|
1553
|
-
Flex,
|
1554
|
-
{
|
1555
|
-
alignItems: "center",
|
1556
|
-
background: "alternative100",
|
1557
|
-
borderStyle: "solid",
|
1558
|
-
borderColor: "alternative200",
|
1559
|
-
borderWidth: "1px",
|
1560
|
-
height: 5,
|
1561
|
-
paddingLeft: 2,
|
1562
|
-
paddingRight: 2,
|
1563
|
-
hasRadius: true,
|
1564
|
-
color: "alternative600",
|
1565
|
-
children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", fontWeight: "bold", lineHeight: 1, children: formatMessage({ id: "global.new", defaultMessage: "New" }) })
|
1566
|
-
}
|
1567
|
-
)
|
1568
|
-
] })
|
1569
|
-
},
|
1570
|
-
action.id
|
1571
|
-
);
|
1572
|
-
}),
|
1573
|
-
children
|
1574
|
-
] }),
|
1575
|
-
actions2.map((action) => {
|
1576
|
-
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
1577
|
-
action.dialog?.type === "dialog" ? /* @__PURE__ */ jsx(
|
1578
|
-
DocumentActionConfirmDialog,
|
1579
|
-
{
|
1580
|
-
...action.dialog,
|
1581
|
-
variant: action.variant,
|
1582
|
-
isOpen: dialogId === action.id,
|
1583
|
-
onClose: handleClose
|
1584
|
-
}
|
1585
|
-
) : null,
|
1586
|
-
action.dialog?.type === "modal" ? /* @__PURE__ */ jsx(
|
1587
|
-
DocumentActionModal,
|
1588
|
-
{
|
1589
|
-
...action.dialog,
|
1590
|
-
onModalClose: handleClose,
|
1591
|
-
isOpen: dialogId === action.id
|
1592
|
-
}
|
1593
|
-
) : null
|
1594
|
-
] }, action.id);
|
1595
|
-
})
|
1596
|
-
] });
|
1597
|
-
};
|
1598
|
-
const convertActionVariantToColor = (variant = "secondary") => {
|
1599
|
-
switch (variant) {
|
1600
|
-
case "danger":
|
1601
|
-
return "danger600";
|
1602
|
-
case "secondary":
|
1603
|
-
return void 0;
|
1604
|
-
case "success":
|
1605
|
-
return "success600";
|
1606
|
-
default:
|
1607
|
-
return "primary600";
|
1608
|
-
}
|
1609
|
-
};
|
1610
|
-
const convertActionVariantToIconColor = (variant = "secondary") => {
|
1611
|
-
switch (variant) {
|
1612
|
-
case "danger":
|
1613
|
-
return "danger600";
|
1614
|
-
case "secondary":
|
1615
|
-
return "neutral500";
|
1616
|
-
case "success":
|
1617
|
-
return "success600";
|
1618
|
-
default:
|
1619
|
-
return "primary600";
|
1620
|
-
}
|
1621
|
-
};
|
1622
|
-
const StyledMoreButton = styled(Menu.Trigger)`
|
1623
|
-
& > span {
|
1624
|
-
display: flex;
|
1625
|
-
}
|
1626
|
-
`;
|
1627
|
-
const DocumentActionConfirmDialog = ({
|
1628
|
-
onClose,
|
1629
|
-
onCancel,
|
1630
|
-
onConfirm,
|
1631
|
-
title,
|
1632
|
-
content,
|
1633
|
-
isOpen,
|
1634
|
-
variant = "secondary"
|
1635
|
-
}) => {
|
1636
|
-
const { formatMessage } = useIntl();
|
1637
|
-
const handleClose = async () => {
|
1638
|
-
if (onCancel) {
|
1639
|
-
await onCancel();
|
1640
|
-
}
|
1641
|
-
onClose();
|
1642
|
-
};
|
1643
|
-
const handleConfirm = async () => {
|
1644
|
-
if (onConfirm) {
|
1645
|
-
await onConfirm();
|
1646
|
-
}
|
1647
|
-
onClose();
|
1648
|
-
};
|
1649
|
-
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
1650
|
-
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
1651
|
-
/* @__PURE__ */ jsx(Dialog.Body, { children: content }),
|
1652
|
-
/* @__PURE__ */ jsxs(Dialog.Footer, { children: [
|
1653
|
-
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", children: formatMessage({
|
1654
|
-
id: "app.components.Button.cancel",
|
1655
|
-
defaultMessage: "Cancel"
|
1656
|
-
}) }) }),
|
1657
|
-
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, children: formatMessage({
|
1658
|
-
id: "app.components.Button.confirm",
|
1659
|
-
defaultMessage: "Confirm"
|
1660
|
-
}) })
|
1661
|
-
] })
|
1662
|
-
] }) });
|
1663
|
-
};
|
1664
|
-
const DocumentActionModal = ({
|
1665
|
-
isOpen,
|
1666
|
-
title,
|
1667
|
-
onClose,
|
1668
|
-
footer: Footer,
|
1669
|
-
content: Content,
|
1670
|
-
onModalClose
|
1671
|
-
}) => {
|
1672
|
-
const handleClose = () => {
|
1673
|
-
if (onClose) {
|
1674
|
-
onClose();
|
1675
|
-
}
|
1676
|
-
onModalClose();
|
1677
|
-
};
|
1678
|
-
return /* @__PURE__ */ jsx(Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
|
1679
|
-
/* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: title }) }),
|
1680
|
-
typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsx(Modal.Body, { children: Content }),
|
1681
|
-
typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
|
1682
|
-
] }) });
|
1683
|
-
};
|
1684
|
-
const PublishAction$1 = ({
|
1685
|
-
activeTab,
|
1686
|
-
documentId,
|
1687
|
-
model,
|
1688
|
-
collectionType,
|
1689
|
-
meta,
|
1690
|
-
document
|
1691
|
-
}) => {
|
1692
|
-
const { schema } = useDoc();
|
1693
|
-
const navigate = useNavigate();
|
1694
|
-
const { toggleNotification } = useNotification();
|
1695
|
-
const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
|
1696
|
-
const isCloning = useMatch(CLONE_PATH) !== null;
|
1697
|
-
const { formatMessage } = useIntl();
|
1698
|
-
const { canPublish, canCreate, canUpdate } = useDocumentRBAC(
|
1699
|
-
"PublishAction",
|
1700
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1505
|
+
},
|
1506
|
+
[trackUsage, unpublishDocument, toggleNotification, formatMessage, formatAPIError]
|
1701
1507
|
);
|
1702
|
-
const
|
1703
|
-
const
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
|
1713
|
-
|
1714
|
-
|
1715
|
-
const setErrors = useForm("PublishAction", (state) => state.setErrors);
|
1716
|
-
const formValues = useForm("PublishAction", ({ values }) => values);
|
1717
|
-
React.useEffect(() => {
|
1718
|
-
if (isErrorDraftRelations) {
|
1719
|
-
toggleNotification({
|
1720
|
-
type: "danger",
|
1721
|
-
message: formatMessage({
|
1722
|
-
id: getTranslation("error.records.fetch-draft-relatons"),
|
1723
|
-
defaultMessage: "An error occurred while fetching draft relations on this document."
|
1724
|
-
})
|
1725
|
-
});
|
1726
|
-
}
|
1727
|
-
}, [isErrorDraftRelations, toggleNotification, formatMessage]);
|
1728
|
-
React.useEffect(() => {
|
1729
|
-
const localDraftRelations = /* @__PURE__ */ new Set();
|
1730
|
-
const extractDraftRelations = (data) => {
|
1731
|
-
const relations = data.connect || [];
|
1732
|
-
relations.forEach((relation) => {
|
1733
|
-
if (relation.status === "draft") {
|
1734
|
-
localDraftRelations.add(relation.id);
|
1735
|
-
}
|
1736
|
-
});
|
1737
|
-
};
|
1738
|
-
const traverseAndExtract = (data) => {
|
1739
|
-
Object.entries(data).forEach(([key, value]) => {
|
1740
|
-
if (key === "connect" && Array.isArray(value)) {
|
1741
|
-
extractDraftRelations({ connect: value });
|
1742
|
-
} else if (typeof value === "object" && value !== null) {
|
1743
|
-
traverseAndExtract(value);
|
1508
|
+
const [unpublishManyDocuments] = useUnpublishManyDocumentsMutation();
|
1509
|
+
const unpublishMany = React.useCallback(
|
1510
|
+
async ({ model, documentIds, params }) => {
|
1511
|
+
try {
|
1512
|
+
trackUsage("willBulkUnpublishEntries");
|
1513
|
+
const res = await unpublishManyDocuments({
|
1514
|
+
model,
|
1515
|
+
documentIds,
|
1516
|
+
params
|
1517
|
+
});
|
1518
|
+
if ("error" in res) {
|
1519
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1520
|
+
return { error: res.error };
|
1744
1521
|
}
|
1745
|
-
|
1746
|
-
|
1747
|
-
|
1748
|
-
|
1749
|
-
|
1750
|
-
|
1751
|
-
|
1752
|
-
|
1753
|
-
|
1754
|
-
|
1755
|
-
|
1756
|
-
|
1522
|
+
trackUsage("didBulkUnpublishEntries");
|
1523
|
+
toggleNotification({
|
1524
|
+
type: "success",
|
1525
|
+
title: formatMessage({
|
1526
|
+
id: getTranslation("success.records.unpublish"),
|
1527
|
+
defaultMessage: "Successfully unpublished."
|
1528
|
+
}),
|
1529
|
+
message: ""
|
1530
|
+
});
|
1531
|
+
return res.data;
|
1532
|
+
} catch (err) {
|
1533
|
+
toggleNotification({
|
1534
|
+
type: "danger",
|
1535
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1536
|
+
});
|
1537
|
+
trackUsage("didNotBulkUnpublishEntries");
|
1538
|
+
throw err;
|
1539
|
+
}
|
1540
|
+
},
|
1541
|
+
[trackUsage, unpublishManyDocuments, toggleNotification, formatMessage, formatAPIError]
|
1542
|
+
);
|
1543
|
+
const [createDocument] = useCreateDocumentMutation();
|
1544
|
+
const create = React.useCallback(
|
1545
|
+
async ({ model, params }, data, trackerProperty) => {
|
1546
|
+
try {
|
1547
|
+
const res = await createDocument({
|
1757
1548
|
model,
|
1758
|
-
|
1549
|
+
data,
|
1759
1550
|
params
|
1760
1551
|
});
|
1761
|
-
if (error) {
|
1762
|
-
|
1552
|
+
if ("error" in res) {
|
1553
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1554
|
+
trackUsage("didNotCreateEntry", { error: res.error, ...trackerProperty });
|
1555
|
+
return { error: res.error };
|
1763
1556
|
}
|
1764
|
-
|
1765
|
-
|
1557
|
+
trackUsage("didCreateEntry", trackerProperty);
|
1558
|
+
toggleNotification({
|
1559
|
+
type: "success",
|
1560
|
+
message: formatMessage({
|
1561
|
+
id: getTranslation("success.record.save"),
|
1562
|
+
defaultMessage: "Saved document"
|
1563
|
+
})
|
1564
|
+
});
|
1565
|
+
setCurrentStep("contentManager.success");
|
1566
|
+
return res.data;
|
1567
|
+
} catch (err) {
|
1568
|
+
toggleNotification({
|
1569
|
+
type: "danger",
|
1570
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1571
|
+
});
|
1572
|
+
trackUsage("didNotCreateEntry", { error: err, ...trackerProperty });
|
1573
|
+
throw err;
|
1574
|
+
}
|
1575
|
+
},
|
1576
|
+
[createDocument, formatAPIError, formatMessage, toggleNotification, trackUsage]
|
1577
|
+
);
|
1578
|
+
const [autoCloneDocument] = useAutoCloneDocumentMutation();
|
1579
|
+
const autoClone = React.useCallback(
|
1580
|
+
async ({ model, sourceId }) => {
|
1581
|
+
try {
|
1582
|
+
const res = await autoCloneDocument({
|
1583
|
+
model,
|
1584
|
+
sourceId
|
1585
|
+
});
|
1586
|
+
if ("error" in res) {
|
1587
|
+
return { error: res.error };
|
1766
1588
|
}
|
1767
|
-
|
1768
|
-
|
1769
|
-
|
1770
|
-
|
1771
|
-
|
1772
|
-
|
1773
|
-
|
1774
|
-
|
1775
|
-
|
1776
|
-
setSubmitting(true);
|
1777
|
-
try {
|
1778
|
-
const { errors } = await validate();
|
1779
|
-
if (errors) {
|
1589
|
+
toggleNotification({
|
1590
|
+
type: "success",
|
1591
|
+
message: formatMessage({
|
1592
|
+
id: getTranslation("success.record.clone"),
|
1593
|
+
defaultMessage: "Cloned document"
|
1594
|
+
})
|
1595
|
+
});
|
1596
|
+
return res.data;
|
1597
|
+
} catch (err) {
|
1780
1598
|
toggleNotification({
|
1781
1599
|
type: "danger",
|
1600
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1601
|
+
});
|
1602
|
+
throw err;
|
1603
|
+
}
|
1604
|
+
},
|
1605
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1606
|
+
);
|
1607
|
+
const [cloneDocument] = useCloneDocumentMutation();
|
1608
|
+
const clone = React.useCallback(
|
1609
|
+
async ({ model, documentId, params }, body, trackerProperty) => {
|
1610
|
+
try {
|
1611
|
+
const { id: _id, ...restBody } = body;
|
1612
|
+
const res = await cloneDocument({
|
1613
|
+
model,
|
1614
|
+
sourceId: documentId,
|
1615
|
+
data: restBody,
|
1616
|
+
params
|
1617
|
+
});
|
1618
|
+
if ("error" in res) {
|
1619
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1620
|
+
trackUsage("didNotCreateEntry", { error: res.error, ...trackerProperty });
|
1621
|
+
return { error: res.error };
|
1622
|
+
}
|
1623
|
+
trackUsage("didCreateEntry", trackerProperty);
|
1624
|
+
toggleNotification({
|
1625
|
+
type: "success",
|
1782
1626
|
message: formatMessage({
|
1783
|
-
id: "
|
1784
|
-
defaultMessage: "
|
1627
|
+
id: getTranslation("success.record.clone"),
|
1628
|
+
defaultMessage: "Cloned document"
|
1629
|
+
})
|
1630
|
+
});
|
1631
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1632
|
+
return res.data;
|
1633
|
+
} catch (err) {
|
1634
|
+
toggleNotification({
|
1635
|
+
type: "danger",
|
1636
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1637
|
+
});
|
1638
|
+
trackUsage("didNotCreateEntry", { error: err, ...trackerProperty });
|
1639
|
+
throw err;
|
1640
|
+
}
|
1641
|
+
},
|
1642
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1643
|
+
);
|
1644
|
+
const [getDoc] = useLazyGetDocumentQuery();
|
1645
|
+
const getDocument = React.useCallback(
|
1646
|
+
async (args) => {
|
1647
|
+
const { data } = await getDoc(args);
|
1648
|
+
return data;
|
1649
|
+
},
|
1650
|
+
[getDoc]
|
1651
|
+
);
|
1652
|
+
return {
|
1653
|
+
autoClone,
|
1654
|
+
clone,
|
1655
|
+
create,
|
1656
|
+
delete: _delete,
|
1657
|
+
deleteMany,
|
1658
|
+
discard,
|
1659
|
+
getDocument,
|
1660
|
+
publish,
|
1661
|
+
publishMany,
|
1662
|
+
unpublish,
|
1663
|
+
unpublishMany,
|
1664
|
+
update
|
1665
|
+
};
|
1666
|
+
};
|
1667
|
+
const ProtectedHistoryPage = lazy(
|
1668
|
+
() => import("./History-Bmu6tx6s.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1669
|
+
);
|
1670
|
+
const routes$1 = [
|
1671
|
+
{
|
1672
|
+
path: ":collectionType/:slug/:id/history",
|
1673
|
+
Component: ProtectedHistoryPage
|
1674
|
+
},
|
1675
|
+
{
|
1676
|
+
path: ":collectionType/:slug/history",
|
1677
|
+
Component: ProtectedHistoryPage
|
1678
|
+
}
|
1679
|
+
];
|
1680
|
+
const ProtectedEditViewPage = lazy(
|
1681
|
+
() => import("./EditViewPage-Dx0QnTxn.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1682
|
+
);
|
1683
|
+
const ProtectedListViewPage = lazy(
|
1684
|
+
() => import("./ListViewPage-DzhuS3CW.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1685
|
+
);
|
1686
|
+
const ProtectedListConfiguration = lazy(
|
1687
|
+
() => import("./ListConfigurationPage-DwijcJ17.mjs").then((mod) => ({
|
1688
|
+
default: mod.ProtectedListConfiguration
|
1689
|
+
}))
|
1690
|
+
);
|
1691
|
+
const ProtectedEditConfigurationPage = lazy(
|
1692
|
+
() => import("./EditConfigurationPage-BWq-9Zhk.mjs").then((mod) => ({
|
1693
|
+
default: mod.ProtectedEditConfigurationPage
|
1694
|
+
}))
|
1695
|
+
);
|
1696
|
+
const ProtectedComponentConfigurationPage = lazy(
|
1697
|
+
() => import("./ComponentConfigurationPage-BVM7LScS.mjs").then((mod) => ({
|
1698
|
+
default: mod.ProtectedComponentConfigurationPage
|
1699
|
+
}))
|
1700
|
+
);
|
1701
|
+
const NoPermissions = lazy(
|
1702
|
+
() => import("./NoPermissionsPage-DBbGJqL9.mjs").then((mod) => ({ default: mod.NoPermissions }))
|
1703
|
+
);
|
1704
|
+
const NoContentType = lazy(
|
1705
|
+
() => import("./NoContentTypePage-BKMgOyd3.mjs").then((mod) => ({ default: mod.NoContentType }))
|
1706
|
+
);
|
1707
|
+
const CollectionTypePages = () => {
|
1708
|
+
const { collectionType } = useParams();
|
1709
|
+
if (collectionType !== COLLECTION_TYPES && collectionType !== SINGLE_TYPES) {
|
1710
|
+
return /* @__PURE__ */ jsx(Navigate, { to: "/404" });
|
1711
|
+
}
|
1712
|
+
return collectionType === COLLECTION_TYPES ? /* @__PURE__ */ jsx(ProtectedListViewPage, {}) : /* @__PURE__ */ jsx(ProtectedEditViewPage, {});
|
1713
|
+
};
|
1714
|
+
const CLONE_RELATIVE_PATH = ":collectionType/:slug/clone/:origin";
|
1715
|
+
const CLONE_PATH = `/content-manager/${CLONE_RELATIVE_PATH}`;
|
1716
|
+
const LIST_RELATIVE_PATH = ":collectionType/:slug";
|
1717
|
+
const LIST_PATH = `/content-manager/${LIST_RELATIVE_PATH}`;
|
1718
|
+
const routes = [
|
1719
|
+
{
|
1720
|
+
path: LIST_RELATIVE_PATH,
|
1721
|
+
element: /* @__PURE__ */ jsx(CollectionTypePages, {})
|
1722
|
+
},
|
1723
|
+
{
|
1724
|
+
path: ":collectionType/:slug/:id",
|
1725
|
+
Component: ProtectedEditViewPage
|
1726
|
+
},
|
1727
|
+
{
|
1728
|
+
path: CLONE_RELATIVE_PATH,
|
1729
|
+
Component: ProtectedEditViewPage
|
1730
|
+
},
|
1731
|
+
{
|
1732
|
+
path: ":collectionType/:slug/configurations/list",
|
1733
|
+
Component: ProtectedListConfiguration
|
1734
|
+
},
|
1735
|
+
{
|
1736
|
+
path: "components/:slug/configurations/edit",
|
1737
|
+
Component: ProtectedComponentConfigurationPage
|
1738
|
+
},
|
1739
|
+
{
|
1740
|
+
path: ":collectionType/:slug/configurations/edit",
|
1741
|
+
Component: ProtectedEditConfigurationPage
|
1742
|
+
},
|
1743
|
+
{
|
1744
|
+
path: "403",
|
1745
|
+
Component: NoPermissions
|
1746
|
+
},
|
1747
|
+
{
|
1748
|
+
path: "no-content-types",
|
1749
|
+
Component: NoContentType
|
1750
|
+
},
|
1751
|
+
...routes$1
|
1752
|
+
];
|
1753
|
+
const DocumentActions = ({ actions: actions2 }) => {
|
1754
|
+
const { formatMessage } = useIntl();
|
1755
|
+
const [primaryAction, secondaryAction, ...restActions] = actions2.filter((action) => {
|
1756
|
+
if (action.position === void 0) {
|
1757
|
+
return true;
|
1758
|
+
}
|
1759
|
+
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
1760
|
+
return positions.includes("panel");
|
1761
|
+
});
|
1762
|
+
if (!primaryAction) {
|
1763
|
+
return null;
|
1764
|
+
}
|
1765
|
+
return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, alignItems: "stretch", width: "100%", children: [
|
1766
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
1767
|
+
/* @__PURE__ */ jsx(DocumentActionButton, { ...primaryAction, variant: primaryAction.variant || "default" }),
|
1768
|
+
restActions.length > 0 ? /* @__PURE__ */ jsx(
|
1769
|
+
DocumentActionsMenu,
|
1770
|
+
{
|
1771
|
+
actions: restActions,
|
1772
|
+
label: formatMessage({
|
1773
|
+
id: "content-manager.containers.edit.panels.default.more-actions",
|
1774
|
+
defaultMessage: "More document actions"
|
1785
1775
|
})
|
1786
|
-
}
|
1787
|
-
|
1776
|
+
}
|
1777
|
+
) : null
|
1778
|
+
] }),
|
1779
|
+
secondaryAction ? /* @__PURE__ */ jsx(
|
1780
|
+
DocumentActionButton,
|
1781
|
+
{
|
1782
|
+
...secondaryAction,
|
1783
|
+
variant: secondaryAction.variant || "secondary"
|
1788
1784
|
}
|
1789
|
-
|
1790
|
-
|
1791
|
-
|
1792
|
-
|
1793
|
-
|
1794
|
-
|
1795
|
-
|
1796
|
-
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
1800
|
-
|
1801
|
-
|
1802
|
-
|
1803
|
-
|
1804
|
-
|
1785
|
+
) : null
|
1786
|
+
] });
|
1787
|
+
};
|
1788
|
+
const DocumentActionButton = (action) => {
|
1789
|
+
const [dialogId, setDialogId] = React.useState(null);
|
1790
|
+
const { toggleNotification } = useNotification();
|
1791
|
+
const handleClick = (action2) => async (e) => {
|
1792
|
+
const { onClick = () => false, dialog, id } = action2;
|
1793
|
+
const muteDialog = await onClick(e);
|
1794
|
+
if (dialog && !muteDialog) {
|
1795
|
+
switch (dialog.type) {
|
1796
|
+
case "notification":
|
1797
|
+
toggleNotification({
|
1798
|
+
title: dialog.title,
|
1799
|
+
message: dialog.content,
|
1800
|
+
type: dialog.status,
|
1801
|
+
timeout: dialog.timeout,
|
1802
|
+
onClose: dialog.onClose
|
1803
|
+
});
|
1804
|
+
break;
|
1805
|
+
case "dialog":
|
1806
|
+
case "modal":
|
1807
|
+
e.preventDefault();
|
1808
|
+
setDialogId(id);
|
1805
1809
|
}
|
1806
|
-
} finally {
|
1807
|
-
setSubmitting(false);
|
1808
1810
|
}
|
1809
1811
|
};
|
1810
|
-
const
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
1815
|
-
|
1816
|
-
|
1817
|
-
|
1818
|
-
|
1819
|
-
|
1820
|
-
|
1821
|
-
|
1822
|
-
|
1823
|
-
|
1824
|
-
|
1825
|
-
|
1826
|
-
}),
|
1827
|
-
onClick: async () => {
|
1828
|
-
if (hasDraftRelations) {
|
1829
|
-
return;
|
1812
|
+
const handleClose = () => {
|
1813
|
+
setDialogId(null);
|
1814
|
+
};
|
1815
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
1816
|
+
/* @__PURE__ */ jsx(
|
1817
|
+
Button,
|
1818
|
+
{
|
1819
|
+
flex: "auto",
|
1820
|
+
startIcon: action.icon,
|
1821
|
+
disabled: action.disabled,
|
1822
|
+
onClick: handleClick(action),
|
1823
|
+
justifyContent: "center",
|
1824
|
+
variant: action.variant || "default",
|
1825
|
+
paddingTop: "7px",
|
1826
|
+
paddingBottom: "7px",
|
1827
|
+
children: action.label
|
1830
1828
|
}
|
1831
|
-
|
1832
|
-
|
1833
|
-
|
1834
|
-
|
1835
|
-
|
1836
|
-
|
1837
|
-
|
1838
|
-
|
1839
|
-
defaultMessage: "Confirmation"
|
1840
|
-
}),
|
1841
|
-
content: formatMessage(
|
1842
|
-
{
|
1843
|
-
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
1844
|
-
defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
|
1845
|
-
},
|
1846
|
-
{
|
1847
|
-
count: totalDraftRelations
|
1848
|
-
}
|
1849
|
-
),
|
1850
|
-
onConfirm: async () => {
|
1851
|
-
await performPublish();
|
1829
|
+
),
|
1830
|
+
action.dialog?.type === "dialog" ? /* @__PURE__ */ jsx(
|
1831
|
+
DocumentActionConfirmDialog,
|
1832
|
+
{
|
1833
|
+
...action.dialog,
|
1834
|
+
variant: action.dialog?.variant ?? action.variant,
|
1835
|
+
isOpen: dialogId === action.id,
|
1836
|
+
onClose: handleClose
|
1852
1837
|
}
|
1853
|
-
|
1854
|
-
|
1838
|
+
) : null,
|
1839
|
+
action.dialog?.type === "modal" ? /* @__PURE__ */ jsx(
|
1840
|
+
DocumentActionModal,
|
1841
|
+
{
|
1842
|
+
...action.dialog,
|
1843
|
+
onModalClose: handleClose,
|
1844
|
+
isOpen: dialogId === action.id
|
1845
|
+
}
|
1846
|
+
) : null
|
1847
|
+
] });
|
1855
1848
|
};
|
1856
|
-
|
1857
|
-
|
1858
|
-
|
1859
|
-
|
1860
|
-
|
1861
|
-
collectionType
|
1849
|
+
const DocumentActionsMenu = ({
|
1850
|
+
actions: actions2,
|
1851
|
+
children,
|
1852
|
+
label,
|
1853
|
+
variant = "tertiary"
|
1862
1854
|
}) => {
|
1863
|
-
const
|
1864
|
-
const
|
1865
|
-
const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
|
1866
|
-
const cloneMatch = useMatch(CLONE_PATH);
|
1867
|
-
const isCloning = cloneMatch !== null;
|
1855
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
1856
|
+
const [dialogId, setDialogId] = React.useState(null);
|
1868
1857
|
const { formatMessage } = useIntl();
|
1869
|
-
|
1870
|
-
|
1871
|
-
|
1872
|
-
|
1873
|
-
|
1874
|
-
|
1875
|
-
|
1876
|
-
|
1877
|
-
const modified = useForm("UpdateAction", ({ modified: modified2 }) => modified2);
|
1878
|
-
const setSubmitting = useForm("UpdateAction", ({ setSubmitting: setSubmitting2 }) => setSubmitting2);
|
1879
|
-
const document = useForm("UpdateAction", ({ values }) => values);
|
1880
|
-
const validate = useForm("UpdateAction", (state) => state.validate);
|
1881
|
-
const setErrors = useForm("UpdateAction", (state) => state.setErrors);
|
1882
|
-
const resetForm = useForm("PublishAction", ({ resetForm: resetForm2 }) => resetForm2);
|
1883
|
-
return {
|
1884
|
-
/**
|
1885
|
-
* Disabled when:
|
1886
|
-
* - the form is submitting
|
1887
|
-
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
1888
|
-
* - the active tab is the published tab
|
1889
|
-
*/
|
1890
|
-
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1891
|
-
label: formatMessage({
|
1892
|
-
id: "content-manager.containers.Edit.save",
|
1893
|
-
defaultMessage: "Save"
|
1894
|
-
}),
|
1895
|
-
onClick: async () => {
|
1896
|
-
setSubmitting(true);
|
1897
|
-
try {
|
1898
|
-
const { errors } = await validate();
|
1899
|
-
if (errors) {
|
1858
|
+
const { toggleNotification } = useNotification();
|
1859
|
+
const isDisabled = actions2.every((action) => action.disabled) || actions2.length === 0;
|
1860
|
+
const handleClick = (action) => async (e) => {
|
1861
|
+
const { onClick = () => false, dialog, id } = action;
|
1862
|
+
const muteDialog = await onClick(e);
|
1863
|
+
if (dialog && !muteDialog) {
|
1864
|
+
switch (dialog.type) {
|
1865
|
+
case "notification":
|
1900
1866
|
toggleNotification({
|
1901
|
-
|
1902
|
-
message:
|
1903
|
-
|
1904
|
-
|
1905
|
-
|
1867
|
+
title: dialog.title,
|
1868
|
+
message: dialog.content,
|
1869
|
+
type: dialog.status,
|
1870
|
+
timeout: dialog.timeout,
|
1871
|
+
onClose: dialog.onClose
|
1906
1872
|
});
|
1907
|
-
|
1908
|
-
|
1909
|
-
|
1910
|
-
|
1911
|
-
{
|
1912
|
-
model,
|
1913
|
-
documentId: cloneMatch.params.origin,
|
1914
|
-
params
|
1915
|
-
},
|
1916
|
-
document
|
1917
|
-
);
|
1918
|
-
if ("data" in res) {
|
1919
|
-
navigate(
|
1920
|
-
{
|
1921
|
-
pathname: `../${res.data.documentId}`,
|
1922
|
-
search: rawQuery
|
1923
|
-
},
|
1924
|
-
{ relative: "path" }
|
1925
|
-
);
|
1926
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1927
|
-
setErrors(formatValidationErrors(res.error));
|
1928
|
-
}
|
1929
|
-
} else if (documentId || collectionType === SINGLE_TYPES) {
|
1930
|
-
const res = await update(
|
1931
|
-
{
|
1932
|
-
collectionType,
|
1933
|
-
model,
|
1934
|
-
documentId,
|
1935
|
-
params
|
1936
|
-
},
|
1937
|
-
document
|
1938
|
-
);
|
1939
|
-
if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1940
|
-
setErrors(formatValidationErrors(res.error));
|
1941
|
-
} else {
|
1942
|
-
resetForm();
|
1943
|
-
}
|
1944
|
-
} else {
|
1945
|
-
const res = await create(
|
1946
|
-
{
|
1947
|
-
model,
|
1948
|
-
params
|
1949
|
-
},
|
1950
|
-
document
|
1951
|
-
);
|
1952
|
-
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1953
|
-
navigate(
|
1954
|
-
{
|
1955
|
-
pathname: `../${res.data.documentId}`,
|
1956
|
-
search: rawQuery
|
1957
|
-
},
|
1958
|
-
{ replace: true, relative: "path" }
|
1959
|
-
);
|
1960
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1961
|
-
setErrors(formatValidationErrors(res.error));
|
1962
|
-
}
|
1963
|
-
}
|
1964
|
-
} finally {
|
1965
|
-
setSubmitting(false);
|
1873
|
+
break;
|
1874
|
+
case "dialog":
|
1875
|
+
case "modal":
|
1876
|
+
setDialogId(id);
|
1966
1877
|
}
|
1967
1878
|
}
|
1968
1879
|
};
|
1969
|
-
|
1970
|
-
|
1971
|
-
|
1972
|
-
KEEP: "keep",
|
1973
|
-
DISCARD: "discard"
|
1974
|
-
};
|
1975
|
-
const UnpublishAction$1 = ({
|
1976
|
-
activeTab,
|
1977
|
-
documentId,
|
1978
|
-
model,
|
1979
|
-
collectionType,
|
1980
|
-
document
|
1981
|
-
}) => {
|
1982
|
-
const { formatMessage } = useIntl();
|
1983
|
-
const { schema } = useDoc();
|
1984
|
-
const canPublish = useDocumentRBAC("UnpublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1985
|
-
const { unpublish } = useDocumentActions();
|
1986
|
-
const [{ query }] = useQueryParams();
|
1987
|
-
const params = React.useMemo(() => buildValidParams(query), [query]);
|
1988
|
-
const { toggleNotification } = useNotification();
|
1989
|
-
const [shouldKeepDraft, setShouldKeepDraft] = React.useState(true);
|
1990
|
-
const isDocumentModified = document?.status === "modified";
|
1991
|
-
const handleChange = (value) => {
|
1992
|
-
setShouldKeepDraft(value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1880
|
+
const handleClose = () => {
|
1881
|
+
setDialogId(null);
|
1882
|
+
setIsOpen(false);
|
1993
1883
|
};
|
1994
|
-
|
1995
|
-
|
1996
|
-
|
1997
|
-
|
1998
|
-
|
1999
|
-
|
2000
|
-
|
2001
|
-
|
2002
|
-
|
2003
|
-
|
2004
|
-
|
2005
|
-
|
2006
|
-
|
2007
|
-
|
2008
|
-
|
2009
|
-
|
2010
|
-
|
2011
|
-
|
2012
|
-
id: "content-manager.actions.unpublish.error",
|
2013
|
-
defaultMessage: "An error occurred while trying to unpublish the document."
|
2014
|
-
}),
|
2015
|
-
type: "danger"
|
2016
|
-
});
|
2017
|
-
}
|
2018
|
-
return;
|
1884
|
+
return /* @__PURE__ */ jsxs(Menu.Root, { open: isOpen, onOpenChange: setIsOpen, children: [
|
1885
|
+
/* @__PURE__ */ jsxs(
|
1886
|
+
Menu.Trigger,
|
1887
|
+
{
|
1888
|
+
disabled: isDisabled,
|
1889
|
+
size: "S",
|
1890
|
+
endIcon: null,
|
1891
|
+
paddingTop: "4px",
|
1892
|
+
paddingLeft: "7px",
|
1893
|
+
paddingRight: "7px",
|
1894
|
+
variant,
|
1895
|
+
children: [
|
1896
|
+
/* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
|
1897
|
+
/* @__PURE__ */ jsx(VisuallyHidden, { tag: "span", children: label || formatMessage({
|
1898
|
+
id: "content-manager.containers.edit.panels.default.more-actions",
|
1899
|
+
defaultMessage: "More document actions"
|
1900
|
+
}) })
|
1901
|
+
]
|
2019
1902
|
}
|
2020
|
-
|
2021
|
-
|
2022
|
-
|
2023
|
-
|
2024
|
-
|
2025
|
-
|
2026
|
-
|
2027
|
-
|
2028
|
-
|
2029
|
-
|
2030
|
-
|
2031
|
-
|
1903
|
+
),
|
1904
|
+
/* @__PURE__ */ jsxs(Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1905
|
+
actions2.map((action) => {
|
1906
|
+
return /* @__PURE__ */ jsx(
|
1907
|
+
Menu.Item,
|
1908
|
+
{
|
1909
|
+
disabled: action.disabled,
|
1910
|
+
onSelect: handleClick(action),
|
1911
|
+
display: "block",
|
1912
|
+
children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", gap: 4, children: [
|
1913
|
+
/* @__PURE__ */ jsxs(
|
1914
|
+
Flex,
|
1915
|
+
{
|
1916
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1917
|
+
gap: 2,
|
1918
|
+
tag: "span",
|
1919
|
+
children: [
|
1920
|
+
/* @__PURE__ */ jsx(
|
1921
|
+
Flex,
|
1922
|
+
{
|
1923
|
+
tag: "span",
|
1924
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1925
|
+
children: action.icon
|
1926
|
+
}
|
1927
|
+
),
|
1928
|
+
action.label
|
1929
|
+
]
|
1930
|
+
}
|
1931
|
+
),
|
1932
|
+
action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsx(
|
1933
|
+
Flex,
|
1934
|
+
{
|
1935
|
+
alignItems: "center",
|
1936
|
+
background: "alternative100",
|
1937
|
+
borderStyle: "solid",
|
1938
|
+
borderColor: "alternative200",
|
1939
|
+
borderWidth: "1px",
|
1940
|
+
height: 5,
|
1941
|
+
paddingLeft: 2,
|
1942
|
+
paddingRight: 2,
|
1943
|
+
hasRadius: true,
|
1944
|
+
color: "alternative600",
|
1945
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", fontWeight: "bold", lineHeight: 1, children: formatMessage({ id: "global.new", defaultMessage: "New" }) })
|
1946
|
+
}
|
1947
|
+
)
|
1948
|
+
] })
|
1949
|
+
},
|
1950
|
+
action.id
|
1951
|
+
);
|
2032
1952
|
}),
|
2033
|
-
|
2034
|
-
|
2035
|
-
|
2036
|
-
|
2037
|
-
|
2038
|
-
|
2039
|
-
}) })
|
2040
|
-
] }),
|
2041
|
-
/* @__PURE__ */ jsxs(
|
2042
|
-
Radio.Group,
|
1953
|
+
children
|
1954
|
+
] }),
|
1955
|
+
actions2.map((action) => {
|
1956
|
+
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
1957
|
+
action.dialog?.type === "dialog" ? /* @__PURE__ */ jsx(
|
1958
|
+
DocumentActionConfirmDialog,
|
2043
1959
|
{
|
2044
|
-
|
2045
|
-
|
2046
|
-
|
2047
|
-
|
2048
|
-
defaultMessage: "Choose an option to unpublish the document."
|
2049
|
-
}),
|
2050
|
-
onValueChange: handleChange,
|
2051
|
-
children: [
|
2052
|
-
/* @__PURE__ */ jsx(Radio.Item, { checked: shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.KEEP, children: formatMessage({
|
2053
|
-
id: "content-manager.actions.unpublish.dialog.option.keep-draft",
|
2054
|
-
defaultMessage: "Keep draft"
|
2055
|
-
}) }),
|
2056
|
-
/* @__PURE__ */ jsx(Radio.Item, { checked: !shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.DISCARD, children: formatMessage({
|
2057
|
-
id: "content-manager.actions.unpublish.dialog.option.replace-draft",
|
2058
|
-
defaultMessage: "Replace draft"
|
2059
|
-
}) })
|
2060
|
-
]
|
1960
|
+
...action.dialog,
|
1961
|
+
variant: action.variant,
|
1962
|
+
isOpen: dialogId === action.id,
|
1963
|
+
onClose: handleClose
|
2061
1964
|
}
|
2062
|
-
)
|
2063
|
-
|
2064
|
-
|
2065
|
-
if (!documentId && collectionType !== SINGLE_TYPES) {
|
2066
|
-
console.error(
|
2067
|
-
"You're trying to unpublish a document without an id, this is likely a bug with Strapi. Please open an issue."
|
2068
|
-
);
|
2069
|
-
toggleNotification({
|
2070
|
-
message: formatMessage({
|
2071
|
-
id: "content-manager.actions.unpublish.error",
|
2072
|
-
defaultMessage: "An error occurred while trying to unpublish the document."
|
2073
|
-
}),
|
2074
|
-
type: "danger"
|
2075
|
-
});
|
2076
|
-
}
|
2077
|
-
await unpublish(
|
1965
|
+
) : null,
|
1966
|
+
action.dialog?.type === "modal" ? /* @__PURE__ */ jsx(
|
1967
|
+
DocumentActionModal,
|
2078
1968
|
{
|
2079
|
-
|
2080
|
-
|
2081
|
-
|
2082
|
-
|
2083
|
-
|
2084
|
-
|
2085
|
-
|
2086
|
-
|
2087
|
-
|
2088
|
-
|
2089
|
-
|
1969
|
+
...action.dialog,
|
1970
|
+
onModalClose: handleClose,
|
1971
|
+
isOpen: dialogId === action.id
|
1972
|
+
}
|
1973
|
+
) : null
|
1974
|
+
] }, action.id);
|
1975
|
+
})
|
1976
|
+
] });
|
1977
|
+
};
|
1978
|
+
const convertActionVariantToColor = (variant = "secondary") => {
|
1979
|
+
switch (variant) {
|
1980
|
+
case "danger":
|
1981
|
+
return "danger600";
|
1982
|
+
case "secondary":
|
1983
|
+
return void 0;
|
1984
|
+
case "success":
|
1985
|
+
return "success600";
|
1986
|
+
default:
|
1987
|
+
return "primary600";
|
1988
|
+
}
|
1989
|
+
};
|
1990
|
+
const convertActionVariantToIconColor = (variant = "secondary") => {
|
1991
|
+
switch (variant) {
|
1992
|
+
case "danger":
|
1993
|
+
return "danger600";
|
1994
|
+
case "secondary":
|
1995
|
+
return "neutral500";
|
1996
|
+
case "success":
|
1997
|
+
return "success600";
|
1998
|
+
default:
|
1999
|
+
return "primary600";
|
2000
|
+
}
|
2001
|
+
};
|
2002
|
+
const DocumentActionConfirmDialog = ({
|
2003
|
+
onClose,
|
2004
|
+
onCancel,
|
2005
|
+
onConfirm,
|
2006
|
+
title,
|
2007
|
+
content,
|
2008
|
+
isOpen,
|
2009
|
+
variant = "secondary"
|
2010
|
+
}) => {
|
2011
|
+
const { formatMessage } = useIntl();
|
2012
|
+
const handleClose = async () => {
|
2013
|
+
if (onCancel) {
|
2014
|
+
await onCancel();
|
2015
|
+
}
|
2016
|
+
onClose();
|
2017
|
+
};
|
2018
|
+
const handleConfirm = async () => {
|
2019
|
+
if (onConfirm) {
|
2020
|
+
await onConfirm();
|
2021
|
+
}
|
2022
|
+
onClose();
|
2023
|
+
};
|
2024
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
2025
|
+
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
2026
|
+
/* @__PURE__ */ jsx(Dialog.Body, { children: content }),
|
2027
|
+
/* @__PURE__ */ jsxs(Dialog.Footer, { children: [
|
2028
|
+
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", fullWidth: true, children: formatMessage({
|
2029
|
+
id: "app.components.Button.cancel",
|
2030
|
+
defaultMessage: "Cancel"
|
2031
|
+
}) }) }),
|
2032
|
+
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
|
2033
|
+
id: "app.components.Button.confirm",
|
2034
|
+
defaultMessage: "Confirm"
|
2035
|
+
}) })
|
2036
|
+
] })
|
2037
|
+
] }) });
|
2038
|
+
};
|
2039
|
+
const DocumentActionModal = ({
|
2040
|
+
isOpen,
|
2041
|
+
title,
|
2042
|
+
onClose,
|
2043
|
+
footer: Footer,
|
2044
|
+
content: Content,
|
2045
|
+
onModalClose
|
2046
|
+
}) => {
|
2047
|
+
const handleClose = () => {
|
2048
|
+
if (onClose) {
|
2049
|
+
onClose();
|
2050
|
+
}
|
2051
|
+
onModalClose();
|
2090
2052
|
};
|
2053
|
+
return /* @__PURE__ */ jsx(Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
|
2054
|
+
/* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: title }) }),
|
2055
|
+
typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsx(Modal.Body, { children: Content }),
|
2056
|
+
typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
|
2057
|
+
] }) });
|
2091
2058
|
};
|
2092
|
-
|
2093
|
-
const DiscardAction = ({
|
2059
|
+
const PublishAction$1 = ({
|
2094
2060
|
activeTab,
|
2095
2061
|
documentId,
|
2096
2062
|
model,
|
2097
2063
|
collectionType,
|
2064
|
+
meta,
|
2098
2065
|
document
|
2099
2066
|
}) => {
|
2100
|
-
const { formatMessage } = useIntl();
|
2101
2067
|
const { schema } = useDoc();
|
2102
|
-
const
|
2103
|
-
const {
|
2104
|
-
const
|
2105
|
-
const
|
2106
|
-
if (!schema?.options?.draftAndPublish) {
|
2107
|
-
return null;
|
2108
|
-
}
|
2109
|
-
return {
|
2110
|
-
disabled: !canUpdate || activeTab === "published" || document?.status !== "modified",
|
2111
|
-
label: formatMessage({
|
2112
|
-
id: "content-manager.actions.discard.label",
|
2113
|
-
defaultMessage: "Discard changes"
|
2114
|
-
}),
|
2115
|
-
icon: /* @__PURE__ */ jsx(StyledCrossCircle, {}),
|
2116
|
-
position: ["panel", "table-row"],
|
2117
|
-
variant: "danger",
|
2118
|
-
dialog: {
|
2119
|
-
type: "dialog",
|
2120
|
-
title: formatMessage({
|
2121
|
-
id: "app.components.ConfirmDialog.title",
|
2122
|
-
defaultMessage: "Confirmation"
|
2123
|
-
}),
|
2124
|
-
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
|
2125
|
-
/* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
2126
|
-
/* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
2127
|
-
id: "content-manager.actions.discard.dialog.body",
|
2128
|
-
defaultMessage: "Are you sure?"
|
2129
|
-
}) })
|
2130
|
-
] }),
|
2131
|
-
onConfirm: async () => {
|
2132
|
-
await discard({
|
2133
|
-
collectionType,
|
2134
|
-
model,
|
2135
|
-
documentId,
|
2136
|
-
params
|
2137
|
-
});
|
2138
|
-
}
|
2139
|
-
}
|
2140
|
-
};
|
2141
|
-
};
|
2142
|
-
DiscardAction.type = "discard";
|
2143
|
-
const StyledCrossCircle = styled(CrossCircle)`
|
2144
|
-
path {
|
2145
|
-
fill: currentColor;
|
2146
|
-
}
|
2147
|
-
`;
|
2148
|
-
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2149
|
-
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2150
|
-
const RelativeTime = React.forwardRef(
|
2151
|
-
({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {
|
2152
|
-
const { formatRelativeTime, formatDate, formatTime } = useIntl();
|
2153
|
-
const interval = intervalToDuration({
|
2154
|
-
start: timestamp,
|
2155
|
-
end: Date.now()
|
2156
|
-
// see https://github.com/date-fns/date-fns/issues/2891 – No idea why it's all partial it returns it every time.
|
2157
|
-
});
|
2158
|
-
const unit = intervals.find((intervalUnit) => {
|
2159
|
-
return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
|
2160
|
-
});
|
2161
|
-
const relativeTime = isPast(timestamp) ? -interval[unit] : interval[unit];
|
2162
|
-
const customInterval = customIntervals.find(
|
2163
|
-
(custom) => interval[custom.unit] < custom.threshold
|
2164
|
-
);
|
2165
|
-
const displayText = customInterval ? customInterval.text : formatRelativeTime(relativeTime, unit, { numeric: "auto" });
|
2166
|
-
return /* @__PURE__ */ jsx(
|
2167
|
-
"time",
|
2168
|
-
{
|
2169
|
-
ref: forwardedRef,
|
2170
|
-
dateTime: timestamp.toISOString(),
|
2171
|
-
role: "time",
|
2172
|
-
title: `${formatDate(timestamp)} ${formatTime(timestamp)}`,
|
2173
|
-
...restProps,
|
2174
|
-
children: displayText
|
2175
|
-
}
|
2176
|
-
);
|
2177
|
-
}
|
2178
|
-
);
|
2179
|
-
const getDisplayName = ({
|
2180
|
-
firstname,
|
2181
|
-
lastname,
|
2182
|
-
username,
|
2183
|
-
email
|
2184
|
-
} = {}) => {
|
2185
|
-
if (username) {
|
2186
|
-
return username;
|
2187
|
-
}
|
2188
|
-
if (firstname) {
|
2189
|
-
return `${firstname} ${lastname ?? ""}`.trim();
|
2190
|
-
}
|
2191
|
-
return email ?? "";
|
2192
|
-
};
|
2193
|
-
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2194
|
-
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2195
|
-
const statusVariant = status === "draft" ? "primary" : status === "published" ? "success" : "alternative";
|
2196
|
-
return /* @__PURE__ */ jsx(Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: capitalise(status) }) });
|
2197
|
-
};
|
2198
|
-
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
2199
|
-
const { formatMessage } = useIntl();
|
2068
|
+
const navigate = useNavigate();
|
2069
|
+
const { toggleNotification } = useNotification();
|
2070
|
+
const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
|
2071
|
+
const isListView = useMatch(LIST_PATH) !== null;
|
2200
2072
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
2201
|
-
const title = isCreating ? formatMessage({
|
2202
|
-
id: "content-manager.containers.edit.title.new",
|
2203
|
-
defaultMessage: "Create an entry"
|
2204
|
-
}) : documentTitle;
|
2205
|
-
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2206
|
-
/* @__PURE__ */ jsx(BackButton, {}),
|
2207
|
-
/* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2208
|
-
/* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
|
2209
|
-
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
2210
|
-
] }),
|
2211
|
-
status ? /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
|
2212
|
-
] });
|
2213
|
-
};
|
2214
|
-
const HeaderToolbar = () => {
|
2215
2073
|
const { formatMessage } = useIntl();
|
2216
|
-
const
|
2074
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
2075
|
+
const { publish } = useDocumentActions();
|
2217
2076
|
const [
|
2218
|
-
|
2219
|
-
|
2077
|
+
countDraftRelations,
|
2078
|
+
{ isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
|
2079
|
+
] = useLazyGetDraftRelationCountQuery();
|
2080
|
+
const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React.useState(0);
|
2081
|
+
const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React.useState(0);
|
2082
|
+
const [{ query, rawQuery }] = useQueryParams();
|
2083
|
+
const params = React.useMemo(() => buildValidParams(query), [query]);
|
2084
|
+
const modified = useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
2085
|
+
const setSubmitting = useForm("PublishAction", ({ setSubmitting: setSubmitting2 }) => setSubmitting2);
|
2086
|
+
const isSubmitting = useForm("PublishAction", ({ isSubmitting: isSubmitting2 }) => isSubmitting2);
|
2087
|
+
const validate = useForm("PublishAction", (state) => state.validate);
|
2088
|
+
const setErrors = useForm("PublishAction", (state) => state.setErrors);
|
2089
|
+
const formValues = useForm("PublishAction", ({ values }) => values);
|
2090
|
+
React.useEffect(() => {
|
2091
|
+
if (isErrorDraftRelations) {
|
2092
|
+
toggleNotification({
|
2093
|
+
type: "danger",
|
2094
|
+
message: formatMessage({
|
2095
|
+
id: getTranslation("error.records.fetch-draft-relatons"),
|
2096
|
+
defaultMessage: "An error occurred while fetching draft relations on this document."
|
2097
|
+
})
|
2098
|
+
});
|
2220
2099
|
}
|
2221
|
-
|
2222
|
-
|
2223
|
-
|
2224
|
-
|
2225
|
-
|
2226
|
-
|
2227
|
-
|
2228
|
-
|
2229
|
-
activeTab: status,
|
2230
|
-
model,
|
2231
|
-
documentId: id,
|
2232
|
-
document: isCloning ? void 0 : document,
|
2233
|
-
meta: isCloning ? void 0 : meta,
|
2234
|
-
collectionType
|
2235
|
-
},
|
2236
|
-
descriptions: plugins["content-manager"].apis.getHeaderActions(),
|
2237
|
-
children: (actions2) => {
|
2238
|
-
if (actions2.length > 0) {
|
2239
|
-
return /* @__PURE__ */ jsx(HeaderActions, { actions: actions2 });
|
2240
|
-
} else {
|
2241
|
-
return null;
|
2242
|
-
}
|
2100
|
+
}, [isErrorDraftRelations, toggleNotification, formatMessage]);
|
2101
|
+
React.useEffect(() => {
|
2102
|
+
const localDraftRelations = /* @__PURE__ */ new Set();
|
2103
|
+
const extractDraftRelations = (data) => {
|
2104
|
+
const relations = data.connect || [];
|
2105
|
+
relations.forEach((relation) => {
|
2106
|
+
if (relation.status === "draft") {
|
2107
|
+
localDraftRelations.add(relation.id);
|
2243
2108
|
}
|
2244
|
-
}
|
2245
|
-
|
2246
|
-
|
2247
|
-
|
2248
|
-
|
2249
|
-
|
2250
|
-
|
2251
|
-
|
2252
|
-
documentId: id,
|
2253
|
-
document: isCloning ? void 0 : document,
|
2254
|
-
meta: isCloning ? void 0 : meta,
|
2255
|
-
collectionType
|
2256
|
-
},
|
2257
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2258
|
-
children: (actions2) => {
|
2259
|
-
const headerActions = actions2.filter((action) => {
|
2260
|
-
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
2261
|
-
return positions.includes("header");
|
2262
|
-
});
|
2263
|
-
return /* @__PURE__ */ jsx(
|
2264
|
-
DocumentActionsMenu,
|
2265
|
-
{
|
2266
|
-
actions: headerActions,
|
2267
|
-
label: formatMessage({
|
2268
|
-
id: "content-manager.containers.edit.header.more-actions",
|
2269
|
-
defaultMessage: "More actions"
|
2270
|
-
}),
|
2271
|
-
children: /* @__PURE__ */ jsx(Information, { activeTab: status })
|
2272
|
-
}
|
2273
|
-
);
|
2109
|
+
});
|
2110
|
+
};
|
2111
|
+
const traverseAndExtract = (data) => {
|
2112
|
+
Object.entries(data).forEach(([key, value]) => {
|
2113
|
+
if (key === "connect" && Array.isArray(value)) {
|
2114
|
+
extractDraftRelations({ connect: value });
|
2115
|
+
} else if (typeof value === "object" && value !== null) {
|
2116
|
+
traverseAndExtract(value);
|
2274
2117
|
}
|
2275
|
-
}
|
2276
|
-
|
2277
|
-
|
2278
|
-
|
2279
|
-
|
2280
|
-
|
2281
|
-
|
2282
|
-
|
2118
|
+
});
|
2119
|
+
};
|
2120
|
+
if (!documentId || modified) {
|
2121
|
+
traverseAndExtract(formValues);
|
2122
|
+
setLocalCountOfDraftRelations(localDraftRelations.size);
|
2123
|
+
}
|
2124
|
+
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
2125
|
+
React.useEffect(() => {
|
2126
|
+
if (!document || !document.documentId || isListView) {
|
2127
|
+
return;
|
2128
|
+
}
|
2129
|
+
const fetchDraftRelationsCount = async () => {
|
2130
|
+
const { data, error } = await countDraftRelations({
|
2131
|
+
collectionType,
|
2132
|
+
model,
|
2133
|
+
documentId,
|
2134
|
+
params
|
2135
|
+
});
|
2136
|
+
if (error) {
|
2137
|
+
throw error;
|
2138
|
+
}
|
2139
|
+
if (data) {
|
2140
|
+
setServerCountOfDraftRelations(data.data);
|
2141
|
+
}
|
2142
|
+
};
|
2143
|
+
fetchDraftRelationsCount();
|
2144
|
+
}, [isListView, document, documentId, countDraftRelations, collectionType, model, params]);
|
2145
|
+
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
2146
|
+
if (!schema?.options?.draftAndPublish) {
|
2283
2147
|
return null;
|
2284
2148
|
}
|
2285
|
-
const
|
2286
|
-
|
2287
|
-
|
2288
|
-
|
2289
|
-
|
2290
|
-
|
2291
|
-
|
2292
|
-
|
2293
|
-
|
2294
|
-
|
2295
|
-
|
2296
|
-
|
2297
|
-
|
2298
|
-
|
2299
|
-
|
2300
|
-
|
2301
|
-
|
2302
|
-
time: /* @__PURE__ */ jsx(RelativeTime, { timestamp: new Date(publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME]) }),
|
2303
|
-
isAnonymous: !publishDocument?.[PUBLISHED_BY_ATTRIBUTE_NAME],
|
2304
|
-
author: publishDocument?.[PUBLISHED_BY_ATTRIBUTE_NAME] ? getDisplayName(publishDocument?.[PUBLISHED_BY_ATTRIBUTE_NAME]) : null
|
2305
|
-
}
|
2306
|
-
)
|
2307
|
-
},
|
2308
|
-
{
|
2309
|
-
isDisplayed: !!createAndUpdateDocument?.[UPDATED_AT_ATTRIBUTE_NAME],
|
2310
|
-
label: formatMessage({
|
2311
|
-
id: "content-manager.containers.edit.information.last-draft.label",
|
2312
|
-
defaultMessage: "Last draft"
|
2313
|
-
}),
|
2314
|
-
value: formatMessage(
|
2149
|
+
const performPublish = async () => {
|
2150
|
+
setSubmitting(true);
|
2151
|
+
try {
|
2152
|
+
const { errors } = await validate(true, {
|
2153
|
+
status: "published"
|
2154
|
+
});
|
2155
|
+
if (errors) {
|
2156
|
+
toggleNotification({
|
2157
|
+
type: "danger",
|
2158
|
+
message: formatMessage({
|
2159
|
+
id: "content-manager.validation.error",
|
2160
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2161
|
+
})
|
2162
|
+
});
|
2163
|
+
return;
|
2164
|
+
}
|
2165
|
+
const res = await publish(
|
2315
2166
|
{
|
2316
|
-
|
2317
|
-
|
2167
|
+
collectionType,
|
2168
|
+
model,
|
2169
|
+
documentId,
|
2170
|
+
params
|
2318
2171
|
},
|
2319
|
-
|
2320
|
-
|
2321
|
-
|
2322
|
-
|
2323
|
-
|
2324
|
-
|
2325
|
-
|
2326
|
-
|
2327
|
-
|
2328
|
-
|
2329
|
-
|
2172
|
+
formDocumentToData(formValues)
|
2173
|
+
);
|
2174
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
2175
|
+
navigate({
|
2176
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
2177
|
+
search: rawQuery
|
2178
|
+
});
|
2179
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2180
|
+
setErrors(formatValidationErrors(res.error));
|
2181
|
+
}
|
2182
|
+
} finally {
|
2183
|
+
setSubmitting(false);
|
2184
|
+
}
|
2185
|
+
};
|
2186
|
+
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
2187
|
+
const enableDraftRelationsCount = false;
|
2188
|
+
const hasDraftRelations = enableDraftRelationsCount;
|
2189
|
+
return {
|
2190
|
+
/**
|
2191
|
+
* Disabled when:
|
2192
|
+
* - currently if you're cloning a document we don't support publish & clone at the same time.
|
2193
|
+
* - the form is submitting
|
2194
|
+
* - the active tab is the published tab
|
2195
|
+
* - the document is already published & not modified
|
2196
|
+
* - the document is being created & not modified
|
2197
|
+
* - the user doesn't have the permission to publish
|
2198
|
+
*/
|
2199
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
2200
|
+
label: formatMessage({
|
2201
|
+
id: "app.utils.publish",
|
2202
|
+
defaultMessage: "Publish"
|
2203
|
+
}),
|
2204
|
+
onClick: async () => {
|
2205
|
+
await performPublish();
|
2330
2206
|
},
|
2331
|
-
{
|
2332
|
-
|
2333
|
-
|
2334
|
-
|
2335
|
-
|
2207
|
+
dialog: hasDraftRelations ? {
|
2208
|
+
type: "dialog",
|
2209
|
+
variant: "danger",
|
2210
|
+
footer: null,
|
2211
|
+
title: formatMessage({
|
2212
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
|
2213
|
+
defaultMessage: "Confirmation"
|
2336
2214
|
}),
|
2337
|
-
|
2215
|
+
content: formatMessage(
|
2338
2216
|
{
|
2339
|
-
id:
|
2340
|
-
defaultMessage:
|
2217
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
2218
|
+
defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
|
2341
2219
|
},
|
2342
2220
|
{
|
2343
|
-
|
2344
|
-
RelativeTime,
|
2345
|
-
{
|
2346
|
-
timestamp: new Date(createAndUpdateDocument?.[CREATED_AT_ATTRIBUTE_NAME])
|
2347
|
-
}
|
2348
|
-
),
|
2349
|
-
isAnonymous: !creator,
|
2350
|
-
author: creator
|
2221
|
+
count: totalDraftRelations
|
2351
2222
|
}
|
2352
|
-
)
|
2223
|
+
),
|
2224
|
+
onConfirm: async () => {
|
2225
|
+
await performPublish();
|
2226
|
+
}
|
2227
|
+
} : void 0
|
2228
|
+
};
|
2229
|
+
};
|
2230
|
+
PublishAction$1.type = "publish";
|
2231
|
+
const formDocumentToData = (document) => {
|
2232
|
+
return Object.keys(document).reduce((acc, key) => {
|
2233
|
+
if (document[key] !== void 0) {
|
2234
|
+
acc[key] = document[key];
|
2353
2235
|
}
|
2354
|
-
|
2355
|
-
|
2356
|
-
|
2357
|
-
|
2358
|
-
|
2359
|
-
|
2360
|
-
|
2361
|
-
|
2362
|
-
|
2363
|
-
|
2364
|
-
|
2365
|
-
|
2366
|
-
|
2367
|
-
|
2368
|
-
|
2369
|
-
|
2370
|
-
|
2371
|
-
|
2372
|
-
|
2373
|
-
|
2236
|
+
if (typeof document[key] === "object" && document[key] !== null) {
|
2237
|
+
if ("connect" in document[key] && document[key].connect !== null) {
|
2238
|
+
acc[key] = {
|
2239
|
+
...acc[key],
|
2240
|
+
connect: document[key].connect.map((item) => {
|
2241
|
+
return {
|
2242
|
+
documentId: item.documentId
|
2243
|
+
};
|
2244
|
+
})
|
2245
|
+
};
|
2246
|
+
}
|
2247
|
+
if ("disconnect" in document[key] && document[key].disconnect !== null) {
|
2248
|
+
acc[key] = {
|
2249
|
+
...acc[key],
|
2250
|
+
disconnect: document[key].disconnect.map((item) => {
|
2251
|
+
return {
|
2252
|
+
documentId: item.documentId
|
2253
|
+
};
|
2254
|
+
})
|
2255
|
+
};
|
2256
|
+
}
|
2257
|
+
}
|
2258
|
+
return acc;
|
2259
|
+
}, {});
|
2260
|
+
};
|
2261
|
+
const UpdateAction = ({
|
2262
|
+
activeTab,
|
2263
|
+
documentId,
|
2264
|
+
model,
|
2265
|
+
collectionType
|
2266
|
+
}) => {
|
2267
|
+
const navigate = useNavigate();
|
2268
|
+
const { toggleNotification } = useNotification();
|
2269
|
+
const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
|
2270
|
+
const cloneMatch = useMatch(CLONE_PATH);
|
2271
|
+
const isCloning = cloneMatch !== null;
|
2272
|
+
const { formatMessage } = useIntl();
|
2273
|
+
const { create, update, clone } = useDocumentActions();
|
2274
|
+
const [{ query, rawQuery }] = useQueryParams();
|
2275
|
+
const params = React.useMemo(() => buildValidParams(query), [query]);
|
2276
|
+
const isSubmitting = useForm("UpdateAction", ({ isSubmitting: isSubmitting2 }) => isSubmitting2);
|
2277
|
+
const modified = useForm("UpdateAction", ({ modified: modified2 }) => modified2);
|
2278
|
+
const setSubmitting = useForm("UpdateAction", ({ setSubmitting: setSubmitting2 }) => setSubmitting2);
|
2279
|
+
const document = useForm("UpdateAction", ({ values }) => values);
|
2280
|
+
const validate = useForm("UpdateAction", (state) => state.validate);
|
2281
|
+
const setErrors = useForm("UpdateAction", (state) => state.setErrors);
|
2282
|
+
const resetForm = useForm("PublishAction", ({ resetForm: resetForm2 }) => resetForm2);
|
2283
|
+
return {
|
2284
|
+
/**
|
2285
|
+
* Disabled when:
|
2286
|
+
* - the form is submitting
|
2287
|
+
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
2288
|
+
* - the active tab is the published tab
|
2289
|
+
*/
|
2290
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
2291
|
+
label: formatMessage({
|
2292
|
+
id: "content-manager.containers.Edit.save",
|
2293
|
+
defaultMessage: "Save"
|
2294
|
+
}),
|
2295
|
+
onClick: async () => {
|
2296
|
+
setSubmitting(true);
|
2297
|
+
try {
|
2298
|
+
const { errors } = await validate(true, {
|
2299
|
+
status: "draft"
|
2300
|
+
});
|
2301
|
+
if (errors) {
|
2302
|
+
toggleNotification({
|
2303
|
+
type: "danger",
|
2304
|
+
message: formatMessage({
|
2305
|
+
id: "content-manager.validation.error",
|
2306
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2307
|
+
})
|
2308
|
+
});
|
2309
|
+
return;
|
2310
|
+
}
|
2311
|
+
if (isCloning) {
|
2312
|
+
const res = await clone(
|
2313
|
+
{
|
2314
|
+
model,
|
2315
|
+
documentId: cloneMatch.params.origin,
|
2316
|
+
params
|
2317
|
+
},
|
2318
|
+
formDocumentToData(document)
|
2319
|
+
);
|
2320
|
+
if ("data" in res) {
|
2321
|
+
navigate(
|
2322
|
+
{
|
2323
|
+
pathname: `../${res.data.documentId}`,
|
2324
|
+
search: rawQuery
|
2325
|
+
},
|
2326
|
+
{ relative: "path" }
|
2327
|
+
);
|
2328
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2329
|
+
setErrors(formatValidationErrors(res.error));
|
2330
|
+
}
|
2331
|
+
} else if (documentId || collectionType === SINGLE_TYPES) {
|
2332
|
+
const res = await update(
|
2333
|
+
{
|
2334
|
+
collectionType,
|
2335
|
+
model,
|
2336
|
+
documentId,
|
2337
|
+
params
|
2338
|
+
},
|
2339
|
+
formDocumentToData(document)
|
2340
|
+
);
|
2341
|
+
if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2342
|
+
setErrors(formatValidationErrors(res.error));
|
2343
|
+
} else {
|
2344
|
+
resetForm();
|
2345
|
+
}
|
2346
|
+
} else {
|
2347
|
+
const res = await create(
|
2348
|
+
{
|
2349
|
+
model,
|
2350
|
+
params
|
2351
|
+
},
|
2352
|
+
formDocumentToData(document)
|
2353
|
+
);
|
2354
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
2355
|
+
navigate(
|
2356
|
+
{
|
2357
|
+
pathname: `../${res.data.documentId}`,
|
2358
|
+
search: rawQuery
|
2359
|
+
},
|
2360
|
+
{ replace: true, relative: "path" }
|
2361
|
+
);
|
2362
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2363
|
+
setErrors(formatValidationErrors(res.error));
|
2364
|
+
}
|
2365
|
+
}
|
2366
|
+
} finally {
|
2367
|
+
setSubmitting(false);
|
2368
|
+
}
|
2374
2369
|
}
|
2375
|
-
|
2370
|
+
};
|
2376
2371
|
};
|
2377
|
-
|
2378
|
-
|
2379
|
-
|
2380
|
-
|
2381
|
-
SingleSelect,
|
2382
|
-
{
|
2383
|
-
size: "S",
|
2384
|
-
disabled: action.disabled,
|
2385
|
-
"aria-label": action.label,
|
2386
|
-
onChange: action.onSelect,
|
2387
|
-
value: action.value,
|
2388
|
-
children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsx(SingleSelectOption, { ...option, children: label }, option.value))
|
2389
|
-
},
|
2390
|
-
action.id
|
2391
|
-
);
|
2392
|
-
} else {
|
2393
|
-
return null;
|
2394
|
-
}
|
2395
|
-
}) });
|
2372
|
+
UpdateAction.type = "update";
|
2373
|
+
const UNPUBLISH_DRAFT_OPTIONS = {
|
2374
|
+
KEEP: "keep",
|
2375
|
+
DISCARD: "discard"
|
2396
2376
|
};
|
2397
|
-
const
|
2398
|
-
|
2377
|
+
const UnpublishAction$1 = ({
|
2378
|
+
activeTab,
|
2379
|
+
documentId,
|
2380
|
+
model,
|
2381
|
+
collectionType,
|
2382
|
+
document
|
2383
|
+
}) => {
|
2399
2384
|
const { formatMessage } = useIntl();
|
2400
|
-
|
2401
|
-
|
2402
|
-
|
2403
|
-
|
2404
|
-
|
2405
|
-
|
2406
|
-
|
2407
|
-
|
2408
|
-
|
2409
|
-
|
2385
|
+
const { schema } = useDoc();
|
2386
|
+
const canPublish = useDocumentRBAC("UnpublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
2387
|
+
const { unpublish } = useDocumentActions();
|
2388
|
+
const [{ query }] = useQueryParams();
|
2389
|
+
const params = React.useMemo(() => buildValidParams(query), [query]);
|
2390
|
+
const { toggleNotification } = useNotification();
|
2391
|
+
const [shouldKeepDraft, setShouldKeepDraft] = React.useState(true);
|
2392
|
+
const isDocumentModified = document?.status === "modified";
|
2393
|
+
const handleChange = (value) => {
|
2394
|
+
setShouldKeepDraft(value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
2410
2395
|
};
|
2411
|
-
|
2412
|
-
|
2413
|
-
|
2414
|
-
const navigate = useNavigate();
|
2415
|
-
const { formatMessage } = useIntl();
|
2396
|
+
if (!schema?.options?.draftAndPublish) {
|
2397
|
+
return null;
|
2398
|
+
}
|
2416
2399
|
return {
|
2400
|
+
disabled: !canPublish || activeTab === "published" || document?.status !== "published" && document?.status !== "modified",
|
2417
2401
|
label: formatMessage({
|
2418
|
-
id: "
|
2419
|
-
defaultMessage: "
|
2402
|
+
id: "app.utils.unpublish",
|
2403
|
+
defaultMessage: "Unpublish"
|
2420
2404
|
}),
|
2421
|
-
icon: /* @__PURE__ */ jsx(
|
2422
|
-
onClick: () => {
|
2423
|
-
|
2405
|
+
icon: /* @__PURE__ */ jsx(Cross, {}),
|
2406
|
+
onClick: async () => {
|
2407
|
+
if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
|
2408
|
+
if (!documentId) {
|
2409
|
+
console.error(
|
2410
|
+
"You're trying to unpublish a document without an id, this is likely a bug with Strapi. Please open an issue."
|
2411
|
+
);
|
2412
|
+
toggleNotification({
|
2413
|
+
message: formatMessage({
|
2414
|
+
id: "content-manager.actions.unpublish.error",
|
2415
|
+
defaultMessage: "An error occurred while trying to unpublish the document."
|
2416
|
+
}),
|
2417
|
+
type: "danger"
|
2418
|
+
});
|
2419
|
+
}
|
2420
|
+
return;
|
2421
|
+
}
|
2422
|
+
await unpublish({
|
2423
|
+
collectionType,
|
2424
|
+
model,
|
2425
|
+
documentId,
|
2426
|
+
params
|
2427
|
+
});
|
2424
2428
|
},
|
2425
|
-
|
2429
|
+
dialog: isDocumentModified ? {
|
2430
|
+
type: "dialog",
|
2431
|
+
title: formatMessage({
|
2432
|
+
id: "app.components.ConfirmDialog.title",
|
2433
|
+
defaultMessage: "Confirmation"
|
2434
|
+
}),
|
2435
|
+
content: /* @__PURE__ */ jsxs(Flex, { alignItems: "flex-start", direction: "column", gap: 6, children: [
|
2436
|
+
/* @__PURE__ */ jsxs(Flex, { width: "100%", direction: "column", gap: 2, children: [
|
2437
|
+
/* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
2438
|
+
/* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
2439
|
+
id: "content-manager.actions.unpublish.dialog.body",
|
2440
|
+
defaultMessage: "Are you sure?"
|
2441
|
+
}) })
|
2442
|
+
] }),
|
2443
|
+
/* @__PURE__ */ jsxs(
|
2444
|
+
Radio.Group,
|
2445
|
+
{
|
2446
|
+
defaultValue: UNPUBLISH_DRAFT_OPTIONS.KEEP,
|
2447
|
+
name: "discard-options",
|
2448
|
+
"aria-label": formatMessage({
|
2449
|
+
id: "content-manager.actions.unpublish.dialog.radio-label",
|
2450
|
+
defaultMessage: "Choose an option to unpublish the document."
|
2451
|
+
}),
|
2452
|
+
onValueChange: handleChange,
|
2453
|
+
children: [
|
2454
|
+
/* @__PURE__ */ jsx(Radio.Item, { checked: shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.KEEP, children: formatMessage({
|
2455
|
+
id: "content-manager.actions.unpublish.dialog.option.keep-draft",
|
2456
|
+
defaultMessage: "Keep draft"
|
2457
|
+
}) }),
|
2458
|
+
/* @__PURE__ */ jsx(Radio.Item, { checked: !shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.DISCARD, children: formatMessage({
|
2459
|
+
id: "content-manager.actions.unpublish.dialog.option.replace-draft",
|
2460
|
+
defaultMessage: "Replace draft"
|
2461
|
+
}) })
|
2462
|
+
]
|
2463
|
+
}
|
2464
|
+
)
|
2465
|
+
] }),
|
2466
|
+
onConfirm: async () => {
|
2467
|
+
if (!documentId && collectionType !== SINGLE_TYPES) {
|
2468
|
+
console.error(
|
2469
|
+
"You're trying to unpublish a document without an id, this is likely a bug with Strapi. Please open an issue."
|
2470
|
+
);
|
2471
|
+
toggleNotification({
|
2472
|
+
message: formatMessage({
|
2473
|
+
id: "content-manager.actions.unpublish.error",
|
2474
|
+
defaultMessage: "An error occurred while trying to unpublish the document."
|
2475
|
+
}),
|
2476
|
+
type: "danger"
|
2477
|
+
});
|
2478
|
+
}
|
2479
|
+
await unpublish(
|
2480
|
+
{
|
2481
|
+
collectionType,
|
2482
|
+
model,
|
2483
|
+
documentId,
|
2484
|
+
params
|
2485
|
+
},
|
2486
|
+
!shouldKeepDraft
|
2487
|
+
);
|
2488
|
+
}
|
2489
|
+
} : void 0,
|
2490
|
+
variant: "danger",
|
2491
|
+
position: ["panel", "table-row"]
|
2426
2492
|
};
|
2427
2493
|
};
|
2428
|
-
|
2429
|
-
const
|
2430
|
-
|
2494
|
+
UnpublishAction$1.type = "unpublish";
|
2495
|
+
const DiscardAction = ({
|
2496
|
+
activeTab,
|
2497
|
+
documentId,
|
2498
|
+
model,
|
2499
|
+
collectionType,
|
2500
|
+
document
|
2501
|
+
}) => {
|
2431
2502
|
const { formatMessage } = useIntl();
|
2432
|
-
const
|
2433
|
-
const
|
2434
|
-
const {
|
2435
|
-
const {
|
2436
|
-
const
|
2503
|
+
const { schema } = useDoc();
|
2504
|
+
const canUpdate = useDocumentRBAC("DiscardAction", ({ canUpdate: canUpdate2 }) => canUpdate2);
|
2505
|
+
const { discard } = useDocumentActions();
|
2506
|
+
const [{ query }] = useQueryParams();
|
2507
|
+
const params = React.useMemo(() => buildValidParams(query), [query]);
|
2508
|
+
if (!schema?.options?.draftAndPublish) {
|
2509
|
+
return null;
|
2510
|
+
}
|
2437
2511
|
return {
|
2438
|
-
disabled: !
|
2512
|
+
disabled: !canUpdate || activeTab === "published" || document?.status !== "modified",
|
2439
2513
|
label: formatMessage({
|
2440
|
-
id: "content-manager.actions.
|
2441
|
-
defaultMessage: "
|
2514
|
+
id: "content-manager.actions.discard.label",
|
2515
|
+
defaultMessage: "Discard changes"
|
2442
2516
|
}),
|
2443
|
-
icon: /* @__PURE__ */ jsx(
|
2517
|
+
icon: /* @__PURE__ */ jsx(Cross, {}),
|
2518
|
+
position: ["panel", "table-row"],
|
2519
|
+
variant: "danger",
|
2444
2520
|
dialog: {
|
2445
2521
|
type: "dialog",
|
2446
2522
|
title: formatMessage({
|
@@ -2450,92 +2526,90 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2450
2526
|
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
|
2451
2527
|
/* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
2452
2528
|
/* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
2453
|
-
id: "content-manager.actions.
|
2529
|
+
id: "content-manager.actions.discard.dialog.body",
|
2454
2530
|
defaultMessage: "Are you sure?"
|
2455
2531
|
}) })
|
2456
2532
|
] }),
|
2457
2533
|
onConfirm: async () => {
|
2458
|
-
|
2459
|
-
|
2460
|
-
|
2461
|
-
|
2462
|
-
|
2463
|
-
|
2464
|
-
|
2465
|
-
|
2466
|
-
|
2467
|
-
|
2468
|
-
|
2469
|
-
|
2470
|
-
|
2471
|
-
|
2472
|
-
|
2473
|
-
|
2474
|
-
|
2475
|
-
|
2476
|
-
|
2477
|
-
|
2478
|
-
|
2479
|
-
|
2480
|
-
|
2481
|
-
|
2482
|
-
|
2483
|
-
|
2484
|
-
|
2485
|
-
|
2486
|
-
|
2487
|
-
|
2488
|
-
|
2489
|
-
|
2490
|
-
|
2534
|
+
await discard({
|
2535
|
+
collectionType,
|
2536
|
+
model,
|
2537
|
+
documentId,
|
2538
|
+
params
|
2539
|
+
});
|
2540
|
+
}
|
2541
|
+
}
|
2542
|
+
};
|
2543
|
+
};
|
2544
|
+
DiscardAction.type = "discard";
|
2545
|
+
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2546
|
+
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2547
|
+
const RelativeTime = React.forwardRef(
|
2548
|
+
({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {
|
2549
|
+
const { formatRelativeTime, formatDate, formatTime } = useIntl();
|
2550
|
+
const interval = intervalToDuration({
|
2551
|
+
start: timestamp,
|
2552
|
+
end: Date.now()
|
2553
|
+
// see https://github.com/date-fns/date-fns/issues/2891 – No idea why it's all partial it returns it every time.
|
2554
|
+
});
|
2555
|
+
const unit = intervals.find((intervalUnit) => {
|
2556
|
+
return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
|
2557
|
+
});
|
2558
|
+
const relativeTime = isPast(timestamp) ? -interval[unit] : interval[unit];
|
2559
|
+
const customInterval = customIntervals.find(
|
2560
|
+
(custom) => interval[custom.unit] < custom.threshold
|
2561
|
+
);
|
2562
|
+
const displayText = customInterval ? customInterval.text : formatRelativeTime(relativeTime, unit, { numeric: "auto" });
|
2563
|
+
return /* @__PURE__ */ jsx(
|
2564
|
+
"time",
|
2565
|
+
{
|
2566
|
+
ref: forwardedRef,
|
2567
|
+
dateTime: timestamp.toISOString(),
|
2568
|
+
role: "time",
|
2569
|
+
title: `${formatDate(timestamp)} ${formatTime(timestamp)}`,
|
2570
|
+
...restProps,
|
2571
|
+
children: displayText
|
2491
2572
|
}
|
2492
|
-
|
2493
|
-
|
2494
|
-
|
2495
|
-
|
2573
|
+
);
|
2574
|
+
}
|
2575
|
+
);
|
2576
|
+
const getDisplayName = ({
|
2577
|
+
firstname,
|
2578
|
+
lastname,
|
2579
|
+
username,
|
2580
|
+
email
|
2581
|
+
} = {}) => {
|
2582
|
+
if (username) {
|
2583
|
+
return username;
|
2584
|
+
}
|
2585
|
+
if (firstname) {
|
2586
|
+
return `${firstname} ${lastname ?? ""}`.trim();
|
2587
|
+
}
|
2588
|
+
return email ?? "";
|
2496
2589
|
};
|
2497
|
-
|
2498
|
-
const
|
2499
|
-
const
|
2500
|
-
|
2501
|
-
const [
|
2502
|
-
{
|
2503
|
-
query: { status }
|
2504
|
-
}
|
2505
|
-
] = useQueryParams({
|
2506
|
-
status: "draft"
|
2507
|
-
});
|
2508
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2509
|
-
const plugins = useStrapiApp("Panels", (state) => state.plugins);
|
2510
|
-
const props = {
|
2511
|
-
activeTab: status,
|
2512
|
-
model,
|
2513
|
-
documentId: id,
|
2514
|
-
document: isCloning ? void 0 : document,
|
2515
|
-
meta: isCloning ? void 0 : meta,
|
2516
|
-
collectionType
|
2517
|
-
};
|
2518
|
-
return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsx(
|
2519
|
-
DescriptionComponentRenderer,
|
2520
|
-
{
|
2521
|
-
props,
|
2522
|
-
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2523
|
-
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsx(Panel, { ...description, children: content }, id2))
|
2524
|
-
}
|
2525
|
-
) });
|
2590
|
+
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2591
|
+
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2592
|
+
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2593
|
+
return /* @__PURE__ */ jsx(Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: capitalise(status) }) });
|
2526
2594
|
};
|
2527
|
-
const
|
2595
|
+
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
2528
2596
|
const { formatMessage } = useIntl();
|
2529
|
-
|
2530
|
-
|
2531
|
-
|
2532
|
-
|
2533
|
-
|
2534
|
-
|
2535
|
-
|
2597
|
+
const isCloning = useMatch(CLONE_PATH) !== null;
|
2598
|
+
const title = isCreating ? formatMessage({
|
2599
|
+
id: "content-manager.containers.edit.title.new",
|
2600
|
+
defaultMessage: "Create an entry"
|
2601
|
+
}) : documentTitle;
|
2602
|
+
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2603
|
+
/* @__PURE__ */ jsx(BackButton, {}),
|
2604
|
+
/* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2605
|
+
/* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
|
2606
|
+
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
2607
|
+
] }),
|
2608
|
+
status ? /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
|
2609
|
+
] });
|
2536
2610
|
};
|
2537
|
-
|
2538
|
-
const
|
2611
|
+
const HeaderToolbar = () => {
|
2612
|
+
const { formatMessage } = useIntl();
|
2539
2613
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
2540
2614
|
const [
|
2541
2615
|
{
|
@@ -2543,355 +2617,432 @@ const ActionsPanelContent = () => {
|
|
2543
2617
|
}
|
2544
2618
|
] = useQueryParams();
|
2545
2619
|
const { model, id, document, meta, collectionType } = useDoc();
|
2546
|
-
const plugins = useStrapiApp("
|
2547
|
-
|
2548
|
-
activeTab: status,
|
2549
|
-
model,
|
2550
|
-
documentId: id,
|
2551
|
-
document: isCloning ? void 0 : document,
|
2552
|
-
meta: isCloning ? void 0 : meta,
|
2553
|
-
collectionType
|
2554
|
-
};
|
2555
|
-
return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
|
2620
|
+
const plugins = useStrapiApp("HeaderToolbar", (state) => state.plugins);
|
2621
|
+
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
2556
2622
|
/* @__PURE__ */ jsx(
|
2557
2623
|
DescriptionComponentRenderer,
|
2558
2624
|
{
|
2559
|
-
props
|
2560
|
-
|
2561
|
-
|
2625
|
+
props: {
|
2626
|
+
activeTab: status,
|
2627
|
+
model,
|
2628
|
+
documentId: id,
|
2629
|
+
document: isCloning ? void 0 : document,
|
2630
|
+
meta: isCloning ? void 0 : meta,
|
2631
|
+
collectionType
|
2632
|
+
},
|
2633
|
+
descriptions: plugins["content-manager"].apis.getHeaderActions(),
|
2634
|
+
children: (actions2) => {
|
2635
|
+
if (actions2.length > 0) {
|
2636
|
+
return /* @__PURE__ */ jsx(HeaderActions, { actions: actions2 });
|
2637
|
+
} else {
|
2638
|
+
return null;
|
2639
|
+
}
|
2640
|
+
}
|
2562
2641
|
}
|
2563
2642
|
),
|
2564
|
-
/* @__PURE__ */ jsx(
|
2643
|
+
/* @__PURE__ */ jsx(
|
2644
|
+
DescriptionComponentRenderer,
|
2645
|
+
{
|
2646
|
+
props: {
|
2647
|
+
activeTab: status,
|
2648
|
+
model,
|
2649
|
+
documentId: id,
|
2650
|
+
document: isCloning ? void 0 : document,
|
2651
|
+
meta: isCloning ? void 0 : meta,
|
2652
|
+
collectionType
|
2653
|
+
},
|
2654
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2655
|
+
children: (actions2) => {
|
2656
|
+
const headerActions = actions2.filter((action) => {
|
2657
|
+
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
2658
|
+
return positions.includes("header");
|
2659
|
+
});
|
2660
|
+
return /* @__PURE__ */ jsx(
|
2661
|
+
DocumentActionsMenu,
|
2662
|
+
{
|
2663
|
+
actions: headerActions,
|
2664
|
+
label: formatMessage({
|
2665
|
+
id: "content-manager.containers.edit.header.more-actions",
|
2666
|
+
defaultMessage: "More actions"
|
2667
|
+
}),
|
2668
|
+
children: /* @__PURE__ */ jsx(Information, { activeTab: status })
|
2669
|
+
}
|
2670
|
+
);
|
2671
|
+
}
|
2672
|
+
}
|
2673
|
+
)
|
2565
2674
|
] });
|
2566
2675
|
};
|
2567
|
-
const
|
2568
|
-
|
2569
|
-
|
2676
|
+
const Information = ({ activeTab }) => {
|
2677
|
+
const { formatMessage } = useIntl();
|
2678
|
+
const { document, meta } = useDoc();
|
2679
|
+
if (!document || !document.id) {
|
2680
|
+
return null;
|
2681
|
+
}
|
2682
|
+
const createAndUpdateDocument = activeTab === "draft" ? document : meta?.availableStatus.find((status) => status.publishedAt === null);
|
2683
|
+
const publishDocument = activeTab === "published" ? document : meta?.availableStatus.find((status) => status.publishedAt !== null);
|
2684
|
+
const creator = createAndUpdateDocument?.[CREATED_BY_ATTRIBUTE_NAME] ? getDisplayName(createAndUpdateDocument[CREATED_BY_ATTRIBUTE_NAME]) : null;
|
2685
|
+
const updator = createAndUpdateDocument?.[UPDATED_BY_ATTRIBUTE_NAME] ? getDisplayName(createAndUpdateDocument[UPDATED_BY_ATTRIBUTE_NAME]) : null;
|
2686
|
+
const information = [
|
2570
2687
|
{
|
2571
|
-
|
2572
|
-
|
2573
|
-
|
2574
|
-
|
2575
|
-
borderColor: "neutral150",
|
2576
|
-
hasRadius: true,
|
2577
|
-
paddingBottom: 4,
|
2578
|
-
paddingLeft: 4,
|
2579
|
-
paddingRight: 4,
|
2580
|
-
paddingTop: 4,
|
2581
|
-
shadow: "tableShadow",
|
2582
|
-
gap: 3,
|
2583
|
-
direction: "column",
|
2584
|
-
justifyContent: "stretch",
|
2585
|
-
alignItems: "flex-start",
|
2586
|
-
children: [
|
2587
|
-
/* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2588
|
-
children
|
2589
|
-
]
|
2590
|
-
}
|
2591
|
-
);
|
2592
|
-
});
|
2593
|
-
const HOOKS = {
|
2594
|
-
/**
|
2595
|
-
* Hook that allows to mutate the displayed headers of the list view table
|
2596
|
-
* @constant
|
2597
|
-
* @type {string}
|
2598
|
-
*/
|
2599
|
-
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2600
|
-
/**
|
2601
|
-
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2602
|
-
* @constant
|
2603
|
-
* @type {string}
|
2604
|
-
*/
|
2605
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2606
|
-
/**
|
2607
|
-
* Hook that allows to mutate the CM's edit view layout
|
2608
|
-
* @constant
|
2609
|
-
* @type {string}
|
2610
|
-
*/
|
2611
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2612
|
-
/**
|
2613
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
2614
|
-
* @constant
|
2615
|
-
* @type {string}
|
2616
|
-
*/
|
2617
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2618
|
-
};
|
2619
|
-
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2620
|
-
endpoints: (builder) => ({
|
2621
|
-
getContentTypeConfiguration: builder.query({
|
2622
|
-
query: (uid) => ({
|
2623
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2624
|
-
method: "GET"
|
2688
|
+
isDisplayed: !!publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME],
|
2689
|
+
label: formatMessage({
|
2690
|
+
id: "content-manager.containers.edit.information.last-published.label",
|
2691
|
+
defaultMessage: "Published"
|
2625
2692
|
}),
|
2626
|
-
|
2627
|
-
|
2628
|
-
|
2629
|
-
|
2630
|
-
|
2631
|
-
|
2632
|
-
|
2633
|
-
|
2634
|
-
|
2635
|
-
|
2636
|
-
|
2637
|
-
|
2638
|
-
|
2639
|
-
|
2640
|
-
|
2641
|
-
|
2693
|
+
value: formatMessage(
|
2694
|
+
{
|
2695
|
+
id: "content-manager.containers.edit.information.last-published.value",
|
2696
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2697
|
+
},
|
2698
|
+
{
|
2699
|
+
time: /* @__PURE__ */ jsx(RelativeTime, { timestamp: new Date(publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME]) }),
|
2700
|
+
isAnonymous: !publishDocument?.[PUBLISHED_BY_ATTRIBUTE_NAME],
|
2701
|
+
author: publishDocument?.[PUBLISHED_BY_ATTRIBUTE_NAME] ? getDisplayName(publishDocument?.[PUBLISHED_BY_ATTRIBUTE_NAME]) : null
|
2702
|
+
}
|
2703
|
+
)
|
2704
|
+
},
|
2705
|
+
{
|
2706
|
+
isDisplayed: !!createAndUpdateDocument?.[UPDATED_AT_ATTRIBUTE_NAME],
|
2707
|
+
label: formatMessage({
|
2708
|
+
id: "content-manager.containers.edit.information.last-draft.label",
|
2709
|
+
defaultMessage: "Updated"
|
2710
|
+
}),
|
2711
|
+
value: formatMessage(
|
2712
|
+
{
|
2713
|
+
id: "content-manager.containers.edit.information.last-draft.value",
|
2714
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2715
|
+
},
|
2716
|
+
{
|
2717
|
+
time: /* @__PURE__ */ jsx(
|
2718
|
+
RelativeTime,
|
2719
|
+
{
|
2720
|
+
timestamp: new Date(createAndUpdateDocument?.[UPDATED_AT_ATTRIBUTE_NAME])
|
2721
|
+
}
|
2722
|
+
),
|
2723
|
+
isAnonymous: !updator,
|
2724
|
+
author: updator
|
2725
|
+
}
|
2726
|
+
)
|
2727
|
+
},
|
2728
|
+
{
|
2729
|
+
isDisplayed: !!createAndUpdateDocument?.[CREATED_AT_ATTRIBUTE_NAME],
|
2730
|
+
label: formatMessage({
|
2731
|
+
id: "content-manager.containers.edit.information.document.label",
|
2732
|
+
defaultMessage: "Created"
|
2642
2733
|
}),
|
2643
|
-
|
2644
|
-
|
2645
|
-
|
2646
|
-
|
2647
|
-
|
2648
|
-
{
|
2649
|
-
|
2650
|
-
|
2651
|
-
|
2652
|
-
|
2653
|
-
|
2654
|
-
|
2655
|
-
|
2656
|
-
|
2657
|
-
}
|
2658
|
-
|
2659
|
-
|
2660
|
-
|
2661
|
-
|
2662
|
-
|
2663
|
-
|
2664
|
-
|
2665
|
-
|
2666
|
-
|
2667
|
-
|
2668
|
-
|
2669
|
-
|
2670
|
-
|
2671
|
-
|
2734
|
+
value: formatMessage(
|
2735
|
+
{
|
2736
|
+
id: "content-manager.containers.edit.information.document.value",
|
2737
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2738
|
+
},
|
2739
|
+
{
|
2740
|
+
time: /* @__PURE__ */ jsx(
|
2741
|
+
RelativeTime,
|
2742
|
+
{
|
2743
|
+
timestamp: new Date(createAndUpdateDocument?.[CREATED_AT_ATTRIBUTE_NAME])
|
2744
|
+
}
|
2745
|
+
),
|
2746
|
+
isAnonymous: !creator,
|
2747
|
+
author: creator
|
2748
|
+
}
|
2749
|
+
)
|
2750
|
+
}
|
2751
|
+
].filter((info) => info.isDisplayed);
|
2752
|
+
return /* @__PURE__ */ jsx(
|
2753
|
+
Flex,
|
2754
|
+
{
|
2755
|
+
borderWidth: "1px 0 0 0",
|
2756
|
+
borderStyle: "solid",
|
2757
|
+
borderColor: "neutral150",
|
2758
|
+
direction: "column",
|
2759
|
+
marginTop: 2,
|
2760
|
+
tag: "dl",
|
2761
|
+
padding: 5,
|
2762
|
+
gap: 3,
|
2763
|
+
alignItems: "flex-start",
|
2764
|
+
marginLeft: "-0.4rem",
|
2765
|
+
marginRight: "-0.4rem",
|
2766
|
+
width: "calc(100% + 8px)",
|
2767
|
+
children: information.map((info) => /* @__PURE__ */ jsxs(Flex, { gap: 1, direction: "column", alignItems: "flex-start", children: [
|
2768
|
+
/* @__PURE__ */ jsx(Typography, { tag: "dt", variant: "pi", fontWeight: "bold", children: info.label }),
|
2769
|
+
/* @__PURE__ */ jsx(Typography, { tag: "dd", variant: "pi", textColor: "neutral600", children: info.value })
|
2770
|
+
] }, info.label))
|
2771
|
+
}
|
2672
2772
|
);
|
2673
|
-
return {
|
2674
|
-
name: mainFieldName,
|
2675
|
-
type: mainFieldType ?? "string"
|
2676
|
-
};
|
2677
|
-
};
|
2678
|
-
const DEFAULT_SETTINGS = {
|
2679
|
-
bulkable: false,
|
2680
|
-
filterable: false,
|
2681
|
-
searchable: false,
|
2682
|
-
pagination: false,
|
2683
|
-
defaultSortBy: "",
|
2684
|
-
defaultSortOrder: "asc",
|
2685
|
-
mainField: "id",
|
2686
|
-
pageSize: 10
|
2687
2773
|
};
|
2688
|
-
const
|
2689
|
-
const
|
2690
|
-
const
|
2691
|
-
|
2692
|
-
|
2693
|
-
|
2694
|
-
|
2695
|
-
|
2696
|
-
|
2697
|
-
|
2698
|
-
error,
|
2699
|
-
isFetching: isFetchingConfigs
|
2700
|
-
} = useGetContentTypeConfigurationQuery(model);
|
2701
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2702
|
-
React.useEffect(() => {
|
2703
|
-
if (error) {
|
2704
|
-
toggleNotification({
|
2705
|
-
type: "danger",
|
2706
|
-
message: formatAPIError(error)
|
2707
|
-
});
|
2774
|
+
const HeaderActions = ({ actions: actions2 }) => {
|
2775
|
+
const [dialogId, setDialogId] = React.useState(null);
|
2776
|
+
const handleClick = (action) => async (e) => {
|
2777
|
+
if (!("options" in action)) {
|
2778
|
+
const { onClick = () => false, dialog, id } = action;
|
2779
|
+
const muteDialog = await onClick(e);
|
2780
|
+
if (dialog && !muteDialog) {
|
2781
|
+
e.preventDefault();
|
2782
|
+
setDialogId(id);
|
2783
|
+
}
|
2708
2784
|
}
|
2709
|
-
}, [error, formatAPIError, toggleNotification]);
|
2710
|
-
const editLayout = React.useMemo(
|
2711
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2712
|
-
layout: [],
|
2713
|
-
components: {},
|
2714
|
-
metadatas: {},
|
2715
|
-
options: {},
|
2716
|
-
settings: DEFAULT_SETTINGS
|
2717
|
-
},
|
2718
|
-
[data, isLoading, schemas, schema, components]
|
2719
|
-
);
|
2720
|
-
const listLayout = React.useMemo(() => {
|
2721
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2722
|
-
layout: [],
|
2723
|
-
metadatas: {},
|
2724
|
-
options: {},
|
2725
|
-
settings: DEFAULT_SETTINGS
|
2726
|
-
};
|
2727
|
-
}, [data, isLoading, schemas, schema, components]);
|
2728
|
-
const { layout: edit } = React.useMemo(
|
2729
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2730
|
-
layout: editLayout,
|
2731
|
-
query
|
2732
|
-
}),
|
2733
|
-
[editLayout, query, runHookWaterfall]
|
2734
|
-
);
|
2735
|
-
return {
|
2736
|
-
error,
|
2737
|
-
isLoading,
|
2738
|
-
edit,
|
2739
|
-
list: listLayout
|
2740
2785
|
};
|
2741
|
-
|
2742
|
-
|
2743
|
-
|
2744
|
-
return
|
2745
|
-
|
2746
|
-
|
2747
|
-
|
2748
|
-
|
2749
|
-
|
2750
|
-
|
2751
|
-
|
2752
|
-
|
2753
|
-
|
2754
|
-
|
2755
|
-
|
2756
|
-
|
2757
|
-
schemas
|
2758
|
-
).reduce((panels, row) => {
|
2759
|
-
if (row.some((field) => field.type === "dynamiczone")) {
|
2760
|
-
panels.push([row]);
|
2761
|
-
currentPanelIndex += 2;
|
2786
|
+
const handleClose = () => {
|
2787
|
+
setDialogId(null);
|
2788
|
+
};
|
2789
|
+
return /* @__PURE__ */ jsx(Flex, { gap: 1, children: actions2.map((action) => {
|
2790
|
+
if (action.options) {
|
2791
|
+
return /* @__PURE__ */ jsx(
|
2792
|
+
SingleSelect,
|
2793
|
+
{
|
2794
|
+
size: "S",
|
2795
|
+
onChange: action.onSelect,
|
2796
|
+
"aria-label": action.label,
|
2797
|
+
...action,
|
2798
|
+
children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsx(SingleSelectOption, { ...option, children: label }, option.value))
|
2799
|
+
},
|
2800
|
+
action.id
|
2801
|
+
);
|
2762
2802
|
} else {
|
2763
|
-
if (
|
2764
|
-
|
2803
|
+
if (action.type === "icon") {
|
2804
|
+
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
2805
|
+
/* @__PURE__ */ jsx(
|
2806
|
+
IconButton,
|
2807
|
+
{
|
2808
|
+
disabled: action.disabled,
|
2809
|
+
label: action.label,
|
2810
|
+
size: "S",
|
2811
|
+
onClick: handleClick(action),
|
2812
|
+
children: action.icon
|
2813
|
+
}
|
2814
|
+
),
|
2815
|
+
action.dialog ? /* @__PURE__ */ jsx(
|
2816
|
+
HeaderActionDialog,
|
2817
|
+
{
|
2818
|
+
...action.dialog,
|
2819
|
+
isOpen: dialogId === action.id,
|
2820
|
+
onClose: handleClose
|
2821
|
+
}
|
2822
|
+
) : null
|
2823
|
+
] }, action.id);
|
2765
2824
|
}
|
2766
|
-
panels[currentPanelIndex].push(row);
|
2767
2825
|
}
|
2768
|
-
|
2769
|
-
|
2770
|
-
|
2771
|
-
|
2772
|
-
|
2773
|
-
|
2774
|
-
|
2775
|
-
|
2776
|
-
|
2777
|
-
|
2778
|
-
|
2779
|
-
|
2780
|
-
|
2781
|
-
|
2782
|
-
|
2783
|
-
|
2784
|
-
|
2785
|
-
}
|
2786
|
-
|
2787
|
-
|
2788
|
-
|
2789
|
-
|
2790
|
-
|
2791
|
-
|
2792
|
-
|
2793
|
-
|
2826
|
+
}) });
|
2827
|
+
};
|
2828
|
+
const HeaderActionDialog = ({
|
2829
|
+
onClose,
|
2830
|
+
onCancel,
|
2831
|
+
title,
|
2832
|
+
content: Content,
|
2833
|
+
isOpen
|
2834
|
+
}) => {
|
2835
|
+
const handleClose = async () => {
|
2836
|
+
if (onCancel) {
|
2837
|
+
await onCancel();
|
2838
|
+
}
|
2839
|
+
onClose();
|
2840
|
+
};
|
2841
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
2842
|
+
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
2843
|
+
typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : Content
|
2844
|
+
] }) });
|
2845
|
+
};
|
2846
|
+
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
2847
|
+
const navigate = useNavigate();
|
2848
|
+
const { formatMessage } = useIntl();
|
2849
|
+
return {
|
2850
|
+
label: formatMessage({
|
2851
|
+
id: "app.links.configure-view",
|
2852
|
+
defaultMessage: "Configure the view"
|
2853
|
+
}),
|
2854
|
+
icon: /* @__PURE__ */ jsx(ListPlus, {}),
|
2855
|
+
onClick: () => {
|
2856
|
+
navigate(`../${collectionType}/${model}/configurations/edit`);
|
2794
2857
|
},
|
2795
|
-
|
2796
|
-
|
2858
|
+
position: "header"
|
2859
|
+
};
|
2860
|
+
};
|
2861
|
+
ConfigureTheViewAction.type = "configure-the-view";
|
2862
|
+
const EditTheModelAction = ({ model }) => {
|
2863
|
+
const navigate = useNavigate();
|
2864
|
+
const { formatMessage } = useIntl();
|
2797
2865
|
return {
|
2798
|
-
|
2799
|
-
|
2800
|
-
|
2801
|
-
|
2802
|
-
|
2803
|
-
|
2866
|
+
label: formatMessage({
|
2867
|
+
id: "content-manager.link-to-ctb",
|
2868
|
+
defaultMessage: "Edit the model"
|
2869
|
+
}),
|
2870
|
+
icon: /* @__PURE__ */ jsx(Pencil, {}),
|
2871
|
+
onClick: () => {
|
2872
|
+
navigate(`/plugins/content-type-builder/content-types/${model}`);
|
2804
2873
|
},
|
2805
|
-
|
2806
|
-
...schema?.options,
|
2807
|
-
...schema?.pluginOptions,
|
2808
|
-
...data.contentType.options
|
2809
|
-
}
|
2874
|
+
position: "header"
|
2810
2875
|
};
|
2811
2876
|
};
|
2812
|
-
|
2813
|
-
|
2814
|
-
|
2815
|
-
|
2816
|
-
|
2817
|
-
|
2877
|
+
EditTheModelAction.type = "edit-the-model";
|
2878
|
+
const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
2879
|
+
const navigate = useNavigate();
|
2880
|
+
const { formatMessage } = useIntl();
|
2881
|
+
const listViewPathMatch = useMatch(LIST_PATH);
|
2882
|
+
const canDelete = useDocumentRBAC("DeleteAction", (state) => state.canDelete);
|
2883
|
+
const { delete: deleteAction } = useDocumentActions();
|
2884
|
+
const { toggleNotification } = useNotification();
|
2885
|
+
const setSubmitting = useForm("DeleteAction", (state) => state.setSubmitting);
|
2886
|
+
const isLocalized = document?.locale != null;
|
2887
|
+
return {
|
2888
|
+
disabled: !canDelete || !document,
|
2889
|
+
label: formatMessage(
|
2890
|
+
{
|
2891
|
+
id: "content-manager.actions.delete.label",
|
2892
|
+
defaultMessage: "Delete entry{isLocalized, select, true { (all locales)} other {}}"
|
2893
|
+
},
|
2894
|
+
{ isLocalized }
|
2895
|
+
),
|
2896
|
+
icon: /* @__PURE__ */ jsx(Trash, {}),
|
2897
|
+
dialog: {
|
2898
|
+
type: "dialog",
|
2899
|
+
title: formatMessage({
|
2900
|
+
id: "app.components.ConfirmDialog.title",
|
2901
|
+
defaultMessage: "Confirmation"
|
2902
|
+
}),
|
2903
|
+
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
|
2904
|
+
/* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
2905
|
+
/* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
2906
|
+
id: "content-manager.actions.delete.dialog.body",
|
2907
|
+
defaultMessage: "Are you sure?"
|
2908
|
+
}) })
|
2909
|
+
] }),
|
2910
|
+
onConfirm: async () => {
|
2911
|
+
if (!listViewPathMatch) {
|
2912
|
+
setSubmitting(true);
|
2913
|
+
}
|
2914
|
+
try {
|
2915
|
+
if (!documentId && collectionType !== SINGLE_TYPES) {
|
2916
|
+
console.error(
|
2917
|
+
"You're trying to delete a document without an id, this is likely a bug with Strapi. Please open an issue."
|
2918
|
+
);
|
2919
|
+
toggleNotification({
|
2920
|
+
message: formatMessage({
|
2921
|
+
id: "content-manager.actions.delete.error",
|
2922
|
+
defaultMessage: "An error occurred while trying to delete the document."
|
2923
|
+
}),
|
2924
|
+
type: "danger"
|
2925
|
+
});
|
2926
|
+
return;
|
2927
|
+
}
|
2928
|
+
const res = await deleteAction({
|
2929
|
+
documentId,
|
2930
|
+
model,
|
2931
|
+
collectionType,
|
2932
|
+
params: {
|
2933
|
+
locale: "*"
|
2934
|
+
}
|
2935
|
+
});
|
2936
|
+
if (!("error" in res)) {
|
2937
|
+
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
2938
|
+
}
|
2939
|
+
} finally {
|
2940
|
+
if (!listViewPathMatch) {
|
2941
|
+
setSubmitting(false);
|
2942
|
+
}
|
2943
|
+
}
|
2818
2944
|
}
|
2819
|
-
const { edit: metadata } = metadatas[field.name];
|
2820
|
-
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
2821
|
-
return {
|
2822
|
-
attribute,
|
2823
|
-
disabled: !metadata.editable,
|
2824
|
-
hint: metadata.description,
|
2825
|
-
label: metadata.label ?? "",
|
2826
|
-
name: field.name,
|
2827
|
-
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
2828
|
-
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
2829
|
-
schemas,
|
2830
|
-
components: components?.schemas ?? {}
|
2831
|
-
}),
|
2832
|
-
placeholder: metadata.placeholder ?? "",
|
2833
|
-
required: attribute.required ?? false,
|
2834
|
-
size: field.size,
|
2835
|
-
unique: "unique" in attribute ? attribute.unique : false,
|
2836
|
-
visible: metadata.visible ?? true,
|
2837
|
-
type: attribute.type
|
2838
|
-
};
|
2839
|
-
}).filter((field) => field !== null)
|
2840
|
-
);
|
2841
|
-
};
|
2842
|
-
const formatListLayout = (data, {
|
2843
|
-
schemas,
|
2844
|
-
schema,
|
2845
|
-
components
|
2846
|
-
}) => {
|
2847
|
-
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2848
|
-
(acc, [attribute, metadata]) => {
|
2849
|
-
return {
|
2850
|
-
...acc,
|
2851
|
-
[attribute]: metadata.list
|
2852
|
-
};
|
2853
2945
|
},
|
2854
|
-
|
2855
|
-
|
2856
|
-
|
2857
|
-
|
2858
|
-
|
2859
|
-
|
2860
|
-
|
2861
|
-
|
2862
|
-
|
2863
|
-
|
2864
|
-
|
2865
|
-
|
2866
|
-
|
2867
|
-
|
2868
|
-
|
2869
|
-
|
2870
|
-
|
2946
|
+
variant: "danger",
|
2947
|
+
position: ["header", "table-row"]
|
2948
|
+
};
|
2949
|
+
};
|
2950
|
+
DeleteAction$1.type = "delete";
|
2951
|
+
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2952
|
+
const Panels = () => {
|
2953
|
+
const isCloning = useMatch(CLONE_PATH) !== null;
|
2954
|
+
const [
|
2955
|
+
{
|
2956
|
+
query: { status }
|
2957
|
+
}
|
2958
|
+
] = useQueryParams({
|
2959
|
+
status: "draft"
|
2960
|
+
});
|
2961
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
2962
|
+
const plugins = useStrapiApp("Panels", (state) => state.plugins);
|
2963
|
+
const props = {
|
2964
|
+
activeTab: status,
|
2965
|
+
model,
|
2966
|
+
documentId: id,
|
2967
|
+
document: isCloning ? void 0 : document,
|
2968
|
+
meta: isCloning ? void 0 : meta,
|
2969
|
+
collectionType
|
2970
|
+
};
|
2971
|
+
return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsx(
|
2972
|
+
DescriptionComponentRenderer,
|
2973
|
+
{
|
2974
|
+
props,
|
2975
|
+
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2976
|
+
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsx(Panel, { ...description, children: content }, id2))
|
2871
2977
|
}
|
2978
|
+
) });
|
2979
|
+
};
|
2980
|
+
const ActionsPanel = () => {
|
2981
|
+
const { formatMessage } = useIntl();
|
2982
|
+
return {
|
2983
|
+
title: formatMessage({
|
2984
|
+
id: "content-manager.containers.edit.panels.default.title",
|
2985
|
+
defaultMessage: "Entry"
|
2986
|
+
}),
|
2987
|
+
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2872
2988
|
};
|
2873
2989
|
};
|
2874
|
-
|
2875
|
-
|
2876
|
-
|
2877
|
-
|
2878
|
-
|
2990
|
+
ActionsPanel.type = "actions";
|
2991
|
+
const ActionsPanelContent = () => {
|
2992
|
+
const isCloning = useMatch(CLONE_PATH) !== null;
|
2993
|
+
const [
|
2994
|
+
{
|
2995
|
+
query: { status = "draft" }
|
2879
2996
|
}
|
2880
|
-
|
2881
|
-
|
2882
|
-
|
2883
|
-
|
2884
|
-
|
2885
|
-
|
2886
|
-
|
2887
|
-
|
2888
|
-
|
2889
|
-
|
2890
|
-
|
2891
|
-
|
2892
|
-
|
2893
|
-
|
2997
|
+
] = useQueryParams();
|
2998
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
2999
|
+
const plugins = useStrapiApp("ActionsPanel", (state) => state.plugins);
|
3000
|
+
const props = {
|
3001
|
+
activeTab: status,
|
3002
|
+
model,
|
3003
|
+
documentId: id,
|
3004
|
+
document: isCloning ? void 0 : document,
|
3005
|
+
meta: isCloning ? void 0 : meta,
|
3006
|
+
collectionType
|
3007
|
+
};
|
3008
|
+
return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
|
3009
|
+
/* @__PURE__ */ jsx(
|
3010
|
+
DescriptionComponentRenderer,
|
3011
|
+
{
|
3012
|
+
props,
|
3013
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3014
|
+
children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
|
3015
|
+
}
|
3016
|
+
),
|
3017
|
+
/* @__PURE__ */ jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
3018
|
+
] });
|
2894
3019
|
};
|
3020
|
+
const Panel = React.forwardRef(({ children, title }, ref) => {
|
3021
|
+
return /* @__PURE__ */ jsxs(
|
3022
|
+
Flex,
|
3023
|
+
{
|
3024
|
+
ref,
|
3025
|
+
tag: "aside",
|
3026
|
+
"aria-labelledby": "additional-information",
|
3027
|
+
background: "neutral0",
|
3028
|
+
borderColor: "neutral150",
|
3029
|
+
hasRadius: true,
|
3030
|
+
paddingBottom: 4,
|
3031
|
+
paddingLeft: 4,
|
3032
|
+
paddingRight: 4,
|
3033
|
+
paddingTop: 4,
|
3034
|
+
shadow: "tableShadow",
|
3035
|
+
gap: 3,
|
3036
|
+
direction: "column",
|
3037
|
+
justifyContent: "stretch",
|
3038
|
+
alignItems: "flex-start",
|
3039
|
+
children: [
|
3040
|
+
/* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
3041
|
+
children
|
3042
|
+
]
|
3043
|
+
}
|
3044
|
+
);
|
3045
|
+
});
|
2895
3046
|
const ConfirmBulkActionDialog = ({
|
2896
3047
|
onToggleDialog,
|
2897
3048
|
isOpen = false,
|
@@ -2930,6 +3081,7 @@ const ConfirmDialogPublishAll = ({
|
|
2930
3081
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(getTranslation);
|
2931
3082
|
const { model, schema } = useDoc();
|
2932
3083
|
const [{ query }] = useQueryParams();
|
3084
|
+
const enableDraftRelationsCount = false;
|
2933
3085
|
const {
|
2934
3086
|
data: countDraftRelations = 0,
|
2935
3087
|
isLoading,
|
@@ -2941,7 +3093,7 @@ const ConfirmDialogPublishAll = ({
|
|
2941
3093
|
locale: query?.plugins?.i18n?.locale
|
2942
3094
|
},
|
2943
3095
|
{
|
2944
|
-
skip:
|
3096
|
+
skip: !enableDraftRelationsCount
|
2945
3097
|
}
|
2946
3098
|
);
|
2947
3099
|
React.useEffect(() => {
|
@@ -3126,7 +3278,7 @@ const SelectedEntriesTableContent = ({
|
|
3126
3278
|
status: row.status
|
3127
3279
|
}
|
3128
3280
|
) }),
|
3129
|
-
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(
|
3281
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
|
3130
3282
|
IconButton,
|
3131
3283
|
{
|
3132
3284
|
tag: Link,
|
@@ -3149,9 +3301,10 @@ const SelectedEntriesTableContent = ({
|
|
3149
3301
|
),
|
3150
3302
|
target: "_blank",
|
3151
3303
|
marginLeft: "auto",
|
3152
|
-
|
3304
|
+
variant: "ghost",
|
3305
|
+
children: /* @__PURE__ */ jsx(Pencil, { width: "1.6rem", height: "1.6rem" })
|
3153
3306
|
}
|
3154
|
-
) })
|
3307
|
+
) }) })
|
3155
3308
|
] }, row.id)) })
|
3156
3309
|
] });
|
3157
3310
|
};
|
@@ -3188,7 +3341,13 @@ const SelectedEntriesModalContent = ({
|
|
3188
3341
|
);
|
3189
3342
|
const { rows, validationErrors } = React.useMemo(() => {
|
3190
3343
|
if (data.length > 0 && schema) {
|
3191
|
-
const validate = createYupSchema(
|
3344
|
+
const validate = createYupSchema(
|
3345
|
+
schema.attributes,
|
3346
|
+
components,
|
3347
|
+
// Since this is the "Publish" action, the validation
|
3348
|
+
// schema must enforce the rules for published entities
|
3349
|
+
{ status: "published" }
|
3350
|
+
);
|
3192
3351
|
const validationErrors2 = {};
|
3193
3352
|
const rows2 = data.map((entry) => {
|
3194
3353
|
try {
|
@@ -3538,7 +3697,7 @@ const TableActions = ({ document }) => {
|
|
3538
3697
|
DescriptionComponentRenderer,
|
3539
3698
|
{
|
3540
3699
|
props,
|
3541
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3700
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
3542
3701
|
children: (actions2) => {
|
3543
3702
|
const tableRowActions = actions2.filter((action) => {
|
3544
3703
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3649,7 +3808,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3649
3808
|
}),
|
3650
3809
|
content: /* @__PURE__ */ jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
3651
3810
|
footer: ({ onClose }) => {
|
3652
|
-
return /* @__PURE__ */ jsxs(
|
3811
|
+
return /* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
3653
3812
|
/* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
3654
3813
|
id: "cancel",
|
3655
3814
|
defaultMessage: "Cancel"
|
@@ -3880,7 +4039,7 @@ const index = {
|
|
3880
4039
|
app.router.addRoute({
|
3881
4040
|
path: "content-manager/*",
|
3882
4041
|
lazy: async () => {
|
3883
|
-
const { Layout } = await import("./layout-
|
4042
|
+
const { Layout } = await import("./layout-aX-RJhd5.mjs");
|
3884
4043
|
return {
|
3885
4044
|
Component: Layout
|
3886
4045
|
};
|
@@ -3897,7 +4056,7 @@ const index = {
|
|
3897
4056
|
async registerTrads({ locales }) {
|
3898
4057
|
const importedTrads = await Promise.all(
|
3899
4058
|
locales.map((locale) => {
|
3900
|
-
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-
|
4059
|
+
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-DKV44jRb.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 }) => {
|
3901
4060
|
return {
|
3902
4061
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3903
4062
|
locale
|
@@ -3918,13 +4077,15 @@ export {
|
|
3918
4077
|
BulkActionsRenderer as B,
|
3919
4078
|
COLLECTION_TYPES as C,
|
3920
4079
|
DocumentStatus as D,
|
3921
|
-
|
3922
|
-
|
3923
|
-
|
4080
|
+
extractContentTypeComponents as E,
|
4081
|
+
DEFAULT_SETTINGS as F,
|
4082
|
+
convertEditLayoutToFieldLayouts as G,
|
3924
4083
|
HOOKS as H,
|
3925
4084
|
InjectionZone as I,
|
3926
|
-
|
3927
|
-
|
4085
|
+
useDocument as J,
|
4086
|
+
index as K,
|
4087
|
+
useContentManagerContext as L,
|
4088
|
+
useDocumentActions as M,
|
3928
4089
|
Panels as P,
|
3929
4090
|
RelativeTime as R,
|
3930
4091
|
SINGLE_TYPES as S,
|
@@ -3942,18 +4103,18 @@ export {
|
|
3942
4103
|
PERMISSIONS as k,
|
3943
4104
|
DocumentRBAC as l,
|
3944
4105
|
DOCUMENT_META_FIELDS as m,
|
3945
|
-
|
3946
|
-
|
3947
|
-
|
3948
|
-
|
3949
|
-
|
4106
|
+
CLONE_PATH as n,
|
4107
|
+
useDocLayout as o,
|
4108
|
+
useGetContentTypeConfigurationQuery as p,
|
4109
|
+
CREATOR_FIELDS as q,
|
4110
|
+
getMainField as r,
|
3950
4111
|
setInitialData as s,
|
3951
|
-
|
4112
|
+
getDisplayName as t,
|
3952
4113
|
useContentTypeSchema as u,
|
3953
|
-
|
3954
|
-
|
3955
|
-
|
3956
|
-
|
3957
|
-
|
4114
|
+
checkIfAttributeIsDisplayable as v,
|
4115
|
+
useGetAllDocumentsQuery as w,
|
4116
|
+
convertListLayoutToFieldLayouts as x,
|
4117
|
+
capitalise as y,
|
4118
|
+
useUpdateContentTypeConfigurationMutation as z
|
3958
4119
|
};
|
3959
|
-
//# sourceMappingURL=index-
|
4120
|
+
//# sourceMappingURL=index-TaRzG09p.mjs.map
|