1
1
import { DatasourceController } from "@mendix/widget-plugin-grid/query/DatasourceController" ;
2
- import { MultiSelectionHelper , SelectionHelper } from "@mendix/widget-plugin-grid/selection/helpers" ;
2
+ import { MultiSelectionHelper } from "@mendix/widget-plugin-grid/selection/helpers" ;
3
+ import { DerivedPropsGate } from "@mendix/widget-plugin-mobx-kit/props-gate" ;
3
4
import { ReactiveController , ReactiveControllerHost } from "@mendix/widget-plugin-mobx-kit/reactive-controller" ;
4
- import { ListValue , ObjectItem } from "mendix" ;
5
+ import { ListValue , ObjectItem , SelectionMultiValue , SelectionSingleValue } from "mendix" ;
5
6
import { SelectAllProgressStore } from "./SelectAllProgressStore" ;
6
7
7
8
interface MultiPageSelectionControllerSpec {
8
9
query : DatasourceController ;
9
10
progressStore : SelectAllProgressStore ;
11
+ gate : Gate ;
10
12
}
13
+ type Gate = DerivedPropsGate < { itemSelection ?: SelectionMultiValue | SelectionSingleValue } > ;
11
14
12
15
export class MultiPageSelectionController implements ReactiveController {
13
16
private query : DatasourceController ;
14
17
private progressStore : SelectAllProgressStore ;
15
18
private abortController ?: AbortController ;
16
19
private locked = false ;
20
+ private gate : Gate ;
17
21
18
22
constructor ( host : ReactiveControllerHost , spec : MultiPageSelectionControllerSpec ) {
19
23
host . addController ( this ) ;
20
24
this . query = spec . query ;
21
25
this . progressStore = spec . progressStore ;
26
+ this . gate = spec . gate ;
22
27
}
23
28
24
29
get isRunning ( ) : boolean {
@@ -43,12 +48,12 @@ export class MultiPageSelectionController implements ReactiveController {
43
48
/**
44
49
* Starts the multi-page selection process
45
50
*/
46
- async selectAllPages ( datasource : ListValue , selectionHelper : SelectionHelper ) : Promise < boolean > {
51
+ async selectAllPages ( ) : Promise < boolean > {
47
52
if ( this . locked ) {
48
53
return false ;
49
54
}
50
55
51
- if ( selectionHelper . type !== "Multi" ) {
56
+ if ( ! this . gate . props . itemSelection || this . gate . props . itemSelection . type !== "Multi" ) {
52
57
return false ;
53
58
}
54
59
@@ -75,11 +80,20 @@ export class MultiPageSelectionController implements ReactiveController {
75
80
76
81
// Use controller-based traversal to properly handle pagination
77
82
const naturalChunkSize = datasource . limit ?? 25 ;
78
- if ( selectionHelper . type !== "Multi" ) {
79
- throw new Error ( "Expected MultiSelectionHelper" ) ;
80
- }
83
+
81
84
const multiHelper = selectionHelper ;
82
- await this . selectAllWithController ( multiHelper , totalCount , naturalChunkSize ) ;
85
+ const originalOffset = this . query . offset ;
86
+ const originalLimit = this . query . limit ;
87
+ const allItems : ObjectItem [ ] = [ ] ;
88
+
89
+ const limit = 100 ;
90
+ const offset = 0 ;
91
+
92
+ while ( this . query . datasource . hasMoreItems ) {
93
+ const page = await this . query . fetchPage ( { limit, offset, signal : this . abortController . signal } ) ;
94
+ allItems . push ( ...page ) ;
95
+ }
96
+ this . gate . props . itemSelection . setSelection ( allItems ) ;
83
97
84
98
success = true ;
85
99
} catch ( _error ) {
@@ -176,8 +190,7 @@ export class MultiPageSelectionController implements ReactiveController {
176
190
}
177
191
178
192
// First, set the selection while we have all the items
179
- ( multiHelper as any ) . selectionValue . setSelection ( allItems ) ;
180
- ( multiHelper as any ) . _resetRange ( ) ;
193
+ this . query . datasource ( multiHelper as any ) . _resetRange ( ) ;
181
194
182
195
// Small delay to ensure selection is committed
183
196
await new Promise ( resolve => setTimeout ( resolve , 50 ) ) ;
@@ -192,19 +205,19 @@ export class MultiPageSelectionController implements ReactiveController {
192
205
/**
193
206
* Waits for the datasource to reflect the controller changes
194
207
*/
195
- private async waitForDatasourceUpdate (
196
- expectedOffset : number ,
197
- expectedLimit : number ,
198
- maxAttempts = 20
199
- ) : Promise < void > {
200
- for ( let i = 0 ; i < maxAttempts ; i ++ ) {
201
- const ds = this . query . datasource ;
202
- if ( ds . status !== "loading" && ds . offset === expectedOffset && ds . limit === expectedLimit ) {
203
- return ;
204
- }
205
- await new Promise ( resolve => setTimeout ( resolve , 50 ) ) ;
206
- }
207
- }
208
+ // private async waitForDatasourceUpdate(
209
+ // expectedOffset: number,
210
+ // expectedLimit: number,
211
+ // maxAttempts = 20
212
+ // ): Promise<void> {
213
+ // for (let i = 0; i < maxAttempts; i++) {
214
+ // const ds = this.query.datasource;
215
+ // if (ds.status !== "loading" && ds.offset === expectedOffset && ds.limit === expectedLimit) {
216
+ // return;
217
+ // }
218
+ // await new Promise(resolve => setTimeout(resolve, 50));
219
+ // }
220
+ // }
208
221
209
222
/**
210
223
* Ensures totalCount is available, requesting it if necessary
0 commit comments