@strapi/admin 4.11.0-beta.1 → 4.11.0-exp.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/admin/src/content-manager/components/ComponentIcon/ComponentIcon.js +16 -26
  2. package/admin/src/content-manager/components/ComponentIcon/constants.js +133 -0
  3. package/admin/src/content-manager/components/DynamicZone/components/AddComponentButton.js +32 -95
  4. package/admin/src/content-manager/components/DynamicZone/components/ComponentCard.js +10 -2
  5. package/admin/src/content-manager/components/DynamicZone/components/ComponentCategory.js +63 -15
  6. package/admin/src/content-manager/components/DynamicZone/components/ComponentPicker.js +50 -63
  7. package/admin/src/content-manager/components/DynamicZone/components/DynamicComponent.js +132 -58
  8. package/admin/src/content-manager/components/DynamicZone/components/DynamicZoneLabel.js +29 -37
  9. package/admin/src/content-manager/components/DynamicZone/index.js +131 -83
  10. package/admin/src/content-manager/components/EditViewDataManagerProvider/index.js +28 -6
  11. package/admin/src/content-manager/components/EditViewDataManagerProvider/reducer.js +18 -6
  12. package/admin/src/content-manager/pages/EditSettingsView/components/DynamicZoneList.js +7 -1
  13. package/admin/src/content-manager/pages/EditView/index.js +1 -1
  14. package/admin/src/hooks/useContentTypes/useContentTypes.js +0 -2
  15. package/admin/src/index.js +4 -3
  16. package/admin/src/pages/SettingsPage/pages/Users/ListPage/index.js +1 -1
  17. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/EventTable/EventTableCE.js +13 -0
  18. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/EventTable/index.js +3 -0
  19. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/Events/index.js +331 -0
  20. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/HeadersInput/Combobox.js +54 -4
  21. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/HeadersInput/index.js +12 -23
  22. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/WebhookForm/index.js +129 -116
  23. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/WebhookForm/utils/makeWebhookValidationSchema.js +62 -0
  24. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/index.js +59 -64
  25. package/admin/src/translations/en.json +6 -0
  26. package/build/1887.6f71e8b2.chunk.js +39 -0
  27. package/build/3081.7e9329cb.chunk.js +105 -0
  28. package/build/371.6e4e2c1f.chunk.js +71 -0
  29. package/build/5542.64b623c9.chunk.js +63 -0
  30. package/build/{5563.79950369.chunk.js → 5563.badbffde.chunk.js} +2 -2
  31. package/build/{6970.7ea35fbd.chunk.js → 6970.d456705f.chunk.js} +1 -1
  32. package/build/{7259.5cc67413.chunk.js → 7259.5d0de931.chunk.js} +1 -1
  33. package/build/8976.a85384ce.chunk.js +155 -0
  34. package/build/{1657.ca8562dd.chunk.js → 9932.5ef475c5.chunk.js} +54 -62
  35. package/build/{Admin-authenticatedApp.990df65d.chunk.js → Admin-authenticatedApp.c985d4a0.chunk.js} +2 -2
  36. package/build/{Admin_InternalErrorPage.96ceaae1.chunk.js → Admin_InternalErrorPage.f25f04f3.chunk.js} +1 -1
  37. package/build/Admin_homePage.05063e43.chunk.js +73 -0
  38. package/build/Admin_marketplace.23ea289f.chunk.js +55 -0
  39. package/build/Admin_pluginsPage.b1031a00.chunk.js +6 -0
  40. package/build/{Admin_profilePage.75bc083a.chunk.js → Admin_profilePage.e7ccee9f.chunk.js} +2 -2
  41. package/build/Admin_settingsPage.07a6a5f0.chunk.js +79 -0
  42. package/build/{Upload_ConfigureTheView.aa64ed9a.chunk.js → Upload_ConfigureTheView.121deffb.chunk.js} +1 -1
  43. package/build/admin-app.8644c322.chunk.js +63 -0
  44. package/build/{admin-edit-roles-page.0d12b741.chunk.js → admin-edit-roles-page.bfe3304d.chunk.js} +3 -3
  45. package/build/{admin-edit-users.f9ce7844.chunk.js → admin-edit-users.6efe0382.chunk.js} +2 -2
  46. package/build/admin-roles-list.b2577370.chunk.js +23 -0
  47. package/build/admin-users.4af49ccf.chunk.js +26 -0
  48. package/build/{api-tokens-create-page.973d2816.chunk.js → api-tokens-create-page.65411a36.chunk.js} +1 -1
  49. package/build/{api-tokens-edit-page.29725c5e.chunk.js → api-tokens-edit-page.60312cb6.chunk.js} +1 -1
  50. package/build/{api-tokens-list-page.66c4fbdd.chunk.js → api-tokens-list-page.01a4d5cd.chunk.js} +2 -2
  51. package/build/audit-logs-settings-page.09c75037.chunk.js +121 -0
  52. package/build/content-manager.04fa9c14.chunk.js +1094 -0
  53. package/build/content-type-builder-list-view.58f9ed20.chunk.js +211 -0
  54. package/build/{content-type-builder-translation-en-json.af293c9e.chunk.js → content-type-builder-translation-en-json.f592325b.chunk.js} +1 -1
  55. package/build/content-type-builder.baeb0413.chunk.js +132 -0
  56. package/build/email-settings-page.85b71afc.chunk.js +11 -0
  57. package/build/en-json.a8f34002.chunk.js +1 -0
  58. package/build/i18n-settings-page.c0da2362.chunk.js +114 -0
  59. package/build/index.html +1 -1
  60. package/build/main.8605d88e.js +2633 -0
  61. package/build/{review-workflows-settings.4b39b837.chunk.js → review-workflows-settings.3a7bae25.chunk.js} +1 -1
  62. package/build/{runtime~main.55d43bd7.js → runtime~main.36375726.js} +2 -2
  63. package/build/{sso-settings-page.265e3d72.chunk.js → sso-settings-page.4bb073e0.chunk.js} +1 -1
  64. package/build/{transfer-tokens-create-page.170acee6.chunk.js → transfer-tokens-create-page.9ec277d7.chunk.js} +1 -1
  65. package/build/{transfer-tokens-edit-page.6cf23295.chunk.js → transfer-tokens-edit-page.fa5ade14.chunk.js} +1 -1
  66. package/build/{transfer-tokens-list-page.c3fec4c1.chunk.js → transfer-tokens-list-page.5d68d590.chunk.js} +2 -2
  67. package/build/upload-settings.2c1565d6.chunk.js +14 -0
  68. package/build/upload.257b2aef.chunk.js +26 -0
  69. package/build/users-advanced-settings-page.dda58320.chunk.js +9 -0
  70. package/build/users-email-settings-page.a0c08594.chunk.js +24 -0
  71. package/build/users-providers-settings-page.14a82632.chunk.js +29 -0
  72. package/build/{users-roles-settings-page.c773086b.chunk.js → users-roles-settings-page.1f408276.chunk.js} +1 -1
  73. package/build/webhook-edit-page.b9a13be7.chunk.js +136 -0
  74. package/build/webhook-list-page.84e5abc9.chunk.js +63 -0
  75. package/ee/admin/pages/SettingsPage/pages/Webhooks/EditView/components/EventTable/EventTableEE.js +23 -0
  76. package/ee/admin/pages/SettingsPage/pages/Webhooks/EditView/components/EventTable/index.js +3 -0
  77. package/ee/server/services/review-workflows/review-workflows.js +4 -0
  78. package/package.json +19 -21
  79. package/server/controllers/webhooks.js +6 -6
  80. package/admin/src/content-manager/components/DynamicZone/utils/connect.js +0 -12
  81. package/admin/src/content-manager/components/DynamicZone/utils/select.js +0 -53
  82. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/EventInput/EventRow.js +0 -70
  83. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/EventInput/index.js +0 -174
  84. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/HeadersInput/keys.js +0 -39
  85. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/utils/fieldsRegex.js +0 -4
  86. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/utils/schema.js +0 -35
  87. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/reducer.js +0 -100
  88. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/utils/formatData.js +0 -20
  89. package/build/3081.c2cdfac8.chunk.js +0 -108
  90. package/build/456.9b85d4c6.chunk.js +0 -39
  91. package/build/462.a073ff1f.chunk.js +0 -71
  92. package/build/5542.002522eb.chunk.js +0 -71
  93. package/build/617.87b2fe96.chunk.js +0 -155
  94. package/build/Admin_homePage.107a9fe0.chunk.js +0 -73
  95. package/build/Admin_marketplace.1436fc2b.chunk.js +0 -55
  96. package/build/Admin_pluginsPage.e1afd5ed.chunk.js +0 -6
  97. package/build/Admin_settingsPage.bd715ed3.chunk.js +0 -79
  98. package/build/admin-app.8b102fe2.chunk.js +0 -63
  99. package/build/admin-roles-list.e8bf9685.chunk.js +0 -31
  100. package/build/admin-users.751b28b2.chunk.js +0 -34
  101. package/build/audit-logs-settings-page.3c6cea81.chunk.js +0 -129
  102. package/build/content-manager.89099707.chunk.js +0 -1123
  103. package/build/content-type-builder-list-view.1e821eb9.chunk.js +0 -215
  104. package/build/content-type-builder.b10576e7.chunk.js +0 -126
  105. package/build/email-settings-page.4368689f.chunk.js +0 -11
  106. package/build/en-json.0f5cc115.chunk.js +0 -1
  107. package/build/i18n-settings-page.7988d872.chunk.js +0 -114
  108. package/build/main.5a232c3d.js +0 -2630
  109. package/build/upload-settings.63d99bf5.chunk.js +0 -14
  110. package/build/upload.c50d8c7a.chunk.js +0 -34
  111. package/build/users-advanced-settings-page.2cfb5d24.chunk.js +0 -9
  112. package/build/users-email-settings-page.bd6c774a.chunk.js +0 -24
  113. package/build/users-providers-settings-page.528f0036.chunk.js +0 -29
  114. package/build/webhook-edit-page.ddd5963d.chunk.js +0 -128
  115. package/build/webhook-list-page.b0f5a02c.chunk.js +0 -71
