Improve validation
[arvados-workbench2.git] / src / views / run-process-panel / inputs / float-input.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import * as React from 'react';
6 import { FloatCommandInputParameter, isRequiredInput } from '~/models/workflow';
7 import { Field } from 'redux-form';
8 import { isNumber } from '~/validators/is-number';
9 import { GenericInput } from '~/views/run-process-panel/inputs/generic-input';
10 import { Input as MaterialInput } from '@material-ui/core';
11 import { GenericInputProps } from './generic-input';
12 export interface FloatInputProps {
13     input: FloatCommandInputParameter;
14 }
15 export const FloatInput = ({ input }: FloatInputProps) =>
16     <Field
17         name={input.id}
18         commandInput={input}
19         component={FloatInputComponent}
20         parse={parseFloat}
21         format={value => isNaN(value) ? '' : JSON.stringify(value)}
22         validate={[
23             isRequiredInput(input)
24                 ? isNumber
25                 : () => undefined,]} />;
26
27 class FloatInputComponent extends React.Component<GenericInputProps> {
28     state = {
29         endsWithDecimalSeparator: false,
30     };
31
32     handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
33         const [base, fraction] = event.target.value.split('.');
34         this.setState({ endsWithDecimalSeparator: fraction === '' });
35         this.props.input.onChange(event);
36     }
37
38     render() {
39         const props = {
40             ...this.props,
41             input: {
42                 ...this.props.input,
43                 value: this.props.input.value + (this.state.endsWithDecimalSeparator ? '.' : ''),
44                 onChange: this.handleChange,
45             },
46         };
47         return <GenericInput
48             component={Input}
49             {...props} />;
50     }
51 }
52
53 const Input = (props: GenericInputProps) =>
54     <MaterialInput fullWidth {...props.input} error={props.meta.touched && !!props.meta.error} />;