Skip to content

Commit 54f32d0

Browse files
iobuhovyordan-st
authored andcommitted
refactor: migrate event controllers from DI to React Context for simplified architecture
1 parent e3a73dd commit 54f32d0

File tree

11 files changed

+115
-81
lines changed

11 files changed

+115
-81
lines changed

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

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,73 @@
1+
import { useClickActionHelper } from "@mendix/widget-plugin-grid/helpers/ClickActionHelper";
2+
import { useFocusTargetController } from "@mendix/widget-plugin-grid/keyboard-navigation/useFocusTargetController";
3+
import { useConst } from "@mendix/widget-plugin-mobx-kit/react/useConst";
14
import { ContainerProvider } from "brandi-react";
25
import { observer } from "mobx-react-lite";
36
import { ReactElement } from "react";
47
import { DatagridContainerProps } from "../typings/DatagridProps";
58
import { Widget } from "./components/Widget";
69
import { useDataExport } from "./features/data-export/useDataExport";
10+
import { useCellEventsController } from "./features/row-interaction/CellEventsController";
11+
import { useCheckboxEventsController } from "./features/row-interaction/CheckboxEventsController";
12+
import { LegacyContext } from "./helpers/root-context";
713
import { useDataGridJSActions } from "./helpers/useDataGridJSActions";
8-
import { useColumnsStore, useExportProgressService } from "./model/hooks/injection-hooks";
14+
import {
15+
useColumnsStore,
16+
useDatagridConfig,
17+
useExportProgressService,
18+
useMainGate,
19+
useSelectActions,
20+
useSelectionHelper
21+
} from "./model/hooks/injection-hooks";
922
import { useDatagridContainer } from "./model/hooks/useDatagridContainer";
1023

1124
const DatagridRoot = observer((props: DatagridContainerProps): ReactElement => {
25+
const config = useDatagridConfig();
26+
const gate = useMainGate();
1227
const columnsStore = useColumnsStore();
1328
const exportProgress = useExportProgressService();
29+
const items = gate.props.datasource.items ?? [];
1430

1531
const [abortExport] = useDataExport(props, columnsStore, exportProgress);
1632

17-
useDataGridJSActions();
33+
const selectionHelper = useSelectionHelper();
1834

19-
return <Widget onExportCancel={abortExport} />;
35+
const selectActionHelper = useSelectActions();
36+
37+
const clickActionHelper = useClickActionHelper({
38+
onClickTrigger: props.onClickTrigger,
39+
onClick: props.onClick
40+
});
41+
42+
useDataGridJSActions(selectActionHelper);
43+
44+
const visibleColumnsCount = config.checkboxColumnEnabled
45+
? columnsStore.visibleColumns.length + 1
46+
: columnsStore.visibleColumns.length;
47+
48+
const focusController = useFocusTargetController({
49+
rows: items.length,
50+
columns: visibleColumnsCount,
51+
pageSize: props.pageSize
52+
});
53+
54+
const cellEventsController = useCellEventsController(selectActionHelper, clickActionHelper, focusController);
55+
56+
const checkboxEventsController = useCheckboxEventsController(selectActionHelper, focusController);
57+
58+
return (
59+
<LegacyContext.Provider
60+
value={useConst({
61+
selectionHelper,
62+
selectActionHelper,
63+
cellEventsController,
64+
checkboxEventsController,
65+
focusController
66+
})}
67+
>
68+
<Widget onExportCancel={abortExport} />
69+
</LegacyContext.Provider>
70+
);
2071
});
2172

2273
DatagridRoot.displayName = "DatagridComponent";

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

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,24 @@
11
import { KeyNavProvider } from "@mendix/widget-plugin-grid/keyboard-navigation/context";
22
import { observer } from "mobx-react-lite";
33
import { ReactElement } from "react";
4-
import {
5-
useCellEventsHandler,
6-
useColumnsStore,
7-
useDatagridConfig,
8-
useFocusService,
9-
useRowClass,
10-
useRows,
11-
useSelectActions
12-
} from "../model/hooks/injection-hooks";
4+
import { useLegacyContext } from "../helpers/root-context";
5+
import { useColumnsStore, useDatagridConfig, useRowClass, useRows } from "../model/hooks/injection-hooks";
136
import { Row } from "./Row";
147

