11import { countBy , flatMap , identity , sortBy } from "lodash" ;
2- import { FC , useEffect , useState } from "react" ;
2+ import { FC , useCallback , useEffect , useState } from "react" ;
33import { useTranslation } from "react-i18next" ;
44
55import { useFiltersActions , useGraphDataset } from "../../core/context/dataContexts" ;
66import { TermsFilterType } from "../../core/filters/types" ;
77import { useFilteredGraphAt } from "../../core/graph" ;
88import { computeAllDynamicAttributes , mergeStaticDynamicData } from "../../core/graph/dynamicAttributes" ;
99import { getFieldValue } from "../../core/graph/fieldModel" ;
10- import { Select } from "../forms/Select" ;
10+ import { BaseOption , Select } from "../forms/Select" ;
1111import { toPairsCompatibleWithSymbol } from "./utils" ;
1212
1313const unavailableValue : unique symbol = Symbol ( "Not Available" ) ;
14+ const trueValue : unique symbol = Symbol ( "True Value" ) ;
15+ const falseValue : unique symbol = Symbol ( "False Value" ) ;
16+
17+ type TermsFilterSymbolsType = typeof unavailableValue | typeof trueValue | typeof falseValue ;
18+ const symbolToValue = ( symbol : TermsFilterSymbolsType ) : boolean | null => {
19+ switch ( symbol ) {
20+ case unavailableValue :
21+ return null ;
22+ case trueValue :
23+ return true ;
24+ case falseValue :
25+ return false ;
26+ }
27+ } ;
28+ const valueToSymbol = ( value : string | boolean | null ) : string | TermsFilterSymbolsType => {
29+ switch ( typeof value ) {
30+ case "string" :
31+ return value ;
32+ case "boolean" :
33+ return value === true ? trueValue : falseValue ;
34+ default :
35+ return unavailableValue ;
36+ }
37+ } ;
1438
1539export const TermsFilter : FC < { filter : TermsFilterType ; filterIndex : number } > = ( { filter, filterIndex } ) => {
1640 const parentGraph = useFilteredGraphAt ( filterIndex - 1 ) ;
1741 const { nodeData, edgeData } = useGraphDataset ( ) ;
1842
1943 const { t } = useTranslation ( ) ;
44+ const termLabel = useCallback (
45+ ( term : string | TermsFilterSymbolsType ) => {
46+ switch ( term ) {
47+ case unavailableValue :
48+ return t ( "filters.noValueOption" ) ;
49+ case trueValue :
50+ return t ( "filters.booleanTrueOption" ) ;
51+ case falseValue :
52+ return t ( "filters.booleanFalseOption" ) ;
53+ default :
54+ return term ;
55+ }
56+ } ,
57+ [ t ] ,
58+ ) ;
2059 const { updateFilter } = useFiltersActions ( ) ;
21- const [ dataTerms , setDataTerms ] = useState < Record < string | typeof unavailableValue , number > > ( {
60+ const [ dataTerms , setDataTerms ] = useState < Record < string | TermsFilterSymbolsType , number > > ( {
2261 [ unavailableValue ] : 0 ,
62+ [ trueValue ] : 0 ,
63+ [ falseValue ] : 0 ,
2364 } ) ;
2465
2566 useEffect ( ( ) => {
@@ -35,36 +76,35 @@ export const TermsFilter: FC<{ filter: TermsFilterType; filterIndex: number }> =
3576 filter . itemType === "nodes" ? parentGraph . nodes ( ) : parentGraph . edges ( ) ,
3677 ( itemId ) => {
3778 const fieldValue = getFieldValue ( itemData [ itemId ] , filter . field ) ;
38- if ( fieldValue === undefined && filter . field . type === "category" )
79+ if ( fieldValue === undefined && ( filter . field . type === "category" || filter . field . type === "boolean" ) )
3980 // if fieldValue is undefined we return the NA symbol but only for category field
4081 return unavailableValue ;
41- else return fieldValue ;
82+ if ( filter . field . type === "boolean" ) return fieldValue === true ? trueValue : falseValue ;
83+ return fieldValue ;
4284 } ,
4385 // for category field we keep notAvailable values to propose it a possible filter value
44- ) . filter ( ( v ) => ( filter . field . type !== "category" ? typeof v === "string" : true ) ) ,
86+ ) . filter ( ( v ) =>
87+ filter . field . type !== "category" && filter . field . type !== "boolean" ? typeof v === "string" : true ,
88+ ) ,
4589 identity ,
4690 ) ;
4791 setDataTerms ( terms as Record < string | symbol , number > ) ;
4892 } , [ filter , parentGraph , nodeData , edgeData ] ) ;
49- console . log ( filter . terms ) ;
93+
5094 return (
5195 < div className = "w-100" >
52- < Select
96+ < Select < BaseOption < string | null | boolean > , true >
5397 autoFocus
5498 value = {
5599 filter . terms
56100 ? Array . from ( filter . terms ) . map ( ( term ) => ( {
57- label : term === null ? t ( "filters.noValueOption" ) : term ,
101+ label : termLabel ( valueToSymbol ( term ) ) ,
58102 value : term ,
59103 } ) )
60104 : [ ]
61105 }
62106 onChange = { ( options ) => {
63- const selectedValues = new Set (
64- options . map ( ( o ) : string | null =>
65- o . value === unavailableValue || typeof o . value === "symbol" ? null : o . value ,
66- ) ,
67- ) ;
107+ const selectedValues = new Set ( options . map ( ( o ) : string | null | boolean => o . value ) ) ;
68108 updateFilter ( filterIndex , {
69109 ...filter ,
70110 terms : selectedValues . size > 0 ? selectedValues : undefined ,
@@ -77,18 +117,18 @@ export const TermsFilter: FC<{ filter: TermsFilterType; filterIndex: number }> =
77117 } }
78118 options = { sortBy ( toPairsCompatibleWithSymbol ( dataTerms ) , ( [ _term , nbOcc ] ) => - 1 * nbOcc ) . map ( ( [ term , nbOcc ] ) => {
79119 return {
80- label : `${ typeof term === "symbol" ? t ( "filters.noValueOption" ) : term } (${ nbOcc } ${ t ( `graph.model.${ filter . itemType } ` ) } )` ,
81- value : term === unavailableValue ? null : term ,
120+ label : `${ termLabel ( term as string | TermsFilterSymbolsType ) } (${ nbOcc } ${ t ( `graph.model.${ filter . itemType } ` ) } )` ,
121+ value : typeof term === "string" ? term : symbolToValue ( term as TermsFilterSymbolsType ) ,
82122 } ;
83123 } ) }
84124 />
85- { filter . field . type !== "category" && (
125+ { filter . field . type !== "category" && filter . field . type !== "boolean" && (
86126 < div className = "form-check mt-1" >
87127 < input
88128 className = "form-check-input"
89129 type = "checkbox"
90130 id = "keepMissingValuesTerms"
91- checked = { ! ! filter . keepMissingValues }
131+ checked = { filter . keepMissingValues === true }
92132 onChange = { ( e ) => {
93133 updateFilter ( filterIndex , { ...filter , keepMissingValues : e . target . checked } ) ;
94134 } }
0 commit comments