Skip to content

Commit a4bb829

Browse files
committed
feat(datagrid-web): wip:refactor, MultiPageSelectionController
1 parent a9c8756 commit a4bb829

File tree

12 files changed

+203
-154
lines changed

12 files changed

+203
-154
lines changed

packages/pluggableWidgets/datagrid-web/src/Datagrid.editorPreview.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ export function preview(props: DatagridPreviewProps): ReactElement {
9797
selectActionHelper,
9898
cellEventsController: eventsController,
9999
checkboxEventsController: eventsController,
100+
multiPageSelectionController: {} as any, // Mock for preview
100101
focusController,
101102
selectionCountStore,
102103
selectAllProgressStore: new SelectAllProgressStore(),

packages/pluggableWidgets/datagrid-web/src/Datagrid.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ const Container = observer((props: Props): ReactElement => {
7474
checkboxEventsController,
7575
focusController,
7676
selectionCountStore: rootStore.selectionCountStore,
77-
selectAllProgressStore: rootStore.selectAllProgressStore,
78-
rootStore
77+
multiPageSelectionController: rootStore.multiPageSelectionController,
78+
selectAllProgressStore: rootStore.selectAllProgressStore
7979
};
8080
});
8181

packages/pluggableWidgets/datagrid-web/src/components/CheckboxColumnHeader.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import { createElement, Fragment, ReactElement } from "react";
33
import { useDatagridRootScope } from "../helpers/root-context";
44

