ultisuite-client/components/gmail/settings/automation/webhook-event-scope-editor.tsx
R3D347HR4Y 20552a34ff feat(automation): multi-domain rules and webhook scope UI
Extend automations to drive and contacts with context-aware triggers,
conditions, and actions. Webhooks can filter event types and scopes per domain.
2026-06-07 15:51:47 +02:00

104 lines
3.6 KiB
TypeScript

"use client"
import { Checkbox } from "@/components/ui/checkbox"
import { Label } from "@/components/ui/label"
import { ApiTokenDriveScopeEditor } from "@/components/gmail/settings/automation/api-token-drive-scope-editor"
import { ApiTokenMailScopeEditor } from "@/components/gmail/settings/automation/api-token-mail-scope-editor"
import { WebhookContactsScopeEditor } from "@/components/gmail/settings/automation/webhook-contacts-scope-editor"
import {
AUTOMATION_DOMAIN_LABELS,
type AutomationDomain,
} from "@/lib/mail-automation/domains"
import type { TriggerType } from "@/lib/mail-automation/types"
import {
hasContactsWebhookEvents,
hasDriveWebhookEvents,
hasMailWebhookEvents,
WEBHOOK_EVENT_OPTIONS,
} from "@/lib/mail-automation/webhook-config"
import type { ApiTokenDriveScope, ApiTokenMailScope } from "@/lib/api/types"
import type { WebhookContactsScope } from "@/lib/mail-automation/webhook-config"
import { cn } from "@/lib/utils"
const DOMAINS: AutomationDomain[] = ["mail", "drive", "contacts"]
export function WebhookEventScopeEditor({
eventTypes,
onEventTypesChange,
mailScope,
onMailScopeChange,
driveScope,
onDriveScopeChange,
contactsScope,
onContactsScopeChange,
className,
}: {
eventTypes: TriggerType[]
onEventTypesChange: (types: TriggerType[]) => void
mailScope: ApiTokenMailScope
onMailScopeChange: (scope: ApiTokenMailScope) => void
driveScope: ApiTokenDriveScope
onDriveScopeChange: (scope: ApiTokenDriveScope) => void
contactsScope: WebhookContactsScope
onContactsScopeChange: (scope: WebhookContactsScope) => void
className?: string
}) {
function toggleEvent(type: TriggerType) {
if (eventTypes.includes(type)) {
onEventTypesChange(eventTypes.filter((t) => t !== type))
} else {
onEventTypesChange([...eventTypes, type])
}
}
return (
<div className={cn("space-y-4", className)}>
<div className="space-y-2">
<Label className="text-sm font-medium">Événements déclencheurs</Label>
<p className="text-xs text-muted-foreground">
Le webhook part uniquement pour les événements cochés, dans le périmètre défini ci-dessous.
</p>
{DOMAINS.map((domain) => {
const options = WEBHOOK_EVENT_OPTIONS.filter((o) => o.domain === domain)
return (
<fieldset key={domain} className="rounded-md border border-border p-3">
<legend className="px-1 text-xs font-medium text-foreground">
{AUTOMATION_DOMAIN_LABELS[domain]}
</legend>
<ul className="mt-2 space-y-1.5">
{options.map((opt) => (
<li key={opt.value}>
<label className="flex cursor-pointer items-center gap-2 text-sm">
<Checkbox
checked={eventTypes.includes(opt.value)}
onCheckedChange={() => toggleEvent(opt.value)}
/>
{opt.label}
</label>
</li>
))}
</ul>
</fieldset>
)
})}
</div>
<ApiTokenMailScopeEditor
enabled={hasMailWebhookEvents(eventTypes)}
scope={mailScope}
onChange={onMailScopeChange}
/>
<ApiTokenDriveScopeEditor
enabled={hasDriveWebhookEvents(eventTypes)}
scope={driveScope}
onChange={onDriveScopeChange}
/>
<WebhookContactsScopeEditor
enabled={hasContactsWebhookEvents(eventTypes)}
scope={contactsScope}
onChange={onContactsScopeChange}
/>
</div>
)
}