@centreon/ui 23.10.114 → 23.10.116

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": "23.10.114",
3
+ "version": "23.10.116",
4
4
  "description": "Centreon UI Components",
5
5
  "scripts": {
6
6
  "eslint": "eslint ./src --ext .js,.jsx,.ts,.tsx --max-warnings 0",
@@ -139,7 +139,6 @@ export const RawValue: Story = {
139
139
  args: {
140
140
  data: dataLastWeek,
141
141
  displayAsRaw: true,
142
- thresholdTooltipLabels: ['Warning', 'Critical'],
143
142
  thresholds: {
144
143
  critical: [
145
144
  {
@@ -0,0 +1,105 @@
1
+ import { Meta, StoryObj } from '@storybook/react';
2
+ import { makeStyles } from 'tss-react/mui';
3
+
4
+ import { Box, Typography } from '@mui/material';
5
+
6
+ import EllipsisTypography from '../../Typography/EllipsisTypography';
7
+
8
+ import heatMapData from './HeatMapData.json';
9
+
10
+ import { HeatMap } from '.';
11
+
12
+ interface Data {
13
+ counter: number;
14
+ host: string;
15
+ service: string;
16
+ }
17
+
18
+ const meta: Meta<typeof HeatMap<Data>> = {
19
+ component: HeatMap
20
+ };
21
+
22
+ export default meta;
23
+ type Story = StoryObj<typeof HeatMap<Data>>;
24
+
25
+ const TileContent = ({
26
+ isSmallestSize,
27
+ data
28
+ }: {
29
+ data: Data;
30
+ isSmallestSize: boolean;
31
+ }): JSX.Element | false =>
32
+ !isSmallestSize && (
33
+ <Box
34
+ sx={{
35
+ alignItems: 'center',
36
+ color: 'common.black',
37
+ display: 'flex',
38
+ flexDirection: 'column',
39
+ width: '100%'
40
+ }}
41
+ >
42
+ <EllipsisTypography textAlign="center">{data.host}</EllipsisTypography>
43
+ <EllipsisTypography textAlign="center">{data.service}</EllipsisTypography>
44
+ <EllipsisTypography textAlign="center">{data.counter}</EllipsisTypography>
45
+ </Box>
46
+ );
47
+
48
+ const TooltipContent = ({ data }: { data: Data }): JSX.Element => {
49
+ return (
50
+ <Box sx={{ backgroundColor: 'common.white', color: 'common.black' }}>
51
+ <Box
52
+ sx={{
53
+ backgroundColor: 'common.black',
54
+ color: 'common.white',
55
+ display: 'flex',
56
+ justifyContent: 'center',
57
+ py: 1,
58
+ width: '100%'
59
+ }}
60
+ >
61
+ <Typography>{data.host}</Typography>
62
+ </Box>
63
+ <Box sx={{ px: 1, textAlign: 'center' }}>
64
+ <Typography>{data.service}</Typography>
65
+ <Typography>{data.counter}</Typography>
66
+ </Box>
67
+ </Box>
68
+ );
69
+ };
70
+
71
+ const useStyles = makeStyles()((theme) => ({
72
+ arrow: {
73
+ color: theme.palette.common.black
74
+ }
75
+ }));
76
+
77
+ const Template = (args): JSX.Element => {
78
+ const { classes } = useStyles();
79
+
80
+ return <HeatMap {...args} arrowClassName={classes.arrow} />;
81
+ };
82
+
83
+ export const normal: Story = {
84
+ args: {
85
+ children: TileContent,
86
+ tiles: heatMapData
87
+ }
88
+ };
89
+
90
+ export const withTooltip: Story = {
91
+ args: {
92
+ children: TileContent,
93
+ tiles: heatMapData,
94
+ tooltipContent: TooltipContent
95
+ },
96
+ render: Template
97
+ };
98
+
99
+ export const tilesWithFixedSize: Story = {
100
+ args: {
101
+ children: TileContent,
102
+ tileSizeFixed: true,
103
+ tiles: heatMapData
104
+ }
105
+ };
@@ -0,0 +1,28 @@
1
+ import { makeStyles } from 'tss-react/mui';
2
+
3
+ export const useHeatMapStyles = makeStyles()((theme) => ({
4
+ arrow: {
5
+ transform: 'transled3d(0px, 8px, 0px)'
6
+ },
7
+ heatMapTile: {
8
+ alignItems: 'center',
9
+ aspectRatio: '1 / 1',
10
+ display: 'flex',
11
+ justifyContent: 'center',
12
+ width: '100%'
13
+ },
14
+ heatMapTileContent: {
15
+ height: `calc(100% - ${theme.spacing(1)})`,
16
+ width: `calc(100% - ${theme.spacing(1)})`
17
+ },
18
+ heatMapTooltip: {
19
+ backgroundColor: theme.palette.background.paper,
20
+ color: theme.palette.text.primary,
21
+ marginLeft: `${theme.spacing(1.25)} !important`,
22
+ padding: 0,
23
+ position: 'relative'
24
+ },
25
+ heatMapTooltipArrow: {
26
+ transform: `translate3d(0px, ${theme.spacing(1)}, 0px) !important`
27
+ }
28
+ }));
@@ -0,0 +1,12 @@
1
+ import { ParentSize } from '../..';
2
+
3
+ import ResponsiveHeatMap from './ResponsiveHeatMap';
4
+ import { HeatMapProps } from './model';
5
+
6
+ const HeatMap = <TData,>(props: HeatMapProps<TData>): JSX.Element => (
7
+ <ParentSize>
8
+ {({ width }) => <ResponsiveHeatMap<TData> {...props} width={width} />}
9
+ </ParentSize>
10
+ );
11
+
12
+ export default HeatMap;
@@ -0,0 +1,137 @@
1
+ [
2
+ {
3
+ "id": "Orbaxter",
4
+ "backgroundColor": "#88B922",
5
+ "data": {
6
+ "host": "Server",
7
+ "service": "Service Counter",
8
+ "counter": 53
9
+ }
10
+ },
11
+ {
12
+ "id": "Interfind",
13
+ "backgroundColor": "#88B922",
14
+ "data": {
15
+ "host": "Server",
16
+ "service": "Service Counter",
17
+ "counter": 779
18
+ }
19
+ },
20
+ {
21
+ "id": "Ecratic",
22
+ "backgroundColor": "#E3E3E3",
23
+ "data": {
24
+ "host": "Server",
25
+ "service": "Service Counter",
26
+ "counter": 504
27
+ }
28
+ },
29
+ {
30
+ "id": "Earthwax",
31
+ "backgroundColor": "#88B922",
32
+ "data": {
33
+ "host": "Server",
34
+ "service": "Service Counter",
35
+ "counter": 374
36
+ }
37
+ },
38
+ {
39
+ "id": "Cytrak",
40
+ "backgroundColor": "#FF6666",
41
+ "data": {
42
+ "host": "Server",
43
+ "service": "Service Counter",
44
+ "counter": 957
45
+ }
46
+ },
47
+ {
48
+ "id": "Exiand",
49
+ "backgroundColor": "#1EBEB3",
50
+ "data": {
51
+ "host": "Server",
52
+ "service": "Service Counter",
53
+ "counter": 281
54
+ }
55
+ },
56
+ {
57
+ "id": "Ginkogene",
58
+ "backgroundColor": "#FF6666",
59
+ "data": {
60
+ "host": "Server",
61
+ "service": "Service Counter",
62
+ "counter": 472
63
+ }
64
+ },
65
+ {
66
+ "id": "Quailcom",
67
+ "backgroundColor": "#88B922",
68
+ "data": {
69
+ "host": "Server",
70
+ "service": "Service Counter",
71
+ "counter": 770
72
+ }
73
+ },
74
+ {
75
+ "id": "Cormoran",
76
+ "backgroundColor": "#FF6666",
77
+ "data": {
78
+ "host": "Server",
79
+ "service": "Service Counter",
80
+ "counter": 908
81
+ }
82
+ },
83
+ {
84
+ "id": "Emergent",
85
+ "backgroundColor": "#1EBEB3",
86
+ "data": {
87
+ "host": "Server",
88
+ "service": "Service Counter",
89
+ "counter": 969
90
+ }
91
+ },
92
+ {
93
+ "id": "Limozen",
94
+ "backgroundColor": "#E3E3E3",
95
+ "data": {
96
+ "host": "Server",
97
+ "service": "Service Counter",
98
+ "counter": 33
99
+ }
100
+ },
101
+ {
102
+ "id": "Gogol",
103
+ "backgroundColor": "#1EBEB3",
104
+ "data": {
105
+ "host": "Server",
106
+ "service": "Service Counter",
107
+ "counter": 870
108
+ }
109
+ },
110
+ {
111
+ "id": "Luxuria",
112
+ "backgroundColor": "#FD9B27",
113
+ "data": {
114
+ "host": "Server",
115
+ "service": "Service Counter",
116
+ "counter": 270
117
+ }
118
+ },
119
+ {
120
+ "id": "Fossiel",
121
+ "backgroundColor": "#1EBEB3",
122
+ "data": {
123
+ "host": "Server",
124
+ "service": "Service Counter",
125
+ "counter": 955
126
+ }
127
+ },
128
+ {
129
+ "id": "Hawkster",
130
+ "backgroundColor": "#88B922",
131
+ "data": {
132
+ "host": "Server",
133
+ "service": "Service Counter",
134
+ "counter": 28
135
+ }
136
+ }
137
+ ]
@@ -0,0 +1,94 @@
1
+ import { useMemo } from 'react';
2
+
3
+ import { scaleLinear } from '@visx/scale';
4
+ import { equals, gt, lt } from 'ramda';
5
+
6
+ import { Box } from '@mui/material';
7
+
8
+ import { Tooltip } from '../../components';
9
+
10
+ import { HeatMapProps } from './model';
11
+ import { useHeatMapStyles } from './HeatMap.styles';
12
+
13
+ const gap = 8;
14
+ const maxTileSize = 120;
15
+ const smallestTileSize = 44;
16
+
17
+ const ResponsiveHeatMap = <TData,>({
18
+ width,
19
+ children,
20
+ tiles,
21
+ arrowClassName,
22
+ tooltipContent,
23
+ tileSizeFixed
24
+ }: HeatMapProps<TData> & { width: number }): JSX.Element | null => {
25
+ const { classes, cx } = useHeatMapStyles();
26
+
27
+ const tileSize = useMemo(() => {
28
+ const scaleWidth = scaleLinear({
29
+ clamp: true,
30
+ domain: [680, 1056],
31
+ range: [76, maxTileSize]
32
+ });
33
+ const tileWidth = scaleWidth(width);
34
+
35
+ const tilesLength = tiles.length;
36
+
37
+ const maxTotalTilesWidth =
38
+ tilesLength * maxTileSize + (tilesLength - 1) * gap;
39
+ const theoricalTotalTilesWidth =
40
+ tilesLength * tileWidth + (tilesLength - 1) * gap;
41
+
42
+ if (lt(width, 680) && gt(maxTotalTilesWidth, width)) {
43
+ return smallestTileSize;
44
+ }
45
+
46
+ if (lt(theoricalTotalTilesWidth, width)) {
47
+ return maxTileSize;
48
+ }
49
+
50
+ return tileSizeFixed ? maxTileSize : tileWidth;
51
+ }, [width, tiles]);
52
+
53
+ const isSmallestSize = equals(tileSize, smallestTileSize);
54
+
55
+ if (equals(width, 0)) {
56
+ return null;
57
+ }
58
+
59
+ return (
60
+ <Box
61
+ sx={{
62
+ display: 'grid',
63
+ gap: 1,
64
+ gridTemplateColumns: `repeat(auto-fit, ${tileSize}px)`
65
+ }}
66
+ >
67
+ {tiles.map(({ backgroundColor, id, data }) => (
68
+ <Box className={classes.heatMapTile} key={id} sx={{ backgroundColor }}>
69
+ <Tooltip
70
+ hasCaret
71
+ classes={{
72
+ arrow: cx(classes.heatMapTooltipArrow, arrowClassName),
73
+ tooltip: classes.heatMapTooltip
74
+ }}
75
+ followCursor={false}
76
+ label={tooltipContent?.({
77
+ backgroundColor,
78
+ data,
79
+ id,
80
+ isSmallestSize
81
+ })}
82
+ position="right-start"
83
+ >
84
+ <div className={classes.heatMapTileContent}>
85
+ {children({ backgroundColor, data, id, isSmallestSize })}
86
+ </div>
87
+ </Tooltip>
88
+ </Box>
89
+ ))}
90
+ </Box>
91
+ );
92
+ };
93
+
94
+ export default ResponsiveHeatMap;
@@ -0,0 +1 @@
1
+ export { default as HeatMap } from './HeatMap';
@@ -0,0 +1,32 @@
1
+ import { ReactElement } from 'react';
2
+
3
+ interface Tile<TData> {
4
+ backgroundColor: string;
5
+ data: TData;
6
+ id: string;
7
+ }
8
+
9
+ interface ChildrenProps<TData> {
10
+ backgroundColor: string;
11
+ data: TData;
12
+ id: string;
13
+ isSmallestSize: boolean;
14
+ }
15
+
16
+ export interface HeatMapProps<TData> {
17
+ arrowClassName?: string;
18
+ children: ({
19
+ backgroundColor,
20
+ id,
21
+ data,
22
+ isSmallestSize
23
+ }: ChildrenProps<TData>) => ReactElement | boolean | null;
24
+ tileSizeFixed?: boolean;
25
+ tiles: Array<Tile<TData>>;
26
+ tooltipContent?: ({
27
+ backgroundColor,
28
+ id,
29
+ data,
30
+ isSmallestSize
31
+ }: ChildrenProps<TData>) => ReactElement | boolean | null;
32
+ }
@@ -2,3 +2,4 @@ export { default as LineChart } from './LineChart';
2
2
  export { Gauge } from './Gauge';
3
3
  export { SingleBar } from './SingleBar';
4
4
  export { Text as GraphText } from './Text';
5
+ export { HeatMap } from './HeatMap';
@@ -0,0 +1,18 @@
1
+ import { Box, Typography, TypographyProps } from '@mui/material';
2
+
3
+ const EllipsisTypography = (props: TypographyProps): JSX.Element => {
4
+ return (
5
+ <Box sx={{ width: '100%' }}>
6
+ <Typography
7
+ sx={{
8
+ overflow: 'hidden',
9
+ textOverflow: 'ellipsis',
10
+ whiteSpace: 'nowrap'
11
+ }}
12
+ {...props}
13
+ />
14
+ </Box>
15
+ );
16
+ };
17
+
18
+ export default EllipsisTypography;
package/src/index.ts CHANGED
@@ -154,6 +154,7 @@ export type { ResponseError, CatchErrorProps } from './api/customFetch';
154
154
 
155
155
  export * from './utils';
156
156
  export { default as FluidTypography } from './Typography/FluidTypography';
157
+ export { default as EllipsisTypography } from './Typography/EllipsisTypography';
157
158
  export * from './Dashboard';
158
159
  export * from './Graph';
159
160
  export type { LineChartData } from './Graph/common/models';