55
export function CheckboxColumnHeader(): ReactElement {
6-
const { selectActionHelper, basicData, selectAllProgressStore, rootStore } = useDatagridRootScope();
6+
const { selectActionHelper, basicData, selectAllProgressStore, multiPageSelectionController } =
7+
useDatagridRootScope();
78
const { showCheckboxColumn, showSelectAllToggle, onSelectAll } = selectActionHelper;
89
const { selectionStatus, selectAllRowsLabel } = basicData;
910

@@ -27,10 +28,14 @@ export function CheckboxColumnHeader(): ReactElement {
2728
if (selectActionHelper.canSelectAllPages) {
2829
if (selectionStatus === "none") {
2930
// Select all pages
30-
await rootStore?.startMultiPageSelectAll(selectActionHelper);
31+
const success = await multiPageSelectionController.selectAllPages();
32+
if (!success) {
33+
// Fallback to single page selection if multi-page fails
34+
onSelectAll();
35+
}
3136
} else {
3237
// Unselect all pages (both "all" and "some" states)
33-
await rootStore?.clearAllPages();
38+
multiPageSelectionController.clearAllPages();
3439
}
3540
return;
3641
}

packages/pluggableWidgets/datagrid-web/src/components/Widget.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ export interface WidgetProps<C extends GridColumn, T extends ObjectItem = Object
8181

8282
export const Widget = observer(<C extends GridColumn>(props: WidgetProps<C>): ReactElement => {
8383
const { className, exporting, numberOfItems, onExportCancel, selectActionHelper } = props;
84-
const { basicData, selectAllProgressStore, rootStore } = useDatagridRootScope();
84+
const { basicData, selectAllProgressStore, multiPageSelectionController } = useDatagridRootScope();
8585

8686
const selectionEnabled = selectActionHelper.selectionType !== "None";
8787

@@ -99,7 +99,7 @@ export const Widget = observer(<C extends GridColumn>(props: WidgetProps<C>): Re
9999
open={selectAllProgressStore.selecting}
100100
selectingLabel={basicData.selectingAllLabel ?? "Selecting all items..."}
101101
cancelLabel={basicData.cancelSelectionLabel ?? "Cancel selection"}
102-
onCancel={() => rootStore.abortMultiPageSelect()}
102+
onCancel={() => multiPageSelectionController.abort()}
103103
progress={selectAllProgressStore.loaded}
104104
total={selectAllProgressStore.total}
105105
/>

packages/pluggableWidgets/datagrid-web/src/components/__tests__/Table.spec.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import { ClickActionHelper } from "@mendix/widget-plugin-grid/helpers/ClickActionHelper";
2-
import { MultiSelectionStatus, useSelectionHelper } from "@mendix/widget-plugin-grid/selection";
2+
import {
3+
MultiSelectionStatus,
4+
useSelectionHelper,
5+
MultiPageSelectionController
6+
} from "@mendix/widget-plugin-grid/selection";
37
import { SelectionCountStore } from "@mendix/widget-plugin-grid/selection/stores/SelectionCountStore";
48
import {
59
list,
@@ -66,6 +70,7 @@ function withCtx(
6670
selectActionHelper: widgetProps.selectActionHelper,
6771
cellEventsController: widgetProps.cellEventsController,
6872
checkboxEventsController: widgetProps.checkboxEventsController,
73+
multiPageSelectionController: {} as unknown as MultiPageSelectionController,
6974
focusController: widgetProps.focusController,
7075
selectionCountStore: defaultSelectionCountStore as unknown as SelectionCountStore,
7176
selectAllProgressStore: {} as unknown as SelectAllProgressStore,

packages/pluggableWidgets/datagrid-web/src/helpers/root-context.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import { SelectionCountStore } from "@mendix/widget-plugin-grid/selection/stores
44
import { createContext, useContext } from "react";
55
import { SelectAllProgressStore } from "../features/multi-page-selection/SelectAllProgressStore";
66
import { GridBasicData } from "../helpers/state/GridBasicData";
7-
import { RootGridStore } from "../helpers/state/RootGridStore";
87
import { EventsController } from "../typings/CellComponent";
98
import { SelectActionHelper } from "./SelectActionHelper";
9+
import { MultiPageSelectionController } from "@mendix/widget-plugin-grid/selection/MultiPageSelectionController";
1010

1111
export interface DatagridRootScope {
1212
basicData: GridBasicData;
@@ -15,10 +15,10 @@ export interface DatagridRootScope {
1515
selectActionHelper: SelectActionHelper;
1616
cellEventsController: EventsController;
1717
checkboxEventsController: EventsController;
18+
multiPageSelectionController: MultiPageSelectionController;
1819
focusController: FocusTargetController;
1920
selectionCountStore: SelectionCountStore;
2021
selectAllProgressStore: SelectAllProgressStore;
21-
rootStore: RootGridStore;
2222
}
2323

2424
export const DatagridContext = createContext<DatagridRootScope | null>(null);

packages/pluggableWidgets/datagrid-web/src/helpers/state/RootGridStore.ts

Lines changed: 11 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { CustomFilterHost } from "@mendix/widget-plugin-filtering/stores/generic
44
import { DatasourceController } from "@mendix/widget-plugin-grid/query/DatasourceController";
55
import { QueryController } from "@mendix/widget-plugin-grid/query/query-controller";
66
import { RefreshController } from "@mendix/widget-plugin-grid/query/RefreshController";
7-
import { clearAllPages, selectAllPages } from "@mendix/widget-plugin-grid/selection/select-all-pages";
7+
import { MultiPageSelectionController } from "@mendix/widget-plugin-grid/selection";
88
import { SelectionCountStore } from "@mendix/widget-plugin-grid/selection/stores/SelectionCountStore";
99
import { BaseControllerHost } from "@mendix/widget-plugin-mobx-kit/BaseControllerHost";
1010
import { disposeBatch } from "@mendix/widget-plugin-mobx-kit/disposeBatch";
@@ -38,6 +38,8 @@ type RequiredProps = Pick<
3838
| "pagination"
3939
| "showPagingButtons"
4040
| "showNumberOfRows"
41+
| "selectAllPagesEnabled"
42+
| "selectAllPagesBufferSize"
4143
>;
4244

4345
type Gate = DerivedPropsGate<RequiredProps>;
@@ -55,8 +57,7 @@ export class RootGridStore extends BaseControllerHost {
5557
staticInfo: StaticInfo;
5658
exportProgressCtrl: ProgressStore;
5759
selectAllProgressStore: SelectAllProgressStore;
58-
private selectAllAbortController?: AbortController;
59-
private selectAllLocked = false;
60+
multiPageSelectionController: MultiPageSelectionController;
6061
loaderCtrl: DerivedLoaderController;
6162
paginationCtrl: PaginationController;
6263
readonly filterAPI: FilterAPI;
@@ -104,6 +105,13 @@ export class RootGridStore extends BaseControllerHost {
104105

105106
this.selectAllProgressStore = new SelectAllProgressStore();
106107

108+
this.multiPageSelectionController = new MultiPageSelectionController(this, {
109+
gate,
110+
query,
111+
progressStore: this.selectAllProgressStore,
112+
bufferSize: props.selectAllPagesBufferSize ?? 500
113+
});
114+
107115
new DatasourceParamsController(this, {
108116
query,
109117
filterHost: combinedFilter,
@@ -140,47 +148,4 @@ export class RootGridStore extends BaseControllerHost {
140148
this.columnsStore.updateProps(props);
141149
this.settingsStore.updateProps(props);
142150
}
143-
144-
async startMultiPageSelectAll(selectActionHelper: SelectActionHelper): Promise<void> {
145-
if (this.selectAllLocked) {
146-
return;
147-
}
148-
149-
// Check if multi-page selection is possible
150-
const canSelect = selectActionHelper.canSelectAllPages;
151-
152-
if (!canSelect) {
153-
selectActionHelper.onSelectAll("selectAll");
154-
return;
155-
}
156-
157-
this.selectAllLocked = true;
158-
this.selectAllAbortController = new AbortController();
159-
const success = await selectAllPages({
160-
query: this.query as QueryController,
161-
gate: this.gate as any,
162-
progress: this.selectAllProgressStore,
163-
bufferSize: selectActionHelper.selectAllPagesBufferSize,
164-
signal: this.selectAllAbortController.signal
165-
});
166-
167-
if (!success) {
168-
selectActionHelper.onSelectAll("selectAll");
169-
}
170-
this.selectAllLocked = false;
171-
this.selectAllAbortController = undefined;
172-
}
173-
174-
async clearAllPages(): Promise<void> {
175-
clearAllPages(this.gate);
176-
}
177-
178-
abortMultiPageSelect(): void {
179-
if (this.selectAllAbortController) {
180-
this.selectAllAbortController.abort();
181-
this.selectAllProgressStore.oncancel();
182-
this.selectAllLocked = false;
183-
this.selectAllAbortController = undefined;
184-
}
185-
}
186151
}

packages/shared/widget-plugin-grid/src/query/DatasourceController.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ export class DatasourceController implements ReactiveController, QueryController
103103
return this.datasource.hasMoreItems ?? false;
104104
}
105105

106+
get items(): ObjectItem[] | undefined {
107+
return this.datasource.items;
108+
}
109+
106110
/**
107111
* Returns computed value that holds controller copy.
108112
* Recomputes the copy every time the datasource changes.

packages/shared/widget-plugin-grid/src/query/query-controller.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ type Members =
99
| "totalCount"
1010
| "limit"
1111
| "offset"
12+
| "items"
1213
| "hasMoreItems";
1314

1415
export interface QueryController extends Pick<ListValue, Members> {

packages/shared/widget-plugin-grid/src/selection.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ export {
66
useCreateSelectionContextValue,
77
useSelectionContextValue
88
} from "./selection/context.js";
9-
export { selectAllPages } from "./selection/select-all-pages.js";
9+
export { MultiPageSelectionController } from "./selection/MultiPageSelectionController.js";
1010
export { SelectActionHandler } from "./selection/select-action-handler.js";

0 commit comments

Comments
 (0)