@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.
Files changed (223) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +19 -0
  3. package/admin/src/InjectedComponents/ContentManager/EditSettingViewButton.js +76 -0
  4. package/admin/src/InjectedComponents/ContentManager/EditViewLink.js +44 -0
  5. package/admin/src/assets/images/logo.svg +1 -0
  6. package/admin/src/components/AllowedTypesSelect/MenuList.js +115 -0
  7. package/admin/src/components/AllowedTypesSelect/Text.js +26 -0
  8. package/admin/src/components/AllowedTypesSelect/index.js +55 -0
  9. package/admin/src/components/AttributeOption/Button.js +50 -0
  10. package/admin/src/components/AttributeOption/Card.js +26 -0
  11. package/admin/src/components/AttributeOption/index.js +127 -0
  12. package/admin/src/components/BooleanBox/CT.js +21 -0
  13. package/admin/src/components/BooleanBox/Enumeration.js +10 -0
  14. package/admin/src/components/BooleanBox/EnumerationWrapper.js +14 -0
  15. package/admin/src/components/BooleanBox/Label.js +9 -0
  16. package/admin/src/components/BooleanBox/ST.js +21 -0
  17. package/admin/src/components/BooleanBox/Wrapper.js +75 -0
  18. package/admin/src/components/BooleanBox/icons/CTSelected.js +136 -0
  19. package/admin/src/components/BooleanBox/icons/CTUnselected.js +136 -0
  20. package/admin/src/components/BooleanBox/icons/STSelected.js +80 -0
  21. package/admin/src/components/BooleanBox/icons/STUnselected.js +76 -0
  22. package/admin/src/components/BooleanBox/index.js +103 -0
  23. package/admin/src/components/CheckboxWithDescription/Wrapper.js +12 -0
  24. package/admin/src/components/CheckboxWithDescription/index.js +40 -0
  25. package/admin/src/components/ComponentCard/Close.js +12 -0
  26. package/admin/src/components/ComponentCard/Wrapper.js +84 -0
  27. package/admin/src/components/ComponentCard/index.js +62 -0
  28. package/admin/src/components/ComponentIconPicker/Cell.js +40 -0
  29. package/admin/src/components/ComponentIconPicker/CellRenderer.js +36 -0
  30. package/admin/src/components/ComponentIconPicker/Search.js +12 -0
  31. package/admin/src/components/ComponentIconPicker/SearchWrapper.js +34 -0
  32. package/admin/src/components/ComponentIconPicker/Wrapper.js +60 -0
  33. package/admin/src/components/ComponentIconPicker/index.js +143 -0
  34. package/admin/src/components/ComponentList/index.js +78 -0
  35. package/admin/src/components/ComponentSelect/Category.js +20 -0
  36. package/admin/src/components/ComponentSelect/CategoryName.js +11 -0
  37. package/admin/src/components/ComponentSelect/MenuList.js +110 -0
  38. package/admin/src/components/ComponentSelect/MultipleMenuList.js +271 -0
  39. package/admin/src/components/ComponentSelect/Value.js +83 -0
  40. package/admin/src/components/ComponentSelect/index.js +83 -0
  41. package/admin/src/components/ComponentSelect/utils/HasSomeSubArray.js +5 -0
  42. package/admin/src/components/ComponentSelect/utils/hasSubArray.js +5 -0
  43. package/admin/src/components/CreatableSelect/index.js +58 -0
  44. package/admin/src/components/CustomCheckbox/StyledCustomCheckbox.js +25 -0
  45. package/admin/src/components/CustomCheckbox/index.js +71 -0
  46. package/admin/src/components/CustomLink/P.js +17 -0
  47. package/admin/src/components/CustomLink/StyledCustomLink.js +20 -0
  48. package/admin/src/components/CustomLink/index.js +31 -0
  49. package/admin/src/components/DynamicZoneList/ComponentButton.js +39 -0
  50. package/admin/src/components/DynamicZoneList/index.js +124 -0
  51. package/admin/src/components/HeaderModalNavContainer/index.js +25 -0
  52. package/admin/src/components/HeaderNavLink/Wrapper.js +21 -0
  53. package/admin/src/components/HeaderNavLink/index.js +50 -0
  54. package/admin/src/components/List/List.js +131 -0
  55. package/admin/src/components/List/index.js +295 -0
  56. package/admin/src/components/ListButton/index.js +9 -0
  57. package/admin/src/components/ListHeader/Title.js +19 -0
  58. package/admin/src/components/ListHeader/Wrapper.js +24 -0
  59. package/admin/src/components/ListHeader/index.js +37 -0
  60. package/admin/src/components/ListRow/Wrapper.js +76 -0
  61. package/admin/src/components/ListRow/index.js +334 -0
  62. package/admin/src/components/ModalHeader/ComponentIcon.js +21 -0
  63. package/admin/src/components/ModalHeader/ComponentInfos.js +22 -0
  64. package/admin/src/components/ModalHeader/ComponentInfosWrapper.js +9 -0
  65. package/admin/src/components/ModalHeader/DropdownInfos.js +50 -0
  66. package/admin/src/components/ModalHeader/Icon.js +26 -0
  67. package/admin/src/components/ModalHeader/IconWrapper.js +11 -0
  68. package/admin/src/components/ModalHeader/Item.js +19 -0
  69. package/admin/src/components/ModalHeader/Menu.js +8 -0
  70. package/admin/src/components/ModalHeader/Toggle.js +14 -0
  71. package/admin/src/components/ModalHeader/Wrapper.js +12 -0
  72. package/admin/src/components/ModalHeader/index.js +105 -0
  73. package/admin/src/components/RelationForm/Wrapper.js +9 -0
  74. package/admin/src/components/RelationForm/index.js +66 -0
  75. package/admin/src/components/RelationFormBox/Wrapper.js +34 -0
  76. package/admin/src/components/RelationFormBox/index.js +85 -0
  77. package/admin/src/components/RelationFormNaturePicker/Wrapper.js +53 -0
  78. package/admin/src/components/RelationFormNaturePicker/index.js +112 -0
  79. package/admin/src/components/RelationTargetPicker/Item.js +62 -0
  80. package/admin/src/components/RelationTargetPicker/Wrapper.js +89 -0
  81. package/admin/src/components/RelationTargetPicker/index.js +88 -0
  82. package/admin/src/components/SelectCheckbox/index.js +8 -0
  83. package/admin/src/components/SelectMenuSubUl/ToggleUl.js +23 -0
  84. package/admin/src/components/SelectMenuSubUl/index.js +23 -0
  85. package/admin/src/components/SelectMenuUl/index.js +66 -0
  86. package/admin/src/components/Td/index.js +37 -0
  87. package/admin/src/components/UpperFirst/index.js +14 -0
  88. package/admin/src/components/WrapperSelect/index.js +89 -0
  89. package/admin/src/containers/App/Wrapper.js +14 -0
  90. package/admin/src/containers/App/index.js +39 -0
  91. package/admin/src/containers/App/utils/icons.json +962 -0
  92. package/admin/src/containers/DataManagerProvider/constants.js +15 -0
  93. package/admin/src/containers/DataManagerProvider/index.js +610 -0
  94. package/admin/src/containers/DataManagerProvider/reducer.js +461 -0
  95. package/admin/src/containers/DataManagerProvider/selectors.js +25 -0
  96. package/admin/src/containers/DataManagerProvider/utils/cleanData.js +167 -0
  97. package/admin/src/containers/DataManagerProvider/utils/createDataObject.js +8 -0
  98. package/admin/src/containers/DataManagerProvider/utils/createModifiedDataSchema.js +91 -0
  99. package/admin/src/containers/DataManagerProvider/utils/retrieveComponentsFromSchema.js +55 -0
  100. package/admin/src/containers/DataManagerProvider/utils/retrieveComponentsThatHaveComponents.js +35 -0
  101. package/admin/src/containers/DataManagerProvider/utils/retrieveNestedComponents.js +34 -0
  102. package/admin/src/containers/DataManagerProvider/utils/retrieveSpecificInfoFromComponents.js +12 -0
  103. package/admin/src/containers/FormModal/CustomButton.js +12 -0
  104. package/admin/src/containers/FormModal/attributes/advancedForm.js +269 -0
  105. package/admin/src/containers/FormModal/attributes/attributeOptions.js +99 -0
  106. package/admin/src/containers/FormModal/attributes/baseForm.js +322 -0
  107. package/admin/src/containers/FormModal/attributes/commonBaseForm.js +7 -0
  108. package/admin/src/containers/FormModal/attributes/form.js +9 -0
  109. package/admin/src/containers/FormModal/attributes/index.js +4 -0
  110. package/admin/src/containers/FormModal/attributes/nameField.js +19 -0
  111. package/admin/src/containers/FormModal/attributes/types.js +309 -0
  112. package/admin/src/containers/FormModal/attributes/uiHelpers.js +11 -0
  113. package/admin/src/containers/FormModal/attributes/validation/common.js +151 -0
  114. package/admin/src/containers/FormModal/category/createCategorySchema.js +28 -0
  115. package/admin/src/containers/FormModal/category/form.js +27 -0
  116. package/admin/src/containers/FormModal/category/index.js +3 -0
  117. package/admin/src/containers/FormModal/category/regex.js +3 -0
  118. package/admin/src/containers/FormModal/component/componentField.js +25 -0
  119. package/admin/src/containers/FormModal/component/createComponentSchema.js +49 -0
  120. package/admin/src/containers/FormModal/component/form.js +67 -0
  121. package/admin/src/containers/FormModal/component/index.js +4 -0
  122. package/admin/src/containers/FormModal/constants.js +11 -0
  123. package/admin/src/containers/FormModal/contentType/createContentTypeSchema.js +44 -0
  124. package/admin/src/containers/FormModal/contentType/form.js +116 -0
  125. package/admin/src/containers/FormModal/contentType/index.js +2 -0
  126. package/admin/src/containers/FormModal/dynamicZone/form.js +45 -0
  127. package/admin/src/containers/FormModal/dynamicZone/index.js +2 -0
  128. package/admin/src/containers/FormModal/forms/index.js +164 -0
  129. package/admin/src/containers/FormModal/index.js +1552 -0
  130. package/admin/src/containers/FormModal/reducer.js +293 -0
  131. package/admin/src/containers/FormModal/selectors.js +24 -0
  132. package/admin/src/containers/FormModal/utils/canEditContentType.js +19 -0
  133. package/admin/src/containers/FormModal/utils/createHeadersArray.js +37 -0
  134. package/admin/src/containers/FormModal/utils/createHeadersObjectFromArray.js +27 -0
  135. package/admin/src/containers/FormModal/utils/createUid.js +17 -0
  136. package/admin/src/containers/FormModal/utils/getAttributesToDisplay.js +35 -0
  137. package/admin/src/containers/FormModal/utils/getModalTitleSubHeader.js +25 -0
  138. package/admin/src/containers/FormModal/utils/getNextSearch.js +17 -0
  139. package/admin/src/containers/FormModal/utils/index.js +6 -0
  140. package/admin/src/containers/FormModal/utils/relations.js +9 -0
  141. package/admin/src/containers/FormModal/utils/staticData.js +43 -0
  142. package/admin/src/containers/Initializer/index.js +26 -0
  143. package/admin/src/containers/LeftMenu/Wrapper.js +14 -0
  144. package/admin/src/containers/LeftMenu/index.js +220 -0
  145. package/admin/src/containers/ListView/Wrapper.js +16 -0
  146. package/admin/src/containers/ListView/index.js +322 -0
  147. package/admin/src/containers/NotFoundPage/index.js +20 -0
  148. package/admin/src/containers/RecursivePath/index.js +22 -0
  149. package/admin/src/contexts/DataManagerContext.js +5 -0
  150. package/admin/src/contexts/ListViewContext.js +5 -0
  151. package/admin/src/hooks/useDataManager.js +6 -0
  152. package/admin/src/hooks/useListView.js +6 -0
  153. package/admin/src/icons/Curve.js +26 -0
  154. package/admin/src/icons/ManyToMany.js +98 -0
  155. package/admin/src/icons/ManyToOne.js +64 -0
  156. package/admin/src/icons/ManyWay.js +36 -0
  157. package/admin/src/icons/OneToMany.js +65 -0
  158. package/admin/src/icons/OneToOne.js +47 -0
  159. package/admin/src/icons/OneWay.js +38 -0
  160. package/admin/src/index.js +83 -0
  161. package/admin/src/lifecycles.js +13 -0
  162. package/admin/src/permissions.js +9 -0
  163. package/admin/src/pluginId.js +5 -0
  164. package/admin/src/reducers.js +10 -0
  165. package/admin/src/translations/ar.json +48 -0
  166. package/admin/src/translations/cs.json +151 -0
  167. package/admin/src/translations/de.json +187 -0
  168. package/admin/src/translations/dk.json +181 -0
  169. package/admin/src/translations/en.json +188 -0
  170. package/admin/src/translations/es.json +188 -0
  171. package/admin/src/translations/fr.json +87 -0
  172. package/admin/src/translations/id.json +187 -0
  173. package/admin/src/translations/index.js +51 -0
  174. package/admin/src/translations/it.json +187 -0
  175. package/admin/src/translations/ja.json +50 -0
  176. package/admin/src/translations/ko.json +57 -0
  177. package/admin/src/translations/ms.json +179 -0
  178. package/admin/src/translations/nl.json +171 -0
  179. package/admin/src/translations/pl.json +152 -0
  180. package/admin/src/translations/pt-BR.json +51 -0
  181. package/admin/src/translations/pt.json +51 -0
  182. package/admin/src/translations/ru.json +188 -0
  183. package/admin/src/translations/sk.json +186 -0
  184. package/admin/src/translations/th.json +181 -0
  185. package/admin/src/translations/tr.json +51 -0
  186. package/admin/src/translations/uk.json +180 -0
  187. package/admin/src/translations/zh-Hans.json +188 -0
  188. package/admin/src/translations/zh.json +178 -0
  189. package/admin/src/utils/convertAttrObjToArray.js +7 -0
  190. package/admin/src/utils/formAPI.js +112 -0
  191. package/admin/src/utils/getAttributeDisplayedType.js +31 -0
  192. package/admin/src/utils/getComponents.js +31 -0
  193. package/admin/src/utils/getTrad.js +5 -0
  194. package/admin/src/utils/makeSearch.js +15 -0
  195. package/admin/src/utils/makeUnique.js +3 -0
  196. package/config/functions/bootstrap.js +14 -0
  197. package/config/routes.json +144 -0
  198. package/controllers/Builder.js +7 -0
  199. package/controllers/ComponentCategories.js +43 -0
  200. package/controllers/Components.js +152 -0
  201. package/controllers/Connections.js +9 -0
  202. package/controllers/ContentTypes.js +143 -0
  203. package/controllers/validation/common.js +118 -0
  204. package/controllers/validation/component-category.js +21 -0
  205. package/controllers/validation/component.js +89 -0
  206. package/controllers/validation/content-type.js +161 -0
  207. package/controllers/validation/data-transform.js +32 -0
  208. package/controllers/validation/model-schema.js +91 -0
  209. package/controllers/validation/relations.js +56 -0
  210. package/controllers/validation/types.js +277 -0
  211. package/package.json +63 -0
  212. package/services/Builder.js +7 -0
  213. package/services/ComponentCategories.js +88 -0
  214. package/services/Components.js +103 -0
  215. package/services/ContentTypes.js +263 -0
  216. package/services/api-handler.js +158 -0
  217. package/services/constants.js +59 -0
  218. package/services/schema-builder/component-builder.js +137 -0
  219. package/services/schema-builder/content-type-builder.js +256 -0
  220. package/services/schema-builder/index.js +196 -0
  221. package/services/schema-builder/schema-handler.js +297 -0
  222. package/utils/attributes.js +154 -0
  223. package/utils/helpers.js +31 -0
