125 lines
3.9 KiB
TypeScript
125 lines
3.9 KiB
TypeScript
'use client'
|
|
|
|
import { useMemo } from 'react'
|
|
import { useQueries } from '@tanstack/react-query'
|
|
import { useAuthReady } from '@/lib/api/use-auth-ready'
|
|
import { useLabels } from '@/lib/api/hooks/use-folder-label-queries'
|
|
import { useUnifiedFolders } from '@/lib/api/hooks/use-unified-folder-queries'
|
|
import { useImapFolders } from '@/lib/api/hooks/use-imap-folders'
|
|
import { useContactBooks, fetchContactsForBook } from '@/lib/api/hooks/use-contact-queries'
|
|
import { useMailWebhooks } from '@/lib/api/hooks/use-mail-automation-queries'
|
|
import type { AutomationSuggestionKind } from '@/lib/mail-automation/condition-helpers'
|
|
|
|
export interface AutomationSuggestion {
|
|
value: string
|
|
label?: string
|
|
}
|
|
|
|
function uniqueSuggestions(items: AutomationSuggestion[]): AutomationSuggestion[] {
|
|
const seen = new Set<string>()
|
|
const out: AutomationSuggestion[] = []
|
|
for (const item of items) {
|
|
const key = item.value.trim().toLowerCase()
|
|
if (!key || seen.has(key)) continue
|
|
seen.add(key)
|
|
out.push(item)
|
|
}
|
|
return out.sort((a, b) => (a.label ?? a.value).localeCompare(b.label ?? b.value, 'fr'))
|
|
}
|
|
|
|
export function useAutomationSuggestions() {
|
|
const { ready, authenticated } = useAuthReady()
|
|
const { data: labels = [] } = useLabels()
|
|
const { data: unifiedFolders = [] } = useUnifiedFolders('all')
|
|
const { folders: imapFolders = [] } = useImapFolders()
|
|
const { data: booksRaw } = useContactBooks()
|
|
const { data: webhooks = [] } = useMailWebhooks()
|
|
|
|
const books = useMemo(() => {
|
|
if (Array.isArray(booksRaw)) return booksRaw
|
|
if (booksRaw && typeof booksRaw === 'object' && 'address_books' in booksRaw) {
|
|
return (booksRaw as { address_books: { id: string; name: string }[] }).address_books ?? []
|
|
}
|
|
return []
|
|
}, [booksRaw])
|
|
|
|
const contactQueries = useQueries({
|
|
queries: books.map((book) => ({
|
|
queryKey: ['contacts', book.id] as const,
|
|
queryFn: () => fetchContactsForBook(book.id),
|
|
enabled: ready && authenticated && !!book.id,
|
|
staleTime: 5 * 60_000,
|
|
})),
|
|
})
|
|
|
|
const labelSuggestions = useMemo(
|
|
() => uniqueSuggestions(labels.map((l) => ({ value: l.name, label: l.name }))),
|
|
[labels]
|
|
)
|
|
|
|
const folderSuggestions = useMemo(() => {
|
|
const unified = unifiedFolders.map((f) => ({ value: f.name, label: f.name }))
|
|
const imap = imapFolders.map((f) => ({
|
|
value: f.name,
|
|
label: f.remote_name !== f.name ? `${f.name} (${f.remote_name})` : f.name,
|
|
}))
|
|
return uniqueSuggestions([...unified, ...imap])
|
|
}, [unifiedFolders, imapFolders])
|
|
|
|
const folderIdSuggestions = useMemo(
|
|
() =>
|
|
uniqueSuggestions(
|
|
unifiedFolders.map((f) => ({
|
|
value: f.id,
|
|
label: `${f.name}${f.scope === 'account' ? ' · compte' : ''}`,
|
|
}))
|
|
),
|
|
[unifiedFolders]
|
|
)
|
|
|
|
const emailSuggestions = useMemo(() => {
|
|
const contacts = contactQueries.flatMap((q) => q.data ?? [])
|
|
const items: AutomationSuggestion[] = []
|
|
for (const c of contacts) {
|
|
if (c.email?.trim()) {
|
|
items.push({
|
|
value: c.email.trim(),
|
|
label: c.full_name ? `${c.full_name} <${c.email}>` : c.email,
|
|
})
|
|
}
|
|
}
|
|
return uniqueSuggestions(items)
|
|
}, [contactQueries])
|
|
|
|
const webhookSuggestions = useMemo(
|
|
() => uniqueSuggestions(webhooks.map((w) => ({ value: w.id, label: w.name }))),
|
|
[webhooks]
|
|
)
|
|
|
|
function suggestionsFor(kind: AutomationSuggestionKind): AutomationSuggestion[] {
|
|
switch (kind) {
|
|
case 'label':
|
|
return labelSuggestions
|
|
case 'folder':
|
|
return folderSuggestions
|
|
case 'folder_id':
|
|
return folderIdSuggestions
|
|
case 'email':
|
|
return emailSuggestions
|
|
case 'webhook':
|
|
return webhookSuggestions
|
|
default:
|
|
return []
|
|
}
|
|
}
|
|
|
|
return {
|
|
suggestionsFor,
|
|
labelSuggestions,
|
|
folderSuggestions,
|
|
folderIdSuggestions,
|
|
emailSuggestions,
|
|
webhookSuggestions,
|
|
}
|
|
}
|