@centreon/ui 26.10.0 → 26.10.1
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/ThemeProvider/palettes.ts +18 -0
- package/src/ThemeProvider/tailwindcss.css +8 -0
- package/src/TopCounterElements/ResourceCounters.tsx +25 -30
- package/src/TopCounterElements/StatusCounter.tsx +39 -30
- package/src/TopCounterElements/TopCounterLayout.tsx +94 -91
- package/src/TopCounterElements/index.tsx +0 -2
- package/src/TopCounterElements/ResourceSubMenu.tsx +0 -110
package/package.json
CHANGED
|
@@ -45,6 +45,7 @@ declare module '@mui/material/styles' {
|
|
|
45
45
|
main: string;
|
|
46
46
|
};
|
|
47
47
|
statusBackground: StatusBackground;
|
|
48
|
+
tile: TypeTile;
|
|
48
49
|
}
|
|
49
50
|
interface StatusBackground {
|
|
50
51
|
error: string;
|
|
@@ -64,6 +65,13 @@ declare module '@mui/material/styles' {
|
|
|
64
65
|
main: string;
|
|
65
66
|
};
|
|
66
67
|
statusBackground: StatusBackground;
|
|
68
|
+
tile: TypeTile;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
interface TypeTile {
|
|
72
|
+
background: string;
|
|
73
|
+
border: string;
|
|
74
|
+
borderHover: string;
|
|
67
75
|
}
|
|
68
76
|
|
|
69
77
|
interface TypeBackground {
|
|
@@ -294,6 +302,11 @@ export const lightPalette: PaletteOptions = {
|
|
|
294
302
|
primary: '#000000',
|
|
295
303
|
secondary: '#666666'
|
|
296
304
|
},
|
|
305
|
+
tile: {
|
|
306
|
+
background: '#FFFFFF',
|
|
307
|
+
border: '#E3E3E3',
|
|
308
|
+
borderHover: '#CCCCCC'
|
|
309
|
+
},
|
|
297
310
|
warning: {
|
|
298
311
|
contrastText: '#000',
|
|
299
312
|
dark: '#FC7E00',
|
|
@@ -436,6 +449,11 @@ export const darkPalette: PaletteOptions = {
|
|
|
436
449
|
primary: '#FFFFFF',
|
|
437
450
|
secondary: '#CCCCCC'
|
|
438
451
|
},
|
|
452
|
+
tile: {
|
|
453
|
+
background: '#2E2E2E',
|
|
454
|
+
border: '#4A4A4A',
|
|
455
|
+
borderHover: '#6D6D6D'
|
|
456
|
+
},
|
|
439
457
|
warning: {
|
|
440
458
|
contrastText: '#fff',
|
|
441
459
|
main: '#C55400'
|
|
@@ -112,6 +112,11 @@
|
|
|
112
112
|
--color-status-background-warning: #fd9b27;
|
|
113
113
|
--color-success-main: #88b922;
|
|
114
114
|
|
|
115
|
+
/* Tile container colors */
|
|
116
|
+
--color-tile-background: #ffffff;
|
|
117
|
+
--color-tile-border: #e3e3e3;
|
|
118
|
+
--color-tile-border-hover: #cccccc;
|
|
119
|
+
|
|
115
120
|
/* Text colors */
|
|
116
121
|
--color-text-disabled: #999999;
|
|
117
122
|
--color-text-primary: #000000;
|
|
@@ -195,6 +200,9 @@
|
|
|
195
200
|
--color-stauts-background-unknown: #666666;
|
|
196
201
|
--color-status-background-warning: #c55400;
|
|
197
202
|
--color-success-main: #5f8118;
|
|
203
|
+
--color-tile-background: #2e2e2e;
|
|
204
|
+
--color-tile-border: #4a4a4a;
|
|
205
|
+
--color-tile-border-hover: #6d6d6d;
|
|
198
206
|
--color-text-disabled: #666666;
|
|
199
207
|
--color-text-primary: #ffffff;
|
|
200
208
|
--color-text-secondary: #cccccc;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { SeverityCode } from '@centreon/ui';
|
|
2
2
|
|
|
3
|
-
import { Fragment } from 'react';
|
|
4
3
|
import { Link } from 'react-router';
|
|
5
4
|
import { makeStyles } from 'tss-react/mui';
|
|
6
5
|
|
|
@@ -8,29 +7,23 @@ import StatusCounter from './StatusCounter';
|
|
|
8
7
|
|
|
9
8
|
const useStyles = makeStyles()((theme) => ({
|
|
10
9
|
container: {
|
|
11
|
-
|
|
10
|
+
alignItems: 'center',
|
|
11
|
+
display: 'flex',
|
|
12
|
+
gap: theme.spacing(1),
|
|
12
13
|
listStyle: 'none',
|
|
13
14
|
margin: 0,
|
|
14
|
-
padding: 0
|
|
15
|
-
[theme.breakpoints.down(1025)]: {
|
|
16
|
-
flexFlow: 'row wrap'
|
|
17
|
-
}
|
|
15
|
+
padding: 0
|
|
18
16
|
},
|
|
19
17
|
item: {
|
|
20
|
-
|
|
18
|
+
alignItems: 'center',
|
|
19
|
+
display: 'flex',
|
|
21
20
|
margin: 0,
|
|
22
|
-
padding: 0
|
|
23
|
-
paddingRight: theme.spacing(0.25)
|
|
21
|
+
padding: 0
|
|
24
22
|
},
|
|
25
23
|
link: {
|
|
24
|
+
alignItems: 'center',
|
|
25
|
+
display: 'flex',
|
|
26
26
|
textDecoration: 'none'
|
|
27
|
-
},
|
|
28
|
-
splitter: {
|
|
29
|
-
display: 'none',
|
|
30
|
-
[theme.breakpoints.down(1025)]: {
|
|
31
|
-
display: 'block',
|
|
32
|
-
marginBottom: theme.spacing(0.25)
|
|
33
|
-
}
|
|
34
27
|
}
|
|
35
28
|
}));
|
|
36
29
|
|
|
@@ -38,6 +31,7 @@ export interface CounterProps {
|
|
|
38
31
|
counters: Array<{
|
|
39
32
|
ariaLabel: string;
|
|
40
33
|
count: string | number;
|
|
34
|
+
detail?: string | number;
|
|
41
35
|
onClick: (e: React.MouseEvent) => void;
|
|
42
36
|
severityCode: SeverityCode;
|
|
43
37
|
to: string;
|
|
@@ -50,20 +44,21 @@ export default ({ counters }: CounterProps): JSX.Element => {
|
|
|
50
44
|
return (
|
|
51
45
|
<ul className={classes.container}>
|
|
52
46
|
{counters.map(
|
|
53
|
-
({ to, ariaLabel, onClick, count, severityCode }
|
|
54
|
-
<
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
47
|
+
({ to, ariaLabel, onClick, count, detail, severityCode }) => (
|
|
48
|
+
<li className={classes.item} key={to.toString().replace(/\W/g, '')}>
|
|
49
|
+
<Link
|
|
50
|
+
aria-label={ariaLabel}
|
|
51
|
+
className={classes.link}
|
|
52
|
+
onClick={onClick}
|
|
53
|
+
to={to}
|
|
54
|
+
>
|
|
55
|
+
<StatusCounter
|
|
56
|
+
count={count}
|
|
57
|
+
detail={detail}
|
|
58
|
+
severityCode={severityCode}
|
|
59
|
+
/>
|
|
60
|
+
</Link>
|
|
61
|
+
</li>
|
|
67
62
|
)
|
|
68
63
|
)}
|
|
69
64
|
</ul>
|
|
@@ -1,63 +1,72 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Tooltip } from '@mui/material';
|
|
2
2
|
|
|
3
3
|
import { getStatusColors, type SeverityCode } from '@centreon/ui';
|
|
4
4
|
|
|
5
5
|
import numeral from 'numeral';
|
|
6
|
+
import { isNil } from 'ramda';
|
|
6
7
|
import { makeStyles } from 'tss-react/mui';
|
|
7
8
|
|
|
8
9
|
export interface StyleProps {
|
|
9
10
|
severityCode?: SeverityCode | null;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
const useStyles = makeStyles<StyleProps>()((theme, { severityCode }) =>
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
13
|
+
const useStyles = makeStyles<StyleProps>()((theme, { severityCode }) => {
|
|
14
|
+
const statusColors = severityCode
|
|
15
|
+
? getStatusColors({ severityCode, theme })
|
|
16
|
+
: null;
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
container: {
|
|
20
|
+
alignItems: 'center',
|
|
21
|
+
color: theme.palette.mode === 'dark' ? '#EAEEF7' : '#1B2233',
|
|
22
|
+
cursor: 'pointer',
|
|
23
|
+
display: 'inline-flex',
|
|
24
|
+
gap: '3px'
|
|
25
|
+
},
|
|
26
|
+
count: {
|
|
27
|
+
fontFamily: 'ui-monospace, "Roboto Mono", Menlo, monospace',
|
|
28
|
+
fontSize: '12px',
|
|
29
|
+
fontWeight: theme.typography.fontWeightMedium,
|
|
30
|
+
lineHeight: 1
|
|
31
|
+
},
|
|
32
|
+
dot: {
|
|
33
|
+
backgroundColor: statusColors?.backgroundColor ?? theme.palette.divider,
|
|
34
|
+
borderRadius: '50%',
|
|
35
|
+
flexShrink: 0,
|
|
36
|
+
height: '9px',
|
|
37
|
+
width: '9px'
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
});
|
|
31
41
|
|
|
32
42
|
export interface Props {
|
|
33
43
|
className?: string;
|
|
34
44
|
count: string | number;
|
|
45
|
+
detail?: string | number;
|
|
35
46
|
severityCode?: SeverityCode | null;
|
|
36
47
|
}
|
|
37
48
|
|
|
38
49
|
const StatusCounter = ({
|
|
39
50
|
severityCode = null,
|
|
40
51
|
count,
|
|
52
|
+
detail,
|
|
41
53
|
className
|
|
42
54
|
}: Props): JSX.Element => {
|
|
43
55
|
const { classes, cx } = useStyles({ severityCode });
|
|
44
|
-
const
|
|
56
|
+
const hasDetail = !isNil(detail);
|
|
57
|
+
const shouldDisableTooltip = !hasDetail && Number(count) < 1000;
|
|
45
58
|
const formattedCount = numeral(count).format('0.[0]a');
|
|
46
59
|
|
|
47
60
|
return (
|
|
48
61
|
<Tooltip
|
|
49
62
|
disableHoverListener={shouldDisableTooltip}
|
|
50
63
|
followCursor
|
|
51
|
-
title={count}
|
|
64
|
+
title={hasDetail ? detail : count}
|
|
52
65
|
>
|
|
53
|
-
<
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}}
|
|
58
|
-
max={Number.POSITIVE_INFINITY}
|
|
59
|
-
overlap="circular"
|
|
60
|
-
/>
|
|
66
|
+
<span className={cx(classes.container, className)}>
|
|
67
|
+
<span className={classes.dot} />
|
|
68
|
+
<span className={classes.count}>{formattedCount}</span>
|
|
69
|
+
</span>
|
|
61
70
|
</Tooltip>
|
|
62
71
|
);
|
|
63
72
|
};
|
|
@@ -1,79 +1,48 @@
|
|
|
1
1
|
import ExpandLessIcon from '@mui/icons-material/ExpandLess';
|
|
2
2
|
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
|
3
3
|
import type { SvgIconProps } from '@mui/material';
|
|
4
|
-
import {
|
|
4
|
+
import { ClickAwayListener, Tooltip } from '@mui/material';
|
|
5
5
|
|
|
6
|
-
import { ComponentType,
|
|
6
|
+
import type { ComponentType, MouseEvent } from 'react';
|
|
7
|
+
import { useEffect, useState } from 'react';
|
|
8
|
+
import { Link } from 'react-router';
|
|
7
9
|
import { makeStyles } from 'tss-react/mui';
|
|
8
10
|
|
|
9
11
|
import useCloseOnLegacyPage from './useCloseOnLegacyPage';
|
|
10
12
|
|
|
11
13
|
const useStyles = makeStyles()((theme) => ({
|
|
12
|
-
button: {
|
|
13
|
-
'& > svg': {
|
|
14
|
-
height: '0.9em',
|
|
15
|
-
margin: `-${theme.spacing(0.5)}`,
|
|
16
|
-
[theme.breakpoints.down(1025)]: {
|
|
17
|
-
margin: `-${theme.spacing(0.5)}`
|
|
18
|
-
}
|
|
19
|
-
},
|
|
20
|
-
appearance: 'none',
|
|
21
|
-
background: 'none',
|
|
22
|
-
border: 0,
|
|
23
|
-
color: theme.palette.common.white,
|
|
24
|
-
cursor: 'pointer',
|
|
25
|
-
display: 'flex',
|
|
26
|
-
|
|
27
|
-
[theme.breakpoints.up(1025)]: {
|
|
28
|
-
alignItems: 'center',
|
|
29
|
-
flexFlow: 'row no-wrap',
|
|
30
|
-
marginTop: theme.spacing(0.5)
|
|
31
|
-
},
|
|
32
|
-
|
|
33
|
-
[theme.breakpoints.down(1025)]: {
|
|
34
|
-
alignItems: 'center',
|
|
35
|
-
flexFlow: 'column wrap',
|
|
36
|
-
order: 1
|
|
37
|
-
},
|
|
38
|
-
|
|
39
|
-
padding: '0'
|
|
40
|
-
},
|
|
41
14
|
container: {
|
|
15
|
+
alignItems: 'center',
|
|
16
|
+
display: 'flex',
|
|
42
17
|
position: 'relative'
|
|
43
18
|
},
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
display: '
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
19
|
+
icon: {
|
|
20
|
+
'& > svg': {
|
|
21
|
+
display: 'block',
|
|
22
|
+
height: '16px',
|
|
23
|
+
width: '16px'
|
|
24
|
+
},
|
|
25
|
+
alignItems: 'center',
|
|
26
|
+
color: 'inherit',
|
|
27
|
+
display: 'inline-flex',
|
|
28
|
+
textDecoration: 'none'
|
|
55
29
|
},
|
|
56
30
|
indicators: {
|
|
31
|
+
alignItems: 'center',
|
|
32
|
+
display: 'inline-flex',
|
|
57
33
|
lineHeight: 1,
|
|
58
34
|
[theme.breakpoints.down(600)]: {
|
|
59
35
|
display: 'none'
|
|
60
|
-
},
|
|
61
|
-
[theme.breakpoints.down(1025)]: {
|
|
62
|
-
flex: 'initial',
|
|
63
|
-
marginLeft: theme.spacing(0.5),
|
|
64
|
-
order: 2
|
|
65
|
-
},
|
|
66
|
-
[theme.breakpoints.up(1025)]: {
|
|
67
|
-
height: theme.spacing(2.5),
|
|
68
|
-
marginLeft: theme.spacing(3.75)
|
|
69
36
|
}
|
|
70
37
|
},
|
|
71
38
|
subMenu: {
|
|
72
39
|
backgroundColor: theme.palette.background.default,
|
|
40
|
+
borderRadius: theme.spacing(1),
|
|
73
41
|
boxShadow: theme.shadows[3],
|
|
74
42
|
boxSizing: 'border-box',
|
|
75
43
|
left: 0,
|
|
76
44
|
minWidth: theme.spacing(20),
|
|
45
|
+
overflow: 'hidden',
|
|
77
46
|
position: 'absolute',
|
|
78
47
|
textAlign: 'left',
|
|
79
48
|
top: `calc(100% + ${theme.spacing(1.25)})`,
|
|
@@ -83,38 +52,53 @@ const useStyles = makeStyles()((theme) => ({
|
|
|
83
52
|
subMenuOpen: {
|
|
84
53
|
visibility: 'visible'
|
|
85
54
|
},
|
|
86
|
-
|
|
55
|
+
tile: {
|
|
56
|
+
'& > svg': {
|
|
57
|
+
height: '16px',
|
|
58
|
+
width: '16px'
|
|
59
|
+
},
|
|
60
|
+
'&:hover': {
|
|
61
|
+
borderColor: theme.palette.tile.borderHover
|
|
62
|
+
},
|
|
87
63
|
alignItems: 'center',
|
|
64
|
+
appearance: 'none',
|
|
65
|
+
background: theme.palette.tile.background,
|
|
66
|
+
border: `1px solid ${theme.palette.tile.border}`,
|
|
67
|
+
borderRadius: theme.spacing(1),
|
|
68
|
+
color: theme.palette.text.primary,
|
|
88
69
|
display: 'inline-flex',
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
display: 'none'
|
|
96
|
-
}
|
|
70
|
+
flexFlow: 'row nowrap',
|
|
71
|
+
gap: theme.spacing(1),
|
|
72
|
+
padding: '5px 9px'
|
|
73
|
+
},
|
|
74
|
+
tileButton: {
|
|
75
|
+
cursor: 'pointer'
|
|
97
76
|
}
|
|
98
77
|
}));
|
|
99
78
|
|
|
100
79
|
interface TopCounterLayoutProps {
|
|
101
80
|
Icon: ComponentType<SvgIconProps>;
|
|
81
|
+
iconLink?: string;
|
|
82
|
+
iconOnClick?: (e: MouseEvent<HTMLAnchorElement>) => void;
|
|
102
83
|
renderIndicators: () => JSX.Element;
|
|
103
|
-
renderSubMenu
|
|
104
|
-
showPendingBadge?: boolean;
|
|
84
|
+
renderSubMenu?: (params: { closeSubMenu: () => void }) => JSX.Element;
|
|
105
85
|
title: string;
|
|
86
|
+
tooltipDescription?: string;
|
|
106
87
|
}
|
|
107
88
|
|
|
108
89
|
const TopCounterLayout = ({
|
|
109
90
|
Icon,
|
|
110
91
|
title,
|
|
92
|
+
iconLink,
|
|
93
|
+
iconOnClick,
|
|
111
94
|
renderIndicators,
|
|
112
95
|
renderSubMenu,
|
|
113
|
-
|
|
96
|
+
tooltipDescription
|
|
114
97
|
}: TopCounterLayoutProps): JSX.Element => {
|
|
115
98
|
const { classes, cx } = useStyles();
|
|
116
99
|
const [toggled, setToggled] = useState(false);
|
|
117
100
|
const subMenuId = title.replace(/[^A-Za-z]/, '-');
|
|
101
|
+
const isExpandable = Boolean(renderSubMenu);
|
|
118
102
|
useCloseOnLegacyPage({ setToggled });
|
|
119
103
|
|
|
120
104
|
useEffect(() => {
|
|
@@ -137,6 +121,38 @@ const TopCounterLayout = ({
|
|
|
137
121
|
};
|
|
138
122
|
}, [toggled]);
|
|
139
123
|
|
|
124
|
+
const iconWithTooltip = (
|
|
125
|
+
<Tooltip
|
|
126
|
+
disableInteractive
|
|
127
|
+
enterDelay={500}
|
|
128
|
+
enterNextDelay={500}
|
|
129
|
+
placement="bottom"
|
|
130
|
+
title={tooltipDescription ?? title}
|
|
131
|
+
>
|
|
132
|
+
<Icon />
|
|
133
|
+
</Tooltip>
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
if (!isExpandable) {
|
|
137
|
+
return (
|
|
138
|
+
<div className={classes.tile}>
|
|
139
|
+
{iconLink ? (
|
|
140
|
+
<Link
|
|
141
|
+
aria-label={title}
|
|
142
|
+
className={classes.icon}
|
|
143
|
+
onClick={iconOnClick}
|
|
144
|
+
to={iconLink}
|
|
145
|
+
>
|
|
146
|
+
{iconWithTooltip}
|
|
147
|
+
</Link>
|
|
148
|
+
) : (
|
|
149
|
+
<span className={classes.icon}>{iconWithTooltip}</span>
|
|
150
|
+
)}
|
|
151
|
+
<span className={classes.indicators}>{renderIndicators()}</span>
|
|
152
|
+
</div>
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
140
156
|
return (
|
|
141
157
|
<ClickAwayListener
|
|
142
158
|
onClickAway={(): void => {
|
|
@@ -147,40 +163,27 @@ const TopCounterLayout = ({
|
|
|
147
163
|
}}
|
|
148
164
|
>
|
|
149
165
|
<div className={classes.container}>
|
|
150
|
-
<
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
>
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
anchorOrigin={{ horizontal: 'right', vertical: 'top' }}
|
|
165
|
-
color="pending"
|
|
166
|
-
invisible={!showPendingBadge}
|
|
167
|
-
overlap="circular"
|
|
168
|
-
variant="dot"
|
|
169
|
-
>
|
|
170
|
-
<Icon />
|
|
171
|
-
</Badge>
|
|
172
|
-
</span>
|
|
173
|
-
<span className={classes.textWrapper}>{title}</span>
|
|
174
|
-
{toggled ? <ExpandLessIcon /> : <ExpandMoreIcon />}
|
|
175
|
-
</button>
|
|
176
|
-
</div>
|
|
166
|
+
<button
|
|
167
|
+
aria-controls={`${subMenuId}-menu`}
|
|
168
|
+
aria-expanded={toggled}
|
|
169
|
+
aria-haspopup="true"
|
|
170
|
+
aria-label={title}
|
|
171
|
+
className={cx(classes.tile, classes.tileButton)}
|
|
172
|
+
id={`${subMenuId}-button`}
|
|
173
|
+
onClick={(): void => setToggled(!toggled)}
|
|
174
|
+
type="button"
|
|
175
|
+
>
|
|
176
|
+
<span className={classes.icon}>{iconWithTooltip}</span>
|
|
177
|
+
<span className={classes.indicators}>{renderIndicators()}</span>
|
|
178
|
+
{toggled ? <ExpandLessIcon /> : <ExpandMoreIcon />}
|
|
179
|
+
</button>
|
|
177
180
|
<div
|
|
178
181
|
aria-labelledby={`${subMenuId}-button`}
|
|
179
182
|
className={cx(classes.subMenu, { [classes.subMenuOpen]: toggled })}
|
|
180
183
|
id={`${subMenuId}-menu`}
|
|
181
184
|
role="menu"
|
|
182
185
|
>
|
|
183
|
-
{renderSubMenu({ closeSubMenu: () => setToggled(false) })}
|
|
186
|
+
{renderSubMenu?.({ closeSubMenu: () => setToggled(false) })}
|
|
184
187
|
</div>
|
|
185
188
|
</div>
|
|
186
189
|
</ClickAwayListener>
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
export * from './formaters';
|
|
2
2
|
export type { CounterProps } from './ResourceCounters';
|
|
3
3
|
export { default as TopCounterResourceCounters } from './ResourceCounters';
|
|
4
|
-
export type { SubMenuProps } from './ResourceSubMenu';
|
|
5
|
-
export { default as TopCounterResourceSubMenu } from './ResourceSubMenu';
|
|
6
4
|
export { default as TopCounterLayout } from './TopCounterLayout';
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { List, ListItem } from '@mui/material';
|
|
2
|
-
|
|
3
|
-
import { getStatusColors, type SeverityCode } from '@centreon/ui';
|
|
4
|
-
import { ThemeMode } from '@centreon/ui-context';
|
|
5
|
-
|
|
6
|
-
import { equals } from 'ramda';
|
|
7
|
-
import { Link } from 'react-router';
|
|
8
|
-
import { makeStyles } from 'tss-react/mui';
|
|
9
|
-
|
|
10
|
-
const useStyles = makeStyles()((theme) => ({
|
|
11
|
-
count: {
|
|
12
|
-
marginLeft: 'auto'
|
|
13
|
-
},
|
|
14
|
-
link: {
|
|
15
|
-
alignItems: 'center',
|
|
16
|
-
color: 'inherit',
|
|
17
|
-
display: 'flex',
|
|
18
|
-
flex: '100%',
|
|
19
|
-
padding: `0 ${theme.spacing(1)}`,
|
|
20
|
-
textDecoration: 'none'
|
|
21
|
-
},
|
|
22
|
-
status: {
|
|
23
|
-
alignItems: 'center',
|
|
24
|
-
display: 'flex'
|
|
25
|
-
},
|
|
26
|
-
statusCounter: {
|
|
27
|
-
borderRadius: '50%',
|
|
28
|
-
height: theme.spacing(1),
|
|
29
|
-
marginRight: theme.spacing(1),
|
|
30
|
-
width: theme.spacing(1)
|
|
31
|
-
},
|
|
32
|
-
submenu: {
|
|
33
|
-
fontSize: theme.typography.body2.fontSize,
|
|
34
|
-
padding: 0
|
|
35
|
-
},
|
|
36
|
-
submenuItem: {
|
|
37
|
-
'&:hover': {
|
|
38
|
-
background: equals(theme.palette.mode, ThemeMode.dark)
|
|
39
|
-
? theme.palette.primary.dark
|
|
40
|
-
: theme.palette.primary.light,
|
|
41
|
-
color: equals(theme.palette.mode, ThemeMode.dark)
|
|
42
|
-
? theme.palette.common.white
|
|
43
|
-
: theme.palette.primary.main
|
|
44
|
-
},
|
|
45
|
-
'&:not(:last-child)': {
|
|
46
|
-
borderBottom: `1px solid ${theme.palette.divider}`
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}));
|
|
50
|
-
|
|
51
|
-
export interface SubMenuProps {
|
|
52
|
-
items: Array<{
|
|
53
|
-
countTestId?: string;
|
|
54
|
-
onClick: (e: React.MouseEvent) => void;
|
|
55
|
-
severityCode: SeverityCode;
|
|
56
|
-
submenuCount: string | number;
|
|
57
|
-
submenuTitle: string;
|
|
58
|
-
to: string;
|
|
59
|
-
}>;
|
|
60
|
-
onClose?: () => void;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const SubMenu = ({ items, onClose }: SubMenuProps): JSX.Element => {
|
|
64
|
-
const { classes, theme } = useStyles();
|
|
65
|
-
|
|
66
|
-
return (
|
|
67
|
-
<List className={classes.submenu}>
|
|
68
|
-
{items.map(
|
|
69
|
-
({
|
|
70
|
-
onClick,
|
|
71
|
-
severityCode,
|
|
72
|
-
submenuTitle,
|
|
73
|
-
submenuCount,
|
|
74
|
-
countTestId,
|
|
75
|
-
to
|
|
76
|
-
}) => (
|
|
77
|
-
<ListItem
|
|
78
|
-
className={classes.submenuItem}
|
|
79
|
-
disableGutters
|
|
80
|
-
key={to}
|
|
81
|
-
onClick={onClose}
|
|
82
|
-
>
|
|
83
|
-
<Link
|
|
84
|
-
className={classes.link}
|
|
85
|
-
onClick={onClick}
|
|
86
|
-
role="menuitem"
|
|
87
|
-
to={to}
|
|
88
|
-
>
|
|
89
|
-
<span className={classes.status}>
|
|
90
|
-
<span
|
|
91
|
-
className={classes.statusCounter}
|
|
92
|
-
style={{
|
|
93
|
-
backgroundColor: getStatusColors({ severityCode, theme })
|
|
94
|
-
?.backgroundColor
|
|
95
|
-
}}
|
|
96
|
-
/>
|
|
97
|
-
<span>{submenuTitle}</span>
|
|
98
|
-
</span>
|
|
99
|
-
<span className={classes.count} data-testid={countTestId}>
|
|
100
|
-
{submenuCount}
|
|
101
|
-
</span>
|
|
102
|
-
</Link>
|
|
103
|
-
</ListItem>
|
|
104
|
-
)
|
|
105
|
-
)}
|
|
106
|
-
</List>
|
|
107
|
-
);
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
export default SubMenu;
|