From eff383e30c284f0e82c7d0ac7b722c8f4f881a10 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 2 Sep 2025 18:21:21 +0000 Subject: [PATCH 1/2] Fix(firestore): Respect data type when applying filter The firestore filter view was incorrectly setting the data type to string if the value was entered before the data type was selected. This was because the data type was being inferred from the value itself. This change lifts the state of the `fieldType` to the parent component, `CollectionFilter.tsx`, and passes it down as a prop. The `onSubmit` function in `CollectionFilter.tsx` now parses the value based on the `fieldType` before dispatching the action. This ensures that the selected data type is always respected, regardless of the order of operations. --- .../CollectionFilter/CollectionFilter.tsx | 25 ++++++++++++++++--- .../CollectionFilter/ConditionEntry.tsx | 18 +++---------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/components/Firestore/CollectionFilter/CollectionFilter.tsx b/src/components/Firestore/CollectionFilter/CollectionFilter.tsx index 4ba153a02..e4f7e82a9 100644 --- a/src/components/Firestore/CollectionFilter/CollectionFilter.tsx +++ b/src/components/Firestore/CollectionFilter/CollectionFilter.tsx @@ -54,7 +54,16 @@ export const CollectionFilter: React.FC< const cf = formMethods.watch(); + const [fieldType, setFieldType] = useState('string'); + const onSubmit = (data: CollectionFilterType) => { + if (isSingleValueCollectionFilter(data)) { + if (fieldType === 'number') { + data.value = Number(data.value); + } else if (fieldType === 'boolean') { + data.value = data.value === 'true'; + } + } dispatch( actions.addCollectionFilter({ path, @@ -96,7 +105,10 @@ export const CollectionFilter: React.FC< preview={} defaultOpen > - + {cf && isSingleValueCollectionFilter(cf) && ( )} @@ -207,9 +221,12 @@ const Preview: React.FC< ); }; -const ConditionSelect: React.FC> = ({ - children, -}) => { +const ConditionSelect: React.FC< + React.PropsWithChildren<{ + fieldType: string; + setFieldType: (type: string) => void; + }> +> = ({ children, fieldType, setFieldType }) => { const options: Array<{ label: string; value: WhereFilterOp; diff --git a/src/components/Firestore/CollectionFilter/ConditionEntry.tsx b/src/components/Firestore/CollectionFilter/ConditionEntry.tsx index 1ee9a8be8..b2c6bfd19 100644 --- a/src/components/Firestore/CollectionFilter/ConditionEntry.tsx +++ b/src/components/Firestore/CollectionFilter/ConditionEntry.tsx @@ -21,29 +21,21 @@ import { Field, SelectField } from '../../../components/common/Field'; import { NUMBER_REGEX, isBoolean, isNumber } from '../utils'; import styles from './CollectionFilter.module.scss'; -function getConditionEntryType(value: any) { - if (isBoolean(value)) { - return 'boolean'; - } - if (isNumber(value)) { - return 'number'; - } - return 'string'; -} interface ConditionEntryProps { name: string; // Error may be undefined; require consumers to still pass or we might end up // in a state where we validate without showing the error message. error: string | undefined; + fieldType: string; + setFieldType: (type: string) => void; } export const ConditionEntry: React.FC< React.PropsWithChildren -> = React.memo(({ name, error }) => { +> = React.memo(({ name, error, fieldType, setFieldType }) => { const { setValue, watch } = useFormContext(); const value = watch(name); - const [fieldType, setFieldType] = useState(getConditionEntryType(value)); useEffect(() => { // Essentially setting the defaultValue of this form-field, @@ -58,9 +50,7 @@ export const ConditionEntry: React.FC< { - setFieldType(evt.currentTarget.value); - }} + onChange={(evt) => setFieldType(evt.currentTarget.value)} fieldClassName={styles.conditionEntryType} /> From aee5250eac3d5c6dfe52bcedec820cbe99227dbd Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 2 Sep 2025 19:47:56 +0000 Subject: [PATCH 2/2] Fix(firestore): Persist filter data type on close This change fixes a regression where the filter data type would always default to "string" when the filter view was closed and reopened. The `fieldType` state is now initialized in the `CollectionFilter` component based on the type of the existing filter value. This ensures that the dropdown correctly reflects the type of the currently applied filter when the view is reopened. --- .../CollectionFilter/CollectionFilter.tsx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/components/Firestore/CollectionFilter/CollectionFilter.tsx b/src/components/Firestore/CollectionFilter/CollectionFilter.tsx index e4f7e82a9..17d3e20fe 100644 --- a/src/components/Firestore/CollectionFilter/CollectionFilter.tsx +++ b/src/components/Firestore/CollectionFilter/CollectionFilter.tsx @@ -31,12 +31,23 @@ import { isSingleValueCollectionFilter, isSortableCollectionFilter, } from '../models'; +import { isBoolean, isNumber } from '../utils'; import { useCollectionFilter, useDispatch } from '../store'; import styles from './CollectionFilter.module.scss'; import { ConditionEntries } from './ConditionEntries'; import { ConditionEntry } from './ConditionEntry'; import { SortRadioGroup } from './SortRadioGroup'; +function getConditionEntryType(value: any) { + if (isBoolean(value)) { + return 'boolean'; + } + if (isNumber(value)) { + return 'number'; + } + return 'string'; +} + export const CollectionFilter: React.FC< React.PropsWithChildren<{ className?: string; @@ -54,7 +65,11 @@ export const CollectionFilter: React.FC< const cf = formMethods.watch(); - const [fieldType, setFieldType] = useState('string'); + const [fieldType, setFieldType] = useState( + getConditionEntryType( + isSingleValueCollectionFilter(collectionFilter) && collectionFilter.value + ) + ); const onSubmit = (data: CollectionFilterType) => { if (isSingleValueCollectionFilter(data)) {