X-Git-Url: https://git.arvados.org/arvados-workbench2.git/blobdiff_plain/32dcbe112366f6ce4037e87527aac5ea7865bee0..fb10daa75864def53d1f0ffa7da3cece8cebe9d0:/src/components/checkbox-field/checkbox-field.tsx

diff --git a/src/components/checkbox-field/checkbox-field.tsx b/src/components/checkbox-field/checkbox-field.tsx
index a5d5b285..accd1e69 100644
--- a/src/components/checkbox-field/checkbox-field.tsx
+++ b/src/components/checkbox-field/checkbox-field.tsx
@@ -2,9 +2,16 @@
 //
 // SPDX-License-Identifier: AGPL-3.0
 
-import * as React from 'react';
+import React from 'react';
 import { WrappedFieldProps } from 'redux-form';
-import { FormControlLabel, Checkbox } from '@material-ui/core';
+import {
+    FormControlLabel,
+    Checkbox,
+    FormControl,
+    FormGroup,
+    FormLabel,
+    FormHelperText
+} from '@material-ui/core';
 
 export const CheckboxField = (props: WrappedFieldProps & { label?: string }) =>
     <FormControlLabel
@@ -15,5 +22,56 @@ export const CheckboxField = (props: WrappedFieldProps & { label?: string }) =>
                 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
