@strapi/admin 4.5.4 → 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 (203) hide show
  1. package/admin/src/components/GlobalStyle/index.js +0 -11
  2. package/admin/src/content-manager/components/ComponentIcon/ComponentIcon.js +49 -0
  3. package/admin/src/content-manager/components/ComponentIcon/index.js +1 -0
  4. package/admin/src/content-manager/components/DynamicZone/components/ComponentCard.js +17 -31
  5. package/admin/src/content-manager/components/DynamicZone/components/ComponentCategory.js +2 -2
  6. package/admin/src/content-manager/components/DynamicZone/components/DynamicComponent.js +3 -3
  7. package/admin/src/content-manager/components/EditViewDataManagerProvider/reducer.js +19 -2
  8. package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/findLeafByPathAndReplace.js +2 -1
  9. package/admin/src/content-manager/components/InputJSON/FieldWrapper.js +10 -2
  10. package/admin/src/content-manager/components/InputJSON/Label.js +2 -18
  11. package/admin/src/content-manager/components/InputJSON/index.js +7 -3
  12. package/admin/src/content-manager/components/RelationInput/RelationInput.js +2 -4
  13. package/admin/src/content-manager/components/RepeatableComponent/AccordionGroupCustom/index.js +0 -1
  14. package/admin/src/content-manager/components/RepeatableComponent/index.js +1 -3
  15. package/admin/src/content-manager/pages/EditSettingsView/components/DynamicZoneList.js +18 -38
  16. package/admin/src/content-manager/pages/EditView/Header/index.js +1 -1
  17. package/admin/src/pages/Admin/Onboarding/index.js +42 -44
  18. package/admin/src/pages/AuthPage/components/Register/index.js +1 -1
  19. package/admin/src/pages/AuthPage/components/ResetPassword/index.js +1 -1
  20. package/admin/src/pages/ProfilePage/index.js +1 -1
  21. package/admin/src/translations/ca.json +2 -3
  22. package/admin/src/translations/dk.json +2 -2
  23. package/admin/src/translations/en.json +2 -1
  24. package/admin/src/translations/es.json +2 -2
  25. package/admin/src/translations/fr.json +2 -2
  26. package/admin/src/translations/hu.json +2 -2
  27. package/admin/src/translations/ja.json +2 -2
  28. package/admin/src/translations/nl.json +2 -2
  29. package/admin/src/translations/sk.json +274 -52
  30. package/admin/src/translations/zh-Hans.json +1 -1
  31. package/admin/src/translations/zh.json +2 -2
  32. package/build/2235.06c13219.chunk.js +106 -0
  33. package/build/{1233.802422fa.chunk.js → 2473.45658149.chunk.js} +40 -40
  34. package/build/2598.962797b2.chunk.js +159 -0
  35. package/build/{4318.9283c350.chunk.js → 4318.0bbd3f4b.chunk.js} +1 -1
  36. package/build/4958.7c118f5e.chunk.js +276 -0
  37. package/build/5052.712419ea.chunk.js +65 -0
  38. package/build/7295.e12e5587.chunk.js +114 -0
  39. package/build/805.ddcead70.chunk.js +138 -0
  40. package/build/{8633.43ec9042.chunk.js → 8633.19be8f45.chunk.js} +1 -1
  41. package/build/874.bde3ea04.chunk.js +104 -0
  42. package/build/9707.77e475ee.chunk.js +101 -0
  43. package/build/Admin-authenticatedApp.59063c5f.chunk.js +72 -0
  44. package/build/{Admin_marketplace.ed754a4a.chunk.js → Admin_marketplace.615343fb.chunk.js} +6 -6
  45. package/build/Admin_pluginsPage.67728975.chunk.js +6 -0
  46. package/build/{Admin_profilePage.60ab80bb.chunk.js → Admin_profilePage.175c6516.chunk.js} +2 -2
  47. package/build/Admin_settingsPage.ba0605a2.chunk.js +178 -0
  48. package/build/Upload_ConfigureTheView.7cb2a3fd.chunk.js +1 -0
  49. package/build/admin-app.77b9f2b9.chunk.js +112 -0
  50. package/build/{admin-users.e64fb0f1.chunk.js → admin-users.4b6b47f8.chunk.js} +2 -2
  51. package/build/api-tokens-create-page.dd4ddfcb.chunk.js +1 -0
  52. package/build/api-tokens-edit-page.821c5a6c.chunk.js +1 -0
  53. package/build/{api-tokens-list-page.700e575f.chunk.js → api-tokens-list-page.50519ed7.chunk.js} +1 -1
  54. package/build/ca-json.fa3e6f48.chunk.js +1 -0
  55. package/build/{codemirror-css.4e2bbed3.chunk.js → codemirror-css.aa4c2de2.chunk.js} +2 -3
  56. package/build/codemirror-theme.c1d2b07c.chunk.js +33 -0
  57. package/build/content-manager.d89dcc40.chunk.js +1184 -0
  58. package/build/content-type-builder-list-view.4aea46fa.chunk.js +198 -0
  59. package/build/content-type-builder-translation-de-json.a52482c7.chunk.js +1 -0
  60. package/build/content-type-builder-translation-dk-json.a8616510.chunk.js +1 -0
  61. package/build/content-type-builder-translation-en-json.1d9a3c14.chunk.js +1 -0
  62. package/build/content-type-builder-translation-es-json.c3ea46fb.chunk.js +1 -0
  63. package/build/content-type-builder-translation-ko-json.3fb7ddc8.chunk.js +1 -0
  64. package/build/content-type-builder-translation-pl-json.9b2993b2.chunk.js +1 -0
  65. package/build/content-type-builder-translation-pt-BR-json.6d255441.chunk.js +1 -0
  66. package/build/content-type-builder-translation-sv-json.c608b9ca.chunk.js +1 -0
  67. package/build/content-type-builder-translation-zh-json.b79513e4.chunk.js +1 -0
  68. package/build/content-type-builder.3b1a75a2.chunk.js +127 -0
  69. package/build/dk-json.ab5dd6ac.chunk.js +1 -0
  70. package/build/email-settings-page.d7165683.chunk.js +15 -0
  71. package/build/en-json.d268c039.chunk.js +1 -0
  72. package/build/es-json.8fe19fb3.chunk.js +1 -0
  73. package/build/fr-json.7ba93468.chunk.js +1 -0
  74. package/build/highlight.js.aea3bcf9.chunk.js +85 -0
  75. package/build/hu-json.459334f8.chunk.js +1 -0
  76. package/build/{i18n-settings-page.195d42fe.chunk.js → i18n-settings-page.ee572037.chunk.js} +1 -1
  77. package/build/index.html +1 -1
  78. package/build/ja-json.e69860d6.chunk.js +1 -0
  79. package/build/main.1a19193b.js +4417 -0
  80. package/build/nl-json.02de2e84.chunk.js +1 -0
  81. package/build/runtime~main.2e5b4723.js +2 -0
  82. package/build/sk-json.2af48064.chunk.js +1 -0
  83. package/build/sso-settings-page.91924df1.chunk.js +41 -0
  84. package/build/upload-settings.5fd96cda.chunk.js +89 -0
  85. package/build/upload-translation-en-json.32cf9aff.chunk.js +1 -0
  86. package/build/upload-translation-sk-json.fe86c53b.chunk.js +1 -0
  87. package/build/upload.9993c14f.chunk.js +38 -0
  88. package/build/users-advanced-settings-page.c4431a05.chunk.js +13 -0
  89. package/build/users-email-settings-page.d8a0bf10.chunk.js +28 -0
  90. package/build/{users-permissions-translation-dk-json.fe39c74b.chunk.js → users-permissions-translation-dk-json.bad0b786.chunk.js} +1 -1
  91. package/build/{users-permissions-translation-en-json.765abf48.chunk.js → users-permissions-translation-en-json.aeab388a.chunk.js} +1 -1
  92. package/build/{users-permissions-translation-es-json.1bb9cde2.chunk.js → users-permissions-translation-es-json.152a923f.chunk.js} +1 -1
  93. package/build/{users-permissions-translation-ko-json.3be77775.chunk.js → users-permissions-translation-ko-json.6bd0ae22.chunk.js} +1 -1
  94. package/build/{users-permissions-translation-pl-json.1dbdd4a1.chunk.js → users-permissions-translation-pl-json.c6a02992.chunk.js} +1 -1
  95. package/build/{users-permissions-translation-sv-json.d5d11648.chunk.js → users-permissions-translation-sv-json.370d6eee.chunk.js} +1 -1
  96. package/build/{users-permissions-translation-zh-json.92f406f9.chunk.js → users-permissions-translation-zh-json.1fea833f.chunk.js} +1 -1
  97. package/build/users-providers-settings-page.47a69fe9.chunk.js +1 -0
  98. package/build/users-roles-settings-page.0a87ba15.chunk.js +30 -0
  99. package/build/{webhook-edit-page.1215a6b7.chunk.js → webhook-edit-page.dcc3d145.chunk.js} +4 -4
  100. package/build/{webhook-list-page.b87821f2.chunk.js → webhook-list-page.894e6959.chunk.js} +1 -1
  101. package/build/zh-Hans-json.1b3b4a64.chunk.js +1 -0
  102. package/build/zh-json.2d46108e.chunk.js +1 -0
  103. package/package.json +13 -18
  104. package/server/index.js +2 -0
  105. package/server/middlewares/index.js +7 -0
  106. package/server/middlewares/rateLimit.js +43 -0
  107. package/server/routes/authentication.js +4 -1
  108. package/server/routes/roles.js +0 -8
  109. package/server/services/role.js +1 -0
  110. package/webpack.alias.js +0 -2
  111. package/admin/src/content-manager/components/BackHeader/index.js +0 -8
  112. package/admin/src/content-manager/components/Block/components.js +0 -28
  113. package/admin/src/content-manager/components/Block/index.js +0 -43
  114. package/admin/src/content-manager/components/Container/index.js +0 -7
  115. package/admin/src/content-manager/components/CustomInputCheckbox/components.js +0 -77
  116. package/admin/src/content-manager/components/CustomInputCheckbox/index.js +0 -53
  117. package/admin/src/content-manager/components/DynamicComponentCard/Wrapper.js +0 -63
  118. package/admin/src/content-manager/components/FilterOptionsCTA/index.js +0 -14
  119. package/admin/src/content-manager/components/FormTitle/index.js +0 -22
  120. package/admin/src/content-manager/components/FormWrapper/index.js +0 -20
  121. package/admin/src/content-manager/components/InputJSON/FieldError.js +0 -38
  122. package/admin/src/content-manager/components/LayoutTitle/index.js +0 -19
  123. package/admin/src/content-manager/components/PlusButton/index.js +0 -52
  124. package/admin/src/content-manager/components/PreviewCarret/components.js +0 -27
  125. package/admin/src/content-manager/components/PreviewCarret/index.js +0 -22
  126. package/admin/src/content-manager/components/SectionTitle/Title.js +0 -11
  127. package/admin/src/content-manager/components/SectionTitle/index.js +0 -26
  128. package/build/1551f4f60c37af51121f.woff2 +0 -0
  129. package/build/1e59d2330b4c6deb84b3.ttf +0 -0
  130. package/build/20fd1704ea223900efa9.woff2 +0 -0
  131. package/build/2285773e6b4b172f07d9.woff +0 -0
  132. package/build/23f19bb08961f37aaf69.eot +0 -0
  133. package/build/2f517e09eb2ca6650ff5.svg +0 -3717
  134. package/build/4306.df40a798.chunk.js +0 -98
  135. package/build/4689f52cc96215721344.svg +0 -801
  136. package/build/491974d108fe4002b2aa.ttf +0 -0
  137. package/build/504.9aeff724.chunk.js +0 -758
  138. package/build/5057.195a59ff.chunk.js +0 -65
  139. package/build/527940b104eb2ea366c8.ttf +0 -0
  140. package/build/77206a6bb316fa0aded5.eot +0 -0
  141. package/build/7a3337626410ca2f4071.woff2 +0 -0
  142. package/build/7a8b4f130182d19a2d7c.svg +0 -5034
  143. package/build/805.e991a370.chunk.js +0 -138
  144. package/build/8176.e929d326.chunk.js +0 -145
  145. package/build/8881.c693411a.chunk.js +0 -245
  146. package/build/8b43027f47b20503057d.eot +0 -0
  147. package/build/9161.4a0ab137.chunk.js +0 -2119
  148. package/build/9279.6290c87a.chunk.js +0 -117
  149. package/build/9707.a0cc4ad8.chunk.js +0 -70
  150. package/build/9bbb245e67a133f6e486.eot +0 -0
  151. package/build/Admin-authenticatedApp.0da578b8.chunk.js +0 -80
  152. package/build/Admin_pluginsPage.3c872de7.chunk.js +0 -6
  153. package/build/Admin_settingsPage.6ef8acc9.chunk.js +0 -178
  154. package/build/admin-app.a3277e72.chunk.js +0 -112
  155. package/build/api-tokens-create-page.93dd0689.chunk.js +0 -1
  156. package/build/api-tokens-edit-page.b0adac81.chunk.js +0 -1
  157. package/build/bb58e57c48a3e911f15f.woff +0 -0
  158. package/build/be9ee23c0c6390141475.ttf +0 -0
  159. package/build/c1e38fd9e0e74ba58f7a.svg +0 -2671
  160. package/build/ca-json.07ae0f2c.chunk.js +0 -1
  161. package/build/codemirror-theme.a82cae4e.chunk.js +0 -34
  162. package/build/content-manager.f9630c3b.chunk.js +0 -1197
  163. package/build/content-type-builder-list-view.4412efc3.chunk.js +0 -201
  164. package/build/content-type-builder-translation-de-json.0d7696b9.chunk.js +0 -1
  165. package/build/content-type-builder-translation-dk-json.4729f055.chunk.js +0 -1
  166. package/build/content-type-builder-translation-en-json.f985c9c4.chunk.js +0 -1
  167. package/build/content-type-builder-translation-es-json.333cf47f.chunk.js +0 -1
  168. package/build/content-type-builder-translation-ko-json.51201b12.chunk.js +0 -1
  169. package/build/content-type-builder-translation-pl-json.4a42349b.chunk.js +0 -1
  170. package/build/content-type-builder-translation-pt-BR-json.6fe3b8d1.chunk.js +0 -1
  171. package/build/content-type-builder-translation-sv-json.6deff030.chunk.js +0 -1
  172. package/build/content-type-builder-translation-zh-json.3b0afd31.chunk.js +0 -1
  173. package/build/content-type-builder.b132b5f4.chunk.js +0 -145
  174. package/build/cropper-css.12fe038c.chunk.js +0 -306
  175. package/build/d878b0a6a1144760244f.woff2 +0 -0
  176. package/build/dk-json.144c6a8e.chunk.js +0 -1
  177. package/build/eeccf4f66002c6f2ba24.woff +0 -0
  178. package/build/email-settings-page.c6e62f6b.chunk.js +0 -15
  179. package/build/en-json.7dd57947.chunk.js +0 -1
  180. package/build/es-json.6d123a82.chunk.js +0 -1
  181. package/build/f691f37e57f04c152e23.woff +0 -0
  182. package/build/fontawesome-css-all.15068c6e.chunk.js +0 -4618
  183. package/build/fontawesome-css.418f40da.chunk.js +0 -6
  184. package/build/fontawesome-js.252cc5f3.chunk.js +0 -7
  185. package/build/fr-json.28ab54cb.chunk.js +0 -1
  186. package/build/highlight.js.af2de364.chunk.js +0 -86
  187. package/build/hu-json.c4b641bb.chunk.js +0 -1
  188. package/build/ja-json.1c9eeeec.chunk.js +0 -1
  189. package/build/main.71f24343.js +0 -2034
  190. package/build/nl-json.26f39180.chunk.js +0 -1
  191. package/build/runtime~main.1115f82b.js +0 -2
  192. package/build/sk-json.7ba4b330.chunk.js +0 -1
  193. package/build/sso-settings-page.feed2f45.chunk.js +0 -1
  194. package/build/upload-settings.450cab1a.chunk.js +0 -18
  195. package/build/upload-translation-en-json.86da7b0a.chunk.js +0 -1
  196. package/build/upload-translation-sk-json.b03d4904.chunk.js +0 -1
  197. package/build/upload.74540aab.chunk.js +0 -64
  198. package/build/users-advanced-settings-page.0c0b8230.chunk.js +0 -13
  199. package/build/users-email-settings-page.3126ff8c.chunk.js +0 -28
  200. package/build/users-providers-settings-page.b7b602e2.chunk.js +0 -33
  201. package/build/users-roles-settings-page.ce5b582d.chunk.js +0 -30
  202. package/build/zh-Hans-json.21617c24.chunk.js +0 -1
  203. package/build/zh-json.2ecc6b99.chunk.js +0 -1
