From: Michal Klobukowski Date: Thu, 29 Nov 2018 16:24:22 +0000 (+0100) Subject: Merge branch '14524-run-a-process-white-screen' X-Git-Tag: 1.3.0~1 X-Git-Url: https://git.arvados.org/arvados-workbench2.git/commitdiff_plain/dbca22d752af6473a39e4f67c5fc0be355c80eaf?hp=7108a1b63584de629f0632f8179304216a5ec9bb Merge branch '14524-run-a-process-white-screen' refs #14524 Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski --- diff --git a/src/views/run-process-panel/inputs/boolean-input.tsx b/src/views/run-process-panel/inputs/boolean-input.tsx index 5da54742..6a214e9d 100644 --- a/src/views/run-process-panel/inputs/boolean-input.tsx +++ b/src/views/run-process-panel/inputs/boolean-input.tsx @@ -3,6 +3,7 @@ // SPDX-License-Identifier: AGPL-3.0 import * as React from 'react'; +import { memoize } from 'lodash/fp'; import { BooleanCommandInputParameter } from '~/models/workflow'; import { Field } from 'redux-form'; import { Switch } from '@material-ui/core'; @@ -16,17 +17,23 @@ export const BooleanInput = ({ input }: BooleanInputProps) => name={input.id} commandInput={input} component={BooleanInputComponent} - normalize={(value, prevValue) => !prevValue} + normalize={normalize} />; +const normalize = (_: any, prevValue: boolean) => !prevValue; + const BooleanInputComponent = (props: GenericInputProps) => ; -const Input = (props: GenericInputProps) => +const Input = ({ input, commandInput }: GenericInputProps) => props.input.onChange(props.input.value)} - disabled={props.commandInput.disabled} />; \ No newline at end of file + checked={input.value} + onChange={handleChange(input.onChange, input.value)} + disabled={commandInput.disabled} />; + +const handleChange = memoize( + (onChange: (value: string) => void, value: string) => () => onChange(value) +); diff --git a/src/views/run-process-panel/inputs/directory-input.tsx b/src/views/run-process-panel/inputs/directory-input.tsx index aa25fefc..29ccd6e0 100644 --- a/src/views/run-process-panel/inputs/directory-input.tsx +++ b/src/views/run-process-panel/inputs/directory-input.tsx @@ -3,23 +3,24 @@ // SPDX-License-Identifier: AGPL-3.0 import * as React from 'react'; +import { connect, DispatchProp } from 'react-redux'; +import { memoize } from 'lodash/fp'; +import { Field } from 'redux-form'; +import { Input, Dialog, DialogTitle, DialogContent, DialogActions, Button } from '@material-ui/core'; import { isRequiredInput, DirectoryCommandInputParameter, CWLType, Directory } from '~/models/workflow'; -import { Field } from 'redux-form'; -import { Input, Dialog, DialogTitle, DialogContent, DialogActions, Button } from '@material-ui/core'; import { GenericInputProps, GenericInput } from './generic-input'; import { ProjectsTreePicker } from '~/views-components/projects-tree-picker/projects-tree-picker'; -import { connect, DispatchProp } from 'react-redux'; import { initProjectsTreePicker } from '~/store/tree-picker/tree-picker-actions'; import { TreeItem } from '~/components/tree/tree'; import { ProjectsTreePickerItem } from '~/views-components/projects-tree-picker/generic-projects-tree-picker'; import { CollectionResource } from '~/models/collection'; import { ResourceKind } from '~/models/resource'; -import { ERROR_MESSAGE } from '../../../validators/require'; +import { ERROR_MESSAGE } from '~/validators/require'; export interface DirectoryInputProps { input: DirectoryCommandInputParameter; @@ -29,18 +30,25 @@ export const DirectoryInput = ({ input }: DirectoryInputProps) => name={input.id} commandInput={input} component={DirectoryInputComponent} - format={(value?: Directory) => value ? value.basename : ''} - parse={(directory: CollectionResource): Directory => ({ - class: CWLType.DIRECTORY, - location: `keep:${directory.portableDataHash}`, - basename: directory.name, - })} - validate={[ - isRequiredInput(input) - ? (directory?: Directory) => directory ? undefined : ERROR_MESSAGE - : () => undefined, - ]} />; - + format={format} + parse={parse} + validate={getValidation(input)} />; + +const format = (value?: Directory) => value ? value.basename : ''; + +const parse = (directory: CollectionResource): Directory => ({ + class: CWLType.DIRECTORY, + location: `keep:${directory.portableDataHash}`, + basename: directory.name, +}); + +const getValidation = memoize( + (input: DirectoryCommandInputParameter) => ([ + isRequiredInput(input) + ? (directory?: Directory) => directory ? undefined : ERROR_MESSAGE + : () => undefined, + ]) +); interface DirectoryInputComponentState { open: boolean; @@ -78,7 +86,7 @@ const DirectoryInputComponent = connect()( this.props.input.onChange(this.state.directory); } - setDirectory = (event: React.MouseEvent, { data }: TreeItem, pickerId: string) => { + setDirectory = (_: {}, { data }: TreeItem) => { if ('kind' in data && data.kind === ResourceKind.COLLECTION) { this.setState({ directory: data }); } else { diff --git a/src/views/run-process-panel/inputs/enum-input.tsx b/src/views/run-process-panel/inputs/enum-input.tsx index 86ff6fb1..3b0289e7 100644 --- a/src/views/run-process-panel/inputs/enum-input.tsx +++ b/src/views/run-process-panel/inputs/enum-input.tsx @@ -3,9 +3,9 @@ // SPDX-License-Identifier: AGPL-3.0 import * as React from 'react'; -import { EnumCommandInputParameter, CommandInputEnumSchema } from '~/models/workflow'; import { Field } from 'redux-form'; import { Select, MenuItem } from '@material-ui/core'; +import { EnumCommandInputParameter, CommandInputEnumSchema } from '~/models/workflow'; import { GenericInputProps, GenericInput } from './generic-input'; export interface EnumInputProps { @@ -30,8 +30,20 @@ const Input = (props: GenericInputProps) => { onChange={props.input.onChange} disabled={props.commandInput.disabled} > {type.symbols.map(symbol => - - {symbol.split('/').pop()} + + {extractValue(symbol)} )} ; -}; \ No newline at end of file +}; + +/** + * Values in workflow definition have an absolute form, for example: + * + * ```#input_collector.cwl/enum_type/Pathway table``` + * + * We want a value that is in form accepted by backend. + * According to the example above, the correct value is: + * + * ```Pathway table``` + */ +const extractValue = (symbol: string) => symbol.split('/').pop(); diff --git a/src/views/run-process-panel/inputs/file-input.tsx b/src/views/run-process-panel/inputs/file-input.tsx index 7e0925e8..06111007 100644 --- a/src/views/run-process-panel/inputs/file-input.tsx +++ b/src/views/run-process-panel/inputs/file-input.tsx @@ -3,6 +3,7 @@ // SPDX-License-Identifier: AGPL-3.0 import * as React from 'react'; +import { memoize } from 'lodash/fp'; import { isRequiredInput, FileCommandInputParameter, @@ -28,18 +29,24 @@ export const FileInput = ({ input }: FileInputProps) => name={input.id} commandInput={input} component={FileInputComponent} - format={(value?: File) => value ? value.basename : ''} - parse={(file: CollectionFile): File => ({ - class: CWLType.FILE, - location: `keep:${file.id}`, - basename: file.name, - })} - validate={[ - isRequiredInput(input) - ? (file?: File) => file ? undefined : ERROR_MESSAGE - : () => undefined, - ]} />; + format={format} + parse={parse} + validate={getValidation(input)} />; +const format = (value?: File) => value ? value.basename : ''; + +const parse = (file: CollectionFile): File => ({ + class: CWLType.FILE, + location: `keep:${file.id}`, + basename: file.name, +}); + +const getValidation = memoize( + (input: FileCommandInputParameter) => ([ + isRequiredInput(input) + ? (file?: File) => file ? undefined : ERROR_MESSAGE + : () => undefined, + ])); interface FileInputComponentState { open: boolean; @@ -77,7 +84,7 @@ const FileInputComponent = connect()( this.props.input.onChange(this.state.file); } - setFile = (event: React.MouseEvent, { data }: TreeItem, pickerId: string) => { + setFile = (_: {}, { data }: TreeItem) => { if ('type' in data && data.type === CollectionFileType.FILE) { this.setState({ file: data }); } else { diff --git a/src/views/run-process-panel/inputs/float-input.tsx b/src/views/run-process-panel/inputs/float-input.tsx index 56a58012..a5905dc5 100644 --- a/src/views/run-process-panel/inputs/float-input.tsx +++ b/src/views/run-process-panel/inputs/float-input.tsx @@ -3,6 +3,7 @@ // SPDX-License-Identifier: AGPL-3.0 import * as React from 'react'; +import { memoize } from 'lodash/fp'; import { FloatCommandInputParameter, isRequiredInput } from '~/models/workflow'; import { Field } from 'redux-form'; import { isNumber } from '~/validators/is-number'; @@ -17,11 +18,17 @@ export const FloatInput = ({ input }: FloatInputProps) => commandInput={input} component={Input} parse={parseFloat} - format={value => isNaN(value) ? '' : JSON.stringify(value)} - validate={[ - isRequiredInput(input) - ? isNumber - : () => undefined,]} />; + format={format} + validate={getValidation(input)} />; + +const format = (value: any) => isNaN(value) ? '' : JSON.stringify(value); + +const getValidation = memoize( + (input: FloatCommandInputParameter) => ([ + isRequiredInput(input) + ? isNumber + : () => undefined,]) +); const Input = (props: GenericInputProps) => name={input.id} commandInput={input} component={InputComponent} - parse={value => parseInt(value, 10)} - format={value => isNaN(value) ? '' : JSON.stringify(value)} - validate={[ - isRequiredInput(input) - ? isInteger - : () => undefined, - ]} />; + parse={parse} + format={format} + validate={getValidation(input)} />; + +const parse = (value: any) => parseInt(value, 10); + +const format = (value: any) => isNaN(value) ? '' : JSON.stringify(value); + +const getValidation = memoize( + (input: IntCommandInputParameter) => ([ + isRequiredInput(input) + ? isInteger + : () => undefined, + ])); const InputComponent = (props: GenericInputProps) => name={input.id} commandInput={input} component={StringInputComponent} - validate={[ - isRequiredInput(input) - ? require - : () => undefined, - ]} />; + validate={getValidation(input)} />; + +const getValidation = memoize( + (input: StringCommandInputParameter) => ([ + isRequiredInput(input) + ? require + : () => undefined, + ])); const StringInputComponent = (props: GenericInputProps) =>