@centreon/ui 24.4.59 → 24.4.61

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 (163) hide show
  1. package/package.json +50 -42
  2. package/public/mockServiceWorker.js +1 -1
  3. package/src/ActionsList/ActionsList.styles.ts +40 -71
  4. package/src/Button/Icon/index.tsx +1 -1
  5. package/src/Button/Save/StartIcon.tsx +3 -3
  6. package/src/Button/Save/index.tsx +9 -5
  7. package/src/Checkbox/Checkbox.tsx +2 -2
  8. package/src/Checkbox/CheckboxGroup/index.tsx +2 -2
  9. package/src/Dashboard/Item.tsx +1 -1
  10. package/src/Dashboard/Layout.tsx +2 -2
  11. package/src/Dialog/Confirm/index.tsx +10 -2
  12. package/src/Dialog/UnsavedChanges/index.tsx +21 -20
  13. package/src/Dialog/UnsavedChanges/translatedLabels.ts +4 -6
  14. package/src/Dialog/index.tsx +9 -2
  15. package/src/FallbackPage/FallbackPage.tsx +3 -3
  16. package/src/FileDropZone/index.tsx +3 -1
  17. package/src/Form/Form.cypress.spec.tsx +133 -0
  18. package/src/Form/Inputs/List/Content.tsx +62 -0
  19. package/src/Form/Inputs/List/List.styles.ts +29 -0
  20. package/src/Form/Inputs/List/List.tsx +58 -0
  21. package/src/Form/Inputs/List/useList.ts +81 -0
  22. package/src/Form/Inputs/Text.tsx +3 -1
  23. package/src/Form/Inputs/index.tsx +3 -1
  24. package/src/Form/Inputs/models.ts +10 -1
  25. package/src/Graph/BarStack/BarStack.cypress.spec.tsx +154 -0
  26. package/src/Graph/BarStack/BarStack.stories.tsx +123 -0
  27. package/src/Graph/BarStack/BarStack.styles.ts +37 -0
  28. package/src/Graph/BarStack/BarStack.tsx +14 -0
  29. package/src/Graph/BarStack/ResponsiveBarStack.tsx +222 -0
  30. package/src/Graph/BarStack/index.ts +1 -0
  31. package/src/Graph/BarStack/models.ts +20 -0
  32. package/src/Graph/BarStack/useResponsiveBarStack.ts +137 -0
  33. package/src/Graph/Gauge/Gauge.cypress.spec.tsx +102 -0
  34. package/src/Graph/Gauge/Gauge.tsx +1 -1
  35. package/src/Graph/HeatMap/HeatMap.cypress.spec.tsx +145 -0
  36. package/src/Graph/HeatMap/HeatMap.stories.tsx +0 -25
  37. package/src/Graph/HeatMap/ResponsiveHeatMap.tsx +8 -2
  38. package/src/Graph/Legend/Legend.tsx +21 -0
  39. package/src/Graph/Legend/index.ts +1 -0
  40. package/src/Graph/Legend/models.ts +11 -0
  41. package/src/Graph/LineChart/BasicComponents/Lines/Threshold/Circle.tsx +2 -2
  42. package/src/Graph/LineChart/BasicComponents/Thresholds.tsx +2 -2
  43. package/src/Graph/LineChart/BasicComponents/useFilterLines.ts +1 -1
  44. package/src/Graph/LineChart/InteractiveComponents/AnchorPoint/GuidingLines.tsx +2 -2
  45. package/src/Graph/LineChart/InteractiveComponents/Annotations/EventAnnotations.tsx +1 -1
  46. package/src/Graph/LineChart/Legend/Legend.styles.ts +1 -1
  47. package/src/Graph/LineChart/Legend/LegendHeader.tsx +1 -1
  48. package/src/Graph/LineChart/Legend/useInteractiveValues.ts +2 -2
  49. package/src/Graph/LineChart/Legend/useLegend.ts +3 -3
  50. package/src/Graph/LineChart/helpers/doc.ts +16 -13
  51. package/src/Graph/LineChart/helpers/index.ts +1 -1
  52. package/src/Graph/LineChart/index.stories.tsx +4 -2
  53. package/src/Graph/LineChart/index.tsx +1 -1
  54. package/src/Graph/PieChart/PieChart.cypress.spec.tsx +169 -0
  55. package/src/Graph/PieChart/PieChart.stories.tsx +194 -0
  56. package/src/Graph/PieChart/PieChart.styles.ts +39 -0
  57. package/src/Graph/PieChart/PieChart.tsx +14 -0
  58. package/src/Graph/PieChart/ResponsivePie.tsx +254 -0
  59. package/src/Graph/PieChart/index.ts +1 -0
  60. package/src/Graph/PieChart/models.ts +20 -0
  61. package/src/Graph/PieChart/useResponsivePie.ts +85 -0
  62. package/src/Graph/SingleBar/SingleBar.cypress.spec.tsx +121 -0
  63. package/src/Graph/SingleBar/Thresholds.tsx +2 -2
  64. package/src/Graph/Text/Text.cypress.spec.tsx +101 -0
  65. package/src/Graph/Text/Text.stories.tsx +60 -4
  66. package/src/Graph/Text/Text.tsx +1 -1
  67. package/src/Graph/common/testUtils.ts +71 -0
  68. package/src/Graph/common/timeSeries/index.ts +22 -14
  69. package/src/Graph/common/utils.ts +19 -0
  70. package/src/Graph/index.ts +3 -0
  71. package/src/Graph/translatedLabels.ts +1 -0
  72. package/src/InputField/Select/Autocomplete/Connected/index.tsx +10 -7
  73. package/src/InputField/Select/Autocomplete/Draggable/SortableList.tsx +1 -1
  74. package/src/InputField/Select/Autocomplete/Draggable/SortableListContent.tsx +1 -1
  75. package/src/InputField/Select/Autocomplete/Draggable/index.tsx +1 -1
  76. package/src/InputField/Select/Autocomplete/Multi/index.tsx +4 -2
  77. package/src/InputField/Select/Autocomplete/index.tsx +129 -116
  78. package/src/InputField/Select/IconPopover/index.tsx +2 -2
  79. package/src/InputField/Select/index.tsx +15 -2
  80. package/src/InputField/Text/index.tsx +2 -2
  81. package/src/Listing/ActionBar/index.tsx +9 -8
  82. package/src/Listing/Cell/DataCell.styles.ts +3 -0
  83. package/src/Listing/Cell/DataCell.tsx +23 -5
  84. package/src/Listing/Header/ListingHeader.tsx +1 -1
  85. package/src/Listing/Listing.cypress.spec.tsx +218 -33
  86. package/src/Listing/Listing.styles.ts +4 -7
  87. package/src/Listing/Row/Row.tsx +7 -3
  88. package/src/Listing/index.stories.tsx +37 -3
  89. package/src/Listing/index.test.tsx +1 -1
  90. package/src/Listing/index.tsx +80 -36
  91. package/src/Listing/models.ts +1 -0
  92. package/src/Listing/useStyleTable.ts +1 -0
  93. package/src/Module/Module.cypress.spec.tsx +129 -0
  94. package/src/Module/index.tsx +2 -4
  95. package/src/PopoverMenu/index.tsx +6 -5
  96. package/src/RichTextEditor/RichTextEditor.tsx +12 -1
  97. package/src/SortableItems/index.tsx +2 -7
  98. package/src/ThemeProvider/index.tsx +24 -0
  99. package/src/TimePeriods/CustomTimePeriod/CompactCustomTimePeriod.styles.ts +6 -7
  100. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/PickersStartEndDate.tsx +8 -3
  101. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/models.ts +0 -2
  102. package/src/TimePeriods/DateTimePickerInput.tsx +56 -19
  103. package/src/TimePeriods/ResolutionTimePeriod.cypress.spec.tsx +12 -9
  104. package/src/TimePeriods/TimePeriods.cypress.spec.tsx +9 -33
  105. package/src/TimePeriods/helpers/index.ts +1 -1
  106. package/src/TimePeriods/index.stories.tsx +12 -4
  107. package/src/TimePeriods/index.tsx +2 -2
  108. package/src/Typography/FluidTypography/FluidTypography.cypress.spec.tsx +27 -0
  109. package/src/Typography/FluidTypography/index.stories.tsx +2 -2
  110. package/src/Typography/FluidTypography/index.tsx +21 -28
  111. package/src/api/QueryProvider.tsx +1 -1
  112. package/src/api/TestQueryProvider.tsx +1 -1
  113. package/src/api/index.ts +3 -3
  114. package/src/api/useFetchQuery/index.ts +27 -23
  115. package/src/api/useMutationQuery/index.test.ts +4 -4
  116. package/src/api/useMutationQuery/index.ts +60 -25
  117. package/src/components/Button/Icon/IconButton.tsx +6 -2
  118. package/src/components/DataTable/DataListing.tsx +6 -0
  119. package/src/components/DataTable/DataTable.cypress.spec.tsx +174 -0
  120. package/src/components/DataTable/DataTable.stories.tsx +40 -0
  121. package/src/components/DataTable/DataTable.styles.ts +3 -0
  122. package/src/components/DataTable/DataTable.tsx +3 -3
  123. package/src/components/DataTable/Item/DataTableItem.styles.ts +7 -2
  124. package/src/components/DataTable/Item/DataTableItem.tsx +4 -60
  125. package/src/components/DataTable/index.ts +3 -1
  126. package/src/components/Form/AccessRights/AccessRights.cypress.spec.tsx +13 -13
  127. package/src/components/Form/AccessRights/ShareInput/ContactSwitch.tsx +3 -3
  128. package/src/components/Form/AccessRights/ShareInput/ShareInput.tsx +1 -0
  129. package/src/components/Form/AccessRights/storiesData.ts +22 -22
  130. package/src/components/Form/Dashboard/DashboardDuplicationForm.tsx +85 -0
  131. package/src/components/Form/Dashboard/DashboardForm.tsx +15 -12
  132. package/src/components/Form/Dashboard/index.ts +1 -0
  133. package/src/components/Form/FormActions.tsx +7 -2
  134. package/src/components/ItemComposition/ItemComposition.styles.ts +2 -2
  135. package/src/components/Layout/PageLayout/PageLayout.tsx +1 -1
  136. package/src/components/Layout/PageLayout/PageLayoutActions.tsx +1 -0
  137. package/src/components/Layout/PageLayout/PageLayoutBody.tsx +1 -0
  138. package/src/components/Layout/PageLayout/PageLayoutHeader.tsx +5 -1
  139. package/src/components/Layout/PageLayout/PageQuickAccess.tsx +76 -0
  140. package/src/components/Layout/PageLayout/index.ts +3 -1
  141. package/src/components/Layout/PageLayout.cypress.spec.tsx +66 -0
  142. package/src/components/List/Item/ListItem.tsx +3 -3
  143. package/src/components/Modal/ConfirmationModal/ConfirmationModal.cypress.spec.tsx +168 -0
  144. package/src/components/Modal/ConfirmationModal/ConfirmationModal.stories.tsx +62 -0
  145. package/src/components/Modal/ConfirmationModal/ConfirmationModal.tsx +87 -0
  146. package/src/components/Modal/Modal.styles.ts +8 -3
  147. package/src/components/Modal/index.ts +2 -0
  148. package/src/components/Tooltip/ConfirmationTooltip/ConfirmationTooltip.stories.tsx +3 -3
  149. package/src/components/Tooltip/ConfirmationTooltip/ConfirmationTooltip.tsx +1 -1
  150. package/src/components/Tooltip/ConfirmationTooltip/models.ts +1 -1
  151. package/src/index.ts +2 -2
  152. package/src/queryParameters/url/index.ts +5 -1
  153. package/src/utils/index.ts +1 -1
  154. package/src/utils/useFullscreen/Fullscreen.cypress.spec.tsx +1 -3
  155. package/src/utils/useFullscreen/useFullscreenListener.ts +10 -7
  156. package/src/utils/useInfiniteScrollListing.ts +4 -1
  157. package/src/utils/{useLicenseExpirationWarning.cypress.spec.tsx → useLicenseExpirationWarning.test.tsx} +48 -37
  158. package/src/utils/useLicenseExpirationWarning.ts +18 -18
  159. package/src/utils/usePluralizedTranslation.ts +21 -0
  160. package/src/Typography/FluidTypography/useFluidResizeObserver.ts +0 -56
  161. package/src/screens/dashboard/DashboardsDetail.stories.tsx +0 -108
  162. package/src/screens/dashboard/DashboardsOverview.stories.tsx +0 -281
  163. package/src/utils/useDateTimePickerAdapter.ts +0 -309
