11import { useDebounce } from '@uidotdev/usehooks'
22import { Search , X } from 'lucide-react'
3- import { parseAsString , useQueryStates } from 'nuqs'
3+ import { parseAsArrayOf , parseAsString , useQueryStates } from 'nuqs'
44import { ChangeEvent , ReactNode , useEffect , useState } from 'react'
55
6+ import { FilterPopover } from 'components/ui/FilterPopover'
7+ import { useDatabaseRolesQuery } from 'data/database-roles/database-roles-query'
8+ import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
69import { Button , Tooltip , TooltipContent , TooltipTrigger } from 'ui'
710import { Input } from 'ui-patterns/DataInputs/Input'
811import { useQueryPerformanceSort } from './hooks/useQueryPerformanceSort'
912
10- export const QueryPerformanceFilterBar = ( { actions } : { actions ?: ReactNode } ) => {
13+ export const QueryPerformanceFilterBar = ( {
14+ actions,
15+ showRolesFilter = false ,
16+ } : {
17+ actions ?: ReactNode
18+ showRolesFilter ?: boolean
19+ } ) => {
20+ const { data : project } = useSelectedProjectQuery ( )
1121 const { sort, clearSort } = useQueryPerformanceSort ( )
1222
13- const [ { search : searchQuery } , setSearchParams ] = useQueryStates ( {
23+ const [ { search : searchQuery , roles : defaultFilterRoles } , setSearchParams ] = useQueryStates ( {
1424 search : parseAsString . withDefault ( '' ) ,
25+ roles : parseAsArrayOf ( parseAsString ) . withDefault ( [ ] ) ,
1526 } )
27+ const { data, isLoading : isLoadingRoles } = useDatabaseRolesQuery ( {
28+ projectRef : project ?. ref ,
29+ connectionString : project ?. connectionString ,
30+ } )
31+ const roles = ( data ?? [ ] ) . sort ( ( a , b ) => a . name . localeCompare ( b . name ) )
1632
33+ const [ filters , setFilters ] = useState < { roles : string [ ] } > ( {
34+ roles : defaultFilterRoles ,
35+ } )
1736 const [ inputValue , setInputValue ] = useState ( searchQuery )
1837 const debouncedInputValue = useDebounce ( inputValue , 500 )
1938 const searchValue = inputValue . length === 0 ? inputValue : debouncedInputValue
@@ -22,6 +41,11 @@ export const QueryPerformanceFilterBar = ({ actions }: { actions?: ReactNode })
2241 setSearchParams ( { search : value || '' } )
2342 }
2443
44+ const onFilterRolesChange = ( roles : string [ ] ) => {
45+ setFilters ( { ...filters , roles } )
46+ setSearchParams ( { roles } )
47+ }
48+
2549 useEffect ( ( ) => {
2650 onSearchQueryChange ( searchValue )
2751 // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -54,6 +78,18 @@ export const QueryPerformanceFilterBar = ({ actions }: { actions?: ReactNode })
5478 ] }
5579 />
5680
81+ { showRolesFilter && (
82+ < FilterPopover
83+ name = "Roles"
84+ options = { roles }
85+ labelKey = "name"
86+ valueKey = "name"
87+ activeOptions = { isLoadingRoles ? [ ] : filters . roles }
88+ onSaveFilters = { onFilterRolesChange }
89+ className = "w-56"
90+ />
91+ ) }
92+
5793 { sort && (
5894 < div className = "text-xs border rounded-md px-1.5 md:px-2.5 py-1 h-[26px] flex items-center gap-x-2" >
5995 < p className = "md:inline-flex gap-x-1 hidden truncate" >
0 commit comments