@centreon/ui 24.6.4 → 24.7.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@centreon/ui",
3
- "version": "24.6.4",
3
+ "version": "24.7.0",
4
4
  "description": "Centreon UI Components",
5
5
  "scripts": {
6
6
  "update:deps": "pnpx npm-check-updates -i --format group",
@@ -12,9 +12,9 @@
12
12
  "test:storybook:local": "test-storybook --url http://127.0.0.1:9001",
13
13
  "test:ci": "jest --silent --reporter=jest-junit",
14
14
  "cypress:ui": "cypress open --component --browser=chrome",
15
- "cypress:cli:updateSnapshot": "pnpm cypress:cli --env updateSnapshots=true",
15
+ "cypress:run:updateSnapshot": "pnpm cypress:cli --env updateSnapshots=true",
16
16
  "cypress:run:coverage": "cypress run --component --browser=chrome --env codeCoverageTasksRegistered=true",
17
- "cypress:cli": "cypress run --component --browser=chrome",
17
+ "cypress:run": "cypress run --component --browser=chrome",
18
18
  "tokens:transform": "TS_NODE_PROJECT=tsconfig.node.json ts-node style-dictionary.transform.ts"
19
19
  },
20
20
  "sideEffects": false,
@@ -8,6 +8,7 @@ import 'dayjs/locale/pt';
8
8
  import localizedFormat from 'dayjs/plugin/localizedFormat';
9
9
  import timezonePlugin from 'dayjs/plugin/timezone';
10
10
  import utcPlugin from 'dayjs/plugin/utc';
11
+ import { Provider } from 'jotai';
11
12
 
12
13
  import { Box } from '@mui/material';
13
14
 
@@ -33,7 +34,7 @@ export interface BarChartProps
33
34
  end: string;
34
35
  limitLegend?: false | number;
35
36
  loading: boolean;
36
- orientation: 'vertical' | 'horizontal';
37
+ orientation: 'vertical' | 'horizontal' | 'auto';
37
38
  start: string;
38
39
  thresholdUnit?: string;
39
40
  thresholds?: Thresholds;
@@ -71,30 +72,32 @@ const BarChart = ({
71
72
  }
72
73
 
73
74
  return (
74
- <Box
75
- ref={lineChartRef}
76
- sx={{ height: '100%', overflow: 'hidden', width: '100%' }}
77
- >
78
- <ParentSize>
79
- {({ height: responsiveHeight, width }) => (
80
- <ResponsiveBarChart
81
- axis={axis}
82
- barStyle={barStyle}
83
- graphData={adjustedData}
84
- graphRef={lineChartRef}
85
- header={header}
86
- height={height || responsiveHeight}
87
- legend={legend}
88
- limitLegend={limitLegend}
89
- orientation={orientation}
90
- thresholdUnit={thresholdUnit}
91
- thresholds={thresholds}
92
- tooltip={tooltip}
93
- width={width}
94
- />
95
- )}
96
- </ParentSize>
97
- </Box>
75
+ <Provider>
76
+ <Box
77
+ ref={lineChartRef}
78
+ sx={{ height: '100%', overflow: 'hidden', width: '100%' }}
79
+ >
80
+ <ParentSize>
81
+ {({ height: responsiveHeight, width }) => (
82
+ <ResponsiveBarChart
83
+ axis={axis}
84
+ barStyle={barStyle}
85
+ graphData={adjustedData}
86
+ graphRef={lineChartRef}
87
+ header={header}
88
+ height={height || responsiveHeight}
89
+ legend={legend}
90
+ limitLegend={limitLegend}
91
+ orientation={orientation}
92
+ thresholdUnit={thresholdUnit}
93
+ thresholds={thresholds}
94
+ tooltip={tooltip}
95
+ width={width}
96
+ />
97
+ )}
98
+ </ParentSize>
99
+ </Box>
100
+ </Provider>
98
101
  );
99
102
  };
100
103
 
