@centreon/ui 25.3.4 → 25.4.0-MON-191119-npm-develop.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 (176) hide show
  1. package/package.json +25 -11
  2. package/public/mockServiceWorker.js +8 -31
  3. package/src/Button/Save/index.stories.tsx +1 -0
  4. package/src/Checkbox/Checkbox.tsx +3 -1
  5. package/src/Checkbox/CheckboxGroup/index.tsx +6 -1
  6. package/src/Colors/index.tsx +1 -1
  7. package/src/Dashboard/Dashboard.styles.ts +1 -1
  8. package/src/Dashboard/Layout.tsx +1 -1
  9. package/src/Dialog/UnsavedChanges/index.stories.tsx +1 -0
  10. package/src/Form/CollapsibleGroup.tsx +13 -13
  11. package/src/Form/Form.cypress.spec.tsx +137 -2
  12. package/src/Form/Form.stories.tsx +11 -31
  13. package/src/Form/Form.tsx +2 -0
  14. package/src/Form/Inputs/Checkbox.tsx +3 -2
  15. package/src/Form/Inputs/ConnectedAutocomplete.tsx +6 -1
  16. package/src/Form/Inputs/Grid.tsx +18 -29
  17. package/src/Form/Inputs/SubGroupDivider.tsx +7 -0
  18. package/src/Form/Inputs/Text.tsx +1 -0
  19. package/src/Form/Inputs/index.tsx +31 -24
  20. package/src/Form/Inputs/models.ts +8 -1
  21. package/src/Form/Section/FormSection.tsx +34 -0
  22. package/src/Form/Section/PanelTabs.tsx +13 -0
  23. package/src/Form/Section/navigateToSection.ts +9 -0
  24. package/src/Form/storiesData.tsx +14 -4
  25. package/src/Graph/BarChart/BarChart.cypress.spec.tsx +46 -6
  26. package/src/Graph/BarChart/BarChart.stories.tsx +60 -0
  27. package/src/Graph/BarChart/BarChart.tsx +56 -32
  28. package/src/Graph/BarChart/BarGroup.tsx +22 -32
  29. package/src/Graph/BarChart/MemoizedGroup.tsx +8 -11
  30. package/src/Graph/BarChart/ResponsiveBarChart.tsx +145 -32
  31. package/src/Graph/BarChart/Tooltip/BarChartTooltip.tsx +2 -2
  32. package/src/Graph/Chart/BasicComponents/Lines/StackedLines/index.tsx +7 -1
  33. package/src/Graph/Chart/BasicComponents/Lines/StackedLines/useStackedLines.ts +18 -45
  34. package/src/Graph/Chart/BasicComponents/Lines/index.tsx +42 -28
  35. package/src/Graph/Chart/Chart.cypress.spec.tsx +85 -15
  36. package/src/Graph/Chart/Chart.stories.tsx +84 -1
  37. package/src/Graph/Chart/Chart.tsx +17 -4
  38. package/src/Graph/Chart/InteractiveComponents/AnchorPoint/RegularAnchorPoint.tsx +8 -2
  39. package/src/Graph/Chart/InteractiveComponents/AnchorPoint/StackedAnchorPoint.tsx +10 -3
  40. package/src/Graph/Chart/InteractiveComponents/AnchorPoint/useTickGraph.ts +19 -2
  41. package/src/Graph/Chart/InteractiveComponents/GraphValueTooltip/useGraphValueTooltip.ts +2 -4
  42. package/src/Graph/Chart/InteractiveComponents/ZoomPreview/index.tsx +14 -3
  43. package/src/Graph/Chart/InteractiveComponents/ZoomPreview/models.ts +3 -0
  44. package/src/Graph/Chart/InteractiveComponents/ZoomPreview/useZoomPreview.ts +12 -10
  45. package/src/Graph/Chart/InteractiveComponents/index.tsx +63 -5
  46. package/src/Graph/Chart/Legend/index.tsx +26 -2
  47. package/src/Graph/Chart/index.tsx +45 -45
  48. package/src/Graph/Chart/models.ts +8 -0
  49. package/src/Graph/Chart/useChartData.ts +14 -2
  50. package/src/Graph/Gauge/Gauge.tsx +18 -14
  51. package/src/Graph/Gauge/ResponsiveGauge.tsx +10 -6
  52. package/src/Graph/Gauge/useResizeObserver.ts +68 -0
  53. package/src/Graph/SingleBar/ResponsiveSingleBar.tsx +18 -16
  54. package/src/Graph/SingleBar/ThresholdLine.tsx +4 -4
  55. package/src/Graph/SingleBar/models.ts +1 -0
  56. package/src/Graph/Text/Text.styles.ts +2 -2
  57. package/src/Graph/Text/Text.tsx +23 -10
  58. package/src/Graph/Timeline/ResponsiveTimeline.tsx +4 -0
  59. package/src/Graph/Timeline/Timeline.tsx +21 -4
  60. package/src/Graph/Tree/Links.tsx +2 -2
  61. package/src/Graph/Tree/Tree.tsx +2 -2
  62. package/src/Graph/Tree/constants.ts +1 -1
  63. package/src/Graph/common/BaseChart/BaseChart.tsx +6 -1
  64. package/src/Graph/common/BaseChart/ChartSvgWrapper.tsx +5 -4
  65. package/src/Graph/common/BaseChart/Header/index.tsx +3 -1
  66. package/src/Graph/common/BaseChart/useComputeBaseChartDimensions.ts +13 -9
  67. package/src/Graph/common/timeSeries/index.test.ts +20 -0
  68. package/src/Graph/common/timeSeries/index.ts +225 -44
  69. package/src/Graph/common/timeSeries/models.ts +6 -2
  70. package/src/Graph/common/utils.ts +45 -12
  71. package/src/Graph/index.ts +3 -1
  72. package/src/Graph/mockedData/dataWithMissingPoint.json +74 -0
  73. package/src/Graph/mockedData/pingServiceWithStackedKeys.json +205 -0
  74. package/src/Icon/RegexIcon.tsx +20 -0
  75. package/src/Icon/index.ts +1 -0
  76. package/src/InputField/Select/Autocomplete/Connected/Multi/MultiConnectedAutocompleteField.cypress.spec.tsx +68 -14
  77. package/src/InputField/Select/Autocomplete/Connected/index.tsx +49 -14
  78. package/src/InputField/Select/Autocomplete/Multi/Listbox.tsx +78 -0
  79. package/src/InputField/Select/Autocomplete/Multi/Multi.styles.ts +26 -0
  80. package/src/InputField/Select/Autocomplete/Multi/Multi.tsx +124 -0
  81. package/src/InputField/Select/Autocomplete/Multi/index.tsx +1 -117
  82. package/src/InputField/Select/Autocomplete/index.tsx +28 -17
  83. package/src/InputField/Select/Option.tsx +3 -3
  84. package/src/InputField/Select/index.tsx +4 -0
  85. package/src/InputField/Text/index.tsx +4 -2
  86. package/src/InputField/translatedLabels.ts +4 -0
  87. package/src/Listing/ActionBar/Pagination.tsx +10 -23
  88. package/src/Listing/ActionBar/PaginationActions.tsx +1 -10
  89. package/src/Listing/ActionBar/index.tsx +1 -1
  90. package/src/Listing/Cell/DataCell.tsx +6 -6
  91. package/src/Listing/Cell/EllipsisTypography.tsx +10 -32
  92. package/src/Listing/Cell/index.tsx +37 -76
  93. package/src/Listing/Checkbox.tsx +8 -20
  94. package/src/Listing/Header/Cell/ListingHeaderCell.tsx +17 -14
  95. package/src/Listing/Header/Cell/SelectActionListingHeaderCell.tsx +5 -9
  96. package/src/Listing/Header/ListingHeader.tsx +2 -5
  97. package/src/Listing/Header/_internals/Label.tsx +1 -17
  98. package/src/Listing/Row/EmptyRow.tsx +2 -6
  99. package/src/Listing/Row/Row.tsx +7 -36
  100. package/src/Listing/index.stories.tsx +1 -0
  101. package/src/Listing/index.tsx +26 -26
  102. package/src/Listing/useStyleTable.ts +58 -32
  103. package/src/ListingPage/index.stories.tsx +1 -0
  104. package/src/Module/index.tsx +8 -2
  105. package/src/MultiSelectEntries/index.stories.tsx +1 -0
  106. package/src/MultiSelectEntries/index.tsx +1 -1
  107. package/src/Pagination/Pagination.cypress.spec.tsx +137 -0
  108. package/src/Pagination/Pagination.stories.tsx +46 -0
  109. package/src/Pagination/Pagination.styles.ts +56 -0
  110. package/src/Pagination/Pagination.tsx +146 -0
  111. package/src/Pagination/index.ts +3 -0
  112. package/src/Pagination/utils.ts +7 -0
  113. package/src/SortableItems/index.stories.tsx +2 -2
  114. package/src/StoryBookThemeProvider/index.tsx +3 -1
  115. package/src/ThemeProvider/base.css +49 -0
  116. package/src/ThemeProvider/index.tsx +21 -47
  117. package/src/ThemeProvider/palettes.ts +3 -1
  118. package/src/ThemeProvider/tailwindcss.css +230 -0
  119. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/PickersStartEndDate.tsx +9 -11
  120. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/models.ts +1 -0
  121. package/src/TimePeriods/DateTimePickerInput.tsx +3 -1
  122. package/src/api/models.ts +9 -0
  123. package/src/api/useGraphQuery/index.ts +108 -12
  124. package/src/components/Avatar/Avatar.stories.tsx +1 -0
  125. package/src/components/Button/Button.module.css +38 -0
  126. package/src/components/Button/Button.stories.tsx +25 -0
  127. package/src/components/Button/Button.tsx +2 -5
  128. package/src/components/CrudPage/CrudPage.stories.tsx +1 -0
  129. package/src/components/CrudPage/CrudPageRoot.tsx +1 -1
  130. package/src/components/DataTable/DataTable.stories.tsx +1 -0
  131. package/src/components/DataTable/EmptyState/DataTableEmptyState.stories.tsx +1 -0
  132. package/src/components/DataTable/EmptyState/DataTableEmptyState.styles.ts +3 -1
  133. package/src/components/DataTable/EmptyState/DataTableEmptyState.tsx +4 -1
  134. package/src/components/DataTable/Item/DataTableItem.stories.tsx +1 -0
  135. package/src/components/Form/AccessRights/AccessRights.stories.tsx +1 -0
  136. package/src/components/Form/AccessRights/ShareInput/ShareInput.tsx +4 -3
  137. package/src/components/Form/AccessRights/ShareInput/useShareInput.tsx +15 -10
  138. package/src/components/Form/FormActions.tsx +21 -12
  139. package/src/components/Layout/AreaIndicator.tsx +4 -6
  140. package/src/components/Layout/PageLayout/PageLayout.stories.tsx +1 -0
  141. package/src/components/Layout/PageLayout/PageLayout.tsx +9 -3
  142. package/src/components/Layout/PageLayout/PageLayoutActions.tsx +5 -3
  143. package/src/components/Layout/PageLayout/PageLayoutBody.tsx +5 -3
  144. package/src/components/Layout/PageLayout/PageLayoutHeader.tsx +5 -3
  145. package/src/components/Layout/PageLayout/PageQuickAccess.tsx +17 -17
  146. package/src/components/Menu/Button/MenuButton.tsx +6 -6
  147. package/src/components/Menu/MenuDivider.tsx +1 -5
  148. package/src/components/Menu/MenuItem.tsx +1 -5
  149. package/src/components/Menu/MenuItems.tsx +5 -4
  150. package/src/components/Modal/ConfirmationModal/ConfirmationModal.stories.tsx +1 -0
  151. package/src/components/Modal/ConfirmationModal/ConfirmationModal.tsx +4 -1
  152. package/src/components/Modal/Modal.stories.tsx +21 -0
  153. package/src/components/Modal/Modal.styles.ts +1 -19
  154. package/src/components/Modal/Modal.tsx +1 -1
  155. package/src/components/Modal/ModalBody.tsx +6 -4
  156. package/src/components/Modal/ModalHeader.tsx +9 -5
  157. package/src/components/Modal/modal.module.css +16 -0
  158. package/src/components/Tabs/Tab.styles.ts +0 -6
  159. package/src/components/Tabs/Tabs.tsx +37 -15
  160. package/src/index.ts +3 -0
  161. package/src/queryParameters/url/index.ts +7 -2
  162. package/src/utils/index.ts +1 -0
  163. package/src/utils/useLocale/index.ts +9 -0
  164. package/src/utils/useLocale/useLocale.cypress.spec.tsx +38 -0
  165. package/src/utils/useLocaleDateTimeFormat/index.ts +4 -2
  166. package/src/utils/usePluralizedTranslation.ts +2 -3
  167. package/src/Listing/Cell/DataCell.styles.ts +0 -27
  168. package/src/Listing/Header/Cell/ListingHeaderCell.styles.ts +0 -71
  169. package/src/Listing/Header/Cell/SelectActionListingHeaderCell.styles.ts +0 -26
  170. package/src/Listing/Header/ListingHeader.styles.ts +0 -16
  171. package/src/Listing/Listing.styles.ts +0 -78
  172. package/src/Listing/Row/EmptyRow.styles.ts +0 -14
  173. package/src/components/Button/Button.styles.ts +0 -44
  174. package/src/components/Layout/AreaIndicator.styles.ts +0 -33
  175. package/src/components/Menu/Button/MenuButton.styles.ts +0 -27
  176. package/src/components/Menu/Menu.styles.ts +0 -68
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@centreon/ui",
3
- "version": "25.3.4",
3
+ "version": "25.4.0-MON-191119-npm-develop.0",
4
4
  "description": "Centreon UI Components",
