@@ -11,12 +11,15 @@ import {
1111 VisualizationDateFilterOperator ,
1212 VisualizationNumberFilterOperator ,
1313 VisualizationStringFilterOperator ,
14+ VisualizationBooleanFilterOperator ,
1415 numberFilterOperators ,
1516 stringFilterOperators ,
1617 dateFilterOperators ,
18+ booleanFilterOperators ,
1719 VisualizationNumberFilter ,
1820 VisualizationStringFilter ,
1921 VisualizationDateFilter ,
22+ VisualizationBooleanFilter ,
2023 toDate ,
2124 DataFrame ,
2225 VisualizationFilter ,
@@ -49,6 +52,7 @@ function isNumberOperator(
4952 | VisualizationNumberFilterOperator
5053 | VisualizationStringFilterOperator
5154 | VisualizationDateFilterOperator
55+ | VisualizationBooleanFilterOperator
5256) : operator is VisualizationNumberFilterOperator {
5357 return VisualizationNumberFilterOperator . safeParse ( operator ) . success
5458}
@@ -58,15 +62,27 @@ function isStringOperator(
5862 | VisualizationNumberFilterOperator
5963 | VisualizationStringFilterOperator
6064 | VisualizationDateFilterOperator
65+ | VisualizationBooleanFilterOperator
6166) : operator is VisualizationStringFilterOperator {
6267 return VisualizationStringFilterOperator . safeParse ( operator ) . success
6368}
6469
70+ function isBooleanOperator (
71+ operator :
72+ | VisualizationNumberFilterOperator
73+ | VisualizationStringFilterOperator
74+ | VisualizationDateFilterOperator
75+ | VisualizationBooleanFilterOperator
76+ ) : operator is VisualizationBooleanFilterOperator {
77+ return VisualizationBooleanFilterOperator . safeParse ( operator ) . success
78+ }
79+
6580function isDateOperator (
6681 operator :
6782 | VisualizationNumberFilterOperator
6883 | VisualizationStringFilterOperator
6984 | VisualizationDateFilterOperator
85+ | VisualizationBooleanFilterOperator
7086) : operator is VisualizationDateFilterOperator {
7187 return VisualizationDateFilterOperator . safeParse ( operator ) . success
7288}
@@ -169,6 +185,27 @@ function stringOperatorLabel(
169185 }
170186}
171187
188+ function booleanOperatorSymbol (
189+ operator : VisualizationBooleanFilterOperator
190+ ) : string {
191+ switch ( operator ) {
192+ case 'isTrue' :
193+ return 'is true'
194+ case 'isFalse' :
195+ return 'is false'
196+ }
197+ }
198+ function booleanOperatorLabel (
199+ operator : VisualizationBooleanFilterOperator
200+ ) : string {
201+ switch ( operator ) {
202+ case 'isTrue' :
203+ return 'Is True'
204+ case 'isFalse' :
205+ return 'Is False'
206+ }
207+ }
208+
172209function dateOperatorSymbol ( operator : VisualizationDateFilterOperator ) : string {
173210 switch ( operator ) {
174211 case 'eq' :
@@ -215,6 +252,7 @@ function getOperatorLabel(
215252 | VisualizationStringFilterOperator
216253 | VisualizationNumberFilterOperator
217254 | VisualizationDateFilterOperator
255+ | VisualizationBooleanFilterOperator
218256) : string {
219257 if ( isNumberOperator ( operator ) ) {
220258 return numberOperatorLabel ( operator )
@@ -224,6 +262,10 @@ function getOperatorLabel(
224262 return stringOperatorLabel ( operator )
225263 }
226264
265+ if ( isBooleanOperator ( operator ) ) {
266+ return booleanOperatorLabel ( operator )
267+ }
268+
227269 return dateOperatorLabel ( operator )
228270}
229271
@@ -232,6 +274,7 @@ function searchOperator<
232274 | VisualizationNumberFilterOperator
233275 | VisualizationStringFilterOperator
234276 | VisualizationDateFilterOperator
277+ | VisualizationBooleanFilterOperator
235278> ( options : T [ ] , query : string ) : T [ ] {
236279 return options . filter ( ( c ) => {
237280 if ( isNumberOperator ( c ) ) {
@@ -248,6 +291,13 @@ function searchOperator<
248291 )
249292 }
250293
294+ if ( isBooleanOperator ( c ) ) {
295+ return (
296+ booleanOperatorLabel ( c ) . toLowerCase ( ) . includes ( query . toLowerCase ( ) ) ||
297+ booleanOperatorSymbol ( c ) . toLowerCase ( ) . includes ( query . toLowerCase ( ) )
298+ )
299+ }
300+
251301 return (
252302 dateOperatorLabel ( c ) . toLowerCase ( ) . includes ( query . toLowerCase ( ) ) ||
253303 dateOperatorSymbol ( c ) . toLowerCase ( ) . includes ( query . toLowerCase ( ) )
@@ -268,9 +318,8 @@ function getOperatorOptions(columnType: DataFrameColumn['type']) {
268318 return dateFilterOperators
269319 }
270320
271- // TODO: add filtering capabilities for boolean types
272321 if ( NumpyBoolTypes . safeParse ( columnType ) . success ) {
273- return [ ]
322+ return booleanFilterOperators
274323 }
275324
276325 // TODO: this should never happen, we should be alerted
@@ -281,6 +330,7 @@ type Operator =
281330 | VisualizationStringFilterOperator
282331 | VisualizationNumberFilterOperator
283332 | VisualizationDateFilterOperator
333+ | VisualizationBooleanFilterOperator
284334
285335interface Props {
286336 dataframe : Pick < DataFrame , 'name' | 'columns' >
@@ -364,6 +414,13 @@ function FilterSelector(props: Props) {
364414 return
365415 }
366416
417+ if ( NumpyBoolTypes . safeParse ( column . type ) . success ) {
418+ if ( ! isBooleanOperator ( operator ) ) {
419+ setOperator ( 'isTrue' )
420+ }
421+ return
422+ }
423+
367424 if ( NumpyDateTypes . safeParse ( column . type ) . success ) {
368425 if ( ! isDateOperator ( operator ) ) {
369426 setOperator ( 'eq' )
@@ -418,6 +475,23 @@ function FilterSelector(props: Props) {
418475 }
419476 }
420477
478+ if (
479+ NumpyBoolTypes . safeParse ( column . type ) . success
480+ ) {
481+ if ( isBooleanOperator ( operator ) ) {
482+ const filter = VisualizationBooleanFilter . safeParse ( {
483+ id : props . filter . id ,
484+ column,
485+ operator,
486+ value,
487+ } )
488+ if ( filter . success ) {
489+ props . onChange ( filter . data )
490+ return
491+ }
492+ }
493+ }
494+
421495 if ( NumpyDateTypes . safeParse ( column . type ) . success ) {
422496 if ( isDateOperator ( operator ) ) {
423497 const filter = VisualizationDateFilter . safeParse ( {
@@ -514,7 +588,7 @@ function FilterSelector(props: Props) {
514588 }
515589 }
516590
517- if ( column && ( newOp === 'isNull' || newOp === 'isNotNull' ) ) {
591+ if ( column && ( newOp === 'isNull' || newOp === 'isNotNull' || newOp === 'isTrue' || newOp === 'isFalse' ) ) {
518592 if (
519593 NumpyNumberTypes . or ( NumpyTimeDeltaTypes ) . safeParse ( column . type )
520594 . success
@@ -528,6 +602,12 @@ function FilterSelector(props: Props) {
528602 setValue ( 'filter' )
529603 }
530604
605+ if (
606+ NumpyBoolTypes . safeParse ( column . type ) . success
607+ ) {
608+ setValue ( 'filter' ) // FIXME: Improve value handling for boolean filtering
609+ }
610+
531611 if ( NumpyDateTypes . safeParse ( column . type ) . success ) {
532612 setValue ( new Date ( ) . toISOString ( ) )
533613 }
@@ -636,7 +716,7 @@ function FilterSelector(props: Props) {
636716 < span > { column ?. name ?? 'New filter' } </ span >
637717 < span
638718 className = { clsx (
639- operator === 'isNull' || operator === 'isNotNull'
719+ operator === 'isNull' || operator === 'isNotNull' || operator === 'isTrue' || operator === 'isFalse'
640720 ? 'pl-0.5'
641721 : 'px-0.5' ,
642722 props . isInvalid ? 'text-red-400' : 'text-gray-400'
@@ -647,10 +727,12 @@ function FilterSelector(props: Props) {
647727 ? numberOperatorSymbol ( operator )
648728 : isStringOperator ( operator )
649729 ? stringOperatorSymbol ( operator )
730+ : isBooleanOperator ( operator )
731+ ? booleanOperatorSymbol ( operator )
650732 : dateOperatorSymbol ( operator )
651733 : '' }
652734 </ span >
653- { operator !== 'isNull' && operator !== 'isNotNull' ? (
735+ { operator !== 'isNull' && operator !== 'isNotNull' && operator !== 'isTrue' && operator !== 'isFalse' ? (
654736 < >
655737 { renderedValue ? (
656738 < span className = "px-1.5 py-0.5 bg-ceramic-100 text-ceramic-500 rounded-md" >
@@ -719,6 +801,7 @@ function FilterSelector(props: Props) {
719801 | VisualizationNumberFilterOperator
720802 | VisualizationDateFilterOperator
721803 | VisualizationStringFilterOperator
804+ | VisualizationBooleanFilterOperator
722805 >
723806 icon = { ( ) => null }
724807 label = "Operator"
@@ -730,7 +813,7 @@ function FilterSelector(props: Props) {
730813 placeholder = "Operator"
731814 disabled = { props . disabled }
732815 />
733- { operator !== 'isNull' && operator !== 'isNotNull' && (
816+ { operator !== 'isNull' && operator !== 'isNotNull' && operator !== 'isTrue' && operator !== 'isFalse' && (
734817 < div className = "relative" >
735818 { VisualizationStringFilterMultiValuesOperator . safeParse (
736819 operator
0 commit comments