@strapi/admin 4.6.0 → 4.6.1

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 (144) hide show
  1. package/.browserslistrc +2 -1
  2. package/admin/src/components/AuthenticatedApp/utils/api.js +5 -4
  3. package/admin/src/components/LeftMenu/index.js +9 -3
  4. package/admin/src/content-manager/components/CollectionTypeFormWrapper/index.js +20 -16
  5. package/admin/src/content-manager/components/DynamicTable/CellContent/RelationMultiple/index.js +5 -5
  6. package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/findLeafByPathAndReplace.js +1 -3
  7. package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/schema.js +6 -5
  8. package/admin/src/content-manager/components/InputUID/index.js +4 -4
  9. package/admin/src/content-manager/components/Inputs/index.js +0 -2
  10. package/admin/src/content-manager/components/SingleTypeFormWrapper/index.js +35 -14
  11. package/admin/src/content-manager/hooks/useFetchContentTypeLayout/index.js +4 -3
  12. package/admin/src/content-manager/hooks/useLazyComponents/index.js +9 -13
  13. package/admin/src/content-manager/hooks/useRelation/useRelation.js +4 -4
  14. package/admin/src/content-manager/pages/App/useModels.js +8 -3
  15. package/admin/src/content-manager/pages/App/utils/getContentTypeLinks.js +3 -2
  16. package/admin/src/content-manager/pages/ComponentSetttingsView/index.js +4 -4
  17. package/admin/src/content-manager/pages/EditSettingsView/utils/api.js +4 -2
  18. package/admin/src/content-manager/pages/ListSettingsView/utils/api.js +4 -2
  19. package/admin/src/content-manager/pages/ListView/index.js +9 -9
  20. package/admin/src/core/utils/index.js +0 -1
  21. package/admin/src/hooks/useFetchEnabledPlugins/utils/api.js +3 -2
  22. package/admin/src/hooks/useInjectReducer/index.js +1 -0
  23. package/admin/src/hooks/useInjectReducer/useInjectReducer.js +19 -0
  24. package/admin/src/hooks/useRegenerate/index.js +3 -3
  25. package/admin/src/hooks/useRolesList/index.js +5 -3
  26. package/admin/src/index.js +4 -3
  27. package/admin/src/pages/ProfilePage/utils/api.js +5 -3
  28. package/admin/src/pages/SettingsPage/{pages/Users/ListPage → components}/Filters/index.js +0 -0
  29. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js +6 -5
  30. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/index.js +4 -3
  31. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/api.js +5 -3
  32. package/admin/src/pages/SettingsPage/pages/Users/EditPage/utils/api.js +6 -3
  33. package/admin/src/pages/SettingsPage/pages/Users/ListPage/ModalForm/index.js +9 -3
  34. package/admin/src/pages/SettingsPage/pages/Users/ListPage/index.js +1 -1
  35. package/admin/src/pages/SettingsPage/pages/Users/ListPage/utils/api.js +6 -3
  36. package/admin/src/pages/SettingsPage/pages/Users/components/SelectRoles/index.js +3 -2
  37. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/index.js +3 -2
  38. package/admin/src/translations/en.json +7 -5
  39. package/admin/src/translations/eu.json +796 -0
  40. package/admin/src/translations/languageNativeNames.js +1 -0
  41. package/admin/src/translations/ru.json +9 -9
  42. package/build/1412.936ed920.chunk.js +159 -0
  43. package/build/1683.c8aa7b7c.chunk.js +268 -0
  44. package/build/2607.2e48dbf8.chunk.js +66 -0
  45. package/build/2743.6d1632f9.chunk.js +45 -0
  46. package/build/3075.dc3894fe.chunk.js +108 -0
  47. package/build/3632.0317b618.chunk.js +138 -0
  48. package/build/4318.f96a9d4d.chunk.js +30 -0
  49. package/build/{5910.a5374848.chunk.js → 4855.bd092921.chunk.js} +65 -65
  50. package/build/8633.00ccd382.chunk.js +1 -0
  51. package/build/9707.7290fd92.chunk.js +96 -0
  52. package/build/Admin-authenticatedApp.ce646f66.chunk.js +75 -0
  53. package/build/{Admin_homePage.79ab880c.chunk.js → Admin_homePage.b1730882.chunk.js} +1 -1
  54. package/build/{Admin_marketplace.eabf21b2.chunk.js → Admin_marketplace.ea0316c2.chunk.js} +2 -2
  55. package/build/Admin_pluginsPage.5c24f963.chunk.js +6 -0
  56. package/build/Admin_profilePage.59af1978.chunk.js +15 -0
  57. package/build/Admin_settingsPage.d1493824.chunk.js +178 -0
  58. package/build/admin-app.25934eaa.chunk.js +112 -0
  59. package/build/admin-edit-roles-page.446b69dc.chunk.js +1 -0
  60. package/build/admin-edit-users.2ed69bfd.chunk.js +10 -0
  61. package/build/admin-users.fc003b10.chunk.js +11 -0
  62. package/build/{api-tokens-create-page.0e686c30.chunk.js → api-tokens-create-page.d248362d.chunk.js} +1 -1
  63. package/build/{api-tokens-edit-page.d6c7487b.chunk.js → api-tokens-edit-page.8516fa20.chunk.js} +1 -1
  64. package/build/api-tokens-list-page.44a79fda.chunk.js +16 -0
  65. package/build/audit-logs-settings-page.c3dce30d.chunk.js +1 -0
  66. package/build/content-manager.35ff9726.chunk.js +1139 -0
  67. package/build/{content-type-builder-list-view.4243b2b1.chunk.js → content-type-builder-list-view.79e84b36.chunk.js} +1 -6
  68. package/build/{content-type-builder.365b6bf4.chunk.js → content-type-builder.855db321.chunk.js} +16 -15
  69. package/build/{email-settings-page.379552b1.chunk.js → email-settings-page.d1fcc7a3.chunk.js} +4 -9
  70. package/build/en-json.1f137a90.chunk.js +1 -0
  71. package/build/eu-json.fceecd8b.chunk.js +1 -0
  72. package/build/i18n-settings-page.b8d8753e.chunk.js +60 -0
  73. package/build/index.html +1 -1
  74. package/build/main.7b151630.js +4377 -0
  75. package/build/ru-json.aa5cd123.chunk.js +1 -0
  76. package/build/runtime~main.a20d633b.js +2 -0
  77. package/build/sso-settings-page.b85ad080.chunk.js +41 -0
  78. package/build/upload-settings.ef64bbf9.chunk.js +84 -0
  79. package/build/upload.c5730dfa.chunk.js +33 -0
  80. package/build/users-advanced-settings-page.fce9908e.chunk.js +8 -0
  81. package/build/users-email-settings-page.343d0ad2.chunk.js +23 -0
  82. package/build/users-providers-settings-page.e5a9a3f1.chunk.js +99 -0
  83. package/build/users-roles-settings-page.66312f31.chunk.js +30 -0
  84. package/build/webhook-edit-page.73e51e64.chunk.js +75 -0
  85. package/build/{webhook-list-page.f75ba3f2.chunk.js → webhook-list-page.1134f130.chunk.js} +1 -1
  86. package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/ComboboxFilter/index.js +41 -0
  87. package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/Modal/ActionBody.js +1 -3
  88. package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/TableRows/index.js +1 -1
  89. package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/hooks/useAuditLogsData.js +47 -0
  90. package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/index.js +30 -31
  91. package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/utils/getActionTypesDefaultMessages.js +7 -9
  92. package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/utils/getDisplayedFilters.js +88 -0
  93. package/ee/admin/pages/SettingsPage/pages/Roles/ListPage/index.js +4 -2
  94. package/ee/server/migrations/audit-logs-table.js +45 -0
  95. package/ee/server/register.js +2 -0
  96. package/ee/server/services/audit-logs.js +11 -1
  97. package/package.json +27 -27
  98. package/server/controllers/admin.js +16 -0
  99. package/admin/src/content-manager/components/InputJSON/FieldWrapper.js +0 -40
  100. package/admin/src/content-manager/components/InputJSON/Label.js +0 -35
  101. package/admin/src/content-manager/components/InputJSON/components.js +0 -36
  102. package/admin/src/content-manager/components/InputJSON/index.js +0 -223
  103. package/admin/src/content-manager/components/InputJSON/jsonlint.js +0 -680
  104. package/admin/src/core/utils/axiosInstance.js +0 -40
  105. package/build/2607.ce06608e.chunk.js +0 -66
  106. package/build/2743.dea372fb.chunk.js +0 -42
  107. package/build/3075.03ebe93d.chunk.js +0 -115
  108. package/build/3632.963ac97d.chunk.js +0 -138
  109. package/build/4318.8cb388a5.chunk.js +0 -30
  110. package/build/4656.a0d43cca.chunk.js +0 -159
  111. package/build/8633.4af74a50.chunk.js +0 -1
  112. package/build/9641.a311b612.chunk.js +0 -276
  113. package/build/9707.62831b4d.chunk.js +0 -101
  114. package/build/Admin-authenticatedApp.50dc27f9.chunk.js +0 -75
  115. package/build/Admin_pluginsPage.953e796b.chunk.js +0 -6
  116. package/build/Admin_profilePage.5c2efda5.chunk.js +0 -15
  117. package/build/Admin_settingsPage.19cfb9ca.chunk.js +0 -178
  118. package/build/admin-app.34295b50.chunk.js +0 -112
  119. package/build/admin-edit-roles-page.d50d9654.chunk.js +0 -1
  120. package/build/admin-edit-users.912b856d.chunk.js +0 -10
  121. package/build/admin-users.e36e7111.chunk.js +0 -11
  122. package/build/api-tokens-list-page.1cd86136.chunk.js +0 -16
  123. package/build/audit-logs-settings-page.308a6250.chunk.js +0 -1
  124. package/build/codemirror-addon-closebrackets.71aa4bbd.chunk.js +0 -2
  125. package/build/codemirror-addon-lint-js.405f70fb.chunk.js +0 -1
  126. package/build/codemirror-addon-lint.8487ad3d.chunk.js +0 -1
  127. package/build/codemirror-addon-mark-selection.1928c849.chunk.js +0 -1
  128. package/build/codemirror-css.359a2a4b.chunk.js +0 -345
  129. package/build/codemirror-javacript.af237b68.chunk.js +0 -1
  130. package/build/codemirror-theme.2fe63a16.chunk.js +0 -33
  131. package/build/content-manager.851f40ce.chunk.js +0 -1170
  132. package/build/en-json.38d182e5.chunk.js +0 -1
  133. package/build/i18n-settings-page.3ab28b1a.chunk.js +0 -65
  134. package/build/main.9f31732e.js +0 -4454
  135. package/build/ru-json.3b411a39.chunk.js +0 -1
  136. package/build/runtime~main.2b8e2318.js +0 -2
  137. package/build/sso-settings-page.b64a44e8.chunk.js +0 -41
  138. package/build/upload-settings.6c26ff37.chunk.js +0 -89
  139. package/build/upload.2c69d238.chunk.js +0 -38
  140. package/build/users-advanced-settings-page.c4270682.chunk.js +0 -13
  141. package/build/users-email-settings-page.60422a2f.chunk.js +0 -28
  142. package/build/users-providers-settings-page.e1834060.chunk.js +0 -104
  143. package/build/users-roles-settings-page.3ef35132.chunk.js +0 -30
  144. package/build/webhook-edit-page.c0080dc1.chunk.js +0 -75
