fix(ui): resets value in where builder when operator changes (#11136)
### What? The list filters in the collection view allows invalid queries. If you enter a value and then change operator, the value will remain even if it doesn't pass the new value field validation, and an error is thrown. ### Why? The value isn't reset or revalidated on operator change. It is reset on field change. ### How? Resets the value field when the operator changes. Fixes #10648
This commit is contained in:
committed by
GitHub
parent
f079eced8a
commit
ec34e64261
@@ -26,8 +26,9 @@ import { useEffectEvent } from '../../../hooks/useEffectEvent.js'
|
||||
import { useTranslation } from '../../../providers/Translation/index.js'
|
||||
import { Button } from '../../Button/index.js'
|
||||
import { ReactSelect } from '../../ReactSelect/index.js'
|
||||
import './index.scss'
|
||||
import { DefaultFilter } from './DefaultFilter/index.js'
|
||||
import { getOperatorValueTypes } from './validOperators.js'
|
||||
import './index.scss'
|
||||
|
||||
const baseClass = 'condition'
|
||||
|
||||
@@ -103,12 +104,25 @@ export const Condition: React.FC<Props> = (props) => {
|
||||
|
||||
const handleOperatorChange = useCallback(
|
||||
async (operator: Option<Operator>) => {
|
||||
const operatorValueTypes = getOperatorValueTypes(reducedField.field.type)
|
||||
const validOperatorValue = operatorValueTypes[operator.value] || 'any'
|
||||
const isValidValue =
|
||||
validOperatorValue === 'any' ||
|
||||
typeof value === validOperatorValue ||
|
||||
(validOperatorValue === 'boolean' && (value === 'true' || value === 'false'))
|
||||
|
||||
if (!isValidValue) {
|
||||
// if the current value is not valid for the new operator
|
||||
// reset the value before passing it to updateCondition
|
||||
setInternalValue(undefined)
|
||||
}
|
||||
|
||||
await updateCondition({
|
||||
andIndex,
|
||||
field: reducedField,
|
||||
operator: operator.value,
|
||||
orIndex,
|
||||
value,
|
||||
value: isValidValue ? value : undefined,
|
||||
})
|
||||
},
|
||||
[andIndex, reducedField, orIndex, updateCondition, value],
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
export const getOperatorValueTypes = (fieldType) => {
|
||||
return {
|
||||
all: 'any',
|
||||
contains: 'string',
|
||||
equals: 'any',
|
||||
/*
|
||||
* exists:
|
||||
* The expected value is boolean, but it's passed as a string ('true' or 'false').
|
||||
* Need to additionally check if the value is strictly 'true' or 'false' as a string,
|
||||
* rather than using a direct typeof comparison.
|
||||
* This is handled as:
|
||||
* validOperatorValue === 'boolean' && (value === 'true' || value === 'false')
|
||||
*/
|
||||
exists: 'boolean',
|
||||
/*
|
||||
* greater_than, greater_than_equal, less_than, less_than_equal:
|
||||
* Used for number and date fields:
|
||||
* - For date fields, the value is an object (e.g., Mon Feb 17 2025 12:00:00 GMT+0000).
|
||||
* - For number fields, the value is a string representing the number.
|
||||
*/
|
||||
greater_than: fieldType === 'date' ? 'object' : 'string',
|
||||
greater_than_equal: fieldType === 'date' ? 'object' : 'string',
|
||||
in: 'any',
|
||||
intersects: 'any',
|
||||
less_than: fieldType === 'date' ? 'object' : 'string',
|
||||
less_than_equal: fieldType === 'date' ? 'object' : 'string',
|
||||
like: 'string',
|
||||
near: 'any',
|
||||
not_equals: 'any',
|
||||
not_in: 'any',
|
||||
not_like: 'string',
|
||||
within: 'any',
|
||||
}
|
||||
}
|
||||
@@ -413,7 +413,6 @@ describe('List View', () => {
|
||||
await expect(whereBuilder.locator('.condition__value input')).toHaveValue('')
|
||||
})
|
||||
|
||||
// eslint-disable-next-line playwright/expect-expect
|
||||
test('should remove condition from URL when value is cleared', async () => {
|
||||
await page.goto(postsUrl.list)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user