values: Value[];
getLabel?: (value: Value) => string;
onChange: (value: Value[]) => void;
+ onPartialInput?: (value: boolean) => void;
handleFocus?: (e: any) => void;
handleBlur?: (e: any) => void;
chipsClassName?: string;
setText = (event: React.ChangeEvent<HTMLInputElement>) => {
this.setState({ text: event.target.value }, () => {
+ // Update partial input status
+ this.props.onPartialInput && this.props.onPartialInput(this.state.text !== '');
+
// If pattern is provided, check for delimiter
if (this.props.pattern) {
const matches = this.state.text.match(this.props.pattern);
this.setState({ text: '' });
this.props.onChange([...this.props.values, newValue]);
}
+ this.props.onPartialInput && this.props.onPartialInput(false);
}
}
import { FormDialog } from 'components/form-dialog/form-dialog';
import { VIRTUAL_MACHINE_ADD_LOGIN_DIALOG, VIRTUAL_MACHINE_ADD_LOGIN_FORM, addUpdateVirtualMachineLogin, AddLoginFormData, VIRTUAL_MACHINE_ADD_LOGIN_USER_FIELD, VIRTUAL_MACHINE_ADD_LOGIN_GROUPS_FIELD } from 'store/virtual-machines/virtual-machines-actions';
import { ParticipantSelect } from 'views-components/sharing-dialog/participant-select';
-import { GroupArrayInput } from 'views-components/virtual-machines-dialog/group-array-input';
+import { GroupArrayInput, GroupArrayDataProps } from 'views-components/virtual-machines-dialog/group-array-input';
export const VirtualMachineAddLoginDialog = compose(
withDialog(VIRTUAL_MACHINE_ADD_LOGIN_DIALOG),
}
})
)(
- (props: CreateGroupDialogComponentProps) =>
- <FormDialog
+ (props: CreateGroupDialogComponentProps) => {
+ const [hasPartialGroupInput, setPartialGroupInput] = React.useState<boolean>(false);
+
+ return <FormDialog
dialogTitle={props.data.updating ? "Update login permission" : "Add login permission"}
formFields={AddLoginFormFields}
submitLabel={props.data.updating ? "Update" : "Add"}
{...props}
- />
+ data={{
+ ...props.data,
+ setPartialGroupInput,
+ hasPartialGroupInput,
+ }}
+ invalid={props.invalid || hasPartialGroupInput}
+ />;
+ }
);
-type CreateGroupDialogComponentProps = WithDialogProps<{updating: boolean}> & InjectedFormProps<AddLoginFormData>;
+type CreateGroupDialogComponentProps = WithDialogProps<{updating: boolean}> & GroupArrayDataProps & InjectedFormProps<AddLoginFormData>;
const AddLoginFormFields = (props) => {
return <>
name={VIRTUAL_MACHINE_ADD_LOGIN_GROUPS_FIELD}
input={{id:"Add groups to VM login (eg: docker, sudo)", disabled:false}}
required={false}
+ setPartialGroupInput={props.data.setPartialGroupInput}
+ hasPartialGroupInput={props.data.hasPartialGroupInput}
/>
</>;
}
import React from 'react';
import { StringArrayCommandInputParameter } from 'models/workflow';
-import { Field } from 'redux-form';
+import { Field, GenericField } from 'redux-form';
import { GenericInputProps } from 'views/run-process-panel/inputs/generic-input';
import { ChipsInput } from 'components/chips-input/chips-input';
import { identity } from 'lodash';
-import { withStyles, WithStyles, FormGroup, Input, InputLabel, FormControl } from '@material-ui/core';
+import { withStyles, WithStyles, FormGroup, Input, InputLabel, FormControl, FormHelperText } from '@material-ui/core';
+import classnames from "classnames";
+import { ArvadosTheme } from 'common/custom-theme';
-export interface StringArrayInputProps {
+export interface GroupArrayDataProps {
+ hasPartialGroupInput?: boolean;
+ setPartialGroupInput?: (value: boolean) => void;
+}
+
+interface GroupArrayFieldProps {
+ commandInput: StringArrayCommandInputParameter;
+}
+
+const GroupArrayField = Field as new () => GenericField<GroupArrayDataProps & GroupArrayFieldProps>;
+
+export interface GroupArrayInputProps {
name: string;
input: StringArrayCommandInputParameter;
required: boolean;
}
-type CssRules = 'chips';
+type CssRules = 'chips' | 'partialInputHelper' | 'partialInputHelperVisible';
-const styles = {
+const styles = (theme: ArvadosTheme) => ({
chips: {
marginTop: "16px",
},
-};
+ partialInputHelper: {
+ textAlign: 'right' as 'right',
+ visibility: 'hidden' as 'hidden',
+ color: theme.palette.error.dark,
+ },
+ partialInputHelperVisible: {
+ visibility: 'visible' as 'visible',
+ }
+});
-export const GroupArrayInput = ({name, input}: StringArrayInputProps) =>
- <Field
- name={name}
- commandInput={input}
- component={StringArrayInputComponent as any}
- />;
+export const GroupArrayInput = ({name, input, setPartialGroupInput, hasPartialGroupInput}: GroupArrayInputProps & GroupArrayDataProps) => {
+ console.log(hasPartialGroupInput);
+ return <GroupArrayField
+ name={name}
+ commandInput={input}
+ component={GroupArrayInputComponent as any}
+ setPartialGroupInput={setPartialGroupInput}
+ hasPartialGroupInput={hasPartialGroupInput}
+ />;
+}
-const StringArrayInputComponent = (props: GenericInputProps) => {
+const GroupArrayInputComponent = (props: GenericInputProps & GroupArrayDataProps) => {
return <FormGroup>
<FormControl fullWidth error={props.meta.error}>
<InputLabel shrink={props.meta.active || props.input.value.length > 0}>{props.commandInput.id}</InputLabel>
};
const StyledInputComponent = withStyles(styles)(
- class InputComponent extends React.PureComponent<GenericInputProps & WithStyles<CssRules>>{
+ class InputComponent extends React.PureComponent<GenericInputProps & WithStyles<CssRules> & GroupArrayDataProps>{
render() {
const { classes } = this.props;
- const { commandInput, input, meta } = this.props;
- return <ChipsInput
- deletable={!commandInput.disabled}
- orderable={!commandInput.disabled}
- disabled={commandInput.disabled}
- values={input.value}
- onChange={this.handleChange}
- handleFocus={input.onFocus}
- createNewValue={identity}
- inputComponent={Input}
- chipsClassName={classes.chips}
- pattern={/[_a-z][-0-9_a-z]*/ig}
- inputProps={{
- error: meta.error,
- }} />;
+ const { commandInput, input, meta, hasPartialGroupInput } = this.props;
+ return <>
+ <ChipsInput
+ deletable={!commandInput.disabled}
+ orderable={!commandInput.disabled}
+ disabled={commandInput.disabled}
+ values={input.value}
+ onChange={this.handleChange}
+ handleFocus={input.onFocus}
+ createNewValue={identity}
+ inputComponent={Input}
+ chipsClassName={classes.chips}
+ pattern={/[_a-z][-0-9_a-z]*/ig}
+ onPartialInput={this.props.setPartialGroupInput}
+ inputProps={{
+ error: meta.error || hasPartialGroupInput,
+ }} />
+ <FormHelperText className={classnames([classes.partialInputHelper, ...(hasPartialGroupInput ? [classes.partialInputHelperVisible] : [])])}>
+ Press enter to complete group name
+ </FormHelperText>
+ </>;
}
handleChange = (values: {}[]) => {