@centreon/ui 23.10.1-sync-dev-23-10-x-develop-oss.0 → 23.10.1-sync-release-34346.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -1
- package/public/mockServiceWorker.js +2 -2
- package/src/Form/Inputs/ConnectedAutocomplete.tsx +3 -1
- package/src/Form/Inputs/models.ts +1 -0
- package/src/Graph/Gauge/Gauge.stories.tsx +15 -2
- package/src/Graph/HeatMap/HeatMap.stories.tsx +105 -0
- package/src/Graph/HeatMap/HeatMap.styles.tsx +29 -0
- package/src/Graph/HeatMap/HeatMap.tsx +12 -0
- package/src/Graph/HeatMap/HeatMapData.json +137 -0
- package/src/Graph/HeatMap/ResponsiveHeatMap.tsx +98 -0
- package/src/Graph/HeatMap/index.ts +1 -0
- package/src/Graph/HeatMap/model.ts +33 -0
- package/src/Graph/LineChart/BasicComponents/Lines/RegularLines/index.tsx +1 -1
- package/src/Graph/LineChart/BasicComponents/useFilterLines.ts +2 -4
- package/src/Graph/LineChart/Legend/InteractiveValue.tsx +3 -3
- package/src/Graph/LineChart/Legend/Legend.styles.ts +78 -32
- package/src/Graph/LineChart/Legend/LegendContent.tsx +12 -6
- package/src/Graph/LineChart/Legend/LegendHeader.tsx +69 -21
- package/src/Graph/LineChart/Legend/index.tsx +51 -23
- package/src/Graph/LineChart/Legend/models.ts +5 -0
- package/src/Graph/LineChart/Legend/useLegend.ts +9 -10
- package/src/Graph/LineChart/LineChart.tsx +17 -3
- package/src/Graph/index.ts +1 -0
- package/src/InputField/Select/Autocomplete/Connected/Multi/index.test.tsx +1 -0
- package/src/InputField/Select/Autocomplete/Connected/index.test.tsx +1 -0
- package/src/InputField/Select/Autocomplete/Connected/index.tsx +15 -3
- package/src/InputField/Text/index.tsx +6 -1
- package/src/Module/LicensedModule/LicenseCheck/index.tsx +24 -9
- package/src/Module/LicensedModule/index.tsx +7 -1
- package/src/RichTextEditor/RichTextEditor.cypress.spec.tsx +100 -52
- package/src/RichTextEditor/RichTextEditor.tsx +9 -3
- package/src/RichTextEditor/plugins/ToolbarPlugin/AlignPicker.tsx +21 -20
- package/src/RichTextEditor/plugins/ToolbarPlugin/BlockButtons.tsx +35 -77
- package/src/RichTextEditor/plugins/ToolbarPlugin/FormatButtons.tsx +29 -83
- package/src/RichTextEditor/plugins/ToolbarPlugin/LinkButton.tsx +106 -0
- package/src/RichTextEditor/plugins/ToolbarPlugin/ListButton.tsx +155 -0
- package/src/RichTextEditor/plugins/ToolbarPlugin/MacrosButton.tsx +23 -39
- package/src/RichTextEditor/plugins/ToolbarPlugin/ToolbarPlugin.styles.ts +24 -14
- package/src/RichTextEditor/plugins/ToolbarPlugin/UndoRedoButtons.tsx +6 -0
- package/src/RichTextEditor/plugins/ToolbarPlugin/index.tsx +5 -10
- package/src/RichTextEditor/translatedLabels.ts +3 -0
- package/src/ThemeProvider/palettes.ts +4 -4
- package/src/Typography/EllipsisTypography.tsx +18 -0
- package/src/Typography/Subtitle.tsx +55 -0
- package/src/api/buildListingEndpoint/models.ts +2 -1
- package/src/api/customFetch.ts +12 -3
- package/src/api/useFetchQuery/index.ts +22 -5
- package/src/api/useGraphQuery/index.ts +4 -1
- package/src/api/useMutationQuery/index.ts +12 -2
- package/src/components/Form/AccessRightsV2/AccessRights.cypress.spec.tsx +350 -0
- package/src/components/Form/AccessRightsV2/AccessRights.stories.tsx +119 -0
- package/src/components/Form/AccessRightsV2/AccessRights.styles.ts +10 -0
- package/src/components/Form/AccessRightsV2/AccessRights.tsx +60 -0
- package/src/components/Form/AccessRightsV2/Actions/Actions.styles.ts +14 -0
- package/src/components/Form/AccessRightsV2/Actions/Actions.tsx +81 -0
- package/src/components/Form/AccessRightsV2/Actions/useActions.ts +79 -0
- package/src/components/Form/AccessRightsV2/List/Item.tsx +90 -0
- package/src/components/Form/AccessRightsV2/List/List.styles.tsx +45 -0
- package/src/components/Form/AccessRightsV2/List/List.tsx +52 -0
- package/src/components/Form/AccessRightsV2/List/ListItemSkeleton.tsx +18 -0
- package/src/components/Form/AccessRightsV2/List/ListSkeleton.tsx +22 -0
- package/src/components/Form/AccessRightsV2/List/RemoveAccessRight.tsx +38 -0
- package/src/components/Form/AccessRightsV2/List/StateChip.tsx +28 -0
- package/src/components/Form/AccessRightsV2/List/useItem.ts +64 -0
- package/src/components/Form/AccessRightsV2/Provider.tsx +15 -0
- package/src/components/Form/AccessRightsV2/ShareInput/ContactSwitch.tsx +42 -0
- package/src/components/Form/AccessRightsV2/ShareInput/ShareInput.styles.ts +9 -0
- package/src/components/Form/AccessRightsV2/ShareInput/ShareInput.tsx +77 -0
- package/src/components/Form/AccessRightsV2/ShareInput/useShareInput.tsx +109 -0
- package/src/components/Form/AccessRightsV2/Stats/Stats.tsx +36 -0
- package/src/components/Form/AccessRightsV2/atoms.ts +97 -0
- package/src/components/Form/AccessRightsV2/common/RoleSelectField.styles.tsx +7 -0
- package/src/components/Form/AccessRightsV2/common/RoleSelectField.tsx +45 -0
- package/src/components/Form/AccessRightsV2/models.ts +54 -0
- package/src/components/Form/AccessRightsV2/storiesData.ts +221 -0
- package/src/components/Form/AccessRightsV2/useAccessRightsInitValues.ts +51 -0
- package/src/components/Form/index.ts +1 -0
- package/src/components/Header/PageHeader/PageHeader.styles.ts +28 -1
- package/src/components/Header/PageHeader/PageHeaderMessage.tsx +32 -0
- package/src/components/Header/PageHeader/index.ts +2 -0
- package/src/components/ItemComposition/Item.tsx +2 -2
- package/src/components/ItemComposition/ItemComposition.styles.ts +3 -0
- package/src/components/ItemComposition/ItemComposition.tsx +4 -2
- package/src/components/List/Item/ListItem.styles.ts +6 -0
- package/src/components/List/Item/ListItem.tsx +3 -1
- package/src/components/List/Item/Text.tsx +5 -3
- package/src/components/Menu/Button/MenuButton.tsx +4 -2
- package/src/components/Menu/MenuItem.tsx +5 -3
- package/src/components/Menu/MenuItems.tsx +4 -3
- package/src/components/Modal/Modal.styles.ts +4 -2
- package/src/index.ts +5 -0
- package/src/utils/useInfiniteScrollListing.ts +22 -7
- package/src/utils/useLocaleDateTimeFormat/index.ts +3 -0
- package/src/Graph/LineChart/Legend/Marker.tsx +0 -43
|
@@ -6,66 +6,112 @@ interface MakeStylesProps {
|
|
|
6
6
|
limitLegendRows?: boolean;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
export const legendWidth = 21;
|
|
10
|
+
const legendItemHeight = 5.25;
|
|
11
|
+
const legendItemHeightCompact = 1.75;
|
|
12
|
+
|
|
9
13
|
export const useStyles = makeStyles<MakeStylesProps>()(
|
|
10
14
|
(theme, { limitLegendRows }) => ({
|
|
11
15
|
highlight: {
|
|
12
16
|
color: theme.typography.body1.color
|
|
13
17
|
},
|
|
14
18
|
item: {
|
|
15
|
-
|
|
16
|
-
gridTemplateColumns: 'min-content minmax(50px, 1fr)',
|
|
17
|
-
marginBottom: theme.spacing(1)
|
|
19
|
+
minWidth: theme.spacing(legendWidth)
|
|
18
20
|
},
|
|
19
21
|
items: {
|
|
22
|
+
'&[data-mode="compact"]': {
|
|
23
|
+
gridAutoRows: theme.spacing(legendItemHeightCompact),
|
|
24
|
+
height: limitLegendRows
|
|
25
|
+
? theme.spacing(legendItemHeightCompact * 2 + 1.5)
|
|
26
|
+
: 'unset'
|
|
27
|
+
},
|
|
28
|
+
columnGap: theme.spacing(3),
|
|
20
29
|
display: 'grid',
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
maxHeight: limitLegendRows
|
|
30
|
+
gridAutoRows: theme.spacing(legendItemHeight),
|
|
31
|
+
gridTemplateColumns: `repeat(auto-fit, ${theme.spacing(legendWidth)})`,
|
|
32
|
+
maxHeight: limitLegendRows
|
|
33
|
+
? theme.spacing(legendItemHeight * 2 + 1)
|
|
34
|
+
: 'unset',
|
|
24
35
|
overflowY: 'auto',
|
|
36
|
+
rowGap: theme.spacing(1),
|
|
25
37
|
width: '100%'
|
|
26
38
|
},
|
|
27
39
|
legend: {
|
|
28
40
|
marginLeft: margin.left,
|
|
29
41
|
marginRight: margin.right,
|
|
30
|
-
|
|
31
|
-
overflowX: 'hidden',
|
|
32
|
-
overflowY: 'auto'
|
|
42
|
+
overflow: 'hidden'
|
|
33
43
|
},
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
44
|
+
minMaxAvgContainer: {
|
|
45
|
+
columnGap: theme.spacing(0.5),
|
|
46
|
+
display: 'grid',
|
|
47
|
+
gridTemplateColumns: 'repeat(2, min-content)',
|
|
48
|
+
whiteSpace: 'nowrap'
|
|
37
49
|
},
|
|
38
|
-
|
|
50
|
+
normal: {
|
|
51
|
+
color: theme.palette.text.primary
|
|
52
|
+
},
|
|
53
|
+
toggable: {
|
|
54
|
+
cursor: 'pointer'
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
interface StylesProps {
|
|
60
|
+
color?: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export const useLegendHeaderStyles = makeStyles<StylesProps>()(
|
|
64
|
+
(theme, { color }) => ({
|
|
65
|
+
container: {
|
|
39
66
|
display: 'flex',
|
|
40
67
|
flexDirection: 'row',
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
overflow: 'hidden',
|
|
44
|
-
textOverflow: 'ellipsis'
|
|
68
|
+
gap: theme.spacing(0.5),
|
|
69
|
+
width: '100%'
|
|
45
70
|
},
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
marginLeft: 'auto',
|
|
49
|
-
marginRight: theme.spacing(0.5),
|
|
50
|
-
overflow: 'hidden',
|
|
51
|
-
textOverflow: 'ellipsis'
|
|
71
|
+
disabled: {
|
|
72
|
+
color: theme.palette.text.disabled
|
|
52
73
|
},
|
|
53
|
-
|
|
54
|
-
|
|
74
|
+
icon: {
|
|
75
|
+
backgroundColor: color,
|
|
76
|
+
borderRadius: theme.shape.borderRadius,
|
|
77
|
+
height: theme.spacing(1.5),
|
|
78
|
+
minWidth: theme.spacing(1.5),
|
|
79
|
+
width: theme.spacing(1.5)
|
|
80
|
+
},
|
|
81
|
+
legendName: {
|
|
82
|
+
'&[data-mode="compact"]': {
|
|
83
|
+
maxWidth: theme.spacing(legendWidth * 0.5)
|
|
84
|
+
},
|
|
85
|
+
maxWidth: theme.spacing(legendWidth * 0.75)
|
|
86
|
+
},
|
|
87
|
+
markerAndLegendName: {
|
|
88
|
+
alignItems: 'center',
|
|
89
|
+
display: 'flex',
|
|
90
|
+
flexDirection: 'row',
|
|
91
|
+
gap: theme.spacing(0.5)
|
|
55
92
|
},
|
|
56
93
|
minMaxAvgContainer: {
|
|
57
94
|
columnGap: theme.spacing(0.5),
|
|
58
95
|
display: 'grid',
|
|
59
|
-
gridAutoRows: theme.spacing(2),
|
|
60
96
|
gridTemplateColumns: 'repeat(2, min-content)',
|
|
61
97
|
whiteSpace: 'nowrap'
|
|
62
98
|
},
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
},
|
|
67
|
-
toggable: {
|
|
68
|
-
cursor: 'pointer'
|
|
99
|
+
text: {
|
|
100
|
+
fontWeight: theme.typography.fontWeightMedium,
|
|
101
|
+
lineHeight: 1
|
|
69
102
|
}
|
|
70
103
|
})
|
|
71
104
|
);
|
|
105
|
+
|
|
106
|
+
export const useLegendContentStyles = makeStyles()((theme) => ({
|
|
107
|
+
minMaxAvgValue: { fontWeight: theme.typography.fontWeightMedium },
|
|
108
|
+
text: {
|
|
109
|
+
lineHeight: 0.9
|
|
110
|
+
}
|
|
111
|
+
}));
|
|
112
|
+
|
|
113
|
+
export const useLegendValueStyles = makeStyles()({
|
|
114
|
+
text: {
|
|
115
|
+
lineHeight: 1.4
|
|
116
|
+
}
|
|
117
|
+
});
|
|
@@ -2,7 +2,7 @@ import { useTranslation } from 'react-i18next';
|
|
|
2
2
|
|
|
3
3
|
import { Typography } from '@mui/material';
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { useLegendContentStyles } from './Legend.styles';
|
|
6
6
|
|
|
7
7
|
interface Props {
|
|
8
8
|
data: string;
|
|
@@ -10,15 +10,21 @@ interface Props {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
const LegendContent = ({ data, label }: Props): JSX.Element => {
|
|
13
|
-
const { classes } =
|
|
13
|
+
const { classes, cx } = useLegendContentStyles();
|
|
14
14
|
|
|
15
15
|
const { t } = useTranslation();
|
|
16
16
|
|
|
17
17
|
return (
|
|
18
|
-
<div data-testid={label}>
|
|
19
|
-
<Typography variant="caption">
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
<div className={classes.text} data-testid={label}>
|
|
19
|
+
<Typography className={classes.text} component="span" variant="caption">
|
|
20
|
+
{t(label)}:{' '}
|
|
21
|
+
<Typography
|
|
22
|
+
className={cx(classes.minMaxAvgValue, classes.text)}
|
|
23
|
+
component="span"
|
|
24
|
+
variant="caption"
|
|
25
|
+
>
|
|
26
|
+
{data}
|
|
27
|
+
</Typography>
|
|
22
28
|
</Typography>
|
|
23
29
|
</div>
|
|
24
30
|
);
|
|
@@ -1,43 +1,91 @@
|
|
|
1
1
|
import { includes, isEmpty, split } from 'ramda';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { Typography } from '@mui/material';
|
|
4
4
|
|
|
5
|
+
import { EllipsisTypography, formatMetricValue } from '../../..';
|
|
5
6
|
import { Line } from '../../common/timeSeries/models';
|
|
7
|
+
import { Tooltip } from '../../../components';
|
|
6
8
|
|
|
7
|
-
import {
|
|
9
|
+
import { useLegendHeaderStyles } from './Legend.styles';
|
|
10
|
+
import { LegendDisplayMode } from './models';
|
|
11
|
+
import LegendContent from './LegendContent';
|
|
8
12
|
|
|
9
13
|
interface Props {
|
|
14
|
+
color: string;
|
|
15
|
+
disabled?: boolean;
|
|
10
16
|
line: Line;
|
|
17
|
+
minMaxAvg?;
|
|
18
|
+
value?: string | null;
|
|
11
19
|
}
|
|
12
20
|
|
|
13
|
-
const LegendHeader = ({
|
|
14
|
-
|
|
21
|
+
const LegendHeader = ({
|
|
22
|
+
line,
|
|
23
|
+
color,
|
|
24
|
+
disabled,
|
|
25
|
+
value,
|
|
26
|
+
minMaxAvg
|
|
27
|
+
}: Props): JSX.Element => {
|
|
28
|
+
const { classes, cx } = useLegendHeaderStyles({ color });
|
|
29
|
+
|
|
15
30
|
const { unit, name, legend } = line;
|
|
16
31
|
|
|
17
32
|
const legendName = legend || name;
|
|
18
|
-
const
|
|
33
|
+
const hasUnit = !isEmpty(unit);
|
|
34
|
+
const unitName = `(${unit})`;
|
|
19
35
|
const metricName = includes('#', legendName)
|
|
20
36
|
? split('#')(legendName)[1]
|
|
21
37
|
: legendName;
|
|
22
38
|
|
|
39
|
+
const getEndText = (): string => {
|
|
40
|
+
if (value) {
|
|
41
|
+
return `${value}${hasUnit ? ` ${unit}` : ''}`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return hasUnit ? ` ${unitName}` : '';
|
|
45
|
+
};
|
|
46
|
+
|
|
23
47
|
return (
|
|
24
|
-
<div className={classes.
|
|
25
|
-
<Tooltip
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
48
|
+
<div className={classes.container}>
|
|
49
|
+
<Tooltip
|
|
50
|
+
followCursor={false}
|
|
51
|
+
label={
|
|
52
|
+
minMaxAvg ? (
|
|
53
|
+
<div>
|
|
54
|
+
<Typography>{`${legendName} ${unitName}`}</Typography>
|
|
55
|
+
<div className={classes.minMaxAvgContainer}>
|
|
56
|
+
{minMaxAvg.map(({ label, value: subValue }) => (
|
|
57
|
+
<LegendContent
|
|
58
|
+
data={formatMetricValue({
|
|
59
|
+
unit: line.unit,
|
|
60
|
+
value: subValue
|
|
61
|
+
})}
|
|
62
|
+
key={label}
|
|
63
|
+
label={label}
|
|
64
|
+
/>
|
|
65
|
+
))}
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
) : (
|
|
69
|
+
`${legendName} ${unitName}`
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
placement="top"
|
|
38
73
|
>
|
|
39
|
-
|
|
40
|
-
|
|
74
|
+
<div className={classes.markerAndLegendName}>
|
|
75
|
+
<div className={cx(classes.icon, { [classes.disabled]: disabled })} />
|
|
76
|
+
<EllipsisTypography
|
|
77
|
+
className={cx(classes.text, classes.legendName)}
|
|
78
|
+
data-mode={
|
|
79
|
+
value ? LegendDisplayMode.Compact : LegendDisplayMode.Normal
|
|
80
|
+
}
|
|
81
|
+
>
|
|
82
|
+
{metricName}
|
|
83
|
+
</EllipsisTypography>
|
|
84
|
+
</div>
|
|
85
|
+
</Tooltip>
|
|
86
|
+
{hasUnit && (
|
|
87
|
+
<Typography className={classes.text}>{getEndText()}</Typography>
|
|
88
|
+
)}
|
|
41
89
|
</div>
|
|
42
90
|
);
|
|
43
91
|
};
|
|
@@ -16,8 +16,7 @@ import { timeValueAtom } from '../InteractiveComponents/interactionWithGraphAtom
|
|
|
16
16
|
import InteractiveValue from './InteractiveValue';
|
|
17
17
|
import { useStyles } from './Legend.styles';
|
|
18
18
|
import LegendHeader from './LegendHeader';
|
|
19
|
-
import
|
|
20
|
-
import { GetMetricValueProps } from './models';
|
|
19
|
+
import { GetMetricValueProps, LegendDisplayMode } from './models';
|
|
21
20
|
import useInteractiveValues from './useInteractiveValues';
|
|
22
21
|
import useLegend from './useLegend';
|
|
23
22
|
import LegendContent from './LegendContent';
|
|
@@ -29,6 +28,7 @@ interface Props {
|
|
|
29
28
|
lines: Array<Line>;
|
|
30
29
|
renderExtraComponent?: ReactNode;
|
|
31
30
|
setLinesGraph: Dispatch<SetStateAction<Array<Line> | null>>;
|
|
31
|
+
shouldDisplayLegendInCompactMode: boolean;
|
|
32
32
|
timeSeries: Array<TimeValue>;
|
|
33
33
|
toggable?: boolean;
|
|
34
34
|
xScale;
|
|
@@ -43,7 +43,8 @@ const MainLegend = ({
|
|
|
43
43
|
renderExtraComponent,
|
|
44
44
|
displayAnchor = true,
|
|
45
45
|
setLinesGraph,
|
|
46
|
-
xScale
|
|
46
|
+
xScale,
|
|
47
|
+
shouldDisplayLegendInCompactMode
|
|
47
48
|
}: Props): JSX.Element => {
|
|
48
49
|
const { classes, cx } = useStyles({ limitLegendRows });
|
|
49
50
|
const theme = useTheme();
|
|
@@ -85,9 +86,13 @@ const MainLegend = ({
|
|
|
85
86
|
selectMetricLine(metric_id);
|
|
86
87
|
};
|
|
87
88
|
|
|
89
|
+
const mode = shouldDisplayLegendInCompactMode
|
|
90
|
+
? LegendDisplayMode.Compact
|
|
91
|
+
: LegendDisplayMode.Normal;
|
|
92
|
+
|
|
88
93
|
return (
|
|
89
94
|
<div className={classes.legend}>
|
|
90
|
-
<div className={classes.items}>
|
|
95
|
+
<div className={classes.items} data-mode={mode}>
|
|
91
96
|
{displayedLines.map((line) => {
|
|
92
97
|
const { color, display, highlight, metric_id } = line;
|
|
93
98
|
|
|
@@ -126,22 +131,37 @@ const MainLegend = ({
|
|
|
126
131
|
onMouseEnter={(): void => highlightLine(metric_id)}
|
|
127
132
|
onMouseLeave={(): void => clearHighlight()}
|
|
128
133
|
>
|
|
129
|
-
<
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
{
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
134
|
+
<LegendHeader
|
|
135
|
+
color={markerColor}
|
|
136
|
+
disabled={!display}
|
|
137
|
+
line={line}
|
|
138
|
+
minMaxAvg={
|
|
139
|
+
shouldDisplayLegendInCompactMode ? minMaxAvg : undefined
|
|
140
|
+
}
|
|
141
|
+
value={
|
|
142
|
+
shouldDisplayLegendInCompactMode
|
|
143
|
+
? interactiveValue
|
|
144
|
+
: undefined
|
|
145
|
+
}
|
|
146
|
+
/>
|
|
147
|
+
{!shouldDisplayLegendInCompactMode && (
|
|
148
|
+
<div>
|
|
149
|
+
{displayAnchor && (
|
|
150
|
+
<InteractiveValue value={interactiveValue} />
|
|
151
|
+
)}
|
|
152
|
+
{!interactiveValue && (
|
|
153
|
+
<div className={classes.minMaxAvgContainer}>
|
|
154
|
+
{minMaxAvg.map(({ label, value }) => (
|
|
155
|
+
<LegendContent
|
|
156
|
+
data={getMetricValue({ unit: line.unit, value })}
|
|
157
|
+
key={label}
|
|
158
|
+
label={label}
|
|
159
|
+
/>
|
|
160
|
+
))}
|
|
161
|
+
</div>
|
|
162
|
+
)}
|
|
163
|
+
</div>
|
|
164
|
+
)}
|
|
145
165
|
</Box>
|
|
146
166
|
);
|
|
147
167
|
})}
|
|
@@ -152,8 +172,15 @@ const MainLegend = ({
|
|
|
152
172
|
};
|
|
153
173
|
|
|
154
174
|
const Legend = (props: Props): JSX.Element => {
|
|
155
|
-
const {
|
|
156
|
-
|
|
175
|
+
const {
|
|
176
|
+
toggable,
|
|
177
|
+
limitLegendRows,
|
|
178
|
+
timeSeries,
|
|
179
|
+
lines,
|
|
180
|
+
base,
|
|
181
|
+
displayAnchor,
|
|
182
|
+
shouldDisplayLegendInCompactMode
|
|
183
|
+
} = props;
|
|
157
184
|
const timeValue = useAtomValue(timeValueAtom);
|
|
158
185
|
|
|
159
186
|
return useMemoComponent({
|
|
@@ -165,7 +192,8 @@ const Legend = (props: Props): JSX.Element => {
|
|
|
165
192
|
base,
|
|
166
193
|
toggable,
|
|
167
194
|
limitLegendRows,
|
|
168
|
-
displayAnchor
|
|
195
|
+
displayAnchor,
|
|
196
|
+
shouldDisplayLegendInCompactMode
|
|
169
197
|
]
|
|
170
198
|
});
|
|
171
199
|
};
|
|
@@ -32,20 +32,19 @@ const useLegend = ({ lines, setLinesGraph }: Props): LegendActions => {
|
|
|
32
32
|
find(propEq('metric_id', metric_id), lines) as Line;
|
|
33
33
|
|
|
34
34
|
const toggleMetricLine = (metric_id): void => {
|
|
35
|
-
const
|
|
35
|
+
const data = lines.map((line) => ({
|
|
36
|
+
...line,
|
|
37
|
+
display: equals(line.metric_id, metric_id) ? !line.display : line.display
|
|
38
|
+
}));
|
|
36
39
|
|
|
37
|
-
setLinesGraph(
|
|
38
|
-
...reject(propEq('metric_id', metric_id), lines),
|
|
39
|
-
{ ...line, display: !line.display }
|
|
40
|
-
]);
|
|
40
|
+
setLinesGraph(data);
|
|
41
41
|
};
|
|
42
42
|
|
|
43
43
|
const highlightLine = (metric_id): void => {
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
];
|
|
44
|
+
const data = lines.map((line) => ({
|
|
45
|
+
...line,
|
|
46
|
+
highlight: equals(line.metric_id, metric_id)
|
|
47
|
+
}));
|
|
49
48
|
|
|
50
49
|
setLinesGraph(data);
|
|
51
50
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MutableRefObject, useMemo, useRef, useState } from 'react';
|
|
2
2
|
|
|
3
3
|
import { Group, Tooltip } from '@visx/visx';
|
|
4
|
-
import { flatten, isNil, pluck } from 'ramda';
|
|
4
|
+
import { flatten, gt, isNil, lte, pluck, reduce } from 'ramda';
|
|
5
5
|
|
|
6
6
|
import { ClickAwayListener, Fade, Skeleton, useTheme } from '@mui/material';
|
|
7
7
|
|
|
@@ -33,6 +33,9 @@ import {
|
|
|
33
33
|
import { useIntersection } from './useLineChartIntersection';
|
|
34
34
|
import { CurveType } from './BasicComponents/Lines/models';
|
|
35
35
|
import Thresholds from './BasicComponents/Thresholds';
|
|
36
|
+
import { legendWidth } from './Legend/Legend.styles';
|
|
37
|
+
|
|
38
|
+
const extraMargin = 10;
|
|
36
39
|
|
|
37
40
|
interface Props extends LineChartProps {
|
|
38
41
|
curve: CurveType;
|
|
@@ -92,7 +95,8 @@ const LineChart = ({
|
|
|
92
95
|
showTooltip: showThresholdTooltip
|
|
93
96
|
} = Tooltip.useTooltip();
|
|
94
97
|
|
|
95
|
-
const graphWidth =
|
|
98
|
+
const graphWidth =
|
|
99
|
+
width > 0 ? width - margin.left - margin.right - extraMargin : 0;
|
|
96
100
|
const graphHeight =
|
|
97
101
|
(height || 0) > 0
|
|
98
102
|
? (height || 0) -
|
|
@@ -158,6 +162,15 @@ const LineChart = ({
|
|
|
158
162
|
const displayLegend = legend?.display ?? true;
|
|
159
163
|
const displayTooltip = !isNil(tooltip?.renderComponent);
|
|
160
164
|
|
|
165
|
+
const legendItemsWidth = reduce(
|
|
166
|
+
(acc) => acc + legendWidth * 8 + 24,
|
|
167
|
+
0,
|
|
168
|
+
displayedLines
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
const shouldDisplayLegendInCompactMode =
|
|
172
|
+
lte(graphWidth, 808) && gt(legendItemsWidth, graphWidth);
|
|
173
|
+
|
|
161
174
|
if (!isInViewport) {
|
|
162
175
|
return (
|
|
163
176
|
<Skeleton
|
|
@@ -185,7 +198,7 @@ const LineChart = ({
|
|
|
185
198
|
width={width}
|
|
186
199
|
/>
|
|
187
200
|
<svg height={graphHeight + margin.top} ref={graphSvgRef} width="100%">
|
|
188
|
-
<Group.Group left={margin.left} top={margin.top}>
|
|
201
|
+
<Group.Group left={margin.left + extraMargin / 2} top={margin.top}>
|
|
189
202
|
<Grids
|
|
190
203
|
height={graphHeight - margin.top}
|
|
191
204
|
leftScale={leftScale}
|
|
@@ -291,6 +304,7 @@ const LineChart = ({
|
|
|
291
304
|
lines={newLines}
|
|
292
305
|
renderExtraComponent={legend?.renderExtraComponent}
|
|
293
306
|
setLinesGraph={setLinesGraph}
|
|
307
|
+
shouldDisplayLegendInCompactMode={shouldDisplayLegendInCompactMode}
|
|
294
308
|
timeSeries={timeSeries}
|
|
295
309
|
xScale={xScale}
|
|
296
310
|
/>
|
package/src/Graph/index.ts
CHANGED
|
@@ -32,6 +32,8 @@ import useFetchQuery from '../../../../api/useFetchQuery';
|
|
|
32
32
|
|
|
33
33
|
export interface ConnectedAutoCompleteFieldProps<TData> {
|
|
34
34
|
allowUniqOption?: boolean;
|
|
35
|
+
baseEndpoint?: string;
|
|
36
|
+
changeIdValue: (item: TData) => number | string;
|
|
35
37
|
conditionField?: keyof SelectEntry;
|
|
36
38
|
field: string;
|
|
37
39
|
getEndpoint: ({ search, page }) => string;
|
|
@@ -60,6 +62,8 @@ const ConnectedAutocompleteField = (
|
|
|
60
62
|
displayOptionThumbnail,
|
|
61
63
|
queryKey,
|
|
62
64
|
allowUniqOption,
|
|
65
|
+
baseEndpoint,
|
|
66
|
+
changeIdValue,
|
|
63
67
|
...props
|
|
64
68
|
}: ConnectedAutoCompleteFieldProps<TData> &
|
|
65
69
|
Omit<AutocompleteFieldProps, 'options'>): JSX.Element => {
|
|
@@ -87,6 +91,7 @@ const ConnectedAutocompleteField = (
|
|
|
87
91
|
const { fetchQuery, isFetching, prefetchNextPage } = useFetchQuery<
|
|
88
92
|
ListingModel<TData>
|
|
89
93
|
>({
|
|
94
|
+
baseEndpoint,
|
|
90
95
|
fetchHeaders: getRequestHeaders,
|
|
91
96
|
getEndpoint: (params) => {
|
|
92
97
|
return getEndpoint({
|
|
@@ -235,17 +240,24 @@ const ConnectedAutocompleteField = (
|
|
|
235
240
|
|
|
236
241
|
const moreOptions = page > 1 ? options : [];
|
|
237
242
|
|
|
243
|
+
const formattedList = changeIdValue
|
|
244
|
+
? newOptions.result.map((item) => ({
|
|
245
|
+
...item,
|
|
246
|
+
id: changeIdValue(item)
|
|
247
|
+
}))
|
|
248
|
+
: newOptions.result;
|
|
249
|
+
|
|
238
250
|
if (!isEmpty(labelKey) && !isNil(labelKey)) {
|
|
239
|
-
const list =
|
|
251
|
+
const list = formattedList.map((item) =>
|
|
240
252
|
renameKey({ key: labelKey, newKey: 'name', object: item })
|
|
241
253
|
);
|
|
242
254
|
setOptions(moreOptions.concat(list as Array<TData>));
|
|
243
255
|
|
|
244
256
|
return;
|
|
245
257
|
}
|
|
246
|
-
setOptions(moreOptions.concat(
|
|
258
|
+
setOptions(moreOptions.concat(formattedList));
|
|
247
259
|
|
|
248
|
-
setOptions(moreOptions.concat(
|
|
260
|
+
setOptions(moreOptions.concat(formattedList as Array<TData>));
|
|
249
261
|
|
|
250
262
|
const total = prop('total', newOptions.meta) || 1;
|
|
251
263
|
const limit = prop('limit', newOptions.meta) || 1;
|
|
@@ -80,6 +80,7 @@ export type Props = {
|
|
|
80
80
|
autoSizeCustomPadding?: number;
|
|
81
81
|
autoSizeDefaultWidth?: number;
|
|
82
82
|
className?: string;
|
|
83
|
+
containerClassName?: string;
|
|
83
84
|
dataTestId: string;
|
|
84
85
|
debounced?: boolean;
|
|
85
86
|
displayErrorInTooltip?: boolean;
|
|
@@ -112,6 +113,7 @@ const TextField = forwardRef(
|
|
|
112
113
|
autoSizeCustomPadding,
|
|
113
114
|
defaultValue,
|
|
114
115
|
required = false,
|
|
116
|
+
containerClassName,
|
|
115
117
|
...rest
|
|
116
118
|
}: Props,
|
|
117
119
|
ref: React.ForwardedRef<HTMLDivElement>
|
|
@@ -142,7 +144,10 @@ const TextField = forwardRef(
|
|
|
142
144
|
}, [innerValue, debounced, defaultValue]);
|
|
143
145
|
|
|
144
146
|
return (
|
|
145
|
-
<Box
|
|
147
|
+
<Box
|
|
148
|
+
className={containerClassName}
|
|
149
|
+
sx={{ width: autoSize ? 'auto' : '100%' }}
|
|
150
|
+
>
|
|
146
151
|
<Tooltip placement="top" title={tooltipTitle}>
|
|
147
152
|
<MuiTextField
|
|
148
153
|
data-testid={dataTestId}
|