158
export const RowsRenderer = observer(function RowsRenderer(): ReactElement {
169
const rows = useRows().get();
1710
const config = useDatagridConfig();
1811
const { visibleColumns } = useColumnsStore();
1912
const rowClass = useRowClass();
20-
const cellEventsController = useCellEventsHandler();
21-
const focusService = useFocusService();
22-
const selectActions = useSelectActions();
23-
13+
const { cellEventsController, focusController, selectActionHelper } = useLegacyContext();
2414
return (
25-
<KeyNavProvider focusController={focusService}>
15+
<KeyNavProvider focusController={focusController}>
2616
{rows.map((item, rowIndex) => {
2717
return (
2818
<Row
2919
totalRows={rows.length}
3020
clickable={config.isInteractive}
31-
selectActions={selectActions}
21+
selectActions={selectActionHelper}
3222
eventsController={cellEventsController}
3323
className={rowClass.class.get(item)}
3424
columns={visibleColumns}

packages/pluggableWidgets/datagrid-web/src/features/row-interaction/CellEventsController.ts

Lines changed: 25 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,13 @@ import { eventSwitch } from "@mendix/widget-plugin-grid/event-switch/event-switc
44
import { ClickActionHelper, ExecuteActionFx } from "@mendix/widget-plugin-grid/helpers/ClickActionHelper";
55
import { FocusTargetController } from "@mendix/widget-plugin-grid/keyboard-navigation/FocusTargetController";
66
import { FocusTargetFx } from "@mendix/widget-plugin-grid/keyboard-navigation/base";
7-
import {
8-
SelectAdjacentFx,
9-
SelectAllFx,
10-
SelectFx,
11-
SelectionMode,
12-
SelectionType
13-
} from "@mendix/widget-plugin-grid/selection";
7+
import { SelectAdjacentFx, SelectAllFx, SelectFx } from "@mendix/widget-plugin-grid/selection";
148
import { ObjectItem } from "mendix";
9+
import { useMemo } from "react";
1510

1611
import { SelectActionsService } from "@mendix/widget-plugin-grid/main";
17-
import { ComputedAtom } from "@mendix/widget-plugin-mobx-kit/main";
1812
import { createActionHandlers } from "./action-handlers";
19-
import { CellContext, SelectionMethod } from "./base";
13+
import { CellContext } from "./base";
2014
import { createFocusTargetHandlers } from "./focus-target-handlers";
2115
import { createSelectHandlers } from "./select-handlers";
2216

@@ -51,34 +45,29 @@ export class CellEventsController {
5145
}
5246
}
5347

54-
export function createCellEventsController(
55-
config: {
56-
selectionType: SelectionType;
57-
selectionMethod: SelectionMethod;
58-
selectionMode: SelectionMode;
59-
},
60-
selectActions: SelectActionsService,
61-
focusController: FocusTargetController,
48+
export function useCellEventsController(
49+
selectHelper: SelectActionsService,
6250
clickHelper: ClickActionHelper,
63-
pageSize: ComputedAtom<number>
51+
focusController: FocusTargetController
6452
): CellEventsController {
65-
// Placeholder function, actual implementation will depend on the specific context and services available.
66-
const cellContextFactory = (item: ObjectItem): CellContext => ({
67-
type: "cell",
68-
item,
69-
pageSize: pageSize.get(),
70-
selectionType: config.selectionType,
71-
selectionMethod: config.selectionMethod,
72-
selectionMode: config.selectionMode,
73-
clickTrigger: clickHelper.clickTrigger
74-
});
53+
const pageSize = 10;
54+
return useMemo(() => {
55+
const cellContextFactory = (item: ObjectItem): CellContext => ({
56+
item,
57+
pageSize: selectHelper.pageSize,
58+
selectionType: selectHelper.selectionType,
59+
selectionMethod: selectHelper.selectionMethod,
60+
selectionMode: selectHelper.selectionMode,
61+
clickTrigger: clickHelper.clickTrigger
62+
});
7563

76-
return new CellEventsController(
77-
cellContextFactory,
78-
selectActions.select,
79-
selectActions.selectPage,
80-
selectActions.selectAdjacent,
81-
clickHelper.onExecuteAction,
82-
focusController.dispatch
83-
);
64+
return new CellEventsController(
65+
cellContextFactory,
66+
selectHelper.onSelect,
67+
selectHelper.onSelectAll,
68+
selectHelper.onSelectAdjacent,
69+
clickHelper.onExecuteAction,
70+
focusController.dispatch
71+
);
72+
}, [selectHelper, clickHelper, focusController]);
8473
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { FocusTargetController } from "@mendix/widget-plugin-grid/keyboard-navigation/FocusTargetController";
2+
import { SelectionHelperService } from "@mendix/widget-plugin-grid/main";
3+
import { createContext, useContext } from "react";
4+
import { SelectActionHelper } from "../model/services/GridSelectActionsProvider.service";
5+
import { EventsController } from "../typings/CellComponent";
6+
7+
export interface LegacyRootScope {
8+
selectionHelper: SelectionHelperService | undefined;
9+
selectActionHelper: SelectActionHelper;
10+
cellEventsController: EventsController;
11+
checkboxEventsController: EventsController;
12+
focusController: FocusTargetController;
13+
}
14+
15+
export const LegacyContext = createContext<LegacyRootScope | null>(null);
16+
17+
export const useLegacyContext = (): LegacyRootScope => {
18+
const contextValue = useContext(LegacyContext);
19+
if (!contextValue) {
20+
throw new Error("useDatagridRootScope must be used within a root context provider");
21+
}
22+
return contextValue;
23+
};

packages/pluggableWidgets/datagrid-web/src/helpers/useDataGridJSActions.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { useOnClearSelectionEvent, useOnResetFiltersEvent } from "@mendix/widget-plugin-external-events/hooks";
2-
import { useDatagridConfig, useSelectActions } from "../model/hooks/injection-hooks";
2+
import { SelectActionsService } from "@mendix/widget-plugin-grid/main";
3+
import { useDatagridConfig } from "../model/hooks/injection-hooks";
34

4-
export function useDataGridJSActions(): void {
5+
export function useDataGridJSActions(selectActions: SelectActionsService): void {
56
const info = useDatagridConfig();
6-
const selectActions = useSelectActions();
77
useOnResetFiltersEvent(info.name, info.filtersChannelName);
88
useOnClearSelectionEvent({
99
widgetName: info.name,

packages/pluggableWidgets/datagrid-web/src/model/containers/Datagrid.container.ts

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import { Container, injected } from "brandi";
1818
import { MainGateProps } from "../../../typings/MainGateProps";
1919
import { WidgetRootViewModel } from "../../features/base/WidgetRoot.viewModel";
2020
import { EmptyPlaceholderViewModel } from "../../features/empty-message/EmptyPlaceholder.viewModel";
21-
import { createCellEventsController } from "../../features/row-interaction/CellEventsController";
2221
import { creteCheckboxEventsController } from "../../features/row-interaction/CheckboxEventsController";
2322
import { SelectAllModule } from "../../features/select-all/SelectAllModule.container";
2423
import { ColumnGroupStore } from "../../helpers/state/ColumnGroupStore";
@@ -39,7 +38,7 @@ injected(DatasourceParamsController, CORE.setupService, DG.query, DG.combinedFil
3938
injected(DatasourceService, CORE.setupService, DG.queryGate, DG.refreshInterval.optional);
4039
injected(PaginationController, CORE.setupService, DG.paginationConfig, DG.query);
4140
injected(GridBasicData, CORE.mainGate);
42-
injected(WidgetRootViewModel, CORE.mainGate, CORE.config, DG.exportProgressService, SA_TOKENS.selectionDialogVM);
41+
injected(WidgetRootViewModel, CORE.mainGate, CORE.config, DG.exportProgressService, SA_TOKENS.progressService);
4342

4443
// loader
4544
injected(DerivedLoaderController, DG.query, DG.exportProgressService, CORE.columnsStore, DG.loaderConfig);
@@ -67,14 +66,6 @@ injected(createFocusController, CORE.setupService, DG.virtualLayout);
6766
injected(creteCheckboxEventsController, CORE.config, DG.selectActions, DG.focusService, CORE.atoms.pageSize);
6867
injected(layoutAtom, CORE.atoms.itemCount, CORE.atoms.columnCount, CORE.atoms.pageSize);
6968
injected(createClickActionHelper, CORE.setupService, CORE.mainGate);
70-
injected(
71-
createCellEventsController,
72-
CORE.config,
73-
DG.selectActions,
74-
DG.focusService,
75-
DG.clickActionHelper,
76-
CORE.atoms.pageSize
77-
);
7869

7970
// selection counter
8071
injected(
@@ -134,8 +125,6 @@ export class DatagridContainer extends Container {
134125
this.bind(DG.focusService).toInstance(createFocusController).inSingletonScope();
135126
// Checkbox events service
136127
this.bind(DG.checkboxEventsHandler).toInstance(creteCheckboxEventsController).inSingletonScope();
137-
// Cell events service
138-
this.bind(DG.cellEventsHandler).toInstance(createCellEventsController).inSingletonScope();
139128
// Click action helper
140129
this.bind(DG.clickActionHelper).toInstance(createClickActionHelper).inSingletonScope();
141130
}
@@ -201,9 +190,6 @@ export class DatagridContainer extends Container {
201190
// Bind selection counter position
202191
this.bind(DG.selectionCounterCfg).toConstant({ position: props.selectionCounterPosition });
203192

204-
// Bind selection type
205-
this.bind(DG.selectionType).toConstant(config.selectionType);
206-
207193
this.postInit(props, config);
208194

209195
return this;

packages/pluggableWidgets/datagrid-web/src/model/containers/Root.container.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ injected(visibleColumnsCountAtom, CORE.columnsStore);
3232
injected(isAllItemsPresentAtom, CORE.atoms.offset, CORE.atoms.hasMoreItems);
3333
injected(rowsAtom, CORE.mainGate);
3434
injected(pageSizeAtom, CORE.pageSizeStore);
35-
injected(columnCount, CORE.atoms.visibleColumnsCount, CORE.config);
35+
injected(columnCount, CORE.atoms.columnCount, CORE.config);
3636

3737
// selection
3838
injected(

packages/pluggableWidgets/datagrid-web/src/model/hooks/injection-hooks.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,3 @@ export const [useRowClass] = createInjectionHooks(DG.rowClass);
2020
export const [useDatagridRootVM] = createInjectionHooks(DG.datagridRootVM);
2121
export const [useRows] = createInjectionHooks(CORE.rows);
2222
export const [useSelectActions] = createInjectionHooks(DG.selectActions);
23-
export const [useClickActionHelper] = createInjectionHooks(DG.clickActionHelper);
24-
export const [useFocusService] = createInjectionHooks(DG.focusService);
25-
export const [useCheckboxEventsHandler] = createInjectionHooks(DG.checkboxEventsHandler);
26-
export const [useCellEventsHandler] = createInjectionHooks(DG.cellEventsHandler);

packages/pluggableWidgets/datagrid-web/src/model/tokens.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import { CSSProperties, ReactNode } from "react";
2626
import { MainGateProps } from "../../typings/MainGateProps";
2727
import { WidgetRootViewModel } from "../features/base/WidgetRoot.viewModel";
2828
import { EmptyPlaceholderViewModel } from "../features/empty-message/EmptyPlaceholder.viewModel";
29-
import { CellEventsController } from "../features/row-interaction/CellEventsController";
3029
import { CheckboxEventsController } from "../features/row-interaction/CheckboxEventsController";
3130
import { SelectAllBarViewModel } from "../features/select-all/SelectAllBar.viewModel";
3231
import { SelectionProgressDialogViewModel } from "../features/select-all/SelectionProgressDialog.viewModel";
@@ -130,8 +129,7 @@ export const DG_TOKENS = {
130129
virtualLayout: token<ComputedAtom<VirtualGridLayout>>("@computed:virtualLayout"),
131130
clickActionHelper: token<ClickActionHelper>("@service:ClickActionHelper"),
132131
focusService: token<FocusTargetController>("@service:FocusTargetController"),
133-
checkboxEventsHandler: token<CheckboxEventsController>("@service:CheckboxEventsController"),
134-
cellEventsHandler: token<CellEventsController>("@service:CellEventsController")
132+
checkboxEventsHandler: token<CheckboxEventsController>("@service:CheckboxEventsController")
135133
};
136134

137135
/** "Select all" module tokens. */

packages/pluggableWidgets/datagrid-web/src/utils/test-utils.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { dynamic, list, listAttribute, listExpression } from "@mendix/widget-plu
22
import { ColumnsType, DatagridContainerProps } from "../../typings/DatagridProps";
33
import { ColumnStore } from "../helpers/state/column/ColumnStore";
44
import { IColumnParentStore } from "../helpers/state/ColumnGroupStore";
5+
import { SelectActionHelper } from "../model/services/GridSelectActionsProvider.service";
56
import { ColumnId, GridColumn } from "../typings/GridColumn";
67

78
export const column = (header = "Test", patch?: (col: ColumnsType) => void): ColumnsType => {

0 commit comments

Comments
 (0)