@centreon/ui 24.4.72 → 24.4.74

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 (131) hide show
  1. package/package.json +24 -23
  2. package/src/Checkbox/fonts/roboto-bold-webfont.ttf +0 -0
  3. package/src/Checkbox/fonts/roboto-bold-webfont.woff +0 -0
  4. package/src/Checkbox/fonts/roboto-bold-webfont.woff2 +0 -0
  5. package/src/Checkbox/fonts/roboto-light-webfont.ttf +0 -0
  6. package/src/Checkbox/fonts/roboto-light-webfont.woff +0 -0
  7. package/src/Checkbox/fonts/roboto-light-webfont.woff2 +0 -0
  8. package/src/Checkbox/fonts/roboto-medium-webfont.ttf +0 -0
  9. package/src/Checkbox/fonts/roboto-medium-webfont.woff +0 -0
  10. package/src/Checkbox/fonts/roboto-medium-webfont.woff2 +0 -0
  11. package/src/Checkbox/fonts/roboto-regular-webfont.ttf +0 -0
  12. package/src/Checkbox/fonts/roboto-regular-webfont.woff +0 -0
  13. package/src/Checkbox/fonts/roboto-regular-webfont.woff2 +0 -0
  14. package/src/Dashboard/Item.tsx +2 -11
  15. package/src/Dashboard/Layout.tsx +2 -4
  16. package/src/Dashboard/utils.ts +1 -1
  17. package/src/Form/Inputs/Grid.tsx +8 -4
  18. package/src/Form/Inputs/models.ts +15 -14
  19. package/src/Graph/BarStack/BarStack.cypress.spec.tsx +87 -9
  20. package/src/Graph/BarStack/BarStack.stories.tsx +4 -2
  21. package/src/Graph/BarStack/BarStack.styles.ts +59 -30
  22. package/src/Graph/BarStack/Graph.tsx +176 -0
  23. package/src/Graph/BarStack/GraphAndLegend.tsx +119 -0
  24. package/src/Graph/BarStack/ResponsiveBarStack.tsx +62 -157
  25. package/src/Graph/BarStack/constants.ts +5 -0
  26. package/src/Graph/BarStack/models.ts +1 -1
  27. package/src/Graph/BarStack/useGraphAndLegend.ts +86 -0
  28. package/src/Graph/BarStack/useResponsiveBarStack.ts +74 -99
  29. package/src/Graph/HeatMap/ResponsiveHeatMap.tsx +19 -2
  30. package/src/Graph/HeatMap/model.ts +5 -1
  31. package/src/Graph/Legend/Legend.styles.ts +10 -0
  32. package/src/Graph/Legend/Legend.tsx +6 -1
  33. package/src/Graph/LineChart/BasicComponents/Lines/RegularLines/index.tsx +2 -1
  34. package/src/Graph/LineChart/BasicComponents/Lines/StackedLines/index.tsx +3 -4
  35. package/src/Graph/LineChart/Icons/Downtime.tsx +3 -3
  36. package/src/Graph/LineChart/InteractiveComponents/ZoomPreview/index.tsx +2 -1
  37. package/src/Graph/LineChart/Legend/Legend.styles.ts +16 -5
  38. package/src/Graph/LineChart/Legend/LegendHeader.tsx +4 -1
  39. package/src/Graph/LineChart/Legend/index.tsx +12 -5
  40. package/src/Graph/LineChart/LineChart.cypress.spec.tsx +53 -0
  41. package/src/Graph/LineChart/LineChart.tsx +10 -9
  42. package/src/Graph/LineChart/index.stories.tsx +13 -0
  43. package/src/Graph/LineChart/mockedData/curvesWithSameColor.json +252 -0
  44. package/src/Graph/LineChart/useLineChartData.ts +68 -18
  45. package/src/Graph/PieChart/ResponsivePie.tsx +3 -1
  46. package/src/Graph/PieChart/models.ts +1 -0
  47. package/src/Graph/Tree/DescendantNodes.tsx +0 -1
  48. package/src/Graph/Tree/Links.tsx +2 -15
  49. package/src/Graph/Tree/Tree.cypress.spec.tsx +0 -24
  50. package/src/Graph/Tree/Tree.stories.tsx +1 -17
  51. package/src/Graph/Tree/models.ts +0 -3
  52. package/src/Graph/common/utils.ts +51 -2
  53. package/src/Icon/BaseIcon.tsx +32 -0
  54. package/src/Icon/DowntimeIcon.tsx +14 -0
  55. package/src/InputField/Select/Autocomplete/Connected/Multi/index.test.tsx +21 -1
  56. package/src/InputField/Select/Autocomplete/Connected/index.test.tsx +2 -2
  57. package/src/InputField/Select/Autocomplete/Connected/index.tsx +10 -7
  58. package/src/InputField/Select/Autocomplete/Multi/index.stories.tsx +19 -0
  59. package/src/InputField/Select/Autocomplete/Multi/index.tsx +8 -5
  60. package/src/InputField/Text/index.tsx +7 -5
  61. package/src/Listing/ActionBar/index.tsx +1 -0
  62. package/src/PopoverMenu/index.tsx +4 -4
  63. package/src/RichTextEditor/ContentEditable.tsx +195 -195
  64. package/src/StoryBookThemeProvider/index.tsx +35 -36
  65. package/src/ThemeProvider/index.tsx +12 -12
  66. package/src/ThemeProvider/palettes.ts +11 -8
  67. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/PickersStartEndDate.tsx +2 -3
  68. package/src/TimePeriods/DateTimePickerInput.tsx +4 -1
  69. package/src/TopCounterElements/TopCounterLayout.tsx +4 -3
  70. package/src/TopCounterElements/useCloseOnLegacyPage.tsx +9 -6
  71. package/src/api/buildListingEndpoint/getSearchQueryParameterValue.ts +7 -1
  72. package/src/api/buildListingEndpoint/models.ts +1 -0
  73. package/src/api/useGraphQuery/index.ts +1 -7
  74. package/src/components/Form/AccessRights/AccessRights.cypress.spec.tsx +13 -27
  75. package/src/components/Form/AccessRights/AccessRights.stories.tsx +19 -0
  76. package/src/components/Form/AccessRights/AccessRights.styles.ts +1 -1
  77. package/src/components/Form/AccessRights/AccessRights.tsx +5 -6
  78. package/src/components/Form/AccessRights/Actions/Actions.styles.ts +7 -3
  79. package/src/components/Form/AccessRights/Actions/Actions.tsx +32 -15
  80. package/src/components/Form/AccessRights/Actions/useActions.ts +37 -4
  81. package/src/components/Form/AccessRights/models.ts +3 -0
  82. package/src/components/Form/AccessRights/storiesData.ts +3 -0
  83. package/src/components/List/Item/ListItem.styles.ts +2 -2
  84. package/src/components/Zoom/Minimap.tsx +2 -4
  85. package/src/components/Zoom/Zoom.cypress.spec.tsx +13 -13
  86. package/src/components/Zoom/Zoom.tsx +1 -4
  87. package/src/components/Zoom/ZoomContent.tsx +2 -5
  88. package/src/components/index.ts +0 -1
  89. package/src/fonts/roboto-bold-webfont.ttf +0 -0
  90. package/src/fonts/roboto-bold-webfont.woff +0 -0
  91. package/src/fonts/roboto-bold-webfont.woff2 +0 -0
  92. package/src/fonts/roboto-light-webfont.ttf +0 -0
  93. package/src/fonts/roboto-light-webfont.woff +0 -0
  94. package/src/fonts/roboto-light-webfont.woff2 +0 -0
  95. package/src/fonts/roboto-medium-webfont.ttf +0 -0
  96. package/src/fonts/roboto-medium-webfont.woff +0 -0
  97. package/src/fonts/roboto-medium-webfont.woff2 +0 -0
  98. package/src/fonts/roboto-regular-webfont.ttf +0 -0
  99. package/src/fonts/roboto-regular-webfont.woff +0 -0
  100. package/src/fonts/roboto-regular-webfont.woff2 +0 -0
  101. package/src/index.ts +1 -0
  102. package/src/utils/index.ts +25 -25
  103. package/src/utils/useFullscreen/Fullscreen.cypress.spec.tsx +3 -0
  104. package/src/utils/useInfiniteScrollListing.ts +6 -1
  105. package/src/utils/useLocale/index.ts +10 -0
  106. package/src/utils/useLocale/useLocale.cypress.spec.tsx +40 -0
  107. package/src/utils/useLocaleDateTimeFormat/index.ts +5 -2
  108. package/src/utils/usePluralizedTranslation.ts +4 -21
  109. package/src/@assets/icons/downtime.icon.svg +0 -1
  110. package/src/components/Form/AccessRights/useAccessRightsChange.ts +0 -30
  111. package/src/components/Form/AccessRights/utils.ts +0 -18
  112. package/src/components/Tabs/Tab.styles.ts +0 -25
  113. package/src/components/Tabs/TabPanel.tsx +0 -22
  114. package/src/components/Tabs/Tabs.cypress.spec.tsx +0 -70
  115. package/src/components/Tabs/Tabs.stories.tsx +0 -55
  116. package/src/components/Tabs/Tabs.tsx +0 -55
  117. package/src/components/Tabs/index.ts +0 -6
  118. package/src/utils/resourcesStatusURL.ts +0 -166
  119. package/src/utils/usePluralizedTranslation.test.ts +0 -159
  120. /package/{public → src/Button}/fonts/roboto-bold-webfont.ttf +0 -0
  121. /package/{public → src/Button}/fonts/roboto-bold-webfont.woff +0 -0
  122. /package/{public → src/Button}/fonts/roboto-bold-webfont.woff2 +0 -0
  123. /package/{public → src/Button}/fonts/roboto-light-webfont.ttf +0 -0
  124. /package/{public → src/Button}/fonts/roboto-light-webfont.woff +0 -0
  125. /package/{public → src/Button}/fonts/roboto-light-webfont.woff2 +0 -0
  126. /package/{public → src/Button}/fonts/roboto-medium-webfont.ttf +0 -0
  127. /package/{public → src/Button}/fonts/roboto-medium-webfont.woff +0 -0
  128. /package/{public → src/Button}/fonts/roboto-medium-webfont.woff2 +0 -0
  129. /package/{public → src/Button}/fonts/roboto-regular-webfont.ttf +0 -0
  130. /package/{public → src/Button}/fonts/roboto-regular-webfont.woff +0 -0
  131. /package/{public → src/Button}/fonts/roboto-regular-webfont.woff2 +0 -0
