@centreon/ui 23.10.56 → 23.10.58

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 (124) hide show
  1. package/package.json +3 -1
  2. package/src/Graph/Gauge/AnimatedPie.tsx +87 -0
  3. package/src/Graph/Gauge/Gauge.stories.tsx +45 -0
  4. package/src/Graph/Gauge/Gauge.tsx +44 -0
  5. package/src/Graph/Gauge/PieData.tsx +79 -0
  6. package/src/Graph/Gauge/ResponsiveGauge.tsx +135 -0
  7. package/src/Graph/Gauge/Thresholds.tsx +87 -0
  8. package/src/Graph/Gauge/index.ts +1 -0
  9. package/src/Graph/Gauge/models.ts +20 -0
  10. package/src/Graph/{BasicComponents → LineChart/BasicComponents}/Axes/index.tsx +1 -1
  11. package/src/Graph/{BasicComponents → LineChart/BasicComponents}/Axes/models.ts +1 -1
  12. package/src/Graph/{BasicComponents → LineChart/BasicComponents}/Axes/useAxisY.ts +1 -1
  13. package/src/Graph/{BasicComponents → LineChart/BasicComponents}/Lines/RegularLines/index.tsx +2 -2
  14. package/src/Graph/{BasicComponents → LineChart/BasicComponents}/Lines/RegularLines/useRegularLines.ts +2 -2
  15. package/src/Graph/{BasicComponents → LineChart/BasicComponents}/Lines/StackedLines/index.tsx +2 -2
  16. package/src/Graph/{BasicComponents → LineChart/BasicComponents}/Lines/StackedLines/useStackedLines.ts +1 -1
  17. package/src/Graph/{BasicComponents → LineChart/BasicComponents}/Lines/Threshold/BasicThreshold.tsx +1 -1
  18. package/src/Graph/{BasicComponents → LineChart/BasicComponents}/Lines/Threshold/ThresholdWithPatternLines.tsx +3 -2
  19. package/src/Graph/{BasicComponents → LineChart/BasicComponents}/Lines/Threshold/ThresholdWithVariation.tsx +1 -1
  20. package/src/Graph/{BasicComponents → LineChart/BasicComponents}/Lines/Threshold/index.tsx +1 -1
  21. package/src/Graph/{BasicComponents → LineChart/BasicComponents}/Lines/Threshold/models.ts +1 -1
  22. package/src/Graph/{BasicComponents → LineChart/BasicComponents}/Lines/Threshold/useScaleThreshold.ts +2 -2
  23. package/src/Graph/{BasicComponents → LineChart/BasicComponents}/Lines/index.tsx +6 -2
  24. package/src/Graph/{BasicComponents → LineChart/BasicComponents}/Lines/models.ts +3 -3
  25. package/src/Graph/{BasicComponents → LineChart/BasicComponents}/useFilterLines.ts +1 -1
  26. package/src/Graph/{Header → LineChart/Header}/index.tsx +4 -4
  27. package/src/Graph/{Icons → LineChart/Icons}/Downtime.tsx +1 -1
  28. package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/AnchorPoint/RegularAnchorPoint.tsx +2 -2
  29. package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/AnchorPoint/StackedAnchorPoint.tsx +2 -2
  30. package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/AnchorPoint/models.ts +1 -1
  31. package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/AnchorPoint/useTickGraph.ts +2 -2
  32. package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/Tooltip/useGraphTooltip.ts +1 -1
  33. package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/index.tsx +2 -2
  34. package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/interactionWithGraphAtoms.ts +1 -1
  35. package/src/Graph/{Legend → LineChart/Legend}/LegendHeader.tsx +1 -1
  36. package/src/Graph/{Legend → LineChart/Legend}/index.tsx +2 -2
  37. package/src/Graph/{Legend → LineChart/Legend}/useInteractiveValues.ts +6 -2
  38. package/src/Graph/{Legend → LineChart/Legend}/useLegend.ts +1 -1
  39. package/src/Graph/{Graph.tsx → LineChart/LineChart.tsx} +8 -7
  40. package/src/Graph/{graphAtoms.ts → LineChart/graphAtoms.ts} +1 -1
  41. package/src/Graph/{helpers → LineChart/helpers}/index.ts +9 -4
  42. package/src/Graph/{index.stories.tsx → LineChart/index.stories.tsx} +39 -38
  43. package/src/Graph/{index.tsx → LineChart/index.tsx} +14 -12
  44. package/src/Graph/{models.ts → LineChart/models.ts} +8 -12
  45. package/src/Graph/{useGraphData.ts → LineChart/useLineChartData.ts} +5 -3
  46. package/src/Graph/SingleBar/ResponsiveSingleBar.tsx +163 -0
  47. package/src/Graph/SingleBar/SingleBar.stories.tsx +45 -0
  48. package/src/Graph/SingleBar/SingleBar.tsx +25 -0
  49. package/src/Graph/SingleBar/Thresholds.tsx +100 -0
  50. package/src/Graph/SingleBar/index.ts +1 -0
  51. package/src/Graph/SingleBar/models.ts +8 -0
  52. package/src/Graph/Text/Text.stories.tsx +54 -0
  53. package/src/Graph/Text/Text.styles.ts +17 -0
  54. package/src/Graph/Text/Text.tsx +80 -0
  55. package/src/Graph/Text/index.ts +1 -0
  56. package/src/Graph/common/margins.ts +1 -0
  57. package/src/Graph/common/models.ts +7 -0
  58. package/src/Graph/{timeSeries → common/timeSeries}/index.test.ts +2 -2
  59. package/src/Graph/{timeSeries → common/timeSeries}/index.ts +22 -6
  60. package/src/Graph/{timeSeries → common/timeSeries}/models.ts +2 -0
  61. package/src/Graph/common/utils.ts +20 -0
  62. package/src/Graph/index.ts +4 -0
  63. package/src/RichTextEditor/ContentEditable.tsx +8 -3
  64. package/src/RichTextEditor/RichTextEditor.cypress.spec.tsx +10 -6
  65. package/src/RichTextEditor/RichTextEditor.tsx +39 -1
  66. package/src/RichTextEditor/plugins/ToolbarPlugin/index.tsx +1 -1
  67. package/src/api/useGraphQuery/index.ts +7 -4
  68. package/src/components/CollapsibleItem/useCollapsibleItemStyles.ts +1 -0
  69. package/src/index.ts +3 -2
  70. /package/src/Graph/{BasicComponents → LineChart/BasicComponents}/Axes/UnitLabel.tsx +0 -0
  71. /package/src/Graph/{BasicComponents → LineChart/BasicComponents}/Grids/index.tsx +0 -0
  72. /package/src/Graph/{BasicComponents → LineChart/BasicComponents}/Lines/Threshold/Circle.tsx +0 -0
  73. /package/src/Graph/{BasicComponents → LineChart/BasicComponents}/Lines/Threshold/helpers/index.ts +0 -0
  74. /package/src/Graph/{BasicComponents → LineChart/BasicComponents}/Lines/Threshold/useCoordinateCircle.ts +0 -0
  75. /package/src/Graph/{BasicComponents → LineChart/BasicComponents}/LoadingProgress.tsx +0 -0
  76. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/AnchorPoint/GuidingLines.tsx +0 -0
  77. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/AnchorPoint/TooltipAnchorPoint.tsx +0 -0
  78. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/AnchorPoint/index.tsx +0 -0
  79. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/AnchorPoint/useTooltipAnchorPoint.ts +0 -0
  80. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/Annotations/Annotation/Area.tsx +0 -0
  81. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/Annotations/Annotation/Line.tsx +0 -0
  82. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/Annotations/Annotation/index.tsx +0 -0
  83. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/Annotations/Area/Downtime.tsx +0 -0
  84. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/Annotations/EventAnnotations.tsx +0 -0
  85. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/Annotations/Line/Acknowledgement.tsx +0 -0
  86. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/Annotations/Line/Comments.tsx +0 -0
  87. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/Annotations/annotationsAtoms.ts +0 -0
  88. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/Annotations/index.tsx +0 -0
  89. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/Annotations/models.ts +0 -0
  90. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/Annotations/useAnnotation.ts +0 -0
  91. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/Bar.tsx +0 -0
  92. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/TimeShiftZones/TimeShiftIcon.tsx +0 -0
  93. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/TimeShiftZones/TimeShiftZone.tsx +0 -0
  94. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/TimeShiftZones/index.tsx +0 -0
  95. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/TimeShiftZones/models.ts +0 -0
  96. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/TimeShiftZones/useTimeShiftZones.ts +0 -0
  97. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/Tooltip/index.tsx +0 -0
  98. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/Tooltip/models.ts +0 -0
  99. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/ZoomPreview/index.tsx +0 -0
  100. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/ZoomPreview/models.ts +0 -0
  101. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/ZoomPreview/useZoomPreview.ts +0 -0
  102. /package/src/Graph/{InteractiveComponents → LineChart/InteractiveComponents}/ZoomPreview/zoomPreviewAtoms.ts +0 -0
  103. /package/src/Graph/{Legend → LineChart/Legend}/InteractiveValue.tsx +0 -0
  104. /package/src/Graph/{Legend → LineChart/Legend}/Legend.styles.ts +0 -0
  105. /package/src/Graph/{Legend → LineChart/Legend}/LegendContent.tsx +0 -0
  106. /package/src/Graph/{Legend → LineChart/Legend}/Marker.tsx +0 -0
  107. /package/src/Graph/{Legend → LineChart/Legend}/models.ts +0 -0
  108. /package/src/Graph/{Graph.styles.ts → LineChart/LineChart.styles.ts} +0 -0
  109. /package/src/Graph/{LoadingSkeleton.tsx → LineChart/LoadingSkeleton.tsx} +0 -0
  110. /package/src/Graph/{common → LineChart/common}/index.ts +0 -0
  111. /package/src/Graph/{helpers → LineChart/helpers}/doc.ts +0 -0
  112. /package/src/Graph/{mockedData → LineChart/mockedData}/annotationData.json +0 -0
  113. /package/src/Graph/{mockedData → LineChart/mockedData}/exclusionPeriodFirstPeriod.json +0 -0
  114. /package/src/Graph/{mockedData → LineChart/mockedData}/exclusionPeriodSecondPeriod.json +0 -0
  115. /package/src/Graph/{mockedData → LineChart/mockedData}/exclusionPeriodThirdPeriod.json +0 -0
  116. /package/src/Graph/{mockedData → LineChart/mockedData}/lastDay.json +0 -0
  117. /package/src/Graph/{mockedData → LineChart/mockedData}/lastDayAreaStack.json +0 -0
  118. /package/src/Graph/{mockedData → LineChart/mockedData}/lastDayForward.json +0 -0
  119. /package/src/Graph/{mockedData → LineChart/mockedData}/lastDayThreshold.json +0 -0
  120. /package/src/Graph/{mockedData → LineChart/mockedData}/lastMonth.json +0 -0
  121. /package/src/Graph/{mockedData → LineChart/mockedData}/lastWeek.json +0 -0
  122. /package/src/Graph/{mockedData → LineChart/mockedData}/zoomPreview.json +0 -0
  123. /package/src/Graph/{translatedLabels.ts → LineChart/translatedLabels.ts} +0 -0
  124. /package/src/Graph/{useGraphIntersection.ts → LineChart/useLineChartIntersection.ts} +0 -0
