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