@strapi/admin 4.5.3 → 4.5.5

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 (245) hide show
  1. package/admin/src/components/AuthenticatedApp/index.js +13 -2
  2. package/admin/src/components/GlobalStyle/index.js +0 -11
  3. package/admin/src/content-manager/components/ComponentIcon/ComponentIcon.js +49 -0
  4. package/admin/src/content-manager/components/ComponentIcon/index.js +1 -0
  5. package/admin/src/content-manager/components/DynamicZone/components/ComponentCard.js +17 -31
  6. package/admin/src/content-manager/components/DynamicZone/components/ComponentCategory.js +2 -2
  7. package/admin/src/content-manager/components/DynamicZone/components/DynamicComponent.js +3 -3
  8. package/admin/src/content-manager/components/EditViewDataManagerProvider/index.js +39 -3
  9. package/admin/src/content-manager/components/EditViewDataManagerProvider/reducer.js +24 -3
  10. package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/findLeafByPathAndReplace.js +2 -1
  11. package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/recursivelyFindPathsBasedOnCondition.js +8 -1
  12. package/admin/src/content-manager/components/InputJSON/FieldWrapper.js +10 -2
  13. package/admin/src/content-manager/components/InputJSON/Label.js +2 -18
  14. package/admin/src/content-manager/components/InputJSON/index.js +7 -3
  15. package/admin/src/content-manager/components/NonRepeatableComponent/index.js +4 -0
  16. package/admin/src/content-manager/components/RelationInput/RelationInput.js +6 -13
  17. package/admin/src/content-manager/components/RelationInputDataManager/RelationInputDataManager.js +1 -1
  18. package/admin/src/content-manager/components/RepeatableComponent/AccordionGroupCustom/index.js +0 -1
  19. package/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js +4 -0
  20. package/admin/src/content-manager/components/RepeatableComponent/index.js +1 -3
  21. package/admin/src/content-manager/components/SingleTypeFormWrapper/index.js +1 -1
  22. package/admin/src/content-manager/components/Wysiwyg/Editor.js +1 -1
  23. package/admin/src/content-manager/hooks/useLazyComponents/index.js +40 -15
  24. package/admin/src/content-manager/pages/EditSettingsView/components/DynamicZoneList.js +18 -38
  25. package/admin/src/content-manager/pages/EditView/Header/index.js +1 -1
  26. package/admin/src/content-manager/sharedReducers/crudReducer/actions.js +5 -0
  27. package/admin/src/content-manager/sharedReducers/crudReducer/constants.js +2 -0
  28. package/admin/src/content-manager/sharedReducers/crudReducer/reducer.js +7 -0
  29. package/admin/src/core/utils/axiosInstance.js +4 -2
  30. package/admin/src/hooks/index.js +1 -0
  31. package/admin/src/hooks/useFetchClient/index.js +23 -0
  32. package/admin/src/pages/Admin/Onboarding/index.js +42 -44
  33. package/admin/src/pages/App/index.js +20 -13
  34. package/admin/src/pages/AuthPage/components/Register/index.js +1 -1
  35. package/admin/src/pages/AuthPage/components/ResetPassword/index.js +1 -1
  36. package/admin/src/pages/HomePage/SocialLinks.js +4 -4
  37. package/admin/src/pages/ProfilePage/index.js +1 -1
  38. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js +2 -3
  39. package/admin/src/pages/SettingsPage/pages/Users/ListPage/ModalForm/index.js +23 -18
  40. package/admin/src/translations/ca.json +2 -3
  41. package/admin/src/translations/dk.json +2 -2
  42. package/admin/src/translations/en.json +2 -1
  43. package/admin/src/translations/es.json +2 -2
  44. package/admin/src/translations/fr.json +2 -2
  45. package/admin/src/translations/hu.json +2 -2
  46. package/admin/src/translations/ja.json +2 -2
  47. package/admin/src/translations/nl.json +2 -2
  48. package/admin/src/translations/sk.json +274 -52
  49. package/admin/src/translations/tr.json +485 -5
  50. package/admin/src/translations/zh-Hans.json +1 -1
  51. package/admin/src/translations/zh.json +2 -2
  52. package/admin/src/utils/fetchClient.js +45 -0
  53. package/admin/src/utils/getFetchClient.js +10 -0
  54. package/admin/src/utils/index.js +1 -0
  55. package/admin/src/utils/uniqueAdminHash.js +22 -0
  56. package/build/2235.06c13219.chunk.js +106 -0
  57. package/build/{1233.80b05d66.chunk.js → 2473.45658149.chunk.js} +67 -67
  58. package/build/2598.962797b2.chunk.js +159 -0
  59. package/build/4318.0bbd3f4b.chunk.js +30 -0
  60. package/build/4958.7c118f5e.chunk.js +276 -0
  61. package/build/5052.712419ea.chunk.js +65 -0
  62. package/build/7295.e12e5587.chunk.js +114 -0
  63. package/build/805.ddcead70.chunk.js +138 -0
  64. package/build/{8633.8da5488a.chunk.js → 8633.19be8f45.chunk.js} +1 -1
  65. package/build/874.bde3ea04.chunk.js +104 -0
  66. package/build/9707.77e475ee.chunk.js +101 -0
  67. package/build/Admin-authenticatedApp.59063c5f.chunk.js +72 -0
  68. package/build/{Admin_homePage.54e33c2d.chunk.js → Admin_homePage.8945f71a.chunk.js} +5 -5
  69. package/build/{Admin_marketplace.8219fda6.chunk.js → Admin_marketplace.615343fb.chunk.js} +6 -6
  70. package/build/Admin_pluginsPage.67728975.chunk.js +6 -0
  71. package/build/{Admin_profilePage.e9fcce92.chunk.js → Admin_profilePage.175c6516.chunk.js} +2 -2
  72. package/build/Admin_settingsPage.ba0605a2.chunk.js +178 -0
  73. package/build/Upload_ConfigureTheView.7cb2a3fd.chunk.js +1 -0
  74. package/build/admin-app.77b9f2b9.chunk.js +112 -0
  75. package/build/admin-edit-roles-page.f407538c.chunk.js +1 -0
  76. package/build/admin-edit-users.5547b126.chunk.js +10 -0
  77. package/build/{admin-users.a0748674.chunk.js → admin-users.4b6b47f8.chunk.js} +2 -2
  78. package/build/api-tokens-create-page.dd4ddfcb.chunk.js +1 -0
  79. package/build/api-tokens-edit-page.821c5a6c.chunk.js +1 -0
  80. package/build/{api-tokens-list-page.700e575f.chunk.js → api-tokens-list-page.50519ed7.chunk.js} +1 -1
  81. package/build/ca-json.fa3e6f48.chunk.js +1 -0
  82. package/build/{codemirror-css.4e2bbed3.chunk.js → codemirror-css.aa4c2de2.chunk.js} +2 -3
  83. package/build/codemirror-theme.c1d2b07c.chunk.js +33 -0
  84. package/build/content-manager.d89dcc40.chunk.js +1184 -0
  85. package/build/content-type-builder-list-view.4aea46fa.chunk.js +198 -0
  86. package/build/content-type-builder-translation-de-json.a52482c7.chunk.js +1 -0
  87. package/build/content-type-builder-translation-dk-json.a8616510.chunk.js +1 -0
  88. package/build/content-type-builder-translation-en-json.1d9a3c14.chunk.js +1 -0
  89. package/build/content-type-builder-translation-es-json.c3ea46fb.chunk.js +1 -0
  90. package/build/content-type-builder-translation-ko-json.3fb7ddc8.chunk.js +1 -0
  91. package/build/content-type-builder-translation-pl-json.9b2993b2.chunk.js +1 -0
  92. package/build/content-type-builder-translation-pt-BR-json.6d255441.chunk.js +1 -0
  93. package/build/content-type-builder-translation-sv-json.c608b9ca.chunk.js +1 -0
  94. package/build/content-type-builder-translation-tr-json.949e22eb.chunk.js +1 -0
  95. package/build/content-type-builder-translation-zh-json.b79513e4.chunk.js +1 -0
  96. package/build/content-type-builder.3b1a75a2.chunk.js +127 -0
  97. package/build/dk-json.ab5dd6ac.chunk.js +1 -0
  98. package/build/email-settings-page.d7165683.chunk.js +15 -0
  99. package/build/email-translation-tr-json.8aa034bb.chunk.js +1 -0
  100. package/build/en-json.d268c039.chunk.js +1 -0
  101. package/build/es-json.8fe19fb3.chunk.js +1 -0
  102. package/build/fr-json.7ba93468.chunk.js +1 -0
  103. package/build/highlight.js.aea3bcf9.chunk.js +85 -0
  104. package/build/hu-json.459334f8.chunk.js +1 -0
  105. package/build/{i18n-settings-page.195d42fe.chunk.js → i18n-settings-page.ee572037.chunk.js} +1 -1
  106. package/build/i18n-translation-tr-json.34ca9d61.chunk.js +1 -0
  107. package/build/index.html +1 -1
  108. package/build/ja-json.e69860d6.chunk.js +1 -0
  109. package/build/main.1a19193b.js +4417 -0
  110. package/build/nl-json.02de2e84.chunk.js +1 -0
  111. package/build/runtime~main.2e5b4723.js +2 -0
  112. package/build/sk-json.2af48064.chunk.js +1 -0
  113. package/build/sso-settings-page.91924df1.chunk.js +41 -0
  114. package/build/tr-json.eac8bd79.chunk.js +1 -0
  115. package/build/upload-settings.5fd96cda.chunk.js +89 -0
  116. package/build/upload-translation-en-json.32cf9aff.chunk.js +1 -0
  117. package/build/upload-translation-sk-json.fe86c53b.chunk.js +1 -0
  118. package/build/upload-translation-tr-json.b173223a.chunk.js +1 -0
  119. package/build/upload.9993c14f.chunk.js +38 -0
  120. package/build/users-advanced-settings-page.c4431a05.chunk.js +13 -0
  121. package/build/users-email-settings-page.d8a0bf10.chunk.js +28 -0
  122. package/build/{users-permissions-translation-dk-json.fe39c74b.chunk.js → users-permissions-translation-dk-json.bad0b786.chunk.js} +1 -1
  123. package/build/{users-permissions-translation-en-json.765abf48.chunk.js → users-permissions-translation-en-json.aeab388a.chunk.js} +1 -1
  124. package/build/{users-permissions-translation-es-json.1bb9cde2.chunk.js → users-permissions-translation-es-json.152a923f.chunk.js} +1 -1
  125. package/build/{users-permissions-translation-ko-json.3be77775.chunk.js → users-permissions-translation-ko-json.6bd0ae22.chunk.js} +1 -1
  126. package/build/{users-permissions-translation-pl-json.1dbdd4a1.chunk.js → users-permissions-translation-pl-json.c6a02992.chunk.js} +1 -1
  127. package/build/{users-permissions-translation-sv-json.d5d11648.chunk.js → users-permissions-translation-sv-json.370d6eee.chunk.js} +1 -1
  128. package/build/users-permissions-translation-tr-json.9bebc250.chunk.js +1 -0
  129. package/build/{users-permissions-translation-zh-json.92f406f9.chunk.js → users-permissions-translation-zh-json.1fea833f.chunk.js} +1 -1
  130. package/build/users-providers-settings-page.47a69fe9.chunk.js +1 -0
  131. package/build/{users-roles-settings-page.445e5e16.chunk.js → users-roles-settings-page.0a87ba15.chunk.js} +3 -3
  132. package/build/{webhook-edit-page.14ad1e6e.chunk.js → webhook-edit-page.dcc3d145.chunk.js} +4 -4
  133. package/build/{webhook-list-page.b87821f2.chunk.js → webhook-list-page.894e6959.chunk.js} +1 -1
  134. package/build/zh-Hans-json.1b3b4a64.chunk.js +1 -0
  135. package/build/zh-json.2d46108e.chunk.js +1 -0
  136. package/package.json +17 -22
  137. package/server/controllers/admin.js +2 -0
  138. package/server/index.js +2 -0
  139. package/server/middlewares/index.js +7 -0
  140. package/server/middlewares/rateLimit.js +43 -0
  141. package/server/routes/admin.js +1 -1
  142. package/server/routes/authentication.js +4 -1
  143. package/server/routes/roles.js +0 -8
  144. package/server/services/metrics.js +5 -2
  145. package/server/services/role.js +1 -0
  146. package/utils/get-plugins-path.js +17 -3
  147. package/webpack.alias.js +0 -2
  148. package/admin/src/content-manager/components/BackHeader/index.js +0 -8
  149. package/admin/src/content-manager/components/Block/components.js +0 -28
  150. package/admin/src/content-manager/components/Block/index.js +0 -43
  151. package/admin/src/content-manager/components/Container/index.js +0 -7
  152. package/admin/src/content-manager/components/CustomInputCheckbox/components.js +0 -77
  153. package/admin/src/content-manager/components/CustomInputCheckbox/index.js +0 -53
  154. package/admin/src/content-manager/components/DynamicComponentCard/Wrapper.js +0 -63
  155. package/admin/src/content-manager/components/FilterOptionsCTA/index.js +0 -14
  156. package/admin/src/content-manager/components/FormTitle/index.js +0 -22
  157. package/admin/src/content-manager/components/FormWrapper/index.js +0 -20
  158. package/admin/src/content-manager/components/InputJSON/FieldError.js +0 -38
  159. package/admin/src/content-manager/components/LayoutTitle/index.js +0 -19
  160. package/admin/src/content-manager/components/PlusButton/index.js +0 -52
  161. package/admin/src/content-manager/components/PreviewCarret/components.js +0 -27
  162. package/admin/src/content-manager/components/PreviewCarret/index.js +0 -22
  163. package/admin/src/content-manager/components/SectionTitle/Title.js +0 -11
  164. package/admin/src/content-manager/components/SectionTitle/index.js +0 -26
  165. package/build/1551f4f60c37af51121f.woff2 +0 -0
  166. package/build/1920.74a262e7.chunk.js +0 -245
  167. package/build/1e59d2330b4c6deb84b3.ttf +0 -0
  168. package/build/20fd1704ea223900efa9.woff2 +0 -0
  169. package/build/2285773e6b4b172f07d9.woff +0 -0
  170. package/build/23f19bb08961f37aaf69.eot +0 -0
  171. package/build/2438.61291207.chunk.js +0 -2183
  172. package/build/2517.9b4940f3.chunk.js +0 -117
  173. package/build/2f517e09eb2ca6650ff5.svg +0 -3717
  174. package/build/4306.f03c2b46.chunk.js +0 -98
  175. package/build/4318.7931eee7.chunk.js +0 -30
  176. package/build/4689f52cc96215721344.svg +0 -801
  177. package/build/491974d108fe4002b2aa.ttf +0 -0
  178. package/build/4986.3820d11d.chunk.js +0 -145
  179. package/build/504.9aeff724.chunk.js +0 -758
  180. package/build/527940b104eb2ea366c8.ttf +0 -0
  181. package/build/77206a6bb316fa0aded5.eot +0 -0
  182. package/build/7a3337626410ca2f4071.woff2 +0 -0
  183. package/build/7a8b4f130182d19a2d7c.svg +0 -5034
  184. package/build/805.e991a370.chunk.js +0 -138
  185. package/build/8b43027f47b20503057d.eot +0 -0
  186. package/build/9707.a0cc4ad8.chunk.js +0 -70
  187. package/build/9bbb245e67a133f6e486.eot +0 -0
  188. package/build/Admin-authenticatedApp.1e1d3bdd.chunk.js +0 -80
  189. package/build/Admin_pluginsPage.3c872de7.chunk.js +0 -6
  190. package/build/Admin_settingsPage.a1a5218b.chunk.js +0 -178
  191. package/build/admin-app.9cb0abc7.chunk.js +0 -112
  192. package/build/admin-edit-roles-page.23f15909.chunk.js +0 -1
  193. package/build/admin-edit-users.283b49ed.chunk.js +0 -10
  194. package/build/api-tokens-create-page.93dd0689.chunk.js +0 -1
  195. package/build/api-tokens-edit-page.b0adac81.chunk.js +0 -1
  196. package/build/bb58e57c48a3e911f15f.woff +0 -0
  197. package/build/be9ee23c0c6390141475.ttf +0 -0
  198. package/build/c1e38fd9e0e74ba58f7a.svg +0 -2671
  199. package/build/ca-json.07ae0f2c.chunk.js +0 -1
  200. package/build/codemirror-theme.a82cae4e.chunk.js +0 -34
  201. package/build/content-manager.01e04e11.chunk.js +0 -1200
  202. package/build/content-type-builder-list-view.4412efc3.chunk.js +0 -201
  203. package/build/content-type-builder-translation-de-json.0d7696b9.chunk.js +0 -1
  204. package/build/content-type-builder-translation-dk-json.4729f055.chunk.js +0 -1
  205. package/build/content-type-builder-translation-en-json.f985c9c4.chunk.js +0 -1
  206. package/build/content-type-builder-translation-es-json.333cf47f.chunk.js +0 -1
  207. package/build/content-type-builder-translation-ko-json.51201b12.chunk.js +0 -1
  208. package/build/content-type-builder-translation-pl-json.4a42349b.chunk.js +0 -1
  209. package/build/content-type-builder-translation-pt-BR-json.6fe3b8d1.chunk.js +0 -1
  210. package/build/content-type-builder-translation-sv-json.6deff030.chunk.js +0 -1
  211. package/build/content-type-builder-translation-tr-json.2e52bc60.chunk.js +0 -1
  212. package/build/content-type-builder-translation-zh-json.3b0afd31.chunk.js +0 -1
  213. package/build/content-type-builder.848a9610.chunk.js +0 -145
  214. package/build/cropper-css.12fe038c.chunk.js +0 -306
  215. package/build/d878b0a6a1144760244f.woff2 +0 -0
  216. package/build/dk-json.144c6a8e.chunk.js +0 -1
  217. package/build/eeccf4f66002c6f2ba24.woff +0 -0
  218. package/build/email-settings-page.d44a57cb.chunk.js +0 -15
  219. package/build/email-translation-tr-json.87f2feb3.chunk.js +0 -1
  220. package/build/en-json.7dd57947.chunk.js +0 -1
  221. package/build/es-json.6d123a82.chunk.js +0 -1
  222. package/build/f691f37e57f04c152e23.woff +0 -0
  223. package/build/fontawesome-css-all.15068c6e.chunk.js +0 -4618
  224. package/build/fontawesome-css.418f40da.chunk.js +0 -6
  225. package/build/fontawesome-js.252cc5f3.chunk.js +0 -7
  226. package/build/fr-json.28ab54cb.chunk.js +0 -1
  227. package/build/highlight.js.af2de364.chunk.js +0 -86
  228. package/build/hu-json.c4b641bb.chunk.js +0 -1
  229. package/build/ja-json.1c9eeeec.chunk.js +0 -1
  230. package/build/main.f31112a5.js +0 -2034
  231. package/build/nl-json.26f39180.chunk.js +0 -1
  232. package/build/runtime~main.f91e75cd.js +0 -2
  233. package/build/sk-json.7ba4b330.chunk.js +0 -1
  234. package/build/sso-settings-page.9f091262.chunk.js +0 -1
  235. package/build/tr-json.9c44ea0c.chunk.js +0 -1
  236. package/build/upload-settings.450cab1a.chunk.js +0 -18
  237. package/build/upload-translation-en-json.86da7b0a.chunk.js +0 -1
  238. package/build/upload-translation-sk-json.b03d4904.chunk.js +0 -1
  239. package/build/upload.a73936d9.chunk.js +0 -64
  240. package/build/users-advanced-settings-page.dc23bc56.chunk.js +0 -13
  241. package/build/users-email-settings-page.6541d372.chunk.js +0 -28
  242. package/build/users-permissions-translation-tr-json.cdc49a3c.chunk.js +0 -1
  243. package/build/users-providers-settings-page.e11a2f64.chunk.js +0 -33
  244. package/build/zh-Hans-json.21617c24.chunk.js +0 -1
  245. package/build/zh-json.2ecc6b99.chunk.js +0 -1