5
5
  "scripts": {
6
6
  "update:deps": "pnpx npm-check-updates -i --format group",
@@ -12,10 +12,10 @@
12
12
  "test": "jest",
13
13
  "test:storybook:local": "test-storybook --url http://127.0.0.1:9001",
14
14
  "test:ci": "jest --silent --reporter=jest-junit",
15
- "cypress:ui": "cypress open --component --browser=chrome",
16
- "cypress:run:updateSnapshots": "cypress run --component --browser=chrome --env updateSnapshots=true",
17
- "cypress:run:coverage": "cypress run --component --browser=chrome --env codeCoverageTasksRegistered=true",
18
- "cypress:run": "cypress run --component --browser=chrome",
15
+ "cypress:ui": "cypress open --component --browser=chromium",
16
+ "cypress:run:updateSnapshots": "cypress run --component --browser=chromium --env updateSnapshots=true",
17
+ "cypress:run:coverage": "cypress run --component --browser=chromium --env codeCoverageTasksRegistered=true",
18
+ "cypress:run": "cypress run --component --browser=chromium",
19
19
  "cypress:install": "cypress install",
20
20
  "cypress:cli": "./cypress/scripts/cypress-cli.sh",
21
21
  "tokens:transform": "TS_NODE_PROJECT=tsconfig.node.json ts-node style-dictionary.transform.ts",
@@ -44,7 +44,8 @@
44
44
  ".": "./src/index.ts",
45
45
  "./components": "./src/components/index.ts",
46
46
  "./fonts/*": "./src/fonts/*",
47
- "./test/testRenderer": "./test/testRenderer.tsx"
47
+ "./test/testRenderer": "./test/testRenderer.tsx",
48
+ "./tailwindcss": "./src/ThemeProvider/tailwindcss.css"
48
49
  },