@@ -171,6 +171,7 @@ const BarGroup = ({
171
171
  <BarStack
172
172
  barIndex={barGroup.index}
173
173
  barPadding={isHorizontal ? bar.x : bar.y}
174
+ barStyle={barStyle}
174
175
  barWidth={isHorizontal ? bar.width : bar.height}
175
176
  isHorizontal={isHorizontal}
176
177
  isTooltipHidden={isTooltipHidden}
@@ -183,6 +184,7 @@ const BarGroup = ({
183
184
  <BarStack
184
185
  barIndex={barGroup.index}
185
186
  barPadding={isHorizontal ? bar.x : bar.y}
187
+ barStyle={barStyle}
186
188
  barWidth={isHorizontal ? bar.width : bar.height}
187
189
  isHorizontal={isHorizontal}
188
190
  isTooltipHidden={isTooltipHidden}
@@ -4,6 +4,7 @@ import { scaleBand } from '@visx/scale';
4
4
  import { equals, gt, pick } from 'ramda';
5
5
 
6
6
  import { useBarStack, UseBarStackProps } from './useBarStack';
7
+ import { BarStyle } from './models';
7
8
 
8
9
  const xScale = scaleBand<number>({
9
10
  domain: [0, 0],
@@ -14,6 +15,7 @@ const xScale = scaleBand<number>({
14
15
  interface Props extends Omit<UseBarStackProps, 'xScale'> {
15
16
  barIndex: number;
16
17
  barPadding: number;
18
+ barStyle: BarStyle;
17
19
  barWidth: number;
18
20
  isTooltipHidden: boolean;
19
21
  }
@@ -34,7 +36,8 @@ const BarStack = ({
34
36
  barWidth,
35
37
  barPadding,
36
38
  barIndex,
37
- isTooltipHidden
39
+ isTooltipHidden,
40
+ barStyle
38
41
  }: Props): JSX.Element => {
39
42
  const {
40
43
  BarStackComponent,
@@ -63,6 +66,7 @@ const BarStack = ({
63
66
  fill={bar.color}
64
67
  height={isHorizontal ? Math.abs(bar.height) : barWidth}
65
68
  key={`bar-stack-${barStack.index}-${bar.index}`}
69
+ opacity={barStyle.opacity}
66
70
  width={isHorizontal ? barWidth : Math.abs(bar.width)}
67
71
  x={
68
72
  isHorizontal
@@ -107,7 +111,8 @@ const propsToMemoize = [
107
111
  'lines',
108
112
  'barPadding',
109
113
  'barIndex',
110
- 'isTooltipHidden'
114
+ 'isTooltipHidden',
115
+ 'barStyle'
111
116
  ];
112
117
 
113
118
  export default memo(BarStack, (prevProps, nextProps) => {
@@ -1,6 +1,6 @@
1
- import { MutableRefObject, useMemo, useRef, useState } from 'react';
1
+ import { MutableRefObject, useEffect, useMemo, useRef, useState } from 'react';
2
2
 
3
- import { equals, flatten, has, isNil, pluck } from 'ramda';
3
+ import { equals, flatten, gte, has, isNil, pluck } from 'ramda';
4
4
  import { useAtom } from 'jotai';
5
5
 
6
6
  import { Skeleton } from '@mui/material';
@@ -22,6 +22,7 @@ import { useTooltipStyles } from '../common/useTooltipStyles';
22
22
  import { margin } from '../LineChart/common';
23
23
  import { Tooltip } from '../../components';
24
24
  import Thresholds from '../common/Thresholds/Thresholds';
25
+ import { useDeepCompare } from '../../utils';
25
26
 
26
27
  import BarGroup from './BarGroup';
27
28
  import { tooltipDataAtom } from './atoms';
@@ -35,7 +36,7 @@ interface Props
35
36
  graphRef: MutableRefObject<HTMLDivElement | null>;
36
37
  height: number;
37
38
  limitLegend?: false | number;
38
- orientation: 'vertical' | 'horizontal';
39
+ orientation: 'vertical' | 'horizontal' | 'auto';
39
40
  thresholdUnit?: string;
40
41
  thresholds?: ThresholdsModel;
41
42
  width: number;
@@ -82,7 +83,13 @@ const ResponsiveBarChart = ({
82
83
  pluck('value', thresholds?.critical || [])
83
84
  ]);
84
85
 
85
- const isHorizontal = equals(orientation, 'horizontal');
86
+ const isHorizontal = useMemo(() => {
87
+ if (!equals(orientation, 'auto')) {
88
+ return equals(orientation, 'horizontal');
89
+ }
90
+
91
+ return gte(graphWidth, graphHeight + 60);
92
+ }, [orientation, graphWidth, graphHeight]);
86
93
 
87
94
  const xScale = useMemo(
88
95
  () =>
@@ -144,6 +151,13 @@ const ResponsiveBarChart = ({
144
151
  ]
145
152
  );
146
153
 
154
+ useEffect(
155
+ () => {
156
+ setLinesGraph(lines);
157
+ },
158
+ useDeepCompare([lines])
159
+ );
160
+
147
161
  const displayLegend = legend?.display ?? true;
148
162
 
149
163
  const displayedLines = useMemo(
@@ -214,7 +228,7 @@ const ResponsiveBarChart = ({
214
228
  graphWidth={graphWidth - (isHorizontal ? 0 : margin.left - 15)}
215
229
  gridLinesType={axis?.gridLinesType}
216
230
  leftScale={leftScale}
217
- orientation={orientation}
231
+ orientation={isHorizontal ? 'horizontal' : 'vertical'}
218
232
  rightScale={rightScale}
219
233
  showGridLines={showGridLines}
220
234
  svgRef={graphSvgRef}
@@ -228,7 +242,7 @@ const ResponsiveBarChart = ({
228
242
  isTooltipHidden={isTooltipHidden}
229
243
  leftScale={leftScale}
230
244
  lines={displayedLines}
231
- orientation={orientation}
245
+ orientation={isHorizontal ? 'horizontal' : 'vertical'}
232
246
  rightScale={rightScale}
233
247
  secondUnit={secondUnit}
234
248
  size={isHorizontal ? graphHeight - margin.top - 5 : graphWidth}
@@ -1,7 +1,7 @@
1
- import { MutableRefObject, useMemo, useRef, useState } from 'react';
1
+ import { MutableRefObject, useEffect, useMemo, useRef, useState } from 'react';
2
2
 
3
3
  import { Tooltip } from '@visx/visx';
4
- import { equals, flatten, isNil, pluck } from 'ramda';
4
+ import { equals, flatten, isNil, pluck, reject } from 'ramda';
5
5
 
6
6
  import { ClickAwayListener, Fade, Skeleton, useTheme } from '@mui/material';
7
7
 
@@ -19,10 +19,15 @@ import BaseChart from '../common/BaseChart/BaseChart';
19
19
  import { useComputeBaseChartDimensions } from '../common/BaseChart/useComputeBaseChartDimensions';
20
20
  import ChartSvgWrapper from '../common/BaseChart/ChartSvgWrapper';
21
21
  import Thresholds from '../common/Thresholds/Thresholds';
22
+ import { useDeepCompare } from '../../utils';
22
23
 
23
24
  import Lines from './BasicComponents/Lines';
24
- import { canDisplayThreshold } from './BasicComponents/Lines/Threshold/models';
25
- import useFilterLines from './BasicComponents/useFilterLines';
25
+ import {
26
+ canDisplayThreshold,
27
+ findLineOfOriginMetricThreshold,
28
+ lowerLineName,
29
+ upperLineName
30
+ } from './BasicComponents/Lines/Threshold/models';
26
31
  import InteractionWithGraph from './InteractiveComponents';
27
32
  import GraphTooltip from './InteractiveComponents/Tooltip';
28
33
  import useGraphTooltip from './InteractiveComponents/Tooltip/useGraphTooltip';
@@ -47,6 +52,23 @@ const baseStyles = {
47
52
  textAlign: 'center'
48
53
  };
49
54
 
55
+ const filterLines = (lines: Array<Line>, displayThreshold): Array<Line> => {
56
+ if (!displayThreshold) {
57
+ return lines;
58
+ }
59
+ const lineOriginMetric = findLineOfOriginMetricThreshold(lines);
60
+
61
+ const findLinesUpperLower = lines.map((line) =>
62
+ equals(line.name, lowerLineName) || equals(line.name, upperLineName)
63
+ ? line
64
+ : null
65
+ );
66
+
67
+ const linesUpperLower = reject((element) => !element, findLinesUpperLower);
68
+
69
+ return [...lineOriginMetric, ...linesUpperLower] as Array<Line>;
70
+ };
71
+
50
72
  const LineChart = ({
51
73
  graphData,
52
74
  height = 500,
@@ -72,7 +94,11 @@ const LineChart = ({
72
94
 
73
95
  const theme = useTheme();
74
96
 
75
- const [linesGraph, setLinesGraph] = useState<Array<Line> | null>(null);
97
+ const { title, timeSeries, baseAxis, lines } = graphData;
98
+
99
+ const [linesGraph, setLinesGraph] = useState<Array<Line>>(
100
+ filterLines(lines, canDisplayThreshold(shapeLines?.areaThresholdLines))
101
+ );
76
102
  const graphSvgRef = useRef<SVGSVGElement | null>(null);
77
103
 
78
104
  const { isInViewport } = useIntersection({ element: graphRef?.current });
@@ -86,21 +112,12 @@ const LineChart = ({
86
112
  showTooltip: showThresholdTooltip
87
113
  } = Tooltip.useTooltip();
88
114
 
89
- const { title, timeSeries, baseAxis, lines } = graphData;
90
-
91
115
  const thresholdValues = flatten([
92
116
  pluck('value', thresholds?.warning || []),
93
117
  pluck('value', thresholds?.critical || [])
94
118
  ]);
95
119
 
96
- const { displayedLines } = useFilterLines({
97
- displayThreshold: canDisplayThreshold(shapeLines?.areaThresholdLines),
98
- lines,
99
- linesGraph,
100
- setLinesGraph
101
- });
102
-
103
- const [, secondUnit] = getUnits(displayedLines);
120
+ const [, secondUnit] = getUnits(linesGraph);
104
121
 
105
122
  const { legendRef, graphWidth, graphHeight } = useComputeBaseChartDimensions({
106
123
  hasSecondUnit: Boolean(secondUnit),
@@ -119,6 +136,11 @@ const LineChart = ({
119
136
  [timeSeries, graphWidth]
120
137
  );
121
138
 
139
+ const displayedLines = useMemo(
140
+ () => linesGraph.filter(({ display }) => display),
141
+ [linesGraph]
142
+ );
143
+
122
144
  const leftScale = useMemo(
123
145
  () =>
124
146
  getLeftScale({
@@ -164,6 +186,15 @@ const LineChart = ({
164
186
  ]
165
187
  );
166
188
 
189
+ useEffect(
190
+ () => {
191
+ setLinesGraph(
192
+ filterLines(lines, canDisplayThreshold(shapeLines?.areaThresholdLines))
193
+ );
194
+ },
195
+ useDeepCompare([lines])
196
+ );
197
+
167
198
  const graphTooltipData = useGraphTooltip({
168
199
  graphWidth,
169
200
  timeSeries,
@@ -204,7 +235,7 @@ const LineChart = ({
204
235
  }}
205
236
  legendRef={legendRef}
206
237
  limitLegend={limitLegend}
207
- lines={displayedLines}
238
+ lines={linesGraph}
208
239
  setLines={setLinesGraph}
209
240
  title={title}
210
241
  >
@@ -269,7 +300,7 @@ const LineChart = ({
269
300
  graphSvgRef,
270
301
  graphWidth,
271
302
  leftScale,
272
- lines: displayedLines,
303
+ lines: linesGraph,
273
304
  rightScale,
274
305
  timeSeries,
275
306
  xScale
@@ -32,8 +32,14 @@ const Axes = ({
32
32
  }: Props): JSX.Element => {
33
33
  const { format } = useLocaleDateTimeFormat();
34
34
  const { lines, showBorder, yAxisTickLabelRotation } = data;
35
+ const isHorizontal = equals(orientation, 'horizontal');
35
36
 
36
- const { axisLeft, axisRight } = useAxisY({ data, graphHeight: height });
37
+ const { axisLeft, axisRight } = useAxisY({
38
+ data,
39
+ graphHeight: height,
40
+ graphWidth: width,
41
+ isHorizontal
42
+ });
37
43
 
38
44
  const [firstUnit, secondUnit, thirdUnit] = getUnits(lines);
39
45
 
@@ -52,8 +58,6 @@ const Axes = ({
52
58
  const hasMoreThanTwoUnits = !isNil(thirdUnit);
53
59
  const displayAxisRight = !isNil(secondUnit) && !hasMoreThanTwoUnits;
54
60
 
55
- const isHorizontal = equals(orientation, 'horizontal');
56
-
57
61
  const AxisBottom = isHorizontal ? Axis.AxisBottom : Axis.AxisLeft;
58
62
  const AxisLeft = isHorizontal ? Axis.AxisLeft : Axis.AxisTop;
59
63
  const AxisRight = isHorizontal ? Axis.AxisRight : Axis.AxisBottom;
@@ -76,7 +80,7 @@ const Axes = ({
76
80
  <UnitLabel
77
81
  unit={firstUnit}
78
82
  x={isHorizontal ? -8 : width + 8}
79
- y={isHorizontal ? 16 : 0}
83
+ y={isHorizontal ? 16 : -2}
80
84
  />
81
85
  )}
82
86
 
@@ -88,8 +92,8 @@ const Axes = ({
88
92
  tickLabelProps={() => ({
89
93
  ...axisLeft.tickLabelProps(),
90
94
  angle: yAxisTickLabelRotation,
91
- dx: isHorizontal ? -8 : 2,
92
- dy: isHorizontal ? 4 : -4
95
+ dx: isHorizontal ? -8 : 16,
96
+ dy: isHorizontal ? 4 : -6
93
97
  })}
94
98
  tickLength={2}
95
99
  />
@@ -27,15 +27,24 @@ interface AxisY {
27
27
  interface Props {
28
28
  data: Omit<Data, 'timeSeries'>;
29
29
  graphHeight?: number;
30
+ graphWidth?: number;
31
+ isHorizontal: boolean;
30
32
  }
31
33
 
32
- const useAxisY = ({ data, graphHeight }: Props): AxisY => {
34
+ const useAxisY = ({
35
+ data,
36
+ graphHeight,
37
+ graphWidth,
38
+ isHorizontal
39
+ }: Props): AxisY => {
33
40
  const theme = useTheme();
34
41
 
35
42
  const { lines } = data;
36
43
  const [firstUnit, secondUnit, thirdUnit] = getUnits(lines);
37
44
 
38
- const numTicks = graphHeight && Math.ceil(graphHeight / 30);
45
+ const numTicks = isHorizontal
46
+ ? graphHeight && Math.ceil(graphHeight / 30)
47
+ : graphWidth && Math.ceil(graphWidth / 60);
39
48
 
40
49
  const hasMoreThanTwoUnits = !isNil(thirdUnit);
41
50
  const hasTwoUnits = !isNil(secondUnit) && !hasMoreThanTwoUnits;
@@ -1,4 +1,5 @@
1
1
  export { default as LineChart } from './LineChart';
2
+ export { default as BarChart } from './BarChart/BarChart';
2
3
  export { Gauge } from './Gauge';
3
4
  export { SingleBar } from './SingleBar';
4
5
  export { Text as GraphText } from './Text';