@@ -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 />;
@@ -1,16 +1,5 @@
1
1
  import { createGlobalStyle } from 'styled-components';
2
2
 
3
- const loadCss = async () => {
4
- await import(/* webpackChunkName: "fontawesome-css" */ 'font-awesome/css/font-awesome.min.css');
5
- await import(
6
- /* webpackChunkName: "fontawesome-css-all" */ '@fortawesome/fontawesome-free/css/all.css'
7
- );
8
- await import(/* webpackChunkName: "fontawesome-js" */ '@fortawesome/fontawesome-free/js/all.min');
9
- await import(/* webpackChunkName: "cropper-css" */ 'cropperjs/dist/cropper.css');
10
- };
11
-
12
- loadCss();
13
-
14
3
  const GlobalStyle = createGlobalStyle`
15
4
  body {
16
5
  background: ${({ theme }) => theme.colors.neutral100};
@@ -0,0 +1,49 @@
1
+ import PropTypes from 'prop-types';
2
+ import React from 'react';
3
+ import styled from 'styled-components';
4
+
5
+ import { Flex } from '@strapi/design-system';
6
+
7
+ const WIDTH_S = 5;
8
+ const WIDTH_M = 8;
9
+
10
+ const Wrapper = styled(Flex)`
11
+ border-radius: ${({ showBackground }) => (showBackground ? `50%` : 0)};
12
+ color: ${({ theme }) => theme.colors.neutral600};
13
+ height: ${({ theme, size }) => theme.spaces[size === 'S' ? WIDTH_S : WIDTH_M]};
14
+ width: ${({ theme, size }) => theme.spaces[size === 'S' ? WIDTH_S : WIDTH_M]};
15
+
16
+ svg {
17
+ height: ${({ theme, size }) => theme.spaces[size === 'S' ? WIDTH_S - 2 : WIDTH_M - 3]};
18
+ width: ${({ theme, size }) => theme.spaces[size === 'S' ? WIDTH_S - 2 : WIDTH_M - 3]};
19
+ }
20
+ `;
21
+
22
+ export function ComponentIcon({ showBackground = true, size = 'M' }) {
23
+ return (
24
+ <Wrapper
25
+ alignItems="center"
26
+ background={showBackground ? 'neutral200' : null}
27
+ justifyContent="center"
28
+ size={size}
29
+ showBackground={showBackground}
30
+ >
31
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
32
+ <path
33
+ d="M216.3 2c4.8-2.6 10.5-2.6 15.3 0L422.3 106c5.1 2.8 8.3 8.2 8.3 14s-3.2 11.2-8.3 14L231.7 238c-4.8 2.6-10.5 2.6-15.3 0L25.7 134c-5.1-2.8-8.3-8.2-8.3-14s3.2-11.2 8.3-14L216.3 2zM23.7 170l176 96c5.1 2.8 8.3 8.2 8.3 14V496c0 5.6-3 10.9-7.8 13.8s-10.9 3-15.8 .3L8.3 414C3.2 411.2 0 405.9 0 400V184c0-5.6 3-10.9 7.8-13.8s10.9-3 15.8-.3zm400.7 0c5-2.7 11-2.6 15.8 .3s7.8 8.1 7.8 13.8V400c0 5.9-3.2 11.2-8.3 14l-176 96c-5 2.7-11 2.6-15.8-.3s-7.8-8.1-7.8-13.8V280c0-5.9 3.2-11.2 8.3-14l176-96z"
34
+ fill="currentColor"
35
+ />
36
+ </svg>
37
+ </Wrapper>
38
+ );
39
+ }
40
+
41
+ ComponentIcon.defaultProps = {
42
+ showBackground: true,
43
+ size: 'M',
44
+ };
45
+
46
+ ComponentIcon.propTypes = {
47
+ showBackground: PropTypes.bool,
48
+ size: PropTypes.string,
49
+ };
@@ -0,0 +1 @@
1
+ export * from './ComponentIcon';
@@ -7,23 +7,13 @@
7
7
  import React from 'react';
8
8
  import PropTypes from 'prop-types';
9
9
  import styled from 'styled-components';
10
- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
11
10
 
12
11
  import { Box } from '@strapi/design-system/Box';
13
12
  import { Typography } from '@strapi/design-system/Typography';
14
13
  import { Stack } from '@strapi/design-system/Stack';
15
14
  import { pxToRem } from '@strapi/helper-plugin';
16
15
 
17
- const StyledFontAwesomeIcon = styled(FontAwesomeIcon)`
18
- width: ${pxToRem(32)} !important;
19
- height: ${pxToRem(32)} !important;
20
- padding: ${pxToRem(9)};
21
- border-radius: ${pxToRem(64)};
22
- background: ${({ theme }) => theme.colors.neutral150};
23
- path {
24
- fill: ${({ theme }) => theme.colors.neutral500};
25
- }
26
- `;
16
+ import { ComponentIcon } from '../../ComponentIcon';
27
17
 
28
18
  const ComponentBox = styled(Box)`
