@akemona-org/strapi-plugin-content-type-builder 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +19 -0
- package/admin/src/InjectedComponents/ContentManager/EditSettingViewButton.js +76 -0
- package/admin/src/InjectedComponents/ContentManager/EditViewLink.js +44 -0
- package/admin/src/assets/images/logo.svg +1 -0
- package/admin/src/components/AllowedTypesSelect/MenuList.js +115 -0
- package/admin/src/components/AllowedTypesSelect/Text.js +26 -0
- package/admin/src/components/AllowedTypesSelect/index.js +55 -0
- package/admin/src/components/AttributeOption/Button.js +50 -0
- package/admin/src/components/AttributeOption/Card.js +26 -0
- package/admin/src/components/AttributeOption/index.js +127 -0
- package/admin/src/components/BooleanBox/CT.js +21 -0
- package/admin/src/components/BooleanBox/Enumeration.js +10 -0
- package/admin/src/components/BooleanBox/EnumerationWrapper.js +14 -0
- package/admin/src/components/BooleanBox/Label.js +9 -0
- package/admin/src/components/BooleanBox/ST.js +21 -0
- package/admin/src/components/BooleanBox/Wrapper.js +75 -0
- package/admin/src/components/BooleanBox/icons/CTSelected.js +136 -0
- package/admin/src/components/BooleanBox/icons/CTUnselected.js +136 -0
- package/admin/src/components/BooleanBox/icons/STSelected.js +80 -0
- package/admin/src/components/BooleanBox/icons/STUnselected.js +76 -0
- package/admin/src/components/BooleanBox/index.js +103 -0
- package/admin/src/components/CheckboxWithDescription/Wrapper.js +12 -0
- package/admin/src/components/CheckboxWithDescription/index.js +40 -0
- package/admin/src/components/ComponentCard/Close.js +12 -0
- package/admin/src/components/ComponentCard/Wrapper.js +84 -0
- package/admin/src/components/ComponentCard/index.js +62 -0
- package/admin/src/components/ComponentIconPicker/Cell.js +40 -0
- package/admin/src/components/ComponentIconPicker/CellRenderer.js +36 -0
- package/admin/src/components/ComponentIconPicker/Search.js +12 -0
- package/admin/src/components/ComponentIconPicker/SearchWrapper.js +34 -0
- package/admin/src/components/ComponentIconPicker/Wrapper.js +60 -0
- package/admin/src/components/ComponentIconPicker/index.js +143 -0
- package/admin/src/components/ComponentList/index.js +78 -0
- package/admin/src/components/ComponentSelect/Category.js +20 -0
- package/admin/src/components/ComponentSelect/CategoryName.js +11 -0
- package/admin/src/components/ComponentSelect/MenuList.js +110 -0
- package/admin/src/components/ComponentSelect/MultipleMenuList.js +271 -0
- package/admin/src/components/ComponentSelect/Value.js +83 -0
- package/admin/src/components/ComponentSelect/index.js +83 -0
- package/admin/src/components/ComponentSelect/utils/HasSomeSubArray.js +5 -0
- package/admin/src/components/ComponentSelect/utils/hasSubArray.js +5 -0
- package/admin/src/components/CreatableSelect/index.js +58 -0
- package/admin/src/components/CustomCheckbox/StyledCustomCheckbox.js +25 -0
- package/admin/src/components/CustomCheckbox/index.js +71 -0
- package/admin/src/components/CustomLink/P.js +17 -0
- package/admin/src/components/CustomLink/StyledCustomLink.js +20 -0
- package/admin/src/components/CustomLink/index.js +31 -0
- package/admin/src/components/DynamicZoneList/ComponentButton.js +39 -0
- package/admin/src/components/DynamicZoneList/index.js +124 -0
- package/admin/src/components/HeaderModalNavContainer/index.js +25 -0
- package/admin/src/components/HeaderNavLink/Wrapper.js +21 -0
- package/admin/src/components/HeaderNavLink/index.js +50 -0
- package/admin/src/components/List/List.js +131 -0
- package/admin/src/components/List/index.js +295 -0
- package/admin/src/components/ListButton/index.js +9 -0
- package/admin/src/components/ListHeader/Title.js +19 -0
- package/admin/src/components/ListHeader/Wrapper.js +24 -0
- package/admin/src/components/ListHeader/index.js +37 -0
- package/admin/src/components/ListRow/Wrapper.js +76 -0
- package/admin/src/components/ListRow/index.js +334 -0
- package/admin/src/components/ModalHeader/ComponentIcon.js +21 -0
- package/admin/src/components/ModalHeader/ComponentInfos.js +22 -0
- package/admin/src/components/ModalHeader/ComponentInfosWrapper.js +9 -0
- package/admin/src/components/ModalHeader/DropdownInfos.js +50 -0
- package/admin/src/components/ModalHeader/Icon.js +26 -0
- package/admin/src/components/ModalHeader/IconWrapper.js +11 -0
- package/admin/src/components/ModalHeader/Item.js +19 -0
- package/admin/src/components/ModalHeader/Menu.js +8 -0
- package/admin/src/components/ModalHeader/Toggle.js +14 -0
- package/admin/src/components/ModalHeader/Wrapper.js +12 -0
- package/admin/src/components/ModalHeader/index.js +105 -0
- package/admin/src/components/RelationForm/Wrapper.js +9 -0
- package/admin/src/components/RelationForm/index.js +66 -0
- package/admin/src/components/RelationFormBox/Wrapper.js +34 -0
- package/admin/src/components/RelationFormBox/index.js +85 -0
- package/admin/src/components/RelationFormNaturePicker/Wrapper.js +53 -0
- package/admin/src/components/RelationFormNaturePicker/index.js +112 -0
- package/admin/src/components/RelationTargetPicker/Item.js +62 -0
- package/admin/src/components/RelationTargetPicker/Wrapper.js +89 -0
- package/admin/src/components/RelationTargetPicker/index.js +88 -0
- package/admin/src/components/SelectCheckbox/index.js +8 -0
- package/admin/src/components/SelectMenuSubUl/ToggleUl.js +23 -0
- package/admin/src/components/SelectMenuSubUl/index.js +23 -0
- package/admin/src/components/SelectMenuUl/index.js +66 -0
- package/admin/src/components/Td/index.js +37 -0
- package/admin/src/components/UpperFirst/index.js +14 -0
- package/admin/src/components/WrapperSelect/index.js +89 -0
- package/admin/src/containers/App/Wrapper.js +14 -0
- package/admin/src/containers/App/index.js +39 -0
- package/admin/src/containers/App/utils/icons.json +962 -0
- package/admin/src/containers/DataManagerProvider/constants.js +15 -0
- package/admin/src/containers/DataManagerProvider/index.js +610 -0
- package/admin/src/containers/DataManagerProvider/reducer.js +461 -0
- package/admin/src/containers/DataManagerProvider/selectors.js +25 -0
- package/admin/src/containers/DataManagerProvider/utils/cleanData.js +167 -0
- package/admin/src/containers/DataManagerProvider/utils/createDataObject.js +8 -0
- package/admin/src/containers/DataManagerProvider/utils/createModifiedDataSchema.js +91 -0
- package/admin/src/containers/DataManagerProvider/utils/retrieveComponentsFromSchema.js +55 -0
- package/admin/src/containers/DataManagerProvider/utils/retrieveComponentsThatHaveComponents.js +35 -0
- package/admin/src/containers/DataManagerProvider/utils/retrieveNestedComponents.js +34 -0
- package/admin/src/containers/DataManagerProvider/utils/retrieveSpecificInfoFromComponents.js +12 -0
- package/admin/src/containers/FormModal/CustomButton.js +12 -0
- package/admin/src/containers/FormModal/attributes/advancedForm.js +269 -0
- package/admin/src/containers/FormModal/attributes/attributeOptions.js +99 -0
- package/admin/src/containers/FormModal/attributes/baseForm.js +322 -0
- package/admin/src/containers/FormModal/attributes/commonBaseForm.js +7 -0
- package/admin/src/containers/FormModal/attributes/form.js +9 -0
- package/admin/src/containers/FormModal/attributes/index.js +4 -0
- package/admin/src/containers/FormModal/attributes/nameField.js +19 -0
- package/admin/src/containers/FormModal/attributes/types.js +309 -0
- package/admin/src/containers/FormModal/attributes/uiHelpers.js +11 -0
- package/admin/src/containers/FormModal/attributes/validation/common.js +151 -0
- package/admin/src/containers/FormModal/category/createCategorySchema.js +28 -0
- package/admin/src/containers/FormModal/category/form.js +27 -0
- package/admin/src/containers/FormModal/category/index.js +3 -0
- package/admin/src/containers/FormModal/category/regex.js +3 -0
- package/admin/src/containers/FormModal/component/componentField.js +25 -0
- package/admin/src/containers/FormModal/component/createComponentSchema.js +49 -0
- package/admin/src/containers/FormModal/component/form.js +67 -0
- package/admin/src/containers/FormModal/component/index.js +4 -0
- package/admin/src/containers/FormModal/constants.js +11 -0
- package/admin/src/containers/FormModal/contentType/createContentTypeSchema.js +44 -0
- package/admin/src/containers/FormModal/contentType/form.js +116 -0
- package/admin/src/containers/FormModal/contentType/index.js +2 -0
- package/admin/src/containers/FormModal/dynamicZone/form.js +45 -0
- package/admin/src/containers/FormModal/dynamicZone/index.js +2 -0
- package/admin/src/containers/FormModal/forms/index.js +164 -0
- package/admin/src/containers/FormModal/index.js +1552 -0
- package/admin/src/containers/FormModal/reducer.js +293 -0
- package/admin/src/containers/FormModal/selectors.js +24 -0
- package/admin/src/containers/FormModal/utils/canEditContentType.js +19 -0
- package/admin/src/containers/FormModal/utils/createHeadersArray.js +37 -0
- package/admin/src/containers/FormModal/utils/createHeadersObjectFromArray.js +27 -0
- package/admin/src/containers/FormModal/utils/createUid.js +17 -0
- package/admin/src/containers/FormModal/utils/getAttributesToDisplay.js +35 -0
- package/admin/src/containers/FormModal/utils/getModalTitleSubHeader.js +25 -0
- package/admin/src/containers/FormModal/utils/getNextSearch.js +17 -0
- package/admin/src/containers/FormModal/utils/index.js +6 -0
- package/admin/src/containers/FormModal/utils/relations.js +9 -0
- package/admin/src/containers/FormModal/utils/staticData.js +43 -0
- package/admin/src/containers/Initializer/index.js +26 -0
- package/admin/src/containers/LeftMenu/Wrapper.js +14 -0
- package/admin/src/containers/LeftMenu/index.js +220 -0
- package/admin/src/containers/ListView/Wrapper.js +16 -0
- package/admin/src/containers/ListView/index.js +322 -0
- package/admin/src/containers/NotFoundPage/index.js +20 -0
- package/admin/src/containers/RecursivePath/index.js +22 -0
- package/admin/src/contexts/DataManagerContext.js +5 -0
- package/admin/src/contexts/ListViewContext.js +5 -0
- package/admin/src/hooks/useDataManager.js +6 -0
- package/admin/src/hooks/useListView.js +6 -0
- package/admin/src/icons/Curve.js +26 -0
- package/admin/src/icons/ManyToMany.js +98 -0
- package/admin/src/icons/ManyToOne.js +64 -0
- package/admin/src/icons/ManyWay.js +36 -0
- package/admin/src/icons/OneToMany.js +65 -0
- package/admin/src/icons/OneToOne.js +47 -0
- package/admin/src/icons/OneWay.js +38 -0
- package/admin/src/index.js +83 -0
- package/admin/src/lifecycles.js +13 -0
- package/admin/src/permissions.js +9 -0
- package/admin/src/pluginId.js +5 -0
- package/admin/src/reducers.js +10 -0
- package/admin/src/translations/ar.json +48 -0
- package/admin/src/translations/cs.json +151 -0
- package/admin/src/translations/de.json +187 -0
- package/admin/src/translations/dk.json +181 -0
- package/admin/src/translations/en.json +188 -0
- package/admin/src/translations/es.json +188 -0
- package/admin/src/translations/fr.json +87 -0
- package/admin/src/translations/id.json +187 -0
- package/admin/src/translations/index.js +51 -0
- package/admin/src/translations/it.json +187 -0
- package/admin/src/translations/ja.json +50 -0
- package/admin/src/translations/ko.json +57 -0
- package/admin/src/translations/ms.json +179 -0
- package/admin/src/translations/nl.json +171 -0
- package/admin/src/translations/pl.json +152 -0
- package/admin/src/translations/pt-BR.json +51 -0
- package/admin/src/translations/pt.json +51 -0
- package/admin/src/translations/ru.json +188 -0
- package/admin/src/translations/sk.json +186 -0
- package/admin/src/translations/th.json +181 -0
- package/admin/src/translations/tr.json +51 -0
- package/admin/src/translations/uk.json +180 -0
- package/admin/src/translations/zh-Hans.json +188 -0
- package/admin/src/translations/zh.json +178 -0
- package/admin/src/utils/convertAttrObjToArray.js +7 -0
- package/admin/src/utils/formAPI.js +112 -0
- package/admin/src/utils/getAttributeDisplayedType.js +31 -0
- package/admin/src/utils/getComponents.js +31 -0
- package/admin/src/utils/getTrad.js +5 -0
- package/admin/src/utils/makeSearch.js +15 -0
- package/admin/src/utils/makeUnique.js +3 -0
- package/config/functions/bootstrap.js +14 -0
- package/config/routes.json +144 -0
- package/controllers/Builder.js +7 -0
- package/controllers/ComponentCategories.js +43 -0
- package/controllers/Components.js +152 -0
- package/controllers/Connections.js +9 -0
- package/controllers/ContentTypes.js +143 -0
- package/controllers/validation/common.js +118 -0
- package/controllers/validation/component-category.js +21 -0
- package/controllers/validation/component.js +89 -0
- package/controllers/validation/content-type.js +161 -0
- package/controllers/validation/data-transform.js +32 -0
- package/controllers/validation/model-schema.js +91 -0
- package/controllers/validation/relations.js +56 -0
- package/controllers/validation/types.js +277 -0
- package/package.json +63 -0
- package/services/Builder.js +7 -0
- package/services/ComponentCategories.js +88 -0
- package/services/Components.js +103 -0
- package/services/ContentTypes.js +263 -0
- package/services/api-handler.js +158 -0
- package/services/constants.js +59 -0
- package/services/schema-builder/component-builder.js +137 -0
- package/services/schema-builder/content-type-builder.js +256 -0
- package/services/schema-builder/index.js +196 -0
- package/services/schema-builder/schema-handler.js +297 -0
- package/utils/attributes.js +154 -0
- package/utils/helpers.js +31 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const ADD_ATTRIBUTE = 'ContentTypeBuilder/DataManagerProvider/ADD_ATTRIBUTE';
|
|
2
|
+
export const ADD_CREATED_COMPONENT_TO_DYNAMIC_ZONE = 'ContentTypeBuilder/DataManagerProvider/ADD_CREATED_COMPONENT_TO_DYNAMIC_ZONE';
|
|
3
|
+
export const CANCEL_CHANGES = 'ContentTypeBuilder/DataManagerProvider/CANCEL_CHANGES';
|
|
4
|
+
export const CHANGE_DYNAMIC_ZONE_COMPONENTS = 'ContentTypeBuilder/DataManagerProvider/CHANGE_DYNAMIC_ZONE_COMPONENTS';
|
|
5
|
+
export const CREATE_SCHEMA = 'ContentTypeBuilder/DataManagerProvider/CREATE_SCHEMA';
|
|
6
|
+
export const CREATE_COMPONENT_SCHEMA = 'ContentTypeBuilder/DataManagerProvider/CREATE_COMPONENT_SCHEMA';
|
|
7
|
+
export const DELETE_NOT_SAVED_TYPE = 'ContentTypeBuilder/DataManagerProvider/DELETE_NOT_SAVED_TYPE';
|
|
8
|
+
export const EDIT_ATTRIBUTE = 'ContentTypeBuilder/DataManagerProvider/EDIT_ATTRIBUTE';
|
|
9
|
+
export const GET_DATA_SUCCEEDED = 'ContentTypeBuilder/DataManagerProvider/GET_DATA_SUCCEEDED';
|
|
10
|
+
export const RELOAD_PLUGIN = 'ContentTypeBuilder/DataManagerProvider/RELOAD_PLUGIN';
|
|
11
|
+
export const REMOVE_FIELD_FROM_DISPLAYED_COMPONENT = 'ContentTypeBuilder/DataManagerProvider/REMOVE_FIELD_FROM_DISPLAYED_COMPONENT';
|
|
12
|
+
export const REMOVE_COMPONENT_FROM_DYNAMIC_ZONE = 'ContentTypeBuilder/DataManagerProvider/REMOVE_COMPONENT_FROM_DYNAMIC_ZONE';
|
|
13
|
+
export const REMOVE_FIELD = 'ContentTypeBuilder/DataManagerProvider/REMOVE_FIELD';
|
|
14
|
+
export const SET_MODIFIED_DATA = 'ContentTypeBuilder/DataManagerProvider/SET_MODIFIED_DATA';
|
|
15
|
+
export const UPDATE_SCHEMA = 'ContentTypeBuilder/DataManagerProvider/UPDATE_SCHEMA';
|
|
@@ -0,0 +1,610 @@
|
|
|
1
|
+
import React, { memo, useEffect, useMemo, useState, useRef } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { get, groupBy, set, size } from 'lodash';
|
|
4
|
+
import {
|
|
5
|
+
request,
|
|
6
|
+
LoadingIndicatorPage,
|
|
7
|
+
useGlobalContext,
|
|
8
|
+
PopUpWarning,
|
|
9
|
+
useStrapi,
|
|
10
|
+
useUser,
|
|
11
|
+
} from 'strapi-helper-plugin';
|
|
12
|
+
import { useHistory, useLocation, useRouteMatch, Redirect } from 'react-router-dom';
|
|
13
|
+
import { connect, useDispatch } from 'react-redux';
|
|
14
|
+
import { compose } from 'redux';
|
|
15
|
+
import DataManagerContext from '../../contexts/DataManagerContext';
|
|
16
|
+
import getTrad from '../../utils/getTrad';
|
|
17
|
+
import makeUnique from '../../utils/makeUnique';
|
|
18
|
+
import pluginId from '../../pluginId';
|
|
19
|
+
import FormModal from '../FormModal';
|
|
20
|
+
import createDataObject from './utils/createDataObject';
|
|
21
|
+
import createModifiedDataSchema, {
|
|
22
|
+
orderAllDataAttributesWithImmutable,
|
|
23
|
+
} from './utils/createModifiedDataSchema';
|
|
24
|
+
import retrieveSpecificInfoFromComponents from './utils/retrieveSpecificInfoFromComponents';
|
|
25
|
+
import retrieveComponentsFromSchema from './utils/retrieveComponentsFromSchema';
|
|
26
|
+
import retrieveNestedComponents from './utils/retrieveNestedComponents';
|
|
27
|
+
import { retrieveComponentsThatHaveComponents } from './utils/retrieveComponentsThatHaveComponents';
|
|
28
|
+
import {
|
|
29
|
+
getComponentsToPost,
|
|
30
|
+
formatMainDataType,
|
|
31
|
+
getCreatedAndModifiedComponents,
|
|
32
|
+
sortContentType,
|
|
33
|
+
} from './utils/cleanData';
|
|
34
|
+
|
|
35
|
+
import {
|
|
36
|
+
ADD_ATTRIBUTE,
|
|
37
|
+
ADD_CREATED_COMPONENT_TO_DYNAMIC_ZONE,
|
|
38
|
+
CANCEL_CHANGES,
|
|
39
|
+
CHANGE_DYNAMIC_ZONE_COMPONENTS,
|
|
40
|
+
CREATE_SCHEMA,
|
|
41
|
+
CREATE_COMPONENT_SCHEMA,
|
|
42
|
+
DELETE_NOT_SAVED_TYPE,
|
|
43
|
+
EDIT_ATTRIBUTE,
|
|
44
|
+
GET_DATA_SUCCEEDED,
|
|
45
|
+
RELOAD_PLUGIN,
|
|
46
|
+
REMOVE_FIELD_FROM_DISPLAYED_COMPONENT,
|
|
47
|
+
REMOVE_COMPONENT_FROM_DYNAMIC_ZONE,
|
|
48
|
+
REMOVE_FIELD,
|
|
49
|
+
SET_MODIFIED_DATA,
|
|
50
|
+
UPDATE_SCHEMA,
|
|
51
|
+
} from './constants';
|
|
52
|
+
import makeSelectDataManagerProvider from './selectors';
|
|
53
|
+
|
|
54
|
+
const DataManagerProvider = ({
|
|
55
|
+
allIcons,
|
|
56
|
+
children,
|
|
57
|
+
components,
|
|
58
|
+
contentTypes,
|
|
59
|
+
isLoading,
|
|
60
|
+
isLoadingForDataToBeSet,
|
|
61
|
+
initialData,
|
|
62
|
+
modifiedData,
|
|
63
|
+
reservedNames,
|
|
64
|
+
}) => {
|
|
65
|
+
const dispatch = useDispatch();
|
|
66
|
+
const {
|
|
67
|
+
strapi: { getPlugin },
|
|
68
|
+
} = useStrapi();
|
|
69
|
+
const { apis } = getPlugin(pluginId);
|
|
70
|
+
const [infoModals, toggleInfoModal] = useState({ cancel: false });
|
|
71
|
+
const { autoReload, emitEvent, formatMessage } = useGlobalContext();
|
|
72
|
+
const { fetchUserPermissions } = useUser();
|
|
73
|
+
|
|
74
|
+
const { pathname } = useLocation();
|
|
75
|
+
const { push } = useHistory();
|
|
76
|
+
const contentTypeMatch = useRouteMatch(`/plugins/${pluginId}/content-types/:uid`);
|
|
77
|
+
const componentMatch = useRouteMatch(
|
|
78
|
+
`/plugins/${pluginId}/component-categories/:categoryUid/:componentUid`
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
const formatMessageRef = useRef();
|
|
82
|
+
formatMessageRef.current = formatMessage;
|
|
83
|
+
const isInDevelopmentMode = autoReload;
|
|
84
|
+
|
|
85
|
+
const isInContentTypeView = contentTypeMatch !== null;
|
|
86
|
+
const firstKeyToMainSchema = isInContentTypeView ? 'contentType' : 'component';
|
|
87
|
+
const currentUid = isInContentTypeView
|
|
88
|
+
? get(contentTypeMatch, 'params.uid', null)
|
|
89
|
+
: get(componentMatch, 'params.componentUid', null);
|
|
90
|
+
const abortController = new AbortController();
|
|
91
|
+
const { signal } = abortController;
|
|
92
|
+
const getDataRef = useRef();
|
|
93
|
+
const endPoint = isInContentTypeView ? 'content-types' : 'components';
|
|
94
|
+
|
|
95
|
+
getDataRef.current = async () => {
|
|
96
|
+
try {
|
|
97
|
+
const [
|
|
98
|
+
{ data: componentsArray },
|
|
99
|
+
{ data: contentTypesArray },
|
|
100
|
+
reservedNames,
|
|
101
|
+
] = await Promise.all(
|
|
102
|
+
['components', 'content-types', 'reserved-names'].map(endPoint => {
|
|
103
|
+
return request(`/${pluginId}/${endPoint}`, {
|
|
104
|
+
method: 'GET',
|
|
105
|
+
signal,
|
|
106
|
+
});
|
|
107
|
+
})
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
const components = createDataObject(componentsArray);
|
|
111
|
+
const contentTypes = createDataObject(contentTypesArray);
|
|
112
|
+
const orderedComponents = orderAllDataAttributesWithImmutable({
|
|
113
|
+
components,
|
|
114
|
+
});
|
|
115
|
+
const orderedContenTypes = orderAllDataAttributesWithImmutable({
|
|
116
|
+
components: contentTypes,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
dispatch({
|
|
120
|
+
type: GET_DATA_SUCCEEDED,
|
|
121
|
+
components: orderedComponents.get('components'),
|
|
122
|
+
contentTypes: orderedContenTypes.get('components'),
|
|
123
|
+
reservedNames,
|
|
124
|
+
});
|
|
125
|
+
} catch (err) {
|
|
126
|
+
console.error({ err });
|
|
127
|
+
strapi.notification.toggle({
|
|
128
|
+
type: 'warning',
|
|
129
|
+
message: { id: 'notification.error' },
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
useEffect(() => {
|
|
135
|
+
getDataRef.current();
|
|
136
|
+
}, []);
|
|
137
|
+
|
|
138
|
+
useEffect(() => {
|
|
139
|
+
// We need to set the modifiedData after the data has been retrieved
|
|
140
|
+
// and also on pathname change
|
|
141
|
+
if (!isLoading && currentUid) {
|
|
142
|
+
setModifiedData();
|
|
143
|
+
}
|
|
144
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
145
|
+
}, [isLoading, pathname, currentUid]);
|
|
146
|
+
|
|
147
|
+
useEffect(() => {
|
|
148
|
+
if (!autoReload) {
|
|
149
|
+
strapi.notification.toggle({
|
|
150
|
+
type: 'info',
|
|
151
|
+
message: { id: getTrad('notification.info.autoreaload-disable') },
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}, [autoReload]);
|
|
155
|
+
|
|
156
|
+
const didModifiedComponents =
|
|
157
|
+
getCreatedAndModifiedComponents(modifiedData.components || {}, components).length > 0;
|
|
158
|
+
|
|
159
|
+
const addAttribute = (
|
|
160
|
+
attributeToSet,
|
|
161
|
+
forTarget,
|
|
162
|
+
targetUid,
|
|
163
|
+
isEditing = false,
|
|
164
|
+
initialAttribute,
|
|
165
|
+
shouldAddComponentToData = false
|
|
166
|
+
) => {
|
|
167
|
+
const actionType = isEditing ? EDIT_ATTRIBUTE : ADD_ATTRIBUTE;
|
|
168
|
+
|
|
169
|
+
dispatch({
|
|
170
|
+
type: actionType,
|
|
171
|
+
attributeToSet,
|
|
172
|
+
forTarget,
|
|
173
|
+
targetUid,
|
|
174
|
+
initialAttribute,
|
|
175
|
+
shouldAddComponentToData,
|
|
176
|
+
});
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const addCreatedComponentToDynamicZone = (dynamicZoneTarget, componentsToAdd) => {
|
|
180
|
+
dispatch({
|
|
181
|
+
type: ADD_CREATED_COMPONENT_TO_DYNAMIC_ZONE,
|
|
182
|
+
dynamicZoneTarget,
|
|
183
|
+
componentsToAdd,
|
|
184
|
+
});
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
const cancelChanges = () => {
|
|
188
|
+
toggleModalCancel();
|
|
189
|
+
dispatch({ type: CANCEL_CHANGES });
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
const createSchema = (
|
|
193
|
+
data,
|
|
194
|
+
schemaType,
|
|
195
|
+
uid,
|
|
196
|
+
componentCategory,
|
|
197
|
+
shouldAddComponentToData = false
|
|
198
|
+
) => {
|
|
199
|
+
const type = schemaType === 'contentType' ? CREATE_SCHEMA : CREATE_COMPONENT_SCHEMA;
|
|
200
|
+
|
|
201
|
+
dispatch({
|
|
202
|
+
type,
|
|
203
|
+
data,
|
|
204
|
+
componentCategory,
|
|
205
|
+
schemaType,
|
|
206
|
+
uid,
|
|
207
|
+
shouldAddComponentToData,
|
|
208
|
+
});
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
const changeDynamicZoneComponents = (dynamicZoneTarget, newComponents) => {
|
|
212
|
+
dispatch({
|
|
213
|
+
type: CHANGE_DYNAMIC_ZONE_COMPONENTS,
|
|
214
|
+
dynamicZoneTarget,
|
|
215
|
+
newComponents,
|
|
216
|
+
});
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
const removeAttribute = (mainDataKey, attributeToRemoveName, componentUid = '') => {
|
|
220
|
+
const type =
|
|
221
|
+
mainDataKey === 'components' ? REMOVE_FIELD_FROM_DISPLAYED_COMPONENT : REMOVE_FIELD;
|
|
222
|
+
|
|
223
|
+
if (mainDataKey === 'contentType') {
|
|
224
|
+
emitEvent('willDeleteFieldOfContentType');
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
dispatch({
|
|
228
|
+
type,
|
|
229
|
+
mainDataKey,
|
|
230
|
+
attributeToRemoveName,
|
|
231
|
+
componentUid,
|
|
232
|
+
});
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
const deleteCategory = async categoryUid => {
|
|
236
|
+
try {
|
|
237
|
+
const requestURL = `/${pluginId}/component-categories/${categoryUid}`;
|
|
238
|
+
// eslint-disable-next-line no-alert
|
|
239
|
+
const userConfirm = window.confirm(
|
|
240
|
+
formatMessage({
|
|
241
|
+
id: getTrad('popUpWarning.bodyMessage.category.delete'),
|
|
242
|
+
})
|
|
243
|
+
);
|
|
244
|
+
// Close the modal
|
|
245
|
+
push({ search: '' });
|
|
246
|
+
|
|
247
|
+
if (userConfirm) {
|
|
248
|
+
strapi.lockApp();
|
|
249
|
+
|
|
250
|
+
await request(requestURL, { method: 'DELETE' }, true);
|
|
251
|
+
|
|
252
|
+
await updatePermissions();
|
|
253
|
+
|
|
254
|
+
// Reload the plugin so the cycle is new again
|
|
255
|
+
dispatch({ type: RELOAD_PLUGIN });
|
|
256
|
+
// Refetch all the data
|
|
257
|
+
getDataRef.current();
|
|
258
|
+
}
|
|
259
|
+
} catch (err) {
|
|
260
|
+
console.error({ err });
|
|
261
|
+
strapi.notification.toggle({
|
|
262
|
+
type: 'warning',
|
|
263
|
+
message: { id: 'notification.error' },
|
|
264
|
+
});
|
|
265
|
+
} finally {
|
|
266
|
+
strapi.unlockApp();
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
const deleteData = async () => {
|
|
271
|
+
try {
|
|
272
|
+
const requestURL = `/${pluginId}/${endPoint}/${currentUid}`;
|
|
273
|
+
const isTemporary = get(modifiedData, [firstKeyToMainSchema, 'isTemporary'], false);
|
|
274
|
+
// eslint-disable-next-line no-alert
|
|
275
|
+
const userConfirm = window.confirm(
|
|
276
|
+
formatMessage({
|
|
277
|
+
id: getTrad(
|
|
278
|
+
`popUpWarning.bodyMessage.${isInContentTypeView ? 'contentType' : 'component'}.delete`
|
|
279
|
+
),
|
|
280
|
+
})
|
|
281
|
+
);
|
|
282
|
+
|
|
283
|
+
// Close the modal
|
|
284
|
+
push({ search: '' });
|
|
285
|
+
|
|
286
|
+
if (userConfirm) {
|
|
287
|
+
if (isTemporary) {
|
|
288
|
+
// Delete the not saved type
|
|
289
|
+
// Here we just need to reset the components to the initial ones and also the content types
|
|
290
|
+
// Doing so will trigging a url change since the type doesn't exist in either the contentTypes or the components
|
|
291
|
+
// so the modified and the initial data will also be reset in the useEffect...
|
|
292
|
+
dispatch({ type: DELETE_NOT_SAVED_TYPE });
|
|
293
|
+
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
strapi.lockApp();
|
|
298
|
+
|
|
299
|
+
await request(requestURL, { method: 'DELETE' }, true);
|
|
300
|
+
|
|
301
|
+
// Reload the plugin so the cycle is new again
|
|
302
|
+
dispatch({ type: RELOAD_PLUGIN });
|
|
303
|
+
|
|
304
|
+
// Refetch the permissions
|
|
305
|
+
await updatePermissions();
|
|
306
|
+
|
|
307
|
+
// Refetch all the data
|
|
308
|
+
getDataRef.current();
|
|
309
|
+
}
|
|
310
|
+
} catch (err) {
|
|
311
|
+
console.error({ err });
|
|
312
|
+
strapi.notification.toggle({
|
|
313
|
+
type: 'warning',
|
|
314
|
+
message: { id: 'notification.error' },
|
|
315
|
+
});
|
|
316
|
+
} finally {
|
|
317
|
+
strapi.unlockApp();
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
const editCategory = async (categoryUid, body) => {
|
|
322
|
+
try {
|
|
323
|
+
const requestURL = `/${pluginId}/component-categories/${categoryUid}`;
|
|
324
|
+
|
|
325
|
+
// Close the modal
|
|
326
|
+
push({ search: '' });
|
|
327
|
+
|
|
328
|
+
// Lock the app
|
|
329
|
+
strapi.lockApp();
|
|
330
|
+
|
|
331
|
+
// Update the category
|
|
332
|
+
await request(requestURL, { method: 'PUT', body }, true);
|
|
333
|
+
|
|
334
|
+
await updatePermissions();
|
|
335
|
+
|
|
336
|
+
// Reload the plugin so the cycle is new again
|
|
337
|
+
dispatch({ type: RELOAD_PLUGIN });
|
|
338
|
+
// Refetch all the data
|
|
339
|
+
getDataRef.current();
|
|
340
|
+
} catch (err) {
|
|
341
|
+
console.error({ err });
|
|
342
|
+
strapi.notification.toggle({
|
|
343
|
+
type: 'warning',
|
|
344
|
+
message: { id: 'notification.error' },
|
|
345
|
+
});
|
|
346
|
+
} finally {
|
|
347
|
+
strapi.unlockApp();
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
const getAllComponentsThatHaveAComponentInTheirAttributes = () => {
|
|
352
|
+
// We need to create an object with all the non modified compos
|
|
353
|
+
// plus the ones that are created on the fly
|
|
354
|
+
const allCompos = Object.assign({}, components, modifiedData.components);
|
|
355
|
+
|
|
356
|
+
// Since we apply the modification of a specific component only in the modified data
|
|
357
|
+
// we need to update all compos with the modifications
|
|
358
|
+
if (!isInContentTypeView) {
|
|
359
|
+
const currentEditedCompo = get(modifiedData, 'component', {});
|
|
360
|
+
|
|
361
|
+
set(allCompos, get(currentEditedCompo, ['uid'], ''), currentEditedCompo);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const composWithCompos = retrieveComponentsThatHaveComponents(allCompos);
|
|
365
|
+
|
|
366
|
+
return makeUnique(composWithCompos);
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
const getAllNestedComponents = () => {
|
|
370
|
+
const appNestedCompo = retrieveNestedComponents(components);
|
|
371
|
+
const editingDataNestedCompos = retrieveNestedComponents(modifiedData.components || {});
|
|
372
|
+
|
|
373
|
+
return makeUnique([...editingDataNestedCompos, ...appNestedCompo]);
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
const removeComponentFromDynamicZone = (dzName, componentToRemoveIndex) => {
|
|
377
|
+
dispatch({
|
|
378
|
+
type: REMOVE_COMPONENT_FROM_DYNAMIC_ZONE,
|
|
379
|
+
dzName,
|
|
380
|
+
componentToRemoveIndex,
|
|
381
|
+
});
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
const setModifiedData = () => {
|
|
385
|
+
const currentSchemas = isInContentTypeView ? contentTypes : components;
|
|
386
|
+
const schemaToSet = get(currentSchemas, currentUid, {
|
|
387
|
+
schema: { attributes: {} },
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
const retrievedComponents = retrieveComponentsFromSchema(
|
|
391
|
+
schemaToSet.schema.attributes,
|
|
392
|
+
components
|
|
393
|
+
);
|
|
394
|
+
const newSchemaToSet = createModifiedDataSchema(
|
|
395
|
+
schemaToSet,
|
|
396
|
+
retrievedComponents,
|
|
397
|
+
components,
|
|
398
|
+
isInContentTypeView
|
|
399
|
+
);
|
|
400
|
+
|
|
401
|
+
const dataShape = orderAllDataAttributesWithImmutable(newSchemaToSet, isInContentTypeView);
|
|
402
|
+
|
|
403
|
+
const hasJustCreatedSchema =
|
|
404
|
+
get(schemaToSet, 'isTemporary', false) &&
|
|
405
|
+
size(get(schemaToSet, 'schema.attributes', {})) === 0;
|
|
406
|
+
|
|
407
|
+
dispatch({
|
|
408
|
+
type: SET_MODIFIED_DATA,
|
|
409
|
+
schemaToSet: dataShape,
|
|
410
|
+
hasJustCreatedSchema,
|
|
411
|
+
});
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
const shouldRedirect = useMemo(() => {
|
|
415
|
+
const dataSet = isInContentTypeView ? contentTypes : components;
|
|
416
|
+
|
|
417
|
+
return !Object.keys(dataSet).includes(currentUid) && !isLoading;
|
|
418
|
+
}, [components, contentTypes, currentUid, isInContentTypeView, isLoading]);
|
|
419
|
+
|
|
420
|
+
const redirectEndpoint = useMemo(() => {
|
|
421
|
+
const allowedEndpoints = Object.keys(contentTypes)
|
|
422
|
+
.filter(uid => get(contentTypes, [uid, 'schema', 'visible'], true))
|
|
423
|
+
.sort();
|
|
424
|
+
|
|
425
|
+
return get(allowedEndpoints, '0', '');
|
|
426
|
+
}, [contentTypes]);
|
|
427
|
+
|
|
428
|
+
if (shouldRedirect) {
|
|
429
|
+
return <Redirect to={`/plugins/${pluginId}/content-types/${redirectEndpoint}`} />;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
const submitData = async additionalContentTypeData => {
|
|
433
|
+
try {
|
|
434
|
+
const isCreating = get(modifiedData, [firstKeyToMainSchema, 'isTemporary'], false);
|
|
435
|
+
const body = {
|
|
436
|
+
components: getComponentsToPost(
|
|
437
|
+
modifiedData.components,
|
|
438
|
+
components,
|
|
439
|
+
currentUid,
|
|
440
|
+
isCreating
|
|
441
|
+
),
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
if (isInContentTypeView) {
|
|
445
|
+
const contentType = apis.forms.mutateContentTypeSchema(
|
|
446
|
+
{
|
|
447
|
+
...formatMainDataType(modifiedData.contentType),
|
|
448
|
+
...additionalContentTypeData,
|
|
449
|
+
},
|
|
450
|
+
initialData.contentType
|
|
451
|
+
);
|
|
452
|
+
|
|
453
|
+
body.contentType = contentType;
|
|
454
|
+
|
|
455
|
+
emitEvent('willSaveContentType');
|
|
456
|
+
} else {
|
|
457
|
+
body.component = formatMainDataType(modifiedData.component, true);
|
|
458
|
+
|
|
459
|
+
emitEvent('willSaveComponent');
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
const method = isCreating ? 'POST' : 'PUT';
|
|
463
|
+
|
|
464
|
+
const baseURL = `/${pluginId}/${endPoint}`;
|
|
465
|
+
const requestURL = isCreating ? baseURL : `${baseURL}/${currentUid}`;
|
|
466
|
+
|
|
467
|
+
// Lock the app
|
|
468
|
+
strapi.lockApp();
|
|
469
|
+
|
|
470
|
+
await request(requestURL, { method, body }, true);
|
|
471
|
+
|
|
472
|
+
await updatePermissions();
|
|
473
|
+
|
|
474
|
+
// Submit ct tracking success
|
|
475
|
+
if (isInContentTypeView) {
|
|
476
|
+
emitEvent('didSaveContentType');
|
|
477
|
+
|
|
478
|
+
const oldName = get(body, ['contentType', 'schema', 'name'], '');
|
|
479
|
+
const newName = get(initialData, ['contentType', 'schema', 'name'], '');
|
|
480
|
+
|
|
481
|
+
if (!isCreating && oldName !== newName) {
|
|
482
|
+
emitEvent('didEditNameOfContentType');
|
|
483
|
+
}
|
|
484
|
+
} else {
|
|
485
|
+
emitEvent('didSaveComponent');
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// Reload the plugin so the cycle is new again
|
|
489
|
+
dispatch({ type: RELOAD_PLUGIN });
|
|
490
|
+
// Refetch all the data
|
|
491
|
+
getDataRef.current();
|
|
492
|
+
} catch (err) {
|
|
493
|
+
if (!isInContentTypeView) {
|
|
494
|
+
emitEvent('didNotSaveComponent');
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
console.error({ err: err.response });
|
|
498
|
+
strapi.notification.toggle({
|
|
499
|
+
type: 'warning',
|
|
500
|
+
message: { id: 'notification.error' },
|
|
501
|
+
});
|
|
502
|
+
} finally {
|
|
503
|
+
strapi.unlockApp();
|
|
504
|
+
}
|
|
505
|
+
};
|
|
506
|
+
|
|
507
|
+
// Open the modal warning cancel changes
|
|
508
|
+
const toggleModalCancel = () => {
|
|
509
|
+
toggleInfoModal(prev => ({ ...prev, cancel: !prev.cancel }));
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
const updatePermissions = async () => {
|
|
513
|
+
await fetchUserPermissions();
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
const updateSchema = (data, schemaType, componentUID) => {
|
|
517
|
+
dispatch({
|
|
518
|
+
type: UPDATE_SCHEMA,
|
|
519
|
+
data,
|
|
520
|
+
schemaType,
|
|
521
|
+
uid: componentUID,
|
|
522
|
+
});
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
return (
|
|
526
|
+
<DataManagerContext.Provider
|
|
527
|
+
value={{
|
|
528
|
+
addAttribute,
|
|
529
|
+
addCreatedComponentToDynamicZone,
|
|
530
|
+
allComponentsCategories: retrieveSpecificInfoFromComponents(components, ['category']),
|
|
531
|
+
allComponentsIconAlreadyTaken: retrieveSpecificInfoFromComponents(components, [
|
|
532
|
+
'schema',
|
|
533
|
+
'icon',
|
|
534
|
+
]),
|
|
535
|
+
allIcons,
|
|
536
|
+
changeDynamicZoneComponents,
|
|
537
|
+
components,
|
|
538
|
+
componentsGroupedByCategory: groupBy(components, 'category'),
|
|
539
|
+
componentsThatHaveOtherComponentInTheirAttributes: getAllComponentsThatHaveAComponentInTheirAttributes(),
|
|
540
|
+
contentTypes,
|
|
541
|
+
createSchema,
|
|
542
|
+
deleteCategory,
|
|
543
|
+
deleteData,
|
|
544
|
+
editCategory,
|
|
545
|
+
isInDevelopmentMode,
|
|
546
|
+
initialData,
|
|
547
|
+
isInContentTypeView,
|
|
548
|
+
modifiedData,
|
|
549
|
+
nestedComponents: getAllNestedComponents(),
|
|
550
|
+
removeAttribute,
|
|
551
|
+
removeComponentFromDynamicZone,
|
|
552
|
+
reservedNames,
|
|
553
|
+
setModifiedData,
|
|
554
|
+
sortedContentTypesList: sortContentType(contentTypes),
|
|
555
|
+
submitData,
|
|
556
|
+
toggleModalCancel,
|
|
557
|
+
updateSchema,
|
|
558
|
+
}}
|
|
559
|
+
>
|
|
560
|
+
{isLoadingForDataToBeSet ? (
|
|
561
|
+
<LoadingIndicatorPage />
|
|
562
|
+
) : (
|
|
563
|
+
<>
|
|
564
|
+
{children}
|
|
565
|
+
{isInDevelopmentMode && (
|
|
566
|
+
<>
|
|
567
|
+
<FormModal />
|
|
568
|
+
<PopUpWarning
|
|
569
|
+
isOpen={infoModals.cancel}
|
|
570
|
+
toggleModal={toggleModalCancel}
|
|
571
|
+
content={{
|
|
572
|
+
message: getTrad(
|
|
573
|
+
`popUpWarning.bodyMessage.cancel-modifications${
|
|
574
|
+
didModifiedComponents ? '.with-components' : ''
|
|
575
|
+
}`
|
|
576
|
+
),
|
|
577
|
+
}}
|
|
578
|
+
popUpWarningType="danger"
|
|
579
|
+
onConfirm={() => {
|
|
580
|
+
cancelChanges();
|
|
581
|
+
}}
|
|
582
|
+
/>
|
|
583
|
+
</>
|
|
584
|
+
)}
|
|
585
|
+
</>
|
|
586
|
+
)}
|
|
587
|
+
</DataManagerContext.Provider>
|
|
588
|
+
);
|
|
589
|
+
};
|
|
590
|
+
|
|
591
|
+
DataManagerProvider.defaultProps = {
|
|
592
|
+
components: {},
|
|
593
|
+
};
|
|
594
|
+
|
|
595
|
+
DataManagerProvider.propTypes = {
|
|
596
|
+
allIcons: PropTypes.array.isRequired,
|
|
597
|
+
children: PropTypes.node.isRequired,
|
|
598
|
+
components: PropTypes.object,
|
|
599
|
+
contentTypes: PropTypes.object.isRequired,
|
|
600
|
+
isLoading: PropTypes.bool.isRequired,
|
|
601
|
+
isLoadingForDataToBeSet: PropTypes.bool.isRequired,
|
|
602
|
+
initialData: PropTypes.object.isRequired,
|
|
603
|
+
modifiedData: PropTypes.object.isRequired,
|
|
604
|
+
reservedNames: PropTypes.object.isRequired,
|
|
605
|
+
};
|
|
606
|
+
|
|
607
|
+
const mapStateToProps = makeSelectDataManagerProvider();
|
|
608
|
+
const withConnect = connect(mapStateToProps, null);
|
|
609
|
+
|
|
610
|
+
export default compose(withConnect)(memo(DataManagerProvider));
|