@centreon/ui 23.10.18-MON-17793-create-graph-component-centreon-ui.13 → 23.10.18-MON-17793-create-graph-component-centreon-ui.14

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.
Files changed (74) hide show
  1. package/package.json +1 -1
  2. package/src/Checkbox/Checkbox.tsx +107 -0
  3. package/src/Checkbox/CheckboxGroup/index.stories.tsx +41 -0
  4. package/src/Checkbox/CheckboxGroup/index.tsx +66 -0
  5. package/src/Checkbox/index.stories.tsx +39 -0
  6. package/src/Checkbox/index.tsx +2 -0
  7. package/src/Form/CollapsibleGroup.tsx +11 -5
  8. package/src/Form/Form.stories.tsx +1 -1
  9. package/src/Form/Form.tsx +24 -9
  10. package/src/Form/Inputs/Checkbox.tsx +57 -0
  11. package/src/Form/Inputs/CheckboxGroup.tsx +76 -0
  12. package/src/Form/Inputs/Grid.tsx +4 -2
  13. package/src/Form/Inputs/index.tsx +29 -7
  14. package/src/Form/Inputs/models.ts +13 -1
  15. package/src/Form/storiesData.tsx +45 -0
  16. package/src/Graph/BasicComponents/Lines/StackedLines/index.tsx +36 -20
  17. package/src/Graph/BasicComponents/Lines/index.tsx +101 -82
  18. package/src/Graph/Graph.tsx +24 -129
  19. package/src/Graph/Header/index.tsx +35 -23
  20. package/src/Graph/{IntercatifsComponents → InteractiveComponents}/AnchorPoint/RegularAnchorPoint.tsx +14 -13
  21. package/src/Graph/{IntercatifsComponents → InteractiveComponents}/AnchorPoint/StackedAnchorPoint.tsx +8 -19
  22. package/src/Graph/InteractiveComponents/AnchorPoint/useTickGraph.ts +57 -0
  23. package/src/Graph/{IntercatifsComponents → InteractiveComponents}/Annotations/useAnnotation.ts +6 -12
  24. package/src/Graph/{IntercatifsComponents → InteractiveComponents}/ZoomPreview/index.tsx +1 -3
  25. package/src/Graph/{IntercatifsComponents → InteractiveComponents}/ZoomPreview/models.ts +0 -3
  26. package/src/Graph/{IntercatifsComponents → InteractiveComponents}/ZoomPreview/useZoomPreview.ts +7 -13
  27. package/src/Graph/{IntercatifsComponents → InteractiveComponents}/index.tsx +44 -13
  28. package/src/Graph/{IntercatifsComponents → InteractiveComponents}/interactionWithGraphAtoms.ts +0 -1
  29. package/src/Graph/Legend/index.tsx +16 -2
  30. package/src/Graph/Legend/useInteractiveValues.ts +10 -8
  31. package/src/Graph/graphAtoms.ts +1 -0
  32. package/src/Graph/helpers/doc.ts +2 -2
  33. package/src/Graph/index.stories.tsx +1 -1
  34. package/src/Graph/index.tsx +3 -3
  35. package/src/Graph/mockedData/annotationData.json +182 -45
  36. package/src/Graph/mockedData/lastDay.json +1179 -1179
  37. package/src/Graph/mockedData/lastDayAreaStack.json +3106 -0
  38. package/src/Graph/mockedData/lastDayForward.json +751 -751
  39. package/src/Graph/mockedData/lastWeek.json +2045 -2045
  40. package/src/Graph/mockedData/zoomPreview.json +591 -199
  41. package/src/Graph/models.ts +4 -13
  42. package/src/Panel/index.tsx +6 -4
  43. package/src/RichTextEditor/ContentEditable.tsx +27 -7
  44. package/src/RichTextEditor/RichTextEditor.tsx +86 -45
  45. package/src/ThemeProvider/index.tsx +4 -1
  46. package/src/ThemeProvider/palettes.ts +7 -0
  47. package/src/index.ts +2 -0
  48. package/src/utils/index.ts +1 -0
  49. package/src/utils/panelSize.ts +15 -0
  50. package/src/Graph/BasicComponents/Lines/RegularLines/useDataRegularLines.ts +0 -37
  51. package/src/Graph/BasicComponents/Lines/StackedLines/useDataStackLines.ts +0 -57
  52. package/src/Graph/IntercatifsComponents/AnchorPoint/useAnchorPoint.ts +0 -107
  53. /package/src/Graph/{IntercatifsComponents → InteractiveComponents}/AnchorPoint/index.tsx +0 -0
  54. /package/src/Graph/{IntercatifsComponents → InteractiveComponents}/AnchorPoint/models.ts +0 -0
  55. /package/src/Graph/{IntercatifsComponents → InteractiveComponents}/Annotations/Annotation/Area.tsx +0 -0
  56. /package/src/Graph/{IntercatifsComponents → InteractiveComponents}/Annotations/Annotation/Line.tsx +0 -0
  57. /package/src/Graph/{IntercatifsComponents → InteractiveComponents}/Annotations/Annotation/index.tsx +0 -0
  58. /package/src/Graph/{IntercatifsComponents → InteractiveComponents}/Annotations/Area/Downtime.tsx +0 -0
  59. /package/src/Graph/{IntercatifsComponents → InteractiveComponents}/Annotations/EventAnnotations.tsx +0 -0
  60. /package/src/Graph/{IntercatifsComponents → InteractiveComponents}/Annotations/Line/Acknowledgement.tsx +0 -0
  61. /package/src/Graph/{IntercatifsComponents → InteractiveComponents}/Annotations/Line/Comments.tsx +0 -0
  62. /package/src/Graph/{IntercatifsComponents → InteractiveComponents}/Annotations/annotationsAtoms.ts +0 -0
  63. /package/src/Graph/{IntercatifsComponents → InteractiveComponents}/Annotations/index.tsx +0 -0
  64. /package/src/Graph/{IntercatifsComponents → InteractiveComponents}/Annotations/models.ts +0 -0
  65. /package/src/Graph/{IntercatifsComponents → InteractiveComponents}/Bar.tsx +0 -0
  66. /package/src/Graph/{IntercatifsComponents → InteractiveComponents}/TimeShiftZones/TimeShiftIcon.tsx +0 -0
  67. /package/src/Graph/{IntercatifsComponents → InteractiveComponents}/TimeShiftZones/TimeShiftZone.tsx +0 -0
  68. /package/src/Graph/{IntercatifsComponents → InteractiveComponents}/TimeShiftZones/index.tsx +0 -0
  69. /package/src/Graph/{IntercatifsComponents → InteractiveComponents}/TimeShiftZones/models.ts +0 -0
  70. /package/src/Graph/{IntercatifsComponents → InteractiveComponents}/TimeShiftZones/useTimeShiftZones.ts +0 -0
  71. /package/src/Graph/{IntercatifsComponents → InteractiveComponents}/Tooltip/index.tsx +0 -0
  72. /package/src/Graph/{IntercatifsComponents → InteractiveComponents}/Tooltip/models.ts +0 -0
  73. /package/src/Graph/{IntercatifsComponents → InteractiveComponents}/Tooltip/useGraphTooltip.ts +0 -0
  74. /package/src/Graph/{IntercatifsComponents → InteractiveComponents}/ZoomPreview/zoomPreviewAtoms.ts +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@centreon/ui",
