@strapi/admin 4.6.0-alpha.0 → 4.6.0-beta.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/admin/src/content-manager/components/ComponentInitializer/index.js +1 -7
- package/admin/src/content-manager/components/{RepeatableComponent/DragPreview.js → DragLayer/ComponentDragPreview.js} +25 -12
- package/admin/src/content-manager/components/DragLayer/RelationDragPreview.js +75 -0
- package/admin/src/content-manager/components/DragLayer/index.js +23 -7
- package/admin/src/content-manager/components/DynamicZone/components/DynamicComponent.js +130 -84
- package/admin/src/content-manager/components/DynamicZone/index.js +99 -24
- package/admin/src/content-manager/components/DynamicZone/utils/select.js +9 -5
- package/admin/src/content-manager/components/EditViewDataManagerProvider/index.js +76 -14
- package/admin/src/content-manager/components/EditViewDataManagerProvider/reducer.js +23 -23
- package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/cleanData.js +24 -5
- package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/recursivelyFindPathsBasedOnCondition.js +8 -1
- package/admin/src/content-manager/components/Inputs/index.js +5 -19
- package/admin/src/content-manager/components/NonRepeatableComponent/index.js +4 -0
- package/admin/src/content-manager/components/RelationInput/RelationInput.js +203 -63
- package/admin/src/content-manager/components/RelationInput/components/RelationItem.js +134 -21
- package/admin/src/content-manager/components/RelationInput/components/RelationList.js +1 -2
- package/admin/src/content-manager/components/RelationInput/constants.js +1 -0
- package/admin/src/content-manager/components/RelationInputDataManager/RelationInputDataManager.js +132 -10
- package/admin/src/content-manager/components/RepeatableComponent/components/Accordion.js +77 -0
- package/admin/src/content-manager/components/RepeatableComponent/components/Component.js +262 -0
- package/admin/src/content-manager/components/RepeatableComponent/{DraggedItem → components}/Preview.js +0 -0
- package/admin/src/content-manager/components/RepeatableComponent/index.js +147 -87
- package/admin/src/content-manager/components/RepeatableComponent/utils/getComponentErrorKeys.js +1 -1
- package/admin/src/content-manager/components/SingleTypeFormWrapper/index.js +1 -1
- package/admin/src/content-manager/components/Wysiwyg/Editor.js +1 -1
- package/admin/src/content-manager/hooks/index.js +2 -0
- package/admin/src/content-manager/hooks/useDragAndDrop.js +120 -0
- package/admin/src/content-manager/hooks/useKeyboardDragAndDrop.js +98 -0
- package/admin/src/content-manager/hooks/useLazyComponents/index.js +69 -0
- package/admin/src/content-manager/pages/CollectionTypeRecursivePath/components/ErrorFallback.js +13 -0
- package/admin/src/content-manager/pages/CollectionTypeRecursivePath/index.js +2 -1
- package/admin/src/content-manager/pages/EditView/GridRow/index.js +62 -0
- package/admin/src/content-manager/pages/EditView/index.js +74 -154
- package/admin/src/content-manager/pages/EditView/selectors.js +14 -0
- package/admin/src/content-manager/pages/EditView/utils/createAttributesLayout.js +11 -6
- package/admin/src/content-manager/pages/EditView/utils/getCustomFieldUidsFromLayout.js +18 -0
- package/admin/src/content-manager/pages/EditView/utils/index.js +1 -0
- package/admin/src/content-manager/pages/EditViewLayoutManager/index.js +1 -1
- package/admin/src/content-manager/sharedReducers/crudReducer/actions.js +5 -0
- package/admin/src/content-manager/sharedReducers/crudReducer/constants.js +2 -0
- package/admin/src/content-manager/sharedReducers/crudReducer/reducer.js +7 -0
- package/admin/src/content-manager/utils/ItemTypes.js +1 -1
- package/admin/src/content-manager/utils/composeRefs.js +28 -0
- package/admin/src/content-manager/utils/getMaxTempKey.js +1 -1
- package/admin/src/content-manager/utils/index.js +7 -0
- package/admin/src/core/utils/axiosInstance.js +4 -2
- package/admin/src/hooks/index.js +1 -0
- package/admin/src/hooks/useFetchClient/index.js +23 -0
- package/admin/src/pages/HomePage/SocialLinks.js +4 -4
- package/admin/src/pages/SettingsPage/pages/Users/ListPage/ModalForm/index.js +23 -18
- package/admin/src/translations/en.json +6 -0
- package/admin/src/translations/ru.json +789 -489
- package/admin/src/utils/fetchClient.js +45 -0
- package/admin/src/utils/getFetchClient.js +10 -0
- package/build/4306.df40a798.chunk.js +98 -0
- package/build/{4318.daf31770.chunk.js → 4318.80bdf035.chunk.js} +2 -2
- package/build/5057.195a59ff.chunk.js +65 -0
- package/build/{805.a1894307.chunk.js → 805.e991a370.chunk.js} +6 -6
- package/build/{4986.3820d11d.chunk.js → 8176.b19bc128.chunk.js} +32 -32
- package/build/{1233.32d6888d.chunk.js → 8186.55910742.chunk.js} +94 -94
- package/build/{8633.8da5488a.chunk.js → 8633.59223842.chunk.js} +1 -1
- package/build/8881.c693411a.chunk.js +245 -0
- package/build/9161.4a0ab137.chunk.js +2119 -0
- package/build/9279.6290c87a.chunk.js +117 -0
- package/build/9707.a0cc4ad8.chunk.js +70 -0
- package/build/Admin-authenticatedApp.f9e74dc0.chunk.js +80 -0
- package/build/{Admin_homePage.b4db4df8.chunk.js → Admin_homePage.8945f71a.chunk.js} +5 -5
- package/build/{Admin_marketplace.fa51405b.chunk.js → Admin_marketplace.ed754a4a.chunk.js} +1 -1
- package/build/{Admin_pluginsPage.14d2840f.chunk.js → Admin_pluginsPage.3c872de7.chunk.js} +1 -1
- package/build/{Admin_profilePage.6c2c8398.chunk.js → Admin_profilePage.c07bdf08.chunk.js} +1 -1
- package/build/{Admin_settingsPage.5e740514.chunk.js → Admin_settingsPage.50a8765b.chunk.js} +5 -5
- package/build/admin-app.2861b6d2.chunk.js +112 -0
- package/build/{admin-edit-roles-page.c7c338b3.chunk.js → admin-edit-roles-page.f407538c.chunk.js} +1 -1
- package/build/{admin-edit-users.d254c128.chunk.js → admin-edit-users.85231e4c.chunk.js} +1 -1
- package/build/{admin-users.7c423e41.chunk.js → admin-users.a2707644.chunk.js} +2 -2
- package/build/api-tokens-create-page.dd4ddfcb.chunk.js +1 -0
- package/build/api-tokens-edit-page.821c5a6c.chunk.js +1 -0
- package/build/{api-tokens-list-page.fe994b6b.chunk.js → api-tokens-list-page.700e575f.chunk.js} +1 -1
- package/build/content-manager.ee948f75.chunk.js +1186 -0
- package/build/content-type-builder-list-view.4412efc3.chunk.js +201 -0
- package/build/content-type-builder.b132b5f4.chunk.js +145 -0
- package/build/email-settings-page.db0d98d1.chunk.js +15 -0
- package/build/{en-json.7dd57947.chunk.js → en-json.4a56dca7.chunk.js} +1 -1
- package/build/index.html +1 -1
- package/build/main.faac89ee.js +2025 -0
- package/build/ru-json.8830286f.chunk.js +1 -0
- package/build/{runtime~main.6e7d95b9.js → runtime~main.75a15b8e.js} +1 -1
- package/build/{sso-settings-page.eb30a02e.chunk.js → sso-settings-page.adb12ac3.chunk.js} +1 -1
- package/build/upload-settings.450cab1a.chunk.js +18 -0
- package/build/upload.e2034370.chunk.js +64 -0
- package/build/users-advanced-settings-page.0c0b8230.chunk.js +13 -0
- package/build/users-email-settings-page.3126ff8c.chunk.js +28 -0
- package/build/users-providers-settings-page.b7b602e2.chunk.js +33 -0
- package/build/users-roles-settings-page.ce5b582d.chunk.js +30 -0
- package/build/webhook-edit-page.1215a6b7.chunk.js +75 -0
- package/build/{webhook-list-page.42533b59.chunk.js → webhook-list-page.b87821f2.chunk.js} +1 -1
- package/ee/server/services/passport/provider-registry.js +1 -1
- package/package.json +15 -15
- package/utils/get-plugins-path.js +17 -3
- package/admin/src/content-manager/components/RepeatableComponent/AccordionGroupCustom/index.js +0 -122
- package/admin/src/content-manager/components/RepeatableComponent/AddFieldButton.js +0 -58
- package/admin/src/content-manager/components/RepeatableComponent/DraggedItem/DraggingSibling.js +0 -72
- package/admin/src/content-manager/components/RepeatableComponent/DraggedItem/IconButtonCustoms.js +0 -32
- package/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js +0 -322
- package/admin/src/content-manager/components/RepeatableComponent/DraggedItem/utils/connect.js +0 -11
- package/admin/src/content-manager/components/RepeatableComponent/DraggedItem/utils/index.js +0 -2
- package/admin/src/content-manager/components/RepeatableComponent/DraggedItem/utils/select.js +0 -30
- package/admin/src/content-manager/components/RepeatableComponent/utils/connect.js +0 -11
- package/admin/src/content-manager/components/RepeatableComponent/utils/select.js +0 -12
- package/admin/src/content-manager/hooks/__test__/usePrev.test.js +0 -26
- package/build/2438.afe24949.chunk.js +0 -2525
- package/build/2517.5cc235ba.chunk.js +0 -117
- package/build/4306.53359960.chunk.js +0 -98
- package/build/8881.bfdb6877.chunk.js +0 -245
- package/build/9707.932a3c12.chunk.js +0 -70
- package/build/Admin-authenticatedApp.cfc3b4c9.chunk.js +0 -80
- package/build/admin-app.ee1211cb.chunk.js +0 -112
- package/build/api-tokens-create-page.4ca2778d.chunk.js +0 -1
- package/build/api-tokens-edit-page.70a791c2.chunk.js +0 -1
- package/build/content-manager.794d3373.chunk.js +0 -1200
- package/build/content-type-builder-list-view.95012cf0.chunk.js +0 -201
- package/build/content-type-builder.95b9d6a2.chunk.js +0 -145
- package/build/email-settings-page.4bb3606f.chunk.js +0 -15
- package/build/main.a6470578.js +0 -2031
- package/build/ru-json.d7cfc2ff.chunk.js +0 -1
- package/build/upload-settings.3010911f.chunk.js +0 -18
- package/build/upload.9f19f2e8.chunk.js +0 -64
- package/build/users-advanced-settings-page.9df41d67.chunk.js +0 -13
- package/build/users-email-settings-page.56d82eaf.chunk.js +0 -28
- package/build/users-providers-settings-page.96bb7da0.chunk.js +0 -33
- package/build/users-roles-settings-page.445e5e16.chunk.js +0 -30
- package/build/webhook-edit-page.c5efc08b.chunk.js +0 -75
|
@@ -9,15 +9,20 @@ function useSelect(name) {
|
|
|
9
9
|
isCreatingEntry,
|
|
10
10
|
formErrors,
|
|
11
11
|
modifiedData,
|
|
12
|
-
|
|
13
|
-
moveComponentDown,
|
|
12
|
+
moveComponentField,
|
|
14
13
|
removeComponentFromDynamicZone,
|
|
15
14
|
readActionAllowedFields,
|
|
16
15
|
updateActionAllowedFields,
|
|
17
16
|
} = useCMEditViewDataManager();
|
|
18
17
|
|
|
19
18
|
const dynamicDisplayedComponents = useMemo(
|
|
20
|
-
() =>
|
|
19
|
+
() =>
|
|
20
|
+
get(modifiedData, [name], []).map((data) => {
|
|
21
|
+
return {
|
|
22
|
+
componentUid: data.__component,
|
|
23
|
+
id: data.id ?? data.__temp_key__,
|
|
24
|
+
};
|
|
25
|
+
}),
|
|
21
26
|
[modifiedData, name]
|
|
22
27
|
);
|
|
23
28
|
|
|
@@ -39,8 +44,7 @@ function useSelect(name) {
|
|
|
39
44
|
isCreatingEntry,
|
|
40
45
|
isFieldAllowed,
|
|
41
46
|
isFieldReadable,
|
|
42
|
-
|
|
43
|
-
moveComponentDown,
|
|
47
|
+
moveComponentField,
|
|
44
48
|
removeComponentFromDynamicZone,
|
|
45
49
|
dynamicDisplayedComponents,
|
|
46
50
|
};
|
|
@@ -8,7 +8,9 @@ import set from 'lodash/set';
|
|
|
8
8
|
import PropTypes from 'prop-types';
|
|
9
9
|
import { useIntl } from 'react-intl';
|
|
10
10
|
import { Prompt, Redirect } from 'react-router-dom';
|
|
11
|
-
import {
|
|
11
|
+
import { useDispatch, useSelector } from 'react-redux';
|
|
12
|
+
|
|
13
|
+
import { Main } from '@strapi/design-system';
|
|
12
14
|
import {
|
|
13
15
|
LoadingIndicatorPage,
|
|
14
16
|
ContentManagerEditViewDataManagerContext,
|
|
@@ -20,8 +22,13 @@ import {
|
|
|
20
22
|
} from '@strapi/helper-plugin';
|
|
21
23
|
|
|
22
24
|
import { getTrad, removeKeyInObject } from '../../utils';
|
|
25
|
+
|
|
26
|
+
import selectCrudReducer from '../../sharedReducers/crudReducer/selectors';
|
|
27
|
+
|
|
23
28
|
import reducer, { initialState } from './reducer';
|
|
24
29
|
import { cleanData, createYupSchema, recursivelyFindPathsBasedOnCondition } from './utils';
|
|
30
|
+
import { clearSetModifiedDataOnly } from '../../sharedReducers/crudReducer/actions';
|
|
31
|
+
import { usePrev } from '../../hooks';
|
|
25
32
|
|
|
26
33
|
const EditViewDataManagerProvider = ({
|
|
27
34
|
allLayoutData,
|
|
@@ -61,6 +68,9 @@ const EditViewDataManagerProvider = ({
|
|
|
61
68
|
publishConfirmation,
|
|
62
69
|
} = reducerState;
|
|
63
70
|
|
|
71
|
+
const { setModifiedDataOnly } = useSelector(selectCrudReducer);
|
|
72
|
+
const reduxDispatch = useDispatch();
|
|
73
|
+
|
|
64
74
|
const toggleNotification = useNotification();
|
|
65
75
|
const { lockApp, unlockApp } = useOverlayBlocker();
|
|
66
76
|
|
|
@@ -144,8 +154,18 @@ const EditViewDataManagerProvider = ({
|
|
|
144
154
|
|
|
145
155
|
const { components } = allLayoutData;
|
|
146
156
|
|
|
157
|
+
const previousInitialValues = usePrev(initialValues);
|
|
158
|
+
|
|
147
159
|
useEffect(() => {
|
|
148
|
-
|
|
160
|
+
/**
|
|
161
|
+
* Only fire this effect if the initialValues are different
|
|
162
|
+
* otherwise it's a fruitless effort no matter what happens.
|
|
163
|
+
*/
|
|
164
|
+
if (
|
|
165
|
+
initialValues &&
|
|
166
|
+
currentContentTypeLayout?.attributes &&
|
|
167
|
+
!isEqual(previousInitialValues, initialValues)
|
|
168
|
+
) {
|
|
149
169
|
/**
|
|
150
170
|
* This will return an array of paths:
|
|
151
171
|
* ['many_to_one', 'one_to_many', 'one_to_one']
|
|
@@ -179,9 +199,25 @@ const EditViewDataManagerProvider = ({
|
|
|
179
199
|
componentPaths,
|
|
180
200
|
repeatableComponentPaths,
|
|
181
201
|
dynamicZonePaths,
|
|
202
|
+
setModifiedDataOnly,
|
|
182
203
|
});
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* TODO: This should be moved to a side-effect e.g. thunks
|
|
207
|
+
* something to consider for V5
|
|
208
|
+
*/
|
|
209
|
+
if (setModifiedDataOnly) {
|
|
210
|
+
reduxDispatch(clearSetModifiedDataOnly());
|
|
211
|
+
}
|
|
183
212
|
}
|
|
184
|
-
}, [
|
|
213
|
+
}, [
|
|
214
|
+
initialValues,
|
|
215
|
+
currentContentTypeLayout,
|
|
216
|
+
components,
|
|
217
|
+
setModifiedDataOnly,
|
|
218
|
+
reduxDispatch,
|
|
219
|
+
previousInitialValues,
|
|
220
|
+
]);
|
|
185
221
|
|
|
186
222
|
const dispatchAddComponent = useCallback(
|
|
187
223
|
(type) =>
|
|
@@ -216,7 +252,7 @@ const EditViewDataManagerProvider = ({
|
|
|
216
252
|
/**
|
|
217
253
|
* @type {({ name: string, value: Relation, toOneRelation: boolean}) => void}
|
|
218
254
|
*/
|
|
219
|
-
const
|
|
255
|
+
const relationConnect = useCallback(({ name, value, toOneRelation }) => {
|
|
220
256
|
dispatch({
|
|
221
257
|
type: 'CONNECT_RELATION',
|
|
222
258
|
keys: name.split('.'),
|
|
@@ -225,7 +261,7 @@ const EditViewDataManagerProvider = ({
|
|
|
225
261
|
});
|
|
226
262
|
}, []);
|
|
227
263
|
|
|
228
|
-
const
|
|
264
|
+
const relationLoad = useCallback(({ target: { name, value } }) => {
|
|
229
265
|
dispatch({
|
|
230
266
|
type: 'LOAD_RELATION',
|
|
231
267
|
keys: name.split('.'),
|
|
@@ -498,16 +534,16 @@ const EditViewDataManagerProvider = ({
|
|
|
498
534
|
[shouldCheckDZErrors]
|
|
499
535
|
);
|
|
500
536
|
|
|
501
|
-
const moveComponentField = useCallback((
|
|
537
|
+
const moveComponentField = useCallback(({ name, newIndex, currentIndex }) => {
|
|
502
538
|
dispatch({
|
|
503
539
|
type: 'MOVE_COMPONENT_FIELD',
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
540
|
+
keys: name.split('.'),
|
|
541
|
+
newIndex,
|
|
542
|
+
oldIndex: currentIndex,
|
|
507
543
|
});
|
|
508
544
|
}, []);
|
|
509
545
|
|
|
510
|
-
const
|
|
546
|
+
const relationDisconnect = useCallback(({ name, id }) => {
|
|
511
547
|
dispatch({
|
|
512
548
|
type: 'DISCONNECT_RELATION',
|
|
513
549
|
keys: name.split('.'),
|
|
@@ -515,6 +551,25 @@ const EditViewDataManagerProvider = ({
|
|
|
515
551
|
});
|
|
516
552
|
}, []);
|
|
517
553
|
|
|
554
|
+
/**
|
|
555
|
+
* @typedef Payload
|
|
556
|
+
* @type {object}
|
|
557
|
+
* @property {string} name - The name of the field in `modifiedData`
|
|
558
|
+
* @property {number} oldIndex - The relation's current index
|
|
559
|
+
* @property {number} newIndex - The relation's new index
|
|
560
|
+
*
|
|
561
|
+
*
|
|
562
|
+
* @type {(payload: Payload) => void}
|
|
563
|
+
*/
|
|
564
|
+
const relationReorder = useCallback(({ name, oldIndex, newIndex }) => {
|
|
565
|
+
dispatch({
|
|
566
|
+
type: 'REORDER_RELATION',
|
|
567
|
+
keys: name.split('.'),
|
|
568
|
+
oldIndex,
|
|
569
|
+
newIndex,
|
|
570
|
+
});
|
|
571
|
+
}, []);
|
|
572
|
+
|
|
518
573
|
const removeComponentFromDynamicZone = useCallback(
|
|
519
574
|
(dynamicZoneName, index) => {
|
|
520
575
|
trackUsageRef.current('removeComponentFromDynamicZone');
|
|
@@ -565,7 +620,6 @@ const EditViewDataManagerProvider = ({
|
|
|
565
620
|
value={{
|
|
566
621
|
addComponentToDynamicZone,
|
|
567
622
|
addNonRepeatableComponentToField,
|
|
568
|
-
connectRelation,
|
|
569
623
|
addRepeatableComponentToField,
|
|
570
624
|
allLayoutData,
|
|
571
625
|
checkFormErrors,
|
|
@@ -578,20 +632,28 @@ const EditViewDataManagerProvider = ({
|
|
|
578
632
|
shouldNotRunValidations,
|
|
579
633
|
status,
|
|
580
634
|
layout: currentContentTypeLayout,
|
|
581
|
-
loadRelation,
|
|
582
635
|
modifiedData,
|
|
583
|
-
moveComponentDown,
|
|
584
636
|
moveComponentField,
|
|
637
|
+
/**
|
|
638
|
+
* @deprecated use `moveComponentField` instead. This will be removed in v5.
|
|
639
|
+
*/
|
|
640
|
+
moveComponentDown,
|
|
641
|
+
/**
|
|
642
|
+
* @deprecated use `moveComponentField` instead. This will be removed in v5.
|
|
643
|
+
*/
|
|
585
644
|
moveComponentUp,
|
|
586
645
|
onChange: handleChange,
|
|
587
646
|
onPublish: handlePublish,
|
|
588
647
|
onUnpublish,
|
|
589
|
-
disconnectRelation,
|
|
590
648
|
readActionAllowedFields,
|
|
591
649
|
redirectToPreviousPage,
|
|
592
650
|
removeComponentFromDynamicZone,
|
|
593
651
|
removeComponentFromField,
|
|
594
652
|
removeRepeatableField,
|
|
653
|
+
relationConnect,
|
|
654
|
+
relationDisconnect,
|
|
655
|
+
relationLoad,
|
|
656
|
+
relationReorder,
|
|
595
657
|
slug,
|
|
596
658
|
triggerFormValidation,
|
|
597
659
|
updateActionAllowedFields,
|
|
@@ -88,6 +88,7 @@ const reducer = (state, action) =>
|
|
|
88
88
|
? {
|
|
89
89
|
...state.componentsDataStructure[componentLayoutData.uid],
|
|
90
90
|
__component: componentLayoutData.uid,
|
|
91
|
+
__temp_key__: getMaxTempKey(currentValue) + 1,
|
|
91
92
|
}
|
|
92
93
|
: {
|
|
93
94
|
...state.componentsDataStructure[componentLayoutData.uid],
|
|
@@ -172,15 +173,29 @@ const reducer = (state, action) =>
|
|
|
172
173
|
const { id } = action;
|
|
173
174
|
const modifiedDataRelation = get(state, [...path]);
|
|
174
175
|
|
|
175
|
-
/**
|
|
176
|
-
* TODO: before merge make this performant (e.g. 1000 relations === long time)
|
|
177
|
-
*/
|
|
178
176
|
const newRelations = modifiedDataRelation.filter((rel) => rel.id !== id);
|
|
179
177
|
|
|
180
178
|
set(draftState, path, newRelations);
|
|
181
179
|
|
|
182
180
|
break;
|
|
183
181
|
}
|
|
182
|
+
case 'MOVE_COMPONENT_FIELD':
|
|
183
|
+
case 'REORDER_RELATION': {
|
|
184
|
+
const { oldIndex, newIndex, keys } = action;
|
|
185
|
+
const path = ['modifiedData', ...keys];
|
|
186
|
+
const modifiedDataRelations = get(state, [...path]);
|
|
187
|
+
|
|
188
|
+
const currentItem = modifiedDataRelations[oldIndex];
|
|
189
|
+
|
|
190
|
+
const newRelations = [...modifiedDataRelations];
|
|
191
|
+
|
|
192
|
+
newRelations.splice(oldIndex, 1);
|
|
193
|
+
newRelations.splice(newIndex, 0, currentItem);
|
|
194
|
+
|
|
195
|
+
set(draftState, path, newRelations);
|
|
196
|
+
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
184
199
|
/**
|
|
185
200
|
* This action will be called when you open your entry (first load)
|
|
186
201
|
* but also every time you press publish.
|
|
@@ -192,6 +207,7 @@ const reducer = (state, action) =>
|
|
|
192
207
|
componentPaths = [],
|
|
193
208
|
repeatableComponentPaths = [],
|
|
194
209
|
dynamicZonePaths = [],
|
|
210
|
+
setModifiedDataOnly,
|
|
195
211
|
} = action;
|
|
196
212
|
|
|
197
213
|
/**
|
|
@@ -243,7 +259,10 @@ const reducer = (state, action) =>
|
|
|
243
259
|
return acc;
|
|
244
260
|
}, data);
|
|
245
261
|
|
|
246
|
-
|
|
262
|
+
if (!setModifiedDataOnly) {
|
|
263
|
+
draftState.initialData = mergeDataWithPreparedRelations;
|
|
264
|
+
}
|
|
265
|
+
|
|
247
266
|
draftState.modifiedData = mergeDataWithPreparedRelations;
|
|
248
267
|
|
|
249
268
|
draftState.formErrors = {};
|
|
@@ -252,25 +271,6 @@ const reducer = (state, action) =>
|
|
|
252
271
|
draftState.shouldCheckErrors = false;
|
|
253
272
|
break;
|
|
254
273
|
}
|
|
255
|
-
case 'MOVE_COMPONENT_FIELD': {
|
|
256
|
-
const currentValue = get(state, ['modifiedData', ...action.pathToComponent]);
|
|
257
|
-
const valueToInsert = get(state, [
|
|
258
|
-
'modifiedData',
|
|
259
|
-
...action.pathToComponent,
|
|
260
|
-
action.dragIndex,
|
|
261
|
-
]);
|
|
262
|
-
|
|
263
|
-
const updatedValue = moveFields(
|
|
264
|
-
currentValue,
|
|
265
|
-
action.dragIndex,
|
|
266
|
-
action.hoverIndex,
|
|
267
|
-
valueToInsert
|
|
268
|
-
);
|
|
269
|
-
|
|
270
|
-
set(draftState, ['modifiedData', ...action.pathToComponent], updatedValue);
|
|
271
|
-
|
|
272
|
-
break;
|
|
273
|
-
}
|
|
274
274
|
case 'MOVE_COMPONENT_UP':
|
|
275
275
|
case 'MOVE_COMPONENT_DOWN': {
|
|
276
276
|
const { currentIndex, dynamicZoneName, shouldCheckErrors } = action;
|
|
@@ -84,14 +84,28 @@ const cleanData = ({ browserState, serverState }, currentSchema, componentsSchem
|
|
|
84
84
|
*/
|
|
85
85
|
let actualOldValue = oldValue ?? [];
|
|
86
86
|
|
|
87
|
+
const valuesWithPositions = value.map((relation, index, allRelations) => {
|
|
88
|
+
const nextRelation = allRelations[index + 1];
|
|
89
|
+
|
|
90
|
+
if (nextRelation) {
|
|
91
|
+
return { ...relation, position: { before: nextRelation.id } };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return { ...relation, position: { end: true } };
|
|
95
|
+
});
|
|
96
|
+
|
|
87
97
|
/**
|
|
88
98
|
* Instead of the full relation object, we only want to send its ID
|
|
89
99
|
* connectedRelations are the items that are in the browserState
|
|
90
100
|
* array but not in the serverState
|
|
91
101
|
*/
|
|
92
|
-
const connectedRelations =
|
|
93
|
-
|
|
94
|
-
|
|
102
|
+
const connectedRelations = valuesWithPositions.reduce((acc, relation, currentIndex) => {
|
|
103
|
+
const indexOfRelationOnServer = actualOldValue.findIndex(
|
|
104
|
+
(oldRelation) => oldRelation.id === relation.id
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
if (indexOfRelationOnServer === -1 || indexOfRelationOnServer !== currentIndex) {
|
|
108
|
+
return [...acc, { id: relation.id, position: relation.position }];
|
|
95
109
|
}
|
|
96
110
|
|
|
97
111
|
return acc;
|
|
@@ -102,7 +116,7 @@ const cleanData = ({ browserState, serverState }, currentSchema, componentsSchem
|
|
|
102
116
|
* are no longer in the browserState
|
|
103
117
|
*/
|
|
104
118
|
const disconnectedRelations = actualOldValue.reduce((acc, relation) => {
|
|
105
|
-
if (!
|
|
119
|
+
if (!valuesWithPositions.find((newRelation) => newRelation.id === relation.id)) {
|
|
106
120
|
return [...acc, { id: relation.id }];
|
|
107
121
|
}
|
|
108
122
|
|
|
@@ -111,7 +125,12 @@ const cleanData = ({ browserState, serverState }, currentSchema, componentsSchem
|
|
|
111
125
|
|
|
112
126
|
cleanedData = {
|
|
113
127
|
disconnect: disconnectedRelations,
|
|
114
|
-
|
|
128
|
+
/**
|
|
129
|
+
* Reverse the array because the API sequentially goes through the list
|
|
130
|
+
* so in an instance where you add two to the end it would fail because index0
|
|
131
|
+
* would want to attach itself to index1 which doesn't exist yet.
|
|
132
|
+
*/
|
|
133
|
+
connect: connectedRelations.reverse(),
|
|
115
134
|
};
|
|
116
135
|
|
|
117
136
|
break;
|
|
@@ -55,8 +55,15 @@ const recursivelyFindPathsBasedOnConditionSetup = (components, predicate = () =>
|
|
|
55
55
|
*
|
|
56
56
|
* NOTE: we don't need to know the path to the `array` because it's about data shape not about the actual data
|
|
57
57
|
*/
|
|
58
|
-
}).map((path) =>
|
|
58
|
+
}).map((path) => {
|
|
59
|
+
return path.split(`${componentName}.`)[1];
|
|
60
|
+
});
|
|
59
61
|
})
|
|
62
|
+
/**
|
|
63
|
+
* We filter because this will give you `dynamiczone.undefined` because the dynamic_zone component
|
|
64
|
+
* is not required to be returned in this circumstance.
|
|
65
|
+
*/
|
|
66
|
+
.filter((path) => Boolean(path))
|
|
60
67
|
.map((path) => `${key}.${path}`);
|
|
61
68
|
|
|
62
69
|
acc = [...acc, attributesInDynamicComponents];
|
|
@@ -5,7 +5,7 @@ import get from 'lodash/get';
|
|
|
5
5
|
import omit from 'lodash/omit';
|
|
6
6
|
import take from 'lodash/take';
|
|
7
7
|
import isEqual from 'react-fast-compare';
|
|
8
|
-
import { GenericInput, NotAllowedInput, useLibrary
|
|
8
|
+
import { GenericInput, NotAllowedInput, useLibrary } from '@strapi/helper-plugin';
|
|
9
9
|
import { useContentTypeLayout } from '../../hooks';
|
|
10
10
|
import { getFieldName } from '../../utils';
|
|
11
11
|
import Wysiwyg from '../Wysiwyg';
|
|
@@ -37,11 +37,11 @@ function Inputs({
|
|
|
37
37
|
queryInfos,
|
|
38
38
|
value,
|
|
39
39
|
size,
|
|
40
|
+
customFieldInputs,
|
|
40
41
|
}) {
|
|
41
42
|
const { fields } = useLibrary();
|
|
42
43
|
const { formatMessage } = useIntl();
|
|
43
44
|
const { contentType: currentContentTypeLayout } = useContentTypeLayout();
|
|
44
|
-
const customFieldsRegistry = useCustomFields();
|
|
45
45
|
|
|
46
46
|
const disabled = useMemo(() => !get(metadatas, 'editable', true), [metadatas]);
|
|
47
47
|
const { type, customField: customFieldUid } = fieldSchema;
|
|
@@ -194,19 +194,6 @@ function Inputs({
|
|
|
194
194
|
return minutes % metadatas.step === 0 ? metadatas.step : step;
|
|
195
195
|
}, [inputType, inputValue, metadatas.step, step]);
|
|
196
196
|
|
|
197
|
-
// Memoize the component to avoid remounting it and losing state
|
|
198
|
-
const CustomFieldInput = useMemo(() => {
|
|
199
|
-
if (customFieldUid) {
|
|
200
|
-
const customField = customFieldsRegistry.get(customFieldUid);
|
|
201
|
-
const CustomFieldInput = React.lazy(customField.components.Input);
|
|
202
|
-
|
|
203
|
-
return CustomFieldInput;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// Not a custom field, component won't be used
|
|
207
|
-
return null;
|
|
208
|
-
}, [customFieldUid, customFieldsRegistry]);
|
|
209
|
-
|
|
210
197
|
if (visible === false) {
|
|
211
198
|
return null;
|
|
212
199
|
}
|
|
@@ -268,12 +255,9 @@ function Inputs({
|
|
|
268
255
|
media: fields.media,
|
|
269
256
|
wysiwyg: Wysiwyg,
|
|
270
257
|
...fields,
|
|
258
|
+
...customFieldInputs,
|
|
271
259
|
};
|
|
272
260
|
|
|
273
|
-
if (customFieldUid) {
|
|
274
|
-
customInputs[customFieldUid] = CustomFieldInput;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
261
|
return (
|
|
278
262
|
<GenericInput
|
|
279
263
|
attribute={fieldSchema}
|
|
@@ -309,6 +293,7 @@ Inputs.defaultProps = {
|
|
|
309
293
|
size: undefined,
|
|
310
294
|
value: null,
|
|
311
295
|
queryInfos: {},
|
|
296
|
+
customFieldInputs: {},
|
|
312
297
|
};
|
|
313
298
|
|
|
314
299
|
Inputs.propTypes = {
|
|
@@ -330,6 +315,7 @@ Inputs.propTypes = {
|
|
|
330
315
|
defaultParams: PropTypes.object,
|
|
331
316
|
endPoint: PropTypes.string,
|
|
332
317
|
}),
|
|
318
|
+
customFieldInputs: PropTypes.object,
|
|
333
319
|
};
|
|
334
320
|
|
|
335
321
|
const Memoized = memo(Inputs, isEqual);
|
|
@@ -9,6 +9,7 @@ import { Stack } from '@strapi/design-system/Stack';
|
|
|
9
9
|
import { useContentTypeLayout } from '../../hooks';
|
|
10
10
|
import FieldComponent from '../FieldComponent';
|
|
11
11
|
import Inputs from '../Inputs';
|
|
12
|
+
import useLazyComponents from '../../hooks/useLazyComponents';
|
|
12
13
|
|
|
13
14
|
const NonRepeatableComponent = ({ componentUid, isFromDynamicZone, isNested, name }) => {
|
|
14
15
|
const { getComponentLayout } = useContentTypeLayout();
|
|
@@ -18,6 +19,8 @@ const NonRepeatableComponent = ({ componentUid, isFromDynamicZone, isNested, nam
|
|
|
18
19
|
);
|
|
19
20
|
const fields = componentLayoutData.layouts.edit;
|
|
20
21
|
|
|
22
|
+
const { lazyComponentStore } = useLazyComponents();
|
|
23
|
+
|
|
21
24
|
return (
|
|
22
25
|
<Box
|
|
23
26
|
background={isFromDynamicZone ? '' : 'neutral100'}
|
|
@@ -67,6 +70,7 @@ const NonRepeatableComponent = ({ componentUid, isFromDynamicZone, isNested, nam
|
|
|
67
70
|
metadatas={metadatas}
|
|
68
71
|
queryInfos={queryInfos}
|
|
69
72
|
size={size}
|
|
73
|
+
customFieldInputs={lazyComponentStore}
|
|
70
74
|
/>
|
|
71
75
|
</GridItem>
|
|
72
76
|
);
|