@centreon/ui 23.10.1-sync-dev-23-10-x-develop-oss.0 → 23.10.1-sync-release-33038.0

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 (59) hide show
  1. package/package.json +1 -1
  2. package/src/Form/Inputs/ConnectedAutocomplete.tsx +3 -1
  3. package/src/Form/Inputs/models.ts +1 -0
  4. package/src/Graph/Gauge/Gauge.stories.tsx +15 -2
  5. package/src/Graph/HeatMap/HeatMap.stories.tsx +105 -0
  6. package/src/Graph/HeatMap/HeatMap.styles.tsx +29 -0
  7. package/src/Graph/HeatMap/HeatMap.tsx +12 -0
  8. package/src/Graph/HeatMap/HeatMapData.json +137 -0
  9. package/src/Graph/HeatMap/ResponsiveHeatMap.tsx +98 -0
  10. package/src/Graph/HeatMap/index.ts +1 -0
  11. package/src/Graph/HeatMap/model.ts +33 -0
  12. package/src/Graph/LineChart/BasicComponents/Lines/RegularLines/index.tsx +1 -1
  13. package/src/Graph/LineChart/BasicComponents/useFilterLines.ts +2 -4
  14. package/src/Graph/LineChart/Legend/InteractiveValue.tsx +3 -3
  15. package/src/Graph/LineChart/Legend/Legend.styles.ts +78 -32
  16. package/src/Graph/LineChart/Legend/LegendContent.tsx +12 -6
  17. package/src/Graph/LineChart/Legend/LegendHeader.tsx +69 -21
  18. package/src/Graph/LineChart/Legend/index.tsx +51 -23
  19. package/src/Graph/LineChart/Legend/models.ts +5 -0
  20. package/src/Graph/LineChart/Legend/useLegend.ts +9 -10
  21. package/src/Graph/LineChart/LineChart.tsx +17 -3
  22. package/src/Graph/index.ts +1 -0
  23. package/src/InputField/Select/Autocomplete/Connected/Multi/index.test.tsx +1 -0
  24. package/src/InputField/Select/Autocomplete/Connected/index.test.tsx +1 -0
  25. package/src/InputField/Select/Autocomplete/Connected/index.tsx +3 -0
  26. package/src/InputField/Text/index.tsx +6 -1
  27. package/src/RichTextEditor/RichTextEditor.cypress.spec.tsx +100 -52
  28. package/src/RichTextEditor/RichTextEditor.tsx +9 -3
  29. package/src/RichTextEditor/plugins/ToolbarPlugin/AlignPicker.tsx +21 -20
  30. package/src/RichTextEditor/plugins/ToolbarPlugin/BlockButtons.tsx +35 -77
  31. package/src/RichTextEditor/plugins/ToolbarPlugin/FormatButtons.tsx +29 -83
  32. package/src/RichTextEditor/plugins/ToolbarPlugin/LinkButton.tsx +106 -0
  33. package/src/RichTextEditor/plugins/ToolbarPlugin/ListButton.tsx +155 -0
  34. package/src/RichTextEditor/plugins/ToolbarPlugin/MacrosButton.tsx +23 -39
  35. package/src/RichTextEditor/plugins/ToolbarPlugin/ToolbarPlugin.styles.ts +24 -14
  36. package/src/RichTextEditor/plugins/ToolbarPlugin/UndoRedoButtons.tsx +6 -0
  37. package/src/RichTextEditor/plugins/ToolbarPlugin/index.tsx +5 -10
  38. package/src/RichTextEditor/translatedLabels.ts +3 -0
  39. package/src/ThemeProvider/palettes.ts +4 -4
  40. package/src/Typography/EllipsisTypography.tsx +18 -0
  41. package/src/api/buildListingEndpoint/models.ts +2 -1
  42. package/src/api/customFetch.ts +12 -3
  43. package/src/api/useFetchQuery/index.ts +16 -5
  44. package/src/api/useGraphQuery/index.ts +4 -1
  45. package/src/api/useMutationQuery/index.ts +4 -1
  46. package/src/components/Header/PageHeader/PageHeader.styles.ts +28 -1
  47. package/src/components/Header/PageHeader/PageHeaderMessage.tsx +32 -0
  48. package/src/components/Header/PageHeader/index.ts +2 -0
  49. package/src/components/ItemComposition/Item.tsx +2 -2
  50. package/src/components/ItemComposition/ItemComposition.styles.ts +3 -0
  51. package/src/components/ItemComposition/ItemComposition.tsx +4 -2
  52. package/src/components/Menu/Button/MenuButton.tsx +4 -2
  53. package/src/components/Menu/MenuItem.tsx +5 -3
  54. package/src/components/Menu/MenuItems.tsx +4 -3
  55. package/src/components/Modal/Modal.styles.ts +4 -2
  56. package/src/index.ts +4 -0
  57. package/src/utils/useInfiniteScrollListing.ts +22 -7
  58. package/src/utils/useLocaleDateTimeFormat/index.ts +3 -0
  59. package/src/Graph/LineChart/Legend/Marker.tsx +0 -43