@@ -1,49 +1,39 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React from 'react';
3
- import styled from 'styled-components';
4
3
 
5
- import { Flex } from '@strapi/design-system';
4
+ import { Flex, Icon } from '@strapi/design-system';
5
+ import { COMPONENT_ICONS } from './constants';
6
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' }) {
7
+ export function ComponentIcon({ showBackground = true, size = 'M', icon }) {
23
8
  return (
24
- <Wrapper
9
+ <Flex
25
10
  alignItems="center"
26
11
  background={showBackground ? 'neutral200' : null}
27
12
  justifyContent="center"
28
13
  size={size}
29
14
  showBackground={showBackground}
15
+ height={size === 'S' ? 5 : 8}
16
+ width={size === 'S' ? 5 : 8}
17
+ color="neutral600"
18
+ borderRadius={showBackground ? '50%' : 0}
30
19
  >
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>
20
+ <Icon
21
+ as={COMPONENT_ICONS[icon] || COMPONENT_ICONS.cube}
22
+ height={size === 'S' ? 3 : 5}
23
+ width={size === 'S' ? 3 : 5}
24
+ />
25
+ </Flex>
38
26
  );
39
27
  }
40
28
 
41
29
  ComponentIcon.defaultProps = {
42
30
  showBackground: true,
43
31
  size: 'M',
32
+ icon: 'Cube',
44
33
  };