@@ -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={icon && <FontAwesomeIcon icon={icon} />}
114
+ startIcon={<ComponentIcon showBackground={false} size="S" />}
115
115
  action={
116
116
  <Stack horizontal spacing={0} expanded={isOpen}>
117
117
  {showDownIcon && (
@@ -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];
@@ -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;
@@ -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}>
@@ -226,15 +226,13 @@ const RelationInput = ({
226
226
  }, [previewRelationsLength, relations]);
227
227
 
228
228
  return (
229
- <Field error={error} name={name} hint={description} id={id}>
229
+ <Field error={error} name={name} hint={description} id={id} required={required}>
230
230
  <Relation
231
231
  totalNumberOfRelations={totalNumberOfRelations}
232
232
  size={size}
233
233
  search={
234
234
  <>
235
- <FieldLabel action={labelAction} required={required}>
236
- {label}
237
- </FieldLabel>
235
+ <FieldLabel action={labelAction}>{label}</FieldLabel>
238
236
  <ReactSelect
239
237
  // position fixed doesn't update position on scroll
240
238
  // react select doesn't update menu position on options change
@@ -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};
@@ -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
 
@@ -1,43 +1,31 @@
1
1
  import React from 'react';
2
- import get from 'lodash/get';
3
- import PropTypes from 'prop-types';
4
- import { Flex } from '@strapi/design-system/Flex';
5
- import { Typography } from '@strapi/design-system/Typography';
6
- import { Box } from '@strapi/design-system/Box';
7
- import { Stack } from '@strapi/design-system/Stack';
8
- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
9
2
  import styled from 'styled-components';
10
3
  import { Link } from 'react-router-dom';
4
+ import PropTypes from 'prop-types';
5
+ import { Box, Flex, Typography, Stack } from '@strapi/design-system';
6
+
7
+ import { ComponentIcon } from '../../../components/ComponentIcon';
11
8
  import useLayoutDnd from '../../../hooks/useLayoutDnd';
12
9
 
13
- const CustomFlex = styled(Flex)`
14
- border-radius: 50%;
15
- svg {
16
- & > * {
17
- fill: ${({ theme }) => theme.colors.neutral500};
18
- }
19
- width: 12px;
20
- height: 12px;
21
- }
22
- `;
23
10
  const CustomLink = styled(Flex)`
24
11
  text-decoration: none;
12
+
13
+ &:focus,
25
14
  &:hover {
26
15
  ${({ theme }) => `
27
- background: ${theme.colors.primary100};
28
- svg {
29
- & > * {
30
- fill: ${theme.colors.primary600};
31
- }
32
- }
16
+ background-color: ${theme.colors.primary100};
17
+ border-color: ${theme.colors.primary200};
18
+
33
19
  ${Typography} {
34
20
  color: ${theme.colors.primary600};
35
21
  }
36
- ${CustomFlex} {
37
- background: ${theme.colors.primary200};
38
- }
39
- border-color: ${theme.colors.primary200};
40
22
  `}
23
+
24
+ /* > ComponentIcon */
25
+ > div:first-child {
26
+ background: ${({ theme }) => theme.colors.primary200};
27
+ color: ${({ theme }) => theme.colors.primary600};
28
+ }
41
29
  }
42
30
  `;
43
31
 
@@ -61,19 +49,11 @@ const DynamicZoneList = ({ components }) => {
61
49
  as={Link}
62
50
  to={`/content-manager/components/${componentUid}/configurations/edit`}
63
51
  >
64
- <CustomFlex
65
- width={`${32 / 16}rem`}
66
- height={`${32 / 16}rem`}
67
- background="neutral150"
68
- justifyContent="center"
69
- alignItems="center"
70
- padding={2}
71
- >
72
- <FontAwesomeIcon icon={get(componentLayouts, [componentUid, 'info', 'icon'], '')} />
73
- </CustomFlex>
52
+ <ComponentIcon />
53
+
74
54
  <Box paddingTop={1}>
75
55
  <Typography fontSize={1} textColor="neutral600" fontWeight="bold">
76
- {get(componentLayouts, [componentUid, 'info', 'displayName'], '')}
56
+ {componentLayouts?.[componentUid]?.info?.displayName ?? ''}
77
57
  </Typography>
78
58
  </Box>
79
59
  </CustomLink>
@@ -74,7 +74,7 @@ const Header = ({
74
74
  {formatMessage({ id: 'app.utils.publish', defaultMessage: 'Publish' })}
75
75
  </Button>
76
76
  )}
77
- <Button disabled={!didChangeData} isLoading={status === 'submit-pending'} type="submit">
77
+ <Button disabled={!didChangeData} loading={status === 'submit-pending'} type="submit">
78
78
  {formatMessage({
79
79
  id: getTrad('containers.Edit.submit'),
80
80
  defaultMessage: 'Save',
@@ -1,11 +1,10 @@
1
1
  import React, { useState } from 'react';
2
2
  import styled from 'styled-components';
3
3
  import { useIntl } from 'react-intl';
4
- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
5
- import { faQuestion, faTimes } from '@fortawesome/free-solid-svg-icons';
6
- import { Box } from '@strapi/design-system/Box';
7
- import { Typography } from '@strapi/design-system/Typography';
8
- import { FocusTrap } from '@strapi/design-system/FocusTrap';
4
+ import { Box, Flex, FocusTrap, Typography, Icon, Stack } from '@strapi/design-system';
5
+ import { Book, Cross, Information, Question } from '@strapi/icons';
6
+ import { pxToRem } from '@strapi/helper-plugin';
7
+
9
8
  import { useConfigurations } from '../../../hooks';
10
9
 
11
10
  const OnboardingWrapper = styled(Box)`
@@ -14,52 +13,44 @@ const OnboardingWrapper = styled(Box)`
14
13
  right: ${({ theme }) => theme.spaces[2]};
15
14
  `;
16
15
 
17
- const Button = styled.button`
16
+ const Button = styled(Box)`
18
17
  width: ${({ theme }) => theme.spaces[8]};
19
18
  height: ${({ theme }) => theme.spaces[8]};
20
19
  background: ${({ theme }) => theme.colors.primary600};
21
20
  box-shadow: ${({ theme }) => theme.shadows.tableShadow};
22
21
  border-radius: 50%;
23
- svg {
24
- color: ${({ theme }) => theme.colors.buttonNeutral0};
22
+
23
+ svg path {
24
+ fill: ${({ theme }) => theme.colors.buttonNeutral0};
25
25
  }
26
26
  `;
27
27
 
28
28
  const LinksWrapper = styled(Box)`
29
- position: absolute;
30
29
  bottom: ${({ theme }) => `${theme.spaces[9]}`};
30
+ min-width: ${200 / 16}rem;
31
+ position: absolute;
31
32
  right: 0;
32
- width: ${200 / 16}rem;
33
33
  `;
34
34
 
35
- const StyledLink = styled.a`
36
- display: flex;
37
- align-items: center;
35
+ const StyledLink = styled(Flex)`
38
36
  text-decoration: none;
39
- padding: ${({ theme }) => theme.spaces[2]};
40
- padding-left: ${({ theme }) => theme.spaces[5]};
41
37
 
42
- svg {
43
- color: ${({ theme }) => theme.colors.neutral600};
44
- margin-right: ${({ theme }) => theme.spaces[2]};
38
+ svg path {
39
+ fill: ${({ theme }) => theme.colors.neutral600};
45
40
  }
46
41
 
42
+ &:focus,
47
43
  &:hover {
48
44
  background: ${({ theme }) => theme.colors.neutral100};
49
- color: ${({ theme }) => theme.colors.neutral500};
50
45
 
51
- svg {
52
- color: ${({ theme }) => theme.colors.neutral700};
46
+ svg path {
47
+ fill: ${({ theme }) => theme.colors.neutral700};
53
48
  }
54
49
 
55
50
  ${[Typography]} {
56
51
  color: ${({ theme }) => theme.colors.neutral700};
57
52
  }
58
53
  }
59
-
60
- ${[Typography]} {
61
- color: ${({ theme }) => theme.colors.neutral600};
62
- }
63
54
  `;
64
55
 
65
56
  const Onboarding = () => {
@@ -71,9 +62,9 @@ const Onboarding = () => {
71
62
  return null;
72
63
  }
73
64
 
74
- const staticLinks = [
65
+ const STATIC_LINKS = [
75
66
  {
76
- icon: 'book',
67
+ Icon: <Book />,
77
68
  label: formatMessage({
78
69
  id: 'global.documentation',
79
70
  defaultMessage: 'Documentation',
@@ -81,7 +72,7 @@ const Onboarding = () => {
81
72
  destination: 'https://docs.strapi.io',
82
73
  },
83
74
  {
84
- icon: 'file',
75
+ Icon: <Information />,
85
76
  label: formatMessage({ id: 'app.static.links.cheatsheet', defaultMessage: 'CheatSheet' }),
86
77
  destination: 'https://strapi-showcase.s3-us-west-2.amazonaws.com/CheatSheet.pdf',
87
78
  },
@@ -94,37 +85,44 @@ const Onboarding = () => {
94
85
  return (
95
86
  <OnboardingWrapper as="aside">
96
87
  <Button
88
+ as="button"
97
89
  id="onboarding"
98
- aria-label={formatMessage({
99
- id: 'app.components.Onboarding.help.button',
100
- defaultMessage: 'Help button',
101
- })}
90
+ aria-label={formatMessage(
91
+ isOpen
92
+ ? {
93
+ id: 'app.components.Onboarding.help.button-close',
94
+ defaultMessage: 'Close help menu',
95
+ }
96
+ : {
97
+ id: 'app.components.Onboarding.help.button',
98
+ defaultMessage: 'Open help menu',
99
+ }
100
+ )}
102
101
  onClick={handleClick}
103
102
  >
104
- {!isOpen && <FontAwesomeIcon icon={faQuestion} />}
105
- {isOpen && <FontAwesomeIcon icon={faTimes} />}
103
+ <Icon as={isOpen ? Cross : Question} height={pxToRem(16)} width={pxToRem(16)} />
106
104
  </Button>
107
105
 
108
106
  {/* FIX ME - replace with popover when overflow popover is fixed
109
107
  + when v4 mockups for onboarding component are ready */}
110
108
  {isOpen && (
111
109
  <FocusTrap onEscape={handleClick}>
112
- <LinksWrapper
113
- background="neutral0"
114
- hasRadius
115
- shadow="tableShadow"
116
- paddingBottom={2}
117
- paddingTop={2}
118
- >
119
- {staticLinks.map((link) => (
110
+ <LinksWrapper background="neutral0" hasRadius shadow="tableShadow" padding={2}>
111
+ {STATIC_LINKS.map((link) => (
120
112
  <StyledLink
113
+ as="a"
121
114
  key={link.label}
122
115
  rel="nofollow noreferrer noopener"
123
116
  target="_blank"
124
117
  href={link.destination}
118
+ padding={2}
119
+ hasRadius
120
+ alignItems="center"
125
121
  >
126
- <FontAwesomeIcon icon={link.icon} />
127
- <Typography>{link.label}</Typography>
122
+ <Stack horizontal spacing={2}>
123
+ {link.Icon}
124
+ <Typography color="neutral600">{link.label}</Typography>
125
+ </Stack>
128
126
  </StyledLink>
129
127
  ))}
130
128
  </LinksWrapper>