@centreon/ui 25.10.20 → 25.10.22

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.
Files changed (34) hide show
  1. package/package.json +1 -1
  2. package/src/Form/Inputs/Grid.tsx +3 -2
  3. package/src/Form/Section/navigateToSection.ts +6 -6
  4. package/src/Graph/BarChart/BarChart.cypress.spec.tsx +19 -0
  5. package/src/Graph/BarChart/BarChart.stories.tsx +51 -1
  6. package/src/Graph/BarChart/BarChart.tsx +1 -1
  7. package/src/Graph/BarChart/BarGroup.tsx +22 -32
  8. package/src/Graph/BarChart/MemoizedGroup.tsx +8 -11
  9. package/src/Graph/BarChart/ResponsiveBarChart.tsx +2 -1
  10. package/src/Graph/Chart/BasicComponents/Lines/StackedLines/useStackedLines.ts +18 -45
  11. package/src/Graph/Chart/BasicComponents/Lines/index.tsx +32 -26
  12. package/src/Graph/Chart/Chart.cypress.spec.tsx +24 -5
  13. package/src/Graph/Chart/Chart.stories.tsx +43 -1
  14. package/src/Graph/Chart/Chart.tsx +3 -2
  15. package/src/Graph/Chart/Legend/index.tsx +26 -2
  16. package/src/Graph/Chart/models.ts +6 -1
  17. package/src/Graph/Chart/useChartData.ts +1 -1
  18. package/src/Graph/common/BaseChart/BaseChart.tsx +6 -1
  19. package/src/Graph/common/timeSeries/index.test.ts +20 -0
  20. package/src/Graph/common/timeSeries/index.ts +121 -11
  21. package/src/Graph/common/timeSeries/models.ts +4 -2
  22. package/src/Graph/common/utils.ts +10 -4
  23. package/src/Graph/mockedData/dataWithMissingPoint.json +74 -0
  24. package/src/Graph/mockedData/pingServiceWithStackedKeys.json +205 -0
  25. package/src/InputField/Select/index.tsx +1 -2
  26. package/src/Module/index.tsx +8 -2
  27. package/src/ThemeProvider/index.tsx +30 -21
  28. package/src/ThemeProvider/tailwindcss.css +10 -10
  29. package/src/components/Layout/PageLayout/PageLayout.tsx +9 -3
  30. package/src/components/Layout/PageLayout/PageLayoutActions.tsx +5 -3
  31. package/src/components/Layout/PageLayout/PageLayoutBody.tsx +5 -3
  32. package/src/components/Layout/PageLayout/PageLayoutHeader.tsx +5 -3
  33. package/src/components/Modal/Modal.styles.ts +1 -2
  34. package/src/components/Modal/ModalHeader.tsx +5 -1