45
34
 
46
35
  ComponentIcon.propTypes = {
47
36
  showBackground: PropTypes.bool,
48
37
  size: PropTypes.string,
38
+ icon: PropTypes.string,
49
39
  };
@@ -0,0 +1,133 @@
1
+ import * as Icons from '@strapi/icons';
2
+
3
+ const COMPONENT_ICONS = {
4
+ alien: Icons.Alien,
5
+ apps: Icons.Apps,
6
+ archive: Icons.Archive,
7
+ arrowDown: Icons.ArrowDown,
8
+ arrowLeft: Icons.ArrowLeft,
9
+ arrowRight: Icons.ArrowRight,
10
+ arrowUp: Icons.ArrowUp,
11
+ attachment: Icons.Attachment,
12
+ bell: Icons.Bell,
13
+ bold: Icons.Bold,
14
+ book: Icons.Book,
15
+ briefcase: Icons.Briefcase,
16
+ brush: Icons.Brush,
17
+ bulletList: Icons.BulletList,
18
+ calendar: Icons.Calendar,
19
+ car: Icons.Car,
20
+ cast: Icons.Cast,
21
+ chartBubble: Icons.ChartBubble,
22
+ chartCircle: Icons.ChartCircle,
23
+ chartPie: Icons.ChartPie,
24
+ check: Icons.Check,
25
+ clock: Icons.Clock,
26
+ cloud: Icons.Cloud,
27
+ code: Icons.Code,
28
+ cog: Icons.Cog,
29
+ collapse: Icons.Collapse,
30
+ command: Icons.Command,
31
+ connector: Icons.Connector,
32
+ crop: Icons.Crop,
33
+ crown: Icons.Crown,
34
+ cube: Icons.Cube,
35
+ cup: Icons.Cup,
36
+ cursor: Icons.Cursor,
37
+ dashboard: Icons.Dashboard,
38
+ database: Icons.Database,
39
+ discuss: Icons.Discuss,
40
+ doctor: Icons.Doctor,
41
+ earth: Icons.Earth,
42
+ emotionHappy: Icons.EmotionHappy,
43
+ emotionUnhappy: Icons.EmotionUnhappy,
44
+ envelop: Icons.Envelop,
45
+ exit: Icons.Exit,
46
+ expand: Icons.Expand,
47
+ eye: Icons.Eye,
48
+ feather: Icons.Feather,
49
+ file: Icons.File,
50
+ fileError: Icons.FileError,
51
+ filePdf: Icons.FilePdf,
52
+ filter: Icons.Filter,
53
+ folder: Icons.Folder,
54
+ gate: Icons.Gate,
55
+ gift: Icons.Gift,
56
+ globe: Icons.Globe,
57
+ grid: Icons.Grid,
58
+ handHeart: Icons.HandHeart,
59
+ hashtag: Icons.Hashtag,
60
+ headphone: Icons.Headphone,
61
+ heart: Icons.Heart,
62
+ house: Icons.House,
63
+ information: Icons.Information,
64
+ italic: Icons.Italic,
65
+ key: Icons.Key,
66
+ landscape: Icons.Landscape,
67
+ layer: Icons.Layer,
68
+ layout: Icons.Layout,
69
+ lightbulb: Icons.Lightbulb,
70
+ link: Icons.Link,
71
+ lock: Icons.Lock,
72
+ magic: Icons.Magic,
73
+ manyToMany: Icons.ManyToMany,
74
+ manyToOne: Icons.ManyToOne,
75
+ manyWays: Icons.ManyWays,
76
+ medium: Icons.Medium,
77
+ message: Icons.Message,
78
+ microphone: Icons.Microphone,
79
+ monitor: Icons.Monitor,
80
+ moon: Icons.Moon,
81
+ music: Icons.Music,
82
+ oneToMany: Icons.OneToMany,
83
+ oneToOne: Icons.OneToOne,
84
+ oneWay: Icons.OneWay,
85
+ paint: Icons.Paint,
86
+ paintBrush: Icons.PaintBrush,
87
+ paperPlane: Icons.PaperPlane,
88
+ pencil: Icons.Pencil,
89
+ phone: Icons.Phone,
90
+ picture: Icons.Picture,
91
+ pin: Icons.Pin,
92
+ pinMap: Icons.PinMap,
93
+ plane: Icons.Plane,
94
+ play: Icons.Play,
95
+ plus: Icons.Plus,
96
+ priceTag: Icons.PriceTag,
97
+ puzzle: Icons.Puzzle,
98
+ question: Icons.Question,
99
+ quote: Icons.Quote,
100
+ refresh: Icons.Refresh,
101
+ repeat: Icons.Repeat,
102
+ restaurant: Icons.Restaurant,
103
+ rocket: Icons.Rocket,
104
+ rotate: Icons.Rotate,
105
+ scissors: Icons.Scissors,
106
+ search: Icons.Search,
107
+ seed: Icons.Seed,
108
+ server: Icons.Server,
109
+ shield: Icons.Shield,
110
+ shirt: Icons.Shirt,
111
+ shoppingCart: Icons.ShoppingCart,
112
+ slideshow: Icons.Slideshow,
113
+ stack: Icons.Stack,
114
+ star: Icons.Star,
115
+ store: Icons.Store,
116
+ strikeThrough: Icons.StrikeThrough,
117
+ sun: Icons.Sun,
118
+ television: Icons.Television,
119
+ thumbDown: Icons.ThumbDown,
120
+ thumbUp: Icons.ThumbUp,
121
+ train: Icons.Train,
122
+ twitter: Icons.Twitter,
123
+ typhoon: Icons.Typhoon,
124
+ underline: Icons.Underline,
125
+ user: Icons.User,
126
+ volumeMute: Icons.VolumeMute,
127
+ volumeUp: Icons.VolumeUp,
128
+ walk: Icons.Walk,
129
+ wheelchair: Icons.Wheelchair,
130
+ write: Icons.Write,
131
+ };
132
+
133
+ export { COMPONENT_ICONS };
@@ -6,14 +6,41 @@
6
6
 
