@centreon/ui 25.7.2 → 25.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/Graph/BarChart/BarChart.cypress.spec.tsx +27 -2
- package/src/Graph/BarChart/BarChart.stories.tsx +10 -0
- package/src/Graph/BarChart/BarChart.tsx +19 -3
- package/src/Graph/BarChart/ResponsiveBarChart.tsx +12 -2
- package/src/Graph/Chart/BasicComponents/Lines/StackedLines/index.tsx +7 -1
- package/src/Graph/Chart/BasicComponents/Lines/index.tsx +10 -2
- package/src/Graph/Chart/Chart.cypress.spec.tsx +66 -13
- package/src/Graph/Chart/Chart.stories.tsx +41 -0
- package/src/Graph/Chart/Chart.tsx +15 -3
- package/src/Graph/Chart/InteractiveComponents/AnchorPoint/RegularAnchorPoint.tsx +8 -2
- package/src/Graph/Chart/InteractiveComponents/AnchorPoint/StackedAnchorPoint.tsx +9 -2
- package/src/Graph/Chart/InteractiveComponents/AnchorPoint/useTickGraph.ts +19 -2
- package/src/Graph/Chart/InteractiveComponents/index.tsx +16 -3
- package/src/Graph/Chart/index.tsx +6 -0
- package/src/Graph/Chart/models.ts +3 -0
- package/src/Graph/common/BaseChart/ChartSvgWrapper.tsx +5 -4
- package/src/Graph/common/timeSeries/index.ts +105 -34
- package/src/Graph/common/utils.ts +19 -0
- package/src/InputField/Select/Autocomplete/Connected/index.tsx +26 -21
- package/src/ThemeProvider/palettes.ts +1 -1
- package/src/api/models.ts +6 -6
package/package.json
CHANGED
|
@@ -30,10 +30,20 @@ const initialize = ({
|
|
|
30
30
|
tooltip,
|
|
31
31
|
axis,
|
|
32
32
|
orientation,
|
|
33
|
-
barStyle
|
|
33
|
+
barStyle,
|
|
34
|
+
min,
|
|
35
|
+
max
|
|
34
36
|
}: Pick<
|
|
35
37
|
BarChartProps,
|
|
36
|
-
|
|
38
|
+
| 'data'
|
|
39
|
+
| 'legend'
|
|
40
|
+
| 'axis'
|
|
41
|
+
| 'barStyle'
|
|
42
|
+
| 'orientation'
|
|
43
|
+
| 'tooltip'
|
|
44
|
+
| 'start'
|
|
45
|
+
| 'min'
|
|
46
|
+
| 'max'
|
|
37
47
|
>): void => {
|
|
38
48
|
cy.adjustViewport();
|
|
39
49
|
|
|
@@ -47,6 +57,8 @@ const initialize = ({
|
|
|
47
57
|
legend={legend}
|
|
48
58
|
orientation={orientation ?? 'horizontal'}
|
|
49
59
|
tooltip={tooltip}
|
|
60
|
+
min={min}
|
|
61
|
+
max={max}
|
|
50
62
|
{...defaultArgs}
|
|
51
63
|
/>
|
|
52
64
|
</div>
|
|
@@ -287,4 +299,17 @@ describe('Bar chart', () => {
|
|
|
287
299
|
cy.contains('05/31/2023').should('be.visible');
|
|
288
300
|
cy.contains('06/07/2023').should('be.visible');
|
|
289
301
|
});
|
|
302
|
+
|
|
303
|
+
it('displays the bar chart according to min and max boundaries', () => {
|
|
304
|
+
initialize({
|
|
305
|
+
data: dataLastWeek,
|
|
306
|
+
min: -0.05,
|
|
307
|
+
max: 1
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
cy.contains('05/31/2023').should('be.visible');
|
|
311
|
+
cy.contains('06/07/2023').should('be.visible');
|
|
312
|
+
cy.contains('1 s').should('be.visible');
|
|
313
|
+
cy.contains('1%').should('be.visible');
|
|
314
|
+
});
|
|
290
315
|
});
|
|
@@ -250,3 +250,13 @@ export const mixedStackedVertical: Story = {
|
|
|
250
250
|
},
|
|
251
251
|
render: Template
|
|
252
252
|
};
|
|
253
|
+
|
|
254
|
+
export const mixedStackedMinMax: Story = {
|
|
255
|
+
args: {
|
|
256
|
+
...defaultArgs,
|
|
257
|
+
data: dataPingServiceMixedStacked,
|
|
258
|
+
min: 10,
|
|
259
|
+
max: 20
|
|
260
|
+
},
|
|
261
|
+
render: Template
|
|
262
|
+
};
|
|
@@ -10,11 +10,11 @@ import { Provider } from 'jotai';
|
|
|
10
10
|
|
|
11
11
|
import { Box } from '@mui/material';
|
|
12
12
|
|
|
13
|
+
import Loading from '../../LoadingSkeleton';
|
|
13
14
|
import LoadingSkeleton from '../Chart/LoadingSkeleton';
|
|
14
15
|
import { LineChartProps } from '../Chart/models';
|
|
15
16
|
import useChartData from '../Chart/useChartData';
|
|
16
17
|
import { LineChartData, Thresholds } from '../common/models';
|
|
17
|
-
import Loading from '../../LoadingSkeleton';
|
|
18
18
|
|
|
19
19
|
import useResizeObserver from 'use-resize-observer';
|
|
20
20
|
import ResponsiveBarChart from './ResponsiveBarChart';
|
|
@@ -26,7 +26,17 @@ dayjs.extend(timezonePlugin);
|
|
|
26
26
|
|
|
27
27
|
export interface BarChartProps
|
|
28
28
|
extends Partial<
|
|
29
|
-
Pick<
|
|
29
|
+
Pick<
|
|
30
|
+
LineChartProps,
|
|
31
|
+
| 'tooltip'
|
|
32
|
+
| 'legend'
|
|
33
|
+
| 'height'
|
|
34
|
+
| 'axis'
|
|
35
|
+
| 'header'
|
|
36
|
+
| 'min'
|
|
37
|
+
| 'max'
|
|
38
|
+
| 'boundariesUnit'
|
|
39
|
+
>
|
|
30
40
|
> {
|
|
31
41
|
barStyle?: BarStyle;
|
|
32
42
|
data?: LineChartData;
|
|
@@ -58,7 +68,10 @@ const BarChart = ({
|
|
|
58
68
|
opacity: 1,
|
|
59
69
|
radius: 0.2
|
|
60
70
|
},
|
|
61
|
-
skipIntersectionObserver
|
|
71
|
+
skipIntersectionObserver,
|
|
72
|
+
min,
|
|
73
|
+
max,
|
|
74
|
+
boundariesUnit
|
|
62
75
|
}: BarChartProps): JSX.Element => {
|
|
63
76
|
const { adjustedData } = useChartData({ data, end, start });
|
|
64
77
|
const { ref, width, height: responsiveHeight } = useResizeObserver();
|
|
@@ -93,6 +106,9 @@ const BarChart = ({
|
|
|
93
106
|
tooltip={tooltip}
|
|
94
107
|
width={width || 0}
|
|
95
108
|
skipIntersectionObserver={skipIntersectionObserver}
|
|
109
|
+
min={min}
|
|
110
|
+
max={max}
|
|
111
|
+
boundariesUnit={boundariesUnit}
|
|
96
112
|
/>
|
|
97
113
|
)}
|
|
98
114
|
</Box>
|
|
@@ -40,6 +40,9 @@ interface Props
|
|
|
40
40
|
thresholds?: ThresholdsModel;
|
|
41
41
|
width: number;
|
|
42
42
|
skipIntersectionObserver?: boolean;
|
|
43
|
+
min?: number;
|
|
44
|
+
max?: number;
|
|
45
|
+
boundariesUnit?: string;
|
|
43
46
|
}
|
|
44
47
|
|
|
45
48
|
const ResponsiveBarChart = ({
|
|
@@ -56,7 +59,10 @@ const ResponsiveBarChart = ({
|
|
|
56
59
|
orientation,
|
|
57
60
|
tooltip,
|
|
58
61
|
barStyle,
|
|
59
|
-
skipIntersectionObserver
|
|
62
|
+
skipIntersectionObserver,
|
|
63
|
+
min,
|
|
64
|
+
max,
|
|
65
|
+
boundariesUnit
|
|
60
66
|
}: Props): JSX.Element => {
|
|
61
67
|
const { title, timeSeries, baseAxis, lines } = graphData || {};
|
|
62
68
|
|
|
@@ -131,7 +137,11 @@ const ResponsiveBarChart = ({
|
|
|
131
137
|
thresholdUnit,
|
|
132
138
|
thresholds: (thresholds?.enabled && thresholdValues) || [],
|
|
133
139
|
valueGraphHeight:
|
|
134
|
-
(isHorizontal ? graphHeight : graphWidth) - margin.bottom
|
|
140
|
+
(isHorizontal ? graphHeight : graphWidth) - margin.bottom,
|
|
141
|
+
min,
|
|
142
|
+
max,
|
|
143
|
+
isBarChart: true,
|
|
144
|
+
boundariesUnit
|
|
135
145
|
}),
|
|
136
146
|
[
|
|
137
147
|
displayedLines,
|
|
@@ -43,6 +43,8 @@ interface Props {
|
|
|
43
43
|
xScale: ScaleTime<number, number>;
|
|
44
44
|
yScale: ScaleLinear<number, number>;
|
|
45
45
|
lineStyle: LineStyle | Array<LineStyle>;
|
|
46
|
+
hasSecondUnit?: boolean;
|
|
47
|
+
maxLeftAxisCharacters: number;
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
const StackLines = ({
|
|
@@ -51,7 +53,9 @@ const StackLines = ({
|
|
|
51
53
|
yScale,
|
|
52
54
|
xScale,
|
|
53
55
|
displayAnchor,
|
|
54
|
-
lineStyle
|
|
56
|
+
lineStyle,
|
|
57
|
+
hasSecondUnit,
|
|
58
|
+
maxLeftAxisCharacters
|
|
55
59
|
}: Props): JSX.Element => {
|
|
56
60
|
const curveType = getCurveFactory(
|
|
57
61
|
(equals(type(lineStyle), 'Array')
|
|
@@ -101,6 +105,8 @@ const StackLines = ({
|
|
|
101
105
|
transparency={transparency}
|
|
102
106
|
xScale={xScale}
|
|
103
107
|
yScale={yScale}
|
|
108
|
+
hasSecondUnit={hasSecondUnit}
|
|
109
|
+
maxLeftAxisCharacters={maxLeftAxisCharacters}
|
|
104
110
|
/>
|
|
105
111
|
)}
|
|
106
112
|
{style?.showPoints &&
|
|
@@ -40,6 +40,8 @@ interface Props extends GlobalAreaLines {
|
|
|
40
40
|
xScale: ScaleLinear<number, number>;
|
|
41
41
|
yScalesPerUnit: Record<string, ScaleLinear<number, number>>;
|
|
42
42
|
lineStyle: LineStyle | Array<LineStyle>;
|
|
43
|
+
hasSecondUnit?: boolean;
|
|
44
|
+
maxLeftAxisCharacters: number;
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
const Lines = ({
|
|
@@ -56,7 +58,9 @@ const Lines = ({
|
|
|
56
58
|
areaRegularLines,
|
|
57
59
|
scale,
|
|
58
60
|
scaleLogarithmicBase,
|
|
59
|
-
lineStyle
|
|
61
|
+
lineStyle,
|
|
62
|
+
hasSecondUnit,
|
|
63
|
+
maxLeftAxisCharacters
|
|
60
64
|
}: Props): JSX.Element => {
|
|
61
65
|
const { stackedLinesData, invertedStackedLinesData } = useStackedLines({
|
|
62
66
|
lines: displayedLines,
|
|
@@ -78,7 +82,9 @@ const Lines = ({
|
|
|
78
82
|
graphHeight: height,
|
|
79
83
|
graphSvgRef,
|
|
80
84
|
graphWidth: width,
|
|
81
|
-
xScale
|
|
85
|
+
xScale,
|
|
86
|
+
hasSecondUnit,
|
|
87
|
+
maxLeftAxisCharacters
|
|
82
88
|
};
|
|
83
89
|
|
|
84
90
|
return (
|
|
@@ -192,6 +198,8 @@ const Lines = ({
|
|
|
192
198
|
transparency={transparency}
|
|
193
199
|
xScale={xScale}
|
|
194
200
|
yScale={yScale}
|
|
201
|
+
maxLeftAxisCharacters={maxLeftAxisCharacters}
|
|
202
|
+
hasSecondUnit={hasSecondUnit}
|
|
195
203
|
/>
|
|
196
204
|
)}
|
|
197
205
|
{style?.showPoints &&
|
|
@@ -22,7 +22,15 @@ import WrapperChart from '.';
|
|
|
22
22
|
interface Props
|
|
23
23
|
extends Pick<
|
|
24
24
|
LineChartProps,
|
|
25
|
-
|
|
25
|
+
| 'legend'
|
|
26
|
+
| 'tooltip'
|
|
27
|
+
| 'axis'
|
|
28
|
+
| 'lineStyle'
|
|
29
|
+
| 'barStyle'
|
|
30
|
+
| 'additionalLines'
|
|
31
|
+
| 'min'
|
|
32
|
+
| 'max'
|
|
33
|
+
| 'boundariesUnit'
|
|
26
34
|
> {
|
|
27
35
|
data?: LineChartData;
|
|
28
36
|
}
|
|
@@ -69,7 +77,10 @@ const initialize = ({
|
|
|
69
77
|
axis,
|
|
70
78
|
lineStyle,
|
|
71
79
|
barStyle,
|
|
72
|
-
additionalLines
|
|
80
|
+
additionalLines,
|
|
81
|
+
min,
|
|
82
|
+
max,
|
|
83
|
+
boundariesUnit
|
|
73
84
|
}: Props): void => {
|
|
74
85
|
cy.adjustViewport();
|
|
75
86
|
|
|
@@ -93,6 +104,9 @@ const initialize = ({
|
|
|
93
104
|
barStyle={barStyle}
|
|
94
105
|
tooltip={tooltip}
|
|
95
106
|
additionalLines={additionalLines}
|
|
107
|
+
min={min}
|
|
108
|
+
max={max}
|
|
109
|
+
boundariesUnit={boundariesUnit}
|
|
96
110
|
/>
|
|
97
111
|
</Provider>
|
|
98
112
|
)
|
|
@@ -165,8 +179,8 @@ describe('Line chart', () => {
|
|
|
165
179
|
|
|
166
180
|
cy.contains('06/18/2023').should('be.visible');
|
|
167
181
|
|
|
168
|
-
cy.contains('0.
|
|
169
|
-
cy.contains('
|
|
182
|
+
cy.contains('0.4 s').should('be.visible');
|
|
183
|
+
cy.contains('75.64%').should('be.visible');
|
|
170
184
|
|
|
171
185
|
cy.makeSnapshot();
|
|
172
186
|
});
|
|
@@ -188,12 +202,12 @@ describe('Line chart', () => {
|
|
|
188
202
|
cy.get('[data-metric="connTime"]').should(
|
|
189
203
|
'have.attr',
|
|
190
204
|
'data-highlight',
|
|
191
|
-
'
|
|
205
|
+
'true'
|
|
192
206
|
);
|
|
193
207
|
cy.get('[data-metric="hitratio"]').should(
|
|
194
208
|
'have.attr',
|
|
195
209
|
'data-highlight',
|
|
196
|
-
'
|
|
210
|
+
'false'
|
|
197
211
|
);
|
|
198
212
|
|
|
199
213
|
cy.makeSnapshot();
|
|
@@ -437,7 +451,7 @@ describe('Line chart', () => {
|
|
|
437
451
|
|
|
438
452
|
cy.contains(':00 AM').should('be.visible');
|
|
439
453
|
|
|
440
|
-
cy.get('text[transform="rotate(-35, -2,
|
|
454
|
+
cy.get('text[transform="rotate(-35, -2, 198.7929601526369)"]').should(
|
|
441
455
|
'be.visible'
|
|
442
456
|
);
|
|
443
457
|
|
|
@@ -451,8 +465,8 @@ describe('Line chart', () => {
|
|
|
451
465
|
|
|
452
466
|
cy.contains(':00 AM').should('be.visible');
|
|
453
467
|
|
|
454
|
-
cy.contains('0.
|
|
455
|
-
cy.contains('-0.
|
|
468
|
+
cy.contains('0.8').should('be.visible');
|
|
469
|
+
cy.contains('-0.8').should('be.visible');
|
|
456
470
|
|
|
457
471
|
cy.makeSnapshot();
|
|
458
472
|
});
|
|
@@ -519,7 +533,7 @@ describe('Line chart', () => {
|
|
|
519
533
|
checkGraphWidth();
|
|
520
534
|
cy.contains(':00 AM').should('be.visible');
|
|
521
535
|
cy.get('circle[cx="250.83333333333334"]').should('be.visible');
|
|
522
|
-
cy.get('circle[cy="
|
|
536
|
+
cy.get('circle[cy="246.2421135204699"]').should('be.visible');
|
|
523
537
|
|
|
524
538
|
cy.makeSnapshot();
|
|
525
539
|
});
|
|
@@ -733,10 +747,10 @@ describe('Lines and bars', () => {
|
|
|
733
747
|
checkGraphWidth();
|
|
734
748
|
|
|
735
749
|
cy.get(
|
|
736
|
-
'path[d="M7.501377410468319,
|
|
737
|
-
)
|
|
750
|
+
'path[d="M7.501377410468319,278.09035407759154 h56.51239669421488 h1v1 v95.90964592240846 a1,1 0 0 1 -1,1 h-56.51239669421488 a1,1 0 0 1 -1,-1 v-95.90964592240846 v-1h1z'
|
|
751
|
+
);
|
|
738
752
|
cy.get(
|
|
739
|
-
'path[d="M24.05509641873278,
|
|
753
|
+
'path[d="M24.05509641873278,225.7604521029811 h23.404958677685954 a17.553719008264462,17.553719008264462 0 0 1 17.553719008264462,17.553719008264462 v17.222463958081512 v17.553719008264462h-17.553719008264462 h-23.404958677685954 h-17.553719008264462v-17.553719008264462 v-17.222463958081512 a17.553719008264462,17.553719008264462 0 0 1 17.553719008264462,-17.553719008264462z"]'
|
|
740
754
|
).should('be.visible');
|
|
741
755
|
|
|
742
756
|
cy.makeSnapshot();
|
|
@@ -763,4 +777,43 @@ describe('Lines and bars', () => {
|
|
|
763
777
|
|
|
764
778
|
cy.makeSnapshot();
|
|
765
779
|
});
|
|
780
|
+
|
|
781
|
+
it('displays graph according to min and max boundaries', () => {
|
|
782
|
+
initialize({
|
|
783
|
+
data: dataPingServiceLines,
|
|
784
|
+
min: 0.01,
|
|
785
|
+
max: 0.1
|
|
786
|
+
});
|
|
787
|
+
|
|
788
|
+
checkGraphWidth();
|
|
789
|
+
|
|
790
|
+
cy.get('path[data-metric="1"]').should('be.visible');
|
|
791
|
+
cy.get('path[data-metric="3"]').should('be.visible');
|
|
792
|
+
cy.get('path[data-metric="3"]').should('be.visible');
|
|
793
|
+
|
|
794
|
+
cy.contains('0.1 ms').should('be.visible');
|
|
795
|
+
cy.contains('0.1%').should('be.visible');
|
|
796
|
+
|
|
797
|
+
cy.makeSnapshot();
|
|
798
|
+
});
|
|
799
|
+
|
|
800
|
+
it('displays graph according to min and max boundaries for a unit', () => {
|
|
801
|
+
initialize({
|
|
802
|
+
data: dataPingServiceLines,
|
|
803
|
+
min: 0.01,
|
|
804
|
+
max: 0.1,
|
|
805
|
+
boundariesUnit: 'ms'
|
|
806
|
+
});
|
|
807
|
+
|
|
808
|
+
checkGraphWidth();
|
|
809
|
+
|
|
810
|
+
cy.get('path[data-metric="1"]').should('be.visible');
|
|
811
|
+
cy.get('path[data-metric="3"]').should('be.visible');
|
|
812
|
+
cy.get('path[data-metric="3"]').should('be.visible');
|
|
813
|
+
|
|
814
|
+
cy.contains('0.1 ms').should('be.visible');
|
|
815
|
+
cy.contains('2%').should('be.visible');
|
|
816
|
+
|
|
817
|
+
cy.makeSnapshot();
|
|
818
|
+
});
|
|
766
819
|
});
|
|
@@ -717,3 +717,44 @@ export const WithAdditionalLines: Story = {
|
|
|
717
717
|
/>
|
|
718
718
|
)
|
|
719
719
|
};
|
|
720
|
+
|
|
721
|
+
export const linesAndBarsMinMax: Story = {
|
|
722
|
+
argTypes,
|
|
723
|
+
args: {
|
|
724
|
+
...argumentsData,
|
|
725
|
+
min: 10,
|
|
726
|
+
max: 30,
|
|
727
|
+
lineStyle: {
|
|
728
|
+
curve: 'natural',
|
|
729
|
+
lineWidth: 2,
|
|
730
|
+
showPoints: true
|
|
731
|
+
}
|
|
732
|
+
},
|
|
733
|
+
render: (args) => (
|
|
734
|
+
<WrapperChart
|
|
735
|
+
{...args}
|
|
736
|
+
data={dataPingServiceLinesBarsMixed as unknown as LineChartData}
|
|
737
|
+
/>
|
|
738
|
+
)
|
|
739
|
+
};
|
|
740
|
+
|
|
741
|
+
export const linesAndBarsMinMaxForUnit: Story = {
|
|
742
|
+
argTypes,
|
|
743
|
+
args: {
|
|
744
|
+
...argumentsData,
|
|
745
|
+
min: 10,
|
|
746
|
+
max: 30,
|
|
747
|
+
boundariesUnit: '%',
|
|
748
|
+
lineStyle: {
|
|
749
|
+
curve: 'natural',
|
|
750
|
+
lineWidth: 2,
|
|
751
|
+
showPoints: true
|
|
752
|
+
}
|
|
753
|
+
},
|
|
754
|
+
render: (args) => (
|
|
755
|
+
<WrapperChart
|
|
756
|
+
{...args}
|
|
757
|
+
data={dataPingServiceLinesBarsMixed as unknown as LineChartData}
|
|
758
|
+
/>
|
|
759
|
+
)
|
|
760
|
+
};
|
|
@@ -112,7 +112,10 @@ const Chart = ({
|
|
|
112
112
|
limitLegend,
|
|
113
113
|
skipIntersectionObserver,
|
|
114
114
|
transformMatrix,
|
|
115
|
-
additionalLines
|
|
115
|
+
additionalLines,
|
|
116
|
+
min,
|
|
117
|
+
max,
|
|
118
|
+
boundariesUnit
|
|
116
119
|
}: Props): JSX.Element => {
|
|
117
120
|
const { classes } = useChartStyles();
|
|
118
121
|
|
|
@@ -191,7 +194,10 @@ const Chart = ({
|
|
|
191
194
|
scaleLogarithmicBase: axis?.scaleLogarithmicBase,
|
|
192
195
|
thresholdUnit,
|
|
193
196
|
thresholds: (thresholds?.enabled && thresholdValues) || [],
|
|
194
|
-
valueGraphHeight: graphHeight - margin.bottom
|
|
197
|
+
valueGraphHeight: graphHeight - margin.bottom,
|
|
198
|
+
min,
|
|
199
|
+
max,
|
|
200
|
+
boundariesUnit
|
|
195
201
|
}),
|
|
196
202
|
[
|
|
197
203
|
linesGraph,
|
|
@@ -246,6 +252,8 @@ const Chart = ({
|
|
|
246
252
|
[axis?.showGridLines]
|
|
247
253
|
);
|
|
248
254
|
|
|
255
|
+
const hasSecondUnit = useMemo(() => Boolean(secondUnit), [secondUnit]);
|
|
256
|
+
|
|
249
257
|
if ((!isInViewport && !skipIntersectionObserver) || !height) {
|
|
250
258
|
return (
|
|
251
259
|
<Skeleton
|
|
@@ -299,7 +307,7 @@ const Chart = ({
|
|
|
299
307
|
timeSeries={timeSeries}
|
|
300
308
|
xScale={xScale}
|
|
301
309
|
maxAxisCharacters={maxLeftAxisCharacters}
|
|
302
|
-
hasSecondUnit={
|
|
310
|
+
hasSecondUnit={hasSecondUnit}
|
|
303
311
|
>
|
|
304
312
|
<>
|
|
305
313
|
{!isEmpty(linesDisplayedAsBar) && (
|
|
@@ -327,6 +335,8 @@ const Chart = ({
|
|
|
327
335
|
width={graphWidth}
|
|
328
336
|
xScale={xScale}
|
|
329
337
|
yScalesPerUnit={yScalesPerUnit}
|
|
338
|
+
hasSecondUnit={hasSecondUnit}
|
|
339
|
+
maxLeftAxisCharacters={maxLeftAxisCharacters}
|
|
330
340
|
{...shapeLines}
|
|
331
341
|
/>
|
|
332
342
|
)}
|
|
@@ -355,6 +365,8 @@ const Chart = ({
|
|
|
355
365
|
}}
|
|
356
366
|
zoomData={{ ...zoomPreview }}
|
|
357
367
|
transformMatrix={transformMatrix}
|
|
368
|
+
hasSecondUnit={hasSecondUnit}
|
|
369
|
+
maxLeftAxisCharacters={maxLeftAxisCharacters}
|
|
358
370
|
/>
|
|
359
371
|
{thresholds?.enabled && (
|
|
360
372
|
<Thresholds
|
|
@@ -15,6 +15,8 @@ interface Props {
|
|
|
15
15
|
timeSeries: Array<TimeValue>;
|
|
16
16
|
xScale: ScaleTime<number, number>;
|
|
17
17
|
yScale: ScaleLinear<number, number>;
|
|
18
|
+
hasSecondUnit?: boolean;
|
|
19
|
+
maxLeftAxisCharacters: number;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
export const getYAnchorPoint = ({
|
|
@@ -38,11 +40,15 @@ const RegularAnchorPoint = ({
|
|
|
38
40
|
yScale,
|
|
39
41
|
metric_id,
|
|
40
42
|
timeSeries,
|
|
41
|
-
lineColor
|
|
43
|
+
lineColor,
|
|
44
|
+
maxLeftAxisCharacters,
|
|
45
|
+
hasSecondUnit
|
|
42
46
|
}: Props): JSX.Element | null => {
|
|
43
47
|
const { tickAxisBottom: timeTick } = useTickGraph({
|
|
44
48
|
timeSeries,
|
|
45
|
-
xScale
|
|
49
|
+
xScale,
|
|
50
|
+
maxLeftAxisCharacters,
|
|
51
|
+
hasSecondUnit
|
|
46
52
|
});
|
|
47
53
|
|
|
48
54
|
if (isNil(timeTick)) {
|
|
@@ -15,7 +15,10 @@ interface Props {
|
|
|
15
15
|
timeSeries: Array<TimeValue>;
|
|
16
16
|
xScale: ScaleTime<number, number>;
|
|
17
17
|
yScale: ScaleLinear<number, number>;
|
|
18
|
+
hasSecondUnit?: boolean;
|
|
19
|
+
maxLeftAxisCharacters: number;
|
|
18
20
|
}
|
|
21
|
+
|
|
19
22
|
interface GetYAnchorPoint {
|
|
20
23
|
stackValues: Array<StackValue>;
|
|
21
24
|
timeTick: Date | null;
|
|
@@ -51,11 +54,15 @@ const StackedAnchorPoint = ({
|
|
|
51
54
|
yScale,
|
|
52
55
|
stackValues,
|
|
53
56
|
timeSeries,
|
|
54
|
-
lineColor
|
|
57
|
+
lineColor,
|
|
58
|
+
hasSecondUnit,
|
|
59
|
+
maxLeftAxisCharacters
|
|
55
60
|
}: Props): JSX.Element | null => {
|
|
56
61
|
const { tickAxisBottom: timeTick } = useTickGraph({
|
|
57
62
|
timeSeries,
|
|
58
|
-
xScale
|
|
63
|
+
xScale,
|
|
64
|
+
hasSecondUnit,
|
|
65
|
+
maxLeftAxisCharacters
|
|
59
66
|
});
|
|
60
67
|
|
|
61
68
|
if (isNil(timeTick)) {
|
|
@@ -6,6 +6,10 @@ import { useAtomValue } from 'jotai';
|
|
|
6
6
|
import useAxisY from '../../../common/Axes/useAxisY';
|
|
7
7
|
import { getTimeValue } from '../../../common/timeSeries';
|
|
8
8
|
import { Line, TimeValue } from '../../../common/timeSeries/models';
|
|
9
|
+
import {
|
|
10
|
+
computPixelsToShiftMouse,
|
|
11
|
+
computeGElementMarginLeft
|
|
12
|
+
} from '../../../common/utils';
|
|
9
13
|
import { margin } from '../../common';
|
|
10
14
|
import { mousePositionAtom } from '../interactionWithGraphAtoms';
|
|
11
15
|
|
|
@@ -25,6 +29,8 @@ interface Props {
|
|
|
25
29
|
rightScale?: ScaleLinear<number, number>;
|
|
26
30
|
timeSeries: Array<TimeValue>;
|
|
27
31
|
xScale: ScaleLinear<number, number>;
|
|
32
|
+
hasSecondUnit?: boolean;
|
|
33
|
+
maxLeftAxisCharacters: number;
|
|
28
34
|
}
|
|
29
35
|
|
|
30
36
|
const useTickGraph = ({
|
|
@@ -33,7 +39,9 @@ const useTickGraph = ({
|
|
|
33
39
|
leftScale,
|
|
34
40
|
rightScale,
|
|
35
41
|
lines = [],
|
|
36
|
-
baseAxis = 1000
|
|
42
|
+
baseAxis = 1000,
|
|
43
|
+
hasSecondUnit,
|
|
44
|
+
maxLeftAxisCharacters
|
|
37
45
|
}: Props): AnchorPointResult => {
|
|
38
46
|
const guidingLinesRef = useRef<SVGGElement | null>(null);
|
|
39
47
|
const [tickAxisBottom, setTickAxisBottom] = useState<Date | null>(null);
|
|
@@ -69,8 +77,17 @@ const useTickGraph = ({
|
|
|
69
77
|
|
|
70
78
|
return;
|
|
71
79
|
}
|
|
80
|
+
const pixelToShift = computPixelsToShiftMouse(xScale);
|
|
72
81
|
const mousePositionTimeTick = mousePosition
|
|
73
|
-
? getTimeValue({
|
|
82
|
+
? getTimeValue({
|
|
83
|
+
timeSeries,
|
|
84
|
+
x: mousePosition[0] - pixelToShift,
|
|
85
|
+
xScale,
|
|
86
|
+
marginLeft: computeGElementMarginLeft({
|
|
87
|
+
maxCharacters: maxLeftAxisCharacters,
|
|
88
|
+
hasSecondUnit
|
|
89
|
+
})
|
|
90
|
+
})?.timeTick
|
|
74
91
|
: 0;
|
|
75
92
|
const timeTickValue = mousePosition
|
|
76
93
|
? new Date(mousePositionTimeTick || 0)
|
|
@@ -37,6 +37,10 @@ import type {
|
|
|
37
37
|
InteractedZone as ZoomPreviewModel
|
|
38
38
|
} from '../models';
|
|
39
39
|
|
|
40
|
+
import {
|
|
41
|
+
computPixelsToShiftMouse,
|
|
42
|
+
computeGElementMarginLeft
|
|
43
|
+
} from '../../common/utils';
|
|
40
44
|
import Annotations from './Annotations';
|
|
41
45
|
import type { TimelineEvent } from './Annotations/models';
|
|
42
46
|
import Bar from './Bar';
|
|
@@ -80,6 +84,8 @@ interface Props {
|
|
|
80
84
|
fx?: (pointX: number) => number;
|
|
81
85
|
fy?: (pointY: number) => number;
|
|
82
86
|
};
|
|
87
|
+
hasSecondUnit?: boolean;
|
|
88
|
+
maxLeftAxisCharacters: number;
|
|
83
89
|
}
|
|
84
90
|
|
|
85
91
|
const InteractionWithGraph = ({
|
|
@@ -87,7 +93,9 @@ const InteractionWithGraph = ({
|
|
|
87
93
|
commonData,
|
|
88
94
|
annotationData,
|
|
89
95
|
timeShiftZonesData,
|
|
90
|
-
transformMatrix
|
|
96
|
+
transformMatrix,
|
|
97
|
+
hasSecondUnit,
|
|
98
|
+
maxLeftAxisCharacters
|
|
91
99
|
}: Props): JSX.Element => {
|
|
92
100
|
const { classes } = useStyles();
|
|
93
101
|
|
|
@@ -151,10 +159,15 @@ const InteractionWithGraph = ({
|
|
|
151
159
|
|
|
152
160
|
return;
|
|
153
161
|
}
|
|
162
|
+
const pixelToShift = computPixelsToShiftMouse(xScale);
|
|
154
163
|
const timeValue = getTimeValue({
|
|
155
164
|
timeSeries,
|
|
156
|
-
x: pointPosition[0],
|
|
157
|
-
xScale
|
|
165
|
+
x: pointPosition[0] - pixelToShift,
|
|
166
|
+
xScale,
|
|
167
|
+
marginLeft: computeGElementMarginLeft({
|
|
168
|
+
maxCharacters: maxLeftAxisCharacters,
|
|
169
|
+
hasSecondUnit
|
|
170
|
+
})
|
|
158
171
|
});
|
|
159
172
|
|
|
160
173
|
if (isNil(timeValue)) {
|
|
@@ -70,6 +70,9 @@ const WrapperChart = ({
|
|
|
70
70
|
getRef,
|
|
71
71
|
transformMatrix,
|
|
72
72
|
additionalLines,
|
|
73
|
+
min,
|
|
74
|
+
max,
|
|
75
|
+
boundariesUnit,
|
|
73
76
|
...rest
|
|
74
77
|
}: Props): JSX.Element | null => {
|
|
75
78
|
const { classes, cx } = useChartStyles();
|
|
@@ -125,6 +128,9 @@ const WrapperChart = ({
|
|
|
125
128
|
skipIntersectionObserver={rest.skipIntersectionObserver}
|
|
126
129
|
additionalLines={additionalLines}
|
|
127
130
|
transformMatrix={transformMatrix}
|
|
131
|
+
min={min}
|
|
132
|
+
max={max}
|
|
133
|
+
boundariesUnit={boundariesUnit}
|
|
128
134
|
/>
|
|
129
135
|
)}
|
|
130
136
|
</div>
|
|
@@ -122,6 +122,9 @@ export interface LineChartProps {
|
|
|
122
122
|
zoomPreview?: InteractedZone;
|
|
123
123
|
skipIntersectionObserver?: boolean;
|
|
124
124
|
additionalLines?: Array<AdditionalLineProps>;
|
|
125
|
+
min?: number;
|
|
126
|
+
max?: number;
|
|
127
|
+
boundariesUnit?: string;
|
|
125
128
|
}
|
|
126
129
|
|
|
127
130
|
export interface Area {
|
|
@@ -8,6 +8,7 @@ import { ChartAxis } from '../../Chart/models';
|
|
|
8
8
|
import Axes from '../Axes';
|
|
9
9
|
import Grids from '../Grids';
|
|
10
10
|
import { Line, TimeValue } from '../timeSeries/models';
|
|
11
|
+
import { computeGElementMarginLeft } from '../utils';
|
|
11
12
|
|
|
12
13
|
interface Props {
|
|
13
14
|
allUnits: Array<string>;
|
|
@@ -58,10 +59,10 @@ const ChartSvgWrapper = ({
|
|
|
58
59
|
width="100%"
|
|
59
60
|
>
|
|
60
61
|
<Group.Group
|
|
61
|
-
left={
|
|
62
|
-
maxAxisCharacters
|
|
63
|
-
|
|
64
|
-
}
|
|
62
|
+
left={computeGElementMarginLeft({
|
|
63
|
+
maxCharacters: maxAxisCharacters,
|
|
64
|
+
hasSecondUnit
|
|
65
|
+
})}
|
|
65
66
|
top={margin.top}
|
|
66
67
|
>
|
|
67
68
|
{showGridLines && (
|
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
includes,
|
|
21
21
|
isEmpty,
|
|
22
22
|
isNil,
|
|
23
|
-
isNotNil,
|
|
24
23
|
keys,
|
|
25
24
|
last,
|
|
26
25
|
lt,
|
|
@@ -353,6 +352,19 @@ const getScaleType = (
|
|
|
353
352
|
const hasOnlyZeroesHasValue = (graphValues: Array<number>): boolean =>
|
|
354
353
|
graphValues.every((value) => equals(value, 0) || equals(value, null));
|
|
355
354
|
|
|
355
|
+
const getSanitizedValues = reject(
|
|
356
|
+
(
|
|
357
|
+
value:
|
|
358
|
+
| number
|
|
359
|
+
| boolean
|
|
360
|
+
| typeof Number.POSITIVE_INFINITY
|
|
361
|
+
| typeof Number.NEGATIVE_INFINITY
|
|
362
|
+
) =>
|
|
363
|
+
equals(value, false) ||
|
|
364
|
+
equals(value, Number.POSITIVE_INFINITY) ||
|
|
365
|
+
equals(value, Number.NEGATIVE_INFINITY)
|
|
366
|
+
);
|
|
367
|
+
|
|
356
368
|
const getScale = ({
|
|
357
369
|
graphValues,
|
|
358
370
|
height,
|
|
@@ -363,23 +375,39 @@ const getScale = ({
|
|
|
363
375
|
scaleLogarithmicBase,
|
|
364
376
|
isHorizontal,
|
|
365
377
|
invert,
|
|
366
|
-
hasDisplayAsBar
|
|
378
|
+
hasDisplayAsBar,
|
|
379
|
+
hasLineFilled,
|
|
380
|
+
min,
|
|
381
|
+
max
|
|
367
382
|
}): ScaleLinear<number, number> => {
|
|
368
383
|
const isLogScale = equals(scale, 'logarithmic');
|
|
369
|
-
const
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
384
|
+
const sanitizedValuesForMinimum = min
|
|
385
|
+
? [min]
|
|
386
|
+
: getSanitizedValues([
|
|
387
|
+
invert && graphValues.every(lt(0))
|
|
388
|
+
? negate(getMax(graphValues))
|
|
389
|
+
: getMin(graphValues),
|
|
390
|
+
!isEmpty(stackedValues) &&
|
|
391
|
+
!equals(stackedValues, [0]) &&
|
|
392
|
+
getMin(stackedValues),
|
|
393
|
+
Math.min(...thresholds)
|
|
394
|
+
]);
|
|
395
|
+
const minValue = Math.min(...sanitizedValuesForMinimum);
|
|
396
|
+
const minValueWithMargin =
|
|
397
|
+
(hasDisplayAsBar || hasLineFilled) && minValue > 0 && !min
|
|
398
|
+
? 0
|
|
399
|
+
: minValue - Math.abs(minValue) * 0.05;
|
|
400
|
+
|
|
401
|
+
const sanitizedValuesForMaximum = max
|
|
402
|
+
? [max]
|
|
403
|
+
: getSanitizedValues([
|
|
404
|
+
getMax(graphValues),
|
|
405
|
+
getMax(stackedValues),
|
|
406
|
+
hasOnlyZeroesHasValue(graphValues) ? 1 : 0,
|
|
407
|
+
Math.max(...thresholds)
|
|
408
|
+
]);
|
|
409
|
+
const maxValue = Math.max(...sanitizedValuesForMaximum);
|
|
410
|
+
const maxValueWithMargin = maxValue + Math.abs(maxValue) * 0.05;
|
|
383
411
|
|
|
384
412
|
const scaleType = getScaleType(scale);
|
|
385
413
|
|
|
@@ -387,21 +415,26 @@ const getScale = ({
|
|
|
387
415
|
const range = [height, upperRangeValue];
|
|
388
416
|
|
|
389
417
|
if (isCenteredZero) {
|
|
390
|
-
const greatestValue = Math.max(
|
|
418
|
+
const greatestValue = Math.max(
|
|
419
|
+
Math.abs(maxValueWithMargin),
|
|
420
|
+
Math.abs(minValueWithMargin)
|
|
421
|
+
);
|
|
391
422
|
|
|
392
423
|
return scaleType<number>({
|
|
393
424
|
base: scaleLogarithmicBase || 2,
|
|
394
425
|
domain: [-greatestValue, greatestValue],
|
|
395
|
-
range: isHorizontal ? range : range.reverse()
|
|
426
|
+
range: isHorizontal ? range : range.reverse(),
|
|
427
|
+
clamp: min || max
|
|
396
428
|
});
|
|
397
429
|
}
|
|
398
430
|
|
|
399
|
-
const domain = [isLogScale ? 0.001 :
|
|
431
|
+
const domain = [isLogScale ? 0.001 : minValueWithMargin, maxValueWithMargin];
|
|
400
432
|
|
|
401
433
|
return scaleType<number>({
|
|
402
434
|
base: scaleLogarithmicBase || 2,
|
|
403
435
|
domain,
|
|
404
|
-
range: isHorizontal ? range : range.reverse()
|
|
436
|
+
range: isHorizontal ? range : range.reverse(),
|
|
437
|
+
clamp: min || max
|
|
405
438
|
});
|
|
406
439
|
};
|
|
407
440
|
|
|
@@ -437,11 +470,19 @@ const getYScaleUnit = ({
|
|
|
437
470
|
scaleLogarithmicBase,
|
|
438
471
|
isHorizontal = true,
|
|
439
472
|
unit,
|
|
440
|
-
invert
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
473
|
+
invert,
|
|
474
|
+
min,
|
|
475
|
+
max,
|
|
476
|
+
isBarChart,
|
|
477
|
+
boundariesUnit
|
|
478
|
+
}: AxeScale & {
|
|
479
|
+
invert?: boolean | string | null;
|
|
480
|
+
unit: string;
|
|
481
|
+
max?: number;
|
|
482
|
+
min?: number;
|
|
483
|
+
boundariesUnit?: string;
|
|
484
|
+
isBarChart?: boolean;
|
|
485
|
+
}): ScaleLinear<number, number> => {
|
|
445
486
|
const [firstUnit] = getUnits(dataLines);
|
|
446
487
|
const shouldApplyThresholds =
|
|
447
488
|
equals(unit, thresholdUnit) || (!thresholdUnit && equals(firstUnit, unit));
|
|
@@ -468,11 +509,14 @@ const getYScaleUnit = ({
|
|
|
468
509
|
|
|
469
510
|
return getScale({
|
|
470
511
|
graphValues,
|
|
471
|
-
hasDisplayAsBar:
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
512
|
+
hasDisplayAsBar:
|
|
513
|
+
isBarChart ||
|
|
514
|
+
dataLines.some(
|
|
515
|
+
({ displayAs, unit: lineUnit }) =>
|
|
516
|
+
equals(unit, lineUnit) && equals(displayAs, 'bar')
|
|
517
|
+
),
|
|
518
|
+
hasLineFilled: dataLines.some(
|
|
519
|
+
({ unit: lineUnit, filled }) => equals(unit, lineUnit) && filled
|
|
476
520
|
),
|
|
477
521
|
height: valueGraphHeight,
|
|
478
522
|
invert,
|
|
@@ -481,10 +525,24 @@ const getYScaleUnit = ({
|
|
|
481
525
|
scale,
|
|
482
526
|
scaleLogarithmicBase,
|
|
483
527
|
stackedValues,
|
|
484
|
-
thresholds: shouldApplyThresholds ? thresholds : []
|
|
528
|
+
thresholds: shouldApplyThresholds ? thresholds : [],
|
|
529
|
+
min: boundaryToApplyToUnit({ unit, boundariesUnit, boundary: min }),
|
|
530
|
+
max: boundaryToApplyToUnit({ unit, boundariesUnit, boundary: max })
|
|
485
531
|
});
|
|
486
532
|
};
|
|
487
533
|
|
|
534
|
+
const boundaryToApplyToUnit = ({
|
|
535
|
+
boundary,
|
|
536
|
+
boundariesUnit,
|
|
537
|
+
unit
|
|
538
|
+
}): number | undefined => {
|
|
539
|
+
if (!boundariesUnit) {
|
|
540
|
+
return boundary;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
return equals(boundariesUnit, unit) ? boundary : undefined;
|
|
544
|
+
};
|
|
545
|
+
|
|
488
546
|
const getYScalePerUnit = ({
|
|
489
547
|
dataLines,
|
|
490
548
|
dataTimeSeries,
|
|
@@ -494,8 +552,17 @@ const getYScalePerUnit = ({
|
|
|
494
552
|
isCenteredZero,
|
|
495
553
|
scale,
|
|
496
554
|
scaleLogarithmicBase,
|
|
497
|
-
isHorizontal = true
|
|
498
|
-
|
|
555
|
+
isHorizontal = true,
|
|
556
|
+
isBarChart,
|
|
557
|
+
min,
|
|
558
|
+
max,
|
|
559
|
+
boundariesUnit
|
|
560
|
+
}: AxeScale & {
|
|
561
|
+
min?: number;
|
|
562
|
+
max?: number;
|
|
563
|
+
isBarChart?: boolean;
|
|
564
|
+
boundariesUnit?: string;
|
|
565
|
+
}): Record<string, ScaleLinear<number, number>> => {
|
|
499
566
|
const units = getUnits(dataLines);
|
|
500
567
|
|
|
501
568
|
const scalePerUnit = units.reduce((acc, unit) => {
|
|
@@ -514,7 +581,11 @@ const getYScalePerUnit = ({
|
|
|
514
581
|
thresholdUnit,
|
|
515
582
|
thresholds,
|
|
516
583
|
unit,
|
|
517
|
-
valueGraphHeight
|
|
584
|
+
valueGraphHeight,
|
|
585
|
+
min,
|
|
586
|
+
max,
|
|
587
|
+
isBarChart,
|
|
588
|
+
boundariesUnit
|
|
518
589
|
})
|
|
519
590
|
};
|
|
520
591
|
}, {});
|
|
@@ -20,7 +20,9 @@ import {
|
|
|
20
20
|
|
|
21
21
|
import { Theme, darken, getLuminance, lighten } from '@mui/material';
|
|
22
22
|
|
|
23
|
+
import dayjs from 'dayjs';
|
|
23
24
|
import { BarStyle } from '../BarChart/models';
|
|
25
|
+
import { margin } from '../Chart/common';
|
|
24
26
|
import { LineStyle } from '../Chart/models';
|
|
25
27
|
import { Threshold, Thresholds } from './models';
|
|
26
28
|
import { formatMetricValue } from './timeSeries';
|
|
@@ -256,3 +258,20 @@ export const getFormattedAxisValues = ({
|
|
|
256
258
|
.concat(formattedThresholdValues)
|
|
257
259
|
.filter((v) => v) as Array<string>;
|
|
258
260
|
};
|
|
261
|
+
|
|
262
|
+
interface ComputeGElementMarginLeftProps {
|
|
263
|
+
maxCharacters: number;
|
|
264
|
+
hasSecondUnit?: boolean;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export const computeGElementMarginLeft = ({
|
|
268
|
+
maxCharacters,
|
|
269
|
+
hasSecondUnit
|
|
270
|
+
}: ComputeGElementMarginLeftProps): number =>
|
|
271
|
+
maxCharacters * 5 + (hasSecondUnit ? margin.top * 0.8 : margin.top * 0.6);
|
|
272
|
+
|
|
273
|
+
export const computPixelsToShiftMouse = (xScale): number => {
|
|
274
|
+
const domain = xScale.domain();
|
|
275
|
+
|
|
276
|
+
return Math.round(8 / dayjs(domain[1]).diff(domain[0], 'h'));
|
|
277
|
+
};
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
import { CircularProgress, useTheme } from '@mui/material';
|
|
18
18
|
|
|
19
19
|
import { Props as AutocompleteFieldProps } from '..';
|
|
20
|
-
import {
|
|
20
|
+
import { ListingMapModel, ListingModel, SelectEntry } from '../../../..';
|
|
21
21
|
import {
|
|
22
22
|
ConditionsSearchParameter,
|
|
23
23
|
SearchParameter
|
|
@@ -122,26 +122,31 @@ const ConnectedAutocompleteField = (
|
|
|
122
122
|
}
|
|
123
123
|
});
|
|
124
124
|
|
|
125
|
-
const getOptionResult = useCallback(
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
125
|
+
const getOptionResult = useCallback(
|
|
126
|
+
(
|
|
127
|
+
newOptions: ListingModel<TData> | ListingMapModel<TData>
|
|
128
|
+
): OptionResult<TData> => {
|
|
129
|
+
if ('result' in newOptions)
|
|
130
|
+
return {
|
|
131
|
+
result: newOptions.result || [],
|
|
132
|
+
total: newOptions.meta.total || 1,
|
|
133
|
+
limit: newOptions.meta.limit || 1
|
|
134
|
+
};
|
|
135
|
+
if ('content' in newOptions)
|
|
136
|
+
return {
|
|
137
|
+
result: newOptions.content || [],
|
|
138
|
+
total: newOptions.totalElements || 1,
|
|
139
|
+
limit: newOptions.size || 1
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
return {
|
|
143
|
+
result: [],
|
|
144
|
+
total: 1,
|
|
145
|
+
limit: 1
|
|
146
|
+
};
|
|
147
|
+
},
|
|
148
|
+
[]
|
|
149
|
+
);
|
|
145
150
|
|
|
146
151
|
const lastOptionRef = useIntersectionObserver({
|
|
147
152
|
action: () => setPage(page + 1),
|
package/src/api/models.ts
CHANGED
|
@@ -10,10 +10,10 @@ export interface Listing<TEntity> {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export interface ListingMap<TEntity> {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
content: Array<TEntity>;
|
|
14
|
+
totalPages: number;
|
|
15
|
+
totalElements: number;
|
|
16
|
+
size: number;
|
|
17
|
+
number: number;
|
|
18
|
+
numberOfElements: number;
|
|
19
19
|
}
|