29
19
  flex-shrink: 0;
@@ -35,46 +25,42 @@ const ComponentBox = styled(Box)`
35
25
  justify-content: center;
36
26
  align-items: center;
37
27
 
38
- &.active,
28
+ &:focus,
39
29
  &:hover {
40
30
  border: 1px solid ${({ theme }) => theme.colors.primary200};
41
31
  background: ${({ theme }) => theme.colors.primary100};
42
32
 
43
- ${StyledFontAwesomeIcon} {
44
- background: ${({ theme }) => theme.colors.primary200};
45
- path {
46
- fill: ${({ theme }) => theme.colors.primary600};
47
- }
33
+ ${Typography} {
34
+ color: ${({ theme }) => theme.colors.primary600};
48
35
  }
49
36
 
50
- ${Typography} {
37
+ /* > Stack > ComponentIcon */
38
+ > div > div:first-child {
39
+ background: ${({ theme }) => theme.colors.primary200};
51
40
  color: ${({ theme }) => theme.colors.primary600};
52
41
  }
53
42
  }
54
43
  `;
55
44
 
56
- export default function ComponentCard({ children, icon, onClick }) {
45
+ export default function ComponentCard({ children, onClick }) {
57
46
  return (
58
- <button type="button" onClick={onClick}>
59
- <ComponentBox borderRadius="borderRadius">
60
- <Stack spacing={1} style={{ justifyContent: 'center', alignItems: 'center' }}>
61
- <StyledFontAwesomeIcon data-testid="component-card-icon" icon={icon} />
62
- <Typography variant="pi" fontWeight="bold" textColor="neutral600">
63
- {children}
64
- </Typography>
65
- </Stack>
66
- </ComponentBox>
67
- </button>
47
+ <ComponentBox as="button" type="button" onClick={onClick} hasRadius>
48
+ <Stack spacing={1} alignItems="center" justifyContent="center">
49
+ <ComponentIcon />
50
+
51
+ <Typography variant="pi" fontWeight="bold" textColor="neutral600">
52
+ {children}
53
+ </Typography>
54
+ </Stack>
55
+ </ComponentBox>
68
56
  );
69
57
  }
70
58
 
71
59
  ComponentCard.defaultProps = {
72
- icon: 'dice-d6',
73
60
  onClick() {},
74
61
  };
75
62
 
76
63
  ComponentCard.propTypes = {
77
64
  children: PropTypes.node.isRequired,
78
- icon: PropTypes.string,
79
65
  onClick: PropTypes.func,
80
66
  };
@@ -30,8 +30,8 @@ const ComponentCategory = ({ category, components, variant, isOpen, onAddCompone
30
30
  <AccordionContent>
31
31
  <Box paddingTop={4} paddingBottom={4} paddingLeft={3} paddingRight={3}>
32
32
  <Grid>
33
- {components.map(({ componentUid, info: { displayName, icon } }) => (
34
- <ComponentCard key={componentUid} icon={icon} onClick={onAddComponent(componentUid)}>
33
+ {components.map(({ componentUid, info: { displayName } }) => (
34
+ <ComponentCard key={componentUid} onClick={onAddComponent(componentUid)}>
35
35
  {formatMessage({ id: displayName, defaultMessage: displayName })}
36
36
  </ComponentCard>
37
37
  ))}
@@ -2,7 +2,6 @@ import React, { useMemo, useState } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import styled from 'styled-components';
4
4
  import { useIntl } from 'react-intl';
5
- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
6
5
  import get from 'lodash/get';
7
6
 
8
7
  import { Accordion, AccordionToggle, AccordionContent } from '@strapi/design-system/Accordion';
@@ -20,6 +19,7 @@ import ArrowUp from '@strapi/icons/ArrowUp';
20
19
  import { useContentTypeLayout } from '../../../hooks';
21
20
  import { getTrad } from '../../../utils';
22
21
 
22
+ import { ComponentIcon } from '../../ComponentIcon';
23
23
  import FieldComponent from '../../FieldComponent';
24
24
 
25
25
  const IconButtonCustom = styled(IconButton)`
@@ -73,7 +73,7 @@ const DynamicZoneComponent = ({
73
73
 
74
74
  const mainField = get(modifiedData, [name, index, mainFieldKey]) ?? '';
75
75
 
76
- const displayedValue = mainFieldKey === 'id' ? '' : mainField.trim();
76
+ const displayedValue = mainFieldKey === 'id' ? '' : String(mainField).trim();
77
77
 
78
78
  const mainValue = displayedValue.length > 0 ? ` - ${displayedValue}` : displayedValue;
79
79
 
@@ -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={<ComponentIcon showBackground={false} size="S" />}
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 { Main } from '@strapi/design-system/Main';
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
- if (initialValues && currentContentTypeLayout?.attributes) {
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
- }, [initialValues, currentContentTypeLayout, components]);
213
+ }, [
214
+ initialValues,
215
+ currentContentTypeLayout,
216
+ components,
217
+ setModifiedDataOnly,
218
+ reduxDispatch,
219
+ previousInitialValues,
220
+ ]);
185
221
 
186
222
  const dispatchAddComponent = useCallback(
187
223
  (type) =>
@@ -104,6 +104,11 @@ const reducer = (state, action) =>
104
104
  (value) => value.type === 'component' && value.repeatable
105
105
  )(componentLayoutData.attributes);
106
106
 
107
+ const nonRepeatableComponentPaths = recursivelyFindPathsBasedOnCondition(
108
+ allComponents,
109
+ (value) => value.type === 'component' && !value.repeatable
110
+ )(componentLayoutData.attributes);
111
+
107
112
  const componentDataStructure = relationPaths.reduce((acc, current) => {
108
113
  const [componentName] = current.split('.');
109
114
 
@@ -112,8 +117,21 @@ const reducer = (state, action) =>
112
117
  * has another repeatable component inside of it we
113
118
  * don't need to attach the array at this point because that will be
114
119
  * done again deeper in the nest.
120
+ *
121
+ * We also need to handle cases with single components nested within
122
+ * repeatables by checking that the relation path does not match a
123
+ * non-repeatable component path. This accounts for component
124
+ * structures such as:
125
+ * - outer_single_compo
126
+ * - level_one_repeatable
127
+ * - level_two_single_component
128
+ * - level_three_repeatable
115
129
  */
116
- if (!repeatableFields.includes(componentName)) {
130
+
131
+ if (
132
+ !repeatableFields.includes(componentName) &&
133
+ !nonRepeatableComponentPaths.includes(componentName)
134
+ ) {
117
135
  set(acc, current, []);
118
136
  }
119
137
 
@@ -128,7 +146,6 @@ const reducer = (state, action) =>
128
146
 
129
147
  break;
130
148
  }
131
-
132
149
  case 'LOAD_RELATION': {
133
150
  const initialDataPath = ['initialData', ...action.keys];
134
151
  const modifiedDataPath = ['modifiedData', ...action.keys];
@@ -192,6 +209,7 @@ const reducer = (state, action) =>
192
209
  componentPaths = [],
193
210
  repeatableComponentPaths = [],
194
211
  dynamicZonePaths = [],
212
+ setModifiedDataOnly,
195
213
  } = action;
196
214
 
197
215
  /**
@@ -243,7 +261,10 @@ const reducer = (state, action) =>
243
261
  return acc;
244
262
  }, data);
245
263
 
246
- draftState.initialData = mergeDataWithPreparedRelations;
264
+ if (!setModifiedDataOnly) {
265
+ draftState.initialData = mergeDataWithPreparedRelations;
266
+ }
267
+
247
268
  draftState.modifiedData = mergeDataWithPreparedRelations;
248
269
 
249
270
  draftState.formErrors = {};
@@ -24,7 +24,8 @@ export const findLeafByPathAndReplace = (endpath, replaceWith) => {
24
24
  * and the current path is not undefined in the accumulator
25
25
  * then we assume it's a leaf and we can replace it.
26
26
  */
27
- if (endpath === curr && acc[curr] !== undefined) {
27
+
28
+ if (ind === currentArr.length - 1 && endpath === curr && acc[curr] !== undefined) {
28
29
  set(acc, curr, replaceWith);
29
30
 
30
31
  return acc;
@@ -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) => path.split(`${componentName}.`)[1]);
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];
@@ -3,12 +3,18 @@ import PropTypes from 'prop-types';
3
3
  import { useIntl } from 'react-intl';
4
4
  import { Field } from '@strapi/design-system/Field';
5
5
 
6
- const FieldWrapper = ({ name, hint, error, children }) => {
6
+ const FieldWrapper = ({ name, hint, error, children, required }) => {
7
7
  const { formatMessage } = useIntl();
8
8
  const errorMessage = error ? formatMessage({ id: error, defaultMessage: error }) : '';
9
9
 
10
10
  return (
11
- <Field name={name} hint={hint && formatMessage(hint)} error={errorMessage} id={name}>
11
+ <Field
12
+ name={name}
13
+ hint={hint && formatMessage(hint)}
14
+ error={errorMessage}
15
+ id={name}
16
+ required={required}
17
+ >
12
18
  {children}
13
19
  </Field>
14
20
  );
@@ -17,6 +23,7 @@ const FieldWrapper = ({ name, hint, error, children }) => {
17
23
  FieldWrapper.defaultProps = {
18
24
  hint: undefined,
19
25
  error: '',
26
+ required: false,
20
27
  };
21
28
 
22
29
  FieldWrapper.propTypes = {
@@ -27,6 +34,7 @@ FieldWrapper.propTypes = {
27
34
  }),
28
35
  error: PropTypes.string,
29
36
  children: PropTypes.node.isRequired,
37
+ required: PropTypes.bool,
30
38
  };
31
39
 
32
40
  export default FieldWrapper;
@@ -1,18 +1,9 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import styled from 'styled-components';
4
3
  import { useIntl } from 'react-intl';
5
4
  import { FieldLabel } from '@strapi/design-system/Field';
6
- import { Box } from '@strapi/design-system/Box';
7
- import { Flex } from '@strapi/design-system/Flex';
8
5
 
9
- const LabelAction = styled(Box)`
10
- svg path {
11
- fill: ${({ theme }) => theme.colors.neutral500};
12
- }
13
- `;
14
-
15
- const Label = ({ intlLabel, labelAction, name, required }) => {
6
+ const Label = ({ intlLabel, labelAction, name }) => {
16
7
  const { formatMessage } = useIntl();
17
8
  const label = intlLabel?.id
18
9
  ? formatMessage(
@@ -21,19 +12,13 @@ const Label = ({ intlLabel, labelAction, name, required }) => {
21
12
  )
22
13
  : name;
23
14
 
24
- return (
25
- <Flex>
26
- <FieldLabel required={required}>{label}</FieldLabel>
27
- {labelAction && <LabelAction paddingLeft={1}>{labelAction}</LabelAction>}
28
- </Flex>
29
- );
15
+ return <FieldLabel action={labelAction}>{label}</FieldLabel>;
30
16
  };
31
17
 
32
18
  Label.defaultProps = {
33
19
  id: undefined,
34
20
  intlLabel: undefined,
35
21
  labelAction: undefined,
36
- required: false,
37
22
  };
38
23
 
39
24
  Label.propTypes = {
@@ -45,7 +30,6 @@ Label.propTypes = {
45
30
  }),
46
31
  labelAction: PropTypes.element,
47
32
  name: PropTypes.string.isRequired,
48
- required: PropTypes.bool,
49
33
  };
50
34
 
51
35
  export default Label;
@@ -157,13 +157,17 @@ class InputJSON extends React.Component {
157
157
  }
158
158
 
159
159
  return (
160
- <FieldWrapper name={this.props.name} hint={this.props.description} error={this.props.error}>
160
+ <FieldWrapper
161
+ name={this.props.name}
162
+ hint={this.props.description}
163
+ error={this.props.error}
164
+ required={this.props.required}
165
+ >
161
166
  <Stack spacing={1}>
162
167
  <Label
163
168
  intlLabel={this.props.intlLabel}
164
- labelAction={this.props.labelAction}
165
169
  name={this.props.name}
166
- required={this.props.required}
170
+ labelAction={this.props.labelAction}
167
171
  />
168
172
  <StyledBox error={this.props.error}>
169
173
  <EditorWrapper disabled={this.props.disabled}>
@@ -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
- white-space: nowrap;
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: inherit;
33
+ display: block;
39
34
  }
40
35
  `;
41
36
 
@@ -231,15 +226,13 @@ const RelationInput = ({
231
226
  }, [previewRelationsLength, relations]);
232
227
 
233
228
  return (
234
- <Field error={error} name={name} hint={description} id={id}>
229
+ <Field error={error} name={name} hint={description} id={id} required={required}>
235
230
  <Relation
236
231
  totalNumberOfRelations={totalNumberOfRelations}
237
232
  size={size}
238
233
  search={
239
234
  <>
240
- <FieldLabel action={labelAction} required={required}>
241
- {label}
242
- </FieldLabel>
235
+ <FieldLabel action={labelAction}>{label}</FieldLabel>
243
236
  <ReactSelect
244
237
  // position fixed doesn't update position on scroll
245
238
  // react select doesn't update menu position on options change
@@ -322,7 +315,7 @@ const RelationInput = ({
322
315
  }
323
316
  style={style}
324
317
  >
325
- <BoxEllipsis minWidth={0} paddingTop={1} paddingBottom={1} paddingRight={4}>
318
+ <Box minWidth={0} paddingTop={1} paddingBottom={1} paddingRight={4}>
326
319
  <Tooltip description={mainField ?? `${id}`}>
327
320
  {href ? (
328
321
  <LinkEllipsis to={href} disabled={disabled}>
@@ -334,7 +327,7 @@ const RelationInput = ({
334
327
  </Typography>
335
328
  )}
336
329
  </Tooltip>
337
- </BoxEllipsis>
330
+ </Box>
338
331
 
339
332
  {publicationState && (
340
333
  <Status variant={statusColor} showBullet={false} size="S">
@@ -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
 
@@ -8,7 +8,6 @@ import { Flex } from '@strapi/design-system/Flex';
8
8
  import { KeyboardNavigable } from '@strapi/design-system/KeyboardNavigable';
9
9
 
10
10
  const AccordionFooter = styled(Box)`
11
- overflow: hidden;
12
11
  border-bottom: 1px solid ${({ theme }) => theme.colors.neutral200};
13
12
  border-right: 1px solid ${({ theme }) => theme.colors.neutral200};
14
13
  border-left: 1px solid ${({ theme }) => theme.colors.neutral200};
@@ -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
  );
@@ -54,9 +54,7 @@ const RepeatableComponent = ({
54
54
  [componentUid, getComponentLayout]
55
55
  );
56
56
 
57
- const nextTempKey = useMemo(() => {
58
- return getMaxTempKey(componentValue || []) + 1;
59
- }, [componentValue]);
57
+ const nextTempKey = useMemo(() => getMaxTempKey(componentValue || []) + 1, [componentValue]);
60
58
 
61
59
  const componentErrorKeys = getComponentErrorKeys(name, formErrors);
62
60