@@ -0,0 +1,252 @@
1
+ {
2
+ "global": {
3
+ "title": "oracle-buffer-hit-ratio graph on srv-oracle-users",
4
+ "start": "2023-06-18T17:04:46+02:00",
5
+ "end": "2023-06-19T17:04:46+02:00",
6
+ "vertical-label": "Value",
7
+ "base": 1000,
8
+ "width": 550,
9
+ "height": 140,
10
+ "scaled": 0,
11
+ "multiple_services": false
12
+ },
13
+ "metrics": [
14
+ {
15
+ "metric_id": 1,
16
+ "metric": "Centreon-Server: rta",
17
+ "metric_legend": "Centreon-Server: rta",
18
+ "unit": "ms",
19
+ "min": 0.0,
20
+ "max": null,
21
+ "ds_data": {
22
+ "ds_color_line": "#29AFEE"
23
+ },
24
+ "legend": "Centreon-Server: Round-Trip Average Time",
25
+ "stack": 0,
26
+ "warning_high_threshold": 200.0,
27
+ "critical_high_threshold": 400.0,
28
+ "warning_low_threshold": 0.0,
29
+ "critical_low_threshold": 0.0,
30
+ "ds_order": 1,
31
+ "data": [
32
+ null,
33
+ null,
34
+ null,
35
+ null,
36
+ null,
37
+ null,
38
+ null,
39
+ null,
40
+ null,
41
+ 0.040219730942,
42
+ 0.03038,
43
+ 0.02108,
44
+ null
45
+ ],
46
+ "last_value": 0.02,
47
+ "minimum_value": null,
48
+ "maximum_value": null,
49
+ "average_value": 0.03
50
+ },
51
+ {
52
+ "metric_id": 21,
53
+ "metric": "Centreon-Server_1: rta",
54
+ "metric_legend": "Centreon-Server_1: rta",
55
+ "unit": "ms",
56
+ "min": 0.0,
57
+ "max": null,
58
+ "ds_data": {
59
+ "ds_color_line": "#29AFEE"
60
+ },
61
+ "legend": "Centreon-Server_1: Round-Trip Average Time",
62
+ "stack": 0,
63
+ "warning_high_threshold": 200.0,
64
+ "critical_high_threshold": 400.0,
65
+ "warning_low_threshold": 0.0,
66
+ "critical_low_threshold": 0.0,
67
+ "ds_order": 1,
68
+ "data": [
69
+ null,
70
+ null,
71
+ null,
72
+ null,
73
+ null,
74
+ null,
75
+ null,
76
+ null,
77
+ null,
78
+ null,
79
+ 0.046261744966,
80
+ 0.033813333333,
81
+ null
82
+ ],
83
+ "last_value": 0.03,
84
+ "minimum_value": null,
85
+ "maximum_value": null,
86
+ "average_value": 0.04
87
+ },
88
+ {
89
+ "metric_id": 17,
90
+ "metric": "Centreon-Server_2: rta",
91
+ "metric_legend": "Centreon-Server_2: rta",
92
+ "unit": "ms",
93
+ "min": 0.0,
94
+ "max": null,
95
+ "ds_data": {
96
+ "ds_color_line": "#29AFEE"
97
+ },
98
+ "legend": "Centreon-Server_2: Round-Trip Average Time",
99
+ "stack": 0,
100
+ "warning_high_threshold": 200.0,
101
+ "critical_high_threshold": 400.0,
102
+ "warning_low_threshold": 0.0,
103
+ "critical_low_threshold": 0.0,
104
+ "ds_order": 1,
105
+ "data": [
106
+ null,
107
+ null,
108
+ null,
109
+ null,
110
+ null,
111
+ null,
112
+ null,
113
+ null,
114
+ null,
115
+ null,
116
+ 0.035661073826,
117
+ 0.03853,
118
+ null
119
+ ],
120
+ "last_value": 0.04,
121
+ "minimum_value": null,
122
+ "maximum_value": null,
123
+ "average_value": 0.04
124
+ },
125
+ {
126
+ "metric_id": 13,
127
+ "metric": "Centreon-Server_3: rta",
128
+ "metric_legend": "Centreon-Server_3: rta",
129
+ "unit": "ms",
130
+ "min": 0.0,
131
+ "max": null,
132
+ "ds_data": {
133
+ "ds_color_line": "#29AFEE"
134
+ },
135
+ "legend": "Centreon-Server_3: Round-Trip Average Time",
136
+ "stack": 0,
137
+ "warning_high_threshold": 200.0,
138
+ "critical_high_threshold": 400.0,
139
+ "warning_low_threshold": 0.0,
140
+ "critical_low_threshold": 0.0,
141
+ "ds_order": 1,
142
+ "data": [
143
+ null,
144
+ null,
145
+ null,
146
+ null,
147
+ null,
148
+ null,
149
+ null,
150
+ null,
151
+ null,
152
+ null,
153
+ 0.055875838926,
154
+ 0.03161,
155
+ null
156
+ ],
157
+ "last_value": 0.03,
158
+ "minimum_value": null,
159
+ "maximum_value": null,
160
+ "average_value": 0.04
161
+ },
162
+ {
163
+ "metric_id": 9,
164
+ "metric": "Centreon-Server_4: rta",
165
+ "metric_legend": "Centreon-Server_4: rta",
166
+ "unit": "ms",
167
+ "min": 0.0,
168
+ "max": null,
169
+ "ds_data": {
170
+ "ds_color_line": "#29AFEE"
171
+ },
172
+ "legend": "Centreon-Server_4: Round-Trip Average Time",
173
+ "stack": 0,
174
+ "warning_high_threshold": 200.0,
175
+ "critical_high_threshold": 400.0,
176
+ "warning_low_threshold": 0.0,
177
+ "critical_low_threshold": 0.0,
178
+ "ds_order": 1,
179
+ "data": [
180
+ null,
181
+ null,
182
+ null,
183
+ null,
184
+ null,
185
+ null,
186
+ null,
187
+ null,
188
+ null,
189
+ null,
190
+ 0.02077852349,
191
+ 0.03634,
192
+ null
193
+ ],
194
+ "last_value": 0.04,
195
+ "minimum_value": null,
196
+ "maximum_value": null,
197
+ "average_value": 0.03
198
+ },
199
+ {
200
+ "metric_id": 5,
201
+ "metric": "Centreon-Server_5: rta",
202
+ "metric_legend": "Centreon-Server_5: rta",
203
+ "unit": "ms",
204
+ "min": 0.0,
205
+ "max": null,
206
+ "ds_data": {
207
+ "ds_color_line": "#29AFEE"
208
+ },
209
+ "legend": "Centreon-Server_5: Round-Trip Average Time",
210
+ "stack": 0,
211
+ "warning_high_threshold": 200.0,
212
+ "critical_high_threshold": 400.0,
213
+ "warning_low_threshold": 0.0,
214
+ "critical_low_threshold": 0.0,
215
+ "ds_order": 1,
216
+ "data": [
217
+ null,
218
+ null,
219
+ null,
220
+ null,
221
+ null,
222
+ null,
223
+ null,
224
+ null,
225
+ null,
226
+ null,
227
+ 0.042899328859,
228
+ 0.051873333333,
229
+ null
230
+ ],
231
+ "last_value": 0.05,
232
+ "minimum_value": null,
233
+ "maximum_value": null,
234
+ "average_value": 0.05
235
+ }
236
+ ],
237
+ "times": [
238
+ "2024-05-10T09:20:00+02:00",
239
+ "2024-05-10T09:25:00+02:00",
240
+ "2024-05-10T09:30:00+02:00",
241
+ "2024-05-10T09:35:00+02:00",
242
+ "2024-05-10T09:40:00+02:00",
243
+ "2024-05-10T09:45:00+02:00",
244
+ "2024-05-10T09:50:00+02:00",
245
+ "2024-05-10T09:55:00+02:00",
246
+ "2024-05-10T10:00:00+02:00",
247
+ "2024-05-10T10:05:00+02:00",
248
+ "2024-05-10T10:10:00+02:00",
249
+ "2024-05-10T10:15:00+02:00",
250
+ "2024-05-10T10:20:00+02:00"
251
+ ]
252
+ }
@@ -1,8 +1,20 @@
1
- import { useEffect, useState } from 'react';
1
+ import { useCallback, useMemo, useRef } from 'react';
2
2
 
