feat: add search functionality to FilterDropdown component and enable it in AuditLogs pages

This commit is contained in:
Yashwin 2026-04-08 14:33:35 +05:30
parent 6a798b2cf4
commit 9067448e63
3 changed files with 28 additions and 1 deletions

View File

@ -17,6 +17,7 @@ interface FilterDropdownProps {
placeholder?: string; placeholder?: string;
showIcon?: boolean; showIcon?: boolean;
icon?: ReactElement; icon?: ReactElement;
isSearchable?: boolean;
} }
export const FilterDropdown = ({ export const FilterDropdown = ({
@ -27,8 +28,10 @@ export const FilterDropdown = ({
placeholder = 'All', placeholder = 'All',
showIcon = false, showIcon = false,
icon, icon,
isSearchable = false,
}: FilterDropdownProps): ReactElement => { }: FilterDropdownProps): ReactElement => {
const [isOpen, setIsOpen] = useState<boolean>(false); const [isOpen, setIsOpen] = useState<boolean>(false);
const [localSearch, setLocalSearch] = useState<string>('');
const dropdownRef = useRef<HTMLDivElement>(null); const dropdownRef = useRef<HTMLDivElement>(null);
const buttonRef = useRef<HTMLButtonElement>(null); const buttonRef = useRef<HTMLButtonElement>(null);
const dropdownMenuRef = useRef<HTMLDivElement>(null); const dropdownMenuRef = useRef<HTMLDivElement>(null);
@ -63,6 +66,7 @@ export const FilterDropdown = ({
return; return;
} }
setIsOpen(false); setIsOpen(false);
setLocalSearch('');
}; };
if (isOpen) { if (isOpen) {
@ -117,6 +121,10 @@ export const FilterDropdown = ({
: null; : null;
const displayText = selectedOption ? selectedOption.label : placeholder; const displayText = selectedOption ? selectedOption.label : placeholder;
const filteredOptions = isSearchable
? options.filter(opt => opt.label.toLowerCase().includes(localSearch.toLowerCase()))
: options;
return ( return (
<div className="relative" ref={dropdownRef}> <div className="relative" ref={dropdownRef}>
<button <button
@ -149,6 +157,18 @@ export const FilterDropdown = ({
className="fixed bg-white border border-[rgba(0,0,0,0.2)] rounded-md shadow-lg z-[250] max-h-60 overflow-y-auto" className="fixed bg-white border border-[rgba(0,0,0,0.2)] rounded-md shadow-lg z-[250] max-h-60 overflow-y-auto"
style={dropdownStyle} style={dropdownStyle}
> >
{isSearchable && (
<div className="p-2 border-b border-[rgba(0,0,0,0.08)] sticky top-0 bg-white z-10">
<input
type="text"
placeholder="Search..."
value={localSearch}
onChange={(e) => setLocalSearch(e.target.value)}
className="w-full px-2 py-1.5 text-xs border border-[rgba(0,0,0,0.08)] rounded focus:outline-none focus:ring-1 focus:ring-[#112868]/20 bg-gray-50/50"
autoFocus
/>
</div>
)}
<ul className="py-1.5"> <ul className="py-1.5">
<li> <li>
<button <button
@ -165,7 +185,12 @@ export const FilterDropdown = ({
{placeholder} {placeholder}
</button> </button>
</li> </li>
{options.map((option, index) => { {filteredOptions.length === 0 && localSearch && (
<li className="px-3 py-4 text-center text-xs text-gray-400">
No results found for "{localSearch}"
</li>
)}
{filteredOptions.map((option, index) => {
const optionKey = Array.isArray(option.value) const optionKey = Array.isArray(option.value)
? option.value.join(':') ? option.value.join(':')
: option.value; : option.value;

View File

@ -411,6 +411,7 @@ const AuditLogs = (): ReactElement => {
setCurrentPage(1); setCurrentPage(1);
}} }}
placeholder="All Resources" placeholder="All Resources"
isSearchable
/> />
{/* Method Filter */} {/* Method Filter */}

View File

@ -432,6 +432,7 @@ const AuditLogs = (): ReactElement => {
setCurrentPage(1); setCurrentPage(1);
}} }}
placeholder="All Resources" placeholder="All Resources"
isSearchable
/> />
</> </>
)} )}