@centreon/ui 23.10.26-MON-19396-update-dashboard-rights.0 → 23.10.26
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/Button/Save/index.stories.tsx +10 -5
- package/src/Checkbox/Checkbox.tsx +107 -0
- package/src/Checkbox/CheckboxGroup/index.stories.tsx +41 -0
- package/src/Checkbox/CheckboxGroup/index.tsx +66 -0
- package/src/Checkbox/index.stories.tsx +39 -0
- package/src/Checkbox/index.tsx +2 -0
- package/src/Form/CollapsibleGroup.tsx +11 -5
- package/src/Form/Form.stories.tsx +1 -1
- package/src/Form/Form.tsx +24 -9
- package/src/Form/Inputs/Checkbox.tsx +57 -0
- package/src/Form/Inputs/CheckboxGroup.tsx +76 -0
- package/src/Form/Inputs/Grid.tsx +4 -2
- package/src/Form/Inputs/index.tsx +29 -7
- package/src/Form/Inputs/models.ts +13 -1
- package/src/Form/storiesData.tsx +45 -0
- package/src/InputField/Text/index.tsx +3 -0
- package/src/Panel/index.tsx +6 -4
- package/src/RichTextEditor/ContentEditable.tsx +27 -7
- package/src/RichTextEditor/RichTextEditor.tsx +86 -45
- package/src/ThemeProvider/index.tsx +4 -1
- package/src/ThemeProvider/palettes.ts +7 -0
- package/src/api/useMutationQuery/index.ts +2 -10
- package/src/components/Button/Button.tsx +1 -1
- package/src/components/DataTable/EmptyState/DataTableEmptyState.tsx +9 -13
- package/src/components/DataTable/Item/DataTableItem.tsx +0 -1
- package/src/components/Form/Dashboard/Dashboard.resource.ts +1 -1
- package/src/components/Form/Dashboard/DashboardForm.tsx +10 -6
- package/src/components/Form/Dashboard/translatedLabels.ts +1 -0
- package/src/components/Modal/Modal.styles.ts +1 -3
- package/src/components/Modal/ModalActions.tsx +1 -4
- package/src/components/index.ts +0 -1
- package/src/index.ts +2 -0
- package/src/utils/index.ts +1 -1
- package/src/utils/panelSize.ts +15 -0
- package/src/components/List/Item/Avatar.tsx +0 -14
- package/src/components/List/Item/Item.tsx +0 -18
- package/src/components/List/Item/Text.tsx +0 -13
- package/src/components/List/Item/index.ts +0 -8
- package/src/components/List/List.stories.tsx +0 -70
- package/src/components/List/List.styles.ts +0 -20
- package/src/components/List/List.tsx +0 -19
- package/src/components/List/index.ts +0 -6
- package/src/utils/useInfiniteScrollListing.ts +0 -106
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ComponentStory } from '@storybook/react';
|
|
2
2
|
import { makeStyles } from 'tss-react/mui';
|
|
3
3
|
|
|
4
4
|
import { Theme } from '@mui/material';
|
|
@@ -13,7 +13,7 @@ const useStyles = makeStyles()((theme: Theme) => ({
|
|
|
13
13
|
}
|
|
14
14
|
}));
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
const meta = {
|
|
17
17
|
argTypes: {
|
|
18
18
|
labelLoading: { control: 'text' },
|
|
19
19
|
labelSave: { control: 'text' },
|
|
@@ -26,8 +26,13 @@ export default {
|
|
|
26
26
|
|
|
27
27
|
component: ButtonSave,
|
|
28
28
|
|
|
29
|
+
parameters: {
|
|
30
|
+
chromatic: { delay: 300 }
|
|
31
|
+
},
|
|
29
32
|
title: 'Button/Save'
|
|
30
|
-
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default meta;
|
|
31
36
|
|
|
32
37
|
const TemplateButtonSave: ComponentStory<typeof ButtonSave> = (args) => (
|
|
33
38
|
<ButtonSave {...args} />
|
|
@@ -42,7 +47,7 @@ export const loading = (): JSX.Element => <ButtonSave loading />;
|
|
|
42
47
|
export const succeeded = (): JSX.Element => <ButtonSave succeeded />;
|
|
43
48
|
|
|
44
49
|
export const normalWithText = (): JSX.Element => (
|
|
45
|
-
<ButtonSave labelSave="Save" />
|
|
50
|
+
<ButtonSave labelSave="Save" size="medium" />
|
|
46
51
|
);
|
|
47
52
|
|
|
48
53
|
export const largeWithText = (): JSX.Element => (
|
|
@@ -50,7 +55,7 @@ export const largeWithText = (): JSX.Element => (
|
|
|
50
55
|
);
|
|
51
56
|
|
|
52
57
|
export const loadingWithTextAndMediumSize = (): JSX.Element => (
|
|
53
|
-
<ButtonSave loading labelLoading="Loading" />
|
|
58
|
+
<ButtonSave loading labelLoading="Loading" size="medium" />
|
|
54
59
|
);
|
|
55
60
|
|
|
56
61
|
export const succeededWithText = (): JSX.Element => (
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { makeStyles } from 'tss-react/mui';
|
|
2
|
+
import { T, always, cond, equals } from 'ramda';
|
|
3
|
+
|
|
4
|
+
import { SvgIconComponent } from '@mui/icons-material';
|
|
5
|
+
import {
|
|
6
|
+
FormControlLabel,
|
|
7
|
+
Checkbox as MuiCheckbox,
|
|
8
|
+
Box,
|
|
9
|
+
Typography
|
|
10
|
+
} from '@mui/material';
|
|
11
|
+
|
|
12
|
+
export type LabelPlacement = 'bottom' | 'top' | 'end' | 'start' | undefined;
|
|
13
|
+
|
|
14
|
+
interface StyleProps {
|
|
15
|
+
disabled: boolean;
|
|
16
|
+
hasIcon: boolean;
|
|
17
|
+
labelPlacement: LabelPlacement;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const getLabelSpacing = (labelPlacement, theme): string => {
|
|
21
|
+
return cond([
|
|
22
|
+
[equals('top'), always(theme.spacing(0, 0, 0.5))],
|
|
23
|
+
[equals('end'), always(theme.spacing(0, 0, 0, 0.5))],
|
|
24
|
+
[T, always(0)]
|
|
25
|
+
])(labelPlacement);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const useStyles = makeStyles<StyleProps>()(
|
|
29
|
+
(theme, { disabled, hasIcon, labelPlacement }) => ({
|
|
30
|
+
container: hasIcon
|
|
31
|
+
? {
|
|
32
|
+
alignItems: 'center',
|
|
33
|
+
display: 'flex',
|
|
34
|
+
flexDirection: 'column',
|
|
35
|
+
justifyContent: 'space-between',
|
|
36
|
+
minHeight: theme.spacing(11)
|
|
37
|
+
}
|
|
38
|
+
: {},
|
|
39
|
+
icon: {
|
|
40
|
+
fontSize: theme.spacing(10)
|
|
41
|
+
},
|
|
42
|
+
label: {
|
|
43
|
+
color: disabled
|
|
44
|
+
? theme.palette.action.disabled
|
|
45
|
+
: theme.palette.text.secondary,
|
|
46
|
+
fontSize: theme.typography.body1.fontSize,
|
|
47
|
+
fontWeight: equals(labelPlacement, 'top')
|
|
48
|
+
? theme.typography.fontWeightBold
|
|
49
|
+
: theme.typography.fontWeightMedium,
|
|
50
|
+
padding: getLabelSpacing(labelPlacement, theme)
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
interface Props {
|
|
56
|
+
Icon?: SvgIconComponent;
|
|
57
|
+
checked: boolean;
|
|
58
|
+
className?: string;
|
|
59
|
+
dataTestId?: string;
|
|
60
|
+
disabled?: boolean;
|
|
61
|
+
label: string;
|
|
62
|
+
labelPlacement?: LabelPlacement;
|
|
63
|
+
onChange?: (e) => void;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const Checkbox = ({
|
|
67
|
+
Icon,
|
|
68
|
+
checked,
|
|
69
|
+
label,
|
|
70
|
+
onChange,
|
|
71
|
+
className,
|
|
72
|
+
disabled = false,
|
|
73
|
+
labelPlacement = 'end',
|
|
74
|
+
dataTestId
|
|
75
|
+
}: Props): JSX.Element => {
|
|
76
|
+
const { classes, cx } = useStyles({
|
|
77
|
+
disabled,
|
|
78
|
+
hasIcon: !!Icon,
|
|
79
|
+
labelPlacement
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
<Box className={cx(classes.container, className)}>
|
|
84
|
+
{Icon && <Icon className={classes.icon} />}
|
|
85
|
+
<FormControlLabel
|
|
86
|
+
control={
|
|
87
|
+
<MuiCheckbox
|
|
88
|
+
checked={checked}
|
|
89
|
+
color="primary"
|
|
90
|
+
disabled={disabled}
|
|
91
|
+
id={label}
|
|
92
|
+
size="small"
|
|
93
|
+
sx={{ padding: 0 }}
|
|
94
|
+
onChange={onChange}
|
|
95
|
+
/>
|
|
96
|
+
}
|
|
97
|
+
data-testid={dataTestId || ''}
|
|
98
|
+
key={label}
|
|
99
|
+
label={<Typography className={classes.label}>{label}</Typography>}
|
|
100
|
+
labelPlacement={labelPlacement}
|
|
101
|
+
sx={{ margin: 0, padding: 0 }}
|
|
102
|
+
/>
|
|
103
|
+
</Box>
|
|
104
|
+
);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export default Checkbox;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ComponentMeta, ComponentStory } from '@storybook/react';
|
|
2
|
+
|
|
3
|
+
import CheckboxGroup from '.';
|
|
4
|
+
|
|
5
|
+
const options = ['ok', 'warning', 'critical', 'unknown'];
|
|
6
|
+
|
|
7
|
+
const values = ['ok', 'critical'];
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
argTypes: {},
|
|
11
|
+
component: CheckboxGroup,
|
|
12
|
+
title: 'Checkbox/Multi'
|
|
13
|
+
} as ComponentMeta<typeof CheckboxGroup>;
|
|
14
|
+
|
|
15
|
+
const Template: ComponentStory<typeof CheckboxGroup> = (args) => (
|
|
16
|
+
<CheckboxGroup {...args} />
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
export const Playground = Template.bind({});
|
|
20
|
+
|
|
21
|
+
Playground.args = {
|
|
22
|
+
options,
|
|
23
|
+
values
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const Horizontal = Template.bind({});
|
|
27
|
+
|
|
28
|
+
Horizontal.args = {
|
|
29
|
+
direction: 'horizontal',
|
|
30
|
+
options,
|
|
31
|
+
values
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const LabelOnTop = Template.bind({});
|
|
35
|
+
|
|
36
|
+
LabelOnTop.args = {
|
|
37
|
+
direction: 'horizontal',
|
|
38
|
+
labelPlacement: 'top',
|
|
39
|
+
options,
|
|
40
|
+
values
|
|
41
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { equals, includes } from 'ramda';
|
|
2
|
+
import { makeStyles } from 'tss-react/mui';
|
|
3
|
+
|
|
4
|
+
import { FormGroup } from '@mui/material';
|
|
5
|
+
|
|
6
|
+
import Checkbox, { LabelPlacement } from '../Checkbox';
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
dataTestId?: string;
|
|
10
|
+
direction?: 'horizontal' | 'vertical';
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
labelPlacement?: LabelPlacement;
|
|
13
|
+
onChange?: (e) => void;
|
|
14
|
+
options: Array<string>;
|
|
15
|
+
values: Array<string>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const useStyles = makeStyles()((theme) => ({
|
|
19
|
+
checkbox: {
|
|
20
|
+
display: 'flex',
|
|
21
|
+
justifyContent: 'center',
|
|
22
|
+
minWidth: theme.spacing(10)
|
|
23
|
+
},
|
|
24
|
+
container: {
|
|
25
|
+
display: 'flex',
|
|
26
|
+
gap: 1
|
|
27
|
+
}
|
|
28
|
+
}));
|
|
29
|
+
|
|
30
|
+
const CheckboxGroup = ({
|
|
31
|
+
options,
|
|
32
|
+
values,
|
|
33
|
+
direction = 'vertical',
|
|
34
|
+
onChange,
|
|
35
|
+
labelPlacement = 'end',
|
|
36
|
+
disabled = false,
|
|
37
|
+
dataTestId
|
|
38
|
+
}: Props): JSX.Element => {
|
|
39
|
+
const { classes } = useStyles();
|
|
40
|
+
|
|
41
|
+
const row = !equals(direction, 'vertical');
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<FormGroup
|
|
45
|
+
className={classes.container}
|
|
46
|
+
data-testid={dataTestId || ''}
|
|
47
|
+
row={row}
|
|
48
|
+
>
|
|
49
|
+
{options.map((value) => {
|
|
50
|
+
return (
|
|
51
|
+
<Checkbox
|
|
52
|
+
checked={includes(value, values)}
|
|
53
|
+
className={classes.checkbox}
|
|
54
|
+
disabled={disabled}
|
|
55
|
+
key={value}
|
|
56
|
+
label={value}
|
|
57
|
+
labelPlacement={labelPlacement}
|
|
58
|
+
onChange={onChange}
|
|
59
|
+
/>
|
|
60
|
+
);
|
|
61
|
+
})}
|
|
62
|
+
</FormGroup>
|
|
63
|
+
);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export default CheckboxGroup;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ComponentMeta, ComponentStory } from '@storybook/react';
|
|
2
|
+
|
|
3
|
+
import MailIcon from '@mui/icons-material/MailOutline';
|
|
4
|
+
|
|
5
|
+
import Checkbox from './Checkbox';
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
argTypes: {},
|
|
9
|
+
component: Checkbox,
|
|
10
|
+
title: 'Checkbox/Single'
|
|
11
|
+
} as ComponentMeta<typeof Checkbox>;
|
|
12
|
+
|
|
13
|
+
const Template: ComponentStory<typeof Checkbox> = (args) => (
|
|
14
|
+
<Checkbox {...args} />
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
export const Playground = Template.bind({});
|
|
18
|
+
|
|
19
|
+
Playground.args = {
|
|
20
|
+
checked: true,
|
|
21
|
+
label: 'Up'
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const WithIcon = Template.bind({});
|
|
25
|
+
|
|
26
|
+
WithIcon.args = {
|
|
27
|
+
Icon: MailIcon,
|
|
28
|
+
checked: true,
|
|
29
|
+
label: 'Mail',
|
|
30
|
+
labelPlacement: 'end'
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const LabelOnTop = Template.bind({});
|
|
34
|
+
|
|
35
|
+
LabelOnTop.args = {
|
|
36
|
+
checked: true,
|
|
37
|
+
label: 'Down',
|
|
38
|
+
labelPlacement: 'top'
|
|
39
|
+
};
|
|
@@ -18,6 +18,7 @@ import { Group } from './Inputs/models';
|
|
|
18
18
|
|
|
19
19
|
interface Props {
|
|
20
20
|
children: React.ReactNode;
|
|
21
|
+
className?: string;
|
|
21
22
|
defaultIsOpen?: boolean;
|
|
22
23
|
group?: Group;
|
|
23
24
|
hasGroupTitle: boolean;
|
|
@@ -50,9 +51,10 @@ const CollapsibleGroup = ({
|
|
|
50
51
|
isCollapsible,
|
|
51
52
|
group,
|
|
52
53
|
hasGroupTitle,
|
|
53
|
-
defaultIsOpen = false
|
|
54
|
+
defaultIsOpen = false,
|
|
55
|
+
className
|
|
54
56
|
}: Props): JSX.Element => {
|
|
55
|
-
const { classes } = useStyles();
|
|
57
|
+
const { classes, cx } = useStyles();
|
|
56
58
|
const { t } = useTranslation();
|
|
57
59
|
|
|
58
60
|
const [isOpen, setIsOpen] = useState(isCollapsible && defaultIsOpen);
|
|
@@ -61,6 +63,8 @@ const CollapsibleGroup = ({
|
|
|
61
63
|
setIsOpen((currentIsOpen) => !currentIsOpen);
|
|
62
64
|
};
|
|
63
65
|
|
|
66
|
+
const containerClassName = className || '';
|
|
67
|
+
|
|
64
68
|
const CollapseIcon = isOpen ? ExpandMore : ChevronRightIcon;
|
|
65
69
|
const ContainerComponent = useCallback(
|
|
66
70
|
({
|
|
@@ -72,13 +76,13 @@ const CollapsibleGroup = ({
|
|
|
72
76
|
disableGutters
|
|
73
77
|
disableRipple
|
|
74
78
|
aria-label={group?.name}
|
|
75
|
-
className={classes.groupTitleContainer}
|
|
79
|
+
className={cx(classes.groupTitleContainer, containerClassName)}
|
|
76
80
|
onClick={toggle}
|
|
77
81
|
>
|
|
78
82
|
{containerComponentChildren}
|
|
79
83
|
</ListItemButton>
|
|
80
84
|
) : (
|
|
81
|
-
<Box className={classes.groupTitleContainer}>
|
|
85
|
+
<Box className={cx(classes.groupTitleContainer, containerClassName)}>
|
|
82
86
|
{containerComponentChildren}
|
|
83
87
|
</Box>
|
|
84
88
|
),
|
|
@@ -91,7 +95,9 @@ const CollapsibleGroup = ({
|
|
|
91
95
|
<ContainerComponent>
|
|
92
96
|
{isCollapsible && <CollapseIcon />}
|
|
93
97
|
<div className={classes.groupTitleIcon}>
|
|
94
|
-
<Typography variant="h5">
|
|
98
|
+
<Typography className="groupText" variant="h5">
|
|
99
|
+
{t(group?.name as string)}
|
|
100
|
+
</Typography>
|
|
95
101
|
{group?.EndIcon && (
|
|
96
102
|
<Tooltip
|
|
97
103
|
classes={{
|
|
@@ -71,7 +71,7 @@ export const basicFormWithHorizontalGroups = (): JSX.Element => (
|
|
|
71
71
|
<Form<BasicForm>
|
|
72
72
|
{...mandatoryProps}
|
|
73
73
|
groupDirection={GroupDirection.Horizontal}
|
|
74
|
-
groups={basicFormGroups}
|
|
74
|
+
groups={basicFormGroups.filter((group) => group.order !== 3)}
|
|
75
75
|
/>
|
|
76
76
|
</Paper>
|
|
77
77
|
);
|
package/src/Form/Form.tsx
CHANGED
|
@@ -18,8 +18,12 @@ export enum GroupDirection {
|
|
|
18
18
|
|
|
19
19
|
export type FormProps<T> = {
|
|
20
20
|
Buttons?: React.ComponentType;
|
|
21
|
+
areGroupsOpen?: boolean;
|
|
22
|
+
children?: JSX.Element;
|
|
23
|
+
className?: string;
|
|
21
24
|
groupDirection?: GroupDirection;
|
|
22
25
|
groups?: Array<Group>;
|
|
26
|
+
groupsClassName?: string;
|
|
23
27
|
initialValues: T;
|
|
24
28
|
inputs: Array<InputProps>;
|
|
25
29
|
isCollapsible?: boolean;
|
|
@@ -30,6 +34,10 @@ export type FormProps<T> = {
|
|
|
30
34
|
} & Omit<FormikSharedConfig<T>, 'isInitialValid'>;
|
|
31
35
|
|
|
32
36
|
const Form = <T extends object>({
|
|
37
|
+
children,
|
|
38
|
+
className,
|
|
39
|
+
groupsClassName,
|
|
40
|
+
areGroupsOpen,
|
|
33
41
|
initialValues,
|
|
34
42
|
validate,
|
|
35
43
|
validationSchema,
|
|
@@ -42,13 +50,15 @@ const Form = <T extends object>({
|
|
|
42
50
|
groupDirection = GroupDirection.Vertical,
|
|
43
51
|
...formikSharedConfig
|
|
44
52
|
}: FormProps<T>): JSX.Element => {
|
|
45
|
-
const { classes } = useStyles();
|
|
53
|
+
const { cx, classes } = useStyles();
|
|
46
54
|
|
|
47
55
|
if (isLoading) {
|
|
48
56
|
return (
|
|
49
57
|
<Inputs
|
|
50
58
|
isLoading
|
|
59
|
+
areGroupsOpen={areGroupsOpen}
|
|
51
60
|
groups={groups}
|
|
61
|
+
groupsClassName={groupsClassName}
|
|
52
62
|
inputs={inputs}
|
|
53
63
|
isCollapsible={isCollapsible}
|
|
54
64
|
/>
|
|
@@ -63,14 +73,19 @@ const Form = <T extends object>({
|
|
|
63
73
|
onSubmit={submit}
|
|
64
74
|
{...formikSharedConfig}
|
|
65
75
|
>
|
|
66
|
-
<div
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
76
|
+
<div>
|
|
77
|
+
{children}
|
|
78
|
+
<div className={cx(className, classes.form)}>
|
|
79
|
+
<Inputs
|
|
80
|
+
areGroupsOpen={areGroupsOpen}
|
|
81
|
+
groupDirection={groupDirection}
|
|
82
|
+
groups={groups}
|
|
83
|
+
groupsClassName={groupsClassName}
|
|
84
|
+
inputs={inputs}
|
|
85
|
+
isCollapsible={isCollapsible}
|
|
86
|
+
/>
|
|
87
|
+
<Buttons />
|
|
88
|
+
</div>
|
|
74
89
|
</div>
|
|
75
90
|
</Formik>
|
|
76
91
|
);
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { ChangeEvent } from 'react';
|
|
2
|
+
|
|
3
|
+
import { FormikValues, useFormikContext } from 'formik';
|
|
4
|
+
import { path, split } from 'ramda';
|
|
5
|
+
|
|
6
|
+
import { Box } from '@mui/material';
|
|
7
|
+
|
|
8
|
+
import { Checkbox as CheckboxComponent } from '../../Checkbox';
|
|
9
|
+
import { useMemoComponent } from '../..';
|
|
10
|
+
|
|
11
|
+
import { InputPropsWithoutGroup } from './models';
|
|
12
|
+
|
|
13
|
+
const Checkbox = ({
|
|
14
|
+
checkbox,
|
|
15
|
+
fieldName,
|
|
16
|
+
getDisabled,
|
|
17
|
+
hideInput,
|
|
18
|
+
dataTestId
|
|
19
|
+
}: InputPropsWithoutGroup): JSX.Element => {
|
|
20
|
+
const { values, setFieldValue } = useFormikContext<FormikValues>();
|
|
21
|
+
|
|
22
|
+
const fieldNamePath = split('.', fieldName);
|
|
23
|
+
|
|
24
|
+
const value = path(fieldNamePath, values);
|
|
25
|
+
|
|
26
|
+
const disabled = getDisabled?.(values) || false;
|
|
27
|
+
const hideCheckbox = hideInput?.(values) || false;
|
|
28
|
+
|
|
29
|
+
const handleChange = (event: ChangeEvent<HTMLInputElement>): void => {
|
|
30
|
+
const newValue = {
|
|
31
|
+
...value,
|
|
32
|
+
checked: event.target.checked,
|
|
33
|
+
label: event.target.id
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
setFieldValue(fieldName, newValue);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
return useMemoComponent({
|
|
40
|
+
Component: hideCheckbox ? (
|
|
41
|
+
<Box />
|
|
42
|
+
) : (
|
|
43
|
+
<CheckboxComponent
|
|
44
|
+
Icon={value?.Icon}
|
|
45
|
+
checked={value?.checked}
|
|
46
|
+
dataTestId={dataTestId || ''}
|
|
47
|
+
disabled={disabled}
|
|
48
|
+
label={value?.label}
|
|
49
|
+
labelPlacement={checkbox?.labelPlacement || 'end'}
|
|
50
|
+
onChange={handleChange}
|
|
51
|
+
/>
|
|
52
|
+
),
|
|
53
|
+
memoProps: [value, disabled, hideCheckbox]
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export default Checkbox;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { ChangeEvent, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
import { FormikValues, useFormikContext } from 'formik';
|
|
4
|
+
import { equals, includes, path, split } from 'ramda';
|
|
5
|
+
|
|
6
|
+
import { Box, Typography } from '@mui/material';
|
|
7
|
+
|
|
8
|
+
import { CheckboxGroup as CheckboxGroupComponent } from '../../Checkbox';
|
|
9
|
+
import { useMemoComponent } from '../..';
|
|
10
|
+
|
|
11
|
+
import { InputPropsWithoutGroup } from './models';
|
|
12
|
+
|
|
13
|
+
const CheckboxGroup = ({
|
|
14
|
+
checkbox,
|
|
15
|
+
fieldName,
|
|
16
|
+
additionalLabel,
|
|
17
|
+
getDisabled,
|
|
18
|
+
hideInput,
|
|
19
|
+
dataTestId
|
|
20
|
+
}: InputPropsWithoutGroup): JSX.Element => {
|
|
21
|
+
const { values, setFieldValue } = useFormikContext<FormikValues>();
|
|
22
|
+
|
|
23
|
+
const fieldNamePath = split('.', fieldName);
|
|
24
|
+
|
|
25
|
+
const value = path(fieldNamePath, values);
|
|
26
|
+
|
|
27
|
+
const disabled = getDisabled?.(values) || false;
|
|
28
|
+
const hideCheckbox = hideInput?.(values) || false;
|
|
29
|
+
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
if (!disabled && !hideCheckbox) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const resetedValue = value?.map((element) => ({
|
|
35
|
+
...element,
|
|
36
|
+
checked: false
|
|
37
|
+
}));
|
|
38
|
+
setFieldValue(fieldName, resetedValue);
|
|
39
|
+
}, [disabled, hideCheckbox]);
|
|
40
|
+
|
|
41
|
+
const handleChange = (event: ChangeEvent<HTMLInputElement>): void => {
|
|
42
|
+
const label = event.target.id;
|
|
43
|
+
if (!includes(label, value)) {
|
|
44
|
+
setFieldValue(fieldName, [...value, label]);
|
|
45
|
+
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
setFieldValue(
|
|
50
|
+
fieldName,
|
|
51
|
+
value?.filter((elm) => !equals(elm, label))
|
|
52
|
+
);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
return useMemoComponent({
|
|
56
|
+
Component: hideCheckbox ? (
|
|
57
|
+
<Box />
|
|
58
|
+
) : (
|
|
59
|
+
<Box>
|
|
60
|
+
{additionalLabel && <Typography>{additionalLabel}</Typography>}
|
|
61
|
+
<CheckboxGroupComponent
|
|
62
|
+
dataTestId={dataTestId || ''}
|
|
63
|
+
direction={checkbox?.direction}
|
|
64
|
+
disabled={disabled}
|
|
65
|
+
labelPlacement={checkbox?.labelPlacement || 'end'}
|
|
66
|
+
options={checkbox?.options as Array<string>}
|
|
67
|
+
values={value}
|
|
68
|
+
onChange={handleChange}
|
|
69
|
+
/>
|
|
70
|
+
</Box>
|
|
71
|
+
),
|
|
72
|
+
memoProps: [value, disabled, hideCheckbox]
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export default CheckboxGroup;
|
package/src/Form/Inputs/Grid.tsx
CHANGED
|
@@ -23,14 +23,16 @@ const useStyles = makeStyles<StylesProps>()(
|
|
|
23
23
|
);
|
|
24
24
|
|
|
25
25
|
const Grid = ({ grid }: InputPropsWithoutGroup): JSX.Element => {
|
|
26
|
-
const { classes } = useStyles({
|
|
26
|
+
const { classes, cx } = useStyles({
|
|
27
27
|
alignItems: grid?.alignItems,
|
|
28
28
|
columns: grid?.columns.length,
|
|
29
29
|
gridTemplateColumns: grid?.gridTemplateColumns
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
+
const className = grid?.className || '';
|
|
33
|
+
|
|
32
34
|
return (
|
|
33
|
-
<div className={classes.gridFields}>
|
|
35
|
+
<div className={cx(classes.gridFields, className)}>
|
|
34
36
|
{grid?.columns.map((field) => {
|
|
35
37
|
const Input = getInput(field.type);
|
|
36
38
|
|