mirror of
https://github.com/rustmailer/bichon.git
synced 2026-08-03 07:48:34 +02:00
feat: search for an email address simultaneously in to, cc and bcc #304
This commit is contained in:
@@ -43,6 +43,10 @@ pub struct EmailSearchFilter {
|
|||||||
pub to: Option<String>,
|
pub to: Option<String>,
|
||||||
pub cc: Option<String>,
|
pub cc: Option<String>,
|
||||||
pub bcc: Option<String>,
|
pub bcc: Option<String>,
|
||||||
|
/// Matches if the address appears in `to`, `cc`, or `bcc` (OR semantics).
|
||||||
|
pub any_recipient: Option<String>,
|
||||||
|
/// Matches if the address appears in `from`, `to`, `cc`, or `bcc` (OR semantics).
|
||||||
|
pub any_participant: Option<String>,
|
||||||
pub since: Option<i64>,
|
pub since: Option<i64>,
|
||||||
pub before: Option<i64>,
|
pub before: Option<i64>,
|
||||||
/// Lower bound (inclusive) on the IMAP server INTERNALDATE timestamp.
|
/// Lower bound (inclusive) on the IMAP server INTERNALDATE timestamp.
|
||||||
|
|||||||
@@ -461,6 +461,34 @@ impl IndexManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// any_recipient: OR across to, cc, bcc
|
||||||
|
if let Some(ref v) = filter.any_recipient {
|
||||||
|
let mut recipient_queries: Vec<(Occur, Box<dyn Query>)> = Vec::new();
|
||||||
|
for field in [f.f_to_text, f.f_cc_text, f.f_bcc_text] {
|
||||||
|
let query_parser = QueryParser::for_index(&self.index, vec![field]);
|
||||||
|
if let Ok(q) = query_parser.parse_query(v) {
|
||||||
|
recipient_queries.push((Occur::Should, q));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !recipient_queries.is_empty() {
|
||||||
|
subqueries.push((Occur::Must, Box::new(BooleanQuery::new(recipient_queries))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// any_participant: OR across from, to, cc, bcc
|
||||||
|
if let Some(ref v) = filter.any_participant {
|
||||||
|
let mut participant_queries: Vec<(Occur, Box<dyn Query>)> = Vec::new();
|
||||||
|
for field in [f.f_from_text, f.f_to_text, f.f_cc_text, f.f_bcc_text] {
|
||||||
|
let query_parser = QueryParser::for_index(&self.index, vec![field]);
|
||||||
|
if let Ok(q) = query_parser.parse_query(v) {
|
||||||
|
participant_queries.push((Occur::Should, q));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !participant_queries.is_empty() {
|
||||||
|
subqueries.push((Occur::Must, Box::new(BooleanQuery::new(participant_queries))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(has) = filter.has_attachment {
|
if let Some(has) = filter.has_attachment {
|
||||||
let lower: Bound<Term>;
|
let lower: Bound<Term>;
|
||||||
let upper: Bound<Term>;
|
let upper: Bound<Term>;
|
||||||
|
|||||||
@@ -30,13 +30,13 @@ import {
|
|||||||
CommandGroup,
|
CommandGroup,
|
||||||
CommandInput,
|
CommandInput,
|
||||||
CommandItem,
|
CommandItem,
|
||||||
CommandList,
|
|
||||||
} from "@/components/ui/command"
|
} from "@/components/ui/command"
|
||||||
|
import { ScrollArea } from "@/components/ui/scroll-area"
|
||||||
|
|
||||||
export function MailFilterPopover() {
|
export function MailFilterPopover() {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { filter, setFilter } = useSearchContext()
|
const { filter, setFilter } = useSearchContext()
|
||||||
const fields = ['from', 'to', 'cc', 'bcc'] as const
|
const fields = ['from', 'to', 'cc', 'bcc', 'any_recipient', 'any_participant'] as const
|
||||||
|
|
||||||
const activeCount = fields.filter(k => !!filter[k]).length
|
const activeCount = fields.filter(k => !!filter[k]).length
|
||||||
|
|
||||||
@@ -196,7 +196,7 @@ function ContactSelectorField({
|
|||||||
value={searchTerm}
|
value={searchTerm}
|
||||||
onValueChange={setSearchTerm}
|
onValueChange={setSearchTerm}
|
||||||
/>
|
/>
|
||||||
<CommandList className="max-h-[360px]">
|
<ScrollArea className="h-[360px]">
|
||||||
{isLoading && (
|
{isLoading && (
|
||||||
<div className="p-4 text-xs text-center opacity-50">{t('search_contacts.loading')}</div>
|
<div className="p-4 text-xs text-center opacity-50">{t('search_contacts.loading')}</div>
|
||||||
)}
|
)}
|
||||||
@@ -227,7 +227,7 @@ function ContactSelectorField({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</CommandGroup>
|
</CommandGroup>
|
||||||
</CommandList>
|
</ScrollArea>
|
||||||
</Command>
|
</Command>
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
|
|||||||
@@ -1001,6 +1001,8 @@
|
|||||||
"advanced": "متقدم",
|
"advanced": "متقدم",
|
||||||
"advancedFilters": "فلاتر متقدمة",
|
"advancedFilters": "فلاتر متقدمة",
|
||||||
"any": "الكل",
|
"any": "الكل",
|
||||||
|
"any_participant": "أي طرف في المراسلة",
|
||||||
|
"any_recipient": "أي مستلم",
|
||||||
"attachmentName": "اسم المرفق",
|
"attachmentName": "اسم المرفق",
|
||||||
"attachmentsSize": "المرفقات والحجم",
|
"attachmentsSize": "المرفقات والحجم",
|
||||||
"bcc": "نسخة مخفية",
|
"bcc": "نسخة مخفية",
|
||||||
|
|||||||
@@ -1001,6 +1001,8 @@
|
|||||||
"advanced": "Avanceret",
|
"advanced": "Avanceret",
|
||||||
"advancedFilters": "Avancerede filtre",
|
"advancedFilters": "Avancerede filtre",
|
||||||
"any": "Alle",
|
"any": "Alle",
|
||||||
|
"any_participant": "Enhver korrespondent",
|
||||||
|
"any_recipient": "Enhver modtager",
|
||||||
"attachmentName": "Vedhæftningsfilnavn",
|
"attachmentName": "Vedhæftningsfilnavn",
|
||||||
"attachmentsSize": "Vedhæftninger & Størrelse",
|
"attachmentsSize": "Vedhæftninger & Størrelse",
|
||||||
"bcc": "Blindkopi (BCC)",
|
"bcc": "Blindkopi (BCC)",
|
||||||
|
|||||||
@@ -1001,6 +1001,8 @@
|
|||||||
"advanced": "Erweitert",
|
"advanced": "Erweitert",
|
||||||
"advancedFilters": "Erweiterte Filter",
|
"advancedFilters": "Erweiterte Filter",
|
||||||
"any": "Beliebig",
|
"any": "Beliebig",
|
||||||
|
"any_participant": "Beliebiger Beteiligter",
|
||||||
|
"any_recipient": "Beliebiger Empfänger",
|
||||||
"attachmentName": "Anhangsname",
|
"attachmentName": "Anhangsname",
|
||||||
"attachmentsSize": "Anhänge & Größe",
|
"attachmentsSize": "Anhänge & Größe",
|
||||||
"bcc": "BCC",
|
"bcc": "BCC",
|
||||||
|
|||||||
@@ -1002,6 +1002,8 @@
|
|||||||
"advanced": "Advanced",
|
"advanced": "Advanced",
|
||||||
"advancedFilters": "Advanced Filters",
|
"advancedFilters": "Advanced Filters",
|
||||||
"any": "Any",
|
"any": "Any",
|
||||||
|
"any_participant": "Any correspondent",
|
||||||
|
"any_recipient": "Any recipient",
|
||||||
"attachmentName": "Attachment Name",
|
"attachmentName": "Attachment Name",
|
||||||
"attachmentsSize": "Attachments & Size",
|
"attachmentsSize": "Attachments & Size",
|
||||||
"bcc": "BCC",
|
"bcc": "BCC",
|
||||||
|
|||||||
@@ -1001,6 +1001,8 @@
|
|||||||
"advanced": "Avanzado",
|
"advanced": "Avanzado",
|
||||||
"advancedFilters": "Filtros avanzados",
|
"advancedFilters": "Filtros avanzados",
|
||||||
"any": "Cualquiera",
|
"any": "Cualquiera",
|
||||||
|
"any_participant": "Cualquier participante",
|
||||||
|
"any_recipient": "Cualquier destinatario",
|
||||||
"attachmentName": "Nombre del adjunto",
|
"attachmentName": "Nombre del adjunto",
|
||||||
"attachmentsSize": "Adjuntos y tamaño",
|
"attachmentsSize": "Adjuntos y tamaño",
|
||||||
"bcc": "CCO",
|
"bcc": "CCO",
|
||||||
|
|||||||
@@ -1001,6 +1001,8 @@
|
|||||||
"advanced": "Tarkennettu",
|
"advanced": "Tarkennettu",
|
||||||
"advancedFilters": "Tarkennetut suodattimet",
|
"advancedFilters": "Tarkennetut suodattimet",
|
||||||
"any": "Kaikki",
|
"any": "Kaikki",
|
||||||
|
"any_participant": "Kuka tahansa osallistuja",
|
||||||
|
"any_recipient": "Kuka tahansa vastaanottaja",
|
||||||
"attachmentName": "Liitteen nimi",
|
"attachmentName": "Liitteen nimi",
|
||||||
"attachmentsSize": "Liitteet ja koko",
|
"attachmentsSize": "Liitteet ja koko",
|
||||||
"bcc": "Piilokopio",
|
"bcc": "Piilokopio",
|
||||||
|
|||||||
@@ -1001,6 +1001,8 @@
|
|||||||
"advanced": "Avancé",
|
"advanced": "Avancé",
|
||||||
"advancedFilters": "Filtres Avancés",
|
"advancedFilters": "Filtres Avancés",
|
||||||
"any": "Toutes",
|
"any": "Toutes",
|
||||||
|
"any_participant": "N'importe quel correspondant",
|
||||||
|
"any_recipient": "N'importe quel destinataire",
|
||||||
"attachmentName": "Nom de la Pièce Jointe",
|
"attachmentName": "Nom de la Pièce Jointe",
|
||||||
"attachmentsSize": "Pièces Jointes et Taille",
|
"attachmentsSize": "Pièces Jointes et Taille",
|
||||||
"bcc": "Cci",
|
"bcc": "Cci",
|
||||||
|
|||||||
@@ -1001,6 +1001,8 @@
|
|||||||
"advanced": "Avanzato",
|
"advanced": "Avanzato",
|
||||||
"advancedFilters": "Filtri Avanzati",
|
"advancedFilters": "Filtri Avanzati",
|
||||||
"any": "Qualsiasi",
|
"any": "Qualsiasi",
|
||||||
|
"any_participant": "Qualsiasi partecipante",
|
||||||
|
"any_recipient": "Qualsiasi destinatario",
|
||||||
"attachmentName": "Nome Allegato",
|
"attachmentName": "Nome Allegato",
|
||||||
"attachmentsSize": "Allegati e Dimensione",
|
"attachmentsSize": "Allegati e Dimensione",
|
||||||
"bcc": "BCC",
|
"bcc": "BCC",
|
||||||
|
|||||||
@@ -1001,6 +1001,8 @@
|
|||||||
"advanced": "高度な設定",
|
"advanced": "高度な設定",
|
||||||
"advancedFilters": "高度なフィルター",
|
"advancedFilters": "高度なフィルター",
|
||||||
"any": "指定なし",
|
"any": "指定なし",
|
||||||
|
"any_participant": "すべての関係者",
|
||||||
|
"any_recipient": "すべての受信者",
|
||||||
"attachmentName": "添付ファイル名",
|
"attachmentName": "添付ファイル名",
|
||||||
"attachmentsSize": "添付ファイルとサイズ",
|
"attachmentsSize": "添付ファイルとサイズ",
|
||||||
"bcc": "BCC(ブラインド写し)",
|
"bcc": "BCC(ブラインド写し)",
|
||||||
|
|||||||
@@ -1001,6 +1001,8 @@
|
|||||||
"advanced": "고급",
|
"advanced": "고급",
|
||||||
"advancedFilters": "고급 필터",
|
"advancedFilters": "고급 필터",
|
||||||
"any": "전체",
|
"any": "전체",
|
||||||
|
"any_participant": "모든 관련자",
|
||||||
|
"any_recipient": "모든 수신자",
|
||||||
"attachmentName": "첨부 파일 이름",
|
"attachmentName": "첨부 파일 이름",
|
||||||
"attachmentsSize": "첨부 파일 및 크기",
|
"attachmentsSize": "첨부 파일 및 크기",
|
||||||
"bcc": "숨은 참조",
|
"bcc": "숨은 참조",
|
||||||
|
|||||||
@@ -1001,6 +1001,8 @@
|
|||||||
"advanced": "Geavanceerd",
|
"advanced": "Geavanceerd",
|
||||||
"advancedFilters": "Geavanceerde Filters",
|
"advancedFilters": "Geavanceerde Filters",
|
||||||
"any": "Alle",
|
"any": "Alle",
|
||||||
|
"any_participant": "Elke correspondent",
|
||||||
|
"any_recipient": "Elke ontvanger",
|
||||||
"attachmentName": "Naam Bijlage",
|
"attachmentName": "Naam Bijlage",
|
||||||
"attachmentsSize": "Bijlagen & Grootte",
|
"attachmentsSize": "Bijlagen & Grootte",
|
||||||
"bcc": "BCC",
|
"bcc": "BCC",
|
||||||
|
|||||||
@@ -1001,6 +1001,8 @@
|
|||||||
"advanced": "Avansert",
|
"advanced": "Avansert",
|
||||||
"advancedFilters": "Avanserte filtre",
|
"advancedFilters": "Avanserte filtre",
|
||||||
"any": "Alle",
|
"any": "Alle",
|
||||||
|
"any_participant": "Enhver korrespondent",
|
||||||
|
"any_recipient": "Enhver mottaker",
|
||||||
"attachmentName": "Vedleggsnavn",
|
"attachmentName": "Vedleggsnavn",
|
||||||
"attachmentsSize": "Vedlegg og størrelse",
|
"attachmentsSize": "Vedlegg og størrelse",
|
||||||
"bcc": "Blindkopi (BCC)",
|
"bcc": "Blindkopi (BCC)",
|
||||||
|
|||||||
@@ -1001,6 +1001,8 @@
|
|||||||
"advanced": "Zaawansowane",
|
"advanced": "Zaawansowane",
|
||||||
"advancedFilters": "Zaawansowane filtry",
|
"advancedFilters": "Zaawansowane filtry",
|
||||||
"any": "Dowolny",
|
"any": "Dowolny",
|
||||||
|
"any_participant": "Dowolny uczestnik",
|
||||||
|
"any_recipient": "Dowolny odbiorca",
|
||||||
"attachmentName": "Nazwa załącznika",
|
"attachmentName": "Nazwa załącznika",
|
||||||
"attachmentsSize": "Załączniki & Rozmiar",
|
"attachmentsSize": "Załączniki & Rozmiar",
|
||||||
"bcc": "UDW",
|
"bcc": "UDW",
|
||||||
|
|||||||
@@ -1001,6 +1001,8 @@
|
|||||||
"advanced": "Avançado",
|
"advanced": "Avançado",
|
||||||
"advancedFilters": "Filtros Avançados",
|
"advancedFilters": "Filtros Avançados",
|
||||||
"any": "Qualquer",
|
"any": "Qualquer",
|
||||||
|
"any_participant": "Qualquer correspondente",
|
||||||
|
"any_recipient": "Qualquer destinatario",
|
||||||
"attachmentName": "Nome do Anexo",
|
"attachmentName": "Nome do Anexo",
|
||||||
"attachmentsSize": "Anexos e Tamanho",
|
"attachmentsSize": "Anexos e Tamanho",
|
||||||
"bcc": "BCC",
|
"bcc": "BCC",
|
||||||
|
|||||||
@@ -1001,6 +1001,8 @@
|
|||||||
"advanced": "Дополнительно",
|
"advanced": "Дополнительно",
|
||||||
"advancedFilters": "Расширенные фильтры",
|
"advancedFilters": "Расширенные фильтры",
|
||||||
"any": "Любой",
|
"any": "Любой",
|
||||||
|
"any_participant": "Любой участник переписки",
|
||||||
|
"any_recipient": "Любой получатель",
|
||||||
"attachmentName": "Имя вложения",
|
"attachmentName": "Имя вложения",
|
||||||
"attachmentsSize": "Вложения и Размер",
|
"attachmentsSize": "Вложения и Размер",
|
||||||
"bcc": "Скрытая копия",
|
"bcc": "Скрытая копия",
|
||||||
|
|||||||
@@ -1001,6 +1001,8 @@
|
|||||||
"advanced": "Avancerat",
|
"advanced": "Avancerat",
|
||||||
"advancedFilters": "Avancerade filter",
|
"advancedFilters": "Avancerade filter",
|
||||||
"any": "Alla",
|
"any": "Alla",
|
||||||
|
"any_participant": "Valfri korrespondent",
|
||||||
|
"any_recipient": "Valfri mottagare",
|
||||||
"attachmentName": "Filnamn på bilaga",
|
"attachmentName": "Filnamn på bilaga",
|
||||||
"attachmentsSize": "Bilagor & storlek",
|
"attachmentsSize": "Bilagor & storlek",
|
||||||
"bcc": "Hemlig kopia (BCC)",
|
"bcc": "Hemlig kopia (BCC)",
|
||||||
|
|||||||
@@ -1001,6 +1001,8 @@
|
|||||||
"advanced": "進階",
|
"advanced": "進階",
|
||||||
"advancedFilters": "進階篩選",
|
"advancedFilters": "進階篩選",
|
||||||
"any": "不限",
|
"any": "不限",
|
||||||
|
"any_participant": "任意關聯人",
|
||||||
|
"any_recipient": "任意收件人",
|
||||||
"attachmentName": "附件名稱",
|
"attachmentName": "附件名稱",
|
||||||
"attachmentsSize": "附件與大小",
|
"attachmentsSize": "附件與大小",
|
||||||
"bcc": "密件副本 (BCC)",
|
"bcc": "密件副本 (BCC)",
|
||||||
|
|||||||
@@ -1001,6 +1001,8 @@
|
|||||||
"advanced": "高级",
|
"advanced": "高级",
|
||||||
"advancedFilters": "高级筛选",
|
"advancedFilters": "高级筛选",
|
||||||
"any": "不限",
|
"any": "不限",
|
||||||
|
"any_participant": "任意关联人",
|
||||||
|
"any_recipient": "任意收件人",
|
||||||
"attachmentName": "附件名称",
|
"attachmentName": "附件名称",
|
||||||
"attachmentsSize": "附件和大小",
|
"attachmentsSize": "附件和大小",
|
||||||
"bcc": "密送",
|
"bcc": "密送",
|
||||||
|
|||||||
Reference in New Issue
Block a user