@@ -8,6 +8,7 @@ import TextField from "@material-ui/core/TextField"
8
8
import SearchIcon from "@material-ui/icons/Search"
9
9
import { FormikErrors , useFormik } from "formik"
10
10
import { useState } from "react"
11
+ import { getValidationErrorMessage } from "../../api/errors"
11
12
import { getFormHelpers , onChangeTrimmed } from "../../util/formUtils"
12
13
import { CloseDropdown , OpenDropdown } from "../DropdownArrows/DropdownArrows"
13
14
import { Stack } from "../Stack/Stack"
@@ -20,6 +21,7 @@ export interface SearchBarWithFilterProps {
20
21
filter ?: string
21
22
onFilter : ( query : string ) => void
22
23
presetFilters ?: PresetFilter [ ]
24
+ error ?: unknown
23
25
}
24
26
25
27
export interface PresetFilter {
@@ -33,7 +35,7 @@ interface FilterFormValues {
33
35
34
36
export type FilterFormErrors = FormikErrors < FilterFormValues >
35
37
36
- export const SearchBarWithFilter : React . FC < SearchBarWithFilterProps > = ( { filter, onFilter, presetFilters } ) => {
38
+ export const SearchBarWithFilter : React . FC < SearchBarWithFilterProps > = ( { filter, onFilter, presetFilters, error } ) => {
37
39
const styles = useStyles ( )
38
40
39
41
const form = useFormik < FilterFormValues > ( {
@@ -64,64 +66,71 @@ export const SearchBarWithFilter: React.FC<SearchBarWithFilterProps> = ({ filter
64
66
handleClose ( )
65
67
}
66
68
69
+ const errorMessage = getValidationErrorMessage ( error )
70
+
67
71
return (
68
- < Stack direction = "row" spacing = { 0 } className = { styles . filterContainer } >
69
- { presetFilters && presetFilters . length > 0 && (
70
- < Button aria-controls = "filter-menu" aria-haspopup = "true" onClick = { handleClick } className = { styles . buttonRoot } >
71
- { Language . filterName } { anchorEl ? < CloseDropdown /> : < OpenDropdown /> }
72
- </ Button >
73
- ) }
74
-
75
- < form onSubmit = { form . handleSubmit } className = { styles . filterForm } >
76
- < TextField
77
- { ...getFieldHelpers ( "query" ) }
78
- className = { styles . textFieldRoot }
79
- onChange = { onChangeTrimmed ( form ) }
80
- fullWidth
81
- variant = "outlined"
82
- InputProps = { {
83
- startAdornment : (
84
- < InputAdornment position = "start" >
85
- < SearchIcon fontSize = "small" />
86
- </ InputAdornment >
87
- ) ,
88
- } }
89
- />
90
- </ form >
91
-
92
- { presetFilters && presetFilters . length > 0 && (
93
- < Menu
94
- id = "filter-menu"
95
- anchorEl = { anchorEl }
96
- keepMounted
97
- open = { Boolean ( anchorEl ) }
98
- onClose = { handleClose }
99
- TransitionComponent = { Fade }
100
- anchorOrigin = { {
101
- vertical : "bottom" ,
102
- horizontal : "left" ,
103
- } }
104
- transformOrigin = { {
105
- vertical : "top" ,
106
- horizontal : "left" ,
107
- } }
108
- >
109
- { presetFilters . map ( ( presetFilter ) => (
110
- < MenuItem key = { presetFilter . name } onClick = { setPresetFilter ( presetFilter . query ) } >
111
- { presetFilter . name }
112
- </ MenuItem >
113
- ) ) }
114
- </ Menu >
115
- ) }
72
+ < Stack spacing = { 1 } className = { styles . root } >
73
+ < Stack direction = "row" spacing = { 0 } className = { styles . filterContainer } >
74
+ { presetFilters && presetFilters . length > 0 && (
75
+ < Button aria-controls = "filter-menu" aria-haspopup = "true" onClick = { handleClick } className = { styles . buttonRoot } >
76
+ { Language . filterName } { anchorEl ? < CloseDropdown /> : < OpenDropdown /> }
77
+ </ Button >
78
+ ) }
79
+
80
+ < form onSubmit = { form . handleSubmit } className = { styles . filterForm } >
81
+ < TextField
82
+ { ...getFieldHelpers ( "query" ) }
83
+ className = { styles . textFieldRoot }
84
+ onChange = { onChangeTrimmed ( form ) }
85
+ fullWidth
86
+ variant = "outlined"
87
+ InputProps = { {
88
+ startAdornment : (
89
+ < InputAdornment position = "start" >
90
+ < SearchIcon fontSize = "small" />
91
+ </ InputAdornment >
92
+ ) ,
93
+ } }
94
+ />
95
+ </ form >
96
+
97
+ { presetFilters && presetFilters . length > 0 && (
98
+ < Menu
99
+ id = "filter-menu"
100
+ anchorEl = { anchorEl }
101
+ keepMounted
102
+ open = { Boolean ( anchorEl ) }
103
+ onClose = { handleClose }
104
+ TransitionComponent = { Fade }
105
+ anchorOrigin = { {
106
+ vertical : "bottom" ,
107
+ horizontal : "left" ,
108
+ } }
109
+ transformOrigin = { {
110
+ vertical : "top" ,
111
+ horizontal : "left" ,
112
+ } }
113
+ >
114
+ { presetFilters . map ( ( presetFilter ) => (
115
+ < MenuItem key = { presetFilter . name } onClick = { setPresetFilter ( presetFilter . query ) } >
116
+ { presetFilter . name }
117
+ </ MenuItem >
118
+ ) ) }
119
+ </ Menu >
120
+ ) }
121
+ </ Stack >
122
+ { errorMessage && < Stack className = { styles . errorRoot } > { errorMessage } </ Stack > }
116
123
</ Stack >
117
124
)
118
125
}
119
126
120
127
const useStyles = makeStyles ( ( theme ) => ( {
128
+ root : {
129
+ marginBottom : theme . spacing ( 2 ) ,
130
+ } ,
121
131
filterContainer : {
122
132
border : `1px solid ${ theme . palette . divider } ` ,
123
133
borderRadius : theme . shape . borderRadius ,
124
- marginBottom : theme . spacing ( 2 ) ,
125
134
} ,
126
135
filterForm : {
127
136
width : "100%" ,
@@ -137,4 +146,7 @@ const useStyles = makeStyles((theme) => ({
137
146
border : "none" ,
138
147
} ,
139
148
} ,
149
+ errorRoot : {
150
+ color : theme . palette . error . dark ,
151
+ } ,
140
152
} ) )
0 commit comments