package/.browserslistrc CHANGED
@@ -1,3 +1,4 @@
1
1
  last 3 major versions
2
2
  Firefox ESR
3
- last 2 Opera versions
3
+ last 2 Opera versions
4
+ not dead
@@ -1,10 +1,11 @@
1
1
  import axios from 'axios';
2
+ import { getFetchClient } from '@strapi/helper-plugin';
2
3
  import checkLatestStrapiVersion from './checkLatestStrapiVersion';
3
- import { axiosInstance } from '../../../core/utils';
4
4
  import packageJSON from '../../../../../package.json';
5
5
 
6
6
  const strapiVersion = packageJSON.version;
7
7
  const showUpdateNotif = !JSON.parse(localStorage.getItem('STRAPI_UPDATE_NOTIF'));
8
+ const { get } = getFetchClient();
8
9
 
9
10
  const fetchStrapiLatestRelease = async (toggleNotification) => {
10
11
  try {
@@ -38,7 +39,7 @@ const fetchStrapiLatestRelease = async (toggleNotification) => {
38
39
 
39
40
  const fetchAppInfo = async () => {
40
41
  try {
41
- const { data, headers } = await axiosInstance.get('/admin/information');
42
+ const { data, headers } = await get('/admin/information');
42
43
 
43
44
  if (!headers['content-type'].includes('application/json')) {
44
45
  throw new Error('Not found');
@@ -52,7 +53,7 @@ const fetchAppInfo = async () => {
52
53
 
53
54
  const fetchCurrentUserPermissions = async () => {
54
55
  try {
55
- const { data, headers } = await axiosInstance.get('/admin/users/me/permissions');
56
+ const { data, headers } = await get('/admin/users/me/permissions');
56
57
 
57
58
  if (!headers['content-type'].includes('application/json')) {
58
59
  throw new Error('Not found');
@@ -70,7 +71,7 @@ const fetchUserRoles = async () => {
70
71
  data: {
71
72
  data: { roles },
72
73
  },
73
- } = await axiosInstance.get('/admin/users/me');
74
+ } = await get('/admin/users/me');
74
75
 
75
76
  return roles;
76
77
  } catch (err) {
@@ -20,9 +20,14 @@ import { Typography } from '@strapi/design-system/Typography';
20
20
  import { Stack } from '@strapi/design-system/Stack';
21
21
  import Write from '@strapi/icons/Write';
22
22
  import Exit from '@strapi/icons/Exit';
23
- import { auth, usePersistentState, useAppInfos, useTracking } from '@strapi/helper-plugin';
23
+ import {
24
+ auth,
25
+ usePersistentState,
26
+ useAppInfos,
27
+ useTracking,
28
+ getFetchClient,
29
+ } from '@strapi/helper-plugin';
24
30
  import { useConfigurations } from '../../hooks';
25
- import { axiosInstance } from '../../core/utils';
26
31
 
27
32
  const LinkUserWrapper = styled(Box)`
28
33
  width: ${150 / 16}rem;
@@ -64,6 +69,7 @@ const LeftMenu = ({ generalSectionLinks, pluginsSectionLinks }) => {
64
69
  const { trackUsage } = useTracking();
65
70
  const { pathname } = useLocation();
66
71
  const history = useHistory();
72
+ const { post } = getFetchClient();
67
73
 
68
74
  const initials = userDisplayName
69
75
  .split(' ')
@@ -74,7 +80,7 @@ const LeftMenu = ({ generalSectionLinks, pluginsSectionLinks }) => {
74
80
  const handleToggleUserLinks = () => setUserLinksVisible((prev) => !prev);
75
81
 
76
82
  const handleLogout = async () => {
77
- await axiosInstance.post('/admin/logout');
83
+ await post('/admin/logout');
78
84
  auth.clearAppStorage();
79
85
  handleToggleUserLinks();
80
86
  history.push('/auth/login');
@@ -10,11 +10,11 @@ import {
10
10
  formatContentTypeData,
11
11
  contentManagementUtilRemoveFieldsFromData,
12
12
  useGuidedTour,
13
+ useFetchClient,
13
14
  } from '@strapi/helper-plugin';
14
15
  import { useSelector, useDispatch } from 'react-redux';
15
16
  import PropTypes from 'prop-types';
16
17
  import isEqual from 'react-fast-compare';
17
- import { axiosInstance } from '../../../core/utils';
18
18
  import {
19
19
  createDefaultForm,
20
20
  getTrad,
@@ -51,6 +51,9 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
51
51
 
52
52
  const allLayoutDataRef = useRef(allLayoutData);
53
53
 
54
+ const fetchClient = useFetchClient();
55
+ const { put, post, del } = fetchClient;
56
+
54
57
  const isCreatingEntry = id === null;
55
58
 
56
59
  const requestURL = useMemo(() => {
@@ -137,7 +140,7 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
137
140
  dispatch(getData());
138
141
 
139
142
  try {
140
- const { data } = await axiosInstance.get(requestURL, { cancelToken: source.token });
143
+ const { data } = await fetchClient.get(requestURL, { cancelToken: source.token });
141
144
 
142
145
  dispatch(getDataSucceeded(cleanReceivedData(cleanClonedData(data))));
143
146
  } catch (err) {
@@ -187,6 +190,7 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
187
190
  source.cancel('Operation canceled by the user.');
188
191
  };
189
192
  }, [
193
+ fetchClient,
190
194
  cleanClonedData,
191
195
  cleanReceivedData,
192
196
  push,
@@ -216,12 +220,12 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
216
220
 
217
221
  const onDelete = useCallback(
218
222
  async (trackerProperty) => {
223
+ console.log('onDelete');
224
+
219
225
  try {
220
226
  trackUsageRef.current('willDeleteEntry', trackerProperty);
221
227
 
222
- const { data } = await axiosInstance.delete(
223
- getRequestUrl(`collection-types/${slug}/${id}`)
224
- );
228
+ const { data } = await del(getRequestUrl(`collection-types/${slug}/${id}`));
225
229
 
226
230
  toggleNotification({
227
231
  type: 'success',
@@ -237,7 +241,7 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
237
241
  return Promise.reject(err);
238
242
  }
239
243
  },
240
- [id, slug, toggleNotification]
244
+ [id, slug, toggleNotification, del]
241
245
  );
242
246
 
243
247
  const onDeleteSucceeded = useCallback(() => {
@@ -247,12 +251,11 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
247
251
  const onPost = useCallback(
248
252
  async (body, trackerProperty) => {
249
253
  const endPoint = `${getRequestUrl(`collection-types/${slug}`)}${rawQuery}`;
250
-
251
254
  try {
252
255
  // Show a loading button in the EditView/Header.js && lock the app => no navigation
253
256
  dispatch(setStatus('submit-pending'));
254
257
 
255
- const { data } = await axiosInstance.post(endPoint, body);
258
+ const { data } = await post(endPoint, body);
256
259
 
257
260
  trackUsageRef.current('didCreateEntry', trackerProperty);
258
261
  toggleNotification({
@@ -291,6 +294,7 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
291
294
  toggleNotification,
292
295
  setCurrentStep,
293
296
  queryClient,
297
+ post,
294
298
  ]
295
299
  );
296
300
 
@@ -303,7 +307,7 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
303
307
  );
304
308
  dispatch(setStatus('draft-relation-check-pending'));
305
309
 
306
- const numberOfDraftRelations = await axiosInstance.get(endPoint);
310
+ const numberOfDraftRelations = await fetchClient.get(endPoint);
307
311
  trackUsageRef.current('didCheckDraftRelations');
308
312
 
309
313
  dispatch(setStatus('resolved'));
@@ -315,7 +319,7 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
315
319
 
316
320
  return Promise.reject(err);
317
321
  }
318
- }, [displayErrors, id, slug, dispatch]);
322
+ }, [displayErrors, id, slug, dispatch, fetchClient]);
319
323
 
320
324
  const onPublish = useCallback(async () => {
321
325
  try {
@@ -324,7 +328,7 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
324
328
 
325
329
  dispatch(setStatus('publish-pending'));
326
330
 
327
- const { data } = await axiosInstance.post(endPoint);
331
+ const { data } = await post(endPoint);
328
332
 
329
333
  trackUsageRef.current('didPublishEntry');
330
334
 
@@ -343,7 +347,7 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
343
347
 
344
348
  return Promise.reject(err);
345
349
  }
346
- }, [cleanReceivedData, displayErrors, id, slug, dispatch, toggleNotification]);
350
+ }, [cleanReceivedData, displayErrors, id, slug, dispatch, toggleNotification, post]);
347
351
 
348
352
  const onPut = useCallback(
349
353
  async (body, trackerProperty) => {
@@ -354,7 +358,7 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
354
358
 
355
359
  dispatch(setStatus('submit-pending'));
356
360
 
357
- const { data } = await axiosInstance.put(endPoint, body);
361
+ const { data } = await put(endPoint, body);
358
362
 
359
363
  trackUsageRef.current('didEditEntry', { trackerProperty });
360
364
  toggleNotification({
@@ -379,7 +383,7 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
379
383
  return Promise.reject(err);
380
384
  }
381
385
  },
382
- [cleanReceivedData, displayErrors, slug, id, dispatch, toggleNotification, queryClient]
386
+ [cleanReceivedData, displayErrors, slug, id, dispatch, toggleNotification, queryClient, put]
383
387
  );
384
388
 
385
389
  const onUnpublish = useCallback(async () => {
@@ -390,7 +394,7 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
390
394
  try {
391
395
  trackUsageRef.current('willUnpublishEntry');
392
396
 
393
- const { data } = await axiosInstance.post(endPoint);
397
+ const { data } = await post(endPoint);
394
398
 
395
399
  trackUsageRef.current('didUnpublishEntry');
396
400
  toggleNotification({
@@ -408,7 +412,7 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
408
412
 
409
413
  return Promise.reject(err);
410
414
  }
411
- }, [cleanReceivedData, displayErrors, id, slug, dispatch, toggleNotification]);
415
+ }, [cleanReceivedData, displayErrors, id, slug, dispatch, toggleNotification, post]);
412
416
 
413
417
  return children({
414
418
  componentsDataStructure,
@@ -10,19 +10,18 @@ import { SimpleMenu, MenuItem } from '@strapi/design-system/SimpleMenu';
10
10
  import { Loader } from '@strapi/design-system/Loader';
11
11
  import styled from 'styled-components';
12
12
  import { useNotifyAT } from '@strapi/design-system/LiveRegions';
13
- import { stopPropagation } from '@strapi/helper-plugin';
13
+ import { stopPropagation, useFetchClient } from '@strapi/helper-plugin';
14
14
  import CellValue from '../CellValue';
15
- import { axiosInstance } from '../../../../../core/utils';
16
15
  import { getRequestUrl, getTrad } from '../../../../utils';
17
16
 
18
17
  const TypographyMaxWidth = styled(Typography)`
19
18
  max-width: 500px;
20
19
  `;
21
20
 
22
- const fetchRelation = async (endPoint, notifyStatus) => {
21
+ const fetchRelation = async (endPoint, notifyStatus, get) => {
23
22
  const {
24
23
  data: { results, pagination },
25
- } = await axiosInstance.get(endPoint);
24
+ } = await get(endPoint);
26
25
 
27
26
  notifyStatus();
28
27
 
@@ -37,6 +36,7 @@ const RelationMultiple = ({ fieldSchema, metadatas, name, entityId, value, conte
37
36
  [entityId, name, contentType]
38
37
  );
39
38
  const [isOpen, setIsOpen] = useState(false);
39
+ const { get } = useFetchClient();
40
40
 
41
41
  const Label = (
42
42
  <Flex gap={1} wrap="nowrap">
@@ -61,7 +61,7 @@ const RelationMultiple = ({ fieldSchema, metadatas, name, entityId, value, conte
61
61
 
62
62
  const { data, status } = useQuery(
63
63
  [fieldSchema.targetModel, entityId],
64
- () => fetchRelation(relationFetchEndpoint, notify),
64
+ () => fetchRelation(relationFetchEndpoint, notify, get),
65
65
  {
66
66
  enabled: isOpen,
67
67
  staleTime: 0,
@@ -21,11 +21,9 @@ export const findLeafByPathAndReplace = (endpath, replaceWith) => {
21
21
 
22
22
  /**
23
23
  * If this is the last item in the array of paths
24
- * and the current path is not undefined in the accumulator
25
24
  * then we assume it's a leaf and we can replace it.
26
25
  */
27
-
28
- if (ind === currentArr.length - 1 && endpath === curr && acc[curr] !== undefined) {
26
+ if (ind === currentArr.length - 1 && endpath === curr) {
29
27
  set(acc, curr, replaceWith);
30
28
 
31
29
  return acc;
@@ -216,10 +216,6 @@ const createYupSchemaAttribute = (type, validations, options) => {
216
216
  schema = yup
217
217
  .mixed(errorsTrads.json)
218
218
  .test('isJSON', errorsTrads.json, (value) => {
219
- if (value === undefined) {
220
- return true;
221
- }
222
-
223
219
  try {
224
220
  JSON.parse(value);
225
221
 
@@ -228,7 +224,12 @@ const createYupSchemaAttribute = (type, validations, options) => {
228
224
  return false;
229
225
  }
230
226
  })
231
- .nullable();
227
+ .nullable()
228
+ .test('required', errorsTrads.required, (value) => {
229
+ if (validations.required && !value.length) return false;
230
+
231
+ return true;
232
+ });
232
233
  }
233
234
 
234
235
  if (type === 'email') {
@@ -1,6 +1,6 @@
1
1
  import React, { useEffect, useState, useRef } from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { useCMEditViewDataManager } from '@strapi/helper-plugin';
3
+ import { useCMEditViewDataManager, useFetchClient } from '@strapi/helper-plugin';
4
4
  import { useIntl } from 'react-intl';
5
5
  import get from 'lodash/get';
6
6
  import { TextInput } from '@strapi/design-system/TextInput';
@@ -9,7 +9,6 @@ import Refresh from '@strapi/icons/Refresh';
9
9
  import CheckCircle from '@strapi/icons/CheckCircle';
10
10
  import ExclamationMarkCircle from '@strapi/icons/ExclamationMarkCircle';
11
11
  import Loader from '@strapi/icons/Loader';
12
- import { axiosInstance } from '../../../core/utils';
13
12
  import { getRequestUrl } from '../../utils';
14
13
  import useDebounce from './useDebounce';
15
14
  import UID_REGEX from './regex';
@@ -46,6 +45,7 @@ const InputUID = ({
46
45
  const debouncedTargetFieldValue = useDebounce(modifiedData[attribute.targetField], 300);
47
46
  const [isCustomized, setIsCustomized] = useState(false);
48
47
  const [regenerateLabel, setRegenerateLabel] = useState(null);
48
+ const { post } = useFetchClient();
49
49
 
50
50
  const label = intlLabel.id
51
51
  ? formatMessage(
@@ -67,7 +67,7 @@ const InputUID = ({
67
67
  try {
68
68
  const {
69
69
  data: { data },
70
- } = await axiosInstance.post(requestURL, {
70
+ } = await post(requestURL, {
71
71
  contentTypeUID,
72
72
  field: name,
73
73
  data: modifiedData,
@@ -89,7 +89,7 @@ const InputUID = ({
89
89
  }
90
90
 
91
91
  try {
92
- const { data } = await axiosInstance.post(requestURL, {
92
+ const { data } = await post(requestURL, {
93
93
  contentTypeUID,
94
94
  field: name,
95
95
  value: value ? value.trim() : '',
@@ -9,7 +9,6 @@ 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';
12
- import InputJSON from '../InputJSON';
13
12
  import InputUID from '../InputUID';
14
13
  import { RelationInputDataManager } from '../RelationInputDataManager';
15
14
 
@@ -250,7 +249,6 @@ function Inputs({
250
249
  }
251
250
 
252
251
  const customInputs = {
253
- json: InputJSON,
254
252
  uid: InputUID,
255
253
  media: fields.media,
256
254
  wysiwyg: Wysiwyg,
@@ -8,11 +8,11 @@ import {
8
8
  useQueryParams,
9
9
  useNotification,
10
10
  useGuidedTour,
11
+ useFetchClient,
11
12
  } from '@strapi/helper-plugin';
12
13
  import { useSelector, useDispatch } from 'react-redux';
13
14
  import PropTypes from 'prop-types';
14
15
  import axios from 'axios';
15
- import { axiosInstance } from '../../../core/utils';
16
16
  import { createDefaultForm, getTrad, removePasswordFieldsFromData } from '../../utils';
17
17
  import {
18
18
  getData,
@@ -39,6 +39,8 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
39
39
  const searchToSend = buildQueryString(query);
40
40
  const toggleNotification = useNotification();
41
41
  const dispatch = useDispatch();
42
+ const fetchClient = useFetchClient();
43
+ const { post, put, del } = fetchClient;
42
44
 
43
45
  const { componentsDataStructure, contentTypeDataStructure, data, isLoading, status } =
44
46
  useSelector(selectCrudReducer);
@@ -103,7 +105,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
103
105
  setIsCreatingEntry(true);
104
106
 
105
107
  try {
106
- const { data } = await axiosInstance.get(getRequestUrl(`${slug}${searchToSend}`), {
108
+ const { data } = await fetchClient.get(getRequestUrl(`${slug}${searchToSend}`), {
107
109
  cancelToken: source.token,
108
110
  });
109
111
 
@@ -136,7 +138,16 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
136
138
  fetchData(source);
137
139
 
138
140
  return () => source.cancel('Operation canceled by the user.');
139
- }, [cleanReceivedData, push, slug, dispatch, searchToSend, rawQuery, toggleNotification]);
141
+ }, [
142
+ fetchClient,
143
+ cleanReceivedData,
144
+ push,
145
+ slug,
146
+ dispatch,
147
+ searchToSend,
148
+ rawQuery,
149
+ toggleNotification,
150
+ ]);
140
151
 
141
152
  const displayErrors = useCallback(
142
153
  (err) => {
@@ -160,7 +171,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
160
171
  try {
161
172
  trackUsageRef.current('willDeleteEntry', trackerProperty);
162
173
 
163
- const { data } = await axiosInstance.delete(getRequestUrl(`${slug}${searchToSend}`));
174
+ const { data } = await del(getRequestUrl(`${slug}${searchToSend}`));
164
175
 
165
176
  toggleNotification({
166
177
  type: 'success',
@@ -178,7 +189,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
178
189
  return Promise.reject(err);
179
190
  }
180
191
  },
181
- [slug, displayErrors, toggleNotification, searchToSend]
192
+ [del, slug, displayErrors, toggleNotification, searchToSend]
182
193
  );
183
194
 
184
195
  const onDeleteSucceeded = useCallback(() => {
@@ -194,7 +205,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
194
205
  try {
195
206
  dispatch(setStatus('submit-pending'));
196
207
 
197
- const { data } = await axiosInstance.put(endPoint, body);
208
+ const { data } = await put(endPoint, body);
198
209
 
199
210
  trackUsageRef.current('didCreateEntry', trackerProperty);
200
211
  toggleNotification({
@@ -224,6 +235,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
224
235
  }
225
236
  },
226
237
  [
238
+ put,
227
239
  cleanReceivedData,
228
240
  displayErrors,
229
241
  slug,
@@ -242,7 +254,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
242
254
  const endPoint = getRequestUrl(`${slug}/actions/numberOfDraftRelations`);
243
255
  dispatch(setStatus('draft-relation-check-pending'));
244
256
 
245
- const numberOfDraftRelations = await axiosInstance.get(endPoint);
257
+ const numberOfDraftRelations = await fetchClient.get(endPoint);
246
258
  trackUsageRef.current('didCheckDraftRelations');
247
259
 
248
260
  dispatch(setStatus('resolved'));
@@ -254,7 +266,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
254
266
 
255
267
  return Promise.reject(err);
256
268
  }
257
- }, [displayErrors, slug, dispatch]);
269
+ }, [fetchClient, displayErrors, slug, dispatch]);
258
270
 
259
271
  const onPublish = useCallback(async () => {
260
272
  try {
@@ -263,7 +275,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
263
275
 
264
276
  dispatch(setStatus('publish-pending'));
265
277
 
266
- const { data } = await axiosInstance.post(endPoint);
278
+ const { data } = await post(endPoint);
267
279
 
268
280
  trackUsageRef.current('didPublishEntry');
269
281
  toggleNotification({
@@ -283,7 +295,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
283
295
 
284
296
  return Promise.reject(err);
285
297
  }
286
- }, [cleanReceivedData, displayErrors, slug, searchToSend, dispatch, toggleNotification]);
298
+ }, [post, cleanReceivedData, displayErrors, slug, searchToSend, dispatch, toggleNotification]);
287
299
 
288
300
  const onPut = useCallback(
289
301
  async (body, trackerProperty) => {
@@ -294,7 +306,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
294
306
 
295
307
  dispatch(setStatus('submit-pending'));
296
308
 
297
- const { data } = await axiosInstance.put(endPoint, body);
309
+ const { data } = await put(endPoint, body);
298
310
 
299
311
  toggleNotification({
300
312
  type: 'success',
@@ -321,7 +333,16 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
321
333
  return Promise.reject(err);
322
334
  }
323
335
  },
324
- [cleanReceivedData, displayErrors, slug, dispatch, rawQuery, toggleNotification, queryClient]
336
+ [
337
+ put,
338
+ cleanReceivedData,
339
+ displayErrors,
340
+ slug,
341
+ dispatch,
342
+ rawQuery,
343
+ toggleNotification,
344
+ queryClient,
345
+ ]
325
346
  );
326
347
 
327
348
  // The publish and unpublish method could be refactored but let's leave the duplication for now
@@ -333,7 +354,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
333
354
  try {
334
355
  trackUsageRef.current('willUnpublishEntry');
335
356
 
336
- const { data } = await axiosInstance.post(endPoint);
357
+ const { data } = await post(endPoint);
337
358
 
338
359
  trackUsageRef.current('didUnpublishEntry');
339
360
  toggleNotification({
@@ -348,7 +369,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
348
369
  dispatch(setStatus('resolved'));
349
370
  displayErrors(err);
350
371
  }
351
- }, [cleanReceivedData, toggleNotification, displayErrors, slug, dispatch, searchToSend]);
372
+ }, [post, cleanReceivedData, toggleNotification, displayErrors, slug, dispatch, searchToSend]);
352
373
 
353
374
  return children({
354
375
  componentsDataStructure,
@@ -1,7 +1,7 @@
1
1
  import { useCallback, useEffect, useMemo, useReducer, useRef } from 'react';
2
2
  import { useSelector, shallowEqual } from 'react-redux';
3
3
  import axios from 'axios';
4
- import { axiosInstance } from '../../../core/utils';
4
+ import { useFetchClient } from '@strapi/helper-plugin';
5
5
  import formatLayouts from './utils/formatLayouts';
6
6
  import reducer, { initialState } from './reducer';
7
7
  import { makeSelectModelAndComponentSchemas } from '../../pages/App/selectors';
@@ -12,6 +12,7 @@ const useFetchContentTypeLayout = (contentTypeUID) => {
12
12
  const schemasSelector = useMemo(makeSelectModelAndComponentSchemas, []);
13
13
  const { schemas } = useSelector((state) => schemasSelector(state), shallowEqual);
14
14
  const isMounted = useRef(true);
15
+ const { get } = useFetchClient();
15
16
 
16
17
  const getData = useCallback(
17
18
  async (uid, source) => {
@@ -27,7 +28,7 @@ const useFetchContentTypeLayout = (contentTypeUID) => {
27
28
 
28
29
  const {
29
30
  data: { data },
30
- } = await axiosInstance.get(endPoint, { cancelToken: source.token });
31
+ } = await get(endPoint, { cancelToken: source.token });
31
32
 
32
33
  dispatch({
33
34
  type: 'GET_DATA_SUCCEEDED',
@@ -47,7 +48,7 @@ const useFetchContentTypeLayout = (contentTypeUID) => {
47
48
  }
48
49
  }
49
50
  },
50
- [layouts, schemas]
51
+ [layouts, schemas, get]
51
52
  );
52
53
 
53
54
  useEffect(() => {
@@ -11,13 +11,12 @@ const componentStore = new Map();
11
11
  */
12
12
  const useLazyComponents = (componentUids = []) => {
13
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
- });
14
+ /**
15
+ * Start loading only if there are any components passed in
16
+ * and there are some new to load
17
+ */
18
+ const newUids = componentUids.filter((uid) => !componentStore.get(uid));
19
+ const [loading, setLoading] = useState(() => !!newUids.length);
21
20
  const customFieldsRegistry = useCustomFields();
22
21
 
23
22
  useEffect(() => {
@@ -36,11 +35,8 @@ const useLazyComponents = (componentUids = []) => {
36
35
  setStore(Object.fromEntries(componentStore));
37
36
  };
38
37
 
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));
38
+ if (newUids.length > 0) {
39
+ setLoading(true);
44
40
 
45
41
  const componentPromises = newUids.map((uid) => {
46
42
  const customField = customFieldsRegistry.get(uid);
@@ -52,7 +48,7 @@ const useLazyComponents = (componentUids = []) => {
52
48
  lazyLoadComponents(newUids, componentPromises);
53
49
  }
54
50
  }
55
- }, [componentUids, customFieldsRegistry, loading]);
51
+ }, [newUids, customFieldsRegistry]);
56
52
 
57
53
  /**
58
54
  * Wrap this in a callback so it can be used in
@@ -1,7 +1,7 @@
1
1
  import { useState, useEffect } from 'react';
2
2
  import { useInfiniteQuery } from 'react-query';
3
3
 
4
- import { axiosInstance } from '../../../core/utils';
4
+ import { useFetchClient } from '@strapi/helper-plugin';
5
5
 
6
6
  import { normalizeRelations } from '../../components/RelationInputDataManager/utils';
7
7
 
@@ -10,13 +10,13 @@ import { useCallbackRef } from '../useCallbackRef';
10
10
  export const useRelation = (cacheKey, { relation, search }) => {
11
11
  const [searchParams, setSearchParams] = useState({});
12
12
  const [currentPage, setCurrentPage] = useState(0);
13
-
13
+ const { get } = useFetchClient();
14
14
  /**
15
15
  * This runs in `useInfiniteQuery` to actually fetch the data
16
16
  */
17
17
  const fetchRelations = async ({ pageParam = 1 }) => {
18
18
  try {
19
- const { data } = await axiosInstance.get(relation?.endpoint, {
19
+ const { data } = await get(relation?.endpoint, {
20
20
  params: {
21
21
  ...(relation.pageParams ?? {}),
22
22
  page: pageParam,
@@ -33,7 +33,7 @@ export const useRelation = (cacheKey, { relation, search }) => {
33
33
 
34
34
  const fetchSearch = async ({ pageParam = 1 }) => {
35
35
  try {
36
- const { data } = await axiosInstance.get(search.endpoint, {
36
+ const { data } = await get(search.endpoint, {
37
37
  params: {
38
38
  ...(search.pageParams ?? {}),
39
39
  ...searchParams,
@@ -1,10 +1,14 @@
1
- import { useNotification, useRBACProvider, useStrapiApp } from '@strapi/helper-plugin';
1
+ import {
2
+ useNotification,
3
+ useRBACProvider,
4
+ useStrapiApp,
5
+ useFetchClient,
6
+ } from '@strapi/helper-plugin';
2
7
  import { useEffect, useRef } from 'react';
3
8
  import { useDispatch, useSelector } from 'react-redux';
4
9
  import { useNotifyAT } from '@strapi/design-system/LiveRegions';
5
10
  import axios from 'axios';
6
11
  import { useIntl } from 'react-intl';
7
- import { axiosInstance } from '../../../core/utils';
8
12
  import { MUTATE_COLLECTION_TYPES_LINKS, MUTATE_SINGLE_TYPES_LINKS } from '../../../exposedHooks';
9
13
  import { getRequestUrl, getTrad } from '../../utils';
10
14
  import { getData, resetProps, setContentTypeLinks } from './actions';
@@ -22,6 +26,7 @@ const useModels = () => {
22
26
  const source = CancelToken.source();
23
27
  const { notifyStatus } = useNotifyAT();
24
28
  const { formatMessage } = useIntl();
29
+ const { get } = useFetchClient();
25
30
 
26
31
  const fetchData = async () => {
27
32
  dispatch(getData());
@@ -36,7 +41,7 @@ const useModels = () => {
36
41
  },
37
42
  ] = await Promise.all(
38
43
  ['components', 'content-types'].map((endPoint) =>
39
- axiosInstance.get(getRequestUrl(endPoint), { cancelToken: source.token })
44
+ get(getRequestUrl(endPoint), { cancelToken: source.token })
40
45
  )
41
46
  );
42
47