@centreon/ui 24.10.12 → 24.10.13

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 (153) hide show
  1. package/package.json +3 -2
  2. package/public/mockServiceWorker.js +1 -1
  3. package/src/Button/Icon/index.tsx +3 -1
  4. package/src/Dashboard/Dashboard.styles.ts +3 -4
  5. package/src/Dashboard/DashboardLayout.stories.tsx +1 -1
  6. package/src/Dashboard/Grid.tsx +11 -17
  7. package/src/Dashboard/Layout.tsx +27 -56
  8. package/src/Dialog/UnsavedChanges/index.tsx +15 -13
  9. package/src/Dialog/UnsavedChanges/translatedLabels.ts +15 -13
  10. package/src/Form/Form.tsx +0 -1
  11. package/src/Form/Inputs/Autocomplete.tsx +1 -1
  12. package/src/Form/Inputs/ConnectedAutocomplete.tsx +5 -2
  13. package/src/Form/Inputs/Grid.tsx +7 -1
  14. package/src/Form/Inputs/Radio.tsx +1 -1
  15. package/src/Form/Inputs/Switch.tsx +1 -1
  16. package/src/Form/Inputs/Text.tsx +1 -1
  17. package/src/Form/Inputs/index.tsx +25 -24
  18. package/src/Form/Inputs/models.ts +2 -0
  19. package/src/Graph/BarChart/BarChart.cypress.spec.tsx +3 -3
  20. package/src/Graph/BarChart/BarChart.tsx +24 -31
  21. package/src/Graph/BarChart/BarGroup.tsx +32 -59
  22. package/src/Graph/BarChart/BarStack.tsx +64 -13
  23. package/src/Graph/BarChart/MemoizedGroup.tsx +123 -0
  24. package/src/Graph/BarChart/ResponsiveBarChart.tsx +21 -7
  25. package/src/Graph/BarStack/BarStack.cypress.spec.tsx +87 -9
  26. package/src/Graph/BarStack/BarStack.stories.tsx +13 -4
  27. package/src/Graph/BarStack/BarStack.styles.ts +57 -33
  28. package/src/Graph/BarStack/Graph.tsx +173 -0
  29. package/src/Graph/BarStack/GraphAndLegend.tsx +117 -0
  30. package/src/Graph/BarStack/ResponsiveBarStack.tsx +61 -168
  31. package/src/Graph/BarStack/constants.ts +5 -0
  32. package/src/Graph/BarStack/models.ts +0 -1
  33. package/src/Graph/BarStack/useGraphAndLegend.ts +84 -0
  34. package/src/Graph/BarStack/useResponsiveBarStack.ts +73 -97
  35. package/src/Graph/Chart/Chart.cypress.spec.tsx +14 -26
  36. package/src/Graph/Chart/Chart.stories.tsx +1 -1
  37. package/src/Graph/Chart/Chart.tsx +53 -37
  38. package/src/Graph/Chart/InteractiveComponents/AnchorPoint/GuidingLines.tsx +3 -3
  39. package/src/Graph/Chart/InteractiveComponents/AnchorPoint/useTickGraph.ts +19 -6
  40. package/src/Graph/Chart/Legend/Legend.styles.ts +25 -11
  41. package/src/Graph/Chart/Legend/index.tsx +6 -24
  42. package/src/Graph/Chart/index.tsx +34 -43
  43. package/src/Graph/Chart/models.ts +0 -1
  44. package/src/Graph/Chart/useChartData.ts +19 -1
  45. package/src/Graph/HeatMap/ResponsiveHeatMap.tsx +20 -2
  46. package/src/Graph/HeatMap/model.ts +6 -2
  47. package/src/Graph/Legend/Legend.styles.ts +10 -0
  48. package/src/Graph/Legend/Legend.tsx +6 -1
  49. package/src/Graph/SingleBar/ResponsiveSingleBar.tsx +9 -10
  50. package/src/Graph/SingleBar/ThresholdLine.tsx +6 -6
  51. package/src/Graph/Text/Text.styles.ts +2 -2
  52. package/src/Graph/Text/Text.tsx +23 -10
  53. package/src/Graph/Timeline/ResponsiveTimeline.tsx +152 -0
  54. package/src/Graph/Timeline/Timeline.cypress.spec.tsx +148 -0
  55. package/src/Graph/Timeline/Timeline.stories.tsx +91 -0
  56. package/src/Graph/Timeline/Timeline.tsx +28 -0
  57. package/src/Graph/Timeline/index.ts +1 -0
  58. package/src/Graph/Timeline/models.ts +20 -0
  59. package/src/Graph/Timeline/timeline.styles.ts +11 -0
  60. package/src/Graph/Timeline/translatedLabel.ts +6 -0
  61. package/src/Graph/Timeline/useTimeline.ts +90 -0
  62. package/src/Graph/Tree/Links.tsx +2 -2
  63. package/src/Graph/Tree/Tree.tsx +2 -2
  64. package/src/Graph/Tree/constants.ts +1 -1
  65. package/src/Graph/common/Axes/index.tsx +1 -1
  66. package/src/Graph/common/Axes/useAxisY.ts +8 -4
  67. package/src/Graph/common/BaseChart/BaseChart.tsx +3 -12
  68. package/src/Graph/common/BaseChart/ChartSvgWrapper.tsx +12 -4
  69. package/src/Graph/common/BaseChart/Header/index.tsx +3 -1
  70. package/src/Graph/common/BaseChart/useComputeBaseChartDimensions.ts +23 -11
  71. package/src/Graph/common/BaseChart/useComputeYAxisMaxCharacters.ts +92 -0
  72. package/src/Graph/common/models.ts +7 -8
  73. package/src/Graph/common/timeSeries/index.test.ts +1 -1
  74. package/src/Graph/common/timeSeries/index.ts +56 -29
  75. package/src/Graph/common/timeSeries/models.ts +2 -0
  76. package/src/Graph/common/utils.ts +51 -3
  77. package/src/Graph/index.ts +4 -1
  78. package/src/Graph/mockedData/lastDayWithNullValues.json +6 -6
  79. package/src/Graph/mockedData/pingServiceLinesBars.json +47 -47
  80. package/src/Icon/DowntimeIcon.tsx +8 -1
  81. package/src/Icon/FlappingIcon.tsx +22 -0
  82. package/src/Icon/index.ts +1 -0
  83. package/src/InputField/Select/Autocomplete/Connected/Multi/index.test.tsx +21 -1
  84. package/src/InputField/Select/Autocomplete/Connected/index.test.tsx +2 -2
  85. package/src/InputField/Select/Autocomplete/Connected/index.tsx +52 -15
  86. package/src/InputField/Select/Autocomplete/Multi/index.stories.tsx +19 -0
  87. package/src/InputField/Select/Autocomplete/Multi/index.tsx +8 -5
  88. package/src/InputField/Select/Autocomplete/index.tsx +79 -54
  89. package/src/InputField/Text/index.tsx +6 -4
  90. package/src/InputField/translatedLabels.ts +2 -0
  91. package/src/Listing/ActionBar/index.tsx +1 -1
  92. package/src/Listing/Listing.styles.ts +3 -3
  93. package/src/Listing/index.tsx +40 -37
  94. package/src/Listing/models.ts +0 -8
  95. package/src/Listing/useStyleTable.ts +58 -32
  96. package/src/MultiSelectEntries/index.tsx +2 -0
  97. package/src/PopoverMenu/index.tsx +2 -9
  98. package/src/SortableItems/index.tsx +0 -1
  99. package/src/ThemeProvider/index.tsx +1 -1
  100. package/src/ThemeProvider/palettes.ts +6 -0
  101. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/PickersStartEndDate.tsx +2 -3
  102. package/src/TimePeriods/DateTimePickerInput.tsx +3 -1
  103. package/src/api/buildListingEndpoint/getSearchQueryParameterValue.ts +7 -1
  104. package/src/api/buildListingEndpoint/models.ts +1 -0
  105. package/src/api/customFetch.ts +4 -1
  106. package/src/api/models.ts +9 -0
  107. package/src/api/useGraphQuery/index.ts +117 -20
  108. package/src/api/useGraphQuery/models.ts +1 -0
  109. package/src/api/useMutationQuery/index.ts +1 -1
  110. package/src/components/DataTable/DataTable.styles.ts +1 -1
  111. package/src/components/DataTable/EmptyState/DataTableEmptyState.styles.ts +2 -1
  112. package/src/components/DataTable/EmptyState/DataTableEmptyState.tsx +4 -1
  113. package/src/components/DataTable/Item/DataTableItem.styles.ts +28 -2
  114. package/src/components/DataTable/Item/DataTableItem.tsx +19 -4
  115. package/src/components/Form/FormActions.tsx +21 -12
  116. package/src/components/Layout/AreaIndicator.tsx +1 -1
  117. package/src/components/Layout/PageLayout/PageLayout.styles.ts +2 -7
  118. package/src/components/Layout/PageLayout/PageLayoutBody.tsx +0 -1
  119. package/src/components/Zoom/Zoom.tsx +9 -2
  120. package/src/components/Zoom/ZoomContent.tsx +143 -136
  121. package/src/components/Zoom/models.ts +18 -15
  122. package/src/components/Zoom/useMinimap.ts +5 -8
  123. package/src/components/Zoom/useZoom.ts +3 -3
  124. package/src/index.ts +2 -0
  125. package/src/utils/index.ts +1 -0
  126. package/src/utils/useLocale/index.ts +9 -0
  127. package/src/utils/useLocale/useLocale.cypress.spec.tsx +38 -0
  128. package/src/utils/useLocaleDateTimeFormat/index.ts +4 -2
  129. package/src/utils/usePluralizedTranslation.ts +2 -3
  130. package/src/Graph/common/timeSeries/index.test.ts-E +0 -622
  131. package/src/components/CrudPage/Actions/Actions.styles.ts +0 -16
  132. package/src/components/CrudPage/Actions/Actions.tsx +0 -24
  133. package/src/components/CrudPage/Actions/AddButton.tsx +0 -23
  134. package/src/components/CrudPage/Actions/Filters.tsx +0 -25
  135. package/src/components/CrudPage/Actions/Search.tsx +0 -31
  136. package/src/components/CrudPage/Actions/useSearch.tsx +0 -24
  137. package/src/components/CrudPage/Columns/Actions.tsx +0 -88
  138. package/src/components/CrudPage/CrudPage.cypress.spec.tsx +0 -559
  139. package/src/components/CrudPage/CrudPage.stories.tsx +0 -278
  140. package/src/components/CrudPage/CrudPageRoot.tsx +0 -142
  141. package/src/components/CrudPage/DeleteModal.tsx +0 -77
  142. package/src/components/CrudPage/Form/AddModal.tsx +0 -35
  143. package/src/components/CrudPage/Form/Buttons.tsx +0 -98
  144. package/src/components/CrudPage/Form/UpdateModal.tsx +0 -60
  145. package/src/components/CrudPage/Listing.tsx +0 -63
  146. package/src/components/CrudPage/atoms.ts +0 -30
  147. package/src/components/CrudPage/hooks/useDeleteItem.ts +0 -53
  148. package/src/components/CrudPage/hooks/useGetItem.ts +0 -36
  149. package/src/components/CrudPage/hooks/useGetItems.ts +0 -67
  150. package/src/components/CrudPage/hooks/useListingQueryKey.ts +0 -31
  151. package/src/components/CrudPage/index.tsx +0 -7
  152. package/src/components/CrudPage/models.ts +0 -118
  153. package/src/components/CrudPage/utils.ts +0 -4