7
7
  import React from 'react';
8
8
  import PropTypes from 'prop-types';
9
- import { useIntl } from 'react-intl';
10
9
  import styled from 'styled-components';
11
10
  import { PlusCircle } from '@strapi/icons';
12
- import { BaseButton, Box, Flex, Typography } from '@strapi/design-system';
11
+ import { BaseButton, Flex, Typography } from '@strapi/design-system';
13
12
 
14
- import { getTrad } from '../../../utils';
13
+ export const AddComponentButton = ({ hasError, isDisabled, isOpen, children, onClick }) => {
14
+ return (
15
+ <StyledButton
16
+ type="button"
17
+ onClick={onClick}
18
+ disabled={isDisabled}
19
+ hasError={hasError}
20
+ background="neutral0"
21
+ paddingTop={3}
22
+ paddingBottom={3}
23
+ paddingLeft={4}
24
+ paddingRight={4}
25
+ style={{ cursor: isDisabled ? 'not-allowed' : 'pointer' }}
26
+ >
27
+ <Flex as="span" gap={2}>
28
+ <StyledAddIcon aria-hidden $isOpen={isOpen} $hasError={hasError && !isOpen} />
29
+ <Typography
30
+ variant="pi"
31
+ fontWeight="bold"
32
+ textColor={hasError && !isOpen ? 'danger600' : 'neutral500'}
33
+ >
34
+ {children}
35
+ </Typography>
36
+ </Flex>
37
+ </StyledButton>
38
+ );
39
+ };
15
40
 
