Merge branch '20029-collection-batch-file-operations' into main. Closes #20029 and...
[arvados-workbench2.git] / src / views-components / virtual-machines-dialog / group-array-input.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import React from 'react';
6 import { StringArrayCommandInputParameter } from 'models/workflow';
7 import { Field, GenericField } from 'redux-form';
8 import { GenericInputProps } from 'views/run-process-panel/inputs/generic-input';
9 import { ChipsInput } from 'components/chips-input/chips-input';
10 import { identity } from 'lodash';
11 import { withStyles, WithStyles, FormGroup, Input, InputLabel, FormControl, FormHelperText } from '@material-ui/core';
12 import classnames from "classnames";
13 import { ArvadosTheme } from 'common/custom-theme';
14
15 export interface GroupArrayDataProps {
16   hasPartialGroupInput?: boolean;
17   setPartialGroupInput?: (value: boolean) => void;
18 }
19
20 interface GroupArrayFieldProps {
21   commandInput: StringArrayCommandInputParameter;
22 }
23
24 const GroupArrayField = Field as new () => GenericField<GroupArrayDataProps & GroupArrayFieldProps>;
25
26 export interface GroupArrayInputProps {
27   name: string;
28   input: StringArrayCommandInputParameter;
29   required: boolean;
30 }
31
32 type CssRules = 'chips' | 'partialInputHelper' | 'partialInputHelperVisible';
33
34 const styles = (theme: ArvadosTheme) => ({
35     chips: {
36         marginTop: "16px",
37     },
38     partialInputHelper: {
39         textAlign: 'right' as 'right',
40         visibility: 'hidden' as 'hidden',
41         color: theme.palette.error.dark,
42     },
43     partialInputHelperVisible: {
44         visibility: 'visible' as 'visible',
45     }
46 });
47
48 export const GroupArrayInput = ({name, input, setPartialGroupInput, hasPartialGroupInput}: GroupArrayInputProps & GroupArrayDataProps) => {
49   console.log(hasPartialGroupInput);
50   return <GroupArrayField
51       name={name}
52       commandInput={input}
53       component={GroupArrayInputComponent as any}
54       setPartialGroupInput={setPartialGroupInput}
55       hasPartialGroupInput={hasPartialGroupInput}
56       />;
57 }
58
59 const GroupArrayInputComponent = (props: GenericInputProps & GroupArrayDataProps) => {
60   return <FormGroup>
61         <FormControl fullWidth error={props.meta.error}>
62           <InputLabel shrink={props.meta.active || props.input.value.length > 0}>{props.commandInput.id}</InputLabel>
63           <StyledInputComponent {...props} />
64         </FormControl>
65     </FormGroup>;
66     };
67
68 const StyledInputComponent = withStyles(styles)(
69   class InputComponent extends React.PureComponent<GenericInputProps & WithStyles<CssRules> & GroupArrayDataProps>{
70       render() {
71           const { classes } = this.props;
72           const { commandInput, input, meta, hasPartialGroupInput } = this.props;
73           return <>
74             <ChipsInput
75                 deletable={!commandInput.disabled}
76                 orderable={!commandInput.disabled}
77                 disabled={commandInput.disabled}
78                 values={input.value}
79                 onChange={this.handleChange}
80                 handleFocus={input.onFocus}
81                 createNewValue={identity}
82                 inputComponent={Input}
83                 chipsClassName={classes.chips}
84                 pattern={/[_a-z][-0-9_a-z]*/ig}
85                 onPartialInput={this.props.setPartialGroupInput}
86                 inputProps={{
87                     error: meta.error || hasPartialGroupInput,
88                 }} />
89                 <FormHelperText className={classnames([classes.partialInputHelper, ...(hasPartialGroupInput ? [classes.partialInputHelperVisible] : [])])}>
90                   Press enter to complete group name
91                 </FormHelperText>
92           </>;
93       }
94
95       handleChange = (values: {}[]) => {
96         const { input, meta } = this.props;
97           if (!meta.touched) {
98               input.onBlur(values);
99           }
100           input.onChange(values);
101       }
102
103   }
104 );