3
- import { compose, prop, sortBy, toLower } from 'ramda';
3
+ import {
4
+ compose,
5
+ flatten,
6
+ groupBy,
7
+ isNil,
8
+ lensPath,
9
+ pipe,
10
+ prop,
11
+ set,
12
+ sortBy,
13
+ toLower
14
+ } from 'ramda';
4
15
 
5
16
  import { LineChartData } from '../common/models';
17
+ import { emphasizeCurveColor } from '../common/utils';
6
18
 
7
19
  import { adjustGraphData } from './helpers';
8
20
  import { Data } from './models';
@@ -18,32 +30,70 @@ interface Props {
18
30
  }
19
31
 
20
32
  const useGraphData = ({ data, end, start }: Props): GraphDataResult => {
21
- const [adjustedData, setAdjustedData] = useState<Data>();
33
+ const adjustedDataRef = useRef<Data>();
22
34
 
23
- const prepareData = (dataToAdjust: LineChartData): void => {
24
- const { timeSeries } = adjustGraphData(dataToAdjust);
25
- const baseAxis = dataToAdjust.global.base;
26
- const { title } = dataToAdjust.global;
35
+ const getBoolean = (value): boolean => Boolean(Number(value));
27
36
 
28
- const newLineData = adjustGraphData(dataToAdjust).lines;
37
+ const dataWithAdjustedMetricsColor = useMemo(() => {
38
+ if (isNil(data)) {
39
+ return data;
40
+ }
41
+ const metricsGroupedByColor = groupBy(
42
+ (metric) => metric.ds_data.ds_color_line
43
+ )(data?.metrics || []);
44
+
45
+ const newMetrics = Object.entries(metricsGroupedByColor).map(
46
+ ([color, value]) => {
47
+ const adjustedValue = value?.map((item) => ({
48
+ ...item,
49
+ ds_data: {
50
+ ...item?.ds_data,
51
+ ds_filled: getBoolean(item?.ds_data?.ds_filled),
52
+ ds_invert: getBoolean(item?.ds_data?.ds_invert)
53
+ }
54
+ }));
55
+
56
+ return adjustedValue?.map((metric, index) =>
57
+ set(
58
+ lensPath(['ds_data', 'ds_color_line']),
59
+ emphasizeCurveColor({ color, index }),
60
+ metric
61
+ )
62
+ );
63
+ }
64
+ );
65
+
66
+ const sortedMetrics = pipe(flatten, sortBy(prop('metric')))(newMetrics);
67
+
68
+ return {
69
+ ...data,
70
+ metrics: sortedMetrics
71
+ };
72
+ }, [data]);
73
+
74
+ const prepareData = useCallback((): void => {
75
+ if (isNil(dataWithAdjustedMetricsColor)) {
76
+ return;
77
+ }
78
+
79
+ const { timeSeries } = adjustGraphData(dataWithAdjustedMetricsColor);
80
+ const baseAxis = dataWithAdjustedMetricsColor.global.base;
81
+ const { title } = dataWithAdjustedMetricsColor.global;
82
+
83
+ const newLineData = adjustGraphData(dataWithAdjustedMetricsColor).lines;
29
84
  const sortedLines = sortBy(compose(toLower, prop('name')), newLineData);
30
85
 
31
- setAdjustedData({
86
+ adjustedDataRef.current = {
32
87
  baseAxis,
33
88
  lines: sortedLines,
34
89
  timeSeries,
35
90
  title
36
- });
37
- };
91
+ };
92
+ }, [dataWithAdjustedMetricsColor, end, start]);
38
93
 
39
- useEffect(() => {
40
- if (!data) {
41
- return;
42
- }
43
- prepareData(data);
44
- }, [end, start, data]);
94
+ prepareData();
45
95
 
46
- return { adjustedData };
96
+ return { adjustedData: adjustedDataRef.current };
47
97
  };
