@@ -11,12 +11,14 @@ import { DateTimePicker } from "@common/features/data/components/FilterEditor/Da
11
11
import { cn } from "@common/lib/cn" ;
12
12
import { UNDEFINED_PLACEHOLDER } from "system-udfs/convex/_system/frontend/patchDocumentsFields" ;
13
13
import { Tooltip } from "@common/elements/Tooltip" ;
14
+ import { ExclamationTriangleIcon } from "@radix-ui/react-icons" ;
14
15
15
16
export type IndexFilterState = FilterByIndex | FilterByIndexRange ;
16
17
17
18
export type IndexFilterEditorProps = {
18
19
idx : number ;
19
20
field : string ;
21
+ error : string | undefined ;
20
22
onChange ( filter : IndexFilterState , idx : number ) : void ;
21
23
onApplyFilters ( ) : void ;
22
24
onError ( idx : number , errors : string [ ] ) : void ;
@@ -38,9 +40,14 @@ const filterTypeOptions: Option<string>[] = [
38
40
{ value : "between" , label : "is between" } ,
39
41
] ;
40
42
43
+ // Define a constant for the error message
44
+ const RANGE_ERROR_MESSAGE =
45
+ "The lower bound of this range is currently set to a value that is higher than the upper bound. This filter would never match any documents." ;
46
+
41
47
export function IndexFilterEditor ( {
42
48
idx,
43
49
field,
50
+ error,
44
51
onChange,
45
52
onApplyFilters,
46
53
onError,
@@ -186,21 +193,45 @@ export function IndexFilterEditor({
186
193
// Handle lower date change for _creationTime between
187
194
const handleLowerDateChange = useCallback (
188
195
( date : Date ) => {
196
+ const timestamp = date . getTime ( ) ;
189
197
if ( "lowerValue" in filter ) {
190
- onChange ( { ...filter , lowerValue : date . getTime ( ) } , idx ) ;
198
+ onChange ( { ...filter , lowerValue : timestamp } , idx ) ;
199
+
200
+ // Check if lowerValue is greater than upperValue
201
+ if (
202
+ filter . type === "indexRange" &&
203
+ typeof filter . upperValue === "number" &&
204
+ timestamp > filter . upperValue
205
+ ) {
206
+ onError ( idx , [ RANGE_ERROR_MESSAGE ] ) ;
207
+ } else if ( error === RANGE_ERROR_MESSAGE ) {
208
+ onError ( idx , [ ] ) ;
209
+ }
191
210
}
192
211
} ,
193
- [ filter , idx , onChange ] ,
212
+ [ filter , idx , onChange , onError , error ] ,
194
213
) ;
195
214
196
215
// Handle upper date change for _creationTime between
197
216
const handleUpperDateChange = useCallback (
198
217
( date : Date ) => {
218
+ const timestamp = date . getTime ( ) ;
199
219
if ( "upperValue" in filter ) {
200
- onChange ( { ...filter , upperValue : date . getTime ( ) } , idx ) ;
220
+ onChange ( { ...filter , upperValue : timestamp } , idx ) ;
221
+
222
+ // Check if upperValue is less than lowerValue
223
+ if (
224
+ filter . type === "indexRange" &&
225
+ typeof filter . lowerValue === "number" &&
226
+ timestamp < filter . lowerValue
227
+ ) {
228
+ onError ( idx , [ RANGE_ERROR_MESSAGE ] ) ;
229
+ } else if ( error === RANGE_ERROR_MESSAGE ) {
230
+ onError ( idx , [ ] ) ;
231
+ }
201
232
}
202
233
} ,
203
- [ filter , idx , onChange ] ,
234
+ [ filter , idx , onChange , onError , error ] ,
204
235
) ;
205
236
206
237
// Handle changes to range filter values
@@ -215,9 +246,21 @@ export function IndexFilterEditor({
215
246
? Number ( value )
216
247
: ( value as JSONValue ) ;
217
248
onChange ( { ...filter , lowerValue : jsonValue } , idx ) ;
249
+
250
+ // Check if lowerValue is greater than upperValue
251
+ if (
252
+ filter . type === "indexRange" &&
253
+ jsonValue !== null &&
254
+ filter . upperValue !== null &&
255
+ filter . upperValue !== undefined &&
256
+ typeof jsonValue === typeof filter . upperValue &&
257
+ jsonValue > filter . upperValue
258
+ ) {
259
+ onError ( idx , [ RANGE_ERROR_MESSAGE ] ) ;
260
+ }
218
261
}
219
262
} ,
220
- [ filter , idx , onChange ] ,
263
+ [ filter , idx , onChange , onError ] ,
221
264
) ;
222
265
223
266
const handleUpperValueChange = useCallback (
@@ -231,9 +274,21 @@ export function IndexFilterEditor({
231
274
? Number ( value )
232
275
: ( value as JSONValue ) ;
233
276
onChange ( { ...filter , upperValue : jsonValue } , idx ) ;
277
+
278
+ // Check if upperValue is less than lowerValue
279
+ if (
280
+ filter . type === "indexRange" &&
281
+ jsonValue !== null &&
282
+ filter . lowerValue !== null &&
283
+ filter . lowerValue !== undefined &&
284
+ typeof jsonValue === typeof filter . lowerValue &&
285
+ jsonValue < filter . lowerValue
286
+ ) {
287
+ onError ( idx , [ RANGE_ERROR_MESSAGE ] ) ;
288
+ }
234
289
}
235
290
} ,
236
- [ filter , idx , onChange ] ,
291
+ [ filter , idx , onChange , onError ] ,
237
292
) ;
238
293
239
294
// Convert to range filter
@@ -612,6 +667,13 @@ export function IndexFilterEditor({
612
667
613
668
{ /* Render the appropriate value editor */ }
614
669
{ renderValueEditor ( ) }
670
+ { error && (
671
+ < Tooltip tip = { error } >
672
+ < div className = "ml-1 rounded border bg-background-error p-1" >
673
+ < ExclamationTriangleIcon className = "size-4 text-content-errorSecondary" />
674
+ </ div >
675
+ </ Tooltip >
676
+ ) }
615
677
</ div >
616
678
</ div >
617
679
) ;
0 commit comments