16
41
  const StyledAddIcon = styled(PlusCircle)`
42
+ height: ${({ theme }) => theme.spaces[6]};
43
+ width: ${({ theme }) => theme.spaces[6]};
17
44
  transform: ${({ $isOpen }) => ($isOpen ? 'rotate(45deg)' : 'rotate(0deg)')};
18
45
  > circle {
19
46
  fill: ${({ theme, $hasError }) =>
@@ -28,25 +55,11 @@ const StyledAddIcon = styled(PlusCircle)`
28
55
  const StyledButton = styled(BaseButton)`
29
56
  border-radius: 26px;
30
57
  border-color: ${({ theme }) => theme.colors.neutral150};
31
- background: ${({ theme }) => theme.colors.neutral0};
32
- padding-top: ${({ theme }) => theme.spaces[3]};
33
- padding-right: ${({ theme }) => theme.spaces[4]};
34
- padding-bottom: ${({ theme }) => theme.spaces[3]};
35
- padding-left: ${({ theme }) => theme.spaces[4]};
36
-
37
58
  box-shadow: ${({ theme }) => theme.shadows.filterShadow};
38
59
 
39
- svg {
40
- height: ${({ theme }) => theme.spaces[6]};
41
- width: ${({ theme }) => theme.spaces[6]};
42
- > path {
43
- fill: ${({ theme }) => theme.colors.neutral600};
44
- }
45
- }
46
60
  &:hover {
47
- color: ${({ theme }) => theme.colors.primary600} !important;
48
61
  ${Typography} {
49
- color: ${({ theme }) => theme.colors.primary600} !important;
62
+ color: ${({ theme }) => theme.colors.primary600};
50
63
  }
51
64
 
52
65
  ${StyledAddIcon} {
@@ -73,92 +86,16 @@ const StyledButton = styled(BaseButton)`
73
86
  }
