@strapi/admin 4.5.2 → 4.5.4
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/components/AuthenticatedApp/index.js +13 -2
- package/admin/src/content-manager/components/DynamicZone/components/DynamicComponent.js +1 -1
- package/admin/src/content-manager/components/EditViewDataManagerProvider/index.js +39 -3
- package/admin/src/content-manager/components/EditViewDataManagerProvider/reducer.js +5 -1
- 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 +4 -9
- package/admin/src/content-manager/components/RelationInputDataManager/RelationInputDataManager.js +1 -1
- package/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js +4 -0
- 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/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/core/apis/CustomFields.js +46 -1
- 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/App/index.js +20 -13
- package/admin/src/pages/HomePage/SocialLinks.js +4 -4
- package/admin/src/pages/MarketplacePage/components/SortSelect/index.js +20 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js +2 -3
- package/admin/src/pages/SettingsPage/pages/Users/ListPage/ModalForm/index.js +23 -18
- package/admin/src/translations/en.json +4 -0
- package/admin/src/translations/ru.json +789 -489
- package/admin/src/translations/tr.json +485 -5
- package/admin/src/utils/fetchClient.js +45 -0
- package/admin/src/utils/getFetchClient.js +10 -0
- package/admin/src/utils/index.js +1 -0
- package/admin/src/utils/uniqueAdminHash.js +22 -0
- package/build/{1233.bddaaa76.chunk.js → 1233.802422fa.chunk.js} +63 -63
- package/build/4306.df40a798.chunk.js +98 -0
- package/build/4318.9283c350.chunk.js +30 -0
- 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.e929d326.chunk.js} +3 -3
- package/build/{8633.8da5488a.chunk.js → 8633.43ec9042.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.0da578b8.chunk.js +80 -0
- package/build/{Admin_homePage.54e33c2d.chunk.js → Admin_homePage.8945f71a.chunk.js} +5 -5
- package/build/{Admin_marketplace.ff012eb2.chunk.js → Admin_marketplace.ed754a4a.chunk.js} +5 -5
- package/build/{Admin_profilePage.e9fcce92.chunk.js → Admin_profilePage.60ab80bb.chunk.js} +1 -1
- package/build/{Admin_settingsPage.a1a5218b.chunk.js → Admin_settingsPage.6ef8acc9.chunk.js} +6 -6
- package/build/admin-app.a3277e72.chunk.js +112 -0
- package/build/admin-edit-roles-page.f407538c.chunk.js +1 -0
- package/build/admin-edit-users.5547b126.chunk.js +10 -0
- package/build/{admin-users.a0748674.chunk.js → admin-users.e64fb0f1.chunk.js} +1 -1
- package/build/content-manager.f9630c3b.chunk.js +1197 -0
- package/build/content-type-builder-list-view.4412efc3.chunk.js +201 -0
- package/build/content-type-builder-translation-tr-json.949e22eb.chunk.js +1 -0
- package/build/content-type-builder.b132b5f4.chunk.js +145 -0
- package/build/email-settings-page.c6e62f6b.chunk.js +15 -0
- package/build/email-translation-tr-json.8aa034bb.chunk.js +1 -0
- package/build/en-json.7dd57947.chunk.js +1 -0
- package/build/i18n-translation-tr-json.34ca9d61.chunk.js +1 -0
- package/build/index.html +1 -1
- package/build/main.71f24343.js +2034 -0
- package/build/ru-json.8830286f.chunk.js +1 -0
- package/build/runtime~main.1115f82b.js +2 -0
- package/build/sso-settings-page.feed2f45.chunk.js +1 -0
- package/build/tr-json.eac8bd79.chunk.js +1 -0
- package/build/upload-settings.450cab1a.chunk.js +18 -0
- package/build/upload-translation-tr-json.b173223a.chunk.js +1 -0
- package/build/upload.74540aab.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-permissions-translation-tr-json.9bebc250.chunk.js +1 -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/package.json +13 -13
- package/server/controllers/admin.js +2 -0
- package/server/routes/admin.js +1 -1
- package/server/services/metrics.js +5 -2
- package/utils/get-plugins-path.js +17 -3
- package/build/1920.208c77f8.chunk.js +0 -245
- package/build/2438.afe24949.chunk.js +0 -2525
- package/build/2517.5cc235ba.chunk.js +0 -117
- package/build/4306.e62b841c.chunk.js +0 -98
- package/build/4318.7931eee7.chunk.js +0 -30
- package/build/9707.932a3c12.chunk.js +0 -70
- package/build/Admin-authenticatedApp.7484bdf1.chunk.js +0 -80
- package/build/admin-app.9cb0abc7.chunk.js +0 -112
- package/build/admin-edit-roles-page.23f15909.chunk.js +0 -1
- package/build/admin-edit-users.283b49ed.chunk.js +0 -10
- package/build/content-manager.577fddcb.chunk.js +0 -1200
- package/build/content-type-builder-list-view.95012cf0.chunk.js +0 -201
- package/build/content-type-builder-translation-tr-json.2e52bc60.chunk.js +0 -1
- package/build/content-type-builder.95b9d6a2.chunk.js +0 -145
- package/build/email-settings-page.4bb3606f.chunk.js +0 -15
- package/build/email-translation-tr-json.87f2feb3.chunk.js +0 -1
- package/build/en-json.4a269f6b.chunk.js +0 -1
- package/build/main.23670c4c.js +0 -2026
- package/build/ru-json.d7cfc2ff.chunk.js +0 -1
- package/build/runtime~main.4dc8c7c6.js +0 -2
- package/build/sso-settings-page.9f091262.chunk.js +0 -1
- package/build/tr-json.9c44ea0c.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-permissions-translation-tr-json.cdc49a3c.chunk.js +0 -1
- 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.3285abc4.chunk.js +0 -75
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
fetchUserRoles,
|
|
21
21
|
} from './utils/api';
|
|
22
22
|
import checkLatestStrapiVersion from './utils/checkLatestStrapiVersion';
|
|
23
|
-
import { getFullName } from '../../utils';
|
|
23
|
+
import { getFullName, hashAdminUserEmail } from '../../utils';
|
|
24
24
|
|
|
25
25
|
const strapiVersion = packageJSON.version;
|
|
26
26
|
|
|
@@ -31,6 +31,7 @@ const AuthenticatedApp = () => {
|
|
|
31
31
|
const userInfo = auth.getUserInfo();
|
|
32
32
|
const userName = get(userInfo, 'username') || getFullName(userInfo.firstname, userInfo.lastname);
|
|
33
33
|
const [userDisplayName, setUserDisplayName] = useState(userName);
|
|
34
|
+
const [userId, setUserId] = useState(null);
|
|
34
35
|
const { showReleaseNotification } = useConfigurations();
|
|
35
36
|
const [
|
|
36
37
|
{ data: appInfos, status },
|
|
@@ -71,6 +72,15 @@ const AuthenticatedApp = () => {
|
|
|
71
72
|
}
|
|
72
73
|
}, [userRoles, appInfos]);
|
|
73
74
|
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
const getUserId = async () => {
|
|
77
|
+
const userId = await hashAdminUserEmail(userInfo);
|
|
78
|
+
setUserId(userId);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
getUserId();
|
|
82
|
+
}, [userInfo]);
|
|
83
|
+
|
|
74
84
|
// We don't need to wait for the release query to be fetched before rendering the plugins
|
|
75
85
|
// however, we need the appInfos and the permissions
|
|
76
86
|
const shouldShowNotDependentQueriesLoader =
|
|
@@ -81,12 +91,13 @@ const AuthenticatedApp = () => {
|
|
|
81
91
|
const appInfosValue = useMemo(() => {
|
|
82
92
|
return {
|
|
83
93
|
...appInfos,
|
|
94
|
+
userId,
|
|
84
95
|
latestStrapiReleaseTag: tag_name,
|
|
85
96
|
setUserDisplayName,
|
|
86
97
|
shouldUpdateStrapi,
|
|
87
98
|
userDisplayName,
|
|
88
99
|
};
|
|
89
|
-
}, [appInfos, tag_name, shouldUpdateStrapi, userDisplayName]);
|
|
100
|
+
}, [appInfos, tag_name, shouldUpdateStrapi, userDisplayName, userId]);
|
|
90
101
|
|
|
91
102
|
if (shouldShowLoader) {
|
|
92
103
|
return <LoadingIndicatorPage />;
|
|
@@ -111,7 +111,7 @@ const DynamicZoneComponent = ({
|
|
|
111
111
|
<StyledBox hasRadius>
|
|
112
112
|
<Accordion expanded={isOpen} onToggle={handleToggle} size="S" error={errorMessage}>
|
|
113
113
|
<AccordionToggle
|
|
114
|
-
startIcon={<FontAwesomeIcon icon={icon} />}
|
|
114
|
+
startIcon={icon && <FontAwesomeIcon icon={icon} />}
|
|
115
115
|
action={
|
|
116
116
|
<Stack horizontal spacing={0} expanded={isOpen}>
|
|
117
117
|
{showDownIcon && (
|
|
@@ -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) =>
|
|
@@ -192,6 +192,7 @@ const reducer = (state, action) =>
|
|
|
192
192
|
componentPaths = [],
|
|
193
193
|
repeatableComponentPaths = [],
|
|
194
194
|
dynamicZonePaths = [],
|
|
195
|
+
setModifiedDataOnly,
|
|
195
196
|
} = action;
|
|
196
197
|
|
|
197
198
|
/**
|
|
@@ -243,7 +244,10 @@ const reducer = (state, action) =>
|
|
|
243
244
|
return acc;
|
|
244
245
|
}, data);
|
|
245
246
|
|
|
246
|
-
|
|
247
|
+
if (!setModifiedDataOnly) {
|
|
248
|
+
draftState.initialData = mergeDataWithPreparedRelations;
|
|
249
|
+
}
|
|
250
|
+
|
|
247
251
|
draftState.modifiedData = mergeDataWithPreparedRelations;
|
|
248
252
|
|
|
249
253
|
draftState.formErrors = {};
|
|
@@ -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
|
);
|
|
@@ -24,18 +24,13 @@ import { RELATION_ITEM_HEIGHT } from './constants';
|
|
|
24
24
|
import { usePrev } from '../../hooks';
|
|
25
25
|
|
|
26
26
|
const LinkEllipsis = styled(Link)`
|
|
27
|
-
|
|
28
|
-
overflow: hidden;
|
|
29
|
-
text-overflow: ellipsis;
|
|
30
|
-
display: inherit;
|
|
31
|
-
`;
|
|
27
|
+
display: block;
|
|
32
28
|
|
|
33
|
-
const BoxEllipsis = styled(Box)`
|
|
34
29
|
> span {
|
|
35
30
|
white-space: nowrap;
|
|
36
31
|
overflow: hidden;
|
|
37
32
|
text-overflow: ellipsis;
|
|
38
|
-
display:
|
|
33
|
+
display: block;
|
|
39
34
|
}
|
|
40
35
|
`;
|
|
41
36
|
|
|
@@ -322,7 +317,7 @@ const RelationInput = ({
|
|
|
322
317
|
}
|
|
323
318
|
style={style}
|
|
324
319
|
>
|
|
325
|
-
<
|
|
320
|
+
<Box minWidth={0} paddingTop={1} paddingBottom={1} paddingRight={4}>
|
|
326
321
|
<Tooltip description={mainField ?? `${id}`}>
|
|
327
322
|
{href ? (
|
|
328
323
|
<LinkEllipsis to={href} disabled={disabled}>
|
|
@@ -334,7 +329,7 @@ const RelationInput = ({
|
|
|
334
329
|
</Typography>
|
|
335
330
|
)}
|
|
336
331
|
</Tooltip>
|
|
337
|
-
</
|
|
332
|
+
</Box>
|
|
338
333
|
|
|
339
334
|
{publicationState && (
|
|
340
335
|
<Status variant={statusColor} showBullet={false} size="S">
|
package/admin/src/content-manager/components/RelationInputDataManager/RelationInputDataManager.js
CHANGED
|
@@ -40,7 +40,7 @@ export const RelationInputDataManager = ({
|
|
|
40
40
|
const { connectRelation, disconnectRelation, loadRelation, modifiedData, slug, initialData } =
|
|
41
41
|
useCMEditViewDataManager();
|
|
42
42
|
|
|
43
|
-
const relationsFromModifiedData = get(modifiedData, name
|
|
43
|
+
const relationsFromModifiedData = get(modifiedData, name, []);
|
|
44
44
|
|
|
45
45
|
const currentLastPage = Math.ceil(get(initialData, name, []).length / RELATIONS_TO_DISPLAY);
|
|
46
46
|
|
|
@@ -21,6 +21,7 @@ import Preview from './Preview';
|
|
|
21
21
|
import DraggingSibling from './DraggingSibling';
|
|
22
22
|
import { CustomIconButton } from './IconButtonCustoms';
|
|
23
23
|
import { connect, select } from './utils';
|
|
24
|
+
import useLazyComponents from '../../../hooks/useLazyComponents';
|
|
24
25
|
|
|
25
26
|
const DragButton = styled.span`
|
|
26
27
|
display: flex;
|
|
@@ -177,6 +178,8 @@ const DraggedItem = ({
|
|
|
177
178
|
const accordionTitle = toString(displayedValue);
|
|
178
179
|
const accordionHasError = hasErrors ? 'error' : undefined;
|
|
179
180
|
|
|
181
|
+
const { lazyComponentStore } = useLazyComponents();
|
|
182
|
+
|
|
180
183
|
return (
|
|
181
184
|
<Box ref={refs ? refs.dropRef : null}>
|
|
182
185
|
{isDragging && <Preview />}
|
|
@@ -273,6 +276,7 @@ const DraggedItem = ({
|
|
|
273
276
|
// onBlur={hasErrors ? checkFormErrors : null}
|
|
274
277
|
queryInfos={queryInfos}
|
|
275
278
|
size={size}
|
|
279
|
+
customFieldInputs={lazyComponentStore}
|
|
276
280
|
/>
|
|
277
281
|
</GridItem>
|
|
278
282
|
);
|
|
@@ -103,7 +103,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
|
|
|
103
103
|
setIsCreatingEntry(true);
|
|
104
104
|
|
|
105
105
|
try {
|
|
106
|
-
const { data } = await axiosInstance(getRequestUrl(`${slug}${searchToSend}`), {
|
|
106
|
+
const { data } = await axiosInstance.get(getRequestUrl(`${slug}${searchToSend}`), {
|
|
107
107
|
cancelToken: source.token,
|
|
108
108
|
});
|
|
109
109
|
|
|
@@ -43,7 +43,7 @@ const Editor = ({
|
|
|
43
43
|
}, [editorRef, textareaRef, name, placeholder]);
|
|
44
44
|
|
|
45
45
|
useEffect(() => {
|
|
46
|
-
if (value && !editorRef.current.
|
|
46
|
+
if (value && !editorRef.current.hasFocus()) {
|
|
47
47
|
editorRef.current.setValue(value);
|
|
48
48
|
}
|
|
49
49
|
}, [editorRef, value]);
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
2
|
+
import { useCustomFields } from '@strapi/helper-plugin';
|
|
3
|
+
|
|
4
|
+
const componentStore = new Map();
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @description
|
|
8
|
+
* A hook to lazy load custom field components
|
|
9
|
+
* @param {Array.<string>} componentUids - The uids to look up components
|
|
10
|
+
* @returns object
|
|
11
|
+
*/
|
|
12
|
+
const useLazyComponents = (componentUids = []) => {
|
|
13
|
+
const [lazyComponentStore, setLazyComponentStore] = useState(Object.fromEntries(componentStore));
|
|
14
|
+
const [loading, setLoading] = useState(() => {
|
|
15
|
+
if (componentStore.size === 0 && componentUids.length > 0) {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return false;
|
|
20
|
+
});
|
|
21
|
+
const customFieldsRegistry = useCustomFields();
|
|
22
|
+
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const setStore = (store) => {
|
|
25
|
+
setLazyComponentStore(store);
|
|
26
|
+
setLoading(false);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const lazyLoadComponents = async (uids, components) => {
|
|
30
|
+
const modules = await Promise.all(components);
|
|
31
|
+
|
|
32
|
+
uids.forEach((uid, index) => {
|
|
33
|
+
componentStore.set(uid, modules[index].default);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
setStore(Object.fromEntries(componentStore));
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
if (componentUids.length && loading) {
|
|
40
|
+
/**
|
|
41
|
+
* These uids are not in the component store therefore we need to get the components
|
|
42
|
+
*/
|
|
43
|
+
const newUids = componentUids.filter((uid) => !componentStore.get(uid));
|
|
44
|
+
|
|
45
|
+
const componentPromises = newUids.map((uid) => {
|
|
46
|
+
const customField = customFieldsRegistry.get(uid);
|
|
47
|
+
|
|
48
|
+
return customField.components.Input();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
if (componentPromises.length > 0) {
|
|
52
|
+
lazyLoadComponents(newUids, componentPromises);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}, [componentUids, customFieldsRegistry, loading]);
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Wrap this in a callback so it can be used in
|
|
59
|
+
* effects to cleanup the cached store if required
|
|
60
|
+
*/
|
|
61
|
+
const cleanup = useCallback(() => {
|
|
62
|
+
componentStore.clear();
|
|
63
|
+
setLazyComponentStore({});
|
|
64
|
+
}, []);
|
|
65
|
+
|
|
66
|
+
return { isLazyLoading: loading, lazyComponentStore, cleanup };
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export default useLazyComponents;
|
package/admin/src/content-manager/pages/CollectionTypeRecursivePath/components/ErrorFallback.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { AnErrorOccurred } from '@strapi/helper-plugin';
|
|
3
|
+
import { Box } from '@strapi/design-system/Box';
|
|
4
|
+
|
|
5
|
+
const ErrorFallback = () => {
|
|
6
|
+
return (
|
|
7
|
+
<Box padding={8}>
|
|
8
|
+
<AnErrorOccurred />
|
|
9
|
+
</Box>
|
|
10
|
+
);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default ErrorFallback;
|
|
@@ -3,7 +3,7 @@ import { Switch, Route } from 'react-router-dom';
|
|
|
3
3
|
import { ErrorBoundary } from 'react-error-boundary';
|
|
4
4
|
import { get } from 'lodash';
|
|
5
5
|
import PropTypes from 'prop-types';
|
|
6
|
-
import {
|
|
6
|
+
import { LoadingIndicatorPage, CheckPagePermissions } from '@strapi/helper-plugin';
|
|
7
7
|
import permissions from '../../../permissions';
|
|
8
8
|
import { ContentTypeLayoutContext } from '../../contexts';
|
|
9
9
|
import { useFetchContentTypeLayout } from '../../hooks';
|
|
@@ -12,6 +12,7 @@ import EditViewLayoutManager from '../EditViewLayoutManager';
|
|
|
12
12
|
import EditSettingsView from '../EditSettingsView';
|
|
13
13
|
import ListViewLayout from '../ListViewLayoutManager';
|
|
14
14
|
import ListSettingsView from '../ListSettingsView';
|
|
15
|
+
import ErrorFallback from './components/ErrorFallback';
|
|
15
16
|
|
|
16
17
|
const cmPermissions = permissions.contentManager;
|
|
17
18
|
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { Grid, GridItem } from '@strapi/design-system/Grid';
|
|
4
|
+
import Inputs from '../../../components/Inputs';
|
|
5
|
+
import FieldComponent from '../../../components/FieldComponent';
|
|
6
|
+
|
|
7
|
+
const GridRow = ({ columns, customFieldInputs }) => {
|
|
8
|
+
return (
|
|
9
|
+
<Grid gap={4}>
|
|
10
|
+
{columns.map(({ fieldSchema, labelAction, metadatas, name, size, queryInfos }) => {
|
|
11
|
+
const isComponent = fieldSchema.type === 'component';
|
|
12
|
+
|
|
13
|
+
if (isComponent) {
|
|
14
|
+
const { component, max, min, repeatable = false, required = false } = fieldSchema;
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<GridItem col={size} s={12} xs={12} key={component}>
|
|
18
|
+
<FieldComponent
|
|
19
|
+
componentUid={component}
|
|
20
|
+
labelAction={labelAction}
|
|
21
|
+
isRepeatable={repeatable}
|
|
22
|
+
intlLabel={{
|
|
23
|
+
id: metadatas.label,
|
|
24
|
+
defaultMessage: metadatas.label,
|
|
25
|
+
}}
|
|
26
|
+
max={max}
|
|
27
|
+
min={min}
|
|
28
|
+
name={name}
|
|
29
|
+
required={required}
|
|
30
|
+
/>
|
|
31
|
+
</GridItem>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<GridItem col={size} key={name} s={12} xs={12}>
|
|
37
|
+
<Inputs
|
|
38
|
+
size={size}
|
|
39
|
+
fieldSchema={fieldSchema}
|
|
40
|
+
keys={name}
|
|
41
|
+
labelAction={labelAction}
|
|
42
|
+
metadatas={metadatas}
|
|
43
|
+
queryInfos={queryInfos}
|
|
44
|
+
customFieldInputs={customFieldInputs}
|
|
45
|
+
/>
|
|
46
|
+
</GridItem>
|
|
47
|
+
);
|
|
48
|
+
})}
|
|
49
|
+
</Grid>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
GridRow.defaultProps = {
|
|
54
|
+
customFieldInputs: {},
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
GridRow.propTypes = {
|
|
58
|
+
columns: PropTypes.array.isRequired,
|
|
59
|
+
customFieldInputs: PropTypes.object,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export default GridRow;
|