@@ -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
+ }
@@ -1,7 +1,7 @@
1
1
  import { Shape } from '@visx/visx';
2
2
  import { isEmpty, isNil } from 'ramda';
3
3
 
4
- import { Circle } from './models';
4
+ import { Circle as CircleModel } from './models';
5
5
  import useCoordinateCircle from './useCoordinateCircle';
6
6
 
7
7
  const Circle = ({
@@ -11,7 +11,7 @@ const Circle = ({
11
11
  timeSeries,
12
12
  getX,
13
13
  getCountDisplayedCircles
14
- }: Circle): JSX.Element | null => {
14
+ }: CircleModel): JSX.Element | null => {
15
15
  const coordinates = useCoordinateCircle({
16
16
  getCountDisplayedCircles,
17
17
  getX,
@@ -2,7 +2,7 @@ import { equals, isNil } from 'ramda';
2
2
 
3
3
  import { getUnits, getYScale } from '../../common/timeSeries';
4
4
  import { Line } from '../../common/timeSeries/models';
5
- import { Thresholds } from '../../common/models';
5
+ import { Thresholds as ThresholdsModel } from '../../common/models';
6
6
 
7
7
  import { ThresholdLine } from './ThresholdLine';
8
8
 
@@ -13,7 +13,7 @@ interface Props {
13
13
  rightScale: (value: number) => number;
14
14
  showTooltip: (props) => void;
15
15
  thresholdUnit?: string;
16
- thresholds: Thresholds;
16
+ thresholds: ThresholdsModel;
17
17
  width: number;
18
18
  }
19
19
 
@@ -28,7 +28,7 @@ const useFilterLines = ({
28
28
  linesGraph,
29
29
  setLinesGraph
30
30
  }: UseFilterLines): Result => {
31
- const displayedLines = reject(propEq('display', false), linesGraph ?? lines);
31
+ const displayedLines = reject(propEq(false, 'display'), linesGraph ?? lines);
32
32
  const filterLines = (): Array<Line> => {
33
33
  const lineOriginMetric = findLineOfOriginMetricThreshold(lines);
34
34
 
@@ -2,7 +2,7 @@ import { Shape } from '@visx/visx';
2
2
 
3
3
  import { grey } from '@mui/material/colors';
4
4
 
5
- import { GuidingLines } from './models';
5
+ import { GuidingLines as GuidingLinesModel } from './models';
6
6
  import useTickGraph from './useTickGraph';
7
7
 
8
8
  const GuidingLines = ({
@@ -10,7 +10,7 @@ const GuidingLines = ({
10
10
  xScale,
11
11
  graphHeight,
12
12
  graphWidth
13
- }: GuidingLines): JSX.Element | null => {
13
+ }: GuidingLinesModel): JSX.Element | null => {
14
14
  const { positionX, positionY } = useTickGraph({
15
15
  timeSeries,
16
16
  xScale
@@ -26,7 +26,7 @@ const EventAnnotations = ({
26
26
  color,
27
27
  annotationHoveredId
28
28
  }: Props): JSX.Element => {
29
- const events = filter(propEq('type', type), data);
29
+ const events = filter(propEq(type, 'type'), data);
30
30
 
31
31
  return (
32
32
  <>
@@ -8,7 +8,7 @@ interface MakeStylesProps {
8
8
 
9
9
  export const legendWidth = 21;
10
10
  const legendItemHeight = 5.25;
11
- const legendItemHeightCompact = 1.75;
11
+ const legendItemHeightCompact = 2;
12
12
 
13
13
  export const useStyles = makeStyles<MakeStylesProps>()(
14
14
  (theme, { limitLegendRows }) => ({
@@ -38,7 +38,7 @@ const LegendHeader = ({
38
38
 
39
39
  const getEndText = (): string => {
40
40
  if (value) {
41
- return `${value}${hasUnit ? ` ${unit}` : ''}`;
41
+ return value;
42
42
  }
43
43
 
44
44
  return hasUnit ? ` ${unitName}` : '';
@@ -5,7 +5,7 @@ import { equals, find, isNil } from 'ramda';
5
5
 
6
6
  import { mousePositionAtom } from '../InteractiveComponents/interactionWithGraphAtoms';
7
7
  import {
8
- formatMetricValue,
8
+ formatMetricValueWithUnit,
9
9
  getLineForMetric,
10
10
  getMetrics,
11
11
  getTimeValue
@@ -73,7 +73,7 @@ const useInteractiveValues = ({
73
73
  metric_id
74
74
  }) as Line;
75
75
 
76
- const formattedValue = formatMetricValue({
76
+ const formattedValue = formatMetricValueWithUnit({
77
77
  base,
78
78
  unit,
79
79
  value
@@ -27,9 +27,9 @@ interface Props {
27
27
  }
28
28
 
29
29
  const useLegend = ({ lines, setLinesGraph }: Props): LegendActions => {
30
- const displayedLines = reject(propEq('display', false), lines);
30
+ const displayedLines = reject(propEq(false, 'display'), lines);
31
31
  const getLineByMetric = (metric_id: number): Line =>
32
- find(propEq('metric_id', metric_id), lines) as Line;
32
+ find(propEq(metric_id, 'metric_id'), lines) as Line;
33
33
 
34
34
  const toggleMetricLine = (metric_id): void => {
35
35
  const data = lines.map((line) => ({
@@ -92,7 +92,7 @@ const useLegend = ({ lines, setLinesGraph }: Props): LegendActions => {
92
92
 
93
93
  const newLines = lines.map((line) => ({
94
94
  ...line,
95
- display: find(propEq('metric_id', line.metric_id), lines)?.display ?? true
95
+ display: find(propEq(line.metric_id, 'metric_id'), lines)?.display ?? true
96
96
  }));
97
97
 
98
98
  setLinesGraph(newLines);
@@ -69,21 +69,24 @@ export const getDescription = ({ sections }: Description): string => {
69
69
  })}<br></details>`;
70
70
  }
71
71
 
72
- const formattedProps = props.reduce((accumulator, currentValue, index) => {
73
- const key = Object.keys(currentValue)[0];
74
- const { description, type } = currentValue[key];
75
- const body = `${accumulator} ${getBodyDescription({
76
- description,
77
- key,
78
- type
79
- })}`;
72
+ const formattedProps = props.reduce(
73
+ (accumulator, currentValue, index) => {
74
+ const key = Object.keys(currentValue)[0];
75
+ const { description, type } = currentValue[key];
76
+ const body = `${accumulator} ${getBodyDescription({
77
+ description,
78
+ key,
79
+ type
80
+ })}`;
80
81
 
81
- if (!equals(index, props.length - 1)) {
82
- return body;
83
- }
82
+ if (!equals(index, props.length - 1)) {
83
+ return body;
84
+ }
84
85
 
85
- return `${body}</details>`;
86
- }, getInitialValue({ section: name, type: item?.type }));
86
+ return `${body}</details>`;
87
+ },
88
+ getInitialValue({ section: name, type: item?.type })
89
+ );
87
90
 
88
91
  return formattedProps as string;
89
92
  });
@@ -14,7 +14,7 @@ import { LineChartData } from '../../common/models';
14
14
  export const adjustGraphData = (graphData: LineChartData): LinesData => {
15
15
  const lines = getLineData(graphData);
16
16
  const sortedLines = sortBy(prop('name'), lines);
17
- const displayedLines = reject(propEq('display', false), sortedLines);
17
+ const displayedLines = reject(propEq(false, 'display'), sortedLines);
18
18
 
19
19
  const timeSeries = getTimeSeries(graphData);
20
20
 
@@ -39,8 +39,7 @@ import { Interval, ThresholdType, TooltipData } from './models';
39
39
  import WrapperLineChart from './index';
40
40
 
41
41
  const meta: Meta<typeof WrapperLineChart> = {
42
- component: WrapperLineChart,
43
- tags: ['autodocs']
42
+ component: WrapperLineChart
44
43
  };
45
44
  export default meta;
46
45
 
@@ -353,6 +352,9 @@ export const LineChartWithTimePeriod: Story = {
353
352
  end: defaultEnd,
354
353
  height: 500,
355
354
  start: defaultStart
355
+ },
356
+ parameters: {
357
+ chromatic: { diffThreshold: 0.1 }
356
358
  }
357
359
  };
358
360
 
@@ -78,7 +78,7 @@ const WrapperLineChart = ({
78
78
  return (
79
79
  <div
80
80
  ref={lineChartRef as MutableRefObject<HTMLDivElement>}
81
- style={{ height: '100%', width: '100%' }}
81
+ style={{ height: '100%', overflowY: 'hidden', width: '100%' }}
82
82
  >
83
83
  <ParentSize>
84
84
  {({
@@ -0,0 +1,169 @@
1
+ import numeral from 'numeral';
2
+
3
+ import PieChart from './PieChart';
4
+ import { ArcType, PieProps } from './models';
5
+
6
+ const defaultData = [
7
+ { color: '#88B922', label: 'Ok', value: 148 },
8
+ { color: '#999999', label: 'Unknown', value: 13 },
9
+ { color: '#F7931A', label: 'Warning', value: 16 },
10
+ { color: '#FF6666', label: 'Down', value: 62 }
11
+ ];
12
+
13
+ const dataWithNullValues = [
14
+ { color: '#88B922', label: 'Ok', value: 0 },
15
+ { color: '#999999', label: 'Unknown', value: 0 },
16
+ { color: '#F7931A', label: 'Warning', value: 0 },
17
+ { color: '#FF6666', label: 'Down', value: 0 }
18
+ ];
19
+
20
+ const total = Math.floor(
21
+ defaultData.reduce((acc, { value }) => acc + value, 0)
22
+ );
23
+
24
+ const TooltipContent = ({ label, color, value }: ArcType): JSX.Element => {
25
+ return (
26
+ <div data-testid={`tooltip-${label}`} style={{ color }}>
27
+ {label} : {value}
28
+ </div>
29
+ );
30
+ };
31
+
32
+ const initialize = ({
33
+ width = '500px',
34
+ height = '500px',
35
+ data = defaultData,
36
+ ...args
37
+ }: Omit<PieProps, 'data'> & {
38
+ data?;
39
+ height?: string;
40
+ width?: string;
41
+ }): void => {
42
+ cy.mount({
43
+ Component: (
44
+ <div style={{ height, width }}>
45
+ <PieChart {...args} data={data} />
46
+ </div>
47
+ )
48
+ });
49
+ };
50
+
51
+ describe('Pie chart', () => {
52
+ it('renders pie chart correctly with provided data', () => {
53
+ initialize({});
54
+
55
+ defaultData.forEach(({ label }) => {
56
+ cy.findByTestId(label).should('be.visible');
57
+ });
58
+
59
+ cy.makeSnapshot();
60
+ });
61
+
62
+ it('adjusts size based on the provided width and height', () => {
63
+ initialize({ displayLegend: false, height: '300px', width: '300px' });
64
+
65
+ cy.findByTestId('pieChart')
66
+ .should('have.css', 'width', '300px')
67
+ .and('have.css', 'height', '300px');
68
+
69
+ cy.makeSnapshot();
70
+ });
71
+
72
+ it('renders as a donut when variant is set to "donut"', () => {
73
+ initialize({ variant: 'donut' });
74
+ cy.get('[data-variant="donut"]').should('exist');
75
+
76
+ cy.makeSnapshot();
77
+ });
78
+
79
+ it('renders as a pie when variant is set to "pie"', () => {
80
+ initialize({ variant: 'pie' });
81
+ cy.get('[data-variant="pie"]').should('exist');
82
+
83
+ cy.makeSnapshot();
84
+ });
85
+
86
+ it('displays tooltip with correct information on hover', () => {
87
+ initialize({ TooltipContent });
88
+
89
+ defaultData.forEach(({ label, value }) => {
90
+ cy.findByTestId(label).trigger('mouseover', { force: true });
91
+
92
+ cy.findByTestId(`tooltip-${label}`)
93
+ .should('contain', label)
94
+ .and('contain', numeral(value).format('0a').toUpperCase());
95
+ });
96
+
97
+ cy.makeSnapshot();
98
+ });
99
+ it('conditionally displays values on arcs based on displayValues prop', () => {
100
+ initialize({ displayValues: true });
101
+ defaultData.forEach(({ value }, index) => {
102
+ cy.findAllByTestId('value')
103
+ .eq(index)
104
+ .children()
105
+ .eq(0)
106
+ .should('have.text', value);
107
+ });
108
+
109
+ initialize({ displayValues: false });
110
+ cy.findAllByTestId('value').should('not.exist');
111
+
112
+ cy.makeSnapshot();
113
+ });
114
+
115
+ it('displays values on arcs in percentage unit when displayValues is set to true and unit to percentage', () => {
116
+ initialize({ displayValues: true, unit: 'percentage' });
117
+ defaultData.forEach(({ value }, index) => {
118
+ cy.findAllByTestId('value')
119
+ .eq(index)
120
+ .children()
121
+ .eq(0)
122
+ .should('have.text', `${((value * 100) / total).toFixed(1)}%`);
123
+ });
124
+
125
+ cy.makeSnapshot();
126
+ });
127
+
128
+ it('displays Legend component based on displayLegend prop', () => {
129
+ initialize({ displayLegend: true });
130
+ cy.findByTestId('Legend').should('be.visible');
131
+
132
+ initialize({ displayLegend: false });
133
+ cy.findByTestId('Legend').should('not.exist');
134
+
135
+ cy.makeSnapshot();
136
+ });
137
+
138
+ it('displays the title when the title is giving', () => {
139
+ initialize({ title: 'host' });
140
+ cy.findByTestId('Title').should('be.visible');
141
+
142
+ initialize({});
143
+ cy.findByTestId('Title').should('not.exist');
144
+
145
+ cy.makeSnapshot();
146
+ });
147
+
148
+ it('adjusts outer radius when chart dimensions are too small', () => {
149
+ initialize({
150
+ displayLegend: false,
151
+ height: '120px',
152
+ title: 'hosts',
153
+ variant: 'donut',
154
+ width: '120px'
155
+ });
156
+
157
+ cy.get('[data-variant="donut"]').should('have.css', 'width', '100px');
158
+
159
+ cy.makeSnapshot();
160
+ });
161
+
162
+ it('displays a message "No Data Available" when all values are null', () => {
163
+ initialize({ data: dataWithNullValues, title: 'host' });
164
+
165
+ cy.contains('No Data Available');
166
+
167
+ cy.makeSnapshot();
168
+ });
169
+ });