3
- "version": "23.10.18-MON-17793-create-graph-component-centreon-ui.13",
3
+ "version": "23.10.18-MON-17793-create-graph-component-centreon-ui.14",
4
4
  "description": "Centreon UI Components",
5
5
  "scripts": {
6
6
  "eslint": "eslint ./src --ext .js,.jsx,.ts,.tsx --max-warnings 0",
@@ -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
+ };
@@ -0,0 +1,2 @@
1
+ export { default as CheckboxGroup } from './CheckboxGroup';
2
+ export { default as Checkbox } from './Checkbox';
@@ -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">{t(group?.name as string)}</Typography>
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 className={classes.form}>
67
- <Inputs
68
- groupDirection={groupDirection}
69
- groups={groups}
70
- inputs={inputs}
71
- isCollapsible={isCollapsible}
72
- />
73
- <Buttons />
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;
@@ -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
 
@@ -18,6 +18,8 @@ import TextInput from './Text';
18
18
  import ConnectedAutocomplete from './ConnectedAutocomplete';
19
19
  import FieldsTable from './FieldsTable/FieldsTable';
20
20
  import Grid from './Grid';
21
+ import CheckboxGroup from './CheckboxGroup';
22
+ import Checkbox from './Checkbox';
21
23
  import Custom from './Custom';
