Add float array input
authorMichal Klobukowski <michal.klobukowski@contractors.roche.com>
Sun, 21 Oct 2018 20:14:12 +0000 (22:14 +0200)
committerMichal Klobukowski <michal.klobukowski@contractors.roche.com>
Sun, 21 Oct 2018 20:14:12 +0000 (22:14 +0200)
Feature #13862

Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski@contractors.roche.com>

src/components/float-input/float-input.tsx
src/index.tsx
src/models/workflow.ts
src/views/run-process-panel/inputs/float-array-input.tsx [new file with mode: 0644]
src/views/run-process-panel/run-process-inputs-form.tsx

index b032319a7e1c83c37c5890990c1192e647210b46..16e18cb1451f143f5267281266ae1d4a7278de9a 100644 (file)
@@ -15,13 +15,17 @@ export class FloatInput extends React.Component<InputProps> {
         const { onChange = () => { return; } } = this.props;
         const [, fraction] = event.target.value.split('.');
         this.setState({ endsWithDecimalSeparator: fraction === '' });
+        const parsedValue = parseFloat(event.target.value).toString();
+        event.target.value = parsedValue;
         onChange(event);
     }
 
     render() {
+        const parsedValue = parseFloat(typeof this.props.value === 'string' ? this.props.value : '');
+        const value = isNaN(parsedValue) ? '' : parsedValue.toString();
         const props = {
             ...this.props,
-            value: this.props.value + (this.state.endsWithDecimalSeparator ? '.' : ''),
+            value: value + (this.state.endsWithDecimalSeparator ? '.' : ''),
             onChange: this.handleChange,
         };
         return <Input {...props} />;
index 77de5abe7058398f75c7511a6820492cddeaaed9..d83abf76c7323bb914011c319328a27c1564785d 100644 (file)
@@ -131,9 +131,9 @@ const createDirectoriesArrayCollectorWorkflow = ({ workflowService }: ServiceRep
 
 const createPrimitiveArraysCollectorWorkflow = ({ workflowService }: ServiceRepository) => {
     workflowService.create({
-        name: 'Primitive data arrays collector',
+        name: 'String, Int and Float arrays collector',
         description: 'Workflow for collecting primitive data arrays',
-        definition: "cwlVersion: v1.0\n$graph:\n- class: CommandLineTool\n\n  requirements:\n  - listing:\n    - entryname: input_collector.log\n      entry: |\n        \"string array\":\n          $(inputs.example_string_array)\n        \"int array\":\n          $(inputs.example_int_array)\n        \"float array\":\n          $(inputs.example_float_array)\n\n    class: InitialWorkDirRequirement\n  inputs:\n  - type:\n      type: array\n      items: string\n    id: '#input_collector.cwl/example_string_array'\n  - type:\n      type: array\n      items: int\n    id: '#input_collector.cwl/example_int_array'\n  - type:\n      type: array\n      items: float\n    id: '#input_collector.cwl/example_float_array'\n  \n  outputs:\n  - type: File\n    outputBinding:\n      glob: '*'\n    id: '#input_collector.cwl/output'\n\n  baseCommand: [echo]\n  id: '#input_collector.cwl'\n- class: Workflow\n  doc: This is the description of the workflow\n  inputs:\n  - type:\n      type: array\n      items: string\n    label: Freetext Array\n    doc: This should allow for entering multiple strings.\n    id: '#main/example_string_array'\n    default:\n    - This is the first string\n    - This is the second string\n  - type:\n      type: array\n      items: int\n    label: Integer Array\n    doc: This should allow for entering multiple integers.\n    id: '#main/example_int_array'\n    default:\n    - 3\n    - 6\n  - type:\n      type: array\n      items: int\n    label: Float Array\n    doc: This should allow for entering multiple floats.\n    id: '#main/example_float_array'\n    default:\n    - 3.33\n    - 66.6\n\n  outputs:\n  - type: File\n    outputSource: '#main/input_collector/output'\n\n    id: '#main/log_file'\n  steps:\n  - run: '#input_collector.cwl'\n    in:\n    - source: '#main/example_string_array'\n      id: '#main/input_collector/example_string_array'\n    - source: '#main/example_int_array'\n      id: '#main/input_collector/example_int_array'\n    - source: '#main/example_float_array'\n      id: '#main/input_collector/example_float_array'\n    out: ['#main/input_collector/output']\n    id: '#main/input_collector'\n  id: '#main'\n",
+        definition: "cwlVersion: v1.0\n$graph:\n- class: CommandLineTool\n\n  requirements:\n  - listing:\n    - entryname: input_collector.log\n      entry: |\n        \"string array\":\n          $(inputs.example_string_array)\n        \"int array\":\n          $(inputs.example_int_array)\n        \"float array\":\n          $(inputs.example_float_array)\n\n    class: InitialWorkDirRequirement\n  inputs:\n  - type:\n      type: array\n      items: string\n    id: '#input_collector.cwl/example_string_array'\n  - type:\n      type: array\n      items: int\n    id: '#input_collector.cwl/example_int_array'\n  - type:\n      type: array\n      items: float\n    id: '#input_collector.cwl/example_float_array'\n  \n  outputs:\n  - type: File\n    outputBinding:\n      glob: '*'\n    id: '#input_collector.cwl/output'\n\n  baseCommand: [echo]\n  id: '#input_collector.cwl'\n- class: Workflow\n  doc: This is the description of the workflow\n  inputs:\n  - type:\n      type: array\n      items: string\n    label: Freetext Array\n    doc: This should allow for entering multiple strings.\n    id: '#main/example_string_array'\n    default:\n    - This is the first string\n    - This is the second string\n  - type:\n      type: array\n      items: int\n    label: Integer Array\n    doc: This should allow for entering multiple integers.\n    id: '#main/example_int_array'\n    default:\n    - 3\n    - 6\n  - type:\n      type: array\n      items: float\n    label: Float Array\n    doc: This should allow for entering multiple floats.\n    id: '#main/example_float_array'\n    default:\n    - 3.33\n    - 66.6\n\n  outputs:\n  - type: File\n    outputSource: '#main/input_collector/output'\n\n    id: '#main/log_file'\n  steps:\n  - run: '#input_collector.cwl'\n    in:\n    - source: '#main/example_string_array'\n      id: '#main/input_collector/example_string_array'\n    - source: '#main/example_int_array'\n      id: '#main/input_collector/example_int_array'\n    - source: '#main/example_float_array'\n      id: '#main/input_collector/example_float_array'\n    out: ['#main/input_collector/output']\n    id: '#main/input_collector'\n  id: '#main'\n",
     });
 };
 
index 59915137427d118167dd14d174574a3fcbdbf3f6..a342dbbfc5fde437e8dbdfb101f8ae3d612ce559 100644 (file)
@@ -41,6 +41,8 @@ export type CommandInputParameter =
     FileCommandInputParameter |
     DirectoryCommandInputParameter |
     StringArrayCommandInputParameter |
+    IntArrayCommandInputParameter |
+    FloatArrayCommandInputParameter |
     FileArrayCommandInputParameter |
     DirectoryArrayCommandInputParameter |
     EnumCommandInputParameter;
@@ -104,6 +106,8 @@ export type DirectoryCommandInputParameter = GenericCommandInputParameter<CWLTyp
 export type EnumCommandInputParameter = GenericCommandInputParameter<CommandInputEnumSchema, string>;
 
 export type StringArrayCommandInputParameter = GenericArrayCommandInputParameter<CWLType.STRING, string>;
+export type IntArrayCommandInputParameter = GenericArrayCommandInputParameter<CWLType.INT, string>;
+export type FloatArrayCommandInputParameter = GenericArrayCommandInputParameter<CWLType.FLOAT, string>;
 export type FileArrayCommandInputParameter = GenericArrayCommandInputParameter<CWLType.FILE, File>;
 export type DirectoryArrayCommandInputParameter = GenericArrayCommandInputParameter<CWLType.DIRECTORY, Directory>;
 
diff --git a/src/views/run-process-panel/inputs/float-array-input.tsx b/src/views/run-process-panel/inputs/float-array-input.tsx
new file mode 100644 (file)
index 0000000..2b6f48c
--- /dev/null
@@ -0,0 +1,64 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from 'react';
+import { isRequiredInput, FloatArrayCommandInputParameter } from '~/models/workflow';
+import { Field } from 'redux-form';
+import { ERROR_MESSAGE } from '~/validators/require';
+import { GenericInputProps, GenericInput } from '~/views/run-process-panel/inputs/generic-input';
+import { ChipsInput } from '~/components/chips-input/chips-input';
+import { identity } from 'lodash';
+import { createSelector } from 'reselect';
+import { FloatInput } from '~/components/float-input/float-input';
+
+export interface FloatArrayInputProps {
+    input: FloatArrayCommandInputParameter;
+}
+export const FloatArrayInput = ({ input }: FloatArrayInputProps) =>
+    <Field
+        name={input.id}
+        commandInput={input}
+        component={FloatArrayInputComponent}
+        validate={validationSelector(input)} />;
+
+
+const validationSelector = createSelector(
+    isRequiredInput,
+    isRequired => isRequired
+        ? [required]
+        : undefined
+);
+
+const required = (value: string[]) =>
+    value.length > 0
+        ? undefined
+        : ERROR_MESSAGE;
+
+const FloatArrayInputComponent = (props: GenericInputProps) =>
+    <GenericInput
+        component={InputComponent}
+        {...props} />;
+
+class InputComponent extends React.PureComponent<GenericInputProps>{
+    render() {
+        return <ChipsInput
+            deletable
+            orderable
+            value={this.props.input.value}
+            onChange={this.handleChange}
+            createNewValue={identity}
+            inputComponent={FloatInput}
+            inputProps={{
+                error: this.props.meta.error,
+            }} />;
+    }
+
+    handleChange = (values: {}[]) => {
+        const { input, meta } = this.props;
+        if (!meta.touched) {
+            input.onBlur(values);
+        }
+        input.onChange(values);
+    }
+}
index 8ec51f6b4cda9b60fb2403ff2e89dcc4bcb650fd..c985dff11eddc2534cc5acc57dd8e77fd366899f 100644 (file)
@@ -4,7 +4,7 @@
 
 import * as React from 'react';
 import { reduxForm, InjectedFormProps } from 'redux-form';
-import { CommandInputParameter, CWLType, IntCommandInputParameter, BooleanCommandInputParameter, FileCommandInputParameter, DirectoryCommandInputParameter, DirectoryArrayCommandInputParameter } from '~/models/workflow';
+import { CommandInputParameter, CWLType, IntCommandInputParameter, BooleanCommandInputParameter, FileCommandInputParameter, DirectoryCommandInputParameter, DirectoryArrayCommandInputParameter, FloatArrayCommandInputParameter } from '~/models/workflow';
 import { IntInput } from '~/views/run-process-panel/inputs/int-input';
 import { StringInput } from '~/views/run-process-panel/inputs/string-input';
 import { StringCommandInputParameter, FloatCommandInputParameter, isPrimitiveOfType, File, Directory, WorkflowInputsData, EnumCommandInputParameter, isArrayOfType, StringArrayCommandInputParameter, FileArrayCommandInputParameter } from '../../models/workflow';
@@ -20,6 +20,7 @@ import { StringArrayInput } from './inputs/string-array-input';
 import { createStructuredSelector, createSelector } from 'reselect';
 import { FileArrayInput } from './inputs/file-array-input';
 import { DirectoryArrayInput } from './inputs/directory-array-input';
+import { FloatArrayInput } from './inputs/float-array-input';
 
 export const RUN_PROCESS_INPUTS_FORM = 'runProcessInputsForm';
 
@@ -99,6 +100,9 @@ const getInputComponent = (input: CommandInputParameter) => {
 
         case isArrayOfType(input, CWLType.STRING):
             return <StringArrayInput input={input as StringArrayCommandInputParameter} />;
+        
+        case isArrayOfType(input, CWLType.FLOAT):
+            return <FloatArrayInput input={input as FloatArrayCommandInputParameter} />;
 
         case isArrayOfType(input, CWLType.FILE):
             return <FileArrayInput input={input as FileArrayCommandInputParameter} />;