import { ChevronRight } from "lucide-react"; import * as React from "react"; import { cn } from "@/shared/lib/cn"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/shared/ui/alert-dialog"; import { Button } from "@/shared/ui/button"; import { Input } from "@/shared/ui/input"; import { Tabs, TabsList, TabsTrigger } from "@/shared/ui/tabs"; import { MESSAGE_TEXT_CONDITION_LABELS, MESSAGE_TEXT_CONDITION_OPERATORS, buildMessageTextCondition, messageTextConditionNeedsValue, parseMessageTextCondition, } from "./workflowMessageTextCondition"; import type { MessageTextCondition } from "./workflowMessageTextCondition"; const DEFAULT_CONDITION: MessageTextCondition = { operator: "contains", value: "", }; type EditorMode = "basic" | "advanced"; function conditionSummary(condition: MessageTextCondition): string { const label = MESSAGE_TEXT_CONDITION_LABELS[condition.operator].toLowerCase(); if (!messageTextConditionNeedsValue(condition.operator)) return label; const value = condition.value.trim(); return value ? `${label} “${value}”` : "Any"; } export function WorkflowMessageTextCondition({ allowAdvanced = true, disabled, onChange, value, }: { allowAdvanced?: boolean; disabled?: boolean; onChange: (value: string) => void; value: string; }) { const initialParsed = React.useRef(parseMessageTextCondition(value)); const [mode, setMode] = React.useState(() => value && !initialParsed.current ? "advanced" : "basic", ); const [expanded, setExpanded] = React.useState( () => !value || initialParsed.current !== null, ); const [replaceAdvancedOpen, setReplaceAdvancedOpen] = React.useState(false); const [condition, setCondition] = React.useState( initialParsed.current ?? DEFAULT_CONDITION, ); const [advancedDraft, setAdvancedDraft] = React.useState(value); const localValueRef = React.useRef(value); const parsed = value ? parseMessageTextCondition(value) : null; const hasUnsupportedExpression = Boolean(value) && parsed === null; React.useEffect(() => { if (value === localValueRef.current) return; localValueRef.current = value; setAdvancedDraft(value); const nextParsed = parseMessageTextCondition(value); if (nextParsed) { setCondition(nextParsed); setMode("basic"); setExpanded(true); } else if (!value) { setCondition(DEFAULT_CONDITION); setMode("basic"); setExpanded(true); } else { setMode("advanced"); setExpanded(false); } }, [value]); const emit = (expression: string) => { localValueRef.current = expression; onChange(expression); }; const updateCondition = (next: MessageTextCondition) => { setCondition(next); emit(buildMessageTextCondition(next) ?? ""); }; const openBasicEditor = () => { if (hasUnsupportedExpression) { setReplaceAdvancedOpen(true); return; } setExpanded((current) => !current); }; return ( <> { if (!allowAdvanced) return; const editorMode = nextMode as EditorMode; setMode(editorMode); setExpanded(false); if (editorMode === "advanced") setAdvancedDraft(value); }} value={allowAdvanced ? mode : "basic"} > {allowAdvanced ? ( Basic Advanced ) : null} {!allowAdvanced || mode === "basic" ? (
{hasUnsupportedExpression ? (

An advanced expression is active. Choosing a basic filter will replace it.

) : null}
{expanded && !hasUnsupportedExpression ? (
Match
{MESSAGE_TEXT_CONDITION_OPERATORS.map((operator) => { const id = `wf-trigger-filter-trigger-text-operator-${operator}`; return (
updateCondition({ ...condition, operator }) } type="radio" value={operator} />
); })}
{messageTextConditionNeedsValue(condition.operator) ? ( updateCondition({ ...condition, value: event.target.value, }) } placeholder="e.g. deploy" value={condition.value} /> ) : null}
) : null}
) : (
{ const expression = event.target.value; setAdvancedDraft(expression); emit(expression.trim()); }} placeholder='e.g. str_contains(trigger_text, "deploy")' value={advancedDraft} />

Use an evalexpr expression with trigger_text.

)}
Replace advanced expression? Choosing a basic filter will replace the entire advanced expression. This cannot be undone. ); }