@centreon/ui 26.9.1 → 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 +2 -2
- package/src/Graph/BarChart/BarChart.cypress.spec.tsx +23 -12
- package/src/Graph/BarChart/ResponsiveBarChart.tsx +13 -22
- package/src/Graph/Chart/BasicComponents/Lines/index.tsx +2 -0
- package/src/Graph/Chart/Chart.cypress.spec.tsx +9 -8
- package/src/Graph/Chart/Chart.tsx +14 -20
- package/src/Graph/Chart/InteractiveComponents/AnchorPoint/GuidingLines.tsx +2 -0
- package/src/Graph/Chart/InteractiveComponents/AnchorPoint/RegularAnchorPoint.tsx +4 -1
- package/src/Graph/Chart/InteractiveComponents/AnchorPoint/StackedAnchorPoint.tsx +3 -0
- package/src/Graph/Chart/InteractiveComponents/AnchorPoint/models.ts +1 -0
- package/src/Graph/Chart/InteractiveComponents/AnchorPoint/useTickGraph.ts +11 -2
- package/src/Graph/Chart/InteractiveComponents/index.tsx +7 -2
- package/src/Graph/common/Axes/index.tsx +1 -6
- package/src/Graph/common/BaseChart/ChartSvgWrapper.tsx +8 -3
- package/src/Graph/common/BaseChart/useComputeBaseChartDimensions.ts +6 -6
- package/src/Graph/common/BaseChart/useComputeYAxisMaxCharacters.ts +68 -52
- package/src/Graph/common/utils.ts +11 -2
- 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
|
@@ -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;
|