49
50
  "files": [
50
51
  "package.json",
@@ -57,6 +58,8 @@
57
58
  "@cypress/webpack-dev-server": "^4.0.1",
58
59
  "@faker-js/faker": "^9.5.1",
59
60
  "@mdx-js/react": "^3.1.0",
61
+ "@rsbuild/core": "^1.3.21",
62
+ "@rsbuild/plugin-react": "^1.3.1",
60
63
  "@simonsmith/cypress-image-snapshot": "^9.1.0",
61
64
  "@storybook/addon-a11y": "^8.6.3",
62
65
  "@storybook/addon-docs": "^8.6.3",
@@ -72,6 +75,9 @@
72
75
  "@storybook/test": "^8.6.3",
73
76
  "@storybook/test-runner": "^0.22.0",
74
77
  "@storybook/theming": "^8.6.3",
78
+ "@tailwindcss/cli": "^4.1.7",
79
+ "@tailwindcss/postcss": "^4.1.7",
80
+ "@tailwindcss/vite": "^4.1.7",
75
81
  "@testing-library/cypress": "^10.0.3",
76
82
  "@testing-library/jest-dom": "^6.6.3",
77
83
  "@testing-library/react": "^16.2.0",
@@ -84,7 +90,7 @@
84
90
  "@vitejs/plugin-react": "^4.3.4",
85
91
  "@vitejs/plugin-react-swc": "^3.8.0",
86
92
  "chai": "^5.2.0",
87
- "cypress": "^14.1.0",
93
+ "cypress": "^15.5.0",
88
94
  "identity-obj-proxy": "^3.0.0",
89
95
  "jest-transform-stub": "^2.0.0",
90
96
  "mochawesome": "^7.1.3",
@@ -95,19 +101,21 @@
95
101
  "react-test-renderer": "^19.0.0",
96
102
  "remark-gfm": "^4.0.1",
97
103
  "speed-measure-vite-plugin": "^1.1.0",
98
- "storybook": "^8.6.3",
104
+ "storybook": "^8.6.14",
99
105
  "storybook-addon-mock": "^5.0.0",
100
106
  "storybook-dark-mode": "^4.0.2",
107
+ "storybook-react-rsbuild": "^1.0.1",
101
108
  "style-dictionary": "^4.3.3",
109
+ "tailwindcss": "^4.1.7",
102
110
  "ts-node": "^10.9.2",
103
111
  "use-resize-observer": "^9.1.0",
104
- "vite": "^6.2.0",
112
+ "vite": "^6.3.5",
105
113
  "vite-plugin-istanbul": "^7.0.0",
106
114
  "vite-plugin-svgr": "^4.3.0",
107
115
  "vite-plugin-turbosnap": "^1.0.3"
108
116
  },
