Visual builder for the triple-array condition-expression dialect defined
in ui/src/conditions.ts (the TypeScript counterpart of the Rust Expr
parser in src/vars/mod.rs). Renders an editable tree of AND/OR/NOT
groups and leaf rules (subject/op/value), with a raw-JSON fallback for
expressions the builder model cannot represent.
Two shapes are supported (see ConditionBuilderProps.shape):
'expr' — a single top-level (implicit AND) expression, used by
request-validation's conditions field.
'or-of-exprs' — an OR-of-ANDed-expressions list (fault-injection-style
vars); the root is a fixed OR and its direct children are fixed AND
"condition sets", both non-negatable and non-retoggleable because
toVarsList does not serialize logic/negate at those two levels.
State model: mode toggles between 'builder' (edits a parsed
ConditionGroup tree, emitting toExpr/toVarsList on every
change) and 'raw' (edits JSON text directly, entered automatically
whenever the incoming value fails to parse). An empty root serializes to
onChange(undefined) rather than [], since the Rust side treats an
absent/empty conditions list as vacuously true and the field is optional.
Visual builder for the triple-array condition-expression dialect defined in
ui/src/conditions.ts(the TypeScript counterpart of the RustExprparser insrc/vars/mod.rs). Renders an editable tree of AND/OR/NOT groups and leaf rules (subject/op/value), with a raw-JSON fallback for expressions the builder model cannot represent.Two shapes are supported (see ConditionBuilderProps.shape):
'expr'— a single top-level (implicit AND) expression, used byrequest-validation'sconditionsfield.'or-of-exprs'— an OR-of-ANDed-expressions list (fault-injection-stylevars); the root is a fixed OR and its direct children are fixed AND "condition sets", both non-negatable and non-retoggleable because toVarsList does not serialize logic/negate at those two levels.State model:
modetoggles between'builder'(edits a parsed ConditionGroup tree, emittingtoExpr/toVarsListon every change) and'raw'(edits JSON text directly, entered automatically whenever the incoming value fails to parse). An empty root serializes toonChange(undefined)rather than[], since the Rust side treats an absent/empty conditions list as vacuously true and the field is optional.