@centreon/ui 23.10.62 → 23.10.63

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.
@@ -1,9 +1,10 @@
1
- import { always, cond, equals, isNil } from 'ramda';
2
-
3
- import { Theme, useTheme } from '@mui/material';
1
+ import { equals, isNil } from 'ramda';
4
2
 
5
3
  import { getUnits, getYScale } from '../../common/timeSeries';
6
4
  import { Line } from '../../common/timeSeries/models';
5
+ import { Thresholds } from '../../common/models';
6
+
7
+ import { ThresholdLine } from './ThresholdLine';
7
8
 
8
9
  interface Props {
9
10
  displayedLines: Array<Line>;
@@ -11,24 +12,11 @@ interface Props {
11
12
  leftScale: (value: number) => number;
12
13
  rightScale: (value: number) => number;
13
14
  showTooltip: (props) => void;
14
- thresholdLabels?: Array<string>;
15
15
  thresholdUnit?: string;
16
- thresholds?: Array<number>;
16
+ thresholds: Thresholds;
17
17
  width: number;
18
18
  }
19
19
 
20
- interface GetColorProps {
21
- index: number;
22
- theme: Theme;
23
- }
24
-
25
- const getColor = ({ index, theme }: GetColorProps): string => {
26
- return cond([
27
- [equals(0), always(theme.palette.warning.main)],
28
- [equals(1), always(theme.palette.error.main)]
29
- ])(index);
30
- };
31
-
32
20
  const Thresholds = ({
33
21
  thresholds,
34
22
  leftScale,
@@ -37,15 +25,8 @@ const Thresholds = ({
37
25
  displayedLines,
38
26
  thresholdUnit,
39
27
  showTooltip,
40
- hideTooltip,
41
- thresholdLabels
42
- }: Props): JSX.Element | null => {
43
- const theme = useTheme();
44
-
45
- if (!thresholds) {
46
- return null;
47
- }
48
-
28
+ hideTooltip
29
+ }: Props): JSX.Element => {
49
30
  const [firstUnit, secondUnit, thirdUnit] = getUnits(
50
31
  displayedLines as Array<Line>
51
32
  );
@@ -63,55 +44,32 @@ const Thresholds = ({
63
44
  unit: firstUnit
64
45
  });
65
46
 
66
- const thresholdScaledValues = thresholds
67
- .sort()
68
- .map((threshold) => yScale(threshold));
69
-
70
47
  return (
71
48
  <>
72
- {thresholdScaledValues.map((threshold, index) => {
73
- return (
74
- <line
75
- data-testid={`threshold-${threshold}`}
76
- key={`threshold-${thresholdLabels?.[index]}-${threshold}`}
77
- stroke={getColor({
78
- index,
79
- theme
80
- })}
81
- strokeDasharray="5,5"
82
- strokeWidth={2}
83
- x1={0}
84
- x2={width}
85
- y1={threshold}
86
- y2={threshold}
87
- />
88
- );
89
- })}
90
- {thresholdScaledValues.map((threshold, index) => {
91
- return (
92
- <line
93
- data-testid={`threshold-${threshold}-tooltip`}
94
- key={`threshold-${thresholdLabels?.[index]}-${threshold}-tooltip`}
95
- stroke="transparent"
96
- strokeWidth={4}
97
- x1={0}
98
- x2={width}
99
- y1={threshold}
100
- y2={threshold}
101
- onMouseEnter={(): void => {
102
- if (!thresholdLabels?.[index]) {
103
- return;
104
- }
105
- showTooltip({
106
- tooltipData: thresholdLabels?.[index],
107
- tooltipLeft: 0,
108
- tooltipTop: threshold
109
- });
110
- }}
111
- onMouseLeave={hideTooltip}
112
- />
113
- );
114
- })}
49
+ {thresholds.warning.map(({ value, label }) => (
50
+ <ThresholdLine
51
+ hideTooltip={hideTooltip}
52
+ key={`warning-${value}`}
53
+ label={label}
54
+ showTooltip={showTooltip}
55
+ thresholdType="warning"
56
+ value={value}
57
+ width={width}
58
+ yScale={yScale}
59
+ />
60
+ ))}
61
+ {thresholds.critical.map(({ value, label }) => (
62
+ <ThresholdLine
63
+ hideTooltip={hideTooltip}
64
+ key={`critical-${value}`}
65
+ label={label}
66
+ showTooltip={showTooltip}
67
+ thresholdType="critical"
68
+ value={value}
69
+ width={width}
70
+ yScale={yScale}
71
+ />
72
+ ))}
115
73
  </>
116
74
  );
117
75
  };
@@ -1,12 +1,13 @@
1
1
  import { MutableRefObject, useMemo, useRef, useState } from 'react';
2
2
 
3
3
  import { Group, Tooltip } from '@visx/visx';
4
- import { isNil } from 'ramda';
4
+ import { flatten, isNil, pluck } from 'ramda';
5
5
 
6
6
  import { ClickAwayListener, Fade, Skeleton, useTheme } from '@mui/material';
7
7
 
8
8
  import { getLeftScale, getRightScale, getXScale } from '../common/timeSeries';
9
9
  import { Line } from '../common/timeSeries/models';
10
+ import { Thresholds as ThresholdsModel } from '../common/models';
10
11
 
11
12
  import Axes from './BasicComponents/Axes';
12
13
  import Grids from './BasicComponents/Grids';
@@ -35,16 +36,14 @@ import Thresholds from './BasicComponents/Thresholds';
35
36
 
36
37
  interface Props extends LineChartProps {
37
38
  curve: CurveType;
38
- disabledThresholds?: boolean;
39
39
  graphData: Data;
40
40
  graphInterval: GraphInterval;
41
41
  graphRef: MutableRefObject<HTMLDivElement | null>;
42
42
  legend?: LegendModel;
43
43
  marginBottom: number;
44
44
  shapeLines?: GlobalAreaLines;
45
- thresholdLabels?: Array<string>;
46
45
  thresholdUnit?: string;
47
- thresholds?: Array<number>;
46
+ thresholds?: ThresholdsModel;
48
47
  }
49
48
 
50
49
  const baseStyles = {
@@ -71,9 +70,7 @@ const LineChart = ({
71
70
  curve,
72
71
  marginBottom,
73
72
  thresholds,
74
- thresholdUnit,
75
- thresholdLabels,
76
- disabledThresholds
73
+ thresholdUnit
77
74
  }: Props): JSX.Element => {
78
75
  const { classes } = useStyles();
79
76
 
@@ -107,6 +104,11 @@ const LineChart = ({
107
104
 
108
105
  const { title, timeSeries, baseAxis, lines } = graphData;
109
106
 
107
+ const thresholdValues = flatten([
108
+ pluck('value', thresholds?.warning || []),
109
+ pluck('value', thresholds?.critical || [])
110
+ ]);
111
+
110
112
  const { displayedLines, newLines } = useFilterLines({
111
113
  displayThreshold: canDisplayThreshold(shapeLines?.areaThresholdLines),
112
114
  lines,
@@ -129,10 +131,10 @@ const LineChart = ({
129
131
  dataLines: displayedLines,
130
132
  dataTimeSeries: timeSeries,
131
133
  thresholdUnit,
132
- thresholds: (!disabledThresholds && thresholds) || [],
134
+ thresholds: (thresholds?.enabled && thresholdValues) || [],
133
135
  valueGraphHeight: graphHeight - 35
134
136
  }),
135
- [displayedLines, timeSeries, graphHeight]
137
+ [displayedLines, timeSeries, graphHeight, thresholdValues]
136
138
  );
137
139
 
138
140
  const rightScale = useMemo(
@@ -141,7 +143,7 @@ const LineChart = ({
141
143
  dataLines: displayedLines,
142
144
  dataTimeSeries: timeSeries,
143
145
  thresholdUnit,
144
- thresholds: (!disabledThresholds && thresholds) || [],
146
+ thresholds: (thresholds?.enabled && thresholdValues) || [],
145
147
  valueGraphHeight: graphHeight - 35
146
148
  }),
147
149
  [timeSeries, displayedLines, graphHeight]
@@ -236,16 +238,15 @@ const LineChart = ({
236
238
  zoomData={{ ...zoomPreview }}
237
239
  />
238
240
 
239
- {!disabledThresholds && (
241
+ {thresholds?.enabled && (
240
242
  <Thresholds
241
243
  displayedLines={displayedLines}
242
244
  hideTooltip={hideThresholdTooltip}
243
245
  leftScale={leftScale}
244
246
  rightScale={rightScale}
245
247
  showTooltip={showThresholdTooltip}
246
- thresholdLabels={thresholdLabels}
247
248
  thresholdUnit={thresholdUnit}
248
- thresholds={thresholds}
249
+ thresholds={thresholds as ThresholdsModel}
249
250
  width={graphWidth}
250
251
  />
251
252
  )}
@@ -387,8 +387,21 @@ export const withThresholds: Story = {
387
387
  argTypes,
388
388
  args: {
389
389
  ...argumentsData,
390
- thresholdLabels: ['threshold 1', 'threshold 2'],
391
- thresholds: [300, 350]
390
+ thresholds: {
391
+ critical: [
392
+ {
393
+ label: 'critical',
394
+ value: 350
395
+ }
396
+ ],
397
+ enabled: true,
398
+ warning: [
399
+ {
400
+ label: 'warning',
401
+ value: 300
402
+ }
403
+ ]
404
+ }
392
405
  },
393
406
  render: (args) => (
394
407
  <WrapperLineChart
@@ -403,7 +416,58 @@ export const withThresholdsAndUnit: Story = {
403
416
  args: {
404
417
  ...argumentsData,
405
418
  thresholdUnit: '%',
406
- thresholds: [65, 79]
419
+ thresholds: {
420
+ critical: [
421
+ {
422
+ label: 'critical',
423
+ value: 79
424
+ }
425
+ ],
426
+ enabled: true,
427
+ warning: [
428
+ {
429
+ label: 'warning',
430
+ value: 65
431
+ }
432
+ ]
433
+ }
434
+ },
435
+ render: (args) => (
436
+ <WrapperLineChart
437
+ {...args}
438
+ data={dataLastDay as unknown as LineChartData}
439
+ />
440
+ )
441
+ };
442
+
443
+ export const thresholdsRange: Story = {
444
+ argTypes,
445
+ args: {
446
+ ...argumentsData,
447
+ thresholdUnit: '%',
448
+ thresholds: {
449
+ critical: [
450
+ {
451
+ label: 'critical 1',
452
+ value: 60
453
+ },
454
+ {
455
+ label: 'critical 2',
456
+ value: 79
457
+ }
458
+ ],
459
+ enabled: true,
460
+ warning: [
461
+ {
462
+ label: 'warning 1',
463
+ value: 20
464
+ },
465
+ {
466
+ label: 'warning 2',
467
+ value: 30
468
+ }
469
+ ]
470
+ }
407
471
  },
408
472
  render: (args) => (
409
473
  <WrapperLineChart
@@ -10,7 +10,7 @@ import localizedFormat from 'dayjs/plugin/localizedFormat';
10
10
  import timezonePlugin from 'dayjs/plugin/timezone';
11
11
  import utcPlugin from 'dayjs/plugin/utc';
12
12
 
13
- import { LineChartData } from '../common/models';
13
+ import { LineChartData, Thresholds } from '../common/models';
14
14
 
15
15
  import LineChart from './LineChart';
16
16
  import LoadingSkeleton from './LoadingSkeleton';
@@ -25,16 +25,14 @@ dayjs.extend(timezonePlugin);
25
25
  interface Props extends Partial<LineChartProps> {
26
26
  curve?: CurveType;
27
27
  data?: LineChartData;
28
- disabledThresholds?: boolean;
29
28
  end: string;
30
29
  legend: LegendModel;
31
30
  loading: boolean;
32
31
  marginBottom?: number;
33
32
  shapeLines?: GlobalAreaLines;
34
33
  start: string;
35
- thresholdLabels?: Array<string>;
36
34
  thresholdUnit?: string;
37
- thresholds?: Array<number>;
35
+ thresholds?: Thresholds;
38
36
  }
39
37
 
40
38
  const WrapperLineChart = ({
@@ -56,9 +54,7 @@ const WrapperLineChart = ({
56
54
  curve = Curve.curveLinear,
57
55
  marginBottom = 0,
58
56
  thresholds,
59
- thresholdUnit,
60
- thresholdLabels,
61
- disabledThresholds
57
+ thresholdUnit
62
58
  }: Props): JSX.Element | null => {
63
59
  const { adjustedData } = useLineChartData({ data, end, start });
64
60
  const lineChartRef = useRef<HTMLDivElement | null>(null);
@@ -91,7 +87,6 @@ const WrapperLineChart = ({
91
87
  annotationEvent={annotationEvent}
92
88
  axis={axis}
93
89
  curve={curve}
94
- disabledThresholds={disabledThresholds}
95
90
  displayAnchor={displayAnchor}
96
91
  graphData={adjustedData}
97
92
  graphInterval={{ end, start }}
@@ -102,7 +97,6 @@ const WrapperLineChart = ({
102
97
  loading={loading}
103
98
  marginBottom={marginBottom}
104
99
  shapeLines={shapeLines}
105
- thresholdLabels={thresholdLabels}
106
100
  thresholdUnit={thresholdUnit}
107
101
  thresholds={thresholds}
108
102
  timeShiftZones={timeShiftZones}
@@ -2,7 +2,7 @@ import { useMemo, useRef } from 'react';
2
2
 
3
3
  import { Group, Tooltip } from '@visx/visx';
4
4
  import { scaleLinear } from '@visx/scale';
5
- import { head } from 'ramda';
5
+ import { flatten, head, pluck } from 'ramda';
6
6
  import { Bar } from '@visx/shape';
7
7
  import { useSpring, animated } from '@react-spring/web';
8
8
 
@@ -17,7 +17,8 @@ import { getColorFromDataAndTresholds } from '../common/utils';
17
17
  import { margins } from '../common/margins';
18
18
 
19
19
  import { SingleBarProps } from './models';
20
- import Thresholds, { barHeight, groupMargin, margin } from './Thresholds';
20
+ import Thresholds, { groupMargin } from './Thresholds';
21
+ import { barHeight, margin } from './ThresholdLine';
21
22
 
22
23
  interface Props extends SingleBarProps {
23
24
  height: number;
@@ -31,19 +32,21 @@ const baseStyles = {
31
32
 
32
33
  const ResponsiveSingleBar = ({
33
34
  data,
34
- thresholdTooltipLabels,
35
35
  thresholds,
36
36
  width,
37
- height,
38
- disabledThresholds
37
+ height
39
38
  }: Props): JSX.Element => {
40
39
  const theme = useTheme();
41
40
 
42
41
  const metric = getMetricWithLatestData(data) as Metric;
43
42
  const latestMetricData = head(metric.data) as number;
43
+ const thresholdValues = flatten([
44
+ pluck('value', thresholds.warning),
45
+ pluck('value', thresholds.critical)
46
+ ]);
44
47
  const adaptedMaxValue = Math.max(
45
48
  metric.maximum_value || 0,
46
- Math.max(...thresholds) * 1.1,
49
+ Math.max(...thresholdValues) * 1.1,
47
50
  head(metric.data) as number
48
51
  );
49
52
 
@@ -131,11 +134,10 @@ const ResponsiveSingleBar = ({
131
134
  x={0}
132
135
  y={groupMargin + margin}
133
136
  />
134
- {!disabledThresholds && (
137
+ {thresholds.enabled && (
135
138
  <Thresholds
136
139
  hideTooltip={hideTooltip}
137
140
  showTooltip={showTooltip}
138
- thresholdTooltipLabels={thresholdTooltipLabels}
139
141
  thresholds={thresholds}
140
142
  xScale={xScale}
141
143
  />
@@ -20,8 +20,21 @@ const Template = (props): JSX.Element => (
20
20
  export const success: Story = {
21
21
  args: {
22
22
  data: dataLastWeek,
23
- thresholdTooltipLabels: ['Warning', 'Critical'],
24
- thresholds: [0.5, 1.5]
23
+ thresholds: {
24
+ critical: [
25
+ {
26
+ label: 'Critical',
27
+ value: 0.6
28
+ }
29
+ ],
30
+ enabled: true,
31
+ warning: [
32
+ {
33
+ label: 'Warning',
34
+ value: 0.5
35
+ }
36
+ ]
37
+ }
25
38
  },
26
39
  render: Template
27
40
  };
@@ -29,8 +42,21 @@ export const success: Story = {
29
42
  export const warning: Story = {
30
43
  args: {
31
44
  data: dataLastWeek,
32
- thresholdTooltipLabels: ['Warning', 'Critical'],
33
- thresholds: [0.2, 0.5]
45
+ thresholds: {
46
+ critical: [
47
+ {
48
+ label: 'Critical',
49
+ value: 0.5
50
+ }
51
+ ],
52
+ enabled: true,
53
+ warning: [
54
+ {
55
+ label: 'Warning',
56
+ value: 0.2
57
+ }
58
+ ]
59
+ }
34
60
  },
35
61
  render: Template
36
62
  };
@@ -38,8 +64,95 @@ export const warning: Story = {
38
64
  export const critical: Story = {
39
65
  args: {
40
66
  data: dataLastWeek,
41
- thresholdTooltipLabels: ['Warning', 'Critical'],
42
- thresholds: [0.13, 0.35]
67
+ thresholds: {
68
+ critical: [
69
+ {
70
+ label: 'Critical',
71
+ value: 0.35
72
+ }
73
+ ],
74
+ enabled: true,
75
+ warning: [
76
+ {
77
+ label: 'Warning',
78
+ value: 0.13
79
+ }
80
+ ]
81
+ }
82
+ },
83
+ render: Template
84
+ };
85
+
86
+ export const disabled: Story = {
87
+ args: {
88
+ data: dataLastWeek,
89
+ thresholds: {
90
+ critical: [
91
+ {
92
+ label: 'Critical',
93
+ value: 0.35
94
+ }
95
+ ],
96
+ enabled: false,
97
+ warning: [
98
+ {
99
+ label: 'Warning',
100
+ value: 0.13
101
+ }
102
+ ]
103
+ }
104
+ },
105
+ render: Template
106
+ };
107
+
108
+ export const criticalLowerThanWarning: Story = {
109
+ args: {
110
+ data: dataLastWeek,
111
+ thresholds: {
112
+ critical: [
113
+ {
114
+ label: 'Critical',
115
+ value: 0.13
116
+ }
117
+ ],
118
+ enabled: true,
119
+ warning: [
120
+ {
121
+ label: 'Warning',
122
+ value: 0.5
123
+ }
124
+ ]
125
+ }
126
+ },
127
+ render: Template
128
+ };
129
+
130
+ export const rangeThresholds: Story = {
131
+ args: {
132
+ data: dataLastWeek,
133
+ thresholds: {
134
+ critical: [
135
+ {
136
+ label: 'Critical 1',
137
+ value: 0.5
138
+ },
139
+ {
140
+ label: 'Critical 2',
141
+ value: 0.6
142
+ }
143
+ ],
144
+ enabled: true,
145
+ warning: [
146
+ {
147
+ label: 'Warning 1',
148
+ value: 0.13
149
+ },
150
+ {
151
+ label: 'Warning 2',
152
+ value: 0.3
153
+ }
154
+ ]
155
+ }
43
156
  },
44
157
  render: Template
45
158
  };
@@ -0,0 +1,74 @@
1
+ import { equals } from 'ramda';
2
+
3
+ import { useTheme } from '@mui/material';
4
+
5
+ import { groupMargin } from './Thresholds';
6
+
7
+ const lineMargin = 10;
8
+
9
+ const thresholdLineHeight = 60 + 2 * lineMargin;
10
+
11
+ export const margin = 40;
12
+
13
+ export const barHeight = 50;
14
+
15
+ interface Props {
16
+ hideTooltip: () => void;
17
+ label: string;
18
+ showTooltip: (args) => void;
19
+ thresholdType: string;
20
+ value: number;
21
+ xScale: (value: number) => number;
22
+ }
23
+
24
+ export const ThresholdLine = ({
25
+ value,
26
+ label,
27
+ xScale,
28
+ thresholdType,
29
+ showTooltip,
30
+ hideTooltip
31
+ }: Props): JSX.Element => {
32
+ const theme = useTheme();
33
+
34
+ const scaledValue = xScale(value) || 0;
35
+
36
+ const bottom = barHeight + margin * 2;
37
+
38
+ const onMouseEnter = (left) => (): void =>
39
+ showTooltip({
40
+ tooltipData: label,
41
+ tooltipLeft: left,
42
+ tooltipTop: bottom
43
+ });
44
+
45
+ const lineColor = equals(thresholdType, 'warning')
46
+ ? theme.palette.warning.main
47
+ : theme.palette.error.main;
48
+
49
+ return (
50
+ <>
51
+ <line
52
+ data-testid={`${thresholdType}-line-${value}`}
53
+ stroke={lineColor}
54
+ strokeDasharray={4}
55
+ strokeWidth={2}
56
+ x1={scaledValue}
57
+ x2={scaledValue}
58
+ y1={groupMargin + 3 * lineMargin}
59
+ y2={thresholdLineHeight + groupMargin + 3 * lineMargin}
60
+ />
61
+ <line
62
+ data-testid={`${thresholdType}-line-${value}-tooltip`}
63
+ stroke="transparent"
64
+ strokeWidth={5}
65
+ x1={scaledValue}
66
+ x2={scaledValue}
67
+ y1={groupMargin + 3 * lineMargin}
68
+ y2={thresholdLineHeight + groupMargin + 3 * lineMargin}
69
+ onMouseEnter={onMouseEnter(scaledValue)}
70
+ onMouseLeave={hideTooltip}
71
+ />
72
+ </>
73
+ );
74
+ };