@@ -2,7 +2,7 @@ import { useTranslation } from 'react-i18next';
2
2
 
3
3
  import { Typography } from '@mui/material';
4
4
 
5
- import { useStyles } from './Legend.styles';
5
+ import { useLegendContentStyles } from './Legend.styles';
6
6
 
7
7
  interface Props {
8
8
  data: string;
@@ -10,15 +10,21 @@ interface Props {
10
10
  }
11
11
 
12
12
  const LegendContent = ({ data, label }: Props): JSX.Element => {
13
- const { classes } = useStyles({});
13
+ const { classes, cx } = useLegendContentStyles();
14
14
 
15
15
  const { t } = useTranslation();
16
16
 
17
17
  return (
18
- <div data-testid={label}>
19
- <Typography variant="caption">{t(label)}: </Typography>
20
- <Typography className={classes.minMaxAvgValue} variant="caption">
21
- {data}
18
+ <div className={classes.text} data-testid={label}>
19
+ <Typography className={classes.text} component="span" variant="caption">
20
+ {t(label)}:{' '}
21
+ <Typography
22
+ className={cx(classes.minMaxAvgValue, classes.text)}
23
+ component="span"
24
+ variant="caption"
25
+ >
26
+ {data}
27
+ </Typography>
22
28
  </Typography>
23
29
  </div>
24
30
  );
@@ -1,43 +1,91 @@
1
1
  import { includes, isEmpty, split } from 'ramda';
2
2
 
3
- import { Tooltip, Typography } from '@mui/material';
3
+ import { Typography } from '@mui/material';
4
4
 
5
+ import { EllipsisTypography, formatMetricValue } from '../../..';
5
6
  import { Line } from '../../common/timeSeries/models';
7
+ import { Tooltip } from '../../../components';
6
8
 
7
- import { useStyles } from './Legend.styles';
9
+ import { useLegendHeaderStyles } from './Legend.styles';
10
+ import { LegendDisplayMode } from './models';
11
+ import LegendContent from './LegendContent';
8
12
 
9
13
  interface Props {
14
+ color: string;
15
+ disabled?: boolean;
10
16
  line: Line;
17
+ minMaxAvg?;
18
+ value?: string | null;
11
19
  }
12
20
 
13
- const LegendHeader = ({ line }: Props): JSX.Element => {
14
- const { classes } = useStyles({});
21
+ const LegendHeader = ({
22
+ line,
23
+ color,
24
+ disabled,
25
+ value,
26
+ minMaxAvg
27
+ }: Props): JSX.Element => {
28
+ const { classes, cx } = useLegendHeaderStyles({ color });
29
+
15
30
  const { unit, name, legend } = line;
16
31
 
17
32
  const legendName = legend || name;
18
- const unitName = ` (${unit})`;
33
+ const hasUnit = !isEmpty(unit);
34
+ const unitName = `(${unit})`;
19
35
  const metricName = includes('#', legendName)
20
36
  ? split('#')(legendName)[1]
21
37
  : legendName;
22
38
 
39
+ const getEndText = (): string => {
40
+ if (value) {
41
+ return `${value}${hasUnit ? ` ${unit}` : ''}`;
42
+ }
43
+
44
+ return hasUnit ? ` ${unitName}` : '';
45
+ };
46
+
23
47
  return (
24
- <div className={classes.legendName}>
25
- <Tooltip placement="top" title={legendName + unitName}>
26
- <Typography
27
- className={classes.legendName}
28
- component="p"
29
- variant="caption"
30
- >
31
- {metricName}
32
- </Typography>
33
- </Tooltip>
34
- <Typography
35
- className={classes.legendUnit}
36
- component="p"
37
- variant="caption"
48
+ <div className={classes.container}>
49
+ <Tooltip
50
+ followCursor={false}
51
+ label={
52
+ minMaxAvg ? (
53
+ <div>
54
+ <Typography>{`${legendName} ${unitName}`}</Typography>
55
+ <div className={classes.minMaxAvgContainer}>
56
+ {minMaxAvg.map(({ label, value: subValue }) => (
57
+ <LegendContent
58
+ data={formatMetricValue({
59
+ unit: line.unit,
60
+ value: subValue
61
+ })}
62
+ key={label}
63
+ label={label}
64
+ />
65
+ ))}
66
+ </div>
67
+ </div>
68
+ ) : (
69
+ `${legendName} ${unitName}`
70
+ )
71
+ }
72
+ placement="top"
38
73
  >
39
- {!isEmpty(line?.unit) && `(${line.unit})`}
40
- </Typography>
74
+ <div className={classes.markerAndLegendName}>
75
+ <div className={cx(classes.icon, { [classes.disabled]: disabled })} />
76
+ <EllipsisTypography
77
+ className={cx(classes.text, classes.legendName)}
78
+ data-mode={
79
+ value ? LegendDisplayMode.Compact : LegendDisplayMode.Normal
80
+ }
81
+ >
82
+ {metricName}
83
+ </EllipsisTypography>
84
+ </div>
85
+ </Tooltip>
86
+ {hasUnit && (
87
+ <Typography className={classes.text}>{getEndText()}</Typography>
88
+ )}
41
89
  </div>
42
90
  );
43
91
  };
@@ -16,8 +16,7 @@ import { timeValueAtom } from '../InteractiveComponents/interactionWithGraphAtom
16
16
  import InteractiveValue from './InteractiveValue';
17
17
  import { useStyles } from './Legend.styles';
18
18
  import LegendHeader from './LegendHeader';
19
- import LegendMarker from './Marker';
20
- import { GetMetricValueProps } from './models';
19
+ import { GetMetricValueProps, LegendDisplayMode } from './models';
21
20
  import useInteractiveValues from './useInteractiveValues';
22
21
  import useLegend from './useLegend';
23
22
  import LegendContent from './LegendContent';
@@ -29,6 +28,7 @@ interface Props {
29
28
  lines: Array<Line>;
30
29
  renderExtraComponent?: ReactNode;
31
30
  setLinesGraph: Dispatch<SetStateAction<Array<Line> | null>>;
31
+ shouldDisplayLegendInCompactMode: boolean;
32
32
  timeSeries: Array<TimeValue>;
33
33
  toggable?: boolean;
34
34
  xScale;
@@ -43,7 +43,8 @@ const MainLegend = ({
43
43
  renderExtraComponent,
44
44
  displayAnchor = true,
45
45
  setLinesGraph,
46
- xScale
46
+ xScale,
47
+ shouldDisplayLegendInCompactMode
47
48
  }: Props): JSX.Element => {
48
49
  const { classes, cx } = useStyles({ limitLegendRows });
49
50
  const theme = useTheme();
@@ -85,9 +86,13 @@ const MainLegend = ({
85
86
  selectMetricLine(metric_id);
86
87
  };
87
88
 
89
+ const mode = shouldDisplayLegendInCompactMode
90
+ ? LegendDisplayMode.Compact
91
+ : LegendDisplayMode.Normal;
92
+
88
93
  return (
89
94
  <div className={classes.legend}>
90
- <div className={classes.items}>
95
+ <div className={classes.items} data-mode={mode}>
91
96
  {displayedLines.map((line) => {
92
97
  const { color, display, highlight, metric_id } = line;
93
98
 
@@ -126,22 +131,37 @@ const MainLegend = ({
126
131
  onMouseEnter={(): void => highlightLine(metric_id)}
127
132
  onMouseLeave={(): void => clearHighlight()}
128
133
  >
129
- <LegendMarker color={markerColor} disabled={!display} />
130
- <div className={classes.legendData}>
131
- <LegendHeader line={line} />
132
- {displayAnchor && <InteractiveValue value={interactiveValue} />}
133
- {!interactiveValue && (
134
- <div className={classes.minMaxAvgContainer}>
135
- {minMaxAvg.map(({ label, value }) => (
136
- <LegendContent
137
- data={getMetricValue({ unit: line.unit, value })}
138
- key={label}
139
- label={label}
140
- />
141
- ))}
142
- </div>
143
- )}
144
- </div>
134
+ <LegendHeader
135
+ color={markerColor}
136
+ disabled={!display}
137
+ line={line}
138
+ minMaxAvg={
139
+ shouldDisplayLegendInCompactMode ? minMaxAvg : undefined
140
+ }
141
+ value={
142
+ shouldDisplayLegendInCompactMode
143
+ ? interactiveValue
144
+ : undefined
145
+ }
146
+ />
147
+ {!shouldDisplayLegendInCompactMode && (
148
+ <div>
149
+ {displayAnchor && (
150
+ <InteractiveValue value={interactiveValue} />
151
+ )}
152
+ {!interactiveValue && (
153
+ <div className={classes.minMaxAvgContainer}>
154
+ {minMaxAvg.map(({ label, value }) => (
155
+ <LegendContent
156
+ data={getMetricValue({ unit: line.unit, value })}
157
+ key={label}
158
+ label={label}
159
+ />
160
+ ))}
161
+ </div>
162
+ )}
163
+ </div>
164
+ )}
145
165
  </Box>
146
166
  );
147
167
  })}
@@ -152,8 +172,15 @@ const MainLegend = ({
152
172
  };
153
173
 
154
174
  const Legend = (props: Props): JSX.Element => {
155
- const { toggable, limitLegendRows, timeSeries, lines, base, displayAnchor } =
156
- props;
175
+ const {
176
+ toggable,
177
+ limitLegendRows,
178
+ timeSeries,
179
+ lines,
180
+ base,
181
+ displayAnchor,
182
+ shouldDisplayLegendInCompactMode
183
+ } = props;
157
184
  const timeValue = useAtomValue(timeValueAtom);
158
185
 
159
186
  return useMemoComponent({
@@ -165,7 +192,8 @@ const Legend = (props: Props): JSX.Element => {
165
192
  base,
166
193
  toggable,
167
194
  limitLegendRows,
168
- displayAnchor
195
+ displayAnchor,
196
+ shouldDisplayLegendInCompactMode
169
197
  ]
170
198
  });
171
199
  };
@@ -9,3 +9,8 @@ export interface GetMetricValueProps {
9
9
  unit: string;
10
10
  value: number | null;
11
11
  }
12
+
13
+ export enum LegendDisplayMode {
14
+ Compact = 'compact',
15
+ Normal = 'normal'
16
+ }
@@ -32,20 +32,19 @@ const useLegend = ({ lines, setLinesGraph }: Props): LegendActions => {
32
32
  find(propEq('metric_id', metric_id), lines) as Line;
33
33
 
34
34
  const toggleMetricLine = (metric_id): void => {
35
- const line = getLineByMetric(metric_id);
35
+ const data = lines.map((line) => ({
36
+ ...line,
37
+ display: equals(line.metric_id, metric_id) ? !line.display : line.display
38
+ }));
36
39
 
37
- setLinesGraph([
38
- ...reject(propEq('metric_id', metric_id), lines),
39
- { ...line, display: !line.display }
40
- ]);
40
+ setLinesGraph(data);
41
41
  };
42
42
 
43
43
  const highlightLine = (metric_id): void => {
44
- const fadedLines = map((line) => ({ ...line, highlight: false }), lines);
45
- const data = [
46
- ...reject(propEq('metric_id', metric_id), fadedLines),
47
- { ...getLineByMetric(metric_id), highlight: true }
48
- ];
44
+ const data = lines.map((line) => ({
45
+ ...line,
46
+ highlight: equals(line.metric_id, metric_id)
47
+ }));
49
48
 
50
49
  setLinesGraph(data);
51
50
  };
@@ -1,7 +1,7 @@
1
1
  import { MutableRefObject, useMemo, useRef, useState } from 'react';
2
2
 
3
3
  import { Group, Tooltip } from '@visx/visx';
4
- import { flatten, isNil, pluck } from 'ramda';
4
+ import { flatten, gt, isNil, lte, pluck, reduce } from 'ramda';
5
5
 
6
6
  import { ClickAwayListener, Fade, Skeleton, useTheme } from '@mui/material';
7
7
 
@@ -33,6 +33,9 @@ import {
33
33
  import { useIntersection } from './useLineChartIntersection';
34
34
  import { CurveType } from './BasicComponents/Lines/models';
35
35
  import Thresholds from './BasicComponents/Thresholds';
36
+ import { legendWidth } from './Legend/Legend.styles';
37
+
38
+ const extraMargin = 10;
36
39
 
37
40
  interface Props extends LineChartProps {
38
41
  curve: CurveType;
@@ -92,7 +95,8 @@ const LineChart = ({
92
95
  showTooltip: showThresholdTooltip
93
96
  } = Tooltip.useTooltip();
94
97
 
95
- const graphWidth = width > 0 ? width - margin.left - margin.right : 0;
98
+ const graphWidth =
99
+ width > 0 ? width - margin.left - margin.right - extraMargin : 0;
96
100
  const graphHeight =
97
101
  (height || 0) > 0
98
102
  ? (height || 0) -
@@ -158,6 +162,15 @@ const LineChart = ({
158
162
  const displayLegend = legend?.display ?? true;
159
163
  const displayTooltip = !isNil(tooltip?.renderComponent);
160
164
 
165
+ const legendItemsWidth = reduce(
166
+ (acc) => acc + legendWidth * 8 + 24,
167
+ 0,
168
+ displayedLines
169
+ );
170
+
171
+ const shouldDisplayLegendInCompactMode =
172
+ lte(graphWidth, 808) && gt(legendItemsWidth, graphWidth);
173
+
161
174
  if (!isInViewport) {
162
175
  return (
163
176
  <Skeleton
@@ -185,7 +198,7 @@ const LineChart = ({
185
198
  width={width}
186
199
  />
187
200
  <svg height={graphHeight + margin.top} ref={graphSvgRef} width="100%">
188
- <Group.Group left={margin.left} top={margin.top}>
201
+ <Group.Group left={margin.left + extraMargin / 2} top={margin.top}>
189
202
  <Grids
190
203
  height={graphHeight - margin.top}
191
204
  leftScale={leftScale}
@@ -291,6 +304,7 @@ const LineChart = ({
291
304
  lines={newLines}
292
305
  renderExtraComponent={legend?.renderExtraComponent}
293
306
  setLinesGraph={setLinesGraph}
307
+ shouldDisplayLegendInCompactMode={shouldDisplayLegendInCompactMode}
294
308
  timeSeries={timeSeries}
295
309
  xScale={xScale}
296
310
  />
@@ -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';
@@ -17,6 +17,7 @@ const renderMultiAutocompleteField = (): RenderResult =>
17
17
  render(
18
18
  <TestQueryProvider>
19
19
  <MultiConnectedAutocompleteField
20
+ baseEndpoint=""
20
21
  field="host.name"
21
22
  getEndpoint={getEndpoint}
22
23
  label={label}
@@ -45,6 +45,7 @@ const renderSingleConnectedAutocompleteField = (
45
45
  render(
46
46
  <TestQueryProvider>
47
47
  <SingleConnectedAutocompleteField
48
+ baseEndpoint=""
48
49
  field="host.name"
49
50
  getEndpoint={getEndpoint}
50
51
  label={label}
@@ -32,6 +32,7 @@ import useFetchQuery from '../../../../api/useFetchQuery';
32
32
 
33
33
  export interface ConnectedAutoCompleteFieldProps<TData> {
34
34
  allowUniqOption?: boolean;
35
+ baseEndpoint?: string;
35
36
  conditionField?: keyof SelectEntry;
36
37
  field: string;
37
38
  getEndpoint: ({ search, page }) => string;
@@ -60,6 +61,7 @@ const ConnectedAutocompleteField = (
60
61
  displayOptionThumbnail,
61
62
  queryKey,
62
63
  allowUniqOption,
64
+ baseEndpoint,
63
65
  ...props
64
66
  }: ConnectedAutoCompleteFieldProps<TData> &
65
67
  Omit<AutocompleteFieldProps, 'options'>): JSX.Element => {
@@ -87,6 +89,7 @@ const ConnectedAutocompleteField = (
87
89
  const { fetchQuery, isFetching, prefetchNextPage } = useFetchQuery<
88
90
  ListingModel<TData>
89
91
  >({
92
+ baseEndpoint,
90
93
  fetchHeaders: getRequestHeaders,
91
94
  getEndpoint: (params) => {
92
95
  return getEndpoint({
@@ -80,6 +80,7 @@ export type Props = {
80
80
  autoSizeCustomPadding?: number;
81
81
  autoSizeDefaultWidth?: number;
82
82
  className?: string;
83
+ containerClassName?: string;
83
84
  dataTestId: string;
84
85
  debounced?: boolean;
85
86
  displayErrorInTooltip?: boolean;
@@ -112,6 +113,7 @@ const TextField = forwardRef(
112
113
  autoSizeCustomPadding,
113
114
  defaultValue,
114
115
  required = false,
116
+ containerClassName,
115
117
  ...rest
116
118
  }: Props,
117
119
  ref: React.ForwardedRef<HTMLDivElement>
@@ -142,7 +144,10 @@ const TextField = forwardRef(
142
144
  }, [innerValue, debounced, defaultValue]);
143
145
 
144
146
  return (
145
- <Box sx={{ width: autoSize ? 'auto' : '100%' }}>
147
+ <Box
148
+ className={containerClassName}
149
+ sx={{ width: autoSize ? 'auto' : '100%' }}
150
+ >
146
151
  <Tooltip placement="top" title={tooltipTitle}>
147
152
  <MuiTextField
148
153
  data-testid={dataTestId}