// // Copyright (c) 2025-2026 rustmailer.com (https://rustmailer.com) // // This file is part of the Bichon Email Archiving Project // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . import * as React from 'react' import { AtSign, ChevronDown, X } from 'lucide-react' import { useTranslation } from 'react-i18next' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' import { Checkbox } from '@/components/ui/checkbox' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { ScrollArea } from '@/components/ui/scroll-area' import { Popover, PopoverContent, PopoverTrigger, } from '@/components/ui/popover' import useMinimalAccountList from '@/hooks/use-minimal-account-list' import { cn } from '@/lib/utils' import { useAttachmentContext } from './context' export function AccountPopover() { const { t } = useTranslation() const { filter, setFilter } = useAttachmentContext() const [search, setSearch] = React.useState('') const { minimalList = [] } = useMinimalAccountList() const selectedIds: number[] = filter.account_ids ?? [] const toggleAccount = (id: number) => { setFilter(prev => { const next = { ...prev } const set = new Set(next.account_ids ?? []) if (set.has(id)) { set.delete(id) } else { set.add(id) } if (set.size === 0) { delete next.account_ids delete next.mailbox_ids } else { next.account_ids = Array.from(set).sort() delete next.mailbox_ids } return next }) } const clearAccounts = () => { setFilter(prev => { const next = { ...prev } delete next.account_ids delete next.mailbox_ids return next }) } const filtered = React.useMemo(() => { const q = search.toLowerCase() return minimalList .filter(a => !q || a.email.toLowerCase().includes(q) || String(a.id).includes(q) ) .sort((a, b) => { const aSel = selectedIds.includes(a.id) const bSel = selectedIds.includes(b.id) if (aSel && !bSel) return -1 if (!aSel && bSel) return 1 return a.id - b.id }) }, [minimalList, search, selectedIds]) return (
setSearch(e.target.value)} placeholder={t('search_accounts.search_placeholder')} className="h-8 text-sm" />
{!search && selectedIds.length > 0 && (
)} {filtered.length === 0 ? (

{t('search_accounts.no_accounts_found')}

) : ( filtered.map(account => { const checked = selectedIds.includes(account.id) const id = `account-${account.id}` return (
toggleAccount(account.id)} className={cn( 'flex items-center gap-2 px-2 py-1.5 rounded-md cursor-pointer', 'hover:bg-accent transition-colors' )} > toggleAccount(account.id) } onClick={e => e.stopPropagation()} />
) }) )}
) }