import React, { useState, useEffect, useRef } from 'react'; import { Button } from "@/components/ui/button.tsx"; import { Input } from "@/components/ui/input.tsx"; import { FormControl, FormItem, FormLabel } from "@/components/ui/form.tsx"; import { getCredentials } from '@/ui/main-axios.ts'; import { useTranslation } from "react-i18next"; import type { Credential } from '../../../../types'; interface CredentialSelectorProps { value?: number | null; onValueChange: (credentialId: number | null) => void; onCredentialSelect?: (credential: Credential | null) => void; } export function CredentialSelector({ value, onValueChange, onCredentialSelect }: CredentialSelectorProps) { const { t } = useTranslation(); const [credentials, setCredentials] = useState([]); const [loading, setLoading] = useState(true); const [dropdownOpen, setDropdownOpen] = useState(false); const [searchQuery, setSearchQuery] = useState(''); const buttonRef = useRef(null); const dropdownRef = useRef(null); useEffect(() => { const fetchCredentials = async () => { try { setLoading(true); const data = await getCredentials(); const credentialsArray = Array.isArray(data) ? data : (data.credentials || data.data || []); setCredentials(credentialsArray); } catch (error) { console.error('Failed to fetch credentials:', error); const {toast} = await import('sonner'); toast.error(t('credentials.failedToFetchCredentials')); setCredentials([]); } finally { setLoading(false); } }; fetchCredentials(); }, []); useEffect(() => { function handleClickOutside(event: MouseEvent) { if ( dropdownRef.current && !dropdownRef.current.contains(event.target as Node) && buttonRef.current && !buttonRef.current.contains(event.target as Node) ) { setDropdownOpen(false); } } if (dropdownOpen) { document.addEventListener('mousedown', handleClickOutside); } else { document.removeEventListener('mousedown', handleClickOutside); } return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, [dropdownOpen]); const selectedCredential = credentials.find(c => c.id === value); const filteredCredentials = credentials.filter(credential => { if (!searchQuery) return true; const searchLower = searchQuery.toLowerCase(); return ( credential.name.toLowerCase().includes(searchLower) || credential.username.toLowerCase().includes(searchLower) || (credential.folder && credential.folder.toLowerCase().includes(searchLower)) ); }); const handleCredentialSelect = (credential: Credential) => { onValueChange(credential.id); if (onCredentialSelect) { onCredentialSelect(credential); } setDropdownOpen(false); setSearchQuery(''); }; const handleClear = () => { onValueChange(null); if (onCredentialSelect) { onCredentialSelect(null); } setDropdownOpen(false); setSearchQuery(''); }; return ( {t('hosts.selectCredential')}
{dropdownOpen && (
setSearchQuery(e.target.value)} className="h-8" />
{loading ? (
{t('common.loading')}
) : filteredCredentials.length === 0 ? (
{searchQuery ? t('credentials.noCredentialsMatchFilters') : t('credentials.noCredentialsYet')}
) : (
{value && ( )} {filteredCredentials.map((credential) => ( ))}
)}
)}
); }