Merge branch '19007-file-browser-action-button'. Closes #19007
[arvados-workbench2.git] / src / views-components / resource-properties-form / property-field-common.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { connect } from 'react-redux';
6 import { change, WrappedFieldMetaProps, WrappedFieldInputProps, WrappedFieldProps } from 'redux-form';
7 import { Vocabulary, PropFieldSuggestion } from 'models/vocabulary';
8 import { RootState } from 'store/store';
9 import { getVocabulary } from 'store/vocabulary/vocabulary-selectors';
10
11 export interface VocabularyProp {
12     vocabulary: Vocabulary;
13 }
14
15 export interface ValidationProp {
16     skipValidation?: boolean;
17 }
18
19 export const mapStateToProps = (state: RootState, ownProps: ValidationProp): VocabularyProp & ValidationProp => ({
20     skipValidation: ownProps.skipValidation,
21     vocabulary: getVocabulary(state.properties),
22 });
23
24 export const connectVocabulary = connect(mapStateToProps);
25
26 export const ITEMS_PLACEHOLDER: string[] = [];
27
28 export const hasError = ({ touched, invalid }: WrappedFieldMetaProps) =>
29     touched && invalid;
30
31 export const getErrorMsg = (meta: WrappedFieldMetaProps) =>
32     hasError(meta)
33         ? meta.error
34         : '';
35
36 export const buildProps = ({ input, meta }: WrappedFieldProps) => {
37     return {
38         value: input.value,
39         items: ITEMS_PLACEHOLDER,
40         renderSuggestion: (item: PropFieldSuggestion) => item.label,
41         error: hasError(meta),
42         helperText: getErrorMsg(meta),
43     };
44 };
45
46 // Attempts to match a manually typed value label with a value ID, when the user
47 // doesn't select the value from the suggestions list.
48 export const handleBlur = (
49     fieldName: string,
50     formName: string,
51     { dispatch }: WrappedFieldMetaProps,
52     { onBlur, value }: WrappedFieldInputProps,
53     fieldValue: string) =>
54     () => {
55         dispatch(change(formName, fieldName, fieldValue));
56         onBlur(value);
57     };
58
59 // When selecting a property value, save its ID for later usage.
60 export const handleSelect = (
61     fieldName: string,
62     formName: string,
63     { onChange }: WrappedFieldInputProps,
64     { dispatch }: WrappedFieldMetaProps) =>
65     (item: PropFieldSuggestion) => {
66         if (item) {
67             onChange(item.label);
68             dispatch(change(formName, fieldName, item.id));
69         }
70     };