@centreon/ui 24.11.2 → 24.11.4
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 +2 -3
- package/src/Dashboard/Dashboard.styles.ts +4 -3
- package/src/Dashboard/DashboardLayout.stories.tsx +1 -1
- package/src/Dashboard/Grid.tsx +17 -11
- package/src/Dashboard/Layout.tsx +56 -27
- package/src/FileDropZone/index.tsx +21 -23
- package/src/Form/CollapsibleGroup.tsx +3 -2
- package/src/Form/Form.cypress.spec.tsx +39 -0
- package/src/Form/Form.tsx +1 -0
- package/src/Form/Inputs/Autocomplete.tsx +27 -4
- package/src/Form/Inputs/ConnectedAutocomplete.tsx +20 -10
- package/src/Form/Inputs/File.tsx +69 -0
- package/src/Form/Inputs/Grid.tsx +30 -2
- package/src/Form/Inputs/Radio.tsx +12 -4
- package/src/Form/Inputs/Switch.tsx +10 -2
- package/src/Form/Inputs/Text.tsx +13 -4
- package/src/Form/Inputs/index.tsx +5 -2
- package/src/Form/Inputs/models.ts +18 -2
- package/src/Form/storiesData.tsx +15 -3
- package/src/Form/translatedLabels.ts +1 -0
- package/src/Graph/BarChart/BarChart.tsx +4 -1
- package/src/Graph/BarChart/ResponsiveBarChart.tsx +3 -2
- package/src/Graph/Chart/Chart.tsx +9 -2
- package/src/Graph/Chart/InteractiveComponents/AnchorPoint/useTickGraph.ts +2 -2
- package/src/Graph/Chart/InteractiveComponents/index.tsx +10 -2
- package/src/Graph/Chart/helpers/index.ts +5 -5
- package/src/Graph/Chart/index.tsx +7 -0
- package/src/Graph/Chart/models.ts +1 -0
- package/src/Graph/common/timeSeries/index.ts +15 -8
- package/src/InputField/Text/index.tsx +1 -1
- package/src/Listing/index.tsx +39 -27
- package/src/Listing/models.ts +8 -0
- package/src/MultiSelectEntries/index.tsx +0 -2
- package/src/PopoverMenu/index.tsx +9 -2
- package/src/SortableItems/index.tsx +1 -0
- package/src/ThemeProvider/index.tsx +1 -1
- package/src/ThemeProvider/palettes.ts +4 -4
- package/src/api/customFetch.ts +4 -1
- package/src/components/CrudPage/Actions/Actions.styles.ts +16 -0
- package/src/components/CrudPage/Actions/Actions.tsx +24 -0
- package/src/components/CrudPage/Actions/AddButton.tsx +23 -0
- package/src/components/CrudPage/Actions/Filters.tsx +25 -0
- package/src/components/CrudPage/Actions/Search.tsx +31 -0
- package/src/components/CrudPage/Actions/useSearch.tsx +24 -0
- package/src/components/CrudPage/Columns/Actions.tsx +88 -0
- package/src/components/CrudPage/CrudPage.cypress.spec.tsx +559 -0
- package/src/components/CrudPage/CrudPage.stories.tsx +278 -0
- package/src/components/CrudPage/CrudPageRoot.tsx +142 -0
- package/src/components/CrudPage/DeleteModal.tsx +77 -0
- package/src/components/CrudPage/Form/AddModal.tsx +35 -0
- package/src/components/CrudPage/Form/Buttons.tsx +98 -0
- package/src/components/CrudPage/Form/UpdateModal.tsx +60 -0
- package/src/components/CrudPage/Listing.tsx +63 -0
- package/src/components/CrudPage/atoms.ts +30 -0
- package/src/components/CrudPage/hooks/useDeleteItem.ts +53 -0
- package/src/components/CrudPage/hooks/useGetItem.ts +36 -0
- package/src/components/CrudPage/hooks/useGetItems.ts +67 -0
- package/src/components/CrudPage/hooks/useListingQueryKey.ts +31 -0
- package/src/components/CrudPage/index.tsx +7 -0
- package/src/components/CrudPage/models.ts +118 -0
- package/src/components/CrudPage/utils.ts +4 -0
- package/src/components/DataTable/DataTable.cypress.spec.tsx +2 -1
- package/src/components/DataTable/DataTable.stories.tsx +17 -0
- package/src/components/DataTable/DataTable.styles.ts +1 -1
- package/src/components/DataTable/EmptyState/DataTableEmptyState.styles.ts +3 -1
- package/src/components/DataTable/EmptyState/DataTableEmptyState.tsx +6 -0
- package/src/components/DataTable/Item/DataTableItem.styles.ts +28 -2
- package/src/components/DataTable/Item/DataTableItem.tsx +19 -4
- package/src/components/Layout/AreaIndicator.tsx +1 -1
- package/src/components/Layout/PageLayout/PageLayout.styles.ts +7 -2
- package/src/components/Layout/PageLayout/PageLayoutBody.tsx +1 -0
- package/src/components/Modal/Modal.styles.ts +1 -1
- package/src/components/Zoom/Zoom.tsx +2 -2
- package/src/components/Zoom/ZoomContent.tsx +2 -2
- package/src/components/index.ts +1 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FormikValues, useFormikContext } from 'formik';
|
|
2
|
-
import {
|
|
2
|
+
import { equals, includes, path, split, type } from 'ramda';
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
4
|
|
|
5
5
|
import {
|
|
@@ -26,12 +26,20 @@ const Radio = ({
|
|
|
26
26
|
}: InputPropsWithoutGroup): JSX.Element => {
|
|
27
27
|
const { t } = useTranslation();
|
|
28
28
|
|
|
29
|
-
const { values, setFieldValue } =
|
|
29
|
+
const { values, setFieldValue, setFieldTouched, setValues, setTouched } =
|
|
30
|
+
useFormikContext<FormikValues>();
|
|
30
31
|
|
|
31
32
|
const changeRadio = (_, value): void => {
|
|
32
33
|
if (includes(value, ['true', 'false'])) {
|
|
33
34
|
if (change) {
|
|
34
|
-
change({
|
|
35
|
+
change({
|
|
36
|
+
setFieldValue,
|
|
37
|
+
value: equals(value, 'true'),
|
|
38
|
+
values,
|
|
39
|
+
setFieldTouched,
|
|
40
|
+
setValues,
|
|
41
|
+
setTouched
|
|
42
|
+
});
|
|
35
43
|
|
|
36
44
|
return;
|
|
37
45
|
}
|
|
@@ -42,7 +50,7 @@ const Radio = ({
|
|
|
42
50
|
}
|
|
43
51
|
|
|
44
52
|
if (change) {
|
|
45
|
-
change({ setFieldValue, value });
|
|
53
|
+
change({ setFieldValue, value, values, setFieldTouched, setValues });
|
|
46
54
|
|
|
47
55
|
return;
|
|
48
56
|
}
|
|
@@ -22,11 +22,19 @@ const Switch = ({
|
|
|
22
22
|
}: InputPropsWithoutGroup): JSX.Element => {
|
|
23
23
|
const { t } = useTranslation();
|
|
24
24
|
|
|
25
|
-
const { values, setFieldValue } =
|
|
25
|
+
const { values, setFieldValue, setFieldTouched, setValues, setTouched } =
|
|
26
|
+
useFormikContext<FormikValues>();
|
|
26
27
|
|
|
27
28
|
const changeSwitchValue = (event: ChangeEvent<HTMLInputElement>): void => {
|
|
28
29
|
if (change) {
|
|
29
|
-
change({
|
|
30
|
+
change({
|
|
31
|
+
setFieldValue,
|
|
32
|
+
value: event.target.checked,
|
|
33
|
+
values,
|
|
34
|
+
setFieldTouched,
|
|
35
|
+
setValues,
|
|
36
|
+
setTouched
|
|
37
|
+
});
|
|
30
38
|
|
|
31
39
|
return;
|
|
32
40
|
}
|
package/src/Form/Inputs/Text.tsx
CHANGED
|
@@ -2,11 +2,11 @@ import { ChangeEvent, useCallback, useState } from 'react';
|
|
|
2
2
|
|
|
3
3
|
import { FormikValues, useFormikContext } from 'formik';
|
|
4
4
|
import {
|
|
5
|
-
path,
|
|
6
5
|
equals,
|
|
7
6
|
gt,
|
|
8
7
|
isEmpty,
|
|
9
8
|
not,
|
|
9
|
+
path,
|
|
10
10
|
split,
|
|
11
11
|
type as variableType
|
|
12
12
|
} from 'ramda';
|
|
@@ -42,7 +42,9 @@ const Text = ({
|
|
|
42
42
|
touched,
|
|
43
43
|
errors,
|
|
44
44
|
handleBlur,
|
|
45
|
-
setFieldTouched
|
|
45
|
+
setFieldTouched,
|
|
46
|
+
setValues,
|
|
47
|
+
setTouched
|
|
46
48
|
} = useFormikContext<FormikValues>();
|
|
47
49
|
|
|
48
50
|
const fieldNamePath = split('.', fieldName);
|
|
@@ -50,7 +52,14 @@ const Text = ({
|
|
|
50
52
|
const changeText = (event: ChangeEvent<HTMLInputElement>): void => {
|
|
51
53
|
const { value } = event.target;
|
|
52
54
|
if (change) {
|
|
53
|
-
change({
|
|
55
|
+
change({
|
|
56
|
+
setFieldValue,
|
|
57
|
+
value,
|
|
58
|
+
setFieldTouched,
|
|
59
|
+
setValues,
|
|
60
|
+
values,
|
|
61
|
+
setTouched
|
|
62
|
+
});
|
|
54
63
|
|
|
55
64
|
return;
|
|
56
65
|
}
|
|
@@ -113,7 +122,7 @@ const Text = ({
|
|
|
113
122
|
return useMemoComponent({
|
|
114
123
|
Component: (
|
|
115
124
|
<TextField
|
|
116
|
-
fullWidth
|
|
125
|
+
fullWidth={text?.fullWidth ?? true}
|
|
117
126
|
EndAdornment={EndAdornment}
|
|
118
127
|
ariaLabel={t(label) || ''}
|
|
119
128
|
autoFocus={autoFocus}
|
|
@@ -36,6 +36,7 @@ import CheckboxGroup from './CheckboxGroup';
|
|
|
36
36
|
import ConnectedAutocomplete from './ConnectedAutocomplete';
|
|
37
37
|
import Custom from './Custom';
|
|
38
38
|
import FieldsTable from './FieldsTable/FieldsTable';
|
|
39
|
+
import File from './File';
|
|
39
40
|
import Grid from './Grid';
|
|
40
41
|
import List from './List/List';
|
|
41
42
|
import LoadingSkeleton from './LoadingSkeleton';
|
|
@@ -78,6 +79,7 @@ export const getInput = cond<
|
|
|
78
79
|
always(CheckboxGroup)
|
|
79
80
|
],
|
|
80
81
|
[equals(InputType.List) as (b: InputType) => boolean, always(List)],
|
|
82
|
+
[equals(InputType.File) as (b: InputType) => boolean, always(File)],
|
|
81
83
|
[T, always(TextInput)]
|
|
82
84
|
]);
|
|
83
85
|
|
|
@@ -113,7 +115,8 @@ const useStyles = makeStyles<StylesProps>()((theme, { groupDirection }) => ({
|
|
|
113
115
|
display: 'flex',
|
|
114
116
|
flexDirection: 'column',
|
|
115
117
|
marginTop: theme.spacing(1),
|
|
116
|
-
rowGap: theme.spacing(2)
|
|
118
|
+
rowGap: theme.spacing(2),
|
|
119
|
+
marginBottom: theme.spacing(1)
|
|
117
120
|
}
|
|
118
121
|
}));
|
|
119
122
|
|
|
@@ -165,7 +168,7 @@ const Inputs = ({
|
|
|
165
168
|
);
|
|
166
169
|
|
|
167
170
|
return pluck('name', usedGroups);
|
|
168
|
-
}, []);
|
|
171
|
+
}, [inputsByGroup, groups]);
|
|
169
172
|
|
|
170
173
|
const sortedInputsByGroup = useMemo(
|
|
171
174
|
() =>
|
|
@@ -19,7 +19,8 @@ export enum InputType {
|
|
|
19
19
|
Custom = 10,
|
|
20
20
|
Checkbox = 11,
|
|
21
21
|
CheckboxGroup = 12,
|
|
22
|
-
List = 13
|
|
22
|
+
List = 13,
|
|
23
|
+
File = 14
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
interface FieldsTableGetRequiredProps {
|
|
@@ -37,8 +38,16 @@ export interface InputProps {
|
|
|
37
38
|
autocomplete?: {
|
|
38
39
|
creatable?: boolean;
|
|
39
40
|
options: Array<SelectEntry>;
|
|
41
|
+
fullWidth?: boolean;
|
|
40
42
|
};
|
|
41
|
-
change?: ({
|
|
43
|
+
change?: ({
|
|
44
|
+
setFieldValue,
|
|
45
|
+
value,
|
|
46
|
+
setFieldTouched,
|
|
47
|
+
setValues,
|
|
48
|
+
values,
|
|
49
|
+
setTouched
|
|
50
|
+
}) => void;
|
|
42
51
|
checkbox?: {
|
|
43
52
|
direction?: 'horizontal' | 'vertical';
|
|
44
53
|
labelPlacement?: LabelPlacement;
|
|
@@ -51,6 +60,12 @@ export interface InputProps {
|
|
|
51
60
|
filterKey?: string;
|
|
52
61
|
getRenderedOptionText?: (option) => string | JSX.Element;
|
|
53
62
|
};
|
|
63
|
+
file?: {
|
|
64
|
+
multiple?: boolean;
|
|
65
|
+
accept?: string;
|
|
66
|
+
maxFileSize?: number;
|
|
67
|
+
CustomDropZoneContent: ({ files }) => JSX.Element;
|
|
68
|
+
};
|
|
54
69
|
custom?: {
|
|
55
70
|
Component: React.ComponentType<InputPropsWithoutGroup>;
|
|
56
71
|
};
|
|
@@ -103,6 +118,7 @@ export interface InputProps {
|
|
|
103
118
|
placeholder?: string;
|
|
104
119
|
type?: string;
|
|
105
120
|
min?: number;
|
|
121
|
+
fullWidth?: boolean;
|
|
106
122
|
};
|
|
107
123
|
type: InputType;
|
|
108
124
|
}
|
package/src/Form/storiesData.tsx
CHANGED
|
@@ -8,7 +8,7 @@ import { Typography } from '@mui/material';
|
|
|
8
8
|
import { SelectEntry } from '../InputField/Select';
|
|
9
9
|
import { Listing } from '../api/models';
|
|
10
10
|
|
|
11
|
-
import { array, boolean, number, object, string } from 'yup';
|
|
11
|
+
import { array, boolean, mixed, number, object, string } from 'yup';
|
|
12
12
|
import {
|
|
13
13
|
Group,
|
|
14
14
|
InputProps,
|
|
@@ -78,7 +78,8 @@ export const basicFormValidationSchema = object().shape({
|
|
|
78
78
|
})
|
|
79
79
|
),
|
|
80
80
|
scopes: array().of(string().min(3, '3 characters min').required('Required')),
|
|
81
|
-
sports: array().of(selectEntryValidationSchema.required('Required'))
|
|
81
|
+
sports: array().of(selectEntryValidationSchema.required('Required')),
|
|
82
|
+
file: mixed()
|
|
82
83
|
});
|
|
83
84
|
|
|
84
85
|
const roleEntries: Array<SelectEntry> = [
|
|
@@ -134,7 +135,8 @@ export const basicFormInitialValues = {
|
|
|
134
135
|
}
|
|
135
136
|
],
|
|
136
137
|
scopes: [],
|
|
137
|
-
sports: []
|
|
138
|
+
sports: [],
|
|
139
|
+
file: null
|
|
138
140
|
};
|
|
139
141
|
|
|
140
142
|
export const classOptions = [...Array(10).keys()].map((idx) => ({
|
|
@@ -444,6 +446,16 @@ export const basicFormInputs: Array<InputProps> = [
|
|
|
444
446
|
multilineRows: 4
|
|
445
447
|
},
|
|
446
448
|
type: InputType.Text
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
fieldName: 'file',
|
|
452
|
+
group: 'First group',
|
|
453
|
+
label: 'File',
|
|
454
|
+
type: InputType.File,
|
|
455
|
+
file: {
|
|
456
|
+
accept: 'image/*',
|
|
457
|
+
multiple: true
|
|
458
|
+
}
|
|
447
459
|
}
|
|
448
460
|
];
|
|
449
461
|
|
|
@@ -38,6 +38,7 @@ export interface BarChartProps
|
|
|
38
38
|
start: string;
|
|
39
39
|
thresholdUnit?: string;
|
|
40
40
|
thresholds?: Thresholds;
|
|
41
|
+
skipIntersectionObserver?: boolean;
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
const BarChart = ({
|
|
@@ -57,7 +58,8 @@ const BarChart = ({
|
|
|
57
58
|
barStyle = {
|
|
58
59
|
opacity: 1,
|
|
59
60
|
radius: 0.2
|
|
60
|
-
}
|
|
61
|
+
},
|
|
62
|
+
skipIntersectionObserver
|
|
61
63
|
}: BarChartProps): JSX.Element => {
|
|
62
64
|
const { adjustedData } = useChartData({ data, end, start });
|
|
63
65
|
const lineChartRef = useRef<HTMLDivElement | null>(null);
|
|
@@ -93,6 +95,7 @@ const BarChart = ({
|
|
|
93
95
|
thresholds={thresholds}
|
|
94
96
|
tooltip={tooltip}
|
|
95
97
|
width={width}
|
|
98
|
+
skipIntersectionObserver={skipIntersectionObserver}
|
|
96
99
|
/>
|
|
97
100
|
)}
|
|
98
101
|
</ParentSize>
|
|
@@ -54,7 +54,8 @@ const ResponsiveBarChart = ({
|
|
|
54
54
|
limitLegend,
|
|
55
55
|
orientation,
|
|
56
56
|
tooltip,
|
|
57
|
-
barStyle
|
|
57
|
+
barStyle,
|
|
58
|
+
skipIntersectionObserver
|
|
58
59
|
}: Props): JSX.Element => {
|
|
59
60
|
const { title, timeSeries, baseAxis, lines } = graphData;
|
|
60
61
|
|
|
@@ -149,7 +150,7 @@ const ResponsiveBarChart = ({
|
|
|
149
150
|
[axis?.showGridLines]
|
|
150
151
|
);
|
|
151
152
|
|
|
152
|
-
if (!isInViewport) {
|
|
153
|
+
if (!isInViewport && !skipIntersectionObserver) {
|
|
153
154
|
return (
|
|
154
155
|
<Skeleton
|
|
155
156
|
height={graphSvgRef?.current?.clientHeight ?? graphHeight}
|
|
@@ -56,6 +56,10 @@ interface Props extends LineChartProps {
|
|
|
56
56
|
shapeLines?: GlobalAreaLines;
|
|
57
57
|
thresholdUnit?: string;
|
|
58
58
|
thresholds?: ThresholdsModel;
|
|
59
|
+
transformMatrix?: {
|
|
60
|
+
fx?: (pointX: number) => number;
|
|
61
|
+
fy?: (pointY: number) => number;
|
|
62
|
+
}
|
|
59
63
|
}
|
|
60
64
|
|
|
61
65
|
const filterLines = (lines: Array<Line>, displayThreshold): Array<Line> => {
|
|
@@ -97,7 +101,9 @@ const Chart = ({
|
|
|
97
101
|
},
|
|
98
102
|
thresholds,
|
|
99
103
|
thresholdUnit,
|
|
100
|
-
limitLegend
|
|
104
|
+
limitLegend,
|
|
105
|
+
skipIntersectionObserver,
|
|
106
|
+
transformMatrix
|
|
101
107
|
}: Props): JSX.Element => {
|
|
102
108
|
const { classes } = useChartStyles();
|
|
103
109
|
|
|
@@ -219,7 +225,7 @@ const Chart = ({
|
|
|
219
225
|
[axis?.showGridLines]
|
|
220
226
|
);
|
|
221
227
|
|
|
222
|
-
if (!isInViewport) {
|
|
228
|
+
if (!isInViewport && !skipIntersectionObserver) {
|
|
223
229
|
return (
|
|
224
230
|
<Skeleton
|
|
225
231
|
height={graphSvgRef?.current?.clientHeight ?? graphHeight}
|
|
@@ -319,6 +325,7 @@ const Chart = ({
|
|
|
319
325
|
graphInterval
|
|
320
326
|
}}
|
|
321
327
|
zoomData={{ ...zoomPreview }}
|
|
328
|
+
transformMatrix={transformMatrix}
|
|
322
329
|
/>
|
|
323
330
|
{thresholds?.enabled && (
|
|
324
331
|
<Thresholds
|
|
@@ -58,10 +58,10 @@ const useTickGraph = ({
|
|
|
58
58
|
return;
|
|
59
59
|
}
|
|
60
60
|
const mousePositionTimeTick = mousePosition
|
|
61
|
-
? getTimeValue({ timeSeries, x: mousePosition[0], xScale })
|
|
61
|
+
? getTimeValue({ timeSeries, x: mousePosition[0], xScale })?.timeTick
|
|
62
62
|
: 0;
|
|
63
63
|
const timeTickValue = mousePosition
|
|
64
|
-
? new Date(mousePositionTimeTick)
|
|
64
|
+
? new Date(mousePositionTimeTick || 0)
|
|
65
65
|
: null;
|
|
66
66
|
|
|
67
67
|
setTickAxisBottom(timeTickValue);
|
|
@@ -76,13 +76,18 @@ interface Props {
|
|
|
76
76
|
commonData: CommonData;
|
|
77
77
|
timeShiftZonesData: TimeShiftZonesData;
|
|
78
78
|
zoomData: ZoomPreviewModel;
|
|
79
|
+
transformMatrix?: {
|
|
80
|
+
fx?: (pointX: number) => number;
|
|
81
|
+
fy?: (pointY: number) => number;
|
|
82
|
+
}
|
|
79
83
|
}
|
|
80
84
|
|
|
81
85
|
const InteractionWithGraph = ({
|
|
82
86
|
zoomData,
|
|
83
87
|
commonData,
|
|
84
88
|
annotationData,
|
|
85
|
-
timeShiftZonesData
|
|
89
|
+
timeShiftZonesData,
|
|
90
|
+
transformMatrix
|
|
86
91
|
}: Props): JSX.Element => {
|
|
87
92
|
const { classes } = useStyles();
|
|
88
93
|
|
|
@@ -127,7 +132,10 @@ const InteractionWithGraph = ({
|
|
|
127
132
|
if (!mousePoint) {
|
|
128
133
|
return;
|
|
129
134
|
}
|
|
130
|
-
updateMousePosition([
|
|
135
|
+
updateMousePosition([
|
|
136
|
+
transformMatrix?.fx?.(mousePoint.x) ?? mousePoint.x,
|
|
137
|
+
transformMatrix?.fy?.(mousePoint.y) ?? mousePoint.y
|
|
138
|
+
]);
|
|
131
139
|
};
|
|
132
140
|
|
|
133
141
|
const mouseDown = (event): void => {
|
|
@@ -2,15 +2,15 @@ import dayjs from 'dayjs';
|
|
|
2
2
|
import durationPlugin from 'dayjs/plugin/duration';
|
|
3
3
|
import { gt, gte, isEmpty, isNil, prop, propEq, reject, sortBy } from 'ramda';
|
|
4
4
|
|
|
5
|
-
import { LineChartData } from '../../common/models';
|
|
5
|
+
import type { LineChartData } from '../../common/models';
|
|
6
6
|
import {
|
|
7
7
|
getLineData,
|
|
8
8
|
getTimeSeries,
|
|
9
9
|
getTimeValue
|
|
10
10
|
} from '../../common/timeSeries';
|
|
11
|
-
import { LinesData } from '../BasicComponents/Lines/models';
|
|
11
|
+
import type { LinesData } from '../BasicComponents/Lines/models';
|
|
12
12
|
import { dateFormat, timeFormat } from '../common';
|
|
13
|
-
import { GetDate, GraphInterval } from '../models';
|
|
13
|
+
import type { GetDate, GraphInterval } from '../models';
|
|
14
14
|
|
|
15
15
|
dayjs.extend(durationPlugin);
|
|
16
16
|
|
|
@@ -56,11 +56,11 @@ export const displayArea = (data: unknown): boolean =>
|
|
|
56
56
|
!isEmpty(data) && !isNil(data);
|
|
57
57
|
|
|
58
58
|
export const getDate = ({ positionX, xScale, timeSeries }: GetDate): Date => {
|
|
59
|
-
const
|
|
59
|
+
const timeValue = getTimeValue({
|
|
60
60
|
timeSeries,
|
|
61
61
|
x: positionX,
|
|
62
62
|
xScale
|
|
63
63
|
});
|
|
64
64
|
|
|
65
|
-
return new Date(timeTick);
|
|
65
|
+
return new Date(timeValue?.timeTick || 0);
|
|
66
66
|
};
|
|
@@ -34,6 +34,10 @@ interface Props extends Partial<LineChartProps> {
|
|
|
34
34
|
thresholds?: Thresholds;
|
|
35
35
|
getRef?: (ref: MutableRefObject<HTMLDivElement | null>) => void;
|
|
36
36
|
containerStyle?: string;
|
|
37
|
+
transformMatrix?: {
|
|
38
|
+
fx?: (pointX: number) => number;
|
|
39
|
+
fy?: (pointY: number) => number;
|
|
40
|
+
}
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
const WrapperChart = ({
|
|
@@ -65,6 +69,7 @@ const WrapperChart = ({
|
|
|
65
69
|
thresholdUnit,
|
|
66
70
|
limitLegend,
|
|
67
71
|
getRef,
|
|
72
|
+
transformMatrix,
|
|
68
73
|
...rest
|
|
69
74
|
}: Props): JSX.Element | null => {
|
|
70
75
|
const { classes, cx } = useChartStyles();
|
|
@@ -120,6 +125,8 @@ const WrapperChart = ({
|
|
|
120
125
|
tooltip={tooltip}
|
|
121
126
|
width={width ?? responsiveWidth}
|
|
122
127
|
zoomPreview={zoomPreview}
|
|
128
|
+
skipIntersectionObserver={rest.skipIntersectionObserver}
|
|
129
|
+
transformMatrix={transformMatrix}
|
|
123
130
|
/>
|
|
124
131
|
);
|
|
125
132
|
}}
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
filter,
|
|
15
15
|
find,
|
|
16
16
|
flatten,
|
|
17
|
+
gt,
|
|
17
18
|
head,
|
|
18
19
|
identity,
|
|
19
20
|
includes,
|
|
@@ -298,13 +299,17 @@ const getTimeSeriesForLines = ({
|
|
|
298
299
|
return map(
|
|
299
300
|
({ timeTick, ...metricsValue }): TimeValue => ({
|
|
300
301
|
...reduce(
|
|
301
|
-
(acc, metric_id): Omit<TimeValue, 'timePick'> =>
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
302
|
+
(acc, metric_id): Omit<TimeValue, 'timePick'> => {
|
|
303
|
+
return {
|
|
304
|
+
...acc,
|
|
305
|
+
[metric_id]:
|
|
306
|
+
invert &&
|
|
307
|
+
metricsValue[metric_id] &&
|
|
308
|
+
gt(metricsValue[metric_id], 0)
|
|
309
|
+
? negate(metricsValue[metric_id])
|
|
310
|
+
: metricsValue[metric_id]
|
|
311
|
+
};
|
|
312
|
+
},
|
|
308
313
|
{},
|
|
309
314
|
metrics
|
|
310
315
|
),
|
|
@@ -363,7 +368,9 @@ const getScale = ({
|
|
|
363
368
|
const isLogScale = equals(scale, 'logarithmic');
|
|
364
369
|
const minValue = Math.min(
|
|
365
370
|
hasDisplayAsBar && 0,
|
|
366
|
-
invert
|
|
371
|
+
invert && graphValues.every(lt(0))
|
|
372
|
+
? negate(getMax(graphValues))
|
|
373
|
+
: getMin(graphValues),
|
|
367
374
|
getMin(stackedValues),
|
|
368
375
|
Math.min(...thresholds)
|
|
369
376
|
);
|
|
@@ -77,7 +77,7 @@ const OptionalLabelInputAdornment = ({
|
|
|
77
77
|
type SizeVariant = 'large' | 'medium' | 'small' | 'compact';
|
|
78
78
|
|
|
79
79
|
export type TextProps = {
|
|
80
|
-
EndAdornment?: React.FC;
|
|
80
|
+
EndAdornment?: React.FC | JSX.Element;
|
|
81
81
|
StartAdornment?: React.FC;
|
|
82
82
|
ariaLabel?: string;
|
|
83
83
|
autoSize?: boolean;
|
package/src/Listing/index.tsx
CHANGED
|
@@ -139,6 +139,7 @@ export interface Props<TRow> {
|
|
|
139
139
|
totalRows?: number;
|
|
140
140
|
viewerModeConfiguration?: ViewerModeConfiguration;
|
|
141
141
|
widthToMoveTablePagination?: number;
|
|
142
|
+
isActionBarVisible: boolean;
|
|
142
143
|
}
|
|
143
144
|
|
|
144
145
|
const defaultColumnConfiguration = {
|
|
@@ -147,7 +148,13 @@ const defaultColumnConfiguration = {
|
|
|
147
148
|
|
|
148
149
|
export const performanceRowsLimit = 60;
|
|
149
150
|
|
|
150
|
-
const Listing = <
|
|
151
|
+
const Listing = <
|
|
152
|
+
TRow extends {
|
|
153
|
+
id: RowId;
|
|
154
|
+
internalListingParentId?: RowId;
|
|
155
|
+
internalListingParentRow: TRow;
|
|
156
|
+
}
|
|
157
|
+
>({
|
|
151
158
|
customListingComponent,
|
|
152
159
|
displayCustomListing,
|
|
153
160
|
limit = 10,
|
|
@@ -191,7 +198,8 @@ const Listing = <TRow extends { id: RowId; internalListingParentId?: RowId }>({
|
|
|
191
198
|
getRowProperty: () => '',
|
|
192
199
|
labelCollapse: 'Collapse',
|
|
193
200
|
labelExpand: 'Expand'
|
|
194
|
-
}
|
|
201
|
+
},
|
|
202
|
+
isActionBarVisible = true
|
|
195
203
|
}: Props<TRow>): JSX.Element => {
|
|
196
204
|
const currentVisibleColumns = getVisibleColumns({
|
|
197
205
|
columnConfiguration,
|
|
@@ -246,7 +254,8 @@ const Listing = <TRow extends { id: RowId; internalListingParentId?: RowId }>({
|
|
|
246
254
|
row,
|
|
247
255
|
...row[subItems.getRowProperty()].map((subRow) => ({
|
|
248
256
|
...subRow,
|
|
249
|
-
internalListingParentId: row.id
|
|
257
|
+
internalListingParentId: row.id,
|
|
258
|
+
internalListingParentRow: row
|
|
250
259
|
}))
|
|
251
260
|
];
|
|
252
261
|
}
|
|
@@ -517,30 +526,33 @@ const Listing = <TRow extends { id: RowId; internalListingParentId?: RowId }>({
|
|
|
517
526
|
className={classes.container}
|
|
518
527
|
ref={containerRef as RefObject<HTMLDivElement>}
|
|
519
528
|
>
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
529
|
+
{
|
|
530
|
+
isActionBarVisible &&
|
|
531
|
+
<div
|
|
532
|
+
className={classes.actionBar}
|
|
533
|
+
ref={actionBarRef as RefObject<HTMLDivElement>}
|
|
534
|
+
>
|
|
535
|
+
<ListingActionBar
|
|
536
|
+
actions={actions}
|
|
537
|
+
actionsBarMemoProps={actionsBarMemoProps}
|
|
538
|
+
columnConfiguration={columnConfiguration}
|
|
539
|
+
columns={columns}
|
|
540
|
+
currentPage={currentPage}
|
|
541
|
+
customPaginationClassName={customPaginationClassName}
|
|
542
|
+
limit={limit}
|
|
543
|
+
listingVariant={listingVariant}
|
|
544
|
+
moveTablePagination={moveTablePagination}
|
|
545
|
+
paginated={paginated}
|
|
546
|
+
totalRows={totalRows}
|
|
547
|
+
viewerModeConfiguration={viewerModeConfiguration}
|
|
548
|
+
widthToMoveTablePagination={widthToMoveTablePagination}
|
|
549
|
+
onLimitChange={changeLimit}
|
|
550
|
+
onPaginate={onPaginate}
|
|
551
|
+
onResetColumns={onResetColumns}
|
|
552
|
+
onSelectColumns={onSelectColumns}
|
|
553
|
+
/>
|
|
554
|
+
</div>
|
|
555
|
+
}
|
|
544
556
|
|
|
545
557
|
<ParentSize
|
|
546
558
|
parentSizeStyles={{
|
package/src/Listing/models.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
} from '@mui/material';
|
|
11
11
|
import type { PopperProps } from '@mui/material/Popper';
|
|
12
12
|
|
|
13
|
+
import { equals, type } from 'ramda';
|
|
13
14
|
import { IconButton } from '..';
|
|
14
15
|
|
|
15
16
|
const useStyles = makeStyles()((theme) => ({
|
|
@@ -29,8 +30,9 @@ interface PopoverData {
|
|
|
29
30
|
|
|
30
31
|
interface Props {
|
|
31
32
|
canOpen?: boolean;
|
|
32
|
-
children: (props?) => JSX.Element;
|
|
33
|
+
children: (props?) => JSX.Element | JSX.Element;
|
|
33
34
|
className?: string;
|
|
35
|
+
tooltipClassName?: string;
|
|
34
36
|
dataTestId?: string;
|
|
35
37
|
getPopoverData?: (data: PopoverData) => void;
|
|
36
38
|
icon: JSX.Element;
|
|
@@ -52,6 +54,7 @@ const PopoverMenu = ({
|
|
|
52
54
|
className,
|
|
53
55
|
dataTestId,
|
|
54
56
|
getPopoverData,
|
|
57
|
+
tooltipClassName,
|
|
55
58
|
popperProps
|
|
56
59
|
}: Props): JSX.Element => {
|
|
57
60
|
const { classes, cx } = useStyles();
|
|
@@ -113,7 +116,11 @@ const PopoverMenu = ({
|
|
|
113
116
|
onResizeCapture={(): undefined => undefined}
|
|
114
117
|
{...popperProps}
|
|
115
118
|
>
|
|
116
|
-
<Paper
|
|
119
|
+
<Paper className={tooltipClassName}>
|
|
120
|
+
{equals(type(children), 'Function')
|
|
121
|
+
? children({ close })
|
|
122
|
+
: children}
|
|
123
|
+
</Paper>
|
|
117
124
|
</Popper>
|
|
118
125
|
</ClickAwayListener>
|
|
119
126
|
)}
|
|
@@ -185,6 +185,7 @@ const SortableItems = <T extends { [propertyToFilterItemsOn]: string }>({
|
|
|
185
185
|
>
|
|
186
186
|
<SortableContext items={sortableItemsIds} strategy={sortingStrategy}>
|
|
187
187
|
<RootComponent>
|
|
188
|
+
{/* biome-ignore lint: */}
|
|
188
189
|
<>
|
|
189
190
|
{sortableItemsIds.map((sortableItemId, index) => {
|
|
190
191
|
const item = getItemById(sortableItemId) as
|