33 Dropdown ,
44 DropdownItem ,
55 DropdownList ,
6+ Flex ,
7+ FlexItem ,
68 MenuToggle ,
79 MenuToggleElement ,
810 Text ,
@@ -135,6 +137,21 @@ export const FiltersChips: React.FC<FiltersChipsProps> = ({
135137 [ filterDefinitions , filters , setFilters ]
136138 ) ;
137139
140+ const getAndOrText = React . useCallback (
141+ ( index : number ) => {
142+ if ( index == 0 ) {
143+ return undefined ;
144+ }
145+
146+ return (
147+ < Text className = "and-or-text" component = "p" >
148+ { filters . match === 'any' ? t ( 'OR' ) : t ( 'AND' ) }
149+ </ Text >
150+ ) ;
151+ } ,
152+ [ filters . match , t ]
153+ ) ;
154+
138155 const getFilterDisplay = React . useCallback (
139156 ( chipFilter : Filter , cfIndex : number ) => {
140157 let fullName = chipFilter . def . name ;
@@ -146,130 +163,133 @@ export const FiltersChips: React.FC<FiltersChipsProps> = ({
146163 }
147164 const someEnabled = hasEnabledFilterValues ( chipFilter ) ;
148165 return (
149- < div key = { cfIndex } className = { `custom-chip-group ${ someEnabled ? '' : 'disabled-group' } ` } >
150- < Tooltip content = { `${ someEnabled ? t ( 'Disable' ) : t ( 'Enable' ) } '${ fullName } ' ${ t ( 'group filter' ) } ` } >
151- < Text
152- className = "pf-v5-c-chip-group__label"
153- component = { TextVariants . p }
154- onClick = { ( ) => {
155- //switch all values if no remaining
156- chipFilter . values . forEach ( fv => {
157- fv . disabled = someEnabled ;
158- } ) ;
159- setFilters ( _ . cloneDeep ( filters ) ) ;
160- } }
161- >
162- { fullName }
163- </ Text >
164- </ Tooltip >
165- { chipFilter . values . map ( ( chipFilterValue , fvIndex ) => {
166- if ( isForced || chipFilterValue . disabled ) {
166+ < div className = "flex-block" >
167+ { getAndOrText ( cfIndex ) }
168+ < div key = { cfIndex } className = { `custom-chip-group ${ someEnabled ? '' : 'disabled-group' } ` } >
169+ < Tooltip content = { `${ someEnabled ? t ( 'Disable' ) : t ( 'Enable' ) } '${ fullName } ' ${ t ( 'group filter' ) } ` } >
170+ < Text
171+ className = "pf-v5-c-chip-group__label"
172+ component = { TextVariants . p }
173+ onClick = { ( ) => {
174+ //switch all values if no remaining
175+ chipFilter . values . forEach ( fv => {
176+ fv . disabled = someEnabled ;
177+ } ) ;
178+ setFilters ( _ . cloneDeep ( filters ) ) ;
179+ } }
180+ >
181+ { fullName }
182+ </ Text >
183+ </ Tooltip >
184+ { chipFilter . values . map ( ( chipFilterValue , fvIndex ) => {
185+ if ( isForced || chipFilterValue . disabled ) {
186+ return (
187+ < div key = { fvIndex } className = { `custom-chip ${ chipFilterValue . disabled ? 'disabled-value' : '' } ` } >
188+ < Tooltip
189+ content = { `${ chipFilterValue . disabled ? t ( 'Enable' ) : t ( 'Disable' ) } ${ fullName } '${
190+ chipFilterValue . display || chipFilterValue . v
191+ } ' ${ t ( 'filter' ) } `}
192+ >
193+ < Text
194+ component = { TextVariants . p }
195+ onClick = { ( ) => {
196+ chipFilterValue . disabled = ! chipFilterValue . disabled ;
197+ setFilters ( _ . cloneDeep ( filters ) ) ;
198+ } }
199+ >
200+ { chipFilterValue . display ? chipFilterValue . display : chipFilterValue . v }
201+ </ Text >
202+ </ Tooltip >
203+ </ div >
204+ ) ;
205+ }
206+
207+ const dropdownId = `${ chipFilter . def . id } -${ fvIndex } ` ;
167208 return (
168- < div key = { fvIndex } className = { `custom-chip ${ chipFilterValue . disabled ? 'disabled-value' : '' } ` } >
169- < Tooltip
170- content = { `${ chipFilterValue . disabled ? t ( 'Enable' ) : t ( 'Disable' ) } ${ fullName } '${
171- chipFilterValue . display || chipFilterValue . v
172- } ' ${ t ( 'filter' ) } `}
173- >
174- < Text
175- component = { TextVariants . p }
209+ < Dropdown
210+ key = { fvIndex }
211+ isOpen = { dropdownId === openedDropdown }
212+ onOpenChange = { ( isOpen : boolean ) => setOpenedDropdown ( isOpen ? dropdownId : undefined ) }
213+ toggle = { ( toggleRef : React . Ref < MenuToggleElement > ) => (
214+ < MenuToggle
215+ ref = { toggleRef }
216+ className = { `custom-chip ${ chipFilterValue . disabled ? 'disabled-value' : '' } ` }
217+ isExpanded = { dropdownId === openedDropdown }
218+ onClick = { ( ) => setOpenedDropdown ( openedDropdown === dropdownId ? undefined : dropdownId ) }
219+ >
220+ { chipFilterValue . display ? chipFilterValue . display : chipFilterValue . v }
221+ </ MenuToggle >
222+ ) }
223+ >
224+ < DropdownList >
225+ < DropdownItem
226+ key = "disable"
176227 onClick = { ( ) => {
177228 chipFilterValue . disabled = ! chipFilterValue . disabled ;
178229 setFilters ( _ . cloneDeep ( filters ) ) ;
230+ setOpenedDropdown ( undefined ) ;
179231 } }
180232 >
181- { chipFilterValue . display ? chipFilterValue . display : chipFilterValue . v }
182- </ Text >
183- </ Tooltip >
184- </ div >
185- ) ;
186- }
187-
188- const dropdownId = `${ chipFilter . def . id } -${ fvIndex } ` ;
189- return (
190- < Dropdown
191- key = { fvIndex }
192- isOpen = { dropdownId === openedDropdown }
193- onOpenChange = { ( isOpen : boolean ) => setOpenedDropdown ( isOpen ? dropdownId : undefined ) }
194- toggle = { ( toggleRef : React . Ref < MenuToggleElement > ) => (
195- < MenuToggle
196- ref = { toggleRef }
197- className = { `custom-chip ${ chipFilterValue . disabled ? 'disabled-value' : '' } ` }
198- isExpanded = { dropdownId === openedDropdown }
199- onClick = { ( ) => setOpenedDropdown ( openedDropdown === dropdownId ? undefined : dropdownId ) }
200- >
201- { chipFilterValue . display ? chipFilterValue . display : chipFilterValue . v }
202- </ MenuToggle >
203- ) }
204- >
205- < DropdownList >
206- < DropdownItem
207- key = "disable"
208- onClick = { ( ) => {
209- chipFilterValue . disabled = ! chipFilterValue . disabled ;
210- setFilters ( _ . cloneDeep ( filters ) ) ;
211- setOpenedDropdown ( undefined ) ;
212- } }
213- >
214- { chipFilterValue . disabled && < CheckIcon /> }
215- { ! chipFilterValue . disabled && < BanIcon /> }
216- { chipFilterValue . disabled ? t ( 'Enable' ) : t ( 'Disable' ) }
217- </ DropdownItem >
218- { filters . match !== 'peers' &&
219- ( chipFilter . def . id . startsWith ( 'src_' ) || chipFilter . def . id . startsWith ( 'dst_' ) ) && (
220- < DropdownItem
221- key = "bnf"
222- onClick = { ( ) => {
223- const bnf = bnfFilterValue (
224- filterDefinitions ,
225- filters ! . list ,
226- chipFilter . def . id ,
227- chipFilterValue
228- ) ;
229- setFilters ( { ...filters ! , list : bnf } ) ;
230- setOpenedDropdown ( undefined ) ;
231- } }
232- >
233- < ArrowsAltVIcon style = { { transform : 'rotate(90deg)' } } />
234- { t ( 'Any' ) }
233+ { chipFilterValue . disabled && < CheckIcon /> }
234+ { ! chipFilterValue . disabled && < BanIcon /> }
235+ { chipFilterValue . disabled ? t ( 'Enable' ) : t ( 'Disable' ) }
236+ </ DropdownItem >
237+ { filters . match !== 'peers' &&
238+ ( chipFilter . def . id . startsWith ( 'src_' ) || chipFilter . def . id . startsWith ( 'dst_' ) ) && (
239+ < DropdownItem
240+ key = "bnf"
241+ onClick = { ( ) => {
242+ const bnf = bnfFilterValue (
243+ filterDefinitions ,
244+ filters ! . list ,
245+ chipFilter . def . id ,
246+ chipFilterValue
247+ ) ;
248+ setFilters ( { ...filters ! , list : bnf } ) ;
249+ setOpenedDropdown ( undefined ) ;
250+ } }
251+ >
252+ < ArrowsAltVIcon style = { { transform : 'rotate(90deg)' } } />
253+ { t ( 'Any' ) }
254+ </ DropdownItem >
255+ ) }
256+ { ( chipFilter . def . category === 'targeteable' || chipFilter . def . id . startsWith ( 'dst_' ) ) && (
257+ < DropdownItem key = "src" onClick = { ( ) => swapValue ( chipFilter , chipFilterValue , 'src' ) } >
258+ < ArrowLeftIcon />
259+ { filters . match === 'peers' ? t ( 'As peer A' ) : t ( 'As source' ) }
235260 </ DropdownItem >
236261 ) }
237- { ( chipFilter . def . category === 'targeteable' || chipFilter . def . id . startsWith ( 'dst_' ) ) && (
238- < DropdownItem key = "src" onClick = { ( ) => swapValue ( chipFilter , chipFilterValue , 'src' ) } >
239- < ArrowLeftIcon />
240- { filters . match === 'peers' ? t ( 'As peer A' ) : t ( 'As source' ) }
241- </ DropdownItem >
242- ) }
243- { ( chipFilter . def . category === 'targeteable' || chipFilter . def . id . startsWith ( 'src_' ) ) && (
244- < DropdownItem key = "dst" onClick = { ( ) => swapValue ( chipFilter , chipFilterValue , 'dst' ) } >
245- < ArrowRightIcon />
246- { filters . match === 'peers' ? t ( 'As peer B' ) : t ( 'As destination' ) }
262+ { ( chipFilter . def . category === 'targeteable' || chipFilter . def . id . startsWith ( 'src_' ) ) && (
263+ < DropdownItem key = "dst" onClick = { ( ) => swapValue ( chipFilter , chipFilterValue , 'dst' ) } >
264+ < ArrowRightIcon />
265+ { filters . match === 'peers' ? t ( 'As peer B' ) : t ( 'As destination' ) }
266+ </ DropdownItem >
267+ ) }
268+ < DropdownItem
269+ key = "remove"
270+ onClick = { ( ) => {
271+ chipFilter . values = chipFilter . values . filter ( val => val . v !== chipFilterValue . v ) ;
272+ if ( _ . isEmpty ( chipFilter . values ) ) {
273+ setFiltersList ( removeFromFilters ( filters . list , chipFilter ) ) ;
274+ } else {
275+ setFilters ( _ . cloneDeep ( filters ) ) ;
276+ }
277+ setOpenedDropdown ( undefined ) ;
278+ } }
279+ >
280+ < TimesIcon />
281+ { t ( 'Remove' ) }
247282 </ DropdownItem >
248- ) }
249- < DropdownItem
250- key = "remove"
251- onClick = { ( ) => {
252- chipFilter . values = chipFilter . values . filter ( val => val . v !== chipFilterValue . v ) ;
253- if ( _ . isEmpty ( chipFilter . values ) ) {
254- setFiltersList ( removeFromFilters ( filters . list , chipFilter ) ) ;
255- } else {
256- setFilters ( _ . cloneDeep ( filters ) ) ;
257- }
258- setOpenedDropdown ( undefined ) ;
259- } }
260- >
261- < TimesIcon />
262- { t ( 'Remove' ) }
263- </ DropdownItem >
264- </ DropdownList >
265- </ Dropdown >
266- ) ;
267- } ) }
268- { ! isForced && (
269- < Button variant = "plain" onClick = { ( ) => setFiltersList ( removeFromFilters ( filters . list , chipFilter ) ) } >
270- < TimesCircleIcon />
271- </ Button >
272- ) }
283+ </ DropdownList >
284+ </ Dropdown >
285+ ) ;
286+ } ) }
287+ { ! isForced && (
288+ < Button variant = "plain" onClick = { ( ) => setFiltersList ( removeFromFilters ( filters . list , chipFilter ) ) } >
289+ < TimesCircleIcon />
290+ </ Button >
291+ ) }
292+ </ div >
273293 </ div >
274294 ) ;
275295 } ,
@@ -301,16 +321,30 @@ export const FiltersChips: React.FC<FiltersChipsProps> = ({
301321 id = { `${ isForced ? 'forced-' : '' } filters` }
302322 variant = "filter-group"
303323 >
304- < MatchDropdown selected = { filters . match } setMatch = { setMatch } />
324+ { ( filters . list . length > 2 || hasSrcOrDstFilters ( filters . list ) ) && (
325+ < ToolbarItem className = "flex-start match-container" >
326+ < Flex direction = { { default : hasSrcOrDstFilters ( filters . list ) ? 'column' : 'row' } } >
327+ < FlexItem >
328+ < Text className = "match-text" > { t ( 'Match' ) } </ Text >
329+ </ FlexItem >
330+ < FlexItem >
331+ < MatchDropdown selected = { filters . match } setMatch = { setMatch } />
332+ </ FlexItem >
333+ </ Flex >
334+ </ ToolbarItem >
335+ ) }
305336 < ToolbarItem className = "flex-start flex" >
306337 { getGroups ( )
307338 . filter ( gp => gp . filters . length )
308- . map ( gp => {
339+ . map ( ( gp , index ) => {
309340 return (
310- < div key = { gp . id } className = { `custom-chip-box ${ gp . id !== 'common' ? 'custom-chip-peer' : '' } ` } >
311- { hasSrcOrDstFilters ( filters . list ) && < Text > { getGroupName ( gp . id ) } </ Text > }
312- < div className = "flex" > { gp . filters . map ( getFilterDisplay ) } </ div >
313- </ div >
341+ < >
342+ { getAndOrText ( index ) }
343+ < div key = { gp . id } className = { `custom-chip-box ${ gp . id !== 'common' ? 'custom-chip-peer' : '' } ` } >
344+ { hasSrcOrDstFilters ( filters . list ) && < Text > { getGroupName ( gp . id ) } </ Text > }
345+ < div className = "flex-block" > { gp . filters . map ( getFilterDisplay ) } </ div >
346+ </ div >
347+ </ >
314348 ) ;
315349 } ) }
316350 </ ToolbarItem >
0 commit comments