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