@centreon/ui 23.10.94 → 23.10.96
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/ActionsList/index.tsx +19 -6
- package/src/Checkbox/Checkbox.tsx +10 -8
- package/src/Checkbox/CheckboxGroup/index.tsx +14 -5
- package/src/Dashboard/Dashboard.styles.ts +3 -0
- package/src/Dashboard/Item.tsx +4 -1
- package/src/PopoverMenu/index.tsx +18 -4
- package/src/api/buildListingEndpoint/getSearchQueryParameterValue.ts +2 -4
- package/src/api/buildListingEndpoint/index.ts +1 -1
- package/src/api/useFetchQuery/index.ts +2 -1
- package/src/api/useMutationQuery/index.ts +2 -1
- package/src/components/DataTable/Item/DataTableItem.tsx +28 -9
- package/src/components/Tooltip/ConfirmationTooltip/ConfirmationTooltip.styles.tsx +3 -0
- package/src/components/Tooltip/ConfirmationTooltip/ConfirmationTooltip.tsx +1 -0
- package/src/components/Tooltip/ConfirmationTooltip/index.ts +1 -0
- package/src/components/Tooltip/index.ts +1 -0
- package/src/index.ts +10 -2
- package/src/utils/useDebounce.ts +7 -2
package/package.json
CHANGED
|
@@ -3,27 +3,37 @@ import { useTranslation } from 'react-i18next';
|
|
|
3
3
|
import { equals } from 'ramda';
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
|
-
SvgIconProps,
|
|
7
6
|
MenuList,
|
|
8
7
|
MenuItem,
|
|
9
8
|
ListItemText,
|
|
10
9
|
ListItemIcon,
|
|
11
|
-
Divider
|
|
10
|
+
Divider,
|
|
11
|
+
SvgIconTypeMap
|
|
12
12
|
} from '@mui/material';
|
|
13
|
+
import { OverridableComponent } from '@mui/material/OverridableComponent';
|
|
14
|
+
|
|
15
|
+
import { sanitizedHTML } from '..';
|
|
13
16
|
|
|
14
17
|
import { useStyles } from './ActionsList.styles';
|
|
15
18
|
import { ActionVariants } from './models';
|
|
16
19
|
|
|
17
20
|
interface ActionsType {
|
|
18
|
-
Icon?:
|
|
21
|
+
Icon?: OverridableComponent<SvgIconTypeMap<object, 'svg'>> & {
|
|
22
|
+
muiName: string;
|
|
23
|
+
};
|
|
19
24
|
label: string;
|
|
20
25
|
onClick?: (e?) => void;
|
|
21
26
|
secondaryLabel?: string;
|
|
22
27
|
variant?: ActionVariants;
|
|
23
28
|
}
|
|
24
29
|
|
|
30
|
+
export enum ActionsListActionDivider {
|
|
31
|
+
divider = 'divider'
|
|
32
|
+
}
|
|
33
|
+
export type ActionsListActions = Array<ActionsType | ActionsListActionDivider>;
|
|
34
|
+
|
|
25
35
|
interface Props {
|
|
26
|
-
actions:
|
|
36
|
+
actions: ActionsListActions;
|
|
27
37
|
className?: string;
|
|
28
38
|
listItemClassName?: string;
|
|
29
39
|
}
|
|
@@ -39,7 +49,7 @@ const ActionsList = ({
|
|
|
39
49
|
return (
|
|
40
50
|
<MenuList className={cx(classes.list, className)}>
|
|
41
51
|
{actions?.map((action, idx) => {
|
|
42
|
-
if (equals(action,
|
|
52
|
+
if (equals(action, ActionsListActionDivider.divider)) {
|
|
43
53
|
return <Divider key={`divider_${idx}`} />;
|
|
44
54
|
}
|
|
45
55
|
|
|
@@ -63,7 +73,10 @@ const ActionsList = ({
|
|
|
63
73
|
<ListItemText
|
|
64
74
|
className={listItemClassName}
|
|
65
75
|
primary={t(label)}
|
|
66
|
-
secondary={
|
|
76
|
+
secondary={
|
|
77
|
+
secondaryLabel &&
|
|
78
|
+
sanitizedHTML({ initialContent: t(secondaryLabel) })
|
|
79
|
+
}
|
|
67
80
|
/>
|
|
68
81
|
</MenuItem>
|
|
69
82
|
);
|
|
@@ -2,12 +2,8 @@ import { makeStyles } from 'tss-react/mui';
|
|
|
2
2
|
import { T, always, cond, equals } from 'ramda';
|
|
3
3
|
|
|
4
4
|
import { SvgIconComponent } from '@mui/icons-material';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
Checkbox as MuiCheckbox,
|
|
8
|
-
Box,
|
|
9
|
-
Typography
|
|
10
|
-
} from '@mui/material';
|
|
5
|
+
import Typography, { TypographyTypeMap } from '@mui/material/Typography';
|
|
6
|
+
import { FormControlLabel, Checkbox as MuiCheckbox, Box } from '@mui/material';
|
|
11
7
|
|
|
12
8
|
export type LabelPlacement = 'bottom' | 'top' | 'end' | 'start' | undefined;
|
|
13
9
|
|
|
@@ -60,6 +56,7 @@ interface Props {
|
|
|
60
56
|
disabled?: boolean;
|
|
61
57
|
label: string;
|
|
62
58
|
labelPlacement?: LabelPlacement;
|
|
59
|
+
labelProps?: TypographyTypeMap['props'];
|
|
63
60
|
onChange?: (e) => void;
|
|
64
61
|
}
|
|
65
62
|
|
|
@@ -71,7 +68,8 @@ const Checkbox = ({
|
|
|
71
68
|
className,
|
|
72
69
|
disabled = false,
|
|
73
70
|
labelPlacement = 'end',
|
|
74
|
-
dataTestId
|
|
71
|
+
dataTestId,
|
|
72
|
+
labelProps
|
|
75
73
|
}: Props): JSX.Element => {
|
|
76
74
|
const { classes, cx } = useStyles({
|
|
77
75
|
hasIcon: !!Icon,
|
|
@@ -96,7 +94,11 @@ const Checkbox = ({
|
|
|
96
94
|
}
|
|
97
95
|
data-testid={dataTestId || ''}
|
|
98
96
|
key={label}
|
|
99
|
-
label={
|
|
97
|
+
label={
|
|
98
|
+
<Typography classes={{ root: classes.label }} {...labelProps}>
|
|
99
|
+
{label}
|
|
100
|
+
</Typography>
|
|
101
|
+
}
|
|
100
102
|
labelPlacement={labelPlacement}
|
|
101
103
|
sx={{ margin: 0, padding: 0 }}
|
|
102
104
|
/>
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { equals, includes } from 'ramda';
|
|
2
2
|
import { makeStyles } from 'tss-react/mui';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import FormGroup, { FormGroupProps } from '@mui/material/FormGroup';
|
|
5
|
+
import { TypographyTypeMap } from '@mui/material/Typography';
|
|
5
6
|
|
|
6
7
|
import Checkbox, { LabelPlacement } from '../Checkbox';
|
|
7
8
|
|
|
8
9
|
interface Props {
|
|
10
|
+
className?: string;
|
|
9
11
|
dataTestId?: string;
|
|
10
12
|
direction?: 'horizontal' | 'vertical';
|
|
11
13
|
disabled?: boolean;
|
|
14
|
+
formGroupProps?: FormGroupProps;
|
|
12
15
|
labelPlacement?: LabelPlacement;
|
|
16
|
+
labelProps?: TypographyTypeMap['props'];
|
|
13
17
|
onChange?: (e) => void;
|
|
14
18
|
options: Array<string>;
|
|
15
19
|
values: Array<string>;
|
|
@@ -34,27 +38,32 @@ const CheckboxGroup = ({
|
|
|
34
38
|
onChange,
|
|
35
39
|
labelPlacement = 'end',
|
|
36
40
|
disabled = false,
|
|
37
|
-
dataTestId
|
|
41
|
+
dataTestId,
|
|
42
|
+
className,
|
|
43
|
+
labelProps,
|
|
44
|
+
formGroupProps
|
|
38
45
|
}: Props): JSX.Element => {
|
|
39
|
-
const { classes } = useStyles();
|
|
46
|
+
const { classes, cx } = useStyles();
|
|
40
47
|
|
|
41
48
|
const row = !equals(direction, 'vertical');
|
|
42
49
|
|
|
43
50
|
return (
|
|
44
51
|
<FormGroup
|
|
45
|
-
|
|
52
|
+
classes={{ root: classes.container }}
|
|
46
53
|
data-testid={dataTestId || ''}
|
|
47
54
|
row={row}
|
|
55
|
+
{...formGroupProps}
|
|
48
56
|
>
|
|
49
57
|
{options.map((value) => {
|
|
50
58
|
return (
|
|
51
59
|
<Checkbox
|
|
52
60
|
checked={includes(value, values)}
|
|
53
|
-
className={classes.checkbox}
|
|
61
|
+
className={cx(classes.checkbox, className)}
|
|
54
62
|
disabled={disabled}
|
|
55
63
|
key={value}
|
|
56
64
|
label={value}
|
|
57
65
|
labelPlacement={labelPlacement}
|
|
66
|
+
labelProps={labelProps}
|
|
58
67
|
onChange={onChange}
|
|
59
68
|
/>
|
|
60
69
|
);
|
|
@@ -69,6 +69,9 @@ export const useDashboardLayoutStyles = makeStyles<boolean>()(
|
|
|
69
69
|
export const useDashboardItemStyles = makeStyles<{ hasHeader: boolean }>()(
|
|
70
70
|
(theme, { hasHeader }) => ({
|
|
71
71
|
widgetContainer: {
|
|
72
|
+
'&[data-padding="false"]': {
|
|
73
|
+
padding: 0
|
|
74
|
+
},
|
|
72
75
|
background: theme.palette.background.widget,
|
|
73
76
|
border: 'none',
|
|
74
77
|
borderRadius: theme.spacing(1),
|
package/src/Dashboard/Item.tsx
CHANGED
|
@@ -67,7 +67,10 @@ const Item = forwardRef(
|
|
|
67
67
|
width: `calc(${prop('width', style) || '0px'} - 12px)`
|
|
68
68
|
}}
|
|
69
69
|
>
|
|
70
|
-
<Card
|
|
70
|
+
<Card
|
|
71
|
+
className={classes.widgetContainer}
|
|
72
|
+
data-padding={!disablePadding}
|
|
73
|
+
>
|
|
71
74
|
{header && (
|
|
72
75
|
<div
|
|
73
76
|
{...listeners}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Dispatch, SetStateAction, useEffect, useState } from 'react';
|
|
2
2
|
|
|
3
3
|
import { makeStyles } from 'tss-react/mui';
|
|
4
4
|
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
PopperPlacementType,
|
|
10
10
|
useTheme
|
|
11
11
|
} from '@mui/material';
|
|
12
|
+
import { PopperProps } from '@mui/material/Popper';
|
|
12
13
|
|
|
13
14
|
import { IconButton } from '..';
|
|
14
15
|
|
|
@@ -19,15 +20,22 @@ const useStyles = makeStyles()(() => ({
|
|
|
19
20
|
}
|
|
20
21
|
}));
|
|
21
22
|
|
|
23
|
+
interface PopoverData {
|
|
24
|
+
anchorEl: HTMLElement | undefined;
|
|
25
|
+
setAnchorEl: Dispatch<SetStateAction<HTMLElement | undefined>>;
|
|
26
|
+
}
|
|
27
|
+
|
|
22
28
|
interface Props {
|
|
23
29
|
canOpen?: boolean;
|
|
24
30
|
children: (props?) => JSX.Element;
|
|
25
31
|
className?: string;
|
|
26
32
|
dataTestId?: string;
|
|
33
|
+
getPopoverData?: (data: PopoverData) => void;
|
|
27
34
|
icon: JSX.Element;
|
|
28
35
|
onClose?: () => void;
|
|
29
36
|
onOpen?: () => void;
|
|
30
37
|
popperPlacement?: PopperPlacementType;
|
|
38
|
+
popperProps?: Partial<PopperProps>;
|
|
31
39
|
title?: string;
|
|
32
40
|
}
|
|
33
41
|
|
|
@@ -40,20 +48,21 @@ const PopoverMenu = ({
|
|
|
40
48
|
onClose,
|
|
41
49
|
canOpen = true,
|
|
42
50
|
className,
|
|
43
|
-
dataTestId
|
|
51
|
+
dataTestId,
|
|
52
|
+
getPopoverData,
|
|
53
|
+
popperProps
|
|
44
54
|
}: Props): JSX.Element => {
|
|
45
55
|
const theme = useTheme();
|
|
46
56
|
const { classes, cx } = useStyles();
|
|
47
57
|
const [anchorEl, setAnchorEl] = useState<HTMLElement | undefined>();
|
|
48
|
-
|
|
49
58
|
const isOpen = Boolean(anchorEl);
|
|
50
59
|
|
|
51
60
|
const close = (reason?): void => {
|
|
52
61
|
const isClosedByInputClick = reason?.type === 'mousedown';
|
|
53
|
-
|
|
54
62
|
if (isClosedByInputClick) {
|
|
55
63
|
return;
|
|
56
64
|
}
|
|
65
|
+
|
|
57
66
|
onClose?.();
|
|
58
67
|
setAnchorEl(undefined);
|
|
59
68
|
};
|
|
@@ -75,6 +84,10 @@ const PopoverMenu = ({
|
|
|
75
84
|
}
|
|
76
85
|
}, [canOpen]);
|
|
77
86
|
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
getPopoverData?.({ anchorEl, setAnchorEl });
|
|
89
|
+
}, [anchorEl]);
|
|
90
|
+
|
|
78
91
|
return (
|
|
79
92
|
<>
|
|
80
93
|
<IconButton
|
|
@@ -97,6 +110,7 @@ const PopoverMenu = ({
|
|
|
97
110
|
style={{ zIndex: theme.zIndex.tooltip }}
|
|
98
111
|
onResize={(): undefined => undefined}
|
|
99
112
|
onResizeCapture={(): undefined => undefined}
|
|
113
|
+
{...popperProps}
|
|
100
114
|
>
|
|
101
115
|
<Paper>{children({ close })}</Paper>
|
|
102
116
|
</Popper>
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
GetConditionsSearchQueryParameterValueState
|
|
22
22
|
} from './models';
|
|
23
23
|
|
|
24
|
-
const getFoundFields = ({
|
|
24
|
+
export const getFoundFields = ({
|
|
25
25
|
value,
|
|
26
26
|
fields
|
|
27
27
|
}: RegexSearchParameter): Array<SearchMatch> => {
|
|
@@ -108,7 +108,7 @@ const getConditionsSearchQueryParameterValue = (
|
|
|
108
108
|
};
|
|
109
109
|
};
|
|
110
110
|
|
|
111
|
-
const getSearchQueryParameterValue = (
|
|
111
|
+
export const getSearchQueryParameterValue = (
|
|
112
112
|
search: SearchParameter | undefined
|
|
113
113
|
): SearchQueryParameterValue => {
|
|
114
114
|
if (search === undefined) {
|
|
@@ -134,5 +134,3 @@ const getSearchQueryParameterValue = (
|
|
|
134
134
|
|
|
135
135
|
return { $and: result };
|
|
136
136
|
};
|
|
137
|
-
|
|
138
|
-
export default getSearchQueryParameterValue;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import toRawQueryParameters from '../../queryParameters';
|
|
2
2
|
import { QueryParameter } from '../../queryParameters/models';
|
|
3
3
|
|
|
4
|
-
import getSearchQueryParameterValue from './getSearchQueryParameterValue';
|
|
4
|
+
import { getSearchQueryParameterValue } from './getSearchQueryParameterValue';
|
|
5
5
|
import { Parameters, BuildListingEndpointParameters } from './models';
|
|
6
6
|
|
|
7
7
|
const getQueryParameters = ({
|
|
@@ -14,6 +14,7 @@ import { has, includes, not, omit } from 'ramda';
|
|
|
14
14
|
|
|
15
15
|
import { CatchErrorProps, customFetch, ResponseError } from '../customFetch';
|
|
16
16
|
import useSnackbar from '../../Snackbar/useSnackbar';
|
|
17
|
+
import { useDeepCompare } from '../../utils';
|
|
17
18
|
|
|
18
19
|
export interface UseFetchQueryProps<T> {
|
|
19
20
|
catchError?: (props: CatchErrorProps) => void;
|
|
@@ -162,7 +163,7 @@ const useFetchQuery = <T extends object>({
|
|
|
162
163
|
|
|
163
164
|
useEffect(() => {
|
|
164
165
|
manageError();
|
|
165
|
-
}, [queryData.data]);
|
|
166
|
+
}, useDeepCompare([queryData.data]));
|
|
166
167
|
|
|
167
168
|
return {
|
|
168
169
|
...omit(['data'], queryData),
|
|
@@ -12,6 +12,7 @@ import { includes } from 'ramda';
|
|
|
12
12
|
|
|
13
13
|
import { CatchErrorProps, customFetch, ResponseError } from '../customFetch';
|
|
14
14
|
import useSnackbar from '../../Snackbar/useSnackbar';
|
|
15
|
+
import { useDeepCompare } from '../../utils';
|
|
15
16
|
|
|
16
17
|
export enum Method {
|
|
17
18
|
DELETE = 'DELETE',
|
|
@@ -98,7 +99,7 @@ const useMutationQuery = <T extends object, TMeta>({
|
|
|
98
99
|
|
|
99
100
|
useEffect(() => {
|
|
100
101
|
manageError();
|
|
101
|
-
}, [queryData.data]);
|
|
102
|
+
}, useDeepCompare([queryData.data]));
|
|
102
103
|
|
|
103
104
|
return {
|
|
104
105
|
...queryData,
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
} from '@mui/icons-material';
|
|
15
15
|
|
|
16
16
|
import { IconButton } from '../../Button';
|
|
17
|
+
import { ConfirmationTooltip } from '../../Tooltip/ConfirmationTooltip';
|
|
17
18
|
|
|
18
19
|
import { useStyles } from './DataTableItem.styles';
|
|
19
20
|
|
|
@@ -21,6 +22,13 @@ export interface DataTableItemProps {
|
|
|
21
22
|
description?: string;
|
|
22
23
|
hasActions?: boolean;
|
|
23
24
|
hasCardAction?: boolean;
|
|
25
|
+
labelsDelete: {
|
|
26
|
+
cancel: string;
|
|
27
|
+
confirm: {
|
|
28
|
+
label: string;
|
|
29
|
+
secondaryLabel?: string;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
24
32
|
onClick?: () => void;
|
|
25
33
|
onDelete?: () => void;
|
|
26
34
|
onEdit?: () => void;
|
|
@@ -38,7 +46,8 @@ const DataTableItem = forwardRef(
|
|
|
38
46
|
onClick,
|
|
39
47
|
onEdit,
|
|
40
48
|
onDelete,
|
|
41
|
-
onEditAccessRights
|
|
49
|
+
onEditAccessRights,
|
|
50
|
+
labelsDelete
|
|
42
51
|
}: DataTableItemProps,
|
|
43
52
|
ref
|
|
44
53
|
): ReactElement => {
|
|
@@ -67,14 +76,24 @@ const DataTableItem = forwardRef(
|
|
|
67
76
|
{hasActions && (
|
|
68
77
|
<MuiCardActions>
|
|
69
78
|
<span>
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
79
|
+
{onDelete && (
|
|
80
|
+
<ConfirmationTooltip
|
|
81
|
+
confirmVariant="error"
|
|
82
|
+
labels={labelsDelete}
|
|
83
|
+
onConfirm={onDelete}
|
|
84
|
+
>
|
|
85
|
+
{(openTooltip) => (
|
|
86
|
+
<IconButton
|
|
87
|
+
aria-label="delete"
|
|
88
|
+
data-testid="delete"
|
|
89
|
+
icon={<DeleteIcon />}
|
|
90
|
+
size="small"
|
|
91
|
+
variant="ghost"
|
|
92
|
+
onClick={openTooltip}
|
|
93
|
+
/>
|
|
94
|
+
)}
|
|
95
|
+
</ConfirmationTooltip>
|
|
96
|
+
)}
|
|
78
97
|
</span>
|
|
79
98
|
<span>
|
|
80
99
|
<IconButton
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ConfirmationTooltip';
|
package/src/index.ts
CHANGED
|
@@ -75,7 +75,10 @@ export { default as useCancelTokenSource } from './api/useCancelTokenSource';
|
|
|
75
75
|
export { getData, patchData, postData, putData, deleteData } from './api';
|
|
76
76
|
export { default as useRequest } from './api/useRequest';
|
|
77
77
|
export { default as buildListingEndpoint } from './api/buildListingEndpoint';
|
|
78
|
-
export {
|
|
78
|
+
export {
|
|
79
|
+
getSearchQueryParameterValue,
|
|
80
|
+
getFoundFields
|
|
81
|
+
} from './api/buildListingEndpoint/getSearchQueryParameterValue';
|
|
79
82
|
export type {
|
|
80
83
|
Parameters as ListingParameters,
|
|
81
84
|
BuildListingEndpointParameters,
|
|
@@ -140,7 +143,12 @@ export * from './TopCounterElements';
|
|
|
140
143
|
export { default as Image, ImageVariant } from './Image/Image';
|
|
141
144
|
export { default as WallpaperPage } from './WallpaperPage';
|
|
142
145
|
export { RichTextEditor } from './RichTextEditor';
|
|
143
|
-
export {
|
|
146
|
+
export {
|
|
147
|
+
default as ActionsList,
|
|
148
|
+
ActionsListActionDivider
|
|
149
|
+
} from './ActionsList';
|
|
150
|
+
export type { ActionsListActions } from './ActionsList';
|
|
151
|
+
export type { ActionVariants } from './ActionsList/models';
|
|
144
152
|
|
|
145
153
|
export type { ResponseError, CatchErrorProps } from './api/customFetch';
|
|
146
154
|
|
package/src/utils/useDebounce.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useRef, useCallback } from 'react';
|
|
1
|
+
import { useRef, useCallback, useEffect } from 'react';
|
|
2
2
|
|
|
3
3
|
interface Props {
|
|
4
4
|
functionToDebounce: (...args) => void;
|
|
@@ -12,6 +12,11 @@ export const useDebounce = ({
|
|
|
12
12
|
memoProps = []
|
|
13
13
|
}: Props): ((...args) => void) => {
|
|
14
14
|
const timeoutRef = useRef<number | null>(null);
|
|
15
|
+
const ref = useRef();
|
|
16
|
+
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
ref.current = functionToDebounce;
|
|
19
|
+
}, [functionToDebounce]);
|
|
15
20
|
|
|
16
21
|
return useCallback((...args): void => {
|
|
17
22
|
if (timeoutRef.current) {
|
|
@@ -19,7 +24,7 @@ export const useDebounce = ({
|
|
|
19
24
|
}
|
|
20
25
|
|
|
21
26
|
timeoutRef.current = setTimeout(() => {
|
|
22
|
-
|
|
27
|
+
ref.current?.(...args);
|
|
23
28
|
}, wait);
|
|
24
29
|
}, memoProps);
|
|
25
30
|
};
|