diff --git a/ui/queryBuilder/QueryBuilder.tsx b/ui/queryBuilder/QueryBuilder.tsx index d2248cfdc..f2984f546 100644 --- a/ui/queryBuilder/QueryBuilder.tsx +++ b/ui/queryBuilder/QueryBuilder.tsx @@ -12,7 +12,13 @@ interface Props { isLoading?: boolean; } -const QueryBuilder = (props: Props) => { +const QueryBuilder = ({ initialValue, onSubmit, isLoading }: Props) => { + const [ currentValue, setCurrentValue ] = React.useState(initialValue); + + React.useEffect(() => { + setCurrentValue(initialValue); + }, [ initialValue ]); + return ( @@ -22,11 +28,20 @@ const QueryBuilder = (props: Props) => { - - + diff --git a/ui/queryBuilder/input/QueryBuilderInput.tsx b/ui/queryBuilder/input/QueryBuilderInput.tsx index ab3e754c2..02d14eb46 100644 --- a/ui/queryBuilder/input/QueryBuilderInput.tsx +++ b/ui/queryBuilder/input/QueryBuilderInput.tsx @@ -79,13 +79,13 @@ const detailsByOperator: Record = { }; interface Props { - initialValue: string; + value: string; + onValueChange: (value: string) => void; onSubmit: (value: string) => void; isLoading?: boolean; } -const QueryBuilderInput = ({ initialValue, onSubmit, isLoading }: Props) => { - const [ value, setValue ] = React.useState(initialValue); +const QueryBuilderInput = ({ value, onValueChange, onSubmit, isLoading }: Props) => { const instanceRef = React.useRef(null); const editorRef = React.useRef(null); @@ -98,8 +98,8 @@ const QueryBuilderInput = ({ initialValue, onSubmit, isLoading }: Props) => { }, [ colorMode ]); const handleChange = React.useCallback((newValue: string | undefined) => { - setValue(newValue || ''); - }, []); + onValueChange(newValue || ''); + }, [ onValueChange ]); const handleSubmit = React.useCallback(() => { if (validation.isValid) { diff --git a/ui/queryBuilder/visual/QueryBuilderVisual.tsx b/ui/queryBuilder/visual/QueryBuilderVisual.tsx index 10096a96b..f2d4b2505 100644 --- a/ui/queryBuilder/visual/QueryBuilderVisual.tsx +++ b/ui/queryBuilder/visual/QueryBuilderVisual.tsx @@ -18,13 +18,30 @@ import ValueEditor from './ValueEditor'; import 'react-querybuilder/dist/query-builder.css'; interface Props { - initialValue: string; + value: string; + onValueChange: (value: string) => void; onSubmit: (value: string) => void; isLoading?: boolean; } -const QueryBuilderVisual = ({ initialValue, onSubmit, isLoading }: Props) => { - const [ query, setQuery ] = React.useState(() => stringToRuleGroup(initialValue)); +const QueryBuilderVisual = ({ value, onValueChange, onSubmit, isLoading }: Props) => { + const [ query, setQuery ] = React.useState(() => stringToRuleGroup(value)); + const lastEmittedValueRef = React.useRef(value); + + React.useEffect(() => { + // Only update query if value changed externally (not from our own handleQueryChange) + if (value !== lastEmittedValueRef.current) { + const newQuery = stringToRuleGroup(value); + setQuery(newQuery); + } + }, [ value ]); + + const handleQueryChange = React.useCallback((newQuery: RuleGroupType) => { + setQuery(newQuery); + const stringValue = ruleGroupToString(newQuery); + lastEmittedValueRef.current = stringValue; + onValueChange(stringValue); + }, [ onValueChange ]); const handleSubmit = React.useCallback(() => { onSubmit(ruleGroupToString(query)); @@ -60,7 +77,7 @@ const QueryBuilderVisual = ({ initialValue, onSubmit, isLoading }: Props) => {