@centreon/ui 23.10.50 → 23.10.52
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/Dashboard/Layout.tsx +4 -2
- package/src/Graph/BasicComponents/Axes/index.tsx +1 -1
- package/src/Graph/BasicComponents/Lines/RegularLines/index.tsx +6 -3
- package/src/Graph/BasicComponents/Lines/StackedLines/index.tsx +6 -3
- package/src/Graph/BasicComponents/Lines/Threshold/BasicThreshold.tsx +5 -3
- package/src/Graph/BasicComponents/Lines/Threshold/ThresholdWithPatternLines.tsx +5 -1
- package/src/Graph/BasicComponents/Lines/Threshold/ThresholdWithVariation.tsx +5 -1
- package/src/Graph/BasicComponents/Lines/Threshold/index.tsx +5 -1
- package/src/Graph/BasicComponents/Lines/index.tsx +6 -1
- package/src/Graph/BasicComponents/Lines/models.ts +3 -0
- package/src/Graph/Graph.tsx +40 -20
- package/src/Graph/Header/index.tsx +7 -7
- package/src/Graph/InteractiveComponents/AnchorPoint/TooltipAnchorPoint.tsx +48 -22
- package/src/Graph/InteractiveComponents/AnchorPoint/index.tsx +14 -12
- package/src/Graph/InteractiveComponents/TimeShiftZones/TimeShiftZone.tsx +1 -1
- package/src/Graph/index.stories.tsx +10 -0
- package/src/Graph/index.tsx +35 -23
- package/src/Graph/models.ts +1 -1
- package/src/InputField/Select/Autocomplete/Connected/index.tsx +9 -1
- package/src/InputField/Select/Autocomplete/Multi/index.tsx +7 -2
- package/src/Panel/index.tsx +3 -1
- package/src/api/useGraphQuery/index.ts +92 -0
- package/src/api/useGraphQuery/models.ts +12 -0
- package/src/components/ItemComposition/Item.tsx +37 -0
- package/src/components/ItemComposition/ItemComposition.stories.tsx +78 -0
- package/src/components/ItemComposition/ItemComposition.styles.ts +26 -0
- package/src/components/ItemComposition/ItemComposition.tsx +41 -0
- package/src/components/ItemComposition/index.ts +6 -0
- package/src/components/Modal/Modal.styles.ts +1 -1
- package/src/components/index.ts +1 -0
- package/src/index.ts +3 -0
- package/src/Graph/InteractiveComponents/AnchorPoint/AnchorPoint.styles.ts +0 -58
package/package.json
CHANGED
package/src/Dashboard/Layout.tsx
CHANGED
|
@@ -16,6 +16,7 @@ interface DashboardLayoutProps<T> {
|
|
|
16
16
|
changeLayout?: (newLayout: Array<Layout>) => void;
|
|
17
17
|
children: Array<JSX.Element>;
|
|
18
18
|
displayGrid?: boolean;
|
|
19
|
+
isStatic?: boolean;
|
|
19
20
|
layout: Array<T>;
|
|
20
21
|
}
|
|
21
22
|
|
|
@@ -23,9 +24,10 @@ const Layout = <T extends Layout>({
|
|
|
23
24
|
children,
|
|
24
25
|
changeLayout,
|
|
25
26
|
displayGrid,
|
|
26
|
-
layout
|
|
27
|
+
layout,
|
|
28
|
+
isStatic = false
|
|
27
29
|
}: DashboardLayoutProps<T>): JSX.Element => {
|
|
28
|
-
const { classes } = useDashboardLayoutStyles();
|
|
30
|
+
const { classes } = useDashboardLayoutStyles(isStatic);
|
|
29
31
|
|
|
30
32
|
const [columns, setColumns] = useState(getColumnsFromScreenSize());
|
|
31
33
|
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { memo } from 'react';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { Shape } from '@visx/visx';
|
|
4
4
|
import { ScaleLinear, ScaleTime } from 'd3-scale';
|
|
5
5
|
import { equals, isNil, prop } from 'ramda';
|
|
6
6
|
|
|
7
7
|
import { getTime } from '../../../timeSeries';
|
|
8
8
|
import { TimeValue } from '../../../timeSeries/models';
|
|
9
9
|
import { getFillColor } from '../../../common';
|
|
10
|
+
import { CurveType } from '../models';
|
|
10
11
|
|
|
11
12
|
interface Props {
|
|
12
13
|
areaColor: string;
|
|
14
|
+
curve: CurveType;
|
|
13
15
|
filled: boolean;
|
|
14
16
|
graphHeight: number;
|
|
15
17
|
highlight?: boolean;
|
|
@@ -35,10 +37,11 @@ const RegularLine = ({
|
|
|
35
37
|
xScale,
|
|
36
38
|
areaColor,
|
|
37
39
|
transparency,
|
|
38
|
-
graphHeight
|
|
40
|
+
graphHeight,
|
|
41
|
+
curve
|
|
39
42
|
}: Props): JSX.Element => {
|
|
40
43
|
const props = {
|
|
41
|
-
curve
|
|
44
|
+
curve,
|
|
42
45
|
data: timeSeries,
|
|
43
46
|
defined: (value): boolean => !isNil(value[metric]),
|
|
44
47
|
opacity: 1,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Shape } from '@visx/visx';
|
|
2
2
|
import { ScaleLinear, ScaleTime } from 'd3-scale';
|
|
3
3
|
import { all, isNil, map, not, nth, path, pipe, prop } from 'ramda';
|
|
4
4
|
|
|
@@ -7,8 +7,10 @@ import { StackValue } from '../../../InteractiveComponents/AnchorPoint/models';
|
|
|
7
7
|
import { getFillColor } from '../../../common';
|
|
8
8
|
import { getTime } from '../../../timeSeries';
|
|
9
9
|
import { Line, TimeValue } from '../../../timeSeries/models';
|
|
10
|
+
import { CurveType } from '../models';
|
|
10
11
|
|
|
11
12
|
interface Props {
|
|
13
|
+
curve: CurveType;
|
|
12
14
|
displayAnchor: boolean;
|
|
13
15
|
lines: Array<Line>;
|
|
14
16
|
timeSeries: Array<TimeValue>;
|
|
@@ -21,11 +23,12 @@ const StackLines = ({
|
|
|
21
23
|
lines,
|
|
22
24
|
yScale,
|
|
23
25
|
xScale,
|
|
24
|
-
displayAnchor
|
|
26
|
+
displayAnchor,
|
|
27
|
+
curve
|
|
25
28
|
}: Props): JSX.Element => {
|
|
26
29
|
return (
|
|
27
30
|
<Shape.AreaStack
|
|
28
|
-
curve={
|
|
31
|
+
curve={curve}
|
|
29
32
|
data={timeSeries}
|
|
30
33
|
defined={(d): boolean => {
|
|
31
34
|
return pipe(
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { curveBasis } from '@visx/curve';
|
|
2
1
|
import { Threshold } from '@visx/threshold';
|
|
3
2
|
|
|
4
3
|
import { TimeValue } from '../../../timeSeries/models';
|
|
4
|
+
import { CurveType } from '../models';
|
|
5
5
|
|
|
6
6
|
interface Props {
|
|
7
|
+
curve: CurveType;
|
|
7
8
|
fillAboveArea: string;
|
|
8
9
|
fillBelowArea: string;
|
|
9
10
|
fillOpacity?: number;
|
|
@@ -24,7 +25,8 @@ const BasicThreshold = ({
|
|
|
24
25
|
fillOpacity = 0.1,
|
|
25
26
|
id,
|
|
26
27
|
fillAboveArea,
|
|
27
|
-
fillBelowArea
|
|
28
|
+
fillBelowArea,
|
|
29
|
+
curve
|
|
28
30
|
}: Props): JSX.Element => {
|
|
29
31
|
return (
|
|
30
32
|
<Threshold
|
|
@@ -38,7 +40,7 @@ const BasicThreshold = ({
|
|
|
38
40
|
}}
|
|
39
41
|
clipAboveTo={0}
|
|
40
42
|
clipBelowTo={graphHeight}
|
|
41
|
-
curve={
|
|
43
|
+
curve={curve}
|
|
42
44
|
data={timeSeries}
|
|
43
45
|
id={id}
|
|
44
46
|
x={getX}
|
|
@@ -5,11 +5,13 @@ import { useTheme } from '@mui/material/styles';
|
|
|
5
5
|
|
|
6
6
|
import { adjustGraphData } from '../../../helpers/index';
|
|
7
7
|
import { GraphData, PatternOrientation } from '../../../models';
|
|
8
|
+
import { CurveType } from '../models';
|
|
8
9
|
|
|
9
10
|
import BasicThreshold from './BasicThreshold';
|
|
10
11
|
import useScaleThreshold from './useScaleThreshold';
|
|
11
12
|
|
|
12
13
|
interface Props {
|
|
14
|
+
curve: CurveType;
|
|
13
15
|
data: GraphData;
|
|
14
16
|
graphHeight: number;
|
|
15
17
|
id: string;
|
|
@@ -26,7 +28,8 @@ const ThresholdWithPatternLines = ({
|
|
|
26
28
|
leftScale,
|
|
27
29
|
rightScale,
|
|
28
30
|
xScale,
|
|
29
|
-
id
|
|
31
|
+
id,
|
|
32
|
+
curve
|
|
30
33
|
}: Props): JSX.Element | null => {
|
|
31
34
|
const theme = useTheme();
|
|
32
35
|
|
|
@@ -47,6 +50,7 @@ const ThresholdWithPatternLines = ({
|
|
|
47
50
|
return (
|
|
48
51
|
<>
|
|
49
52
|
<BasicThreshold
|
|
53
|
+
curve={curve}
|
|
50
54
|
fillAboveArea={"url('#lines')"}
|
|
51
55
|
fillBelowArea={"url('#lines')"}
|
|
52
56
|
fillOpacity={0.8}
|
|
@@ -4,10 +4,12 @@ import { LinePath } from '@visx/shape';
|
|
|
4
4
|
import { useTheme } from '@mui/material/styles';
|
|
5
5
|
|
|
6
6
|
import { TimeValue } from '../../../timeSeries/models';
|
|
7
|
+
import { CurveType } from '../models';
|
|
7
8
|
|
|
8
9
|
import BasicThreshold from './BasicThreshold';
|
|
9
10
|
|
|
10
11
|
interface Props {
|
|
12
|
+
curve: CurveType;
|
|
11
13
|
getX: (timeValue: TimeValue) => number;
|
|
12
14
|
getY0Variation: (timeValue: TimeValue) => number;
|
|
13
15
|
getY1Variation: (timeValue: TimeValue) => number;
|
|
@@ -24,7 +26,8 @@ const ThresholdWithVariation = ({
|
|
|
24
26
|
getY1Variation,
|
|
25
27
|
graphHeight,
|
|
26
28
|
lineColorY1,
|
|
27
|
-
lineColorY0
|
|
29
|
+
lineColorY0,
|
|
30
|
+
curve
|
|
28
31
|
}: Props): JSX.Element => {
|
|
29
32
|
const theme = useTheme();
|
|
30
33
|
|
|
@@ -40,6 +43,7 @@ const ThresholdWithVariation = ({
|
|
|
40
43
|
return (
|
|
41
44
|
<>
|
|
42
45
|
<BasicThreshold
|
|
46
|
+
curve={curve}
|
|
43
47
|
fillAboveArea={lineColorY1}
|
|
44
48
|
fillBelowArea={lineColorY0}
|
|
45
49
|
getX={getX}
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
VariationThreshold
|
|
8
8
|
} from '../../../models';
|
|
9
9
|
import { TimeValue } from '../../../timeSeries/models';
|
|
10
|
+
import { CurveType } from '../models';
|
|
10
11
|
|
|
11
12
|
import BasicThreshold from './BasicThreshold';
|
|
12
13
|
import Circle from './Circle';
|
|
@@ -16,6 +17,7 @@ import { WrapperThresholdLinesModel } from './models';
|
|
|
16
17
|
import useScaleThreshold from './useScaleThreshold';
|
|
17
18
|
|
|
18
19
|
interface Props extends WrapperThresholdLinesModel {
|
|
20
|
+
curve: CurveType;
|
|
19
21
|
graphHeight: number;
|
|
20
22
|
timeSeries: Array<TimeValue>;
|
|
21
23
|
}
|
|
@@ -27,7 +29,8 @@ const WrapperThresholdLines = ({
|
|
|
27
29
|
lines,
|
|
28
30
|
rightScale,
|
|
29
31
|
timeSeries,
|
|
30
|
-
xScale
|
|
32
|
+
xScale,
|
|
33
|
+
curve
|
|
31
34
|
}: Props): JSX.Element | null => {
|
|
32
35
|
const data = useScaleThreshold({
|
|
33
36
|
areaThresholdLines,
|
|
@@ -44,6 +47,7 @@ const WrapperThresholdLines = ({
|
|
|
44
47
|
const { getX, getY0, getY1, lineColorY0, lineColorY1, ...rest } = data;
|
|
45
48
|
|
|
46
49
|
const commonProps = {
|
|
50
|
+
curve,
|
|
47
51
|
fillAboveArea: lineColorY0,
|
|
48
52
|
fillBelowArea: lineColorY1,
|
|
49
53
|
getX,
|
|
@@ -19,8 +19,10 @@ import {
|
|
|
19
19
|
canDisplayThreshold,
|
|
20
20
|
requiredNumberLinesThreshold
|
|
21
21
|
} from './Threshold/models';
|
|
22
|
+
import { CurveType } from './models';
|
|
22
23
|
|
|
23
24
|
interface Props extends GlobalAreaLines {
|
|
25
|
+
curve: CurveType;
|
|
24
26
|
displayAnchor?: DisplayAnchor;
|
|
25
27
|
displayedLines: Array<Line>;
|
|
26
28
|
graphSvgRef: MutableRefObject<SVGSVGElement | null>;
|
|
@@ -44,7 +46,8 @@ const Lines = ({
|
|
|
44
46
|
displayedLines,
|
|
45
47
|
areaThresholdLines,
|
|
46
48
|
areaStackedLines,
|
|
47
|
-
areaRegularLines
|
|
49
|
+
areaRegularLines,
|
|
50
|
+
curve
|
|
48
51
|
}: Props): JSX.Element => {
|
|
49
52
|
const { stackedLinesData, invertedStackedLinesData } = useStackedLines({
|
|
50
53
|
lines: displayedLines,
|
|
@@ -67,6 +70,7 @@ const Lines = ({
|
|
|
67
70
|
|
|
68
71
|
const displayGuidingLines = displayAnchor?.displayGuidingLines ?? true;
|
|
69
72
|
const commonStackedLinesProps = {
|
|
73
|
+
curve,
|
|
70
74
|
displayAnchor: displayGuidingLines,
|
|
71
75
|
graphHeight: height,
|
|
72
76
|
graphSvgRef,
|
|
@@ -157,6 +161,7 @@ const Lines = ({
|
|
|
157
161
|
)}
|
|
158
162
|
<RegularLine
|
|
159
163
|
areaColor={areaColor}
|
|
164
|
+
curve={curve}
|
|
160
165
|
filled={filled}
|
|
161
166
|
graphHeight={height}
|
|
162
167
|
highlight={highlight}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ScaleLinear } from 'd3-scale';
|
|
2
|
+
import { curveBasis } from '@visx/curve';
|
|
2
3
|
|
|
3
4
|
import { GraphData } from '../../models';
|
|
4
5
|
import { Line, TimeValue } from '../../timeSeries/models';
|
|
@@ -40,3 +41,5 @@ export interface Shape {
|
|
|
40
41
|
areaStackedLines: AreaStackedLines;
|
|
41
42
|
areaThreshold: AreaThreshold;
|
|
42
43
|
}
|
|
44
|
+
|
|
45
|
+
export type CurveType = typeof curveBasis;
|
package/src/Graph/Graph.tsx
CHANGED
|
@@ -28,12 +28,15 @@ import {
|
|
|
28
28
|
} from './models';
|
|
29
29
|
import { getLeftScale, getRightScale, getXScale } from './timeSeries';
|
|
30
30
|
import { useIntersection } from './useGraphIntersection';
|
|
31
|
+
import { CurveType } from './BasicComponents/Lines/models';
|
|
31
32
|
|
|
32
33
|
interface Props extends GraphProps {
|
|
34
|
+
curve: CurveType;
|
|
33
35
|
graphData: Data;
|
|
34
36
|
graphInterval: GraphInterval;
|
|
35
37
|
graphRef: MutableRefObject<HTMLDivElement | null>;
|
|
36
38
|
legend?: LegendModel;
|
|
39
|
+
marginBottom: number;
|
|
37
40
|
shapeLines?: GlobalAreaLines;
|
|
38
41
|
}
|
|
39
42
|
|
|
@@ -52,15 +55,26 @@ const Graph = ({
|
|
|
52
55
|
tooltip,
|
|
53
56
|
legend,
|
|
54
57
|
graphRef,
|
|
55
|
-
header
|
|
58
|
+
header,
|
|
59
|
+
curve,
|
|
60
|
+
marginBottom
|
|
56
61
|
}: Props): JSX.Element => {
|
|
57
62
|
const graphSvgRef = useRef<SVGSVGElement | null>(null);
|
|
58
63
|
|
|
59
64
|
const { classes } = useStyles();
|
|
60
65
|
const { isInViewport } = useIntersection({ element: graphRef?.current });
|
|
61
66
|
|
|
67
|
+
const legendRef = useRef<HTMLDivElement | null>(null);
|
|
68
|
+
|
|
62
69
|
const graphWidth = width > 0 ? width - margin.left - margin.right : 0;
|
|
63
|
-
const graphHeight =
|
|
70
|
+
const graphHeight =
|
|
71
|
+
(height || 0) > 0
|
|
72
|
+
? (height || 0) -
|
|
73
|
+
margin.top -
|
|
74
|
+
margin.bottom -
|
|
75
|
+
marginBottom -
|
|
76
|
+
(legendRef.current?.getBoundingClientRect().height || 0)
|
|
77
|
+
: 0;
|
|
64
78
|
|
|
65
79
|
const { title, timeSeries, baseAxis, lines } = graphData;
|
|
66
80
|
|
|
@@ -83,7 +97,7 @@ const Graph = ({
|
|
|
83
97
|
getLeftScale({
|
|
84
98
|
dataLines: displayedLines,
|
|
85
99
|
dataTimeSeries: timeSeries,
|
|
86
|
-
valueGraphHeight: graphHeight
|
|
100
|
+
valueGraphHeight: graphHeight - 35
|
|
87
101
|
}),
|
|
88
102
|
[displayedLines, timeSeries, graphHeight]
|
|
89
103
|
);
|
|
@@ -93,7 +107,7 @@ const Graph = ({
|
|
|
93
107
|
getRightScale({
|
|
94
108
|
dataLines: displayedLines,
|
|
95
109
|
dataTimeSeries: timeSeries,
|
|
96
|
-
valueGraphHeight: graphHeight
|
|
110
|
+
valueGraphHeight: graphHeight - 35
|
|
97
111
|
}),
|
|
98
112
|
[timeSeries, displayedLines, graphHeight]
|
|
99
113
|
);
|
|
@@ -128,11 +142,15 @@ const Graph = ({
|
|
|
128
142
|
/>
|
|
129
143
|
<ClickAwayListener onClickAway={graphTooltipData?.hideTooltip}>
|
|
130
144
|
<div className={classes.container}>
|
|
131
|
-
<LoadingProgress
|
|
132
|
-
|
|
145
|
+
<LoadingProgress
|
|
146
|
+
display={loading}
|
|
147
|
+
height={graphHeight}
|
|
148
|
+
width={width}
|
|
149
|
+
/>
|
|
150
|
+
<svg height={graphHeight + margin.top} ref={graphSvgRef} width="100%">
|
|
133
151
|
<Group.Group left={margin.left} top={margin.top}>
|
|
134
152
|
<Grids
|
|
135
|
-
height={graphHeight}
|
|
153
|
+
height={graphHeight - margin.top}
|
|
136
154
|
leftScale={leftScale}
|
|
137
155
|
width={graphWidth}
|
|
138
156
|
xScale={xScale}
|
|
@@ -145,7 +163,7 @@ const Graph = ({
|
|
|
145
163
|
...axis
|
|
146
164
|
}}
|
|
147
165
|
graphInterval={graphInterval}
|
|
148
|
-
height={graphHeight}
|
|
166
|
+
height={graphHeight - margin.top}
|
|
149
167
|
leftScale={leftScale}
|
|
150
168
|
rightScale={rightScale}
|
|
151
169
|
width={graphWidth}
|
|
@@ -153,10 +171,11 @@ const Graph = ({
|
|
|
153
171
|
/>
|
|
154
172
|
|
|
155
173
|
<Lines
|
|
174
|
+
curve={curve}
|
|
156
175
|
displayAnchor={displayAnchor}
|
|
157
176
|
displayedLines={displayedLines}
|
|
158
177
|
graphSvgRef={graphSvgRef}
|
|
159
|
-
height={graphHeight}
|
|
178
|
+
height={graphHeight - margin.top}
|
|
160
179
|
leftScale={leftScale}
|
|
161
180
|
rightScale={rightScale}
|
|
162
181
|
timeSeries={timeSeries}
|
|
@@ -189,7 +208,7 @@ const Graph = ({
|
|
|
189
208
|
{(displayAnchor?.displayTooltipsGuidingLines ?? true) && (
|
|
190
209
|
<TooltipAnchorPoint
|
|
191
210
|
baseAxis={baseAxis}
|
|
192
|
-
graphHeight={graphHeight}
|
|
211
|
+
graphHeight={graphHeight - 35}
|
|
193
212
|
graphWidth={graphWidth}
|
|
194
213
|
leftScale={leftScale}
|
|
195
214
|
lines={displayedLines}
|
|
@@ -198,18 +217,19 @@ const Graph = ({
|
|
|
198
217
|
xScale={xScale}
|
|
199
218
|
/>
|
|
200
219
|
)}
|
|
201
|
-
|
|
202
|
-
{displayLegend && (
|
|
203
|
-
<Legend
|
|
204
|
-
base={baseAxis}
|
|
205
|
-
displayAnchor={displayAnchor?.displayGuidingLines ?? true}
|
|
206
|
-
lines={newLines}
|
|
207
|
-
renderExtraComponent={legend?.renderExtraComponent}
|
|
208
|
-
timeSeries={timeSeries}
|
|
209
|
-
/>
|
|
210
|
-
)}
|
|
211
220
|
</div>
|
|
212
221
|
</ClickAwayListener>
|
|
222
|
+
{displayLegend && (
|
|
223
|
+
<div ref={legendRef}>
|
|
224
|
+
<Legend
|
|
225
|
+
base={baseAxis}
|
|
226
|
+
displayAnchor={displayAnchor?.displayGuidingLines ?? true}
|
|
227
|
+
lines={newLines}
|
|
228
|
+
renderExtraComponent={legend?.renderExtraComponent}
|
|
229
|
+
timeSeries={timeSeries}
|
|
230
|
+
/>
|
|
231
|
+
</div>
|
|
232
|
+
)}
|
|
213
233
|
</>
|
|
214
234
|
);
|
|
215
235
|
};
|
|
@@ -43,17 +43,17 @@ const Header = ({
|
|
|
43
43
|
Component: (
|
|
44
44
|
<div className={classes.header}>
|
|
45
45
|
<div />
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
<div>
|
|
47
|
+
{displayTitle && (
|
|
48
48
|
<Typography align="center" variant="body1">
|
|
49
49
|
{title}
|
|
50
50
|
</Typography>
|
|
51
|
+
)}
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
)}
|
|
53
|
+
<Typography align="center" style={{ height: 20 }} variant="body1">
|
|
54
|
+
{time}
|
|
55
|
+
</Typography>
|
|
56
|
+
</div>
|
|
57
57
|
{header?.extraComponent}
|
|
58
58
|
</div>
|
|
59
59
|
),
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import { Tooltip } from '@visx/visx';
|
|
2
|
+
|
|
3
|
+
import { Typography, useTheme } from '@mui/material';
|
|
3
4
|
|
|
4
5
|
import useTooltipAnchorPoint from './useTooltipAnchorPoint';
|
|
5
|
-
import { useStyles } from './AnchorPoint.styles';
|
|
6
6
|
import { TooltipAnchorModel } from './models';
|
|
7
7
|
|
|
8
|
+
const baseStyles = {
|
|
9
|
+
...Tooltip.defaultStyles,
|
|
10
|
+
textAlign: 'center'
|
|
11
|
+
};
|
|
12
|
+
|
|
8
13
|
const TooltipAnchorPoint = ({
|
|
9
14
|
timeSeries,
|
|
10
15
|
xScale,
|
|
@@ -15,12 +20,13 @@ const TooltipAnchorPoint = ({
|
|
|
15
20
|
lines,
|
|
16
21
|
baseAxis
|
|
17
22
|
}: TooltipAnchorModel): JSX.Element => {
|
|
23
|
+
const theme = useTheme();
|
|
24
|
+
|
|
18
25
|
const {
|
|
19
26
|
tooltipDataAxisX,
|
|
20
27
|
tooltipDataAxisYLeft,
|
|
21
28
|
tooltipLeftAxisX,
|
|
22
29
|
tooltipLeftAxisYLeft,
|
|
23
|
-
tooltipTopAxisX,
|
|
24
30
|
tooltipTopAxisYLeft,
|
|
25
31
|
tooltipDataAxisYRight,
|
|
26
32
|
tooltipTopAxisYRight,
|
|
@@ -35,33 +41,53 @@ const TooltipAnchorPoint = ({
|
|
|
35
41
|
timeSeries,
|
|
36
42
|
xScale
|
|
37
43
|
});
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
tooltipTopAxisYRight
|
|
45
|
-
});
|
|
44
|
+
|
|
45
|
+
const cardStyles = {
|
|
46
|
+
backgroundColor: theme.palette.background.paper,
|
|
47
|
+
color: theme.palette.text.primary,
|
|
48
|
+
padding: theme.spacing(0.25, 0.5)
|
|
49
|
+
};
|
|
46
50
|
|
|
47
51
|
return (
|
|
48
52
|
<>
|
|
49
|
-
{tooltipDataAxisYLeft && (
|
|
50
|
-
<Paper className={cx(classes.tooltipAxis, classes.tooltipAxisLeftY)}>
|
|
51
|
-
<Typography variant="caption">{tooltipDataAxisYLeft}</Typography>
|
|
52
|
-
</Paper>
|
|
53
|
-
)}
|
|
54
53
|
{tooltipDataAxisX && (
|
|
55
|
-
<
|
|
54
|
+
<Tooltip.Tooltip
|
|
55
|
+
left={tooltipLeftAxisX}
|
|
56
|
+
style={{
|
|
57
|
+
...baseStyles,
|
|
58
|
+
...cardStyles,
|
|
59
|
+
transform: 'translateX(-70%)'
|
|
60
|
+
}}
|
|
61
|
+
top={0}
|
|
62
|
+
>
|
|
56
63
|
<Typography variant="caption">{tooltipDataAxisX}</Typography>
|
|
57
|
-
</
|
|
64
|
+
</Tooltip.Tooltip>
|
|
65
|
+
)}
|
|
66
|
+
{tooltipDataAxisYLeft && (
|
|
67
|
+
<Tooltip.Tooltip
|
|
68
|
+
left={tooltipLeftAxisYLeft}
|
|
69
|
+
style={{
|
|
70
|
+
...baseStyles,
|
|
71
|
+
...cardStyles,
|
|
72
|
+
transform: 'translateX(-70%) translateY(-100%)'
|
|
73
|
+
}}
|
|
74
|
+
top={tooltipTopAxisYLeft}
|
|
75
|
+
>
|
|
76
|
+
<Typography variant="caption">{tooltipDataAxisYLeft}</Typography>
|
|
77
|
+
</Tooltip.Tooltip>
|
|
58
78
|
)}
|
|
59
79
|
{tooltipDataAxisYRight && (
|
|
60
|
-
<
|
|
61
|
-
|
|
80
|
+
<Tooltip.Tooltip
|
|
81
|
+
left={tooltipLeftAxisYRight}
|
|
82
|
+
style={{
|
|
83
|
+
...baseStyles,
|
|
84
|
+
...cardStyles,
|
|
85
|
+
transform: 'translateX(-70%) translateY(-80%)'
|
|
86
|
+
}}
|
|
87
|
+
top={tooltipTopAxisYRight}
|
|
62
88
|
>
|
|
63
89
|
<Typography variant="caption">{tooltipDataAxisYRight}</Typography>
|
|
64
|
-
</
|
|
90
|
+
</Tooltip.Tooltip>
|
|
65
91
|
)}
|
|
66
92
|
</>
|
|
67
93
|
);
|
|
@@ -1,20 +1,22 @@
|
|
|
1
|
+
import { alpha } from '@mui/system';
|
|
2
|
+
|
|
1
3
|
interface Props {
|
|
2
4
|
lineColor: string;
|
|
3
5
|
x: number;
|
|
4
6
|
y: number;
|
|
5
7
|
}
|
|
6
8
|
|
|
7
|
-
const Point = ({ lineColor, x, y }: Props): JSX.Element =>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
9
|
+
const Point = ({ lineColor, x, y }: Props): JSX.Element => (
|
|
10
|
+
<circle
|
|
11
|
+
fill={alpha(lineColor, 0.5)}
|
|
12
|
+
r={4}
|
|
13
|
+
stroke={lineColor}
|
|
14
|
+
strokeWidth={2}
|
|
15
|
+
style={{
|
|
16
|
+
transform: `translate(${x}px, ${y}px)`,
|
|
17
|
+
transition: 'transform 0.08s ease-out'
|
|
18
|
+
}}
|
|
19
|
+
/>
|
|
20
|
+
);
|
|
19
21
|
|
|
20
22
|
export default Point;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useEffect, useState } from 'react';
|
|
2
2
|
|
|
3
3
|
import { Meta, StoryObj } from '@storybook/react';
|
|
4
|
+
import { Curve } from '@visx/visx';
|
|
4
5
|
|
|
5
6
|
import { Button } from '@mui/material';
|
|
6
7
|
import ButtonGroup from '@mui/material/ButtonGroup';
|
|
@@ -335,6 +336,15 @@ export const Graph: Story = {
|
|
|
335
336
|
args: argumentsData
|
|
336
337
|
};
|
|
337
338
|
|
|
339
|
+
export const GraphWithStepCurve: Story = {
|
|
340
|
+
...Template,
|
|
341
|
+
argTypes,
|
|
342
|
+
args: {
|
|
343
|
+
...argumentsData,
|
|
344
|
+
curve: Curve.curveStep
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
|
|
338
348
|
export const GraphWithTimePeriod: Story = {
|
|
339
349
|
...WithTimePeriod,
|
|
340
350
|
args: {
|
package/src/Graph/index.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MutableRefObject, useRef } from 'react';
|
|
2
2
|
|
|
3
|
-
import { Responsive } from '@visx/visx';
|
|
3
|
+
import { Curve, Responsive } from '@visx/visx';
|
|
4
4
|
import dayjs from 'dayjs';
|
|
5
5
|
import 'dayjs/locale/en';
|
|
6
6
|
import 'dayjs/locale/es';
|
|
@@ -14,16 +14,19 @@ import Graph from './Graph';
|
|
|
14
14
|
import LoadingSkeleton from './LoadingSkeleton';
|
|
15
15
|
import { GlobalAreaLines, GraphData, GraphProps, LegendModel } from './models';
|
|
16
16
|
import useGraphData from './useGraphData';
|
|
17
|
+
import { CurveType } from './BasicComponents/Lines/models';
|
|
17
18
|
|
|
18
19
|
dayjs.extend(localizedFormat);
|
|
19
20
|
dayjs.extend(utcPlugin);
|
|
20
21
|
dayjs.extend(timezonePlugin);
|
|
21
22
|
|
|
22
23
|
interface Props extends Partial<GraphProps> {
|
|
24
|
+
curve?: CurveType;
|
|
23
25
|
data?: GraphData;
|
|
24
26
|
end: string;
|
|
25
27
|
legend: LegendModel;
|
|
26
28
|
loading: boolean;
|
|
29
|
+
marginBottom?: number;
|
|
27
30
|
shapeLines?: GlobalAreaLines;
|
|
28
31
|
start: string;
|
|
29
32
|
}
|
|
@@ -43,7 +46,9 @@ const WrapperGraph = ({
|
|
|
43
46
|
tooltip,
|
|
44
47
|
annotationEvent,
|
|
45
48
|
legend,
|
|
46
|
-
header
|
|
49
|
+
header,
|
|
50
|
+
curve = Curve.curveLinear,
|
|
51
|
+
marginBottom = 0
|
|
47
52
|
}: Props): JSX.Element | null => {
|
|
48
53
|
const { adjustedData } = useGraphData({ data, end, start });
|
|
49
54
|
const graphRef = useRef<HTMLDivElement | null>(null);
|
|
@@ -52,36 +57,43 @@ const WrapperGraph = ({
|
|
|
52
57
|
return (
|
|
53
58
|
<LoadingSkeleton
|
|
54
59
|
displayTitleSkeleton={header?.displayTitle ?? true}
|
|
55
|
-
graphHeight={height}
|
|
60
|
+
graphHeight={height || 200}
|
|
56
61
|
/>
|
|
57
62
|
);
|
|
58
63
|
}
|
|
59
64
|
|
|
60
65
|
return (
|
|
61
|
-
<div
|
|
66
|
+
<div
|
|
67
|
+
ref={graphRef as MutableRefObject<HTMLDivElement>}
|
|
68
|
+
style={{ height: '100%', width: '100%' }}
|
|
69
|
+
>
|
|
62
70
|
<Responsive.ParentSize>
|
|
63
71
|
{({
|
|
64
72
|
height: responsiveHeight,
|
|
65
73
|
width: responsiveWidth
|
|
66
|
-
}): JSX.Element =>
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
74
|
+
}): JSX.Element => {
|
|
75
|
+
return (
|
|
76
|
+
<Graph
|
|
77
|
+
annotationEvent={annotationEvent}
|
|
78
|
+
axis={axis}
|
|
79
|
+
curve={curve}
|
|
80
|
+
displayAnchor={displayAnchor}
|
|
81
|
+
graphData={adjustedData}
|
|
82
|
+
graphInterval={{ end, start }}
|
|
83
|
+
graphRef={graphRef}
|
|
84
|
+
header={header}
|
|
85
|
+
height={height || responsiveHeight}
|
|
86
|
+
legend={legend}
|
|
87
|
+
loading={loading}
|
|
88
|
+
marginBottom={marginBottom}
|
|
89
|
+
shapeLines={shapeLines}
|
|
90
|
+
timeShiftZones={timeShiftZones}
|
|
91
|
+
tooltip={tooltip}
|
|
92
|
+
width={width ?? responsiveWidth}
|
|
93
|
+
zoomPreview={zoomPreview}
|
|
94
|
+
/>
|
|
95
|
+
);
|
|
96
|
+
}}
|
|
85
97
|
</Responsive.ParentSize>
|
|
86
98
|
</div>
|
|
87
99
|
);
|
package/src/Graph/models.ts
CHANGED
|
@@ -37,6 +37,7 @@ export interface ConnectedAutoCompleteFieldProps<TData> {
|
|
|
37
37
|
getRequestHeaders?: HeadersInit;
|
|
38
38
|
initialPage: number;
|
|
39
39
|
labelKey?: string;
|
|
40
|
+
queryKey?: string;
|
|
40
41
|
searchConditions?: Array<ConditionsSearchParameter>;
|
|
41
42
|
}
|
|
42
43
|
|
|
@@ -55,6 +56,7 @@ const ConnectedAutocompleteField = (
|
|
|
55
56
|
getRenderedOptionText = (option): string => option.name?.toString(),
|
|
56
57
|
getRequestHeaders,
|
|
57
58
|
displayOptionThumbnail,
|
|
59
|
+
queryKey,
|
|
58
60
|
...props
|
|
59
61
|
}: ConnectedAutoCompleteFieldProps<TData> &
|
|
60
62
|
Omit<AutocompleteFieldProps, 'options'>): JSX.Element => {
|
|
@@ -89,10 +91,16 @@ const ConnectedAutocompleteField = (
|
|
|
89
91
|
search: searchParameter
|
|
90
92
|
});
|
|
91
93
|
},
|
|
92
|
-
getQueryKey: () => [
|
|
94
|
+
getQueryKey: () => [
|
|
95
|
+
`autocomplete-${queryKey || props.label}`,
|
|
96
|
+
page,
|
|
97
|
+
searchParameter
|
|
98
|
+
],
|
|
93
99
|
isPaginated: true,
|
|
94
100
|
queryOptions: {
|
|
101
|
+
cacheTime: 0,
|
|
95
102
|
enabled: false,
|
|
103
|
+
staleTime: 0,
|
|
96
104
|
suspense: false
|
|
97
105
|
}
|
|
98
106
|
});
|
|
@@ -34,12 +34,17 @@ export interface Props
|
|
|
34
34
|
'multiple'
|
|
35
35
|
> {
|
|
36
36
|
disableSortedOptions?: boolean;
|
|
37
|
+
getTagLabel?: (option) => string;
|
|
38
|
+
optionProperty?: string;
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
const MultiAutocompleteField = ({
|
|
40
42
|
value,
|
|
41
43
|
options,
|
|
42
44
|
disableSortedOptions = false,
|
|
45
|
+
optionProperty = 'name',
|
|
46
|
+
getOptionLabel = (option): string => option.name,
|
|
47
|
+
getTagLabel = (option): string => option[optionProperty],
|
|
43
48
|
...props
|
|
44
49
|
}: Props): JSX.Element => {
|
|
45
50
|
const { classes } = useStyles();
|
|
@@ -52,7 +57,7 @@ const MultiAutocompleteField = ({
|
|
|
52
57
|
root: classes.tag
|
|
53
58
|
}}
|
|
54
59
|
key={option.id}
|
|
55
|
-
label={option
|
|
60
|
+
label={getTagLabel(option)}
|
|
56
61
|
size="medium"
|
|
57
62
|
{...getTagProps({ index })}
|
|
58
63
|
/>
|
|
@@ -84,7 +89,7 @@ const MultiAutocompleteField = ({
|
|
|
84
89
|
key={option.id}
|
|
85
90
|
{...(renderProps as React.HTMLAttributes<HTMLLIElement>)}
|
|
86
91
|
>
|
|
87
|
-
<Option checkboxSelected={selected}>{option
|
|
92
|
+
<Option checkboxSelected={selected}>{getOptionLabel(option)}</Option>
|
|
88
93
|
</li>
|
|
89
94
|
)}
|
|
90
95
|
renderTags={renderTags}
|
package/src/Panel/index.tsx
CHANGED
|
@@ -226,7 +226,9 @@ const Panel = React.forwardRef(
|
|
|
226
226
|
className={classes.contentContainer}
|
|
227
227
|
ref={ref as React.RefObject<HTMLDivElement>}
|
|
228
228
|
>
|
|
229
|
-
<div className={classes.content}>
|
|
229
|
+
<div className={classes.content} id="panel-content">
|
|
230
|
+
{selectedTab}
|
|
231
|
+
</div>
|
|
230
232
|
</div>
|
|
231
233
|
</div>
|
|
232
234
|
</Paper>
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { T, always, cond, flatten, isEmpty, join, pipe, pluck } from 'ramda';
|
|
2
|
+
import dayjs from 'dayjs';
|
|
3
|
+
|
|
4
|
+
import { GraphData, useFetchQuery } from '../..';
|
|
5
|
+
|
|
6
|
+
import { ServiceMetric } from './models';
|
|
7
|
+
|
|
8
|
+
interface UseMetricsQueryProps {
|
|
9
|
+
baseEndpoint: string;
|
|
10
|
+
metrics: Array<ServiceMetric>;
|
|
11
|
+
timePeriod?: TimePeriod;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface UseMetricsQueryState {
|
|
15
|
+
end: string;
|
|
16
|
+
graphData: GraphData | undefined;
|
|
17
|
+
isGraphLoading: boolean;
|
|
18
|
+
isMetricIdsEmpty: boolean;
|
|
19
|
+
start: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
enum TimePeriod {
|
|
23
|
+
lastDay = 'last_day'
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const getStartEndFromTimePeriod = (
|
|
27
|
+
timePeriod: TimePeriod
|
|
28
|
+
): { end: string; start: string } => {
|
|
29
|
+
return cond([
|
|
30
|
+
[
|
|
31
|
+
T,
|
|
32
|
+
always({
|
|
33
|
+
end: dayjs().toISOString(),
|
|
34
|
+
start: dayjs().subtract(1, 'day').toISOString()
|
|
35
|
+
})
|
|
36
|
+
]
|
|
37
|
+
])(timePeriod);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
interface PerformanceGraphData extends Omit<GraphData, 'global'> {
|
|
41
|
+
base: number;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const useGraphQuery = ({
|
|
45
|
+
metrics,
|
|
46
|
+
baseEndpoint,
|
|
47
|
+
timePeriod = TimePeriod.lastDay
|
|
48
|
+
}: UseMetricsQueryProps): UseMetricsQueryState => {
|
|
49
|
+
const metricIds = pipe(
|
|
50
|
+
pluck('metrics'),
|
|
51
|
+
flatten,
|
|
52
|
+
pluck('id'),
|
|
53
|
+
join(',')
|
|
54
|
+
)(metrics);
|
|
55
|
+
|
|
56
|
+
const { end, start } = getStartEndFromTimePeriod(timePeriod);
|
|
57
|
+
|
|
58
|
+
const {
|
|
59
|
+
data: graphData,
|
|
60
|
+
isFetching,
|
|
61
|
+
isLoading
|
|
62
|
+
} = useFetchQuery<PerformanceGraphData>({
|
|
63
|
+
getEndpoint: () =>
|
|
64
|
+
`${baseEndpoint}?metricIds=[${metricIds}]&start=${start}&end=${end}`,
|
|
65
|
+
getQueryKey: () => ['graph', metricIds],
|
|
66
|
+
queryOptions: {
|
|
67
|
+
enabled: !isEmpty(metricIds),
|
|
68
|
+
suspense: false
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const formattedGraphData = graphData
|
|
73
|
+
? {
|
|
74
|
+
global: {
|
|
75
|
+
base: graphData.base,
|
|
76
|
+
title: ''
|
|
77
|
+
},
|
|
78
|
+
metrics: graphData.metrics,
|
|
79
|
+
times: graphData.times
|
|
80
|
+
}
|
|
81
|
+
: undefined;
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
end,
|
|
85
|
+
graphData: formattedGraphData,
|
|
86
|
+
isGraphLoading: isFetching || (isLoading && !isEmpty(metricIds)),
|
|
87
|
+
isMetricIdsEmpty: isEmpty(metricIds),
|
|
88
|
+
start
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export default useGraphQuery;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
|
|
3
|
+
import CloseIcon from '@mui/icons-material/Close';
|
|
4
|
+
|
|
5
|
+
import { IconButton } from '..';
|
|
6
|
+
|
|
7
|
+
import { useItemStyles } from './ItemComposition.styles';
|
|
8
|
+
|
|
9
|
+
type Props = {
|
|
10
|
+
children: Array<ReactElement>;
|
|
11
|
+
className?: string;
|
|
12
|
+
labelDelete: string;
|
|
13
|
+
onDeleteItem: () => void;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const Item = ({
|
|
17
|
+
onDeleteItem,
|
|
18
|
+
children,
|
|
19
|
+
labelDelete,
|
|
20
|
+
className
|
|
21
|
+
}: Props): JSX.Element => {
|
|
22
|
+
const { classes, cx } = useItemStyles();
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<div className={classes.itemContainer}>
|
|
26
|
+
<div className={cx(classes.itemContent, className)}>{children}</div>
|
|
27
|
+
<IconButton
|
|
28
|
+
aria-label={labelDelete}
|
|
29
|
+
data-testid={labelDelete}
|
|
30
|
+
icon={<CloseIcon />}
|
|
31
|
+
size="small"
|
|
32
|
+
variant="ghost"
|
|
33
|
+
onClick={onDeleteItem}
|
|
34
|
+
/>
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/* eslint-disable react/no-array-index-key */
|
|
2
|
+
import { Meta, StoryObj } from '@storybook/react';
|
|
3
|
+
|
|
4
|
+
import { Typography } from '@mui/material';
|
|
5
|
+
|
|
6
|
+
import { SelectField } from '../..';
|
|
7
|
+
|
|
8
|
+
import { ItemComposition } from '.';
|
|
9
|
+
|
|
10
|
+
const meta: Meta<typeof ItemComposition> = {
|
|
11
|
+
component: ItemComposition
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default meta;
|
|
15
|
+
type Story = StoryObj<typeof ItemComposition>;
|
|
16
|
+
|
|
17
|
+
const stub = (): void => undefined;
|
|
18
|
+
|
|
19
|
+
export const Default: Story = {
|
|
20
|
+
args: {
|
|
21
|
+
children: [...Array(5)].map((_, i) => (
|
|
22
|
+
<ItemComposition.Item key={i} labelDelete="Delete" onDeleteItem={stub}>
|
|
23
|
+
<Typography>Item 1</Typography>
|
|
24
|
+
<Typography>Item 2</Typography>
|
|
25
|
+
</ItemComposition.Item>
|
|
26
|
+
)),
|
|
27
|
+
labelAdd: 'Add',
|
|
28
|
+
onAddItem: stub
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const Empty: Story = {
|
|
33
|
+
args: {
|
|
34
|
+
children: [],
|
|
35
|
+
labelAdd: 'Add',
|
|
36
|
+
onAddItem: stub
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const options = [
|
|
41
|
+
{
|
|
42
|
+
id: 1,
|
|
43
|
+
name: 'Test select 1'
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: 2,
|
|
47
|
+
name: 'Test select 2'
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: 3,
|
|
51
|
+
name: 'Test select 3'
|
|
52
|
+
}
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
export const WithSelectInputs: Story = {
|
|
56
|
+
args: {
|
|
57
|
+
children: [...Array(5)].map((_, i) => (
|
|
58
|
+
<ItemComposition.Item key={i} labelDelete="Delete" onDeleteItem={stub}>
|
|
59
|
+
<SelectField
|
|
60
|
+
dataTestId="select 1"
|
|
61
|
+
label="select 1"
|
|
62
|
+
options={options}
|
|
63
|
+
selectedOptionId={1}
|
|
64
|
+
onChange={stub}
|
|
65
|
+
/>
|
|
66
|
+
<SelectField
|
|
67
|
+
dataTestId="select 2"
|
|
68
|
+
label="select 2"
|
|
69
|
+
options={options}
|
|
70
|
+
selectedOptionId={2}
|
|
71
|
+
onChange={stub}
|
|
72
|
+
/>
|
|
73
|
+
</ItemComposition.Item>
|
|
74
|
+
)),
|
|
75
|
+
labelAdd: 'Add',
|
|
76
|
+
onAddItem: stub
|
|
77
|
+
}
|
|
78
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { makeStyles } from 'tss-react/mui';
|
|
2
|
+
|
|
3
|
+
export const useItemCompositionStyles = makeStyles()((theme) => ({
|
|
4
|
+
itemCompositionContainer: {
|
|
5
|
+
alignItems: 'flex-start',
|
|
6
|
+
display: 'flex',
|
|
7
|
+
flexDirection: 'column',
|
|
8
|
+
gap: theme.spacing(2),
|
|
9
|
+
width: '100%'
|
|
10
|
+
}
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
export const useItemStyles = makeStyles()((theme) => ({
|
|
14
|
+
itemContainer: {
|
|
15
|
+
alignItems: 'center',
|
|
16
|
+
display: 'flex',
|
|
17
|
+
flexDirection: 'row',
|
|
18
|
+
gap: theme.spacing(1),
|
|
19
|
+
width: '100%'
|
|
20
|
+
},
|
|
21
|
+
itemContent: {
|
|
22
|
+
display: 'flex',
|
|
23
|
+
flexDirection: 'row',
|
|
24
|
+
width: '100%'
|
|
25
|
+
}
|
|
26
|
+
}));
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
|
|
3
|
+
import AddIcon from '@mui/icons-material/Add';
|
|
4
|
+
|
|
5
|
+
import { Button } from '..';
|
|
6
|
+
|
|
7
|
+
import { useItemCompositionStyles } from './ItemComposition.styles';
|
|
8
|
+
|
|
9
|
+
type Props = {
|
|
10
|
+
addbuttonDisabled?: boolean;
|
|
11
|
+
children: Array<ReactElement>;
|
|
12
|
+
labelAdd: string;
|
|
13
|
+
onAddItem: () => void;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const ItemComposition = ({
|
|
17
|
+
onAddItem,
|
|
18
|
+
children,
|
|
19
|
+
labelAdd,
|
|
20
|
+
addbuttonDisabled
|
|
21
|
+
}: Props): JSX.Element => {
|
|
22
|
+
const { classes } = useItemCompositionStyles();
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<div className={classes.itemCompositionContainer}>
|
|
26
|
+
{children}
|
|
27
|
+
<Button
|
|
28
|
+
aria-label={labelAdd}
|
|
29
|
+
data-testid={labelAdd}
|
|
30
|
+
disabled={addbuttonDisabled}
|
|
31
|
+
icon={<AddIcon />}
|
|
32
|
+
iconVariant="start"
|
|
33
|
+
size="small"
|
|
34
|
+
variant="ghost"
|
|
35
|
+
onClick={onAddItem}
|
|
36
|
+
>
|
|
37
|
+
{labelAdd}
|
|
38
|
+
</Button>
|
|
39
|
+
</div>
|
|
40
|
+
);
|
|
41
|
+
};
|
package/src/components/index.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -123,6 +123,7 @@ export type {
|
|
|
123
123
|
export { default as Responsive } from './Responsive';
|
|
124
124
|
export { default as useFetchQuery } from './api/useFetchQuery';
|
|
125
125
|
export { default as useMutationQuery, Method } from './api/useMutationQuery';
|
|
126
|
+
export { default as useGraphQuery } from './api/useGraphQuery';
|
|
126
127
|
export { default as QueryProvider } from './api/QueryProvider';
|
|
127
128
|
export {
|
|
128
129
|
default as FileDropZone,
|
|
@@ -143,3 +144,5 @@ export type { ResponseError, CatchErrorProps } from './api/customFetch';
|
|
|
143
144
|
export * from './utils';
|
|
144
145
|
export { default as FluidTypography } from './Typography/FluidTypography';
|
|
145
146
|
export * from './Dashboard';
|
|
147
|
+
export { default as Graph } from './Graph';
|
|
148
|
+
export type { GraphData } from './Graph/models';
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { makeStyles } from 'tss-react/mui';
|
|
2
|
-
|
|
3
|
-
interface StylesProps {
|
|
4
|
-
tooltipLeftAxisX?: number;
|
|
5
|
-
tooltipLeftAxisYLeft?: number;
|
|
6
|
-
tooltipLeftAxisYRight?: number;
|
|
7
|
-
tooltipTopAxisX?: number;
|
|
8
|
-
tooltipTopAxisYLeft?: number;
|
|
9
|
-
tooltipTopAxisYRight?: number;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export const useStyles = makeStyles<StylesProps>()(
|
|
13
|
-
(
|
|
14
|
-
theme,
|
|
15
|
-
{
|
|
16
|
-
tooltipLeftAxisX,
|
|
17
|
-
tooltipTopAxisX,
|
|
18
|
-
tooltipLeftAxisYLeft,
|
|
19
|
-
tooltipTopAxisYLeft,
|
|
20
|
-
tooltipLeftAxisYRight,
|
|
21
|
-
tooltipTopAxisYRight
|
|
22
|
-
}
|
|
23
|
-
) => ({
|
|
24
|
-
tooltipAxis: {
|
|
25
|
-
'& > span': {
|
|
26
|
-
fontSize: 'inherit',
|
|
27
|
-
fontWeight: 'inherit',
|
|
28
|
-
lineHeight: 'inherit'
|
|
29
|
-
},
|
|
30
|
-
backgroundColor: theme.palette.background.tooltip,
|
|
31
|
-
border: 'unset',
|
|
32
|
-
borderRadius: theme.spacing(0.25),
|
|
33
|
-
color: theme.palette.primary.contrastText,
|
|
34
|
-
fontSize: '10px',
|
|
35
|
-
fontWeight: 500,
|
|
36
|
-
letterSpacing: '0.15px',
|
|
37
|
-
lineHeight: '100%',
|
|
38
|
-
padding: theme.spacing(0.375, 0.5),
|
|
39
|
-
position: 'absolute',
|
|
40
|
-
textAlign: 'center',
|
|
41
|
-
transform: 'translate(-50%, -50%)',
|
|
42
|
-
transformOrigin: 'center center',
|
|
43
|
-
transition: 'unset'
|
|
44
|
-
},
|
|
45
|
-
tooltipAxisBottom: {
|
|
46
|
-
left: tooltipLeftAxisX ?? 0,
|
|
47
|
-
top: tooltipTopAxisX ?? 0
|
|
48
|
-
},
|
|
49
|
-
tooltipAxisLeftY: {
|
|
50
|
-
left: tooltipLeftAxisYLeft ?? 0,
|
|
51
|
-
top: tooltipTopAxisYLeft ?? 0
|
|
52
|
-
},
|
|
53
|
-
tooltipLeftAxisRightY: {
|
|
54
|
-
left: tooltipLeftAxisYRight ?? 0,
|
|
55
|
-
top: tooltipTopAxisYRight ?? 0
|
|
56
|
-
}
|
|
57
|
-
})
|
|
58
|
-
);
|