@centreon/ui 26.11.12 → 26.11.13
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 +1 -1
- package/src/Graph/BarChart/BarChart.cypress.spec.tsx +81 -0
- package/src/Graph/BarChart/Tooltip/BarChartTooltip.tsx +8 -9
- package/src/Graph/Chart/Chart.cypress.spec.tsx +42 -0
- package/src/Graph/Chart/InteractiveComponents/GraphValueTooltip/GraphValueTooltip.tsx +1 -1
- package/src/Graph/Chart/InteractiveComponents/GraphValueTooltip/GraphValueTooltipContent.tsx +5 -4
- package/src/Graph/Chart/InteractiveComponents/GraphValueTooltip/useGraphValueTooltip.ts +13 -21
- package/src/Graph/Chart/models.ts +1 -1
- package/src/Graph/common/utils.ts +23 -1
package/package.json
CHANGED
|
@@ -3,6 +3,7 @@ import { userAtom } from '@centreon/ui-context';
|
|
|
3
3
|
import { renderHook } from '@testing-library/react';
|
|
4
4
|
import dayjs from 'dayjs';
|
|
5
5
|
import { useAtomValue } from 'jotai';
|
|
6
|
+
import { equals, update } from 'ramda';
|
|
6
7
|
|
|
7
8
|
import { labelAvg, labelMax, labelMin } from '../Chart/translatedLabels';
|
|
8
9
|
import dataMissingPoint from '../mockedData/dataWithMissingPoint.json';
|
|
@@ -19,6 +20,29 @@ const defaultStart = new Date(
|
|
|
19
20
|
|
|
20
21
|
const defaultEnd = new Date(Date.now()).toISOString();
|
|
21
22
|
|
|
23
|
+
const hoveredStackedBarIndex = 6;
|
|
24
|
+
|
|
25
|
+
const dataPingServiceStackedWithUndefinedValues = {
|
|
26
|
+
...dataPingServiceStacked,
|
|
27
|
+
metrics: dataPingServiceStacked.metrics.map((metric) => {
|
|
28
|
+
if (equals(metric.metric_id, 3)) {
|
|
29
|
+
return {
|
|
30
|
+
...metric,
|
|
31
|
+
data: update(hoveredStackedBarIndex, null, metric.data)
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (equals(metric.metric_id, 4)) {
|
|
36
|
+
return {
|
|
37
|
+
...metric,
|
|
38
|
+
data: update(hoveredStackedBarIndex, 0, metric.data)
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return metric;
|
|
43
|
+
})
|
|
44
|
+
};
|
|
45
|
+
|
|
22
46
|
const defaultArgs = {
|
|
23
47
|
end: defaultEnd,
|
|
24
48
|
height: 500,
|
|
@@ -229,6 +253,63 @@ describe('Bar chart', () => {
|
|
|
229
253
|
});
|
|
230
254
|
});
|
|
231
255
|
|
|
256
|
+
it('displays only metrics with a defined value in the tooltip when the mode is set to defined', () => {
|
|
257
|
+
initialize({
|
|
258
|
+
data: dataPingServiceStackedWithUndefinedValues,
|
|
259
|
+
orientation: 'horizontal',
|
|
260
|
+
tooltip: {
|
|
261
|
+
mode: 'defined',
|
|
262
|
+
sortOrder: 'name'
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
checkWidth();
|
|
267
|
+
cy.contains('0 ms').should('be.visible');
|
|
268
|
+
cy.contains(':40 AM').should('be.visible');
|
|
269
|
+
|
|
270
|
+
cy.get('body').realMouseMove(0, 0);
|
|
271
|
+
cy.findByTestId('stacked-bar-1-0-0.05296').realHover();
|
|
272
|
+
|
|
273
|
+
cy.contains('06/19/2024').should('be.visible');
|
|
274
|
+
|
|
275
|
+
cy.get('[data-metric="Centreon-Server: Round-Trip Average Time"]').should(
|
|
276
|
+
'be.visible'
|
|
277
|
+
);
|
|
278
|
+
cy.get('[data-metric="Centreon-Server: Round-Trip Maximum Time"]').should(
|
|
279
|
+
'not.exist'
|
|
280
|
+
);
|
|
281
|
+
cy.get('[data-metric="Centreon-Server: Round-Trip Minimum Time"]').should(
|
|
282
|
+
'not.exist'
|
|
283
|
+
);
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
it('displays metrics with an undefined value in the tooltip when the mode is set to all', () => {
|
|
287
|
+
initialize({
|
|
288
|
+
data: dataPingServiceStackedWithUndefinedValues,
|
|
289
|
+
orientation: 'horizontal',
|
|
290
|
+
tooltip: {
|
|
291
|
+
mode: 'all',
|
|
292
|
+
sortOrder: 'name'
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
checkWidth();
|
|
297
|
+
cy.contains('0 ms').should('be.visible');
|
|
298
|
+
cy.contains(':40 AM').should('be.visible');
|
|
299
|
+
|
|
300
|
+
cy.get('body').realMouseMove(0, 0);
|
|
301
|
+
cy.findByTestId('stacked-bar-1-0-0.05296').realHover();
|
|
302
|
+
|
|
303
|
+
cy.contains('06/19/2024').should('be.visible');
|
|
304
|
+
|
|
305
|
+
cy.get('[data-metric="Centreon-Server: Round-Trip Maximum Time"]').should(
|
|
306
|
+
'be.visible'
|
|
307
|
+
);
|
|
308
|
+
cy.get('[data-metric="Centreon-Server: Round-Trip Minimum Time"]').should(
|
|
309
|
+
'be.visible'
|
|
310
|
+
);
|
|
311
|
+
});
|
|
312
|
+
|
|
232
313
|
it('does not display a tooltip when a bar is hovered and a props is set', () => {
|
|
233
314
|
initialize({
|
|
234
315
|
data: dataPingServiceStacked,
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
always,
|
|
6
6
|
cond,
|
|
7
7
|
equals,
|
|
8
|
-
filter,
|
|
9
8
|
gt,
|
|
10
9
|
has,
|
|
11
10
|
isNil,
|
|
@@ -20,6 +19,7 @@ import { useLocaleDateTimeFormat } from '../../../utils';
|
|
|
20
19
|
import type { Tooltip } from '../../Chart/models';
|
|
21
20
|
import { formatMetricValueWithUnit } from '../../common/timeSeries';
|
|
22
21
|
import type { TimeValue } from '../../common/timeSeries/models';
|
|
22
|
+
import { isMetricDisplayedInTooltip } from '../../common/utils';
|
|
23
23
|
import { tooltipDataAtom } from '../atoms';
|
|
24
24
|
import { useBarChartTooltipStyles } from './useBarChartTooltipStyles';
|
|
25
25
|
|
|
@@ -49,14 +49,13 @@ const BarChartTooltip = ({
|
|
|
49
49
|
const date = timeSeries[tooltipData.index].timeTick;
|
|
50
50
|
const formattedDateTime = format({ date, formatString: 'L LTS' });
|
|
51
51
|
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
: tooltipData.data;
|
|
52
|
+
const filteredMetrics = tooltipData.data.filter(({ metric, value }) =>
|
|
53
|
+
isMetricDisplayedInTooltip({
|
|
54
|
+
isHighlighted: equals(metric.metric_id, tooltipData.highlightedMetric),
|
|
55
|
+
mode,
|
|
56
|
+
value
|
|
57
|
+
})
|
|
58
|
+
);
|
|
60
59
|
|
|
61
60
|
const displayHighLightedMetric = gt(filteredMetrics.length, 1);
|
|
62
61
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { userAtom } from '@centreon/ui-context';
|
|
2
2
|
|
|
3
3
|
import { createStore, Provider } from 'jotai';
|
|
4
|
+
import { always, equals } from 'ramda';
|
|
4
5
|
import { useState } from 'react';
|
|
5
6
|
|
|
6
7
|
import type { LineChartData } from '../common/models';
|
|
@@ -17,6 +18,15 @@ import { args as argumentsData } from './helpers/doc';
|
|
|
17
18
|
import type { LineChartProps } from './models';
|
|
18
19
|
import { labelAvg, labelMin } from './translatedLabels';
|
|
19
20
|
|
|
21
|
+
const dataLastDayWithZeroConnTime = {
|
|
22
|
+
...dataLastDay,
|
|
23
|
+
metrics: dataLastDay.metrics.map((metric) =>
|
|
24
|
+
equals(metric.metric, 'connTime')
|
|
25
|
+
? { ...metric, data: metric.data.map(always(0)) }
|
|
26
|
+
: metric
|
|
27
|
+
)
|
|
28
|
+
};
|
|
29
|
+
|
|
20
30
|
interface Props
|
|
21
31
|
extends Pick<
|
|
22
32
|
LineChartProps,
|
|
@@ -281,6 +291,38 @@ describe('Line chart', () => {
|
|
|
281
291
|
|
|
282
292
|
cy.makeSnapshot();
|
|
283
293
|
});
|
|
294
|
+
|
|
295
|
+
it('displays only metrics with a defined value when the mode is set to defined', () => {
|
|
296
|
+
initialize({
|
|
297
|
+
data: dataLastDayWithZeroConnTime,
|
|
298
|
+
tooltip: { mode: 'defined', sortOrder: 'name' }
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
checkGraphWidth();
|
|
302
|
+
|
|
303
|
+
cy.contains('Min: 70.31').should('be.visible');
|
|
304
|
+
|
|
305
|
+
cy.findByTestId('graph-interaction-zone').realMouseMove(452, 26);
|
|
306
|
+
|
|
307
|
+
cy.get('[data-metric="querytime"]').should('be.visible');
|
|
308
|
+
cy.get('[data-metric="connTime"]').should('not.exist');
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
it('displays metrics with a zero value when the mode is set to all', () => {
|
|
312
|
+
initialize({
|
|
313
|
+
data: dataLastDayWithZeroConnTime,
|
|
314
|
+
tooltip: { mode: 'all', sortOrder: 'name' }
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
checkGraphWidth();
|
|
318
|
+
|
|
319
|
+
cy.contains('Min: 70.31').should('be.visible');
|
|
320
|
+
|
|
321
|
+
cy.findByTestId('graph-interaction-zone').realMouseMove(452, 26);
|
|
322
|
+
|
|
323
|
+
cy.get('[data-metric="querytime"]').should('be.visible');
|
|
324
|
+
cy.get('[data-metric="connTime"]').should('be.visible');
|
|
325
|
+
});
|
|
284
326
|
});
|
|
285
327
|
|
|
286
328
|
it('displays the curves with different shades when curves have same color', () => {
|
|
@@ -48,7 +48,7 @@ const GraphValueTooltip = ({
|
|
|
48
48
|
equals('hidden', tooltip?.mode) ? null : (
|
|
49
49
|
<GraphValueTooltipContent
|
|
50
50
|
base={baseAxis}
|
|
51
|
-
|
|
51
|
+
mode={tooltip?.mode}
|
|
52
52
|
// @ts-expect-error - suppressing pre-existing type mismatch
|
|
53
53
|
sortOrder={tooltip?.sortOrder}
|
|
54
54
|
/>
|
package/src/Graph/Chart/InteractiveComponents/GraphValueTooltip/GraphValueTooltipContent.tsx
CHANGED
|
@@ -9,20 +9,21 @@ import { mousePositionAtom } from '../interactionWithGraphAtoms';
|
|
|
9
9
|
import { useGraphValueTooltip } from './useGraphValueTooltip';
|
|
10
10
|
import { useGraphValueTooltipStyles } from './useGraphValueTooltipStyles';
|
|
11
11
|
|
|
12
|
-
interface Props
|
|
12
|
+
interface Props
|
|
13
|
+
extends Pick<Tooltip, 'sortOrder'>,
|
|
14
|
+
Partial<Pick<Tooltip, 'mode'>> {
|
|
13
15
|
base: number;
|
|
14
|
-
isSingleMode: boolean;
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
const GraphValueTooltipContent = ({
|
|
18
19
|
base,
|
|
19
|
-
|
|
20
|
+
mode,
|
|
20
21
|
sortOrder
|
|
21
22
|
}: Props): JSX.Element | null => {
|
|
22
23
|
const { classes } = useGraphValueTooltipStyles();
|
|
23
24
|
const mousePosition = useAtomValue(mousePositionAtom);
|
|
24
25
|
|
|
25
|
-
const graphValue = useGraphValueTooltip({
|
|
26
|
+
const graphValue = useGraphValueTooltip({ mode, sortOrder });
|
|
26
27
|
|
|
27
28
|
if (isNil(graphValue) || isNil(mousePosition)) {
|
|
28
29
|
return null;
|
|
@@ -1,17 +1,8 @@
|
|
|
1
1
|
import { useAtomValue } from 'jotai';
|
|
2
|
-
import {
|
|
3
|
-
always,
|
|
4
|
-
cond,
|
|
5
|
-
equals,
|
|
6
|
-
filter,
|
|
7
|
-
isNil,
|
|
8
|
-
prop,
|
|
9
|
-
reverse,
|
|
10
|
-
sortBy,
|
|
11
|
-
T
|
|
12
|
-
} from 'ramda';
|
|
2
|
+
import { always, cond, equals, isNil, prop, reverse, sortBy, T } from 'ramda';
|
|
13
3
|
|
|
14
4
|
import { useLocaleDateTimeFormat } from '../../../../utils';
|
|
5
|
+
import { isMetricDisplayedInTooltip } from '../../../common/utils';
|
|
15
6
|
import type { GraphTooltipData, Tooltip } from '../../models';
|
|
16
7
|
import { graphTooltipDataAtom } from '../interactionWithGraphAtoms';
|
|
17
8
|
|
|
@@ -19,12 +10,12 @@ interface UseGraphValueTooltipState extends Omit<GraphTooltipData, 'date'> {
|
|
|
19
10
|
dateTime: string;
|
|
20
11
|
}
|
|
21
12
|
|
|
22
|
-
interface UseGraphValueTooltipProps
|
|
23
|
-
|
|
24
|
-
}
|
|
13
|
+
interface UseGraphValueTooltipProps
|
|
14
|
+
extends Pick<Tooltip, 'sortOrder'>,
|
|
15
|
+
Partial<Pick<Tooltip, 'mode'>> {}
|
|
25
16
|
|
|
26
17
|
export const useGraphValueTooltip = ({
|
|
27
|
-
|
|
18
|
+
mode,
|
|
28
19
|
sortOrder
|
|
29
20
|
}: UseGraphValueTooltipProps): UseGraphValueTooltipState | null => {
|
|
30
21
|
const { format } = useLocaleDateTimeFormat();
|
|
@@ -34,12 +25,13 @@ export const useGraphValueTooltip = ({
|
|
|
34
25
|
return null;
|
|
35
26
|
}
|
|
36
27
|
|
|
37
|
-
const filteredMetrics =
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
28
|
+
const filteredMetrics = graphTooltipData.metrics.filter(({ id, value }) =>
|
|
29
|
+
isMetricDisplayedInTooltip({
|
|
30
|
+
isHighlighted: equals(id, graphTooltipData.highlightedMetricId),
|
|
31
|
+
mode,
|
|
32
|
+
value
|
|
33
|
+
})
|
|
34
|
+
);
|
|
43
35
|
|
|
44
36
|
const sortedMetrics = cond([
|
|
45
37
|
[equals('name'), always(sortBy(prop('name'), filteredMetrics))],
|
|
@@ -74,7 +74,7 @@ export interface ThresholdTooltip {
|
|
|
74
74
|
thresholdLabel?: string;
|
|
75
75
|
}
|
|
76
76
|
export interface Tooltip {
|
|
77
|
-
mode: 'all' | 'single' | 'hidden';
|
|
77
|
+
mode: 'all' | 'single' | 'hidden' | 'defined';
|
|
78
78
|
renderComponent?: (args: TooltipData) => ReactNode;
|
|
79
79
|
sortOrder: 'name' | 'ascending' | 'descending';
|
|
80
80
|
}
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
} from 'ramda';
|
|
23
23
|
|
|
24
24
|
import type { BarStyle } from '../BarChart/models';
|
|
25
|
-
import type { LineStyle } from '../Chart/models';
|
|
25
|
+
import type { LineStyle, Tooltip } from '../Chart/models';
|
|
26
26
|
import type { Threshold, Thresholds } from './models';
|
|
27
27
|
import { formatMetricValueWithUnit } from './timeSeries';
|
|
28
28
|
import type { Line, TimeValue } from './timeSeries/models';
|
|
@@ -278,3 +278,25 @@ export const computPixelsToShiftMouse = (
|
|
|
278
278
|
|
|
279
279
|
return Math.round(8 / hoursDiffInGraph);
|
|
280
280
|
};
|
|
281
|
+
|
|
282
|
+
interface IsMetricDisplayedInTooltipProps
|
|
283
|
+
extends Partial<Pick<Tooltip, 'mode'>> {
|
|
284
|
+
isHighlighted: boolean;
|
|
285
|
+
value?: number | null;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export const isMetricDisplayedInTooltip = ({
|
|
289
|
+
mode,
|
|
290
|
+
isHighlighted,
|
|
291
|
+
value
|
|
292
|
+
}: IsMetricDisplayedInTooltipProps): boolean => {
|
|
293
|
+
if (equals(mode, 'single')) {
|
|
294
|
+
return isHighlighted;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (equals(mode, 'defined')) {
|
|
298
|
+
return Boolean(value);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return true;
|
|
302
|
+
};
|