@centreon/ui 24.4.1-sync-release-34022.1 → 24.4.1-test-code-coverage.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 (220) hide show
  1. package/package.json +48 -40
  2. package/src/ActionsList/ActionsList.styles.ts +40 -71
  3. package/src/Button/Icon/index.stories.tsx +1 -1
  4. package/src/Button/Icon/index.tsx +1 -1
  5. package/src/Dashboard/Dashboard.styles.ts +6 -5
  6. package/src/Dialog/Confirm/index.tsx +10 -2
  7. package/src/Dialog/UnsavedChanges/index.tsx +21 -20
  8. package/src/Dialog/UnsavedChanges/translatedLabels.ts +4 -6
  9. package/src/Dialog/index.tsx +8 -1
  10. package/src/Form/Inputs/CheckboxGroup.tsx +4 -1
  11. package/src/Form/Inputs/Text.tsx +3 -1
  12. package/src/Form/Inputs/models.ts +1 -0
  13. package/src/Graph/BarStack/BarStack.cypress.spec.tsx +139 -0
  14. package/src/Graph/BarStack/BarStack.stories.tsx +123 -0
  15. package/src/Graph/BarStack/BarStack.styles.ts +37 -0
  16. package/src/Graph/BarStack/BarStack.tsx +14 -0
  17. package/src/Graph/BarStack/ResponsiveBarStack.tsx +209 -0
  18. package/src/Graph/BarStack/index.ts +1 -0
  19. package/src/Graph/BarStack/models.ts +19 -0
  20. package/src/Graph/BarStack/useResponsiveBarStack.ts +131 -0
  21. package/src/Graph/Gauge/Gauge.cypress.spec.tsx +102 -0
  22. package/src/Graph/Gauge/Gauge.tsx +1 -1
  23. package/src/Graph/HeatMap/HeatMap.cypress.spec.tsx +145 -0
  24. package/src/Graph/HeatMap/HeatMap.stories.tsx +0 -25
  25. package/src/Graph/HeatMap/ResponsiveHeatMap.tsx +8 -2
  26. package/src/Graph/Legend/Legend.tsx +21 -0
  27. package/src/Graph/Legend/index.ts +1 -0
  28. package/src/Graph/Legend/models.ts +11 -0
  29. package/src/Graph/LineChart/BasicComponents/Lines/Threshold/index.tsx +4 -5
  30. package/src/Graph/LineChart/BasicComponents/ThresholdLine.tsx +3 -1
  31. package/src/Graph/LineChart/Header/index.tsx +3 -31
  32. package/src/Graph/LineChart/InteractiveComponents/AnchorPoint/useTickGraph.ts +9 -11
  33. package/src/Graph/LineChart/InteractiveComponents/Annotations/Annotation/index.tsx +3 -2
  34. package/src/Graph/LineChart/InteractiveComponents/GraphValueTooltip/GraphValueTooltip.tsx +68 -0
  35. package/src/Graph/LineChart/InteractiveComponents/GraphValueTooltip/useGraphValueTooltip.ts +27 -0
  36. package/src/Graph/LineChart/InteractiveComponents/GraphValueTooltip/useGraphValueTooltipStyles.ts +31 -0
  37. package/src/Graph/LineChart/InteractiveComponents/index.tsx +132 -17
  38. package/src/Graph/LineChart/InteractiveComponents/interactionWithGraphAtoms.ts +7 -27
  39. package/src/Graph/LineChart/Legend/Legend.styles.ts +5 -9
  40. package/src/Graph/LineChart/Legend/LegendHeader.tsx +10 -22
  41. package/src/Graph/LineChart/Legend/index.tsx +17 -55
  42. package/src/Graph/LineChart/LineChart.cypress.spec.tsx +91 -0
  43. package/src/Graph/LineChart/LineChart.styles.ts +8 -0
  44. package/src/Graph/LineChart/LineChart.tsx +106 -116
  45. package/src/Graph/LineChart/LoadingSkeleton.tsx +2 -2
  46. package/src/Graph/LineChart/index.tsx +6 -7
  47. package/src/Graph/LineChart/mockedData/lastDayWithIncompleteValues.json +1320 -0
  48. package/src/Graph/LineChart/mockedData/lastDayWithNullValues.json +1314 -0
  49. package/src/Graph/LineChart/models.ts +12 -1
  50. package/src/Graph/PieChart/PieChart.cypress.spec.tsx +154 -0
  51. package/src/Graph/PieChart/PieChart.stories.tsx +194 -0
  52. package/src/Graph/PieChart/PieChart.styles.ts +39 -0
  53. package/src/Graph/PieChart/PieChart.tsx +14 -0
  54. package/src/Graph/PieChart/ResponsivePie.tsx +243 -0
  55. package/src/Graph/PieChart/index.ts +1 -0
  56. package/src/Graph/PieChart/models.ts +19 -0
  57. package/src/Graph/PieChart/useResponsivePie.ts +81 -0
  58. package/src/Graph/SingleBar/SingleBar.cypress.spec.tsx +121 -0
  59. package/src/Graph/Text/Text.cypress.spec.tsx +101 -0
  60. package/src/Graph/Text/Text.styles.ts +12 -1
  61. package/src/Graph/Text/Text.tsx +17 -12
  62. package/src/Graph/Tree/DescendantNodes.tsx +89 -0
  63. package/src/Graph/Tree/Links.tsx +77 -0
  64. package/src/Graph/Tree/StandaloneTree.tsx +32 -0
  65. package/src/Graph/Tree/Tree.cypress.spec.tsx +195 -0
  66. package/src/Graph/Tree/Tree.stories.tsx +160 -0
  67. package/src/Graph/Tree/Tree.tsx +116 -0
  68. package/src/Graph/Tree/constants.ts +2 -0
  69. package/src/Graph/Tree/index.ts +4 -0
  70. package/src/Graph/Tree/models.ts +55 -0
  71. package/src/Graph/Tree/stories/contents.tsx +164 -0
  72. package/src/Graph/Tree/stories/datas.ts +305 -0
  73. package/src/Graph/Tree/utils.ts +49 -0
  74. package/src/Graph/common/testUtils.ts +71 -0
  75. package/src/Graph/common/timeSeries/index.ts +50 -12
  76. package/src/Graph/common/utils.ts +19 -0
  77. package/src/Graph/index.ts +4 -0
  78. package/src/InputField/Number/Number.cypress.spec.tsx +85 -0
  79. package/src/InputField/Number/Number.stories.tsx +66 -0
  80. package/src/InputField/Number/Number.tsx +74 -0
  81. package/src/InputField/Search/index.tsx +2 -2
  82. package/src/InputField/Select/Autocomplete/Multi/index.tsx +4 -2
  83. package/src/InputField/Select/Autocomplete/index.tsx +10 -3
  84. package/src/InputField/Select/IconPopover/index.tsx +1 -1
  85. package/src/InputField/Select/index.tsx +14 -1
  86. package/src/InputField/Text/index.tsx +38 -38
  87. package/src/Listing/ActionBar/index.tsx +10 -10
  88. package/src/Listing/Cell/DataCell.styles.ts +3 -0
  89. package/src/Listing/Cell/DataCell.tsx +8 -4
  90. package/src/Listing/Listing.cypress.spec.tsx +217 -33
  91. package/src/Listing/Listing.styles.ts +3 -5
  92. package/src/Listing/Row/Row.tsx +7 -3
  93. package/src/Listing/index.stories.tsx +25 -2
  94. package/src/Listing/index.test.tsx +1 -1
  95. package/src/Listing/index.tsx +202 -143
  96. package/src/Listing/models.ts +1 -0
  97. package/src/Listing/useStyleTable.ts +1 -0
  98. package/src/Panel/index.tsx +1 -1
  99. package/src/PopoverMenu/index.tsx +6 -5
  100. package/src/ThemeProvider/index.tsx +3 -0
  101. package/src/TimePeriods/CustomTimePeriod/CompactCustomTimePeriod.styles.ts +6 -7
  102. package/src/TimePeriods/ResolutionTimePeriod.cypress.spec.tsx +12 -9
  103. package/src/Typography/FluidTypography/FluidTypography.cypress.spec.tsx +27 -0
  104. package/src/Typography/FluidTypography/index.stories.tsx +2 -2
  105. package/src/Typography/FluidTypography/index.tsx +21 -28
  106. package/src/api/index.ts +3 -3
  107. package/src/api/useGraphQuery/index.ts +26 -5
  108. package/src/api/useGraphQuery/models.ts +5 -0
  109. package/src/api/useMutationQuery/index.test.ts +4 -4
  110. package/src/api/useMutationQuery/index.ts +24 -13
  111. package/src/components/CollapsibleItem/CollapsibleItem.cypress.spec.tsx +76 -0
  112. package/src/components/CollapsibleItem/CollapsibleItem.stories.tsx +26 -0
  113. package/src/components/CollapsibleItem/CollapsibleItem.tsx +43 -14
  114. package/src/components/CollapsibleItem/useCollapsibleItemStyles.ts +24 -1
  115. package/src/components/DataTable/DataTable.cypress.spec.tsx +14 -33
  116. package/src/components/DataTable/Item/DataTableItem.tsx +4 -60
  117. package/src/components/Form/{AccessRightsV2 → AccessRights}/AccessRights.cypress.spec.tsx +36 -13
  118. package/src/components/Form/{AccessRightsV2 → AccessRights}/ShareInput/ContactSwitch.tsx +11 -3
  119. package/src/components/Form/{AccessRightsV2 → AccessRights}/ShareInput/ShareInput.styles.ts +8 -0
  120. package/src/components/Form/{AccessRightsV2 → AccessRights}/ShareInput/ShareInput.tsx +1 -0
  121. package/src/components/Form/{AccessRightsV2 → AccessRights}/ShareInput/useShareInput.tsx +4 -0
  122. package/src/components/Form/{AccessRightsV2 → AccessRights}/models.ts +1 -0
  123. package/src/components/Form/{AccessRightsV2 → AccessRights}/storiesData.ts +23 -22
  124. package/src/components/Form/Dashboard/DashboardDuplicationForm.tsx +85 -0
  125. package/src/components/Form/Dashboard/index.ts +1 -0
  126. package/src/components/Form/FormActions.tsx +7 -2
  127. package/src/components/Form/index.ts +2 -2
  128. package/src/components/ItemComposition/Item.tsx +1 -1
  129. package/src/components/ItemComposition/ItemComposition.cypress.spec.tsx +113 -0
  130. package/src/components/ItemComposition/ItemComposition.stories.tsx +14 -0
  131. package/src/components/ItemComposition/ItemComposition.styles.ts +36 -3
  132. package/src/components/ItemComposition/ItemComposition.tsx +41 -17
  133. package/src/components/List/Item/ListItem.tsx +3 -3
  134. package/src/components/Modal/ConfirmationModal/ConfirmationModal.cypress.spec.tsx +168 -0
  135. package/src/components/Modal/ConfirmationModal/ConfirmationModal.stories.tsx +62 -0
  136. package/src/components/Modal/ConfirmationModal/ConfirmationModal.tsx +87 -0
  137. package/src/components/Modal/Modal.styles.ts +8 -3
  138. package/src/components/Modal/index.ts +2 -0
  139. package/src/components/Tooltip/ConfirmationTooltip/ConfirmationTooltip.stories.tsx +3 -3
  140. package/src/components/Tooltip/ConfirmationTooltip/ConfirmationTooltip.tsx +1 -1
  141. package/src/components/Tooltip/ConfirmationTooltip/models.ts +1 -1
  142. package/src/components/Zoom/Minimap.tsx +129 -0
  143. package/src/components/Zoom/Zoom.cypress.spec.tsx +246 -0
  144. package/src/components/Zoom/Zoom.stories.tsx +115 -0
  145. package/src/components/Zoom/Zoom.styles.tsx +68 -0
  146. package/src/components/Zoom/Zoom.tsx +64 -0
  147. package/src/components/Zoom/ZoomContent.tsx +170 -0
  148. package/src/components/Zoom/constants.ts +2 -0
  149. package/src/components/Zoom/localPoint.ts +51 -0
  150. package/src/components/Zoom/models.ts +25 -0
  151. package/src/components/Zoom/useMinimap.ts +156 -0
  152. package/src/components/Zoom/useZoom.ts +70 -0
  153. package/src/components/Zoom/utils.ts +55 -0
  154. package/src/components/index.ts +1 -0
  155. package/src/index.ts +1 -0
  156. package/src/utils/index.ts +3 -0
  157. package/src/utils/resourcesStatusURL.ts +166 -0
  158. package/src/utils/useFullscreen/Fullscreen.cypress.spec.tsx +130 -0
  159. package/src/utils/useFullscreen/atoms.ts +3 -0
  160. package/src/utils/useFullscreen/index.ts +2 -0
  161. package/src/utils/useFullscreen/translatedLabels.ts +1 -0
  162. package/src/utils/useFullscreen/useFullscreen.ts +73 -0
  163. package/src/utils/useFullscreen/useFullscreenListener.ts +62 -0
  164. package/src/utils/useInfiniteScrollListing.ts +4 -1
  165. package/src/Graph/LineChart/BasicComponents/LoadingProgress.tsx +0 -46
  166. package/src/Graph/LineChart/InteractiveComponents/AnchorPoint/TooltipAnchorPoint.tsx +0 -96
  167. package/src/Graph/LineChart/InteractiveComponents/AnchorPoint/useTooltipAnchorPoint.ts +0 -107
  168. package/src/Graph/LineChart/Legend/InteractiveValue.tsx +0 -22
  169. package/src/Graph/LineChart/Legend/useInteractiveValues.ts +0 -99
  170. package/src/Typography/FluidTypography/useFluidResizeObserver.ts +0 -56
  171. package/src/components/Form/AccessRights/AccessRights.resource.ts +0 -45
  172. package/src/components/Form/AccessRights/AccessRightsForm.stories.tsx +0 -59
  173. package/src/components/Form/AccessRights/AccessRightsForm.styles.ts +0 -21
  174. package/src/components/Form/AccessRights/AccessRightsForm.tsx +0 -67
  175. package/src/components/Form/AccessRights/AccessRightsFormActions.tsx +0 -80
  176. package/src/components/Form/AccessRights/Input/AddAction.tsx +0 -31
  177. package/src/components/Form/AccessRights/Input/ContactAccessRightInput.stories.tsx +0 -54
  178. package/src/components/Form/AccessRights/Input/ContactAccessRightInput.tsx +0 -72
  179. package/src/components/Form/AccessRights/Input/ContactAccessRightsInput.styles.ts +0 -22
  180. package/src/components/Form/AccessRights/Input/ContactInputField.tsx +0 -105
  181. package/src/components/Form/AccessRights/Input/RoleInputField.tsx +0 -29
  182. package/src/components/Form/AccessRights/List/ContactAccessRightsList.stories.tsx +0 -97
  183. package/src/components/Form/AccessRights/List/ContactAccessRightsList.styles.ts +0 -71
  184. package/src/components/Form/AccessRights/List/ContactAccessRightsList.tsx +0 -51
  185. package/src/components/Form/AccessRights/List/ContactAccessRightsListItem.stories.tsx +0 -116
  186. package/src/components/Form/AccessRights/List/ContactAccessRightsListItem.tsx +0 -118
  187. package/src/components/Form/AccessRights/List/ContactAccessRightsListItemSkeleton.tsx +0 -26
  188. package/src/components/Form/AccessRights/List/ContactAccessRightsListSkeleton.tsx +0 -28
  189. package/src/components/Form/AccessRights/Stats/AccessRightsStats.styles.ts +0 -18
  190. package/src/components/Form/AccessRights/Stats/AccessRightsStats.tsx +0 -41
  191. package/src/components/Form/AccessRights/__fixtures__/contactAccessRight.mock.ts +0 -54
  192. package/src/components/Form/AccessRights/common/GroupLabel.styles.ts +0 -18
  193. package/src/components/Form/AccessRights/common/GroupLabel.tsx +0 -15
  194. package/src/components/Form/AccessRights/common/Input.styles.ts +0 -48
  195. package/src/components/Form/AccessRights/common/RoleInputSelect.styles.ts +0 -11
  196. package/src/components/Form/AccessRights/common/RoleInputSelect.tsx +0 -57
  197. package/src/components/Form/AccessRights/index.ts +0 -3
  198. package/src/components/Form/AccessRights/useAccessRightsForm.test.tsx +0 -531
  199. package/src/components/Form/AccessRights/useAccessRightsForm.tsx +0 -282
  200. package/src/components/Form/AccessRights/useAccessRightsForm.utils.ts +0 -41
  201. /package/src/components/Form/{AccessRightsV2 → AccessRights}/AccessRights.stories.tsx +0 -0
  202. /package/src/components/Form/{AccessRightsV2 → AccessRights}/AccessRights.styles.ts +0 -0
  203. /package/src/components/Form/{AccessRightsV2 → AccessRights}/AccessRights.tsx +0 -0
  204. /package/src/components/Form/{AccessRightsV2 → AccessRights}/Actions/Actions.styles.ts +0 -0
  205. /package/src/components/Form/{AccessRightsV2 → AccessRights}/Actions/Actions.tsx +0 -0
  206. /package/src/components/Form/{AccessRightsV2 → AccessRights}/Actions/useActions.ts +0 -0
  207. /package/src/components/Form/{AccessRightsV2 → AccessRights}/List/Item.tsx +0 -0
  208. /package/src/components/Form/{AccessRightsV2 → AccessRights}/List/List.styles.tsx +0 -0
  209. /package/src/components/Form/{AccessRightsV2 → AccessRights}/List/List.tsx +0 -0
  210. /package/src/components/Form/{AccessRightsV2 → AccessRights}/List/ListItemSkeleton.tsx +0 -0
  211. /package/src/components/Form/{AccessRightsV2 → AccessRights}/List/ListSkeleton.tsx +0 -0
  212. /package/src/components/Form/{AccessRightsV2 → AccessRights}/List/RemoveAccessRight.tsx +0 -0
  213. /package/src/components/Form/{AccessRightsV2 → AccessRights}/List/StateChip.tsx +0 -0
  214. /package/src/components/Form/{AccessRightsV2 → AccessRights}/List/useItem.ts +0 -0
  215. /package/src/components/Form/{AccessRightsV2 → AccessRights}/Provider.tsx +0 -0
  216. /package/src/components/Form/{AccessRightsV2 → AccessRights}/Stats/Stats.tsx +0 -0
  217. /package/src/components/Form/{AccessRightsV2 → AccessRights}/atoms.ts +0 -0
  218. /package/src/components/Form/{AccessRightsV2 → AccessRights}/common/RoleSelectField.styles.tsx +0 -0
  219. /package/src/components/Form/{AccessRightsV2 → AccessRights}/common/RoleSelectField.tsx +0 -0
  220. /package/src/components/Form/{AccessRightsV2 → AccessRights}/useAccessRightsInitValues.ts +0 -0
