/* * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ import { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { Input } from '@/components/ui/input'; import { Button } from '@/components/ui/button'; import { Separator } from '@/components/ui/separator'; import { X, Plus } from 'lucide-react'; function BufferedExprInput({ value, onCommit, ...rest }: { value: string; onCommit: (v: string) => void } & Omit< React.InputHTMLAttributes, 'onChange' | 'value' >) { const [local, setLocal] = useState(value); useEffect(() => { setLocal(value); }, [value]); const commit = () => { if (local !== value) onCommit(local); }; return ( setLocal(e.target.value)} onBlur={commit} onKeyDown={(e) => { if (e.key === 'Enter') commit(); }} /> ); } interface ExpressionEditorProps { value: { match: Record; else: string; }; onChange: (value: { match: Record; else: string }) => void; readOnly?: boolean; } export function ExpressionEditor({ value, onChange, readOnly = false }: ExpressionEditorProps) { const { t } = useTranslation(); const [nextIndex, setNextIndex] = useState(() => { const keys = Object.keys(value.match).map(Number).filter(Number.isFinite); return keys.length > 0 ? Math.max(...keys) + 1 : 0; }); const matchEntries = Object.entries(value.match); const handleConditionChange = (key: string, field: 'if' | 'then', fieldValue: string) => { onChange({ ...value, match: { ...value.match, [key]: { ...value.match[key], [field]: fieldValue }, }, }); }; const handleElseChange = (elseValue: string) => { onChange({ ...value, else: elseValue }); }; const handleAdd = () => { const key = String(nextIndex); setNextIndex(nextIndex + 1); onChange({ ...value, match: { ...value.match, [key]: { if: '', then: '' } }, }); }; const handleRemove = (key: string) => { const { [key]: _removed, ...rest } = value.match; void _removed; onChange({ ...value, match: rest }); }; return (
{matchEntries.map(([key, entry], index) => (
{t('expression.if', 'IF')} handleConditionChange(key, 'if', v)} disabled={readOnly} placeholder={t('expression.condition', 'Condition')} className="flex-1" /> {!readOnly && ( )}
{t('expression.then', 'THEN')} handleConditionChange(key, 'then', v)} disabled={readOnly} placeholder={t('expression.result', 'Result')} className="flex-1" /> {!readOnly &&
}
{index < matchEntries.length - 1 && }
))} {!readOnly && (
)} {matchEntries.length > 0 && }
{matchEntries.length > 0 && ( {t('expression.else', 'ELSE')} )} 0 ? t('expression.defaultValue', 'Default value') : t('expression.value', 'Value') } className="flex-1" /> {!readOnly && matchEntries.length > 0 &&
}
); }