109
117
  "peerDependencies": {
110
- "@centreon/ui-context": "link:../ui-context"
118
+ "@centreon/ui-context": "workspace:*"
111
119
  },
112
120
  "dependencies": {
113
121
  "@lexical/html": "^0.27.0",
@@ -117,7 +125,7 @@
117
125
  "@lexical/rich-text": "^0.27.0",
118
126
  "@lexical/selection": "^0.27.0",
119
127
  "@lexical/utils": "^0.27.0",
120
- "@mui/material": "^6.4.6",
128
+ "@mui/material": "^7.1.0",
121
129
  "@react-spring/web": "^9.7.5",
122
130
  "@visx/clip-path": "^3.12.0",
123
131
  "@visx/curve": "^3.12.0",
@@ -158,5 +166,11 @@
158
166
  "workerDirectory": [
159
167
  "public"
160
168
  ]
169
+ },
170
+ "nyc": {
171
+ "report-dir": "coverage",
172
+ "reporter": [
173
+ "json"
174
+ ]
161
175
  }
162
176
  }
@@ -8,8 +8,8 @@
8
8
  * - Please do NOT serve this file on production.
9
9
  */
10
10
 
11
- const PACKAGE_VERSION = '2.7.3'
12
- const INTEGRITY_CHECKSUM = '00729d72e3b82faf54ca8b9621dbb96f'
11
+ const PACKAGE_VERSION = '2.2.14'
12
+ const INTEGRITY_CHECKSUM = '26357c79639bfa20d64c0efca2a87423'
13
13
  const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
14
14
  const activeClientIds = new Set()
15
15
 