@@ -0,0 +1,102 @@
1
+ import dataLastWeek from '../LineChart/mockedData/lastWeek.json';
2
+ import {
3
+ criticalThresholds,
4
+ rangedThresholds,
5
+ successThresholds,
6
+ warningThresholds
7
+ } from '../common/testUtils';
8
+
9
+ import { Props, Gauge } from './Gauge';
10
+
11
+ const initialize = (
12
+ args: Omit<Props, 'data' | 'labels' | 'baseColor'>
13
+ ): void => {
14
+ cy.mount({
15
+ Component: (
16
+ <div style={{ height: '100vh', width: '100vw' }}>
17
+ <Gauge
18
+ baseColor="#000"
19
+ data={dataLastWeek}
20
+ labels={{
21
+ critical: 'Critical',
22
+ warning: 'Warning'
23
+ }}
24
+ {...args}
25
+ />
26
+ </div>
27
+ )
28
+ });
29
+ };
30
+
31
+ describe('Gauge', () => {
32
+ it('does not display the gauge when there is no data', () => {
33
+ initialize({ data: undefined, thresholds: successThresholds });
34
+
35
+ cy.contains('0.41 s').should('not.exist');
36
+ });
37
+
38
+ it('displays the gauge as success when corresponding thresholds are set', () => {
39
+ initialize({ thresholds: successThresholds });
40
+
41
+ cy.contains('0.41 s').should('have.css', 'fill', 'rgb(136, 185, 34)');
42
+ cy.findByTestId('1.1500000000000001-arc').should('be.visible');
43
+ cy.findByTestId('0.15000000000000013-arc').should('be.visible');
44
+
45
+ cy.makeSnapshot();
46
+ });
47
+
48
+ it('displays the gauge as warning when corresponding thresholds are set', () => {
49
+ initialize({ thresholds: warningThresholds });
50
+
51
+ cy.contains('0.41 s').should('have.css', 'fill', 'rgb(253, 155, 39)');
52
+ cy.findByTestId('1.25-arc').should('be.visible');
53
+ cy.findByTestId('0.15000000000000013-arc').should('be.visible');
54
+
55
+ cy.makeSnapshot();
56
+ });
57
+
58
+ it('displays the gauge as critical when corresponding thresholds are set', () => {
59
+ initialize({ thresholds: criticalThresholds });
60
+
61
+ cy.contains('0.41 s').should('have.css', 'fill', 'rgb(255, 74, 74)');
62
+ cy.findByTestId('0.6399999999999999-arc').should('be.visible');
63
+ cy.findByTestId('0.54-arc').should('be.visible');
64
+
65
+ cy.makeSnapshot();
66
+ });
67
+
68
+ it('displays ranged thresholds', () => {
69
+ initialize({ thresholds: rangedThresholds });
70
+
71
+ cy.findByTestId('0.37-arc').should('be.visible');
72
+ cy.findByTestId('0.09999999999999998-arc').should('be.visible');
73
+
74
+ cy.makeSnapshot();
75
+ });
76
+
77
+ it('displays the threshold tooltip when a threshold is hovered', () => {
78
+ initialize({ thresholds: successThresholds });
79
+
80
+ cy.findByTestId('1.1500000000000001-arc').trigger('mouseover', {
81
+ force: true
82
+ });
83
+
84
+ cy.contains('Warning').should('be.visible');
85
+
86
+ cy.findByTestId('0.15000000000000013-arc').trigger('mouseover', {
87
+ force: true
88
+ });
89
+
90
+ cy.contains('Critical').should('be.visible');
91
+
92
+ cy.makeSnapshot();
93
+ });
94
+
95
+ it('displays the value as raw when the prop is set', () => {
96
+ initialize({ displayAsRaw: true, thresholds: successThresholds });
97
+
98
+ cy.contains('0.40663333333 s').should('be.visible');
99
+
100
+ cy.makeSnapshot();
101
+ });
102
+ });
@@ -5,7 +5,7 @@ import { Metric } from '../common/timeSeries/models';
5
5
 