74
87
  `;
75
88
 
76
- const BoxFullHeight = styled(Box)`
77
- height: 100%;
78
- `;
79
-
80
- const AddComponentButton = ({
81
- hasError,
82
- hasMaxError,
83
- hasMinError,
84
- isDisabled,
85
- isOpen,
86
- label,
87
- missingComponentNumber,
88
- name,
89
- onClick,
90
- }) => {
91
- const { formatMessage } = useIntl();
92
- const addLabel = formatMessage(
93
- {
94
- id: getTrad('components.DynamicZone.add-component'),
95
- defaultMessage: 'Add a component to {componentName}',
96
- },
97
- { componentName: label || name }
98
- );
99
- const closeLabel = formatMessage({ id: 'app.utils.close-label', defaultMessage: 'Close' });
100
- let buttonLabel = isOpen ? closeLabel : addLabel;
101
-
102
- if (hasMaxError && !isOpen) {
103
- buttonLabel = formatMessage({
104
- id: 'components.Input.error.validation.max',
105
- defaultMessage: 'The value is too high.',
106
- });
107
- }
108
-
109
- if (hasMinError && !isOpen) {
110
- buttonLabel = formatMessage(
111
- {
112
- id: getTrad(`components.DynamicZone.missing-components`),
113
- defaultMessage:
114
- 'There {number, plural, =0 {are # missing components} one {is # missing component} other {are # missing components}}',
115
- },
116
- { number: missingComponentNumber }
117
- );
118
- }
119
-
120
- return (
121
- <Flex justifyContent="center">
122
- <Box style={{ cursor: isDisabled ? 'not-allowed' : 'pointer' }}>
123
- <StyledButton type="button" onClick={onClick} disabled={isDisabled} hasError={hasError}>
124
- <Flex>
125
- <BoxFullHeight aria-hidden paddingRight={2}>
126
- <StyledAddIcon $isOpen={isOpen} $hasError={hasError && !isOpen} />
127
- </BoxFullHeight>
128
- <Typography
129
- variant="pi"
130
- fontWeight="bold"
131
- textColor={hasError && !isOpen ? 'danger600' : 'neutral500'}
132
- >
133
- {buttonLabel}
134
- </Typography>
135
- </Flex>
136
- </StyledButton>
137
- </Box>
138
- </Flex>
139
- );
140
- };
141
-
142
89
  AddComponentButton.defaultProps = {
143
90
  hasError: false,
144
- hasMaxError: false,
145
- hasMinError: false,
146
91
  isDisabled: false,
147
92
  isOpen: false,
148
- label: '',
149
- missingComponentNumber: 0,
150
93
  };
151
94
 
152
95
  AddComponentButton.propTypes = {
153
- label: PropTypes.string,
96
+ children: PropTypes.node.isRequired,
154
97
  hasError: PropTypes.bool,
155
- hasMaxError: PropTypes.bool,
156
- hasMinError: PropTypes.bool,
157
98
  isDisabled: PropTypes.bool,
158
99
  isOpen: PropTypes.bool,
159
- missingComponentNumber: PropTypes.number,
160
- name: PropTypes.string.isRequired,
161
100
  onClick: PropTypes.func.isRequired,
162
101
  };
163
-
164
- export default AddComponentButton;
@@ -36,15 +36,21 @@ const ComponentBox = styled(Box)`
36
36
  > div > div:first-child {
37
37
  background: ${({ theme }) => theme.colors.primary200};
38
38
  color: ${({ theme }) => theme.colors.primary600};
39
+
40
+ svg {
41
+ path {
42
+ fill: ${({ theme }) => theme.colors.primary600};
43
+ }
44
+ }
39
45
  }
40
46
  }