22
24
  import LoadingSkeleton from './LoadingSkeleton';
23
25
 
@@ -61,7 +63,15 @@ export const getInput = R.cond<
61
63
  R.always(FieldsTable)
62
64
  ],
63
65
  [R.equals(InputType.Grid) as (b: InputType) => boolean, R.always(Grid)],
64
- [R.equals(InputType.Custom) as (b: InputType) => boolean, R.always(Custom)]
66
+ [R.equals(InputType.Custom) as (b: InputType) => boolean, R.always(Custom)],
67
+ [
68
+ R.equals(InputType.Checkbox) as (b: InputType) => boolean,
69
+ R.always(Checkbox)
70
+ ],
71
+ [
72
+ R.equals(InputType.CheckboxGroup) as (b: InputType) => boolean,
73
+ R.always(CheckboxGroup)
74
+ ]
65
75
  ]);
66
76
 
67
77
  interface StylesProps {
@@ -89,7 +99,9 @@ const useStyles = makeStyles<StylesProps>()((theme, { groupDirection }) => ({
89
99
  ? 'row'
90
100
  : 'column'
91
101
  },
92
- inputWrapper: { width: '100%' },
102
+ inputWrapper: {
103
+ width: '100%'
104
+ },
93
105
  inputs: {
94
106
  display: 'flex',
95
107
  flexDirection: 'column',
@@ -99,8 +111,10 @@ const useStyles = makeStyles<StylesProps>()((theme, { groupDirection }) => ({
99
111
  }));
100
112
 
101
113
  interface Props {
114
+ areGroupsOpen?: boolean;
102
115
  groupDirection?: GroupDirection;
103
116
  groups?: Array<Group>;
117
+ groupsClassName?: string;
104
118
  inputs: Array<InputProps>;
105
119
  isCollapsible: boolean;
106
120
  isLoading?: boolean;
@@ -111,9 +125,11 @@ const Inputs = ({
111
125
  groups = [],
112
126
  isLoading = false,
113
127
  isCollapsible,
114
- groupDirection
128
+ groupDirection,
129
+ groupsClassName,
130
+ areGroupsOpen
115
131
  }: Props): JSX.Element => {
116
- const { classes } = useStyles({ groupDirection });
132
+ const { classes, cx } = useStyles({ groupDirection });
117
133
  const { t } = useTranslation();
118
134
  const formikContext = useFormikContext<FormikValues>();
119
135
 
@@ -178,12 +194,13 @@ const Inputs = ({
178
194
  ? R.find(R.propEq('name', groupName), groups)
179
195
  : ({} as Group);
180
196
 
181
- const isFirstElement = R.equals(index, 0);
197
+ const isFirstElement = areGroupsOpen || R.equals(index, 0);
182
198
 
183
199
  return (
184
200
  <Fragment key={groupName}>
185
201
  <div>
186
202
  <CollapsibleGroup
203
+ className={groupsClassName}
187
204
  defaultIsOpen={isFirstElement}
188
205
  group={groupProps}
189
206
  hasGroupTitle={hasGroupTitle}
@@ -209,13 +226,18 @@ const Inputs = ({
209
226
  >
210
227
  {inputProps.additionalLabel && (
211
228
  <Typography
212
- className={classes.additionalLabel}
229
+ className={cx(
230
+ classes.additionalLabel,
231
+ inputProps?.additionalLabelClassName
232
+ )}
213
233
  variant="body1"
214
234
  >
215
235
  {t(inputProps.additionalLabel)}
216
236
  </Typography>
217
237
  )}
218
- <Input {...inputProps} />
238
+ <div className={inputProps?.inputClassName || ''}>
239
+ <Input {...inputProps} />
240
+ </div>
219
241
  </div>
220
242
  );
221
243
  })}