15768: made new filters.ts file Arvados-DCO-1.1-Signed-off-by: Lisa Knox <lisa.knox...
[arvados-workbench2.git] / src / components / checkbox-field / checkbox-field.tsx
index 48737eeb6377b4d55879ef27c9dd7749fe850820..accd1e698067627d640063fde7e1478dd8ff4fe6 100644 (file)
@@ -2,20 +2,18 @@
 //
 // SPDX-License-Identifier: AGPL-3.0
 
-import * as React from 'react';
+import React from 'react';
 import { WrappedFieldProps } from 'redux-form';
-import { ArvadosTheme } from '~/common/custom-theme';
-import { FormControlLabel, Checkbox, StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core';
+import {
+    FormControlLabel,
+    Checkbox,
+    FormControl,
+    FormGroup,
+    FormLabel,
+    FormHelperText
+} from '@material-ui/core';
 
-type CssRules = 'checkboxField';
-
-const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
-    checkboxField: {
-
-    }
-});
-
-export const CheckboxField = withStyles(styles)((props: WrappedFieldProps & WithStyles<CssRules> & { label?: string }) =>
+export const CheckboxField = (props: WrappedFieldProps & { label?: string }) =>
     <FormControlLabel
         control={
             <Checkbox
@@ -24,5 +22,56 @@ export const CheckboxField = withStyles(styles)((props: WrappedFieldProps & With
                 disabled={props.meta.submitting}
                 color="primary" />
         }
-        label={props.label} 
-    />);
\ No newline at end of file
+        label={props.label}
+    />;
+
+type MultiCheckboxFieldProps = {
+    items: string[];
+    defaultValues?: string[];
+    label?: string;
+    minSelection?: number;
+    maxSelection?: number;
+    helperText?: string;
+    rowLayout?: boolean;
+}
+
+export const MultiCheckboxField = (props: WrappedFieldProps & MultiCheckboxFieldProps) => {
+    const isValid = (items: string[]) => (items.length >= (props.minSelection || 0)) &&
+        (items.length <= (props.maxSelection || items.length));
+    if (props.input.value.length === 0 && (props.defaultValues || []).length !== 0) {
+        props.input.value = props.defaultValues ? [...props.defaultValues] : [];
+    }
+    return <FormControl error={!isValid(props.input.value)}>
+        <FormLabel component='label'>{props.label}</FormLabel>
+        <FormGroup row={props.rowLayout}>
+        { props.items.map((item, idx) =>
+            <FormControlLabel
+                key={`label-${idx}`}
+                control={
+                    <Checkbox
+                        data-cy={`checkbox-${item}`}
+                        key={`control-${idx}`}
+                        name={`${props.input.name}[${idx}]`}
+                        value={item}
+                        checked={
+                            props.input.value.indexOf(item) !== -1 ||
+                            (props.input.value.length === 0 &&
+                                (props.defaultValues || []).indexOf(item) !== -1)
+                        }
+                        onChange={e => {
+                            const newValue = [...props.input.value];
+                            if (e.target.checked) {
+                                newValue.push(item);
+                            } else {
+                                newValue.splice(newValue.indexOf(item), 1);
+                            }
+                            if (!isValid(newValue)) { return; }
+                            return props.input.onChange(newValue);
+                        }}
+                        disabled={props.meta.submitting}
+                        color="primary" />
+                }
+                label={item} />) }
+        </FormGroup>
+        <FormHelperText>{props.helperText}</FormHelperText>
+    </FormControl> };
\ No newline at end of file