@@ -62,12 +62,7 @@ self.addEventListener('message', async function (event) {
62
62
 
63
63
  sendToClient(client, {
64
64
  type: 'MOCKING_ENABLED',
65
- payload: {
66
- client: {
67
- id: client.id,
68
- frameType: client.frameType,
69
- },
70
- },
65
+ payload: true,
71
66
  })
72
67
  break
73
68
  }
@@ -160,10 +155,6 @@ async function handleRequest(event, requestId) {
160
155
  async function resolveMainClient(event) {
161
156
  const client = await self.clients.get(event.clientId)
162
157
 
163
- if (activeClientIds.has(event.clientId)) {
164
- return client
165
- }
166
-
167
158
  if (client?.frameType === 'top-level') {
168
159
  return client
169
160
  }
@@ -192,26 +183,12 @@ async function getResponse(event, client, requestId) {
192
183
  const requestClone = request.clone()
193
184
 
194
185
  function passthrough() {
195
- // Cast the request headers to a new Headers instance
196
- // so the headers can be manipulated with.
197
- const headers = new Headers(requestClone.headers)
198
-
199
- // Remove the "accept" header value that marked this request as passthrough.
200
- // This prevents request alteration and also keeps it compliant with the
201
- // user-defined CORS policies.
202
- const acceptHeader = headers.get('accept')
203
- if (acceptHeader) {
204
- const values = acceptHeader.split(',').map((value) => value.trim())
205
- const filteredValues = values.filter(
206
- (value) => value !== 'msw/passthrough',
207
- )
186
+ const headers = Object.fromEntries(requestClone.headers.entries())
208
187
 
209
- if (filteredValues.length > 0) {
210
- headers.set('accept', filteredValues.join(', '))
211
- } else {
212
- headers.delete('accept')
213
- }
214
- }
188
+ // Remove internal MSW request header so the passthrough request
189
+ // complies with any potential CORS preflight checks on the server.
190
+ // Some servers forbid unknown request headers.
191
+ delete headers['x-msw-intention']
215
192
 
216
193
  return fetch(requestClone, { headers })
217
194
  }
@@ -4,6 +4,7 @@ import { makeStyles } from 'tss-react/mui';
4
4
  import { Theme } from '@mui/material';
5
5
 
6
6
  import ButtonSave from '.';
7
+ import '../../ThemeProvider/tailwindcss.css';
7
8
 
8
9
  const useStyles = makeStyles()((theme: Theme) => ({
9
10
  root: {
@@ -55,12 +55,14 @@ interface Props {
55
55
  dataTestId?: string;
56
56
  disabled?: boolean;
57
57
  label: string;
58
+ id: string;
58
59
  labelPlacement?: LabelPlacement;
59
60
  labelProps?: TypographyProps;
60
61
  onChange?: (e) => void;
61
62
  }
62
63
 
63
64
  const Checkbox = ({
65
+ id,
64
66
  Icon,
65
67
  checked,
66
68
  label,
@@ -86,7 +88,7 @@ const Checkbox = ({
86
88
  className={classes.checkbox}
87
89
  color="primary"
88
90
  disabled={disabled}
89
- id={label}
91
+ id={id}
90
92
  size="small"
91
93
  sx={{ padding: 0 }}
92
94
  onChange={onChange}
@@ -6,6 +6,8 @@ import { TypographyProps } from '@mui/material/Typography';
6
6
 
7
7
  import Checkbox, { LabelPlacement } from '../Checkbox';
8
8
 
9
+ import { useTranslation } from 'react-i18next';
10
+
9
11
  interface Props {
10
12
  className?: string;
11
13
  dataTestId?: string;
@@ -45,6 +47,8 @@ const CheckboxGroup = ({
45
47
  }: Props): JSX.Element => {
46
48
  const { classes, cx } = useStyles();
47
49
 
50
+ const { t } = useTranslation();
51
+
48
52
  const row = !equals(direction, 'vertical');
49
53
 
50
54
  return (
@@ -61,10 +65,11 @@ const CheckboxGroup = ({
61
65
  className={cx(classes.checkbox, className)}
62
66
  disabled={disabled}
63
67
  key={value}
64
- label={value}
68
+ label={t(value)}
65
69
  labelPlacement={labelPlacement}
66
70
  labelProps={labelProps}
67
71
  onChange={onChange}
72
+ id={value}
68
73
  />
69
74
  );
70
75
  })}
@@ -55,7 +55,7 @@ const ContainerDescription = ({
55
55
  {toPairs(palette[keyTheme]).map(
56
56
  ([key, value]) =>
57
57
  !includes(key, keysToRemove) && (
58
- <Grid item key={key} xs={6}>
58
+ <Grid item key={key} size={6}>
59
59
  <div className={classes.headerContainer}>
60
60
  <Typography variant="h6">{key}</Typography>
61
61
  <Typography variant="button">{value}</Typography>
@@ -17,7 +17,7 @@ export const useDashboardLayoutStyles = makeStyles<boolean>()(
17
17
  boxShadow: theme.shadows[3]
18
18
  },
19
19
  '& .react-grid-item.react-grid-placeholder': {
20
- backgroundColor: alpha(theme.palette.primary.main, 0.4)
20
+ background: `${alpha(theme.palette.primary.main, 0.4)} !important`
21
21
  },
22
22
  '& .react-grid-item.resizing': {
23
23
  boxShadow: theme.shadows[3]
@@ -2,7 +2,6 @@ import { useCallback, useEffect, useRef, useState } from 'react';
2
2
 
3
3
  import { useSetAtom } from 'jotai';
4
4
  import GridLayout, { Layout, WidthProvider } from 'react-grid-layout';
5
- import 'react-grid-layout/css/styles.css';
6
5
 
7
6
  import { ParentSize, useMemoComponent } from '..';
8
7
 
@@ -10,6 +9,7 @@ import { Box } from '@mui/material';
10
9
  import { useDashboardLayoutStyles } from './Dashboard.styles';
11
10
  import { isResizingItemAtom } from './atoms';
12
11
  import { getColumnsFromScreenSize, getLayout, rowHeight } from './utils';
12
+ import 'react-grid-layout/css/styles.css';
13
13
 
14
14
  const ReactGridLayout = WidthProvider(GridLayout);
15
15
 
@@ -4,6 +4,7 @@ import { useSnackbar } from '../..';
4
4
  import SnackbarProvider from '../../Snackbar/SnackbarProvider';
5
5
 
6
6
  import UnsavedChangesDialog from '.';
7
+ import '../../ThemeProvider/tailwindcss.css';
7
8
 
8
9
  export default {
9
10
  argTypes: {
@@ -3,8 +3,8 @@ import { useCallback, useState } from 'react';
3
3
  import { useTranslation } from 'react-i18next';
4
4
  import { makeStyles } from 'tss-react/mui';
5
5
 
6
- import ChevronRightIcon from '@mui/icons-material/ChevronRight';
7
- import ExpandMore from '@mui/icons-material/ExpandMore';
6
+ import { ExpandLess, ExpandMore } from '@mui/icons-material';
7
+
8
8
  import {
9
9
  Box,
10
10
  Collapse,
@@ -35,12 +35,6 @@ const useStyles = makeStyles()((theme) => ({
35
35
  display: 'flex',
36
36
  flexDirection: 'row'
37
37
  },
38
- groupTitleIcon: {
39
- alignItems: 'center',
40
- columnGap: theme.spacing(1),
41
- display: 'flex',
42
- flexDirection: 'row'
43
- },
44
38
  tooltip: {
45
39
  maxWidth: theme.spacing(60)
46
40
  },
@@ -66,7 +60,7 @@ const CollapsibleGroup = ({
66
60
 
67
61
  const containerClassName = className || '';
68
62
 
69
- const CollapseIcon = isOpen ? ExpandMore : ChevronRightIcon;
63
+ const CollapseIcon = isOpen ? ExpandLess : ExpandMore;
70
64
  const ContainerComponent = useCallback(
71
65
  ({
72
66
  children: containerComponentChildren
@@ -77,7 +71,7 @@ const CollapsibleGroup = ({
77
71
  disableGutters
78
72
  disableRipple
79
73
  aria-label={group?.name}
80
- className={cx(classes.groupTitleContainer, containerClassName)}
74
+ className={`${cx(classes.groupTitleContainer, containerClassName)} bg-background-listing-header`}
81
75
  onClick={toggle}
82
76
  >
83
77
  {containerComponentChildren}
@@ -94,12 +88,17 @@ const CollapsibleGroup = ({
94
88
  <>
95
89
  {hasGroupTitle && (
96
90
  <ContainerComponent>
97
- {isCollapsible && <CollapseIcon />}
98
- <div className={classes.groupTitleIcon}>
91
+ <div
92
+ data-testid={`${group?.name}-header`}
93
+ className={
94
+ 'snap-y flex flex-row justify-between w-full pl-3 pr-1 text-white items-center'
95
+ }
96
+ >
99
97
  <Typography
100
- className="groupText"
98
+ className="groupText scroll-m-12 snap-start"
101
99
  variant="h6"
102
100
  {...group?.titleAttributes}
101
+ data-section-group-form-id={group?.name}
103
102
  >
104
103
  {t(group?.name as string)}
105
104
  </Typography>
@@ -116,6 +115,7 @@ const CollapsibleGroup = ({
116
115
  </MuiIconButton>
117
116
  </Tooltip>
118
117
  )}
118
+ {isCollapsible && <CollapseIcon />}
119
119
  </div>
120
120
  </ContainerComponent>
121
121
  )}
@@ -132,16 +132,129 @@ describe('Form list', () => {
132
132
  });
133
133
  });
134
134
 
135
- const initializeFile = (): void => {
135
+ const initializeFormWithSections = (): void => {
136
136
  cy.mount({
137
137
  Component: (
138
138
  <Form
139
+ isCollapsible
139
140
  initialValues={{
140
141
  list: []
141
142
  }}
143
+ groups={[
144
+ {
145
+ name: 'First group',
146
+ order: 1
147
+ },
148
+ {
149
+ name: 'Third group',
150
+ order: 3
151
+ },
152
+ {
153
+ name: 'Second group',
154
+ order: 2
155
+ },
156
+ {
157
+ name: 'Fourth group',
158
+ order: 4
159
+ }
160
+ ]}
142
161
  inputs={[
143
162
  {
144
- fieldName: 'file',
163
+ fieldName: 'First name',
164
+ group: 'First group',
165
+ label: 'Name',
166
+ type: InputType.Text
167
+ },
168
+ {
169
+ fieldName: 'Divider',
170
+ group: 'First group',
171
+ label: 'Divider',
172
+ type: InputType.Divider
173
+ },
174
+ {
175
+ fieldName: 'Second name',
176
+ group: 'First group',
177
+ label: 'Name',
178
+ type: InputType.Text
179
+ },
180
+ {
181
+ fieldName: 'Third name',
182
+ group: 'First group',
183
+ label: 'Name',
184
+ type: InputType.Text
185
+ },
186
+ {
187
+ fieldName: 'Fourth name',
188
+ group: 'First group',
189
+ label: 'Name',
190
+ type: InputType.Text
191
+ },
192
+ {
193
+ fieldName: 'Fifth name',
194
+ group: 'First group',
195
+ label: 'Name',
196
+ type: InputType.Text
197
+ },
198
+ {
199
+ fieldName: 'Sixth name',
200
+ group: 'First group',
201
+ label: 'Name',
202
+ type: InputType.Text
203
+ },
204
+ {
205
+ fieldName: 'Seventh name',
206
+ group: 'First group',
207
+ label: 'Name',
208
+ type: InputType.Text
209
+ },
210
+ {
211
+ fieldName: 'Eighth name',
212
+ group: 'First group',
213
+ label: 'Name',
214
+ type: InputType.Text
215
+ },
216
+ {
217
+ fieldName: 'Ninth name',
218
+ group: 'First group',
219
+ label: 'Name',
220
+ type: InputType.Text
221
+ },
222
+ {
223
+ fieldName: 'First second group name',
224
+ group: 'Second group',
225
+ label: 'Name',
226
+ type: InputType.Text
227
+ },
228
+ {
229
+ fieldName: 'First third group name',
230
+ group: 'Third group',
231
+ label: 'Name',
232
+ type: InputType.Text
233
+ },
234
+ {
235
+ fieldName: 'First fourth group name',
236
+ group: 'Fourth group',
237
+ label: 'Name',
238
+ type: InputType.Text
239
+ }
240
+ ]}
241
+ submit={cy.stub()}
242
+ validationSchema={object()}
243
+ />
244
+ )
245
+ });
246
+ };
247
+
248
+ const initializeFile = () => {
249
+ cy.mount({
250
+ Component: (
251
+ <Form
252
+ initialValues={{
253
+ list: []
254
+ }}
255
+ inputs={[
256
+ {
257
+ fieldName: 'list',
145
258
  group: '',
146
259
  label: 'json',
147
260
  type: InputType.File,
@@ -170,3 +283,25 @@ describe('File', () => {
170
283
  cy.makeSnapshot();
171
284
  });
172
285
  });
286
+
287
+ describe('Form with sections', () => {
288
+ beforeEach(initializeFormWithSections);
289
+ it('displays sections when correct amount of sections', () => {
290
+ cy.contains('First group').should('be.visible');
291
+ cy.contains('Second group').should('be.visible');
292
+ cy.contains('Third group').should('be.visible');
293
+ cy.contains('Fourth group').should('be.visible');
294
+ cy.makeSnapshot();
295
+ });
296
+
297
+ it('scrolls correctly to section', () => {
298
+ cy.window().then((win) => {
299
+ const initialScrollY = win.scrollY;
300
+ cy.contains('Third group').click();
301
+ cy.window().its('scrollY').should('be.greaterThan', initialScrollY);
302
+ });
303
+
304
+ cy.wait(500); // Wait for the scroll animation to complete
305
+ cy.makeSnapshot();
306
+ });
307
+ });
@@ -1,5 +1,3 @@
1
- import { Paper } from '@mui/material';
2
-
3
1
  import { Form, GroupDirection } from './Form';
4
2
  import {
5
3
  BasicForm,
@@ -27,51 +25,33 @@ const mandatoryProps = {
27
25
  };
28
26
 
29
27
  export const basicForm = (): JSX.Element => (
30
- <Paper elevation={0} sx={{ p: 1 }}>
31
- <Form<BasicForm> {...mandatoryProps} />
32
- </Paper>
28
+ <Form<BasicForm> {...mandatoryProps} />
33
29
  );
34
30
 
35
31
  export const basicFormWithGroups = (): JSX.Element => (
36
- <Paper elevation={0} sx={{ p: 1 }}>
37
- <Form<BasicForm> {...mandatoryProps} groups={basicFormGroups} />
38
- </Paper>
32
+ <Form<BasicForm> {...mandatoryProps} groups={basicFormGroups} />
39
33
  );
40
34
 
41
35
  export const basicFormWithCollapsibleGroups = (): JSX.Element => (
42
- <Paper elevation={0} sx={{ p: 1 }}>
43
- <Form<BasicForm>
44
- {...mandatoryProps}
45
- isCollapsible
46
- groups={basicFormGroups}
47
- />
48
- </Paper>
36
+ <Form<BasicForm> {...mandatoryProps} isCollapsible groups={basicFormGroups} />
49
37
  );
50
38
 
51
39
  export const basicFormWithCustomButton = (): JSX.Element => (
52
- <Paper elevation={0} sx={{ p: 1 }}>
53
- <Form<BasicForm> {...mandatoryProps} Buttons={CustomButton} />
54
- </Paper>
40
+ <Form<BasicForm> {...mandatoryProps} Buttons={CustomButton} />
55
41
  );
56
42
 
57
43
  export const loadingForm = (): JSX.Element => (
58
- <Paper elevation={0} sx={{ p: 1 }}>
59
- <Form<BasicForm> {...mandatoryProps} isLoading />
60
- </Paper>
44
+ <Form<BasicForm> {...mandatoryProps} isLoading />
61
45
  );
62
46
 
63
47
  export const loadingFormWithGroups = (): JSX.Element => (
64
- <Paper elevation={0} sx={{ p: 1 }}>
65
- <Form<BasicForm> {...mandatoryProps} isLoading groups={basicFormGroups} />
66
- </Paper>
48
+ <Form<BasicForm> {...mandatoryProps} isLoading groups={basicFormGroups} />
67
49
  );
68
50
 
69
51
  export const basicFormWithHorizontalGroups = (): JSX.Element => (
70
- <Paper elevation={0} sx={{ p: 1 }}>
71
- <Form<BasicForm>
72
- {...mandatoryProps}
73
- groupDirection={GroupDirection.Horizontal}
74
- groups={basicFormGroups.filter((group) => group.order !== 3)}
75
- />
76
- </Paper>
52
+ <Form<BasicForm>
53
+ {...mandatoryProps}
54
+ groupDirection={GroupDirection.Horizontal}
55
+ groups={basicFormGroups.filter((group) => group.order !== 3)}
56
+ />
77
57
  );
package/src/Form/Form.tsx CHANGED
@@ -11,6 +11,7 @@ import { useStyles } from './Form.styles';
11
11
  import FormButtons from './FormButtons';
12
12
  import Inputs from './Inputs';
13
13
  import { Group, InputProps } from './Inputs/models';
14
+ import { FormSection } from './Section/FormSection';
14
15
 
15
16
  export enum GroupDirection {
16
17
  Horizontal = 'horizontal',
@@ -76,6 +77,7 @@ const Form = <T extends object>({
76
77
  {...formikSharedConfig}
77
78
  >
78
79
  <div>
80
+ <FormSection groups={groups} />
79
81
  {children}
80
82
  <div className={cx(className, classes.form)}>
81
83
  <Inputs
@@ -15,7 +15,8 @@ const Checkbox = ({
15
15
  fieldName,
16
16
  getDisabled,
17
17
  hideInput,
18
- dataTestId
18
+ dataTestId,
19
+ label
19
20
  }: InputPropsWithoutGroup): JSX.Element => {
20
21
  const { values, setFieldValue } = useFormikContext<FormikValues>();
21
22
 
@@ -45,7 +46,7 @@ const Checkbox = ({
45
46
  checked={value?.checked}
46
47
  dataTestId={dataTestId || ''}
47
48
  disabled={disabled}
48
- label={value?.label}
49
+ label={label}
49
50
  labelPlacement={checkbox?.labelPlacement || 'end'}
50
51
  onChange={handleChange}
51
52
  />
@@ -57,7 +57,8 @@ const ConnectedAutocomplete = ({
57
57
  ...parameters.search
58
58
  },
59
59
  sort: { [filterKey]: 'ASC' }
60
- }
60
+ },
61
+ customQueryParameters: connectedAutocomplete?.customQueryParameters || []
61
62
  });
62
63
 
63
64
  const fieldNamePath = split('.', fieldName);
@@ -134,6 +135,7 @@ const ConnectedAutocomplete = ({
134
135
  error={error}
135
136
  field={filterKey}
136
137
  getEndpoint={getEndpoint}
138
+ decoder={connectedAutocomplete?.decoder}
137
139
  getRenderedOptionText={connectedAutocomplete?.getRenderedOptionText}
138
140
  initialPage={1}
139
141
  isOptionEqualToValue={isOptionEqualToValue}
@@ -143,6 +145,9 @@ const ConnectedAutocomplete = ({
143
145
  value={value ?? null}
144
146
  onBlur={blur}
145
147
  onChange={changeAutocomplete}
148
+ disableSelectAll={connectedAutocomplete?.disableSelectAll}
149
+ limitTags={connectedAutocomplete?.limitTags}
150
+ searchConditions={connectedAutocomplete?.additionalConditionParameters}
146
151
  />
147
152
  ),
148
153
  memoProps: [