Improve validation
[arvados-workbench2.git] / src / views / run-process-panel / inputs / float-input.tsx
index 0f5a116280793671dda3c3d86ca23f4f8c983a49..aeaf6cdd48dd8aa4bb0d420b7a7d24e314bad7ff 100644 (file)
@@ -3,20 +3,52 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as React from 'react';
-import { getInputLabel, FloatCommandInputParameter } from '~/models/workflow';
+import { FloatCommandInputParameter, isRequiredInput } from '~/models/workflow';
 import { Field } from 'redux-form';
-import { TextField } from '~/components/text-field/text-field';
 import { isNumber } from '~/validators/is-number';
-import { toNumber } from 'lodash';
+import { GenericInput } from '~/views/run-process-panel/inputs/generic-input';
+import { Input as MaterialInput } from '@material-ui/core';
+import { GenericInputProps } from './generic-input';
 export interface FloatInputProps {
     input: FloatCommandInputParameter;
 }
 export const FloatInput = ({ input }: FloatInputProps) =>
     <Field
         name={input.id}
-        label={getInputLabel(input)}
-        component={TextField}
-        parse={value => toNumber(value)}
+        commandInput={input}
+        component={FloatInputComponent}
+        parse={parseFloat}
         format={value => isNaN(value) ? '' : JSON.stringify(value)}
-        validate={[isNumber]} />;
+        validate={[
+            isRequiredInput(input)
+                ? isNumber
+                : () => undefined,]} />;
 
+class FloatInputComponent extends React.Component<GenericInputProps> {
+    state = {
+        endsWithDecimalSeparator: false,
+    };
+
+    handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
+        const [base, fraction] = event.target.value.split('.');
+        this.setState({ endsWithDecimalSeparator: fraction === '' });
+        this.props.input.onChange(event);
+    }
+
+    render() {
+        const props = {
+            ...this.props,
+            input: {
+                ...this.props.input,
+                value: this.props.input.value + (this.state.endsWithDecimalSeparator ? '.' : ''),
+                onChange: this.handleChange,
+            },
+        };
+        return <GenericInput
+            component={Input}
+            {...props} />;
+    }
+}
+
+const Input = (props: GenericInputProps) =>
+    <MaterialInput fullWidth {...props.input} error={props.meta.touched && !!props.meta.error} />;