@@ -13,24 +13,31 @@ import {
13
13
ModalFooter ,
14
14
ModalHeader ,
15
15
ModalOverlay ,
16
+ Text as ChakraText ,
17
+ Textarea ,
18
+ VStack ,
16
19
} from '@chakra-ui/react' ;
17
20
import React , { useState } from 'react' ;
18
21
import { useAppDispatch , useAppSelector } from '../../app/hooks' ;
19
- import { addFilter , selectFilterList , selectFilterString , toggleAddFilterDialog } from '../ui/uiSlice' ;
22
+ import { selectFilterList , selectFilterString , toggleAddFilterDialog , upsertFilter } from '../ui/uiSlice' ;
23
+ import { isValidFilterToken } from './model/filterFactory' ;
20
24
21
25
export const SaveFilterDialog : React . FC = function ( ) {
22
26
const dispatch = useAppDispatch ( ) ;
23
- const filter = useAppSelector ( selectFilterString ) ;
24
27
const savedFilters = useAppSelector ( selectFilterList ) ;
28
+
25
29
const [ filterName , setFilterName ] = useState ( '' ) ;
30
+ const [ filterString , setFilterString ] = useState ( useAppSelector ( selectFilterString ) ) ;
26
31
27
- const alreadyIncluded : boolean = savedFilters . some ( ( it ) => {
32
+ const alreadyIncluded = savedFilters . some ( ( it ) => {
28
33
return it . name === filterName ;
29
34
} ) ;
35
+ const invalidTokens = filterString . split ( ' ' ) . filter ( ( token ) => token !== '' && ! isValidFilterToken ( token ) ) ;
36
+ const filterStringIsValid = invalidTokens . length === 0 ;
30
37
31
38
const submit = ( ) => {
32
- if ( filterName !== '' && ! alreadyIncluded ) {
33
- dispatch ( addFilter ( { filter, name : filterName } ) ) ;
39
+ if ( filterName . trim ( ) !== '' && filterStringIsValid ) {
40
+ dispatch ( upsertFilter ( { filter : filterString , name : filterName } ) ) ;
34
41
dispatch ( toggleAddFilterDialog ( ) ) ;
35
42
}
36
43
} ;
@@ -46,33 +53,53 @@ export const SaveFilterDialog: React.FC = function () {
46
53
< Heading > Save Filter</ Heading >
47
54
</ ModalHeader >
48
55
< ModalBody >
49
- < FormControl isInvalid = { alreadyIncluded || filterName . trim ( ) === '' } >
50
- < FormLabel htmlFor = "newFilterName" >
51
- Name for the current filter < Code > { filter } </ Code > :
52
- </ FormLabel >
53
- < Input
54
- type = "text"
55
- id = "newFilterName"
56
- value = { filterName }
57
- onChange = { ( event ) => setFilterName ( event . target . value ) }
58
- spellCheck = { false }
59
- />
60
- { alreadyIncluded && (
61
- < FormErrorMessage > A filter with this name is saved already.</ FormErrorMessage >
62
- ) }
63
- { filterName . trim ( ) === '' && (
64
- < FormErrorMessage > The filter name must not be blank.</ FormErrorMessage >
65
- ) }
66
- </ FormControl >
56
+ < VStack spacing = { 4 } >
57
+ < FormControl isInvalid = { filterName . trim ( ) === '' } >
58
+ < FormLabel htmlFor = "newFilterName" > Filter Name:</ FormLabel >
59
+ < Input
60
+ type = "text"
61
+ id = "newFilterName"
62
+ value = { filterName }
63
+ onChange = { ( event ) => setFilterName ( event . target . value ) }
64
+ spellCheck = { false }
65
+ />
66
+ { filterName . trim ( ) === '' && (
67
+ < FormErrorMessage > The filter name must not be blank.</ FormErrorMessage >
68
+ ) }
69
+ </ FormControl >
70
+
71
+ < FormControl isInvalid = { ! filterStringIsValid } >
72
+ < FormLabel htmlFor = "newFilterString" > Filter String:</ FormLabel >
73
+ < Textarea
74
+ id = "newFilterString"
75
+ value = { filterString }
76
+ onChange = { ( event ) => setFilterString ( event . target . value ) }
77
+ spellCheck = { false }
78
+ />
79
+ { ! filterStringIsValid && (
80
+ < FormErrorMessage >
81
+ < ChakraText >
82
+ Filter has invalid tokens:{ ' ' }
83
+ { invalidTokens . map ( ( token , index ) => (
84
+ < >
85
+ < Code > { token } </ Code >
86
+ { index < invalidTokens . length - 1 && ', ' }
87
+ </ >
88
+ ) ) }
89
+ </ ChakraText >
90
+ </ FormErrorMessage >
91
+ ) }
92
+ </ FormControl >
93
+ </ VStack >
67
94
</ ModalBody >
68
95
< ModalFooter >
69
96
< HStack spacing = { 4 } >
70
97
< Button
71
98
colorScheme = "blue"
72
99
onClick = { submit }
73
- isDisabled = { alreadyIncluded || filterName . trim ( ) === '' }
100
+ isDisabled = { filterName . trim ( ) === '' || ! filterStringIsValid }
74
101
>
75
- Submit
102
+ { alreadyIncluded ? 'Replace' : 'Add' }
76
103
</ Button >
77
104
< Button colorScheme = "red" onClick = { close } >
78
105
Cancel
0 commit comments