"use client"; import { ReactNode } from "react"; import { InfoIcon, Plus, Trash2 } from "lucide-react"; import { useFieldArray } from "react-hook-form"; import { toast } from "sonner"; import { Label } from "@/components/ui/label"; import { Button } from "@/components/ui/button"; import { ButtonWithLoading } from "@/components/common/button-with-loading"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { MultiSelect } from "@/components/common/multi-select"; import { Switch } from "@/components/ui/switch"; import { Card } from "@/components/ui/card"; import { useIsMobile } from "@/hooks/use-mobile"; import { ChannelKind, getChannelIcon, getChannelTextBasedOnKind } from "@/features/channel/channels-helpers"; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, useZodForm } from "@/components/ui/form"; import { EVENT_KIND_BACKUP_ONLY_OPTIONS, EVENT_KIND_OPTIONS, PoliciesSchema, PoliciesType, PolicyType, } from "@/features/database/channels-policy.schema"; export type ChannelEntry = { id: string; name: string; provider: string }; type ChannelPoliciesFormProps = { channels: ChannelEntry[]; defaultPolicies: PolicyType[]; kind: ChannelKind; isBackupOnly?: boolean; isPending?: boolean; onSave: (policies: PolicyType[]) => Promise; onCancel?: () => void; noChannelsMessage?: ReactNode; }; export const ChannelPoliciesForm = ({ channels, defaultPolicies, kind, isBackupOnly = false, isPending = false, onSave, onCancel, noChannelsMessage, }: ChannelPoliciesFormProps) => { const isMobile = useIsMobile(); const channelText = getChannelTextBasedOnKind(kind); const form = useZodForm({ schema: PoliciesSchema, defaultValues: { policies: defaultPolicies }, context: { kind }, }); const { fields, append, remove } = useFieldArray({ control: form.control, name: "policies" }); const addPolicy = () => append({ channelId: "", eventKinds: [], enabled: true }); const handleCancel = () => { form.reset(); onCancel?.(); }; return (
{ if (kind === "notification") { for (const policy of values.policies) { if (!policy.eventKinds || policy.eventKinds.length === 0) { toast.error("Please select at least one event for all notification policies"); return; } } } await onSave(values.policies); }} >
{!isMobile && (

{kind === "notification" ? "Choose which channels receive notifications for specific events." : "Choose which storage to use with your database"}

)}
{channels.length === 0 ? (

No channels

{noChannelsMessage ?? (

No {channelText.toLowerCase()} channels configured.

)}
) : fields.length === 0 ? (

No policies

{kind === "notification" ? `Click "Add Policy" to start receiving notifications.` : `Click "Add Policy" to use this storage.`}

) : (
{fields.map((field, index) => (
{ const selectedIds = form .watch("policies") .map((a: PolicyType) => a.channelId) .filter(Boolean); const available = channels.filter( (c) => c.id.toString() === field.value?.toString() || !selectedIds.includes(c.id.toString()), ); const selected = channels.find((c) => c.id === field.value); return ( ); }} />
(
{!isMobile && ( )}
)} />
{kind === "notification" && ( ( Trigger Events
)} /> )}
))}
)}
{onCancel && ( Cancel )} Save Changes
); };