6
6
  import ResponsiveGauge from './ResponsiveGauge';
7
7
 
8
- interface Props {
8
+ export interface Props {
9
9
  baseColor?: string;
10
10
  data?: LineChartData;
11
11
  displayAsRaw?: boolean;
@@ -0,0 +1,145 @@
1
+ import { pluck } from 'ramda';
2
+
3
+ import { Box, Typography } from '@mui/material';
4
+
5
+ import EllipsisTypography from '../../Typography/EllipsisTypography';
6
+
7
+ import HeatMap from './HeatMap';
8
+ import heatMapData from './HeatMapData.json';
9
+ import { HeatMapProps } from './model';
10
+
11
+ const dataIds = pluck('id', heatMapData);
12
+
13
+ interface Data {
14
+ counter: number;
15
+ host: string;
16
+ service: string;
17
+ }
18
+
19
+ const TileContent = ({
20
+ isSmallestSize,
21
+ data
22
+ }: {
23
+ data: Data;
24
+ isSmallestSize: boolean;
25
+ }): JSX.Element | false =>
26
+ !isSmallestSize && (
27
+ <Box
28
+ sx={{
29
+ alignItems: 'center',
30
+ color: 'common.black',
31
+ display: 'flex',
32
+ flexDirection: 'column',
33
+ width: '100%'
34
+ }}
35
+ >
36
+ <EllipsisTypography textAlign="center">{data.host}</EllipsisTypography>
37
+ <EllipsisTypography textAlign="center">{data.service}</EllipsisTypography>
38
+ <EllipsisTypography textAlign="center">{data.counter}</EllipsisTypography>
39
+ </Box>
40
+ );
41
+
42
+ const initialize = ({
43
+ width = '100vw',
44
+ height = '100vh',
45
+ ...args
46
+ }: Omit<HeatMapProps<Data>, 'tiles' | 'children'> & {
47
+ height?: string;
48
+ width?: string;
49
+ }): void => {
50
+ cy.mount({
51
+ Component: (
52
+ <div style={{ height, width }}>
53
+ <HeatMap tiles={heatMapData} {...args}>
54
+ {TileContent}
55
+ </HeatMap>
56
+ </div>
57
+ )
58
+ });
59
+ };
60
+
61
+ describe('HeatMap', () => {
62
+ it('displays tiles', () => {
63
+ initialize({});
64
+ dataIds.forEach((id) => {
65
+ cy.findByTestId(id).should('be.visible');
66
+ });
67
+ });
68
+
69
+ it('does not display the tooltip when the prop is not set and the tile is hovered', () => {
70
+ initialize({});
71
+
72
+ cy.findByTestId(dataIds[0]).trigger('mouseover');
73
+
74
+ cy.findByTestId(`tooltip-${dataIds[0]}`).should('not.exist');
75
+ });
76
+
77
+ it('displays the tooltip when the prop is set and the tile is hovered', () => {
78
+ initialize({
79
+ tooltipContent: ({ data }) => (
80
+ <Typography>
81
+ This is the tooltip for {data.host}-{data.service}-{data.counter}
82
+ </Typography>
83
+ )
84
+ });
85
+
86
+ cy.findByTestId(dataIds[0]).trigger('mouseover');
87
+
88
+ cy.contains(`This is the tooltip for Server-Service Counter-53`).should(
89
+ 'be.visible'
90
+ );
91
+ });
92
+
93
+ it('displays the tooltip conditionally when the prop is set and the tile is hovered', () => {
94
+ initialize({
95
+ displayTooltipCondition: ({ counter }) => counter > 100,
96
+ tooltipContent: ({ data }) => (
97
+ <Typography>
98
+ This is the tooltip for {data.host}-{data.service}-{data.counter}
99
+ </Typography>
100
+ )
101
+ });
102
+
103
+ cy.findByTestId(dataIds[0]).trigger('mouseover');
104
+
105
+ cy.contains(`This is the tooltip for Server-Service Counter-53`).should(
106
+ 'not.exist'
107
+ );
108
+
109
+ cy.findByTestId(dataIds[1]).trigger('mouseover');
110
+
111
+ cy.contains(`This is the tooltip for Server-Service Counter-779`).should(
112
+ 'be.visible'
113
+ );
114
+ });
115
+
116
+ it('displays tiles with fixed size', () => {
117
+ initialize({ height: '200px', tileSizeFixed: true, width: '590px' });
118
+ dataIds.forEach((id) => {
119
+ cy.findByTestId(id).should('be.visible');
120
+ });
121
+ });
122
+
123
+ it('displays tiles as small when the container width is under the breakpoint', () => {
124
+ initialize({ height: '200px', width: '590px' });
125
+ dataIds.forEach((id) => {
126
+ cy.findByTestId(id).should('be.visible');
127
+ });
128
+
129
+ cy.makeSnapshot();
130
+ });
131
+
132
+ it('does not display tiles as small when the contains width is 0', () => {
133
+ initialize({ height: '200px', width: '0px' });
134
+ dataIds.forEach((id) => {
135
+ cy.findByTestId(id).should('not.exist');
136
+ });
137
+
138
+ cy.makeSnapshot();
139
+ });
140
+
141
+ it('displays a single tile', () => {
142
+ initialize({ tiles: [heatMapData[0]] });
143
+ cy.findByTestId(dataIds[0]).should('be.visible');
144
+ });
145
+ });
@@ -3,8 +3,6 @@ import { makeStyles } from 'tss-react/mui';
3
3
 
4
4
  import { Box, Typography } from '@mui/material';
5
5
 
6
- import EllipsisTypography from '../../Typography/EllipsisTypography';
7
-
8
6
  import heatMapData from './HeatMapData.json';
9
7
 
10
8
  import { HeatMap } from '.';
@@ -22,29 +20,6 @@ const meta: Meta<typeof HeatMap<Data>> = {
22
20
  export default meta;
23
21
  type Story = StoryObj<typeof HeatMap<Data>>;
24
22
 
25
- const TileContent = ({
26
- isSmallestSize,
27
- data
28
- }: {
29
- data: Data;
30
- isSmallestSize: boolean;
31
- }): JSX.Element | false =>
32
- !isSmallestSize && (
33
- <Box
34
- sx={{
35
- alignItems: 'center',
36
- color: 'common.black',
37
- display: 'flex',
38
- flexDirection: 'column',
39
- width: '100%'
40
- }}
41
- >
42
- <EllipsisTypography textAlign="center">{data.host}</EllipsisTypography>
43
- <EllipsisTypography textAlign="center">{data.service}</EllipsisTypography>
44
- <EllipsisTypography textAlign="center">{data.counter}</EllipsisTypography>
45
- </Box>
46
- );
47
-
48
23
  const TooltipContent = ({ data }: { data: Data }): JSX.Element => {
49
24
  return (
50
25
  <Box sx={{ backgroundColor: 'common.white', color: 'common.black' }}>
@@ -40,7 +40,7 @@ const ResponsiveHeatMap = <TData,>({
40
40
  const theoricalTotalTilesWidth =
41
41
  tilesLength * tileWidth + (tilesLength - 1) * gap;
42
42
 
43
- if (lt(width, 680) && gt(maxTotalTilesWidth, width)) {
43
+ if (lt(width, 680) && gt(maxTotalTilesWidth, width) && !tileSizeFixed) {
44
44
  return smallestTileSize;
45
45
  }
46
46
 
@@ -66,13 +66,19 @@ const ResponsiveHeatMap = <TData,>({
66
66
  }}
67
67
  >
68
68
  {tiles.map(({ backgroundColor, id, data }) => (
69
- <Box className={classes.heatMapTile} key={id} sx={{ backgroundColor }}>
69
+ <Box
70
+ className={classes.heatMapTile}
71
+ data-testid={id}
72
+ key={id}
73
+ sx={{ backgroundColor }}
74
+ >
70
75
  <Tooltip
71
76
  hasCaret
72
77
  classes={{
73
78
  arrow: cx(classes.heatMapTooltipArrow, arrowClassName),
74
79
  tooltip: classes.heatMapTooltip
75
80
  }}
81
+ data-testid={`tooltip-${data?.id}`}
76
82
  followCursor={false}
77
83
  label={
78
84
  displayTooltipCondition?.(data) &&
@@ -0,0 +1,21 @@
1
+ import { LegendOrdinal } from '@visx/legend';
2
+ import { scaleOrdinal } from '@visx/scale';
3
+
4
+ import { LegendProps } from './models';
5
+
6
+ const Legend = ({ scale, direction = 'column' }: LegendProps): JSX.Element => {
7
+ const legendScale = scaleOrdinal({
8
+ domain: scale.domain,
9
+ range: scale.range
10
+ });
11
+
12
+ return (
13
+ <LegendOrdinal
14
+ direction={direction}
15
+ labelMargin="0 16px 0 0"
16
+ scale={legendScale}
17
+ />
18
+ );
19
+ };
20
+
21
+ export default Legend;
@@ -0,0 +1 @@
1
+ export { default as Legend } from './Legend';
@@ -0,0 +1,11 @@
1
+ export type LegendDirection = 'row' | 'column';
2
+
3
+ export interface LegendScale {
4
+ domain: Array<number | string>;
5
+ range: Array<string>;
6
+ }
7
+
8
+ export interface LegendProps {
9
+ direction?: LegendDirection;
10
+ scale: LegendScale;
11
+ }
@@ -130,11 +130,10 @@ const WrapperThresholdLines = ({
130
130
 
131
131
  return (
132
132
  <g>
133
- {filteredThresholdLines.map(
134
- (element) =>
135
- element?.map(({ Component, props, key }) => (
136
- <Component {...props} id={key} key={key} />
137
- ))
133
+ {filteredThresholdLines.map((element) =>
134
+ element?.map(({ Component, props, key }) => (
135
+ <Component {...props} id={key} key={key} />
136
+ ))
138
137
  )}
139
138
  </g>
140
139
  );
@@ -2,6 +2,8 @@ import { equals } from 'ramda';
2
2
 
3
3
  import { useTheme } from '@mui/material';
4
4
 
5
+ import { margin } from '../common';
6
+
5
7
  interface Props {
6
8
  hideTooltip: () => void;
7
9
  label: string;
@@ -28,7 +30,7 @@ export const ThresholdLine = ({
28
30
  const onMouseEnter = (): void =>
29
31
  showTooltip({
30
32
  tooltipData: label,
31
- tooltipLeft: 0,
33
+ tooltipLeft: -(margin.left + margin.right),
32
34
  tooltipTop: scaledValue
33
35
  });
34
36
 
@@ -1,41 +1,17 @@
1
- import { ScaleLinear } from 'd3-scale';
2
- import { isNil } from 'ramda';
3
-
4
1
  import Typography from '@mui/material/Typography';
5
2
 
6
- import { useLocaleDateTimeFormat, useMemoComponent } from '@centreon/ui';
3
+ import { useMemoComponent } from '@centreon/ui';
7
4
 
8
5
  import { useStyles } from '../LineChart.styles';
9
- import useTickGraph from '../InteractiveComponents/AnchorPoint/useTickGraph';
10
6
  import { LineChartHeader } from '../models';
11
- import { TimeValue } from '../../common/timeSeries/models';
12
7
 
13
8
  interface Props {
14
- displayTimeTick?: boolean;
15
9
  header?: LineChartHeader;
16
- timeSeries: Array<TimeValue>;
17
10
  title: string;
18
- xScale: ScaleLinear<number, number>;
19
11
  }
20
12
 
21
- const Header = ({
22
- title,
23
- displayTimeTick = true,
24
- header,
25
- timeSeries,
26
- xScale
27
- }: Props): JSX.Element => {
13
+ const Header = ({ title, header }: Props): JSX.Element => {
28
14
  const { classes } = useStyles();
29
- const { toDateTime } = useLocaleDateTimeFormat();
30
-
31
- const { tickAxisBottom } = useTickGraph({
32
- timeSeries,
33
- xScale
34
- });
35
- const time =
36
- displayTimeTick && !isNil(tickAxisBottom)
37
- ? toDateTime(tickAxisBottom)
38
- : null;
39
15
 
40
16
  const displayTitle = header?.displayTitle ?? true;
41
17
 
@@ -49,16 +25,12 @@ const Header = ({
49
25
  {title}
50
26
  </Typography>
51
27
  )}
52
-
53
- <Typography align="center" style={{ height: 20 }} variant="body1">
54
- {time}
55
- </Typography>
56
28
  </div>
57
29
  {header?.extraComponent}
58
30
  </div>
59
31
  ),
60
32
 
61
- memoProps: [time, timeSeries, xScale, displayTimeTick, title, header]
33
+ memoProps: [title, header]
62
34
  });
63
35
  };
64
36
 
@@ -2,13 +2,12 @@ import { useEffect, useState } from 'react';
2
2
 
3
3
  import { ScaleLinear } from 'd3-scale';
4
4
  import { useAtomValue } from 'jotai';
5
- import { isEmpty, isNil, not } from 'ramda';
6
5
 
7
6
  import useAxisY from '../../BasicComponents/Axes/useAxisY';
8
7
  import { margin } from '../../common';
9
- import { getMetrics, getTimeValue } from '../../../common/timeSeries';
8
+ import { getTimeValue } from '../../../common/timeSeries';
10
9
  import { Line, TimeValue } from '../../../common/timeSeries/models';
11
- import { mousePositionAtom, timeValueAtom } from '../interactionWithGraphAtoms';
10
+ import { mousePositionAtom } from '../interactionWithGraphAtoms';
12
11
 
13
12
  interface AnchorPointResult {
14
13
  positionX?: number;
@@ -42,14 +41,13 @@ const useTickGraph = ({
42
41
  const { axisRight, axisLeft } = useAxisY({ data: { baseAxis, lines } });
43
42
 
44
43
  const mousePosition = useAtomValue(mousePositionAtom);
45
- const timeValueData = useAtomValue(timeValueAtom);
46
44
 
47
- const metrics = getMetrics(timeValueData as TimeValue);
48
-
49
- const containsMetrics = not(isNil(metrics)) && not(isEmpty(metrics));
50
-
51
- const positionX = mousePosition ? mousePosition[0] - margin.left : undefined;
52
- const positionY = mousePosition ? mousePosition[1] - margin.top : undefined;
45
+ const positionX = mousePosition
46
+ ? mousePosition[0] - margin.left - 4
47
+ : undefined;
48
+ const positionY = mousePosition
49
+ ? mousePosition[1] - margin.top + 2
50
+ : undefined;
53
51
 
54
52
  useEffect(() => {
55
53
  if (!mousePosition) {
@@ -62,7 +60,7 @@ const useTickGraph = ({
62
60
  const mousePositionTimeTick = mousePosition
63
61
  ? getTimeValue({ timeSeries, x: mousePosition[0], xScale }).timeTick
64
62
  : 0;
65
- const timeTickValue = containsMetrics
63
+ const timeTickValue = mousePosition
66
64
  ? new Date(mousePositionTimeTick)
67
65
  : null;
68
66
 
@@ -43,8 +43,9 @@ const Annotation = ({
43
43
 
44
44
  const setAnnotationHovered = useSetAtom(annotationHoveredAtom);
45
45
 
46
- const content = `${truncate(event.content)} (${t(labelBy)} ${event.contact
47
- ?.name})`;
46
+ const content = `${truncate(event.content)} (${t(labelBy)} ${
47
+ event.contact?.name
48
+ })`;
48
49
 
49
50
  return (
50
51
  <g>
@@ -0,0 +1,68 @@
1
+ import { useAtomValue } from 'jotai';
2
+ import { equals, isNil } from 'ramda';
3
+
4
+ import { Box, Typography } from '@mui/material';
5
+
6
+ import { mousePositionAtom } from '../interactionWithGraphAtoms';
7
+ import { formatMetricValueWithUnit } from '../../../common/timeSeries';
8
+
9
+ import { useGraphValueTooltip } from './useGraphValueTooltip';
10
+ import { useGraphValueTooltipStyles } from './useGraphValueTooltipStyles';
11
+
12
+ interface Props {
13
+ base: number;
14
+ }
15
+
16
+ const GraphValueTooltip = ({ base }: Props): JSX.Element | null => {
17
+ const { classes } = useGraphValueTooltipStyles();
18
+ const mousePosition = useAtomValue(mousePositionAtom);
19
+
20
+ const graphValue = useGraphValueTooltip();
21
+
22
+ if (isNil(graphValue) || isNil(mousePosition)) {
23
+ return null;
24
+ }
25
+
26
+ return (
27
+ <div className={classes.tooltipContainer}>
28
+ <Typography fontWeight="bold">{graphValue.dateTime}</Typography>
29
+ <div className={classes.metrics}>
30
+ {graphValue.metrics.map(({ unit, color, id, value, name }) => {
31
+ const isMetricHighlighted = equals(
32
+ id,
33
+ graphValue.highlightedMetricId
34
+ );
35
+
36
+ return (
37
+ <div
38
+ className={classes.metric}
39
+ data-highlight={isMetricHighlighted}
40
+ data-metric={name}
41
+ key={id}
42
+ >
43
+ <Box
44
+ className={classes.metricColorBox}
45
+ sx={{ backgroundColor: color }}
46
+ />
47
+ <Typography
48
+ className={classes.metricName}
49
+ fontWeight={isMetricHighlighted ? 'bold' : undefined}
50
+ >
51
+ {name}
52
+ </Typography>
53
+ <Typography fontWeight={isMetricHighlighted ? 'bold' : undefined}>
54
+ {formatMetricValueWithUnit({
55
+ base,
56
+ unit,
57
+ value
58
+ })}
59
+ </Typography>
60
+ </div>
61
+ );
62
+ })}
63
+ </div>
64
+ </div>
65
+ );
66
+ };
67
+
68
+ export default GraphValueTooltip;
@@ -0,0 +1,27 @@
1
+ import { useAtomValue } from 'jotai';
2
+ import { isNil } from 'ramda';
3
+
4
+ import { graphTooltipDataAtom } from '../interactionWithGraphAtoms';
5
+ import { useLocaleDateTimeFormat } from '../../../../utils';
6
+ import { GraphTooltipData } from '../../models';
7
+
8
+ interface UseGraphValueTooltipState extends Omit<GraphTooltipData, 'date'> {
9
+ dateTime: string;
10
+ }
11
+
12
+ export const useGraphValueTooltip = (): UseGraphValueTooltipState | null => {
13
+ const { toDate, toTime } = useLocaleDateTimeFormat();
14
+ const graphTooltipData = useAtomValue(graphTooltipDataAtom);
15
+
16
+ if (isNil(graphTooltipData)) {
17
+ return null;
18
+ }
19
+
20
+ const formattedDateTime = `${toDate(graphTooltipData.date)} / ${toTime(graphTooltipData.date)}`;
21
+
22
+ return {
23
+ dateTime: formattedDateTime,
24
+ highlightedMetricId: graphTooltipData.highlightedMetricId,
25
+ metrics: graphTooltipData.metrics
26
+ };
27
+ };
@@ -0,0 +1,31 @@
1
+ import { makeStyles } from 'tss-react/mui';
2
+
3
+ export const useGraphValueTooltipStyles = makeStyles()((theme) => ({
4
+ dateTimeLabel: {
5
+ fontSize: '1.1rem'
6
+ },
7
+ metric: {
8
+ alignItems: 'center',
9
+ display: 'flex',
10
+ gap: theme.spacing(1),
11
+ weidth: '100%'
12
+ },
13
+ metricColorBox: {
14
+ borderRadius: theme.shape.borderRadius,
15
+ flexShrink: 0,
16
+ height: theme.spacing(1.5),
17
+ width: theme.spacing(1.5)
18
+ },
19
+ metricName: {
20
+ flexGrow: 1
21
+ },
22
+ metrics: {
23
+ display: 'flex',
24
+ flexDirection: 'column',
25
+ marginTop: theme.spacing(0.5),
26
+ width: '100%'
27
+ },
28
+ tooltipContainer: {
29
+ padding: theme.spacing(1)
30
+ }
31
+ }));