@@ -2,15 +2,17 @@ import { useEffect, useState } from 'react';
2
2
 
3
3
  import { compose, prop, sortBy, toLower } from 'ramda';
4
4
 
5
+ import { LineChartData } from '../common/models';
6
+
5
7
  import { adjustGraphData } from './helpers';
6
- import { Data, GraphData } from './models';
8
+ import { Data } from './models';
7
9
 
8
10
  interface GraphDataResult {
9
11
  adjustedData?: Data;
10
12
  }
11
13
 
12
14
  interface Props {
13
- data?: GraphData;
15
+ data?: LineChartData;
14
16
  end?: string;
15
17
  start?: string;
16
18
  }
@@ -18,7 +20,7 @@ interface Props {
18
20
  const useGraphData = ({ data, end, start }: Props): GraphDataResult => {
19
21
  const [adjustedData, setAdjustedData] = useState<Data>();
20
22
 
21
- const prepareData = (dataToAdjust: GraphData): void => {
23
+ const prepareData = (dataToAdjust: LineChartData): void => {
22
24
  const { timeSeries } = adjustGraphData(dataToAdjust);
23
25
  const baseAxis = dataToAdjust.global.base;
24
26
  const { title } = dataToAdjust.global;
@@ -0,0 +1,163 @@
1
+ import { useMemo, useRef } from 'react';
2
+
3
+ import { Group, Tooltip } from '@visx/visx';
4
+ import { scaleLinear } from '@visx/scale';
5
+ import { head } from 'ramda';
6
+ import { Bar } from '@visx/shape';
7
+ import { useSpring, animated } from '@react-spring/web';
8
+
9
+ import { alpha, Box, Fade, useTheme } from '@mui/material';
10
+
11
+ import {
12
+ formatMetricValue,
13
+ getMetricWithLatestData
14
+ } from '../common/timeSeries';
15
+ import { Metric } from '../common/timeSeries/models';
16
+ import { getColorFromDataAndTresholds } from '../common/utils';
17
+ import { margins } from '../common/margins';
18
+
19
+ import { SingleBarProps } from './models';
20
+ import Thresholds, { barHeight, groupMargin, margin } from './Thresholds';
21
+
22
+ interface Props extends SingleBarProps {
23
+ height: number;
24
+ width: number;
25
+ }
26
+
27
+ const baseStyles = {
28
+ ...Tooltip.defaultStyles,
29
+ textAlign: 'center'
30
+ };
31
+
32
+ const ResponsiveSingleBar = ({
33
+ data,
34
+ thresholdTooltipLabels,
35
+ thresholds,
36
+ width,
37
+ height,
38
+ disabledThresholds
39
+ }: Props): JSX.Element => {
40
+ const theme = useTheme();
41
+
42
+ const metric = getMetricWithLatestData(data) as Metric;
43
+ const latestMetricData = head(metric.data) as number;
44
+ const adaptedMaxValue = Math.max(
45
+ metric.maximum_value || 0,
46
+ Math.max(...thresholds) * 1.1,
47
+ head(metric.data) as number
48
+ );
49
+
50
+ const innerHeight = height;
51
+ const centerY = innerHeight / 4;
52
+
53
+ const {
54
+ showTooltip,
55
+ hideTooltip,
56
+ tooltipOpen,
57
+ tooltipLeft,
58
+ tooltipTop,
59
+ tooltipData
60
+ } = Tooltip.useTooltip();
61
+ const svgRef = useRef<SVGSVGElement | null>(null);
62
+
63
+ const barColor = useMemo(
64
+ () =>
65
+ getColorFromDataAndTresholds({
66
+ data: latestMetricData,
67
+ theme,
68
+ thresholds
69
+ }),
70
+ [latestMetricData, thresholds, theme]
71
+ );
72
+
73
+ const text = (
74
+ <text
75
+ dominantBaseline="middle"
76
+ style={{ fill: barColor, ...theme.typography.h3 }}
77
+ textAnchor="middle"
78
+ x="50%"
79
+ y={25}
80
+ >
81
+ {formatMetricValue({
82
+ base: 1000,
83
+ unit: metric.unit,
84
+ value: metric.data[0]
85
+ })}{' '}
86
+ {metric.unit}
87
+ </text>
88
+ );
89
+
90
+ const xScale = useMemo(
91
+ () =>
92
+ scaleLinear<number>({
93
+ domain: [0, adaptedMaxValue],
94
+ range: [0, width]
95
+ }),
96
+ [width, adaptedMaxValue]
97
+ );
98
+
99
+ const metricBarWidth = useMemo(
100
+ () => xScale(latestMetricData),
101
+ [xScale, latestMetricData]
102
+ );
103
+ const maxBarWidth = useMemo(
104
+ () => xScale(adaptedMaxValue),
105
+ [xScale, adaptedMaxValue]
106
+ );
107
+
108
+ const springStyle = useSpring({ width: metricBarWidth });
109
+
110
+ return (
111
+ <Box sx={{ position: 'relative' }}>
112
+ <svg height={height} ref={svgRef} width={width}>
113
+ <Group.Group top={centerY - margins.bottom}>
114
+ {text}
115
+ <animated.rect
116
+ data-testid={`${latestMetricData}-bar-${barColor}`}
117
+ fill={barColor}
118
+ height={barHeight}
119
+ rx={4}
120
+ style={springStyle}
121
+ x={0}
122
+ y={groupMargin + margin}
123
+ />
124
+ <Bar
125
+ fill="transparent"
126
+ height={barHeight}
127
+ rx={4}
128
+ ry={4}
129
+ stroke={alpha(theme.palette.text.primary, 0.3)}
130
+ width={maxBarWidth}
131
+ x={0}
132
+ y={groupMargin + margin}
133
+ />
134
+ {!disabledThresholds && (
135
+ <Thresholds
136
+ hideTooltip={hideTooltip}
137
+ showTooltip={showTooltip}
138
+ thresholdTooltipLabels={thresholdTooltipLabels}
139
+ thresholds={thresholds}
140
+ xScale={xScale}
141
+ />
142
+ )}
143
+ </Group.Group>
144
+ </svg>
145
+ <Fade in={tooltipOpen}>
146
+ <Tooltip.Tooltip
147
+ left={tooltipLeft}
148
+ style={{
149
+ ...baseStyles,
150
+ backgroundColor: theme.palette.background.paper,
151
+ color: theme.palette.text.primary,
152
+ transform: 'translate(-50%, -20px)'
153
+ }}
154
+ top={tooltipTop}
155
+ >
156
+ {tooltipData}
157
+ </Tooltip.Tooltip>
158
+ </Fade>
159
+ </Box>
160
+ );
161
+ };
162
+
163
+ export default ResponsiveSingleBar;
@@ -0,0 +1,45 @@
1
+ import { Meta, StoryObj } from '@storybook/react';
2
+
3
+ import dataLastWeek from '../LineChart/mockedData/lastWeek.json';
4
+
5
+ import { SingleBar } from '.';
6
+
7
+ const meta: Meta<typeof SingleBar> = {
8
+ component: SingleBar
9
+ };
10
+
11
+ export default meta;
12
+ type Story = StoryObj<typeof SingleBar>;
13
+
14
+ const Template = (props): JSX.Element => (
15
+ <div style={{ height: '500px', width: '500px' }}>
16
+ <SingleBar {...props} />
17
+ </div>
18
+ );
19
+
20
+ export const success: Story = {
21
+ args: {
22
+ data: dataLastWeek,
23
+ thresholdTooltipLabels: ['Warning', 'Critical'],
24
+ thresholds: [0.5, 1.5]
25
+ },
26
+ render: Template
27
+ };
28
+
29
+ export const warning: Story = {
30
+ args: {
31
+ data: dataLastWeek,
32
+ thresholdTooltipLabels: ['Warning', 'Critical'],
33
+ thresholds: [0.2, 0.5]
34
+ },
35
+ render: Template
36
+ };
37
+
38
+ export const critical: Story = {
39
+ args: {
40
+ data: dataLastWeek,
41
+ thresholdTooltipLabels: ['Warning', 'Critical'],
42
+ thresholds: [0.13, 0.35]
43
+ },
44
+ render: Template
45
+ };
@@ -0,0 +1,25 @@
1
+ import { Responsive } from '@visx/visx';
2
+
3
+ import { SingleBarProps } from './models';
4
+ import ResponsiveSingleBar from './ResponsiveSingleBar';
5
+
6
+ const SingleBar = ({ data, ...props }: SingleBarProps): JSX.Element | null => {
7
+ if (!data) {
8
+ return null;
9
+ }
10
+
11
+ return (
12
+ <Responsive.ParentSizeModern>
13
+ {({ width, height }) => (
14
+ <ResponsiveSingleBar
15
+ {...props}
16
+ data={data}
17
+ height={height}
18
+ width={width}
19
+ />
20
+ )}
21
+ </Responsive.ParentSizeModern>
22
+ );
23
+ };
24
+
25
+ export default SingleBar;
@@ -0,0 +1,100 @@
1
+ import { useTheme } from '@mui/material';
2
+
3
+ export const margin = 40;
4
+
5
+ export const barHeight = 50;
6
+
7
+ export const groupMargin = 25;
8
+
9
+ const lineMargin = 10;
10
+
11
+ const thresholdLineHeight = 60 + 2 * lineMargin;
12
+
13
+ interface Props {
14
+ hideTooltip: () => void;
15
+ showTooltip: (args) => void;
16
+ thresholdTooltipLabels: Array<string>;
17
+ thresholds: Array<number>;
18
+ xScale: (value: number) => number;
19
+ }
20
+
21
+ const Thresholds = ({
22
+ xScale,
23
+ thresholds,
24
+ showTooltip,
25
+ hideTooltip,
26
+ thresholdTooltipLabels
27
+ }: Props): JSX.Element => {
28
+ const theme = useTheme();
29
+
30
+ const warningValue = thresholds[0];
31
+ const criticalValue = thresholds[1];
32
+ const warningTooltipLabel = thresholdTooltipLabels[0];
33
+ const criticalTooltipLabel = thresholdTooltipLabels[1];
34
+
35
+ const bottom = barHeight + margin * 2;
36
+
37
+ const onMouseEnter =
38
+ ({ label, left }) =>
39
+ (): void =>
40
+ showTooltip({
41
+ tooltipData: label,
42
+ tooltipLeft: left,
43
+ tooltipTop: bottom
44
+ });
45
+
46
+ return (
47
+ <>
48
+ <line
49
+ data-testid="warning-line"
50
+ stroke={theme.palette.warning.main}
51
+ strokeDasharray={4}
52
+ strokeWidth={2}
53
+ x1={xScale(warningValue)}
54
+ x2={xScale(warningValue)}
55
+ y1={groupMargin + 3 * lineMargin}
56
+ y2={thresholdLineHeight + groupMargin + 3 * lineMargin}
57
+ />
58
+ <line
59
+ data-testid="critical-line"
60
+ stroke={theme.palette.error.main}
61
+ strokeDasharray={4}
62
+ strokeWidth={2}
63
+ x1={xScale(criticalValue)}
64
+ x2={xScale(criticalValue)}
65
+ y1={groupMargin + 3 * lineMargin}
66
+ y2={thresholdLineHeight + groupMargin + 3 * lineMargin}
67
+ />
68
+ <line
69
+ data-testid="warning-line-tooltip"
70
+ stroke="transparent"
71
+ strokeWidth={5}
72
+ x1={xScale(warningValue)}
73
+ x2={xScale(warningValue)}
74
+ y1={groupMargin + 3 * lineMargin}
75
+ y2={thresholdLineHeight + groupMargin + 3 * lineMargin}
76
+ onMouseEnter={onMouseEnter({
77
+ label: warningTooltipLabel,
78
+ left: xScale(warningValue)
79
+ })}
80
+ onMouseLeave={hideTooltip}
81
+ />
82
+ <line
83
+ data-testid="critical-line-tooltip"
84
+ stroke="transparent"
85
+ strokeWidth={5}
86
+ x1={xScale(criticalValue)}
87
+ x2={xScale(criticalValue)}
88
+ y1={groupMargin + 3 * lineMargin}
89
+ y2={thresholdLineHeight + groupMargin + 3 * lineMargin}
90
+ onMouseEnter={onMouseEnter({
91
+ label: criticalTooltipLabel,
92
+ left: xScale(criticalValue)
93
+ })}
94
+ onMouseLeave={hideTooltip}
95
+ />
96
+ </>
97
+ );
98
+ };
99
+
100
+ export default Thresholds;
@@ -0,0 +1 @@
1
+ export { default as SingleBar } from './SingleBar';
@@ -0,0 +1,8 @@
1
+ import { LineChartData } from '../common/models';
2
+
3
+ export interface SingleBarProps {
4
+ data?: LineChartData;
5
+ disabledThresholds?: boolean;
6
+ thresholdTooltipLabels: Array<string>;
7
+ thresholds: Array<number>;
8
+ }
@@ -0,0 +1,54 @@
1
+ import { Meta, StoryObj } from '@storybook/react';
2
+
3
+ import dataLastWeek from '../LineChart/mockedData/lastWeek.json';
4
+
5
+ import { Text } from '.';
6
+
7
+ const meta: Meta<typeof Text> = {
8
+ component: Text
9
+ };
10
+
11
+ export default meta;
12
+ type Story = StoryObj<typeof Text>;
13
+
14
+ const Template = (props): JSX.Element => (
15
+ <div style={{ height: '500px', width: '500px' }}>
16
+ <Text {...props} />
17
+ </div>
18
+ );
19
+
20
+ export const success: Story = {
21
+ args: {
22
+ data: dataLastWeek,
23
+ labels: {
24
+ critical: 'Critical',
25
+ warning: 'Warning'
26
+ },
27
+ thresholds: [0.5, 1.5]
28
+ },
29
+ render: Template
30
+ };
31
+
32
+ export const warning: Story = {
33
+ args: {
34
+ data: dataLastWeek,
35
+ labels: {
36
+ critical: 'Critical',
37
+ warning: 'Warning'
38
+ },
39
+ thresholds: [0.2, 0.5]
40
+ },
41
+ render: Template
42
+ };
43
+
44
+ export const critical: Story = {
45
+ args: {
46
+ data: dataLastWeek,
47
+ labels: {
48
+ critical: 'Critical',
49
+ warning: 'Warning'
50
+ },
51
+ thresholds: [0.13, 0.35]
52
+ },
53
+ render: Template
54
+ };
@@ -0,0 +1,17 @@
1
+ import { makeStyles } from 'tss-react/mui';
2
+
3
+ export const useTextStyles = makeStyles()((theme) => ({
4
+ graphText: {
5
+ alignItems: 'center',
6
+ display: 'flex',
7
+ flexDirection: 'column',
8
+ gap: theme.spacing(1),
9
+ height: '100%',
10
+ justifyContent: 'center'
11
+ },
12
+ thresholds: {
13
+ display: 'flex',
14
+ flexDirection: 'row',
15
+ gap: theme.spacing(5)
16
+ }
17
+ }));
@@ -0,0 +1,80 @@
1
+ import { isNil } from 'ramda';
2
+
3
+ import { Typography, useTheme } from '@mui/material';
4
+
5
+ import { LineChartData } from '../common/models';
6
+ import {
7
+ formatMetricValue,
8
+ getMetricWithLatestData
9
+ } from '../common/timeSeries';
10
+ import { getColorFromDataAndTresholds } from '../common/utils';
11
+
12
+ import { useTextStyles } from './Text.styles';
13
+
14
+ interface Props {
15
+ data?: LineChartData;
16
+ disabledThresholds?: boolean;
17
+ labels: {
18
+ critical: string;
19
+ warning: string;
20
+ };
21
+ thresholds: Array<number>;
22
+ }
23
+
24
+ export const Text = ({
25
+ thresholds,
26
+ data,
27
+ labels,
28
+ disabledThresholds
29
+ }: Props): JSX.Element | null => {
30
+ const theme = useTheme();
31
+ const { classes } = useTextStyles();
32
+
33
+ if (isNil(data)) {
34
+ return null;
35
+ }
36
+
37
+ const metric = getMetricWithLatestData(data);
38
+ const metricValue = metric?.data[0] ?? 0;
39
+ const metricUnit = metric?.unit ?? '';
40
+
41
+ const color = getColorFromDataAndTresholds({
42
+ data: metricValue,
43
+ theme,
44
+ thresholds
45
+ });
46
+
47
+ return (
48
+ <div className={classes.graphText}>
49
+ <Typography sx={{ color }} variant="h3">
50
+ {formatMetricValue({
51
+ unit: metricUnit,
52
+ value: metricValue
53
+ })}{' '}
54
+ {metricUnit}
55
+ </Typography>
56
+ {!disabledThresholds && (
57
+ <div className={classes.thresholds}>
58
+ <Typography sx={{ color: 'warning.main' }} variant="h5">
59
+ {labels.warning}
60
+ {': '}
61
+ {formatMetricValue({
62
+ unit: metricUnit,
63
+ value: thresholds[0]
64
+ })}{' '}
65
+ {metricUnit}
66
+ </Typography>
67
+ <Typography sx={{ color: 'error.main' }} variant="h5">
68
+ {labels.critical}
69
+ {': '}
70
+ {formatMetricValue({
71
+ unit: metricUnit,
72
+ value: thresholds[1]
73
+ })}{' '}
74
+ {metricUnit}
75
+ </Typography>
76
+ </div>
77
+ )}
78
+ </div>
79
+ );
80
+ };
@@ -0,0 +1 @@
1
+ export { Text } from './Text';
@@ -0,0 +1 @@
1
+ export const margins = { bottom: 20, left: 20, right: 20, top: 20 };
@@ -0,0 +1,7 @@
1
+ import { Metric } from './timeSeries/models';
2
+
3
+ export interface LineChartData {
4
+ global;
5
+ metrics: Array<Metric>;
6
+ times: Array<string>;
7
+ }
@@ -1,11 +1,11 @@
1
- import { GraphData } from '../models';
1
+ import { LineChartData } from '../models';
2
2
 
3
3
  import * as timeSeries from '.';
4
4
 
5
5
  type TestCase = [number | null, string, 1000 | 1024, string | null];
6
6
 
7
7
  describe('timeSeries', () => {
8
- const graphData: GraphData = {
8
+ const graphData: LineChartData = {
9
9
  global: {},
10
10
  metrics: [
11
11
  {
@@ -26,11 +26,13 @@ import {
26
26
  min,
27
27
  max,
28
28
  lt,
29
- identity
29
+ identity,
30
+ head,
31
+ last
30
32
  } from 'ramda';
31
33
 
32
- import { margin } from '../common';
33
- import { GraphData } from '../models';
34
+ import { margin } from '../../LineChart/common';
35
+ import { LineChartData } from '../models';
34
36
 
35
37
  import {
36
38
  Metric,
@@ -76,7 +78,7 @@ const toTimeTickValue = (
76
78
  return { timeTick, ...getMetricsForIndex() };
77
79
  };
78
80
 
79
- const getTimeSeries = (graphData: GraphData): Array<TimeValue> => {
81
+ const getTimeSeries = (graphData: LineChartData): Array<TimeValue> => {
80
82
  const isGreaterThanLowerLimit = (value): boolean => {
81
83
  const lowerLimit = path<number>(['global', 'lower-limit'], graphData);
82
84
 
@@ -133,7 +135,7 @@ const toLine = ({
133
135
  unit
134
136
  });
135
137
 
136
- const getLineData = (graphData: GraphData): Array<Line> =>
138
+ const getLineData = (graphData: LineChartData): Array<Line> =>
137
139
  map(toLine, graphData.metrics);
138
140
 
139
141
  const getMin = (values: Array<number>): number => Math.min(...values);
@@ -481,6 +483,19 @@ const getTimeValue = ({
481
483
  return timeSeries[index];
482
484
  };
483
485
 
486
+ const getMetricWithLatestData = (
487
+ graphData: LineChartData
488
+ ): Metric | undefined => {
489
+ const metric = head(graphData.metrics) as Metric;
490
+
491
+ const lastData = last(metric?.data.filter((v) => v) || []);
492
+
493
+ return {
494
+ ...metric,
495
+ data: lastData ? [lastData] : []
496
+ };
497
+ };
498
+
484
499
  export {
485
500
  getTimeSeries,
486
501
  getLineData,
@@ -508,5 +523,6 @@ export {
508
523
  formatMetricValue,
509
524
  getStackedYScale,
510
525
  getTimeValue,
511
- bisectDate
526
+ bisectDate,
527
+ getMetricWithLatestData
512
528
  };
@@ -13,6 +13,7 @@ interface DsData {
13
13
 
14
14
  export interface Metric {
15
15
  average_value: number | null;
16
+ crit: number | null;
16
17
  data: Array<number>;
17
18
  ds_data: DsData;
18
19
  legend: string;
@@ -20,6 +21,7 @@ export interface Metric {
20
21
  metric: string;
21
22
  minimum_value: number | null;
22
23
  unit: string;
24
+ warn: number | null;
23
25
  }
24
26
 
25
27
  type TimeSeries = { timeTick: string };
@@ -0,0 +1,20 @@
1
+ import { T, always, cond, gt, head } from 'ramda';
2
+
3
+ import { Theme } from '@mui/material';
4
+
5
+ interface GetColorFromDataAndThresholdsProps {
6
+ data: number;
7
+ theme: Theme;
8
+ thresholds: Array<number>;
9
+ }
10
+
11
+ export const getColorFromDataAndTresholds = ({
12
+ data,
13
+ thresholds,
14
+ theme
15
+ }: GetColorFromDataAndThresholdsProps): string =>
16
+ cond([
17
+ [gt(head(thresholds) as number), always(theme.palette.success.main)],
18
+ [gt(thresholds[1]), always(theme.palette.warning.main)],
19
+ [T, always(theme.palette.error.main)]
20
+ ])(data);
@@ -0,0 +1,4 @@
1
+ export { default as LineChart } from './LineChart';
2
+ export { Gauge } from './Gauge';
3
+ export { SingleBar } from './SingleBar';
4
+ export { Text as GraphText } from './Text';
@@ -47,7 +47,7 @@ const useStyles = makeStyles<StyleProps>()(
47
47
 
48
48
  interface Props {
49
49
  className?: string;
50
- disabled: boolean;
50
+ disabled?: boolean;
51
51
  editable: boolean;
52
52
  editorState?: string;
53
53
  error?: string;
@@ -61,6 +61,9 @@ interface Props {
61
61
  resetEditorToInitialStateCondition?: () => boolean;
62
62
  }
63
63
 
64
+ const defaultState =
65
+ '{"root":{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1}],"direction":null,"format":"","indent":0,"type":"root","version":1}}';
66
+
64
67
  const ContentEditable = ({
65
68
  minInputHeight,
66
69
  inputClassname,
@@ -91,8 +94,10 @@ const ContentEditable = ({
91
94
  );
92
95
 
93
96
  useLayoutEffect(() => {
94
- if (editorState && !editable) {
95
- const newEditorState = editor.parseEditorState(editorState);
97
+ if (!editable) {
98
+ const newEditorState = editor.parseEditorState(
99
+ editorState || defaultState
100
+ );
96
101
 
97
102
  editor.setEditorState(newEditorState);
98
103
  }