@@ -129,13 +129,13 @@ const initializeCustomUnits = ({
129
129
  };
130
130
 
131
131
  const checkGraphWidth = (): void => {
132
- cy.findByTestId('graph-interaction-zone')
133
- .should('have.attr', 'width')
134
- .and('equal', '1170');
135
-
136
132
  cy.findByTestId('graph-interaction-zone')
137
133
  .should('have.attr', 'height')
138
134
  .and('equal', '393');
135
+
136
+ cy.findByTestId('graph-interaction-zone').then((graph) => {
137
+ expect(Number(graph[0].attributes.width.value)).to.be.greaterThan(1170);
138
+ });
139
139
  };
140
140
 
141
141
  describe('Line chart', () => {
@@ -158,8 +158,7 @@ describe('Line chart', () => {
158
158
  cy.contains('06/18/2023').should('be.visible');
159
159
 
160
160
  cy.contains('0.45 s').should('be.visible');
161
- cy.contains('75.93%').should('be.visible');
162
- cy.contains('0.43 s').should('be.visible');
161
+ cy.contains('73.65%').should('be.visible');
163
162
 
164
163
  cy.makeSnapshot();
165
164
  });
@@ -176,12 +175,12 @@ describe('Line chart', () => {
176
175
  cy.get('[data-metric="querytime"]').should(
177
176
  'have.attr',
178
177
  'data-highlight',
179
- 'false'
178
+ 'true'
180
179
  );
181
180
  cy.get('[data-metric="connTime"]').should(
182
181
  'have.attr',
183
182
  'data-highlight',
184
- 'true'
183
+ 'false'
185
184
  );
186
185
 
187
186
  cy.makeSnapshot();
@@ -194,7 +193,7 @@ describe('Line chart', () => {
194
193
 
195
194
  cy.contains('Min: 70.31').should('be.visible');
196
195
 
197
- cy.findByTestId('graph-interaction-zone').realMouseMove(1185, 100);
196
+ cy.findByTestId('graph-interaction-zone').realMouseMove(1198, 100);
198
197
 
199
198
  cy.get('[data-metric="querytime"]').should('not.exist');
200
199
 
@@ -208,10 +207,10 @@ describe('Line chart', () => {
208
207
 
209
208
  cy.contains('Min: 70.31').should('be.visible');
210
209
 
211
- cy.findByTestId('graph-interaction-zone').realMouseMove(1152, 100);
210
+ cy.findByTestId('graph-interaction-zone').realMouseMove(1170, 100);
212
211
 
213
212
  cy.get('[data-metric="querytime"]').should('be.visible');
214
- cy.get('[data-metric="hitratio"]').should('not.exist');
213
+ cy.get('[data-metric="hitratio"]').should('be.visible');
215
214
 
216
215
  cy.makeSnapshot();
217
216
  });
@@ -225,7 +224,7 @@ describe('Line chart', () => {
225
224
 
226
225
  cy.findByTestId('graph-interaction-zone').realMouseMove(452, 26);
227
226
 
228
- cy.get('[data-metric="connTime"]').should(
227
+ cy.get('[data-metric="querytime"]').should(
229
228
  'have.attr',
230
229
  'data-highlight',
231
230
  'true'
@@ -286,7 +285,7 @@ describe('Line chart', () => {
286
285
 
287
286
  cy.findByTestId('graph-interaction-zone')
288
287
  .should('have.attr', 'width')
289
- .and('equal', '1212');
288
+ .and('equal', '1200');
290
289
 
291
290
  cy.findByLabelText('Centreon-Server: Round-Trip Average Time')
292
291
  .find('[data-icon="true"]')
@@ -362,8 +361,6 @@ describe('Line chart', () => {
362
361
  cy.get('[data-as-list="true"]').should('exist');
363
362
 
364
363
  cy.contains(':00 AM').should('be.visible');
365
-
366
- cy.makeSnapshot();
367
364
  });
368
365
 
369
366
  it('displays the legend on the right side of the graph as list when the corresponding props are set', () => {
@@ -373,8 +370,6 @@ describe('Line chart', () => {
373
370
  cy.get('[data-as-list="true"]').should('exist');
374
371
 
375
372
  cy.contains(':00 AM').should('be.visible');
376
-
377
- cy.makeSnapshot();
378
373
  });
379
374
  });
380
375
 
@@ -448,7 +443,7 @@ describe('Line chart', () => {
448
443
 
449
444
  cy.contains(':00 AM').should('be.visible');
450
445
 
451
- cy.get('text[transform="rotate(-35, -2, 312.508173777963)"]').should(
446
+ cy.get('text[transform="rotate(-35, -2, 227.55748987831032)"]').should(
452
447
  'be.visible'
453
448
  );
454
449
 
@@ -479,8 +474,6 @@ describe('Line chart', () => {
479
474
  cy.get('[data-metric="13536"]').should('be.visible');
480
475
  cy.get('[data-metric="13534"]').should('be.visible');
481
476
  cy.get('[data-metric="13535"]').should('be.visible');
482
-
483
- cy.makeSnapshot();
484
477
  });
485
478
 
486
479
  it('displays the curve in a step style when the prop is set', () => {
@@ -493,8 +486,6 @@ describe('Line chart', () => {
493
486
  cy.get('[data-metric="13534"]').should('be.visible');
494
487
  cy.get('[data-metric="13535"]').should('be.visible');
495
488
  checkLegendInformation();
496
-
497
- cy.makeSnapshot();
498
489
  });
499
490
 
500
491
  it('shows the area when the prop is set', () => {
@@ -530,8 +521,7 @@ describe('Line chart', () => {
530
521
 
531
522
  checkGraphWidth();
532
523
  cy.contains(':00 AM').should('be.visible');
533
- cy.get('circle[cx="4.0625"]').should('be.visible');
534
- cy.get('circle[cy="105.21757370835121"]').should('be.visible');
524
+ cy.get('circle[cx="37.625"]').should('be.visible');
535
525
 
536
526
  cy.makeSnapshot();
537
527
  });
@@ -583,7 +573,6 @@ describe('Lines and bars', () => {
583
573
  cy.get('path[data-metric="3"]').should('be.visible');
584
574
  cy.get('path[data-metric="3"]').should('be.visible');
585
575
  cy.findByTestId('stacked-bar-10-0-7650.368581547736').should('be.visible');
586
- cy.findByTestId('stacked-bar-2-0-10').should('be.visible');
587
576
 
588
577
  cy.makeSnapshot();
589
578
  });
@@ -634,7 +623,6 @@ describe('Lines and bars', () => {
634
623
  cy.get('path[data-metric="3"]').should('be.visible');
635
624
  cy.get('path[data-metric="3"]').should('be.visible');
636
625
  cy.findByTestId('stacked-bar-10-0-7650.368581547736').should('be.visible');
637
- cy.findByTestId('stacked-bar-2-0-10').should('be.visible');
638
626
 
639
627
  cy.makeSnapshot();
640
628
  });
@@ -669,7 +669,7 @@ export const linesAndBarsMixedCenteredZero: Story = {
669
669
  )
670
670
  };
671
671
  const CustomYUnits = (props): JSX.Element => {
672
- const [leftUnit, setLeftUnit] = useState('b');
672
+ const [leftUnit, setLeftUnit] = useState('B');
673
673
  const [rightUnit, setRightUnit] = useState('ms');
674
674
 
675
675
  return (
@@ -7,7 +7,7 @@ import {
7
7
  } from 'react';
8
8
 
9
9
  import { useAtom } from 'jotai';
10
- import { equals, flatten, isNil, pluck, reject } from 'ramda';
10
+ import { equals, flatten, isEmpty, isNil, pluck, reject } from 'ramda';
11
11
 
12
12
  import { ClickAwayListener, Skeleton } from '@mui/material';
13
13
 
@@ -16,6 +16,7 @@ import BarGroup from '../BarChart/BarGroup';
16
16
  import BaseChart from '../common/BaseChart/BaseChart';
17
17
  import ChartSvgWrapper from '../common/BaseChart/ChartSvgWrapper';
18
18
  import { useComputeBaseChartDimensions } from '../common/BaseChart/useComputeBaseChartDimensions';
19
+ import { useComputeYAxisMaxCharacters } from '../common/BaseChart/useComputeYAxisMaxCharacters';
19
20
  import Thresholds from '../common/Thresholds/Thresholds';
20
21
  import type { Thresholds as ThresholdsModel } from '../common/models';
21
22
  import {
@@ -25,7 +26,6 @@ import {
25
26
  getYScalePerUnit
26
27
  } from '../common/timeSeries';
27
28
  import type { Line } from '../common/timeSeries/models';
28
-
29
29
  import Lines from './BasicComponents/Lines';
30
30
  import {
31
31
  canDisplayThreshold,
@@ -97,8 +97,7 @@ const Chart = ({
97
97
  },
98
98
  thresholds,
99
99
  thresholdUnit,
100
- limitLegend,
101
- skipIntersectionObserver
100
+ limitLegend
102
101
  }: Props): JSX.Element => {
103
102
  const { classes } = useChartStyles();
104
103
 
@@ -128,13 +127,24 @@ const Chart = ({
128
127
  [displayedLines]
129
128
  );
130
129
 
130
+ const { maxLeftAxisCharacters, maxRightAxisCharacters } =
131
+ useComputeYAxisMaxCharacters({
132
+ graphData,
133
+ thresholds,
134
+ thresholdUnit,
135
+ axis,
136
+ firstUnit,
137
+ secondUnit
138
+ });
139
+
131
140
  const { legendRef, graphWidth, graphHeight } = useComputeBaseChartDimensions({
132
141
  hasSecondUnit: Boolean(secondUnit),
133
142
  height,
134
143
  legendDisplay: legend?.display,
135
144
  legendHeight: legend?.height,
136
145
  legendPlacement: legend?.placement,
137
- width
146
+ width,
147
+ maxAxisCharacters: maxRightAxisCharacters || maxLeftAxisCharacters
138
148
  });
139
149
 
140
150
  const xScale = useMemo(
@@ -220,7 +230,7 @@ const Chart = ({
220
230
  [axis?.showGridLines]
221
231
  );
222
232
 
223
- if (!isInViewport && !skipIntersectionObserver) {
233
+ if (!isInViewport) {
224
234
  return (
225
235
  <Skeleton
226
236
  height={graphSvgRef?.current?.clientHeight ?? graphHeight}
@@ -271,39 +281,45 @@ const Chart = ({
271
281
  svgRef={graphSvgRef}
272
282
  timeSeries={timeSeries}
273
283
  xScale={xScale}
284
+ maxAxisCharacters={maxLeftAxisCharacters}
285
+ hasSecondUnit={Boolean(secondUnit)}
274
286
  >
275
287
  <>
276
- <BarGroup
277
- barStyle={barStyle}
278
- isTooltipHidden={false}
279
- lines={linesDisplayedAsBar}
280
- orientation="horizontal"
281
- size={graphHeight - margin.top - 5}
282
- timeSeries={timeSeries}
283
- xScale={xScaleBand}
284
- yScalesPerUnit={yScalesPerUnit}
285
- />
286
- <Lines
287
- areaTransparency={lineStyle?.areaTransparency}
288
- curve={lineStyle?.curve || 'linear'}
289
- dashLength={lineStyle?.dashLength}
290
- dashOffset={lineStyle?.dashOffset}
291
- displayAnchor={displayAnchor}
292
- displayedLines={linesDisplayedAsLine}
293
- dotOffset={lineStyle?.dotOffset}
294
- graphSvgRef={graphSvgRef}
295
- height={graphHeight - margin.top}
296
- lineWidth={lineStyle?.lineWidth}
297
- scale={axis?.scale}
298
- scaleLogarithmicBase={axis?.scaleLogarithmicBase}
299
- showArea={lineStyle?.showArea}
300
- showPoints={lineStyle?.showPoints}
301
- timeSeries={timeSeries}
302
- width={graphWidth}
303
- xScale={xScale}
304
- yScalesPerUnit={yScalesPerUnit}
305
- {...shapeLines}
306
- />
288
+ {!isEmpty(linesDisplayedAsBar) && (
289
+ <BarGroup
290
+ barStyle={barStyle}
291
+ isTooltipHidden={false}
292
+ lines={linesDisplayedAsBar}
293
+ orientation="horizontal"
294
+ size={graphHeight - margin.top - 5}
295
+ timeSeries={timeSeries}
296
+ xScale={xScaleBand}
297
+ yScalesPerUnit={yScalesPerUnit}
298
+ />
299
+ )}
300
+ {!isEmpty(linesDisplayedAsLine) && (
301
+ <Lines
302
+ areaTransparency={lineStyle?.areaTransparency}
303
+ curve={lineStyle?.curve || 'linear'}
304
+ dashLength={lineStyle?.dashLength}
305
+ dashOffset={lineStyle?.dashOffset}
306
+ displayAnchor={displayAnchor}
307
+ displayedLines={linesDisplayedAsLine}
308
+ dotOffset={lineStyle?.dotOffset}
309
+ graphSvgRef={graphSvgRef}
310
+ height={graphHeight - margin.top}
311
+ lineWidth={lineStyle?.lineWidth}
312
+ scale={axis?.scale}
313
+ scaleLogarithmicBase={axis?.scaleLogarithmicBase}
314
+ showArea={lineStyle?.showArea}
315
+ showPoints={lineStyle?.showPoints}
316
+ timeSeries={timeSeries}
317
+ width={graphWidth}
318
+ xScale={xScale}
319
+ yScalesPerUnit={yScalesPerUnit}
320
+ {...shapeLines}
321
+ />
322
+ )}
307
323
  <InteractionWithGraph
308
324
  annotationData={{ ...annotationEvent }}
309
325
  commonData={{
@@ -11,7 +11,7 @@ const GuidingLines = ({
11
11
  graphHeight,
12
12
  graphWidth
13
13
  }: GuidingLinesModel): JSX.Element | null => {
14
- const { positionX, positionY } = useTickGraph({
14
+ const { positionX, positionY, guidingLinesRef } = useTickGraph({
15
15
  timeSeries,
16
16
  xScale
17
17
  });
@@ -20,7 +20,7 @@ const GuidingLines = ({
20
20
  }
21
21
 
22
22
  return (
23
- <>
23
+ <g ref={guidingLinesRef}>
24
24
  <Shape.Line
25
25
  fill="dotted"
26
26
  from={{ x: positionX, y: 0 }}
@@ -38,7 +38,7 @@ const GuidingLines = ({
38
38
  strokeWidth={1}
39
39
  to={{ x: graphWidth, y: positionY }}
40
40
  />
41
- </>
41
+ </g>
42
42
  );
43
43
  };
44
44
 
@@ -1,4 +1,4 @@
1
- import { useEffect, useState } from 'react';
1
+ import { MutableRefObject, useEffect, useMemo, useRef, useState } from 'react';
2
2
 
3
3
  import { ScaleLinear } from 'd3-scale';
4
4
  import { useAtomValue } from 'jotai';
@@ -15,6 +15,7 @@ interface AnchorPointResult {
15
15
  tickAxisBottom: Date | null;
16
16
  tickAxisLeft: string | null;
17
17
  tickAxisRight: string | null;
18
+ guidingLinesRef: MutableRefObject<SVGGElement | null>;
18
19
  }
19
20
 
20
21
  interface Props {
@@ -34,6 +35,7 @@ const useTickGraph = ({
34
35
  lines = [],
35
36
  baseAxis = 1000
36
37
  }: Props): AnchorPointResult => {
38
+ const guidingLinesRef = useRef<SVGGElement | null>(null);
37
39
  const [tickAxisBottom, setTickAxisBottom] = useState<Date | null>(null);
38
40
  const [tickAxisLeft, setTickAxisLeft] = useState<string | null>(null);
39
41
  const [tickAxisRight, setTickAxisRight] = useState<string | null>(null);
@@ -42,12 +44,22 @@ const useTickGraph = ({
42
44
 
43
45
  const mousePosition = useAtomValue(mousePositionAtom);
44
46
 
47
+ const paddingLeftString = useMemo(
48
+ () =>
49
+ (
50
+ guidingLinesRef.current?.parentElement?.parentElement?.attributes
51
+ ?.transform.value || ''
52
+ ).match(/translate\(([0-9\.]+), ([0-9\.]+)\)/)?.[1] || '0',
53
+ [
54
+ guidingLinesRef.current?.parentElement?.parentElement?.attributes
55
+ ?.transform.value
56
+ ]
57
+ );
58
+
45
59
  const positionX = mousePosition
46
- ? mousePosition[0] - margin.left - 4
47
- : undefined;
48
- const positionY = mousePosition
49
- ? mousePosition[1] - margin.top + 2
60
+ ? mousePosition[0] - Number(paddingLeftString) - 1
50
61
  : undefined;
62
+ const positionY = mousePosition ? mousePosition[1] - margin.top : undefined;
51
63
 
52
64
  useEffect(() => {
53
65
  if (!mousePosition) {
@@ -86,7 +98,8 @@ const useTickGraph = ({
86
98
  positionY,
87
99
  tickAxisBottom,
88
100
  tickAxisLeft,
89
- tickAxisRight
101
+ tickAxisRight,
102
+ guidingLinesRef
90
103
  };
91
104
  };
92
105
  export default useTickGraph;
@@ -1,17 +1,33 @@
1
1
  import { makeStyles } from 'tss-react/mui';
2
2
 
3
+ import { equals, lt } from 'ramda';
3
4
  import { margin } from '../common';
5
+ import type { LegendModel } from '../models';
4
6
 
5
7
  interface MakeStylesProps {
6
8
  limitLegendRows?: boolean;
9
+ placement: Pick<LegendModel, 'placement'>;
10
+ height?: number | null;
7
11
  }
8
12
 
9
13
  export const legendWidth = 21;
10
14
  const legendItemHeight = 5.25;
11
15
  const legendItemHeightCompact = 2;
12
16
 
17
+ const getLegendMaxHeight = ({ placement, height }) => {
18
+ if (!equals(placement, 'bottom')) {
19
+ return height || 0;
20
+ }
21
+
22
+ if (lt(height || 0, 220)) {
23
+ return 40;
24
+ }
25
+
26
+ return 90;
27
+ };
28
+
13
29
  export const useStyles = makeStyles<MakeStylesProps>()(
14
- (theme, { limitLegendRows }) => ({
30
+ (theme, { limitLegendRows, placement, height = 0 }) => ({
15
31
  highlight: {
16
32
  color: theme.typography.body1.color
17
33
  },
@@ -35,25 +51,23 @@ export const useStyles = makeStyles<MakeStylesProps>()(
35
51
  display: 'grid',
36
52
  gridAutoRows: theme.spacing(legendItemHeight),
37
53
  gridTemplateColumns: `repeat(auto-fit, minmax(${theme.spacing(legendWidth)}, 1fr))`,
38
- maxHeight: limitLegendRows
39
- ? theme.spacing(legendItemHeight * 2 + 1)
40
- : 'unset',
41
- overflowX: 'hidden',
42
- overflowY: 'auto',
43
54
  rowGap: theme.spacing(1),
44
55
  width: '100%'
45
56
  },
46
57
  legend: {
47
58
  '&[data-display-side="false"]': {
48
59
  marginLeft: margin.left,
49
- marginRight: margin.right,
50
- overflow: 'hidden'
60
+ marginRight: margin.right
51
61
  },
52
62
  '&[data-display-side="true"]': {
53
63
  height: '100%',
54
- marginTop: `${margin.top / 2}px`,
55
- overflowY: 'auto'
56
- }
64
+ marginTop: `${margin.top / 2}px`
65
+ },
66
+ maxHeight: limitLegendRows
67
+ ? theme.spacing(legendItemHeight * 2 + 1)
68
+ : getLegendMaxHeight({ placement, height }),
69
+ overflowY: 'auto',
70
+ overflowX: 'hidden'
57
71
  },
58
72
  minMaxAvgContainer: {
59
73
  columnGap: theme.spacing(0.5),
@@ -1,6 +1,6 @@
1
1
  import { Dispatch, ReactNode, SetStateAction, useMemo } from 'react';
2
2
 
3
- import { equals, lt, prop, slice, sortBy } from 'ramda';
3
+ import { equals, prop, slice, sortBy } from 'ramda';
4
4
 
5
5
  import { Box, alpha, useTheme } from '@mui/material';
6
6
 
@@ -8,7 +8,6 @@ import { useMemoComponent } from '@centreon/ui';
8
8
 
9
9
  import { formatMetricValue } from '../../common/timeSeries';
10
10
  import { Line } from '../../common/timeSeries/models';
11
- import { margin } from '../common';
12
11
  import { LegendModel } from '../models';
13
12
  import { labelAvg, labelMax, labelMin } from '../translatedLabels';
14
13
 
@@ -41,7 +40,11 @@ const MainLegend = ({
41
40
  height,
42
41
  mode
43
42
  }: Props): JSX.Element => {
44
- const { classes, cx } = useStyles({ limitLegendRows: Boolean(limitLegend) });
43
+ const { classes, cx } = useStyles({
44
+ limitLegendRows: Boolean(limitLegend),
45
+ placement,
46
+ height
47
+ });
45
48
  const theme = useTheme();
46
49
 
47
50
  const { selectMetricLine, clearHighlight, highlightLine, toggleMetricLine } =
@@ -81,31 +84,10 @@ const MainLegend = ({
81
84
  ? LegendDisplayMode.Compact
82
85
  : LegendDisplayMode.Normal;
83
86
 
84
- const legendMaxHeight = useMemo(() => {
85
- if (!isListMode || !equals(placement, 'bottom')) {
86
- return 'none';
87
- }
88
-
89
- if (lt(height || 0, 220)) {
90
- return 40;
91
- }
92
-
93
- return 90;
94
- }, [height, isListMode, placement]);
95
-
96
- const overflow = equals(legendMaxHeight, 'none') ? 'hidden' : 'auto';
97
-
98
87
  return (
99
88
  <div
100
89
  className={classes.legend}
101
90
  data-display-side={!equals(placement, 'bottom')}
102
- style={{
103
- height: !equals(placement, 'bottom')
104
- ? (height || 0) - margin.top / 2
105
- : undefined,
106
- maxHeight: legendMaxHeight,
107
- overflow
108
- }}
109
91
  >
110
92
  <div
111
93
  className={classes.items}
@@ -1,4 +1,4 @@
1
- import { type MutableRefObject, memo, useEffect, useRef } from 'react';
1
+ import { RefCallback, memo, useEffect, useRef } from 'react';
2
2
 
3
3
  import dayjs from 'dayjs';
4
4
  import 'dayjs/locale/en';
@@ -8,11 +8,10 @@ import 'dayjs/locale/pt';
8
8
  import localizedFormat from 'dayjs/plugin/localizedFormat';
9
9
  import timezonePlugin from 'dayjs/plugin/timezone';
10
10
  import utcPlugin from 'dayjs/plugin/utc';
11
-
12
- import { ParentSize } from '../..';
13
11
  import Loading from '../../LoadingSkeleton';
14
12
  import type { LineChartData, Thresholds } from '../common/models';
15
13
 
14
+ import useResizeObserver from 'use-resize-observer';
16
15
  import Chart from './Chart';
17
16
  import { useChartStyles } from './Chart.styles';
18
17
  import LoadingSkeleton from './LoadingSkeleton';
@@ -32,7 +31,7 @@ interface Props extends Partial<LineChartProps> {
32
31
  start: string;
33
32
  thresholdUnit?: string;
34
33
  thresholds?: Thresholds;
35
- getRef?: (ref: MutableRefObject<HTMLDivElement | null>) => void;
34
+ getRef?: (ref: RefCallback<Element>) => void;
36
35
  containerStyle?: string;
37
36
  }
38
37
 
@@ -68,13 +67,15 @@ const WrapperChart = ({
68
67
  ...rest
69
68
  }: Props): JSX.Element | null => {
70
69
  const { classes, cx } = useChartStyles();
70
+ const ref = useRef<HTMLDivElement | null>(null);
71
71
 
72
72
  const { adjustedData } = useChartData({ data, end, start });
73
- const lineChartRef = useRef<HTMLDivElement | null>(null);
73
+ const { width: responsiveWidth, height: responsiveHeight } =
74
+ useResizeObserver({ ref });
74
75
 
75
76
  useEffect(() => {
76
- getRef?.(lineChartRef);
77
- }, [lineChartRef?.current]);
77
+ getRef?.(ref);
78
+ }, [ref?.current]);
78
79
 
79
80
  if (loading && !adjustedData) {
80
81
  return (
@@ -85,46 +86,36 @@ const WrapperChart = ({
85
86
  );
86
87
  }
87
88
 
88
- if (!adjustedData) {
89
- return <Loading height={height} width={width} />;
90
- }
91
-
92
89
  return (
93
90
  <div
94
- ref={lineChartRef as MutableRefObject<HTMLDivElement>}
91
+ ref={ref}
95
92
  className={cx(classes.wrapperContainer, rest?.containerStyle)}
96
93
  >
97
- <ParentSize>
98
- {({
99
- height: responsiveHeight,
100
- width: responsiveWidth
101
- }): JSX.Element => {
102
- return (
103
- <Chart
104
- annotationEvent={annotationEvent}
105
- axis={axis}
106
- barStyle={barStyle}
107
- displayAnchor={displayAnchor}
108
- graphData={adjustedData}
109
- graphInterval={{ end, start }}
110
- graphRef={lineChartRef}
111
- header={header}
112
- height={height || responsiveHeight}
113
- legend={legend}
114
- limitLegend={limitLegend}
115
- lineStyle={lineStyle}
116
- shapeLines={shapeLines}
117
- thresholdUnit={thresholdUnit}
118
- thresholds={thresholds}
119
- timeShiftZones={timeShiftZones}
120
- tooltip={tooltip}
121
- width={width ?? responsiveWidth}
122
- zoomPreview={zoomPreview}
123
- skipIntersectionObserver={rest.skipIntersectionObserver}
124
- />
125
- );
126
- }}
127
- </ParentSize>
94
+ {!responsiveHeight || !data ? (
95
+ <Loading height={height || '100%'} width={width} />
96
+ ) : (
97
+ <Chart
98
+ annotationEvent={annotationEvent}
99
+ axis={axis}
100
+ barStyle={barStyle}
101
+ displayAnchor={displayAnchor}
102
+ graphData={adjustedData}
103
+ graphInterval={{ end, start }}
104
+ graphRef={ref}
105
+ header={header}
106
+ height={height || responsiveHeight}
107
+ legend={legend}
108
+ limitLegend={limitLegend}
109
+ lineStyle={lineStyle}
110
+ shapeLines={shapeLines}
111
+ thresholdUnit={thresholdUnit}
112
+ thresholds={thresholds}
113
+ timeShiftZones={timeShiftZones}
114
+ tooltip={tooltip}
115
+ width={width || responsiveWidth || 0}
116
+ zoomPreview={zoomPreview}
117
+ />
118
+ )}
128
119
  </div>
129
120
  );
130
121
  };
@@ -120,7 +120,6 @@ export interface LineChartProps {
120
120
  tooltip?: Tooltip;
121
121
  width: number;
122
122
  zoomPreview?: InteractedZone;
123
- skipIntersectionObserver?: boolean;
124
123
  }
125
124
 
126
125
  export interface Area {