// 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';
name={input.id}
commandInput={input}
component={BooleanInputComponent}
- normalize={(value, prevValue) => !prevValue}
+ normalize={normalize}
/>;
+const normalize = (_: any, prevValue: boolean) => !prevValue;
+
const BooleanInputComponent = (props: GenericInputProps) =>
<GenericInput
component={Input}
{...props} />;
-const Input = (props: GenericInputProps) =>
+const Input = ({ input, commandInput }: GenericInputProps) =>
<Switch
color='primary'
- checked={props.input.value}
- onChange={() => 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)
+);
// 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;
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;
this.props.input.onChange(this.state.directory);
}
- setDirectory = (event: React.MouseEvent<HTMLElement>, { data }: TreeItem<ProjectsTreePickerItem>, pickerId: string) => {
+ setDirectory = (_: {}, { data }: TreeItem<ProjectsTreePickerItem>) => {
if ('kind' in data && data.kind === ResourceKind.COLLECTION) {
this.setState({ directory: data });
} else {
// 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 {
onChange={props.input.onChange}
disabled={props.commandInput.disabled} >
{type.symbols.map(symbol =>
- <MenuItem key={symbol} value={symbol.split('/').pop()}>
- {symbol.split('/').pop()}
+ <MenuItem key={symbol} value={extractValue(symbol)}>
+ {extractValue(symbol)}
</MenuItem>)}
</Select>;
-};
\ 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();
// SPDX-License-Identifier: AGPL-3.0
import * as React from 'react';
+import { memoize } from 'lodash/fp';
import {
isRequiredInput,
FileCommandInputParameter,
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;
this.props.input.onChange(this.state.file);
}
- setFile = (event: React.MouseEvent<HTMLElement>, { data }: TreeItem<ProjectsTreePickerItem>, pickerId: string) => {
+ setFile = (_: {}, { data }: TreeItem<ProjectsTreePickerItem>) => {
if ('type' in data && data.type === CollectionFileType.FILE) {
this.setState({ file: data });
} else {
// 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';
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) =>
<GenericInput
// SPDX-License-Identifier: AGPL-3.0
import * as React from 'react';
+import { memoize } from 'lodash/fp';
import { IntCommandInputParameter, isRequiredInput } from '~/models/workflow';
import { Field } from 'redux-form';
import { isInteger } from '~/validators/is-integer';
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) =>
<GenericInput
// SPDX-License-Identifier: AGPL-3.0
import * as React from 'react';
+import { memoize } from 'lodash/fp';
import { isRequiredInput, StringCommandInputParameter } from '~/models/workflow';
import { Field } from 'redux-form';
import { require } from '~/validators/require';
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) =>
<GenericInput