@centreon/ui 24.4.72 → 24.4.74
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 +24 -23
- package/src/Checkbox/fonts/roboto-bold-webfont.ttf +0 -0
- package/src/Checkbox/fonts/roboto-bold-webfont.woff +0 -0
- package/src/Checkbox/fonts/roboto-bold-webfont.woff2 +0 -0
- package/src/Checkbox/fonts/roboto-light-webfont.ttf +0 -0
- package/src/Checkbox/fonts/roboto-light-webfont.woff +0 -0
- package/src/Checkbox/fonts/roboto-light-webfont.woff2 +0 -0
- package/src/Checkbox/fonts/roboto-medium-webfont.ttf +0 -0
- package/src/Checkbox/fonts/roboto-medium-webfont.woff +0 -0
- package/src/Checkbox/fonts/roboto-medium-webfont.woff2 +0 -0
- package/src/Checkbox/fonts/roboto-regular-webfont.ttf +0 -0
- package/src/Checkbox/fonts/roboto-regular-webfont.woff +0 -0
- package/src/Checkbox/fonts/roboto-regular-webfont.woff2 +0 -0
- package/src/Dashboard/Item.tsx +2 -11
- package/src/Dashboard/Layout.tsx +2 -4
- package/src/Dashboard/utils.ts +1 -1
- package/src/Form/Inputs/Grid.tsx +8 -4
- package/src/Form/Inputs/models.ts +15 -14
- package/src/Graph/BarStack/BarStack.cypress.spec.tsx +87 -9
- package/src/Graph/BarStack/BarStack.stories.tsx +4 -2
- package/src/Graph/BarStack/BarStack.styles.ts +59 -30
- package/src/Graph/BarStack/Graph.tsx +176 -0
- package/src/Graph/BarStack/GraphAndLegend.tsx +119 -0
- package/src/Graph/BarStack/ResponsiveBarStack.tsx +62 -157
- package/src/Graph/BarStack/constants.ts +5 -0
- package/src/Graph/BarStack/models.ts +1 -1
- package/src/Graph/BarStack/useGraphAndLegend.ts +86 -0
- package/src/Graph/BarStack/useResponsiveBarStack.ts +74 -99
- package/src/Graph/HeatMap/ResponsiveHeatMap.tsx +19 -2
- package/src/Graph/HeatMap/model.ts +5 -1
- package/src/Graph/Legend/Legend.styles.ts +10 -0
- package/src/Graph/Legend/Legend.tsx +6 -1
- package/src/Graph/LineChart/BasicComponents/Lines/RegularLines/index.tsx +2 -1
- package/src/Graph/LineChart/BasicComponents/Lines/StackedLines/index.tsx +3 -4
- package/src/Graph/LineChart/Icons/Downtime.tsx +3 -3
- package/src/Graph/LineChart/InteractiveComponents/ZoomPreview/index.tsx +2 -1
- package/src/Graph/LineChart/Legend/Legend.styles.ts +16 -5
- package/src/Graph/LineChart/Legend/LegendHeader.tsx +4 -1
- package/src/Graph/LineChart/Legend/index.tsx +12 -5
- package/src/Graph/LineChart/LineChart.cypress.spec.tsx +53 -0
- package/src/Graph/LineChart/LineChart.tsx +10 -9
- package/src/Graph/LineChart/index.stories.tsx +13 -0
- package/src/Graph/LineChart/mockedData/curvesWithSameColor.json +252 -0
- package/src/Graph/LineChart/useLineChartData.ts +68 -18
- package/src/Graph/PieChart/ResponsivePie.tsx +3 -1
- package/src/Graph/PieChart/models.ts +1 -0
- package/src/Graph/Tree/DescendantNodes.tsx +0 -1
- package/src/Graph/Tree/Links.tsx +2 -15
- package/src/Graph/Tree/Tree.cypress.spec.tsx +0 -24
- package/src/Graph/Tree/Tree.stories.tsx +1 -17
- package/src/Graph/Tree/models.ts +0 -3
- package/src/Graph/common/utils.ts +51 -2
- package/src/Icon/BaseIcon.tsx +32 -0
- package/src/Icon/DowntimeIcon.tsx +14 -0
- package/src/InputField/Select/Autocomplete/Connected/Multi/index.test.tsx +21 -1
- package/src/InputField/Select/Autocomplete/Connected/index.test.tsx +2 -2
- package/src/InputField/Select/Autocomplete/Connected/index.tsx +10 -7
- package/src/InputField/Select/Autocomplete/Multi/index.stories.tsx +19 -0
- package/src/InputField/Select/Autocomplete/Multi/index.tsx +8 -5
- package/src/InputField/Text/index.tsx +7 -5
- package/src/Listing/ActionBar/index.tsx +1 -0
- package/src/PopoverMenu/index.tsx +4 -4
- package/src/RichTextEditor/ContentEditable.tsx +195 -195
- package/src/StoryBookThemeProvider/index.tsx +35 -36
- package/src/ThemeProvider/index.tsx +12 -12
- package/src/ThemeProvider/palettes.ts +11 -8
- package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/PickersStartEndDate.tsx +2 -3
- package/src/TimePeriods/DateTimePickerInput.tsx +4 -1
- package/src/TopCounterElements/TopCounterLayout.tsx +4 -3
- package/src/TopCounterElements/useCloseOnLegacyPage.tsx +9 -6
- package/src/api/buildListingEndpoint/getSearchQueryParameterValue.ts +7 -1
- package/src/api/buildListingEndpoint/models.ts +1 -0
- package/src/api/useGraphQuery/index.ts +1 -7
- package/src/components/Form/AccessRights/AccessRights.cypress.spec.tsx +13 -27
- package/src/components/Form/AccessRights/AccessRights.stories.tsx +19 -0
- package/src/components/Form/AccessRights/AccessRights.styles.ts +1 -1
- package/src/components/Form/AccessRights/AccessRights.tsx +5 -6
- package/src/components/Form/AccessRights/Actions/Actions.styles.ts +7 -3
- package/src/components/Form/AccessRights/Actions/Actions.tsx +32 -15
- package/src/components/Form/AccessRights/Actions/useActions.ts +37 -4
- package/src/components/Form/AccessRights/models.ts +3 -0
- package/src/components/Form/AccessRights/storiesData.ts +3 -0
- package/src/components/List/Item/ListItem.styles.ts +2 -2
- package/src/components/Zoom/Minimap.tsx +2 -4
- package/src/components/Zoom/Zoom.cypress.spec.tsx +13 -13
- package/src/components/Zoom/Zoom.tsx +1 -4
- package/src/components/Zoom/ZoomContent.tsx +2 -5
- package/src/components/index.ts +0 -1
- package/src/fonts/roboto-bold-webfont.ttf +0 -0
- package/src/fonts/roboto-bold-webfont.woff +0 -0
- package/src/fonts/roboto-bold-webfont.woff2 +0 -0
- package/src/fonts/roboto-light-webfont.ttf +0 -0
- package/src/fonts/roboto-light-webfont.woff +0 -0
- package/src/fonts/roboto-light-webfont.woff2 +0 -0
- package/src/fonts/roboto-medium-webfont.ttf +0 -0
- package/src/fonts/roboto-medium-webfont.woff +0 -0
- package/src/fonts/roboto-medium-webfont.woff2 +0 -0
- package/src/fonts/roboto-regular-webfont.ttf +0 -0
- package/src/fonts/roboto-regular-webfont.woff +0 -0
- package/src/fonts/roboto-regular-webfont.woff2 +0 -0
- package/src/index.ts +1 -0
- package/src/utils/index.ts +25 -25
- package/src/utils/useFullscreen/Fullscreen.cypress.spec.tsx +3 -0
- package/src/utils/useInfiniteScrollListing.ts +6 -1
- package/src/utils/useLocale/index.ts +10 -0
- package/src/utils/useLocale/useLocale.cypress.spec.tsx +40 -0
- package/src/utils/useLocaleDateTimeFormat/index.ts +5 -2
- package/src/utils/usePluralizedTranslation.ts +4 -21
- package/src/@assets/icons/downtime.icon.svg +0 -1
- package/src/components/Form/AccessRights/useAccessRightsChange.ts +0 -30
- package/src/components/Form/AccessRights/utils.ts +0 -18
- package/src/components/Tabs/Tab.styles.ts +0 -25
- package/src/components/Tabs/TabPanel.tsx +0 -22
- package/src/components/Tabs/Tabs.cypress.spec.tsx +0 -70
- package/src/components/Tabs/Tabs.stories.tsx +0 -55
- package/src/components/Tabs/Tabs.tsx +0 -55
- package/src/components/Tabs/index.ts +0 -6
- package/src/utils/resourcesStatusURL.ts +0 -166
- package/src/utils/usePluralizedTranslation.test.ts +0 -159
- /package/{public → src/Button}/fonts/roboto-bold-webfont.ttf +0 -0
- /package/{public → src/Button}/fonts/roboto-bold-webfont.woff +0 -0
- /package/{public → src/Button}/fonts/roboto-bold-webfont.woff2 +0 -0
- /package/{public → src/Button}/fonts/roboto-light-webfont.ttf +0 -0
- /package/{public → src/Button}/fonts/roboto-light-webfont.woff +0 -0
- /package/{public → src/Button}/fonts/roboto-light-webfont.woff2 +0 -0
- /package/{public → src/Button}/fonts/roboto-medium-webfont.ttf +0 -0
- /package/{public → src/Button}/fonts/roboto-medium-webfont.woff +0 -0
- /package/{public → src/Button}/fonts/roboto-medium-webfont.woff2 +0 -0
- /package/{public → src/Button}/fonts/roboto-regular-webfont.ttf +0 -0
- /package/{public → src/Button}/fonts/roboto-regular-webfont.woff +0 -0
- /package/{public → src/Button}/fonts/roboto-regular-webfont.woff2 +0 -0
|
@@ -1,38 +1,30 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
|
|
3
|
+
import { scaleOrdinal } from '@visx/scale';
|
|
4
|
+
import { equals, isNil, pluck } from 'ramda';
|
|
3
5
|
|
|
4
|
-
import { getValueByUnit } from '../common/utils';
|
|
5
6
|
import { LegendScale } from '../Legend/models';
|
|
7
|
+
import { getValueByUnit } from '../common/utils';
|
|
6
8
|
|
|
7
9
|
import { BarType } from './models';
|
|
8
10
|
|
|
9
|
-
interface
|
|
10
|
-
height: number;
|
|
11
|
-
width: number;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
interface useBarStackProps {
|
|
11
|
+
interface UseBarStackProps {
|
|
15
12
|
data: Array<BarType>;
|
|
16
13
|
height: number;
|
|
17
|
-
|
|
18
|
-
size: number;
|
|
19
|
-
titleRef;
|
|
14
|
+
legendDirection?: 'column' | 'row';
|
|
20
15
|
unit?: 'percentage' | 'number';
|
|
21
16
|
variant?: 'vertical' | 'horizontal';
|
|
22
17
|
width: number;
|
|
23
18
|
}
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
|
|
20
|
+
interface UseBarStackState {
|
|
26
21
|
colorScale;
|
|
27
|
-
|
|
22
|
+
formattedLegendDirection: 'column' | 'row';
|
|
23
|
+
isSmall: boolean;
|
|
28
24
|
isVerticalBar: boolean;
|
|
29
|
-
keys: Array<string>;
|
|
30
25
|
legendScale: LegendScale;
|
|
31
|
-
|
|
32
|
-
svgWrapperWidth: number;
|
|
26
|
+
titleVariant: 'xs' | 'sm' | 'md';
|
|
33
27
|
total: number;
|
|
34
|
-
xScale;
|
|
35
|
-
yScale;
|
|
36
28
|
}
|
|
37
29
|
|
|
38
30
|
const useResponsiveBarStack = ({
|
|
@@ -41,90 +33,73 @@ const useResponsiveBarStack = ({
|
|
|
41
33
|
height,
|
|
42
34
|
width,
|
|
43
35
|
unit = 'number',
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
domain:
|
|
78
|
-
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
const xMax = barSize.width;
|
|
105
|
-
const yMax = barSize.height;
|
|
106
|
-
|
|
107
|
-
xScale.rangeRound([0, xMax]);
|
|
108
|
-
yScale.range([yMax, 0]);
|
|
109
|
-
|
|
110
|
-
const input = data.reduce((acc, { label, value }) => {
|
|
111
|
-
acc[label] = value;
|
|
112
|
-
|
|
113
|
-
return acc;
|
|
114
|
-
}, {});
|
|
36
|
+
legendDirection
|
|
37
|
+
}: UseBarStackProps): UseBarStackState => {
|
|
38
|
+
const total = useMemo(
|
|
39
|
+
() => Math.floor(data.reduce((acc, { value }) => acc + value, 0)),
|
|
40
|
+
[data]
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
const isVerticalBar = useMemo(() => equals(variant, 'vertical'), [variant]);
|
|
44
|
+
|
|
45
|
+
const isSmall = useMemo(
|
|
46
|
+
() => Math.floor(height) < 90,
|
|
47
|
+
[isVerticalBar, height]
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const titleVariant = useMemo(() => {
|
|
51
|
+
if (width <= 105) {
|
|
52
|
+
return 'xs';
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (width <= 150 || isSmall) {
|
|
56
|
+
return 'sm';
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return 'md';
|
|
60
|
+
}, [isSmall, width]);
|
|
61
|
+
|
|
62
|
+
const keys = useMemo(() => pluck('label', data), [data]);
|
|
63
|
+
|
|
64
|
+
const colorsRange = useMemo(() => pluck('color', data), [data]);
|
|
65
|
+
|
|
66
|
+
const colorScale = useMemo(
|
|
67
|
+
() =>
|
|
68
|
+
scaleOrdinal({
|
|
69
|
+
domain: keys,
|
|
70
|
+
range: colorsRange
|
|
71
|
+
}),
|
|
72
|
+
[keys, colorsRange]
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
const legendScale = useMemo(
|
|
76
|
+
() => ({
|
|
77
|
+
domain: data.map(({ value }) => getValueByUnit({ total, unit, value })),
|
|
78
|
+
range: colorsRange
|
|
79
|
+
}),
|
|
80
|
+
[data, colorsRange]
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
const formattedLegendDirection = useMemo(() => {
|
|
84
|
+
if (!isNil(legendDirection)) {
|
|
85
|
+
return legendDirection;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (equals(variant, 'horizontal')) {
|
|
89
|
+
return 'row';
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return 'column';
|
|
93
|
+
}, [legendDirection, variant]);
|
|
115
94
|
|
|
116
95
|
return {
|
|
117
|
-
barSize,
|
|
118
96
|
colorScale,
|
|
119
|
-
|
|
97
|
+
formattedLegendDirection,
|
|
98
|
+
isSmall,
|
|
120
99
|
isVerticalBar,
|
|
121
|
-
keys,
|
|
122
100
|
legendScale,
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
total,
|
|
126
|
-
xScale,
|
|
127
|
-
yScale
|
|
101
|
+
titleVariant,
|
|
102
|
+
total
|
|
128
103
|
};
|
|
129
104
|
};
|
|
130
105
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useMemo } from 'react';
|
|
1
|
+
import { useMemo, useRef } from 'react';
|
|
2
2
|
|
|
3
3
|
import { scaleLinear } from '@visx/scale';
|
|
4
4
|
import { T, equals, gt, lt } from 'ramda';
|
|
@@ -13,6 +13,7 @@ import { useHeatMapStyles } from './HeatMap.styles';
|
|
|
13
13
|
const gap = 8;
|
|
14
14
|
const maxTileSize = 120;
|
|
15
15
|
const smallestTileSize = 44;
|
|
16
|
+
const toleratedRangeWidth = 10;
|
|
16
17
|
|
|
17
18
|
const ResponsiveHeatMap = <TData,>({
|
|
18
19
|
width,
|
|
@@ -24,6 +25,7 @@ const ResponsiveHeatMap = <TData,>({
|
|
|
24
25
|
displayTooltipCondition = T
|
|
25
26
|
}: HeatMapProps<TData> & { width: number }): JSX.Element | null => {
|
|
26
27
|
const { classes, cx } = useHeatMapStyles();
|
|
28
|
+
const previousTileSize = useRef(0);
|
|
27
29
|
|
|
28
30
|
const tileSize = useMemo(() => {
|
|
29
31
|
const scaleWidth = scaleLinear({
|
|
@@ -39,6 +41,12 @@ const ResponsiveHeatMap = <TData,>({
|
|
|
39
41
|
tilesLength * maxTileSize + (tilesLength - 1) * gap;
|
|
40
42
|
const theoricalTotalTilesWidth =
|
|
41
43
|
tilesLength * tileWidth + (tilesLength - 1) * gap;
|
|
44
|
+
const canUpdateTileSize =
|
|
45
|
+
Math.abs(tileWidth - previousTileSize.current) > toleratedRangeWidth;
|
|
46
|
+
|
|
47
|
+
if (!canUpdateTileSize) {
|
|
48
|
+
return previousTileSize.current;
|
|
49
|
+
}
|
|
42
50
|
|
|
43
51
|
if (lt(width, 680) && gt(maxTotalTilesWidth, width) && !tileSizeFixed) {
|
|
44
52
|
return smallestTileSize;
|
|
@@ -52,6 +60,8 @@ const ResponsiveHeatMap = <TData,>({
|
|
|
52
60
|
}, [width, tiles]);
|
|
53
61
|
|
|
54
62
|
const isSmallestSize = equals(tileSize, smallestTileSize);
|
|
63
|
+
const isMediumSize = !isSmallestSize && lt(tileSize, 90);
|
|
64
|
+
previousTileSize.current = tileSize;
|
|
55
65
|
|
|
56
66
|
if (equals(width, 0)) {
|
|
57
67
|
return null;
|
|
@@ -92,7 +102,14 @@ const ResponsiveHeatMap = <TData,>({
|
|
|
92
102
|
position="right-start"
|
|
93
103
|
>
|
|
94
104
|
<div className={classes.heatMapTileContent}>
|
|
95
|
-
{children({
|
|
105
|
+
{children({
|
|
106
|
+
backgroundColor,
|
|
107
|
+
data,
|
|
108
|
+
id,
|
|
109
|
+
isMediumSize,
|
|
110
|
+
isSmallestSize,
|
|
111
|
+
tileSize
|
|
112
|
+
})}
|
|
96
113
|
</div>
|
|
97
114
|
</Tooltip>
|
|
98
115
|
</Box>
|
|
@@ -10,7 +10,9 @@ interface ChildrenProps<TData> {
|
|
|
10
10
|
backgroundColor: string;
|
|
11
11
|
data: TData;
|
|
12
12
|
id: string;
|
|
13
|
+
isMediumSize?: boolean;
|
|
13
14
|
isSmallestSize: boolean;
|
|
15
|
+
tileSize?: number;
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
export interface HeatMapProps<TData> {
|
|
@@ -19,7 +21,9 @@ export interface HeatMapProps<TData> {
|
|
|
19
21
|
backgroundColor,
|
|
20
22
|
id,
|
|
21
23
|
data,
|
|
22
|
-
isSmallestSize
|
|
24
|
+
isSmallestSize,
|
|
25
|
+
tileSize,
|
|
26
|
+
isMediumSize
|
|
23
27
|
}: ChildrenProps<TData>) => ReactElement | boolean | null;
|
|
24
28
|
displayTooltipCondition?: (data: TData) => boolean;
|
|
25
29
|
tileSizeFixed?: boolean;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { makeStyles } from 'tss-react/mui';
|
|
2
|
+
|
|
3
|
+
export const useStyles = makeStyles()((theme) => ({
|
|
4
|
+
container: {
|
|
5
|
+
border: `1px solid ${theme.palette.divider}`,
|
|
6
|
+
borderRadius: theme.shape.borderRadius,
|
|
7
|
+
padding: theme.spacing(1),
|
|
8
|
+
width: 'fit-content'
|
|
9
|
+
}
|
|
10
|
+
}));
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { LegendOrdinal } from '@visx/legend';
|
|
2
2
|
import { scaleOrdinal } from '@visx/scale';
|
|
3
|
+
import { equals } from 'ramda';
|
|
3
4
|
|
|
5
|
+
import { useStyles } from './Legend.styles';
|
|
4
6
|
import { LegendProps } from './models';
|
|
5
7
|
|
|
6
8
|
const Legend = ({ scale, direction = 'column' }: LegendProps): JSX.Element => {
|
|
9
|
+
const { classes } = useStyles();
|
|
10
|
+
|
|
7
11
|
const legendScale = scaleOrdinal({
|
|
8
12
|
domain: scale.domain,
|
|
9
13
|
range: scale.range
|
|
@@ -11,8 +15,9 @@ const Legend = ({ scale, direction = 'column' }: LegendProps): JSX.Element => {
|
|
|
11
15
|
|
|
12
16
|
return (
|
|
13
17
|
<LegendOrdinal
|
|
18
|
+
className={classes.container}
|
|
14
19
|
direction={direction}
|
|
15
|
-
labelMargin=
|
|
20
|
+
labelMargin={equals(direction, 'row') ? '0 12px 0 0' : '0 0 0 0'}
|
|
16
21
|
scale={legendScale}
|
|
17
22
|
/>
|
|
18
23
|
);
|
|
@@ -55,6 +55,7 @@ const RegularLine = ({
|
|
|
55
55
|
if (filled) {
|
|
56
56
|
return (
|
|
57
57
|
<Shape.AreaClosed<TimeValue>
|
|
58
|
+
data-metric={metric_id}
|
|
58
59
|
fill={getFillColor({ areaColor, transparency })}
|
|
59
60
|
fillRule="nonzero"
|
|
60
61
|
key={metric_id}
|
|
@@ -65,7 +66,7 @@ const RegularLine = ({
|
|
|
65
66
|
);
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
return <Shape.LinePath<TimeValue> {...props} />;
|
|
69
|
+
return <Shape.LinePath<TimeValue> data-metric={metric_id} {...props} />;
|
|
69
70
|
};
|
|
70
71
|
|
|
71
72
|
export default memo(RegularLine, (prevProps, nextProps) => {
|
|
@@ -45,10 +45,8 @@ const StackLines = ({
|
|
|
45
45
|
>
|
|
46
46
|
{({ stacks, path: linePath }): Array<JSX.Element> => {
|
|
47
47
|
return stacks.map((stack, index) => {
|
|
48
|
-
const { areaColor, transparency, lineColor, highlight } =
|
|
49
|
-
index,
|
|
50
|
-
lines
|
|
51
|
-
) as Line;
|
|
48
|
+
const { areaColor, transparency, lineColor, highlight, metric_id } =
|
|
49
|
+
nth(index, lines) as Line;
|
|
52
50
|
|
|
53
51
|
return (
|
|
54
52
|
<g key={`stack-${prop('key', stack)}`}>
|
|
@@ -65,6 +63,7 @@ const StackLines = ({
|
|
|
65
63
|
)}
|
|
66
64
|
<path
|
|
67
65
|
d={linePath(stack) || ''}
|
|
66
|
+
data-metric={metric_id}
|
|
68
67
|
fill={getFillColor({ areaColor, transparency })}
|
|
69
68
|
opacity={highlight === false ? 0.3 : 1}
|
|
70
69
|
stroke={lineColor}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SvgIconProps } from '@mui/material';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { DowntimeIcon } from '../../../Icon/DowntimeIcon';
|
|
4
4
|
|
|
5
5
|
const Downtime = (props: SvgIconProps): JSX.Element => (
|
|
6
|
-
<
|
|
6
|
+
<DowntimeIcon {...props} />
|
|
7
7
|
);
|
|
8
8
|
|
|
9
9
|
export default Downtime;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { lt } from 'ramda';
|
|
1
2
|
import { makeStyles } from 'tss-react/mui';
|
|
2
3
|
|
|
3
4
|
import { margin } from '../common';
|
|
4
5
|
|
|
5
6
|
interface MakeStylesProps {
|
|
7
|
+
height?: number | null;
|
|
6
8
|
limitLegendRows?: boolean;
|
|
7
9
|
}
|
|
8
10
|
|
|
@@ -10,8 +12,16 @@ export const legendWidth = 21;
|
|
|
10
12
|
const legendItemHeight = 5.25;
|
|
11
13
|
const legendItemHeightCompact = 2;
|
|
12
14
|
|
|
15
|
+
const getLegendMaxHeight = ({ height }): number => {
|
|
16
|
+
if (lt(height || 0, 220)) {
|
|
17
|
+
return 40;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return 90;
|
|
21
|
+
};
|
|
22
|
+
|
|
13
23
|
export const useStyles = makeStyles<MakeStylesProps>()(
|
|
14
|
-
(theme, { limitLegendRows }) => ({
|
|
24
|
+
(theme, { limitLegendRows, height = 0 }) => ({
|
|
15
25
|
highlight: {
|
|
16
26
|
color: theme.typography.body1.color
|
|
17
27
|
},
|
|
@@ -29,9 +39,6 @@ export const useStyles = makeStyles<MakeStylesProps>()(
|
|
|
29
39
|
display: 'grid',
|
|
30
40
|
gridAutoRows: theme.spacing(legendItemHeight),
|
|
31
41
|
gridTemplateColumns: `repeat(auto-fit, minmax(${theme.spacing(legendWidth)}, 1fr))`,
|
|
32
|
-
maxHeight: limitLegendRows
|
|
33
|
-
? theme.spacing(legendItemHeight * 2 + 1)
|
|
34
|
-
: 'unset',
|
|
35
42
|
overflowX: 'hidden',
|
|
36
43
|
overflowY: 'auto',
|
|
37
44
|
rowGap: theme.spacing(1),
|
|
@@ -40,7 +47,11 @@ export const useStyles = makeStyles<MakeStylesProps>()(
|
|
|
40
47
|
legend: {
|
|
41
48
|
marginLeft: margin.left,
|
|
42
49
|
marginRight: margin.right,
|
|
43
|
-
|
|
50
|
+
maxHeight: limitLegendRows
|
|
51
|
+
? theme.spacing(legendItemHeight * 2 + 1)
|
|
52
|
+
: getLegendMaxHeight({ height }),
|
|
53
|
+
overflowX: 'hidden',
|
|
54
|
+
overflowY: 'auto'
|
|
44
55
|
},
|
|
45
56
|
minMaxAvgContainer: {
|
|
46
57
|
columnGap: theme.spacing(0.5),
|
|
@@ -63,7 +63,10 @@ const LegendHeader = ({
|
|
|
63
63
|
placement="top"
|
|
64
64
|
>
|
|
65
65
|
<div className={classes.markerAndLegendName}>
|
|
66
|
-
<div
|
|
66
|
+
<div
|
|
67
|
+
data-icon
|
|
68
|
+
className={cx(classes.icon, { [classes.disabled]: disabled })}
|
|
69
|
+
/>
|
|
67
70
|
<EllipsisTypography
|
|
68
71
|
className={cx(classes.text, classes.legendName)}
|
|
69
72
|
data-mode={
|
|
@@ -11,13 +11,14 @@ import { Line } from '../../common/timeSeries/models';
|
|
|
11
11
|
import { labelAvg, labelMax, labelMin } from '../translatedLabels';
|
|
12
12
|
|
|
13
13
|
import { useStyles } from './Legend.styles';
|
|
14
|
+
import LegendContent from './LegendContent';
|
|
14
15
|
import LegendHeader from './LegendHeader';
|
|
15
16
|
import { GetMetricValueProps, LegendDisplayMode } from './models';
|
|
16
17
|
import useLegend from './useLegend';
|
|
17
|
-
import LegendContent from './LegendContent';
|
|
18
18
|
|
|
19
19
|
interface Props {
|
|
20
20
|
base: number;
|
|
21
|
+
height?: number | null;
|
|
21
22
|
limitLegend?: false | number;
|
|
22
23
|
lines: Array<Line>;
|
|
23
24
|
renderExtraComponent?: ReactNode;
|
|
@@ -33,9 +34,13 @@ const MainLegend = ({
|
|
|
33
34
|
limitLegend = false,
|
|
34
35
|
renderExtraComponent,
|
|
35
36
|
setLinesGraph,
|
|
36
|
-
shouldDisplayLegendInCompactMode
|
|
37
|
+
shouldDisplayLegendInCompactMode,
|
|
38
|
+
height
|
|
37
39
|
}: Props): JSX.Element => {
|
|
38
|
-
const { classes, cx } = useStyles({
|
|
40
|
+
const { classes, cx } = useStyles({
|
|
41
|
+
height,
|
|
42
|
+
limitLegendRows: Boolean(limitLegend)
|
|
43
|
+
});
|
|
39
44
|
const theme = useTheme();
|
|
40
45
|
|
|
41
46
|
const { selectMetricLine, clearHighlight, highlightLine, toggleMetricLine } =
|
|
@@ -145,7 +150,8 @@ const Legend = (props: Props): JSX.Element => {
|
|
|
145
150
|
limitLegend,
|
|
146
151
|
lines,
|
|
147
152
|
base,
|
|
148
|
-
shouldDisplayLegendInCompactMode
|
|
153
|
+
shouldDisplayLegendInCompactMode,
|
|
154
|
+
height
|
|
149
155
|
} = props;
|
|
150
156
|
|
|
151
157
|
return useMemoComponent({
|
|
@@ -155,7 +161,8 @@ const Legend = (props: Props): JSX.Element => {
|
|
|
155
161
|
base,
|
|
156
162
|
toggable,
|
|
157
163
|
limitLegend,
|
|
158
|
-
shouldDisplayLegendInCompactMode
|
|
164
|
+
shouldDisplayLegendInCompactMode,
|
|
165
|
+
height
|
|
159
166
|
]
|
|
160
167
|
});
|
|
161
168
|
};
|
|
@@ -3,6 +3,7 @@ import { LineChartData } from '../common/models';
|
|
|
3
3
|
import dataLastDay from './mockedData/lastDay.json';
|
|
4
4
|
import dataLastDayWithNullValues from './mockedData/lastDayWithNullValues.json';
|
|
5
5
|
import dataLastDayWithIncompleteValues from './mockedData/lastDayWithIncompleteValues.json';
|
|
6
|
+
import dataCurvesWithSameColor from './mockedData/curvesWithSameColor.json';
|
|
6
7
|
import { args as argumentsData } from './helpers/doc';
|
|
7
8
|
|
|
8
9
|
import WrapperLineChart from '.';
|
|
@@ -88,4 +89,56 @@ describe('Line chart', () => {
|
|
|
88
89
|
cy.makeSnapshot();
|
|
89
90
|
});
|
|
90
91
|
});
|
|
92
|
+
|
|
93
|
+
it('displays the curves with different shades when curves have same color', () => {
|
|
94
|
+
initialize(dataCurvesWithSameColor);
|
|
95
|
+
|
|
96
|
+
cy.findByLabelText('Centreon-Server: Round-Trip Average Time')
|
|
97
|
+
.find('[data-icon="true"]')
|
|
98
|
+
.should('have.css', 'background-color', 'rgb(41, 175, 238)');
|
|
99
|
+
cy.findByLabelText('Centreon-Server_5: Round-Trip Average Time')
|
|
100
|
+
.find('[data-icon="true"]')
|
|
101
|
+
.should('have.css', 'background-color', 'rgb(83, 191, 241)');
|
|
102
|
+
cy.findByLabelText('Centreon-Server_4: Round-Trip Average Time')
|
|
103
|
+
.find('[data-icon="true"]')
|
|
104
|
+
.should('have.css', 'background-color', 'rgb(8, 34, 47)');
|
|
105
|
+
cy.findByLabelText('Centreon-Server_3: Round-Trip Average Time')
|
|
106
|
+
.find('[data-icon="true"]')
|
|
107
|
+
.should('have.css', 'background-color', 'rgb(16, 70, 95)');
|
|
108
|
+
cy.findByLabelText('Centreon-Server_2: Round-Trip Average Time')
|
|
109
|
+
.find('[data-icon="true"]')
|
|
110
|
+
.should('have.css', 'background-color', 'rgb(24, 105, 142)');
|
|
111
|
+
cy.findByLabelText('Centreon-Server_1: Round-Trip Average Time')
|
|
112
|
+
.find('[data-icon="true"]')
|
|
113
|
+
.should('have.css', 'background-color', 'rgb(32, 140, 190)');
|
|
114
|
+
|
|
115
|
+
cy.get('[data-metric="1"]').should(
|
|
116
|
+
'have.attr',
|
|
117
|
+
'stroke',
|
|
118
|
+
'rgb(41, 175, 238)'
|
|
119
|
+
);
|
|
120
|
+
cy.get('[data-metric="21"]').should(
|
|
121
|
+
'have.attr',
|
|
122
|
+
'stroke',
|
|
123
|
+
'rgb(32, 140, 190)'
|
|
124
|
+
);
|
|
125
|
+
cy.get('[data-metric="17"]').should(
|
|
126
|
+
'have.attr',
|
|
127
|
+
'stroke',
|
|
128
|
+
'rgb(24, 105, 142)'
|
|
129
|
+
);
|
|
130
|
+
cy.get('[data-metric="13"]').should(
|
|
131
|
+
'have.attr',
|
|
132
|
+
'stroke',
|
|
133
|
+
'rgb(16, 70, 95)'
|
|
134
|
+
);
|
|
135
|
+
cy.get('[data-metric="9"]').should('have.attr', 'stroke', 'rgb(8, 34, 47)');
|
|
136
|
+
cy.get('[data-metric="5"]').should(
|
|
137
|
+
'have.attr',
|
|
138
|
+
'stroke',
|
|
139
|
+
'rgb(83, 191, 241)'
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
cy.makeSnapshot();
|
|
143
|
+
});
|
|
91
144
|
});
|
|
@@ -5,35 +5,35 @@ import { flatten, gt, isNil, lte, pluck, reduce } from 'ramda';
|
|
|
5
5
|
|
|
6
6
|
import { ClickAwayListener, Fade, Skeleton, useTheme } from '@mui/material';
|
|
7
7
|
|
|
8
|
+
import { Tooltip as MuiTooltip } from '../../components/Tooltip';
|
|
9
|
+
import { Thresholds as ThresholdsModel } from '../common/models';
|
|
8
10
|
import { getLeftScale, getRightScale, getXScale } from '../common/timeSeries';
|
|
9
11
|
import { Line } from '../common/timeSeries/models';
|
|
10
|
-
import { Thresholds as ThresholdsModel } from '../common/models';
|
|
11
|
-
import { Tooltip as MuiTooltip } from '../../components/Tooltip';
|
|
12
12
|
|
|
13
13
|
import Axes from './BasicComponents/Axes';
|
|
14
14
|
import Grids from './BasicComponents/Grids';
|
|
15
15
|
import Lines from './BasicComponents/Lines';
|
|
16
16
|
import { canDisplayThreshold } from './BasicComponents/Lines/Threshold/models';
|
|
17
|
+
import { CurveType } from './BasicComponents/Lines/models';
|
|
18
|
+
import Thresholds from './BasicComponents/Thresholds';
|
|
17
19
|
import useFilterLines from './BasicComponents/useFilterLines';
|
|
18
|
-
import { useStyles } from './LineChart.styles';
|
|
19
20
|
import Header from './Header';
|
|
20
21
|
import InteractionWithGraph from './InteractiveComponents';
|
|
22
|
+
import GraphValueTooltip from './InteractiveComponents/GraphValueTooltip/GraphValueTooltip';
|
|
21
23
|
import GraphTooltip from './InteractiveComponents/Tooltip';
|
|
22
24
|
import useGraphTooltip from './InteractiveComponents/Tooltip/useGraphTooltip';
|
|
23
25
|
import Legend from './Legend';
|
|
26
|
+
import { legendWidth } from './Legend/Legend.styles';
|
|
27
|
+
import { useStyles } from './LineChart.styles';
|
|
24
28
|
import { margin } from './common';
|
|
25
29
|
import {
|
|
26
30
|
Data,
|
|
27
31
|
GlobalAreaLines,
|
|
28
32
|
GraphInterval,
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
LegendModel,
|
|
34
|
+
LineChartProps
|
|
31
35
|
} from './models';
|
|
32
36
|
import { useIntersection } from './useLineChartIntersection';
|
|
33
|
-
import { CurveType } from './BasicComponents/Lines/models';
|
|
34
|
-
import Thresholds from './BasicComponents/Thresholds';
|
|
35
|
-
import { legendWidth } from './Legend/Legend.styles';
|
|
36
|
-
import GraphValueTooltip from './InteractiveComponents/GraphValueTooltip/GraphValueTooltip';
|
|
37
37
|
|
|
38
38
|
const extraMargin = 10;
|
|
39
39
|
|
|
@@ -292,6 +292,7 @@ const LineChart = ({
|
|
|
292
292
|
<div ref={legendRef}>
|
|
293
293
|
<Legend
|
|
294
294
|
base={baseAxis}
|
|
295
|
+
height={height}
|
|
295
296
|
limitLegend={limitLegend}
|
|
296
297
|
lines={newLines}
|
|
297
298
|
renderExtraComponent={legend?.renderExtraComponent}
|
|
@@ -34,6 +34,7 @@ import dataLastMonth from './mockedData/lastMonth.json';
|
|
|
34
34
|
import dataLastWeek from './mockedData/lastWeek.json';
|
|
35
35
|
import dataZoomPreview from './mockedData/zoomPreview.json';
|
|
36
36
|
import dataLastDay from './mockedData/lastDay.json';
|
|
37
|
+
import dataCurvesSameColor from './mockedData/curvesWithSameColor.json';
|
|
37
38
|
import { Interval, ThresholdType, TooltipData } from './models';
|
|
38
39
|
|
|
39
40
|
import WrapperLineChart from './index';
|
|
@@ -478,3 +479,15 @@ export const thresholdsRange: Story = {
|
|
|
478
479
|
/>
|
|
479
480
|
)
|
|
480
481
|
};
|
|
482
|
+
|
|
483
|
+
export const LineChartWithSameColorCurves: Story = {
|
|
484
|
+
...Template,
|
|
485
|
+
argTypes,
|
|
486
|
+
args: argumentsData,
|
|
487
|
+
render: (args) => (
|
|
488
|
+
<WrapperLineChart
|
|
489
|
+
{...args}
|
|
490
|
+
data={dataCurvesSameColor as unknown as LineChartData}
|
|
491
|
+
/>
|
|
492
|
+
)
|
|
493
|
+
};
|