import { useEffect, useMemo, useRef, useState } from "react"; import { createPortal } from "react-dom"; import { Button } from "@govoplan/core-webui"; import { Dialog } from "@govoplan/core-webui"; import { DismissibleAlert } from "@govoplan/core-webui"; import { buildUndefinedPlaceholders, extractTemplatePlaceholders, removePlaceholderFromText, replacePlaceholderInText, type TemplateNamespace, type UndefinedPlaceholder } from "../utils/templatePlaceholders"; import { TemplateFieldChipList, UndefinedPlaceholderDecisionDialog, UndefinedPlaceholderList, type TemplateFieldOption } from "./TemplatePlaceholderControls"; export default function TemplateExpressionEditorDialog({ open, title, value, localFields, globalFields, placeholder, description, saveLabel = "i18n:govoplan-campaign.save.efc007a3", validate, onCancel, onSave, onAddField, canAddField = () => true }: {open: boolean;title: string;value: string;localFields: TemplateFieldOption[];globalFields: TemplateFieldOption[];placeholder?: string;description?: string;saveLabel?: string;validate?: (value: string) => string;onCancel: () => void;onSave: (value: string) => void;onAddField: (name: string) => void;canAddField?: (name: string) => boolean;}) { const [draftValue, setDraftValue] = useState(value); const [undefinedDialog, setUndefinedDialog] = useState(null); const inputRef = useRef(null); useEffect(() => { if (!open) return; setDraftValue(value); setUndefinedDialog(null); }, [open, value]); const usedPlaceholders = useMemo(() => extractTemplatePlaceholders(draftValue), [draftValue]); const localNames = useMemo(() => new Set(localFields.map((field) => field.name)), [localFields]); const globalNames = useMemo(() => new Set(globalFields.map((field) => field.name)), [globalFields]); const availableNames = useMemo(() => new Set([...localNames, ...globalNames]), [globalNames, localNames]); const undefinedPlaceholders = useMemo( () => buildUndefinedPlaceholders(usedPlaceholders, availableNames, { local: localNames, global: globalNames }), [availableNames, globalNames, localNames, usedPlaceholders] ); const validationMessage = validate?.(draftValue) ?? ""; function insertPlaceholder(namespace: TemplateNamespace, name: string) { const input = inputRef.current; const token = `{{${namespace}:${name}}}`; const defaultPosition = draftValue.toLocaleLowerCase().endsWith(".zip") ? draftValue.length - 4 : draftValue.length; const start = input?.selectionStart ?? defaultPosition; const end = input?.selectionEnd ?? start; setDraftValue(`${draftValue.slice(0, start)}${token}${draftValue.slice(end)}`); window.requestAnimationFrame(() => { input?.focus(); const cursor = start + token.length; input?.setSelectionRange(cursor, cursor); }); } function requestSave() { if (validationMessage) return; if (undefinedPlaceholders.length > 0) { setUndefinedDialog(undefinedPlaceholders[0]); return; } onSave(draftValue.trim()); } function removeUndefined(field: UndefinedPlaceholder) { setDraftValue((current) => removePlaceholderFromText(current, field.raw)); setUndefinedDialog(null); } function addUndefined(field: UndefinedPlaceholder) { if (!field.name || field.reason === "invalid-namespace") return; onAddField(field.name); setUndefinedDialog(null); } function replaceUndefined(field: UndefinedPlaceholder, namespace: TemplateNamespace, name: string) { setDraftValue((current) => replacePlaceholderInText(current, field.raw, `{{${namespace}:${name}}}`)); setUndefinedDialog(null); } if (!open || typeof document === "undefined") return null; return createPortal( <> }> {description &&

{description}

} {validationMessage && {validationMessage}}

i18n:govoplan-campaign.recipient_fields.fdbcd95b

i18n:govoplan-campaign.select_a_field_to_insert_it_at_the_current_curso.1d1b51be i18n:govoplan-campaign.to_2.8c1db0c7 or i18n:govoplan-campaign.to_2_email.5ad61c1a i18n:govoplan-campaign.for_another_single_value.ce57d76a

i18n:govoplan-campaign.campaign_fields.969e7d80

i18n:govoplan-campaign.used_but_undefined.3b829043

setUndefinedDialog(null)} onRemove={removeUndefined} onReplace={replaceUndefined} onAddField={addUndefined} localFields={localFields} globalFields={globalFields} addDisabled={Boolean(undefinedDialog?.name) && !canAddField(undefinedDialog?.name ?? "")} /> , document.body ); }