@@ -0,0 +1,205 @@
1
+ {
2
+ "global": {
3
+ "base": 1000,
4
+ "title": "Ping service"
5
+ },
6
+ "metrics": [
7
+ {
8
+ "metric_id": 2,
9
+ "metric": "Centreon-Server: pl",
10
+ "metric_legend": "Centreon-Server: pl",
11
+ "unit": "%",
12
+ "min": 0.0,
13
+ "max": 100.0,
14
+ "ds_data": {
15
+ "ds_color_line": "#F30B23",
16
+ "ds_color_area": "#F30B23",
17
+ "ds_filled": true,
18
+ "ds_invert": false,
19
+ "ds_legend": null,
20
+ "ds_stack": false,
21
+ "ds_order": 1,
22
+ "ds_transparency": 80.0,
23
+ "ds_color_line_mode": 0
24
+ },
25
+ "legend": "Centreon-Server: Packet Loss",
26
+ "stack": 0,
27
+ "warning_high_threshold": 20.0,
28
+ "critical_high_threshold": 50.0,
29
+ "warning_low_threshold": 0.0,
30
+ "critical_low_threshold": 0.0,
31
+ "ds_order": 1,
32
+ "data": [
33
+ 0.0,
34
+ 0.0,
35
+ 0.0,
36
+ 0.0,
37
+ 0.0,
38
+ 0.0,
39
+ 0.0,
40
+ 0.0,
41
+ 0.0,
42
+ 10.0,
43
+ 20.0,
44
+ null,
45
+ null
46
+ ],
47
+ "last_value": 0.0,
48
+ "minimum_value": null,
49
+ "maximum_value": 0.0,
50
+ "average_value": 0.0
51
+ },
52
+ {
53
+ "metric_id": 1,
54
+ "metric": "Centreon-Server: rta",
55
+ "metric_legend": "Centreon-Server: rta",
56
+ "unit": "ms",
57
+ "min": 0.0,
58
+ "max": null,
59
+ "ds_data": {
60
+ "ds_color_line": "#29AFEE",
61
+ "ds_color_area": "#29AFEE",
62
+ "ds_filled": true,
63
+ "ds_invert": false,
64
+ "ds_legend": null,
65
+ "ds_stack": true,
66
+ "ds_order": 1,
67
+ "ds_transparency": 80.0,
68
+ "ds_color_line_mode": 0
69
+ },
70
+ "legend": "Centreon-Server: Round-Trip Average Time",
71
+ "stack": 0,
72
+ "warning_high_threshold": 200.0,
73
+ "critical_high_threshold": 400.0,
74
+ "warning_low_threshold": 0.0,
75
+ "critical_low_threshold": 0.0,
76
+ "ds_order": 1,
77
+ "data": [
78
+ 0.04508,
79
+ 0.0242,
80
+ 0.03592,
81
+ 0.01304,
82
+ 0.025,
83
+ 0.02748,
84
+ 0.05296,
85
+ 0.01864,
86
+ 0.02688,
87
+ 0.03676,
88
+ 0.03696,
89
+ null,
90
+ null
91
+ ],
92
+ "last_value": 0.04,
93
+ "minimum_value": null,
94
+ "maximum_value": null,
95
+ "average_value": 0.03
96
+ },
97
+ {
98
+ "metric_id": 3,
99
+ "metric": "Centreon-Server: rtmax",
100
+ "metric_legend": "Centreon-Server: rtmax",
101
+ "unit": "ms",
102
+ "min": null,
103
+ "max": null,
104
+ "ds_data": {
105
+ "ds_color_line": "#525256",
106
+ "ds_color_area": "#525256",
107
+ "ds_filled": false,
108
+ "ds_invert": false,
109
+ "ds_legend": null,
110
+ "ds_stack": true,
111
+ "ds_stack_key": "test",
112
+ "ds_order": 2,
113
+ "ds_transparency": 80.0,
114
+ "ds_color_line_mode": 0
115
+ },
116
+ "legend": "Centreon-Server: Round-Trip Maximum Time",
117
+ "stack": 0,
118
+ "warning_high_threshold": null,
119
+ "critical_high_threshold": null,
120
+ "warning_low_threshold": null,
121
+ "critical_low_threshold": null,
122
+ "ds_order": 2,
123
+ "data": [
124
+ 0.11372,
125
+ 0.05604,
126
+ 0.08556,
127
+ 0.02548,
128
+ 0.05352,
129
+ 0.05336,
130
+ 0.109,
131
+ 0.04112,
132
+ 0.05504,
133
+ 0.06812,
134
+ 0.08644,
135
+ null,
136
+ null
137
+ ],
138
+ "last_value": 0.09,
139
+ "minimum_value": null,
140
+ "maximum_value": 0.11,
141
+ "average_value": null
142
+ },
143
+ {
144
+ "metric_id": 4,
145
+ "metric": "Centreon-Server: rtmin",
146
+ "metric_legend": "Centreon-Server: rtmin",
147
+ "unit": "ms",
148
+ "min": null,
149
+ "max": null,
150
+ "ds_data": {
151
+ "ds_color_line": "#191777",
152
+ "ds_color_area": "#191777",
153
+ "ds_filled": false,
154
+ "ds_invert": false,
155
+ "ds_legend": null,
156
+ "ds_stack": true,
157
+ "ds_stack_key": "test",
158
+ "ds_order": 2,
159
+ "ds_transparency": 80.0,
160
+ "ds_color_line_mode": 0
161
+ },
162
+ "legend": "Centreon-Server: Round-Trip Minimum Time",
163
+ "stack": 0,
164
+ "warning_high_threshold": null,
165
+ "critical_high_threshold": null,
166
+ "warning_low_threshold": null,
167
+ "critical_low_threshold": null,
168
+ "ds_order": 2,
169
+ "data": [
170
+ 0.00984,
171
+ 0.008,
172
+ 0.00784,
173
+ 0.00624,
174
+ 0.00932,
175
+ 0.01348,
176
+ 0.01796,
177
+ 0.0064,
178
+ 0.01148,
179
+ 0.01644,
180
+ 0.01168,
181
+ null,
182
+ null
183
+ ],
184
+ "last_value": 0.01,
185
+ "minimum_value": 0.01,
186
+ "maximum_value": null,
187
+ "average_value": null
188
+ }
189
+ ],
190
+ "times": [
191
+ "2024-06-19T10:50:00+02:00",
192
+ "2024-06-19T10:55:00+02:00",
193
+ "2024-06-19T11:00:00+02:00",
194
+ "2024-06-19T11:05:00+02:00",
195
+ "2024-06-19T11:10:00+02:00",
196
+ "2024-06-19T11:15:00+02:00",
197
+ "2024-06-19T11:20:00+02:00",
198
+ "2024-06-19T11:25:00+02:00",
199
+ "2024-06-19T11:30:00+02:00",
200
+ "2024-06-19T11:35:00+02:00",
201
+ "2024-06-19T11:40:00+02:00",
202
+ "2024-06-19T11:45:00+02:00",
203
+ "2024-06-19T11:50:00+02:00"
204
+ ]
205
+ }
@@ -96,7 +96,6 @@ const SelectField = ({
96
96
  fullWidth={fullWidth}
97
97
  size="small"
98
98
  {...formControlProps}
99
-
100
99
  >
101
100
  {label && <InputLabel>{label}</InputLabel>}
102
101
  <Select
@@ -151,4 +150,4 @@ const SelectField = ({
151
150
  );
152
151
  };
153
152
 
154
- export default SelectField;
153
+ export default SelectField;
@@ -3,6 +3,7 @@ import { Provider as JotaiProvider, createStore } from 'jotai';
3
3
 
4
4
  import { StylesProvider, createGenerateClassName } from '@mui/styles';
5
5
 
6
+ import { ThemeOptions } from '@mui/material';
6
7
  import { QueryProvider, ThemeProvider } from '..';
7
8
  import SnackbarProvider from '../Snackbar/SnackbarProvider';
8
9
 
@@ -12,6 +13,10 @@ export interface ModuleProps {
12
13
  queryClient?: QueryClient;
13
14
  seedName: string;
14
15
  store: ReturnType<typeof createStore>;
16
+ overrideTheme?: {
17
+ light: Partial<ThemeOptions>;
18
+ dark: Partial<ThemeOptions>;
19
+ };
15
20
  }
16
21
 
17
22
  const Module = ({
@@ -19,7 +24,8 @@ const Module = ({
19
24
  seedName,
20
25
  maxSnackbars = 3,
21
26
  store,
22
- queryClient
27
+ queryClient,
28
+ overrideTheme
23
29
  }: ModuleProps): JSX.Element => {
24
30
  const generateClassName = createGenerateClassName({
25
31
  seed: seedName
@@ -29,7 +35,7 @@ const Module = ({
29
35
  <QueryProvider queryClient={queryClient}>
30
36
  <JotaiProvider store={store}>
31
37
  <StylesProvider generateClassName={generateClassName}>
32
- <ThemeProvider>
38
+ <ThemeProvider overrideTheme={overrideTheme}>
33
39
  <SnackbarProvider maxSnackbars={maxSnackbars}>
34
40
  {children}
35
41
  </SnackbarProvider>
@@ -1,11 +1,12 @@
1
1
  import { useAtomValue } from 'jotai';
2
- import { equals } from 'ramda';
2
+ import { equals, mergeDeepRight } from 'ramda';
3
3
  import { CSSInterpolation } from 'tss-react';
4
4
 
5
5
  import {
6
6
  ButtonProps,
7
7
  InputBaseProps,
8
8
  ThemeProvider as MuiThemeProvider,
9
+ PaletteOptions,
9
10
  StyledEngineProvider,
10
11
  Theme,
11
12
  createTheme
@@ -26,7 +27,7 @@ import { ReactNode, useMemo } from 'react';
26
27
  import { getPalette } from './palettes';
27
28
 
28
29
  declare module '@mui/styles/defaultTheme' {
29
- interface DefaultTheme extends Theme { }
30
+ interface DefaultTheme extends Theme {}
30
31
  }
31
32
 
32
33
  declare module '@mui/material/TextField' {
@@ -198,14 +199,14 @@ export const getTheme = (mode: ThemeMode): ThemeOptions => ({
198
199
  styleOverrides: {
199
200
  root: ({ theme }) => ({
200
201
  '&:hover, &.Mui-selected, &.Mui-selected:hover, &.Mui-selected:focus':
201
- {
202
- background: equals(theme.palette.mode, ThemeMode.dark)
203
- ? theme.palette.primary.dark
204
- : theme.palette.primary.light,
205
- color: equals(theme.palette.mode, ThemeMode.dark)
206
- ? theme.palette.common.white
207
- : theme.palette.primary.main
208
- },
202
+ {
203
+ background: equals(theme.palette.mode, ThemeMode.dark)
204
+ ? theme.palette.primary.dark
205
+ : theme.palette.primary.light,
206
+ color: equals(theme.palette.mode, ThemeMode.dark)
207
+ ? theme.palette.common.white
208
+ : theme.palette.primary.main
209
+ },
209
210
  fontSize: theme.typography.body2.fontSize
210
211
  })
211
212
  }
@@ -222,12 +223,12 @@ export const getTheme = (mode: ThemeMode): ThemeOptions => ({
222
223
  styleOverrides: {
223
224
  root: ({ theme }) => ({
224
225
  [`[role="tooltip"] &, &.MuiMenu-paper, &.${autocompleteClasses.paper}`]:
225
- {
226
- backgroundColor: theme.palette.background.default,
227
- border: 'none',
228
- borderRadius: `${theme.shape.borderRadius}px`,
229
- boxShadow: theme.shadows[3]
230
- }
226
+ {
227
+ backgroundColor: theme.palette.background.default,
228
+ border: 'none',
229
+ borderRadius: `${theme.shape.borderRadius}px`,
230
+ boxShadow: theme.shadows[3]
231
+ }
231
232
  })
232
233
  }
233
234
  },
@@ -257,15 +258,23 @@ export const getTheme = (mode: ThemeMode): ThemeOptions => ({
257
258
 
258
259
  interface Props {
259
260
  children: ReactNode;
261
+ overrideTheme?: {
262
+ light: Partial<PaletteOptions>;
263
+ dark: Partial<PaletteOptions>;
264
+ };
260
265
  }
261
266
 
262
- const ThemeProvider = ({ children }: Props): JSX.Element => {
267
+ const ThemeProvider = ({ children, overrideTheme }: Props): JSX.Element => {
263
268
  const { themeMode } = useAtomValue(userAtom);
264
269
 
265
- const theme = useMemo(
266
- () => createTheme(getTheme(themeMode || ThemeMode.light)),
267
- [themeMode]
268
- );
270
+ const theme = useMemo(() => {
271
+ const overrideThemeByMode = overrideTheme?.[themeMode || 'light'];
272
+ return createTheme(
273
+ mergeDeepRight(getTheme(themeMode || ThemeMode.light), {
274
+ palette: overrideThemeByMode || {}
275
+ })
276
+ );
277
+ }, [themeMode, overrideTheme]);
269
278
 
270
279
  return (
271
280
  <StyledEngineProvider injectFirst enableCssLayer>
@@ -25,7 +25,7 @@
25
25
  /* =============
26
26
  COLOR SYSTEM
27
27
  ============= */
28
-
28
+
29
29
  /* Action colors */
30
30
  --color-action-acknowledged: #745f35;
31
31
  --color-action-acknowledged-background: #dfd2b9;
@@ -43,7 +43,7 @@
43
43
  --color-action-in-downtime-background: #e5d8f3;
44
44
  --color-action-selected: rgba(102, 102, 102, 0.3);
45
45
  --color-action-selected-opacity: 0.3;
46
-
46
+
47
47
  /* Background colors */
48
48
  --color-background-default: #f4f4f4;
49
49
  --color-background-listing-header: #666666;
@@ -52,18 +52,18 @@
52
52
  --color-background-paper: #ffffff;
53
53
  --color-background-tooltip: #434e58;
54
54
  --color-background-widget: #f8f8f8;
55
-
55
+
56
56
  /* Chip colors */
57
57
  --color-chip-error: #ff6666;
58
58
  --color-chip-info: #1588d1;
59
59
  --color-chip-neutral: #6da4e4;
60
60
  --color-chip-success: #88b922;
61
61
  --color-chip-warning: #fd9b27;
62
-
62
+
63
63
  /* Utility colors */
64
64
  --color-divider: #e3e3e3;
65
65
  --color-error-main: #ff4a4a;
66
-
66
+
67
67
  /* Header colors */
68
68
  --color-header-page-action-background-active: #1975d10f;
69
69
  --color-header-page-action-background-default: #ffffff00;
@@ -90,10 +90,10 @@
90
90
  --color-header-menu-item-color-active: #3e85d5;
91
91
  --color-header-menu-item-color-default: #1b2127;
92
92
  --color-header-menu-item-color-hover: #101418;
93
-
93
+
94
94
  /* State colors */
95
95
  --color-pending-main: #1ebeb3;
96
-
96
+
97
97
  /* Primary & Secondary colors */
98
98
  --color-primary-main: #2e68aa;
99
99
  --color-primary-light: #cde7fc;
@@ -101,7 +101,7 @@
101
101
  --color-secondary-main: #c772d6;
102
102
  --color-secondary-light: #e5a5f0;
103
103
  --color-secondary-dark: #ac28c1;
104
-
104
+
105
105
  /* Status colors */
106
106
  --color-status-background-error: #ff6666;
107
107
  --color-status-background-none: --alpha(#2e68aa / 10%);
@@ -110,7 +110,7 @@
110
110
  --color-stauts-background-unknown: #e3e3e3;
111
111
  --color-status-background-warning: #fd9b27;
112
112
  --color-success-main: #88b922;
113
-
113
+
114
114
  /* Text colors */
115
115
  --color-text-disabled: #999999;
116
116
  --color-text-primary: #000000;
@@ -118,7 +118,7 @@
118
118
  --color-warning-main: #fd9b27;
119
119
  --color-warning-light: #fcc481;
120
120
  --color-warning-dark: #fc7e00;
121
-
121
+
122
122
  /* Base colors */
123
123
  --color-white: #ffffff;
124
124
  --color-black: #000000;
@@ -5,16 +5,22 @@ import { useStyles } from './PageLayout.styles';
5
5
  type PageLayoutProps = {
6
6
  children: Array<ReactNode> | ReactNode;
7
7
  variant?: 'default' | 'fixed-header';
8
+ className?: string;
8
9
  };
9
10
 
10
11
  export const PageLayout = ({
11
12
  children,
12
- variant = 'default'
13
+ variant = 'default',
14
+ className
13
15
  }: PageLayoutProps): ReactElement => {
14
- const { classes } = useStyles();
16
+ const { classes, cx } = useStyles();
15
17
 
16
18
  return (
17
- <section className={classes.pageLayout} data-variant={variant} id="page">
19
+ <section
20
+ className={cx(classes.pageLayout, className)}
21
+ data-variant={variant}
22
+ id="page"
23
+ >
18
24
  {children}
19
25
  </section>
20
26
  );
@@ -5,17 +5,19 @@ import { useStyles } from './PageLayout.styles';
5
5
  interface PageLayoutActionsProps {
6
6
  children: Array<ReactNode> | ReactNode;
7
7
  rowReverse?: boolean;
8
+ className?: string;
8
9
  }
9
10
 
10
11
  export const PageLayoutActions = ({
11
12
  children,
12
- rowReverse
13
+ rowReverse,
14
+ className
13
15
  }: PageLayoutActionsProps): ReactElement => {
14
- const { classes } = useStyles();
16
+ const { classes, cx } = useStyles();
15
17
 
16
18
  return (
17
19
  <section
18
- className={classes.pageLayoutActions}
20
+ className={cx(classes.pageLayoutActions, className)}
19
21
  data-row-reverse={rowReverse}
20
22
  id="actions"
21
23
  >
@@ -5,17 +5,19 @@ import { useStyles } from './PageLayout.styles';
5
5
  type PageLayoutBodyProps = {
6
6
  children: Array<ReactNode> | ReactNode;
7
7
  hasBackground?: boolean;
8
+ className?: string;
8
9
  };
9
10
 
10
11
  export const PageLayoutBody = ({
11
12
  children,
12
- hasBackground = false
13
+ hasBackground = false,
14
+ className
13
15
  }: PageLayoutBodyProps): ReactElement => {
14
- const { classes } = useStyles();
16
+ const { classes, cx } = useStyles();
15
17
 
16
18
  return (
17
19
  <section
18
- className={classes.pageLayoutBody}
20
+ className={cx(classes.pageLayoutBody, className)}
19
21
  data-has-background={hasBackground}
20
22
  data-has-actions={!!children?.length}
21
23
  id="page-body"
@@ -4,15 +4,17 @@ import { useStyles } from './PageLayout.styles';
4
4
 
5
5
  type PageLayoutHeaderProps = {
6
6
  children: Array<ReactNode> | ReactNode;
7
+ className?: string;
7
8
  };
8
9
 
9
10
  export const PageLayoutHeader = ({
10
- children
11
+ children,
12
+ className
11
13
  }: PageLayoutHeaderProps): JSX.Element => {
12
- const { classes } = useStyles();
14
+ const { classes, cx } = useStyles();
13
15
 
14
16
  return (
15
- <header className={classes.pageLayoutHeader} id="header">
17
+ <header className={cx(classes.pageLayoutHeader, className)} id="header">
16
18
  {children}
17
19
  </header>
18
20
  );
@@ -72,8 +72,7 @@ const useStyles = makeStyles<{
72
72
  opacity: 0.6
73
73
  },
74
74
  top: theme.spacing(1)
75
- },
76
-
75
+ }
77
76
  }));
78
77
 
79
78
  export { useStyles };
@@ -16,7 +16,11 @@ const ModalHeader = ({
16
16
  }: ModalHeaderProps & DialogTitleProps): ReactElement => {
17
17
  return (
18
18
  <div className={modalHeader}>
19
- <MuiDialogTitle className="p-0 font-bold text-2xl" color="primary" {...rest}>
19
+ <MuiDialogTitle
20
+ className="p-0 font-bold text-2xl"
21
+ color="primary"
22
+ {...rest}
23
+ >
20
24
  {children}
21
25
  </MuiDialogTitle>
22
26
  </div>