1- import { compactArray , fromCompactArray , isAnd } from "@mendix/filter-commons/condition-utils" ;
1+ import { reduceArray , restoreArray } from "@mendix/filter-commons/condition-utils" ;
22import { QueryController } from "@mendix/widget-plugin-grid/query/query-controller" ;
3+ import { fnv1aHash } from "@mendix/widget-plugin-grid/utils/fnv-1a-hash" ;
34import { disposeBatch } from "@mendix/widget-plugin-mobx-kit/disposeBatch" ;
45import { ReactiveController , ReactiveControllerHost } from "@mendix/widget-plugin-mobx-kit/reactive-controller" ;
56import { FilterCondition } from "mendix/filters" ;
6- import { and } from "mendix/filters/builders" ;
77import { makeAutoObservable , reaction } from "mobx" ;
88import { SortInstruction } from "../typings/sorting" ;
99
@@ -22,10 +22,19 @@ type DatasourceParamsControllerSpec = {
2222 customFilters : FiltersInput ;
2323} ;
2424
25+ type FiltersMeta = {
26+ columnFilters : string ;
27+ customFilters : string ;
28+ combined : string ;
29+ } ;
30+
31+ type CondArray = Array < FilterCondition | undefined > ;
32+
2533export class DatasourceParamsController implements ReactiveController {
2634 private columns : Columns ;
2735 private query : QueryController ;
2836 private customFilters : FiltersInput ;
37+ readonly widgetName : string = "dataKey" ;
2938
3039 constructor ( host : ReactiveControllerHost , spec : DatasourceParamsControllerSpec ) {
3140 host . addController ( this ) ;
@@ -36,16 +45,41 @@ export class DatasourceParamsController implements ReactiveController {
3645 makeAutoObservable ( this , { setup : false } ) ;
3746 }
3847
39- private get derivedFilter ( ) : FilterCondition | undefined {
40- const { columns, customFilters } = this ;
48+ private get derivedFilter ( ) : {
49+ filter : FilterCondition | undefined ;
50+ meta : FiltersMeta ;
51+ hash : string | null ;
52+ } {
53+ // return and(compactArray(this.columns.conditions), compactArray(this.customFilters.conditions));
54+ return this . reduceFilters ( this . columns . conditions , this . customFilters . conditions ) ;
55+
56+ // console.dir(...reduceArray(columns.conditions));
4157
42- return and ( compactArray ( columns . conditions ) , compactArray ( customFilters . conditions ) ) ;
58+ // return [this. columns.conditions, this. customFilters.conditions] ;
4359 }
4460
4561 private get derivedSortOrder ( ) : SortInstruction [ ] | undefined {
4662 return this . columns . sortInstructions ;
4763 }
4864
65+ reduceFilters (
66+ columnFilters : CondArray ,
67+ customFilters : CondArray
68+ ) : {
69+ filter : FilterCondition | undefined ;
70+ meta : FiltersMeta ;
71+ hash : string | null ;
72+ } {
73+ const [ columnsCond , columnsMeta ] = reduceArray ( columnFilters ) ;
74+ const [ customCond , customMeta ] = reduceArray ( customFilters ) ;
75+ const [ filter , combinedMeta ] = reduceArray ( [ columnsCond , customCond ] ) ;
76+
77+ const meta : FiltersMeta = { columnFilters : columnsMeta , customFilters : customMeta , combined : combinedMeta } ;
78+ const hash = filter ? DatasourceParamsController . filterHash ( filter ) : null ;
79+
80+ return { filter, meta, hash } ;
81+ }
82+
4983 setup ( ) : ( ) => void {
5084 const [ add , disposeAll ] = disposeBatch ( ) ;
5185 add (
@@ -58,28 +92,71 @@ export class DatasourceParamsController implements ReactiveController {
5892 add (
5993 reaction (
6094 ( ) => this . derivedFilter ,
61- filter => this . query . setFilter ( filter ) ,
95+ ( next , prev ) => {
96+ if ( prev && prev . hash ) {
97+ this . clearFilterMeta ( prev . hash ) ;
98+ }
99+ if ( next . hash ) {
100+ this . saveFilterMeta ( next . hash , next . meta ) ;
101+ }
102+ this . query . setFilter ( next . filter ) ;
103+ } ,
62104 { fireImmediately : true }
63105 )
64106 ) ;
65107
66108 return disposeAll ;
67109 }
68110
111+ storageKey ( hash : string ) : string {
112+ return `${ this . widgetName } :[${ hash } ]` ;
113+ }
114+
115+ clearFilterMeta ( hash : string ) : void {
116+ sessionStorage . removeItem ( this . storageKey ( hash ) ) ;
117+ }
118+
119+ saveFilterMeta ( hash : string | null , meta : FiltersMeta ) : void {
120+ if ( ! hash ) {
121+ return ;
122+ }
123+
124+ sessionStorage . setItem ( this . storageKey ( hash ) , JSON . stringify ( meta ) ) ;
125+ }
126+
127+ readFilterMeta ( hash : string ) : FiltersMeta | null {
128+ const item = sessionStorage . getItem ( this . storageKey ( hash ) ) ;
129+ if ( ! item ) {
130+ return null ;
131+ }
132+ try {
133+ return JSON . parse ( item ) as FiltersMeta ;
134+ } catch ( e ) {
135+ console . error ( `DatasourceParamsController.readFilterMeta: Error parsing meta for hash ${ hash } ` , e ) ;
136+ return null ;
137+ }
138+ }
139+
140+ static filterHash ( filter : FilterCondition ) : string {
141+ return fnv1aHash ( JSON . stringify ( filter ) ) . toString ( ) ;
142+ }
143+
69144 static unzipFilter (
70- filter ?: FilterCondition
71- ) : [ columns : Array < FilterCondition | undefined > , sharedFilter : Array < FilterCondition | undefined > ] {
145+ filter ?: FilterCondition ,
146+ widgetName = "dataKey"
147+ ) : [ columnFilters : Array < FilterCondition | undefined > , customFilters : Array < FilterCondition | undefined > ] {
72148 if ( ! filter ) {
73149 return [ [ ] , [ ] ] ;
74150 }
75- if ( ! isAnd ( filter ) ) {
151+ const hash = this . filterHash ( filter ) ;
152+ const metaJson = sessionStorage . getItem ( `${ widgetName } :[${ hash } ]` ) ;
153+ if ( ! metaJson ) {
76154 return [ [ ] , [ ] ] ;
77155 }
78- if ( filter . args . length !== 2 ) {
79- return [ [ ] , [ ] ] ;
80- }
81-
82- const [ columns , shared ] = filter . args ;
83- return [ fromCompactArray ( columns ) , fromCompactArray ( shared ) ] ;
156+ const meta = JSON . parse ( metaJson ) as FiltersMeta ;
157+ const [ x , y ] = restoreArray ( filter , meta . combined ) ;
158+ const columnFilters = restoreArray ( x , meta . columnFilters ) ;
159+ const customFilters = restoreArray ( y , meta . customFilters ) ;
160+ return [ columnFilters , customFilters ] ;
84161 }
85162}
0 commit comments