41
47
  `;
42
48
 
43
- export default function ComponentCard({ children, onClick }) {
49
+ export default function ComponentCard({ children, onClick, icon }) {
44
50
  return (
45
51
  <ComponentBox as="button" type="button" onClick={onClick} hasRadius>
46
52
  <Flex direction="column" gap={1} alignItems="center" justifyContent="center">
47
- <ComponentIcon />
53
+ <ComponentIcon icon={icon} />
48
54
 
49
55
  <Typography variant="pi" fontWeight="bold" textColor="neutral600">
50
56
  {children}
@@ -56,9 +62,11 @@ export default function ComponentCard({ children, onClick }) {
56
62
 
57
63
  ComponentCard.defaultProps = {
58
64
  onClick() {},
65
+ icon: 'Cube',
59
66
  };
60
67
 
61
68
  ComponentCard.propTypes = {
62
69
  children: PropTypes.node.isRequired,
63
70
  onClick: PropTypes.func,
71
+ icon: PropTypes.string,
64
72
  };
@@ -1,18 +1,27 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { Accordion, AccordionToggle, AccordionContent, Box } from '@strapi/design-system';
3
+ import {
4
+ Accordion,
5
+ AccordionToggle,
6
+ AccordionContent,
7
+ Box,
8
+ Flex,
9
+ Typography,
10
+ } from '@strapi/design-system';
11
+ import { pxToRem } from '@strapi/helper-plugin';
4
12
  import styled from 'styled-components';
5
13
  import { useIntl } from 'react-intl';
6
14
 
7
- import ComponentCard from './ComponentCard';
15
+ import { ComponentIcon } from '../../ComponentIcon';
8
16
 
9
- const Grid = styled.div`
10
- display: grid;
11
- grid-template-columns: repeat(auto-fit, ${140 / 16}rem);
12
- grid-gap: ${({ theme }) => theme.spaces[1]};
13
- `;
14
-
15
- const ComponentCategory = ({ category, components, variant, isOpen, onAddComponent, onToggle }) => {
17
+ export const ComponentCategory = ({
18
+ category,
19
+ components,
20
+ variant,
21
+ isOpen,
22
+ onAddComponent,
23
+ onToggle,
24
+ }) => {
16
25
  const { formatMessage } = useIntl();
17
26
 
18
27
  const handleToggle = () => {
@@ -29,10 +38,27 @@ const ComponentCategory = ({ category, components, variant, isOpen, onAddCompone
29
38
  <AccordionContent>
30
39
  <Box paddingTop={4} paddingBottom={4} paddingLeft={3} paddingRight={3}>
31
40
  <Grid>
32
- {components.map(({ componentUid, info: { displayName } }) => (
33
- <ComponentCard key={componentUid} onClick={onAddComponent(componentUid)}>
34
- {formatMessage({ id: displayName, defaultMessage: displayName })}
35
- </ComponentCard>
41
+ {components.map(({ componentUid, info: { displayName, icon } }) => (
42
+ <ComponentBox
43
+ key={componentUid}
44
+ as="button"
45
+ type="button"
46
+ background="neutral100"
47
+ justifyContent="center"
48
+ onClick={onAddComponent(componentUid)}
49
+ hasRadius
50
+ height={pxToRem(84)}
51
+ shrink={0}
52
+ borderColor="neutral200"
53
+ >
54
+ <Flex direction="column" gap={1} alignItems="center" justifyContent="center">
55
+ <ComponentIcon icon={icon} />
56
+
57
+ <Typography variant="pi" fontWeight="bold" textColor="neutral600">
58
+ {formatMessage({ id: displayName, defaultMessage: displayName })}
59
+ </Typography>
60
+ </Flex>
61
+ </ComponentBox>
36
62
  ))}
37
63
  </Grid>
38
64
  </Box>
@@ -41,6 +67,30 @@ const ComponentCategory = ({ category, components, variant, isOpen, onAddCompone
41
67
  );
42
68
  };
43
69
 
70
+ const Grid = styled.div`
71
+ display: grid;
72
+ grid-template-columns: repeat(auto-fit, ${140 / 16}rem);
73
+ grid-gap: ${({ theme }) => theme.spaces[1]};
74
+ `;
75
+
76
+ const ComponentBox = styled(Flex)`
77
+ &:focus,
78
+ &:hover {
79
+ border: 1px solid ${({ theme }) => theme.colors.primary200};
80
+ background: ${({ theme }) => theme.colors.primary100};
81
+
82
+ ${Typography} {
83
+ color: ${({ theme }) => theme.colors.primary600};
84
+ }
85
+
86
+ /* > Flex > ComponentIcon */
87
+ > div > div:first-child {
88
+ background: ${({ theme }) => theme.colors.primary200};
89
+ color: ${({ theme }) => theme.colors.primary600};
90
+ }
91
+ }
92
+ `;
93
+
44
94
  ComponentCategory.defaultProps = {
45
95
  components: [],
46
96
  isOpen: false,
@@ -55,5 +105,3 @@ ComponentCategory.propTypes = {
55
105
  onToggle: PropTypes.func.isRequired,
56
106
  variant: PropTypes.oneOf(['primary', 'secondary']),
57
107
  };
58
-
59
- export default ComponentCategory;
@@ -1,40 +1,24 @@
1
- import React, { useEffect, useMemo, useState } from 'react';
2
- import groupBy from 'lodash/groupBy';
1
+ import React, { useEffect, useState } from 'react';
3
2
  import PropTypes from 'prop-types';
4
3
  import { useIntl } from 'react-intl';
5
4
  import { KeyboardNavigable, Box, Flex, Typography } from '@strapi/design-system';
6
5
 
7
6
  import { getTrad } from '../../../utils';
8
- import { useContentTypeLayout } from '../../../hooks';
9
7
 
10
- import ComponentCategory from './ComponentCategory';
8
+ import { ComponentCategory } from './ComponentCategory';
11
9
 
12
- const ComponentPicker = ({ components, isOpen, onClickAddComponent }) => {
10
+ export const ComponentPicker = ({ dynamicComponentsByCategory, isOpen, onClickAddComponent }) => {
13
11
  const { formatMessage } = useIntl();
14
- const { getComponentLayout } = useContentTypeLayout();
15
- const [categoryToOpen, setCategoryToOpen] = useState('');
16
-
17
- const dynamicComponentCategories = useMemo(() => {
18
- const componentsWithInfo = components.map((componentUid) => {
19
- const { category, info } = getComponentLayout(componentUid);
20
-
21
- return { componentUid, category, info };
22
- });
23
-
24
- const categories = groupBy(componentsWithInfo, 'category');
25
12
 
26
- return Object.keys(categories).reduce((acc, current) => {
27
- acc.push({ category: current, components: categories[current] });
28
-
29
- return acc;
30
- }, []);
31
- }, [components, getComponentLayout]);
13
+ const [categoryToOpen, setCategoryToOpen] = useState('');
32
14
 
33
15
  useEffect(() => {
34
- if (isOpen && dynamicComponentCategories.length > 0) {
35
- setCategoryToOpen(dynamicComponentCategories[0].category);
16
+ const categoryKeys = Object.keys(dynamicComponentsByCategory);
17
+
18
+ if (isOpen && categoryKeys.length > 0) {
19
+ setCategoryToOpen(categoryKeys[0]);
36
20
  }
37
- }, [isOpen, dynamicComponentCategories]);
21
+ }, [isOpen, dynamicComponentsByCategory]);
38
22
 
39
23
  const handleAddComponentToDz = (componentUid) => () => {
40
24
  onClickAddComponent(componentUid);
@@ -53,54 +37,57 @@ const ComponentPicker = ({ components, isOpen, onClickAddComponent }) => {
53
37
  }
54
38
 
55
39
  return (
56
- <Box paddingBottom={6}>
57
- <Box
58
- paddingTop={6}
59
- paddingBottom={6}
60
- paddingLeft={5}
61
- paddingRight={5}
62
- background="neutral0"
63
- shadow="tableShadow"
64
- borderColor="neutral150"
65
- hasRadius
66
- >
67
- <Flex justifyContent="center">
68
- <Typography fontWeight="bold" textColor="neutral600">
69
- {formatMessage({
70
- id: getTrad('components.DynamicZone.ComponentPicker-label'),
71
- defaultMessage: 'Pick one component',
72
- })}
73
- </Typography>
74
- </Flex>
75
- <Box paddingTop={2}>
76
- <KeyboardNavigable attributeName="data-strapi-accordion-toggle">
77
- {dynamicComponentCategories.map(({ category, components }, index) => (
78
- <ComponentCategory
79
- key={category}
80
- category={category}
81
- components={components}
82
- onAddComponent={handleAddComponentToDz}
83
- isOpen={category === categoryToOpen}
84
- onToggle={handleClickToggle}
85
- variant={index % 2 === 1 ? 'primary' : 'secondary'}
86
- />
87
- ))}
88
- </KeyboardNavigable>
89
- </Box>
40
+ <Box
41
+ paddingTop={6}
42
+ paddingBottom={6}
43
+ paddingLeft={5}
44
+ paddingRight={5}
45
+ background="neutral0"
46
+ shadow="tableShadow"
47
+ borderColor="neutral150"
48
+ hasRadius
49
+ >
50
+ <Flex justifyContent="center">
51
+ <Typography fontWeight="bold" textColor="neutral600">
52
+ {formatMessage({
53
+ id: getTrad('components.DynamicZone.ComponentPicker-label'),
54
+ defaultMessage: 'Pick one component',
55
+ })}
56
+ </Typography>
57
+ </Flex>
58
+ <Box paddingTop={2}>
59
+ <KeyboardNavigable attributeName="data-strapi-accordion-toggle">
60
+ {Object.entries(dynamicComponentsByCategory).map(([category, components], index) => (
61
+ <ComponentCategory
62
+ key={category}
63
+ category={category}
64
+ components={components}
65
+ onAddComponent={handleAddComponentToDz}
66
+ isOpen={category === categoryToOpen}
67
+ onToggle={handleClickToggle}
68
+ variant={index % 2 === 1 ? 'primary' : 'secondary'}
69
+ />
70
+ ))}
71
+ </KeyboardNavigable>
90
72
  </Box>
91
73
  </Box>
92
74
  );
93
75
  };
94
76
 
95
77
  ComponentPicker.defaultProps = {
96
- components: [],
78
+ dynamicComponentsByCategory: {},
97
79
  isOpen: false,
98
80
  };
99
81
 
100
82
  ComponentPicker.propTypes = {
101
- components: PropTypes.array,
83
+ dynamicComponentsByCategory: PropTypes.shape({
84
+ components: PropTypes.arrayOf(
85
+ PropTypes.shape({
86
+ componentUid: PropTypes.string.isRequired,
87
+ info: PropTypes.object,
88
+ })
89
+ ),
90
+ }),
102
91
  isOpen: PropTypes.bool,
103
92
  onClickAddComponent: PropTypes.func.isRequired,
104
93
  };
105
-
106
- export default ComponentPicker;