refs #14080 Merge branch 'origin/14080-cwl-graphs'
[arvados-workbench2.git] / src / views-components / search-bar / search-bar-advanced-properties-view.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import * as React from 'react';
6 import { Dispatch } from 'redux';
7 import { connect } from 'react-redux';
8 import { InjectedFormProps, formValueSelector } from 'redux-form';
9 import { Grid, withStyles, StyleRulesCallback, WithStyles, Button } from '@material-ui/core';
10 import { RootState } from '~/store/store';
11 import { 
12     SEARCH_BAR_ADVANCE_FORM_NAME, 
13     changeAdvanceFormProperty, 
14     updateAdvanceFormProperties 
15 } from '~/store/search-bar/search-bar-actions';
16 import { PropertyValues } from '~/models/search-bar';
17 import { ArvadosTheme } from '~/common/custom-theme';
18 import { SearchBarKeyField, SearchBarValueField } from '~/views-components/form-fields/search-bar-form-fields';
19 import { Chips } from '~/components/chips/chips';
20
21 type CssRules = 'label' | 'button';
22
23 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
24     label: {
25         color: theme.palette.grey["500"],
26         fontSize: '0.8125rem',
27         alignSelf: 'center'
28     },
29     button: {
30         boxShadow: 'none'
31     }
32 });
33
34 interface SearchBarAdvancedPropertiesViewDataProps {
35     submitting: boolean;
36     invalid: boolean;
37     pristine: boolean;
38     propertyValues: PropertyValues;
39     fields: PropertyValues[];
40 }
41
42 interface SearchBarAdvancedPropertiesViewActionProps {
43     setProps: () => void;
44     addProp: (propertyValues: PropertyValues) => void;
45     getAllFields: (propertyValues: PropertyValues[]) => PropertyValues[] | [];
46 }
47
48 type SearchBarAdvancedPropertiesViewProps = SearchBarAdvancedPropertiesViewDataProps 
49     & SearchBarAdvancedPropertiesViewActionProps 
50     & InjectedFormProps & WithStyles<CssRules>;
51
52 const selector = formValueSelector(SEARCH_BAR_ADVANCE_FORM_NAME);
53 const mapStateToProps = (state: RootState) => {
54     return {
55         propertyValues: selector(state, 'key', 'value')
56     };
57 };
58
59 const mapDispatchToProps = (dispatch: Dispatch) => ({
60     setProps: (propertyValues: PropertyValues[]) => {
61         dispatch<any>(changeAdvanceFormProperty('properties', propertyValues));
62     },
63     addProp: (propertyValues: PropertyValues) => {
64         dispatch<any>(updateAdvanceFormProperties(propertyValues));
65         dispatch<any>(changeAdvanceFormProperty('key'));
66         dispatch<any>(changeAdvanceFormProperty('value'));
67     },
68     getAllFields: (fields: any) => {
69         return fields.getAll() || [];
70     }
71 });
72
73 export const SearchBarAdvancedPropertiesView = connect(mapStateToProps, mapDispatchToProps)(
74     withStyles(styles)(
75         ({ classes, fields, propertyValues, setProps, addProp, getAllFields }: SearchBarAdvancedPropertiesViewProps) =>
76             <Grid container item xs={12} spacing={16}>
77                 <Grid item xs={2} className={classes.label}>Properties</Grid>
78                 <Grid item xs={4}>
79                     <SearchBarKeyField />
80                 </Grid>
81                 <Grid item xs={4}>
82                     <SearchBarValueField />
83                 </Grid>
84                 <Grid container item xs={2} justify='flex-end' alignItems="center">
85                     <Button className={classes.button} onClick={() => addProp(propertyValues)}
86                         color="primary"
87                         size='small'
88                         variant="contained">
89                         Add
90                     </Button>
91                 </Grid>
92                 <Grid item xs={2} />
93                 <Grid container item xs={10} spacing={8}>
94                     <Chips values={getAllFields(fields)} 
95                         deletable
96                         onChange={setProps} 
97                         getLabel={(field: PropertyValues) => `${field.key}: ${field.value}`} />
98                 </Grid>
99             </Grid>
100     )
101 );