48
98
 
49
99
  export default useGraphData;
@@ -53,7 +53,8 @@ const ResponsivePie = ({
53
53
  onArcClick,
54
54
  displayValues,
55
55
  TooltipContent,
56
- legendDirection = 'column'
56
+ legendDirection = 'column',
57
+ tooltipProps = {}
57
58
  }: PieProps & { height: number; width: number }): JSX.Element => {
58
59
  const { t } = useTranslation();
59
60
  const theme = useTheme();
@@ -157,6 +158,7 @@ const ResponsivePie = ({
157
158
  title={title}
158
159
  total={total}
159
160
  value={arc.data.value}
161
+ {...tooltipProps}
160
162
  />
161
163
  )
162
164
  }
@@ -14,6 +14,7 @@ export interface PieProps {
14
14
  legendDirection?: 'row' | 'column';
15
15
  onArcClick?: (ardata) => void;
16
16
  title?: string;
17
+ tooltipProps?: object;
17
18
  unit?: 'percentage' | 'number';
18
19
  variant?: 'pie' | 'donut';
19
20
  }
@@ -65,7 +65,6 @@ const DescendantNodes = <TData extends BaseProp>({
65
65
  <Group key={key} left={left} top={top}>
66
66
  <foreignObject
67
67
  height={nodeSize.height}
68
- style={{ userSelect: 'none' }}
69
68
  width={nodeSize.width}
70
69
  x={-nodeSize.width / 2}
71
70
  y={-nodeSize.height / 2}
@@ -1,10 +1,5 @@
1
- import {
2
- LinkHorizontal,
3
- LinkHorizontalStep,
4
- LinkHorizontalLine
5
- } from '@visx/shape';
1
+ import { LinkHorizontal } from '@visx/shape';
6
2
  import { HierarchyPointLink } from '@visx/hierarchy/lib/types';
7
- import { always, cond, equals, T } from 'ramda';
8
3
 
9
4
  import { useTheme } from '@mui/material';
10
5
 
@@ -14,12 +9,6 @@ interface Props<TData> extends Pick<TreeProps<TData>, 'treeLink'> {
14
9
  links: Array<HierarchyPointLink<Node<TData>>>;
15
10
  }
16
11
 
17
- const getLinkComponent = cond([
18
- [equals('line'), always(LinkHorizontalLine)],
19
- [equals('step'), always(LinkHorizontalStep)],
20
- [T, always(LinkHorizontal)]
21
- ]);
22
-
23
12
  const Links = <TData extends BaseProp>({
24
13
  links,
25
14
  treeLink
@@ -35,12 +24,10 @@ const Links = <TData extends BaseProp>({
35
24
  .descendants()
36
25
  .map((ancestor) => ancestor.data.data.id);
37
26
 
38
- const LinkComponent = getLinkComponent(treeLink?.type);
39
-
40
27
  const key = `${link.source.data.data.id}-${link.source.data.data.name}-${ancestorIds}_${link.target.data.data.id}-${link.target.data.data.name}-${descendantIds}`;
41
28
 
42
29
  return (
43
- <LinkComponent
30
+ <LinkHorizontal
44
31
  data={link}
45
32
  data-testid={`${link.source.data.data.id}_to_${link.target.data.data.id}`}
46
33
  fill="none"
@@ -168,28 +168,4 @@ describe('Complex data tree', () => {
168
168
 
169
169
  cy.makeSnapshot();
170
170
  });
171
-
172
- it('displays the tree with step links when a prop is set', () => {
173
- initializeStandaloneTree({
174
- treeLink: {
175
- type: 'step'
176
- }
177
- });
178
-
179
- cy.contains('T').should('be.visible');
180
-
181
- cy.makeSnapshot();
182
- });
183
-
184
- it('displays the tree with line links when a prop is set', () => {
185
- initializeStandaloneTree({
186
- treeLink: {
187
- type: 'line'
188
- }
189
- });
190
-
191
- cy.contains('T').should('be.visible');
192
-
193
- cy.makeSnapshot();
194
- });
195
171
  });
@@ -82,21 +82,6 @@ export const WithDefaultExpandFilter: Story = {
82
82
  render: StandaloneTreeTemplate
83
83
  };
84
84
 
85
- export const WithStepLink: Story = {
86
- args: {
87
- children: SimpleContent,
88
- node: {
89
- height: 90,
90
- width: 90
91
- },
92
- tree: simpleData,
93
- treeLink: {
94
- type: 'step'
95
- }
96
- },
97
- render: StandaloneTreeTemplate
98
- };
99
-
100
85
  export const WithCustomLinks: Story = {
101
86
  args: {
102
87
  children: SimpleContent,
@@ -110,8 +95,7 @@ export const WithCustomLinks: Story = {
110
95
  getStrokeDasharray: ({ target }) =>
111
96
  target.status === 'ok' ? '5,5' : '0',
112
97
  getStrokeOpacity: ({ target }) => (target.status === 'ok' ? 0.8 : 1),
113
- getStrokeWidth: ({ target }) => (target.status === 'ok' ? 1 : 2),
114
- type: 'line'
98
+ getStrokeWidth: ({ target }) => (target.status === 'ok' ? 1 : 2)
115
99
  }
116
100
  },
117
101
  render: StandaloneTreeTemplate
@@ -14,8 +14,6 @@ export interface BaseProp {
14
14
  name: string;
15
15
  }
16
16
 
17
- export type Link = 'curve' | 'line' | 'step';
18
-
19
17
  export interface ChildrenProps<TData> {
20
18
  ancestors: Array<Node<TData>>;
21
19
  depth: number;
@@ -50,6 +48,5 @@ export interface TreeProps<TData> {
50
48
  ) => string | number | undefined;
51
49
  getStrokeOpacity?: (props: LinkProps<TData>) => string | number | undefined;
52
50
  getStrokeWidth?: (props: LinkProps<TData>) => string | number | undefined;
53
- type?: Link;
54
51
  };
55
52
  }
@@ -1,3 +1,4 @@
1
+ import numeral from 'numeral';
1
2
  import {
2
3
  T,
3
4
  always,
@@ -6,14 +7,14 @@ import {
6
7
  gt,
7
8
  gte,
8
9
  head,
10
+ last,
9
11
  length,
10
12
  lt,
11
13
  lte,
12
14
  pluck
13
15
  } from 'ramda';
14
- import numeral from 'numeral';
15
16
 
16
- import { Theme } from '@mui/material';
17
+ import { Theme, darken, getLuminance, lighten } from '@mui/material';
17
18
 
18
19
  import { Thresholds } from './models';
19
20
 
@@ -92,3 +93,51 @@ export const getValueByUnit = ({
92
93
 
93
94
  return `${((value * 100) / total).toFixed(1)}%`;
94
95
  };
96
+
97
+ interface NormalizeLevelProps {
98
+ factor: number;
99
+ level: number;
100
+ }
101
+
102
+ const normalizeLevel = ({ level, factor }: NormalizeLevelProps): number =>
103
+ (level * factor) / 10;
104
+
105
+ interface EmphasizeCurveColorProps {
106
+ color: string;
107
+ index: number;
108
+ }
109
+
110
+ export const emphasizeCurveColor = ({
111
+ color,
112
+ index
113
+ }: EmphasizeCurveColorProps): string => {
114
+ const totalLevels = 5;
115
+ const levels = [...Array(totalLevels).keys()];
116
+ const factor = 10 / totalLevels;
117
+
118
+ if (gte(getLuminance(color), 0.5)) {
119
+ if (gte(index, totalLevels * 2)) {
120
+ return darken(color, normalizeLevel({ factor, level: last(levels) }));
121
+ }
122
+ if (gte(index, totalLevels)) {
123
+ return darken(
124
+ color,
125
+ normalizeLevel({ factor, level: levels[totalLevels + 1 - index] })
126
+ );
127
+ }
128
+
129
+ return lighten(color, normalizeLevel({ factor, level: levels[index] }));
130
+ }
131
+
132
+ if (gte(index, totalLevels * 2)) {
133
+ return lighten(color, normalizeLevel({ factor, level: last(levels) }));
134
+ }
135
+ if (gte(index, totalLevels)) {
136
+ return lighten(
137
+ color,
138
+ normalizeLevel({ factor, level: levels[totalLevels + 1 - index] })
139
+ );
140
+ }
141
+
142
+ return darken(color, normalizeLevel({ factor, level: levels[index] }));
143
+ };
@@ -0,0 +1,32 @@
1
+ import { has } from 'ramda';
2
+
3
+ import { SvgIcon, SvgIconProps, SvgIconTypeMap } from '@mui/material';
4
+ import { OverridableComponent } from '@mui/material/OverridableComponent';
5
+
6
+ interface Props extends SvgIconProps {
7
+ Icon: JSX.Element | OverridableComponent<SvgIconTypeMap>;
8
+ dataTestId?: string;
9
+ }
10
+
11
+ const BaseIcon = ({ Icon, dataTestId, ...props }: Props): JSX.Element => {
12
+ if (!has('key', Icon)) {
13
+ const Component = Icon as (props: SvgIconProps) => JSX.Element;
14
+
15
+ return (
16
+ <SvgIcon
17
+ data-testid={dataTestId || (Icon as () => JSX.Element).name}
18
+ {...props}
19
+ >
20
+ <Component />
21
+ </SvgIcon>
22
+ );
23
+ }
24
+
25
+ return (
26
+ <SvgIcon data-testid={dataTestId} {...props}>
27
+ {Icon as JSX.Element}
28
+ </SvgIcon>
29
+ );
30
+ };
31
+
32
+ export default BaseIcon;
@@ -0,0 +1,14 @@
1
+ import { SvgIconProps } from '@mui/material';
2
+
3
+ import BaseIcon from './BaseIcon';
4
+
5
+ const icon = (
6
+ <g>
7
+ <path d="M7.6215 5.243C7.9422 5.243 8.2557 5.1479 8.52236 4.96972C8.78901 4.79155 8.99685 4.53831 9.11958 4.24202C9.2423 3.94573 9.27441 3.6197 9.21185 3.30516C9.14928 2.99062 8.99485 2.70169 8.76808 2.47492C8.54131 2.24815 8.25238 2.09372 7.93784 2.03116C7.6233 1.96859 7.29727 2.0007 7.00098 2.12343C6.70469 2.24616 6.45145 2.45399 6.27327 2.72065C6.0951 2.9873 6 3.30079 6 3.6215C6 4.05155 6.17084 4.46398 6.47493 4.76807C6.77902 5.07216 7.19145 5.243 7.6215 5.243Z" />
8
+ <path d="M17.8192 12.3739C17.743 12.1905 17.6143 12.0338 17.4492 11.9235C17.2841 11.8132 17.0901 11.7541 16.8915 11.7538C16.8915 11.7538 14.9107 11.4903 14.3232 11.8736C14.0659 12.083 13.8556 12.3442 13.706 12.6403L10.396 12.1161C10.142 11.2785 9.05429 8.10738 9.05429 8.10738L8.24354 6.81076C8.09994 6.57117 7.89855 6.37142 7.6578 6.22979C7.41705 6.08815 7.14463 6.00914 6.86545 6C6.64749 6.01064 6.43062 6.03754 6.21666 6.0805L2 7.86971V11.68H2.23096L4.36037 12.0174L2.81746 19.7866H4.52041L5.979 13.3006L7.68196 14.9221V19.7866H9.30345V13.706L8.16304 12.6183L13.3649 13.4415L10.4094 19.9725L20.928 19.8671L17.8192 12.3739ZM8.03845 9.87167C8.03845 9.87167 8.59142 11.1712 8.88179 11.8736L7.67525 11.682L8.03845 9.87167ZM3.62437 11.0408V8.921L5.08295 8.35368L4.52137 11.1827L3.62437 11.0408Z" />
9
+ </g>
10
+ );
11
+
12
+ export const DowntimeIcon = (props: SvgIconProps): JSX.Element => (
13
+ <BaseIcon {...props} Icon={icon} height="24" viewBox="0 0 24 24" width="24" />
14
+ );
@@ -13,11 +13,12 @@ import { baseEndpoint, getEndpoint, label, optionsData } from './utils';
13
13
 
14
14
  import MultiConnectedAutocompleteField from '.';
15
15
 
16
- const renderMultiAutocompleteField = (): RenderResult =>
16
+ const renderMultiAutocompleteField = (customRenderTags?): RenderResult =>
17
17
  render(
18
18
  <TestQueryProvider>
19
19
  <MultiConnectedAutocompleteField
20
20
  baseEndpoint=""
21
+ customRenderTags={customRenderTags}
21
22
  field="host.name"
22
23
  getEndpoint={getEndpoint}
23
24
  label={label}
@@ -42,4 +43,23 @@ describe(MultiConnectedAutocompleteField, () => {
42
43
  expect(getFetchCall(0)).toEqual(`${baseEndpoint}?page=1`);
43
44
  });
44
45
  });
46
+
47
+ it('display tags when customTagsRender is defined', async () => {
48
+ const customRender = (tags: React.ReactNode): React.ReactNode => (
49
+ <div data-testid="custom-tags-wrapper">{tags}</div>
50
+ );
51
+
52
+ const { getByLabelText, getByTestId } =
53
+ renderMultiAutocompleteField(customRender);
54
+
55
+ fireEvent.click(getByLabelText('Open'));
56
+
57
+ await waitFor(() => {
58
+ const tagChip = getByTestId(
59
+ `tag-option-chip-${optionsData.result[0].id}`
60
+ );
61
+ expect(tagChip).toBeVisible();
62
+ expect(tagChip).toHaveTextContent(optionsData.result[0].name);
63
+ });
64
+ });
45
65
  });
@@ -95,8 +95,8 @@ describe(SingleConnectedAutocompleteField, () => {
95
95
  });
96
96
 
97
97
  await waitFor(() => {
98
- expect(getFetchCall(2)).toEqual(
99
- `${baseEndpoint}?page=1&search=%7B%22%24and%22%3A%5B%7B%22%24or%22%3A%5B%7B%22host.name%22%3A%7B%22%24lk%22%3A%22%25My%20Option%202%25%22%7D%7D%5D%7D%5D%7D`
98
+ expect(decodeURIComponent(getFetchCall(2))).toEqual(
99
+ 'endpoint?page=1&search={"$and":[{"$and":[{"host.name":{"$lk":"%My Option 2%"}}]}]}'
100
100
  );
101
101
  });
102
102
  });