Merge 'main' into 20382-process-action-menu-cancel
[arvados.git] / src / views / run-process-panel / inputs / enum-input.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import React from 'react';
6 import { Field } from 'redux-form';
7 import { memoize } from 'lodash/fp';
8 import { require } from 'validators/require';
9 import { Select, MenuItem } from '@material-ui/core';
10 import { EnumCommandInputParameter, CommandInputEnumSchema, isRequiredInput, getEnumType } from 'models/workflow';
11 import { GenericInputProps, GenericInput } from './generic-input';
12
13 export interface EnumInputProps {
14     input: EnumCommandInputParameter;
15 }
16
17 const getValidation = memoize(
18     (input: EnumCommandInputParameter) => ([
19         isRequiredInput(input)
20             ? require
21             : () => undefined,
22     ]));
23
24 const emptyToNull = value => {
25     if (value === '') {
26         return null;
27     } else {
28         return value;
29     }
30 };
31
32 export const EnumInput = ({ input }: EnumInputProps) =>
33     <Field
34         name={input.id}
35         commandInput={input}
36         component={EnumInputComponent}
37         validate={getValidation(input)}
38         normalize={emptyToNull}
39     />;
40
41 const EnumInputComponent = (props: GenericInputProps) =>
42     <GenericInput
43         component={Input}
44         {...props} />;
45
46 const Input = (props: GenericInputProps) => {
47     const type = getEnumType(props.commandInput) as CommandInputEnumSchema;
48     return <Select
49         value={props.input.value}
50         onChange={props.input.onChange}
51         disabled={props.commandInput.disabled} >
52         {(isRequiredInput(props.commandInput) ? [] : [<MenuItem key={'_empty'} value={''} />]).concat(type.symbols.map(symbol =>
53             <MenuItem key={symbol} value={extractValue(symbol)}>
54                 {extractValue(symbol)}
55             </MenuItem>))}
56     </Select>;
57 };
58
59 /**
60  * Values in workflow definition have an absolute form, for example:
61  *
62  * ```#input_collector.cwl/enum_type/Pathway table```
63  *
64  * We want a value that is in form accepted by backend.
65  * According to the example above, the correct value is:
66  *
67  * ```Pathway table```
68  */
69 const extractValue = (symbol: string) => symbol.split('/').pop();