@@ -0,0 +1,293 @@
1
+ import { fromJS, List } from 'immutable';
2
+ import pluralize from 'pluralize';
3
+ import { snakeCase } from 'lodash';
4
+ import makeUnique from '../../utils/makeUnique';
5
+ import { createComponentUid } from './utils/createUid';
6
+ import { shouldPluralizeName, shouldPluralizeTargetAttribute } from './utils/relations';
7
+ import * as actions from './constants';
8
+
9
+ const initialState = fromJS({
10
+ formErrors: {},
11
+ modifiedData: {},
12
+ initialData: {},
13
+ componentToCreate: {},
14
+ isCreatingComponentWhileAddingAField: false,
15
+ });
16
+
17
+ const reducer = (state = initialState, action) => {
18
+ switch (action.type) {
19
+ case actions.ADD_COMPONENTS_TO_DYNAMIC_ZONE: {
20
+ const { name, components, shouldAddComponents } = action;
21
+
22
+ return state.updateIn(['modifiedData', name], list => {
23
+ let updatedList = list;
24
+
25
+ if (shouldAddComponents) {
26
+ updatedList = list.concat(components);
27
+ } else {
28
+ updatedList = list.filter(comp => {
29
+ return components.indexOf(comp) === -1;
30
+ });
31
+ }
32
+
33
+ return List(makeUnique(updatedList.toJS()));
34
+ });
35
+ }
36
+ case actions.ON_CHANGE:
37
+ return state.update('modifiedData', obj => {
38
+ const {
39
+ selectedContentTypeFriendlyName,
40
+ keys,
41
+ value,
42
+ oneThatIsCreatingARelationWithAnother,
43
+ } = action;
44
+ const hasDefaultValue = Boolean(obj.getIn(['default']));
45
+
46
+ // There is no need to remove the default key if the default value isn't defined
47
+ if (hasDefaultValue && keys.length === 1 && keys.includes('type')) {
48
+ const previousType = obj.getIn(['type']);
49
+
50
+ if (previousType && ['date', 'datetime', 'time'].includes(previousType)) {
51
+ return obj.updateIn(keys, () => value).remove('default');
52
+ }
53
+ }
54
+
55
+ if (keys.length === 1 && keys.includes('nature')) {
56
+ return obj
57
+ .update('nature', () => value)
58
+ .update('dominant', () => {
59
+ if (value === 'manyToMany') {
60
+ return true;
61
+ }
62
+
63
+ return null;
64
+ })
65
+ .update('name', oldValue => {
66
+ return pluralize(snakeCase(oldValue), shouldPluralizeName(value));
67
+ })
68
+ .update('targetAttribute', oldValue => {
69
+ if (['oneWay', 'manyWay'].includes(value)) {
70
+ return '-';
71
+ }
72
+
73
+ return pluralize(
74
+ oldValue === '-' ? snakeCase(oneThatIsCreatingARelationWithAnother) : oldValue,
75
+ shouldPluralizeTargetAttribute(value)
76
+ );
77
+ })
78
+ .update('targetColumnName', oldValue => {
79
+ if (['oneWay', 'manyWay'].includes(value)) {
80
+ return null;
81
+ }
82
+
83
+ return oldValue;
84
+ });
85
+ }
86
+
87
+ if (keys.length === 1 && keys.includes('target')) {
88
+ const { targetContentTypeAllowedRelations } = action;
89
+ let didChangeNatureBecauseOfRestrictedRelation = false;
90
+
91
+ return obj
92
+ .update('target', () => value)
93
+ .update('nature', currentNature => {
94
+ if (targetContentTypeAllowedRelations === null) {
95
+ return currentNature;
96
+ }
97
+
98
+ if (!targetContentTypeAllowedRelations.includes(currentNature)) {
99
+ didChangeNatureBecauseOfRestrictedRelation = true;
100
+
101
+ return targetContentTypeAllowedRelations[0];
102
+ }
103
+
104
+ return currentNature;
105
+ })
106
+ .update('name', () => {
107
+ if (didChangeNatureBecauseOfRestrictedRelation) {
108
+ return pluralize(
109
+ snakeCase(selectedContentTypeFriendlyName),
110
+ shouldPluralizeName(targetContentTypeAllowedRelations[0])
111
+ );
112
+ }
113
+
114
+ return pluralize(
115
+ snakeCase(selectedContentTypeFriendlyName),
116
+
117
+ shouldPluralizeName(obj.get('nature'))
118
+ );
119
+ })
120
+ .update('targetAttribute', () => {
121
+ if (['oneWay', 'manyWay'].includes(obj.get('nature'))) {
122
+ return '-';
123
+ }
124
+
125
+ if (
126
+ didChangeNatureBecauseOfRestrictedRelation &&
127
+ ['oneWay', 'manyWay'].includes(targetContentTypeAllowedRelations[0])
128
+ ) {
129
+ return '-';
130
+ }
131
+
132
+ return pluralize(
133
+ snakeCase(oneThatIsCreatingARelationWithAnother),
134
+ shouldPluralizeTargetAttribute(obj.get('nature'))
135
+ );
136
+ });
137
+ }
138
+
139
+ return obj.updateIn(keys, () => value);
140
+ });
141
+ case actions.ON_CHANGE_ALLOWED_TYPE: {
142
+ if (action.name === 'all') {
143
+ return state.updateIn(['modifiedData', 'allowedTypes'], () => {
144
+ if (action.value) {
145
+ return fromJS(['images', 'videos', 'files']);
146
+ }
147
+
148
+ return null;
149
+ });
150
+ }
151
+
152
+ return state.updateIn(['modifiedData', 'allowedTypes'], currentList => {
153
+ let list = currentList || fromJS([]);
154
+
155
+ if (list.includes(action.name)) {
156
+ list = list.filter(v => v !== action.name);
157
+
158
+ if (list.size === 0) {
159
+ return null;
160
+ }
161
+
162
+ return list;
163
+ }
164
+
165
+ return list.push(action.name);
166
+ });
167
+ }
168
+ case actions.RESET_PROPS:
169
+ return initialState;
170
+ case actions.RESET_PROPS_AND_SET_FORM_FOR_ADDING_AN_EXISTING_COMPO: {
171
+ // This is run when the user doesn't want to create a new component
172
+ return initialState.update('modifiedData', () =>
173
+ fromJS({ type: 'component', repeatable: true, ...action.options })
174
+ );
175
+ }
176
+ case actions.RESET_PROPS_AND_SAVE_CURRENT_DATA: {
177
+ // This is run when the user has created a new component
178
+ const componentToCreate = state.getIn(['modifiedData', 'componentToCreate']);
179
+ const modifiedData = fromJS({
180
+ name: componentToCreate.get('name'),
181
+ type: 'component',
182
+ repeatable: false,
183
+ ...action.options,
184
+ component: createComponentUid(
185
+ componentToCreate.get('name'),
186
+ componentToCreate.get('category')
187
+ ),
188
+ });
189
+
190
+ return initialState
191
+ .update('componentToCreate', () => componentToCreate)
192
+ .update('modifiedData', () => modifiedData)
193
+ .update('isCreatingComponentWhileAddingAField', () =>
194
+ state.getIn(['modifiedData', 'createComponent'])
195
+ );
196
+ }
197
+ case actions.RESET_PROPS_AND_SET_THE_FORM_FOR_ADDING_A_COMPO_TO_A_DZ: {
198
+ const createdDZ = state.get('modifiedData');
199
+ const dataToSet = createdDZ
200
+ .set('createComponent', true)
201
+ .set('componentToCreate', fromJS({ type: 'component' }));
202
+
203
+ return initialState.update('modifiedData', () => dataToSet);
204
+ }
205
+ case actions.SET_DATA_TO_EDIT: {
206
+ return state
207
+ .updateIn(['modifiedData'], () => fromJS(action.data))
208
+ .updateIn(['initialData'], () => fromJS(action.data));
209
+ }
210
+ case actions.SET_ATTRIBUTE_DATA_SCHEMA: {
211
+ const {
212
+ attributeType,
213
+ isEditing,
214
+ modifiedDataToSetForEditing,
215
+ nameToSetForRelation,
216
+ targetUid,
217
+ step,
218
+ options = {},
219
+ } = action;
220
+
221
+ if (isEditing) {
222
+ return state
223
+ .update('modifiedData', () => fromJS(modifiedDataToSetForEditing))
224
+ .update('initialData', () => fromJS(modifiedDataToSetForEditing));
225
+ }
226
+
227
+ let dataToSet;
228
+
229
+ if (attributeType === 'component') {
230
+ if (step === '1') {
231
+ dataToSet = {
232
+ type: 'component',
233
+ createComponent: true,
234
+ componentToCreate: { type: 'component' },
235
+ };
236
+ } else {
237
+ dataToSet = {
238
+ ...options,
239
+ type: 'component',
240
+ repeatable: true,
241
+ };
242
+ }
243
+ } else if (attributeType === 'dynamiczone') {
244
+ dataToSet = {
245
+ ...options,
246
+ type: 'dynamiczone',
247
+ components: [],
248
+ };
249
+ } else if (attributeType === 'text') {
250
+ dataToSet = { ...options, type: 'string' };
251
+ } else if (attributeType === 'number' || attributeType === 'date') {
252
+ dataToSet = options;
253
+ } else if (attributeType === 'media') {
254
+ dataToSet = {
255
+ allowedTypes: ['images', 'files', 'videos'],
256
+ type: 'media',
257
+ multiple: true,
258
+ ...options,
259
+ };
260
+ } else if (attributeType === 'enumeration') {
261
+ dataToSet = { ...options, type: 'enumeration', enum: [] };
262
+ } else if (attributeType === 'relation') {
263
+ dataToSet = {
264
+ name: snakeCase(nameToSetForRelation),
265
+ nature: 'oneWay',
266
+ targetAttribute: '-',
267
+ target: targetUid,
268
+ unique: false,
269
+ dominant: null,
270
+ columnName: null,
271
+ targetColumnName: null,
272
+ };
273
+ } else {
274
+ dataToSet = { ...options, type: attributeType, default: null };
275
+ }
276
+
277
+ return state.update('modifiedData', () => fromJS(dataToSet));
278
+ }
279
+ case actions.SET_DYNAMIC_ZONE_DATA_SCHEMA: {
280
+ return state
281
+ .update('modifiedData', () => fromJS(action.attributeToEdit))
282
+ .update('initialData', () => fromJS(action.attributeToEdit));
283
+ }
284
+
285
+ case actions.SET_ERRORS:
286
+ return state.update('formErrors', () => fromJS(action.errors));
287
+ default:
288
+ return state;
289
+ }
290
+ };
291
+
292
+ export default reducer;
293
+ export { initialState };
@@ -0,0 +1,24 @@
1
+ import { createSelector } from 'reselect';
2
+ import pluginId from '../../pluginId';
3
+ import { initialState } from './reducer';
4
+
5
+ /**
6
+ * Direct selector to the formModal state domain
7
+ */
8
+ const formModalDomain = () => state => state.get(`${pluginId}_formModal`) || initialState;
9
+
10
+ /**
11
+ * Other specific selectors
12
+ */
13
+
14
+ /**
15
+ * Default selector used by formModal
16
+ */
17
+
18
+ const makeSelectFormModal = () =>
19
+ createSelector(formModalDomain(), substate => {
20
+ return substate;
21
+ });
22
+
23
+ export default makeSelectFormModal;
24
+ export { formModalDomain };
@@ -0,0 +1,19 @@
1
+ import { get } from 'lodash';
2
+
3
+ const canEditContentType = (data, modifiedData) => {
4
+ const kind = get(data, ['contentType', 'schema', 'kind'], '');
5
+
6
+ // if kind isn't modified or content type is a single type, there is no need to check attributes.
7
+ if (kind === 'singleType' || kind === modifiedData.kind) {
8
+ return true;
9
+ }
10
+
11
+ const contentTypeAttributes = get(data, ['contentType', 'schema', 'attributes'], '');
12
+ const relationAttributes = Object.values(contentTypeAttributes).filter(
13
+ ({ nature }) => nature && !['oneWay', 'manyWay'].includes(nature)
14
+ );
15
+
16
+ return relationAttributes.length === 0;
17
+ };
18
+
19
+ export default canEditContentType;
@@ -0,0 +1,37 @@
1
+ import { set } from 'lodash';
2
+
3
+ const ALLOWED_KEYS = [
4
+ 'header_label',
5
+ 'header_icon_name',
6
+ 'header_icon_isCustom',
7
+ 'header_info_category',
8
+ 'header_info_name',
9
+ ];
10
+ const createHeadersArray = obj => {
11
+ const array = Object.keys(obj).reduce((acc, current) => {
12
+ const splitted = current.split('_');
13
+ const currentKeys = splitted.filter((_, i) => i !== splitted.length - 1);
14
+
15
+ if (ALLOWED_KEYS.includes(currentKeys.join('_'))) {
16
+ const currentKeysIndex = parseInt(splitted[splitted.length - 1] - 1, 10);
17
+ const path = [
18
+ currentKeysIndex,
19
+ ...currentKeys.filter(key => key !== 'header'),
20
+ ];
21
+
22
+ let value = obj[current];
23
+
24
+ if (current.includes('isCustom')) {
25
+ value = obj[current] === 'true';
26
+ }
27
+
28
+ set(acc, path, value);
29
+ }
30
+
31
+ return acc;
32
+ }, []);
33
+
34
+ return array.filter(obj => obj.label !== null);
35
+ };
36
+
37
+ export default createHeadersArray;
@@ -0,0 +1,27 @@
1
+ import { isObject } from 'lodash';
2
+
3
+ const createHeadersObjectFromArray = array => {
4
+ return array.reduce((acc, current, index) => {
5
+ const createHeaderObject = (obj, i, middle = '') =>
6
+ Object.keys(obj).reduce((acc1, current1) => {
7
+ if (isObject(obj[current1])) {
8
+ return {
9
+ ...acc1,
10
+ ...createHeaderObject(obj[current1], i, `_${current1}`),
11
+ };
12
+ }
13
+
14
+ const name = `header${middle}_${current1}_${i}`;
15
+
16
+ acc1[name] = obj[current1];
17
+
18
+ return acc1;
19
+ }, {});
20
+
21
+ const headerObject = createHeaderObject(current, index + 1);
22
+
23
+ return { ...acc, ...headerObject };
24
+ }, {});
25
+ };
26
+
27
+ export default createHeadersObjectFromArray;
@@ -0,0 +1,17 @@
1
+ import slugify from '@sindresorhus/slugify';
2
+
3
+ const nameToSlug = name => slugify(name, { separator: '-' });
4
+
5
+ const createUid = name => {
6
+ const modelName = nameToSlug(name);
7
+ const uid = `application::${modelName}.${modelName}`;
8
+
9
+ return uid;
10
+ };
11
+
12
+ // From `content-type-builder/services/Components/createComponentUid`
13
+ const createComponentUid = (name, category) => {
14
+ return `${nameToSlug(category)}.${nameToSlug(name)}`;
15
+ };
16
+
17
+ export { createComponentUid, createUid, nameToSlug };
@@ -0,0 +1,35 @@
1
+ const getAttributes = (dataTarget = '', targetUid, nestedComponents) => {
2
+ const defaultAttributes = [
3
+ 'text',
4
+ 'email',
5
+ 'richtext',
6
+ 'password',
7
+ 'number',
8
+ 'enumeration',
9
+ 'date',
10
+ 'media',
11
+ 'boolean',
12
+ 'json',
13
+ 'relation',
14
+ ];
15
+
16
+ const isPickingAttributeForAContentType = dataTarget === 'contentType';
17
+ const isNestedInAnotherComponent = nestedComponents.includes(targetUid);
18
+ const canAddComponentInAnotherComponent =
19
+ !isPickingAttributeForAContentType && !isNestedInAnotherComponent;
20
+
21
+ if (isPickingAttributeForAContentType) {
22
+ return [
23
+ [...defaultAttributes, 'uid'],
24
+ ['component', 'dynamiczone'],
25
+ ];
26
+ }
27
+
28
+ if (canAddComponentInAnotherComponent) {
29
+ return [defaultAttributes, ['component']];
30
+ }
31
+
32
+ return [defaultAttributes];
33
+ };
34
+
35
+ export default getAttributes;
@@ -0,0 +1,25 @@
1
+ import getTrad from '../../../utils/getTrad';
2
+
3
+ const getModalTitleSubHeader = state => {
4
+ switch (state.modalType) {
5
+ case 'chooseAttribute':
6
+ return getTrad(
7
+ `modalForm.sub-header.chooseAttribute.${
8
+ state.forTarget.includes('component') ? 'component' : state.kind
9
+ }`
10
+ );
11
+ case 'attribute': {
12
+ return getTrad(
13
+ `modalForm.sub-header.attribute.${state.actionType}${
14
+ state.step !== 'null' && state.step !== null && state.actionType !== 'edit' ? '.step' : ''
15
+ }`
16
+ );
17
+ }
18
+ case 'addComponentToDynamicZone':
19
+ return getTrad('modalForm.sub-header.addComponentToDynamicZone');
20
+ default:
21
+ return getTrad('configurations');
22
+ }
23
+ };
24
+
25
+ export default getModalTitleSubHeader;
@@ -0,0 +1,17 @@
1
+ const getNextSearch = (nextTab, state) => {
2
+ const newSearch = Object.keys(state).reduce((acc, current, index) => {
3
+ if (state[current] !== null && current !== 'pathToSchema') {
4
+ if (current !== 'settingType') {
5
+ acc = `${acc}${index === 0 ? '' : '&'}${current}=${state[current]}`;
6
+ } else {
7
+ acc = `${acc}${index === 0 ? '' : '&'}${current}=${nextTab}`;
8
+ }
9
+ }
10
+
11
+ return acc;
12
+ }, '');
13
+
14
+ return newSearch;
15
+ };
16
+
17
+ export default getNextSearch;
@@ -0,0 +1,6 @@
1
+ export { default as canEditContentType } from './canEditContentType';
2
+ export { default as createHeadersArray } from './createHeadersArray';
3
+ export { default as createHeadersObjectFromArray } from './createHeadersObjectFromArray';
4
+ export { default as getAttributesToDisplay } from './getAttributesToDisplay';
5
+ export { default as getModalTitleSubHeader } from './getModalTitleSubHeader';
6
+ export { default as getNextSearch } from './getNextSearch';
@@ -0,0 +1,9 @@
1
+ /* eslint-disable no-confusing-arrow */
2
+
3
+ const shouldPluralizeName = nature =>
4
+ ['manyToMany', 'oneToMany', 'manyWay'].includes(nature) ? 2 : 1;
5
+
6
+ const shouldPluralizeTargetAttribute = nature =>
7
+ ['manyToMany', 'manyToOne'].includes(nature) ? 2 : 1;
8
+
9
+ export { shouldPluralizeName, shouldPluralizeTargetAttribute };
@@ -0,0 +1,43 @@
1
+ const NAVLINKS = [{ id: 'base' }, { id: 'advanced' }];
2
+
3
+ const INITIAL_STATE_DATA = {
4
+ actionType: null,
5
+ attributeName: null,
6
+ attributeType: null,
7
+ dynamicZoneTarget: null,
8
+ forTarget: null,
9
+ modalType: null,
10
+ kind: null,
11
+ pathToSchema: [],
12
+ settingType: null,
13
+ step: null,
14
+ targetUid: null,
15
+ headerId: null,
16
+ header_label_1: null,
17
+ header_icon_name_1: null,
18
+ header_icon_isCustom_1: null,
19
+ header_info_category_1: null,
20
+ header_info_name_1: null,
21
+ header_label_2: null,
22
+ header_icon_name_2: null,
23
+ header_icon_isCustom_2: null,
24
+ header_info_category_2: null,
25
+ header_info_name_2: null,
26
+ header_label_3: null,
27
+ header_icon_name_3: null,
28
+ header_icon_isCustom_3: null,
29
+ header_info_category_3: null,
30
+ header_info_name_3: null,
31
+ header_label_4: null,
32
+ header_icon_name_4: null,
33
+ header_icon_isCustom_4: null,
34
+ header_info_category_4: null,
35
+ header_info_name_4: null,
36
+ header_label_5: null,
37
+ header_icon_name_5: null,
38
+ header_icon_isCustom_5: null,
39
+ header_info_category_5: null,
40
+ header_info_name_5: null,
41
+ };
42
+
43
+ export { NAVLINKS, INITIAL_STATE_DATA };
@@ -0,0 +1,26 @@
1
+ /**
2
+ *
3
+ * Initializer
4
+ *
5
+ */
6
+
7
+ import { useEffect, useRef } from 'react';
8
+ import PropTypes from 'prop-types';
9
+ import pluginId from '../../pluginId';
10
+
11
+ const Initializer = ({ updatePlugin }) => {
12
+ const ref = useRef();
13
+ ref.current = updatePlugin;
14
+
15
+ useEffect(() => {
16
+ ref.current(pluginId, 'isReady', true);
17
+ }, []);
18
+
19
+ return null;
20
+ };
21
+
22
+ Initializer.propTypes = {
23
+ updatePlugin: PropTypes.func.isRequired,
24
+ };
25
+
26
+ export default Initializer;
@@ -0,0 +1,14 @@
1
+ import styled from 'styled-components';
2
+
3
+ import { colors, sizes } from 'strapi-helper-plugin';
4
+
5
+ const Wrapper = styled.div`
6
+ width: 100%;
7
+ min-height: calc(100vh - ${sizes.header.height});
8
+ background-color: ${colors.leftMenu.mediumGrey};
9
+ padding-top: 3.1rem;
10
+ padding-left: 2rem;
11
+ padding-right: 2rem;
12
+ `;
13
+
14
+ export default Wrapper;