Skip to content

Commit 387fb4b

Browse files
committed
feat: switch to inject hooks
1 parent 90c3e6f commit 387fb4b

File tree

8 files changed

+167
-138
lines changed

8 files changed

+167
-138
lines changed

packages/pluggableWidgets/datagrid-web/src/Datagrid.depsContainer.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import { GridPersonalizationStore } from "./helpers/state/GridPersonalizationSto
2525
import { DatagridSetupService } from "./services/DatagridSetupService";
2626
import { StaticInfo } from "./typings/static-info";
2727

28-
/** Type to declare props available through main gait. */
28+
/** Type to declare props available through main gate. */
2929
type MainGateProps = Pick<
3030
DatagridContainerProps,
3131
| "name"
@@ -45,25 +45,25 @@ type MainGateProps = Pick<
4545
>;
4646

4747
/** Tokens to resolve dependencies from the container. */
48-
const TOKENS = {
48+
export const TOKENS = {
4949
basicDate: token<GridBasicData>("GridBasicData"),
5050
columnsStore: token<ColumnGroupStore>("ColumnGroupStore"),
5151
combinedFilter: token<CombinedFilter>("CombinedFilter"),
5252
combinedFilterConfig: token<CombinedFilterConfig>("CombinedFilterKey"),
5353
exportProgressService: token<ProgressStore>("ExportProgressService"),
5454
filterAPI: token<FilterAPI>("FilterAPI"),
5555
filterHost: token<CustomFilterHost>("FilterHost"),
56-
loaderViewModel: token<DerivedLoaderController>("DatagridLoaderViewModel"),
5756
loaderConfig: token<DerivedLoaderControllerConfig>("DatagridLoaderConfig"),
57+
loaderViewModel: token<DerivedLoaderController>("DatagridLoaderViewModel"),
5858
mainGate: token<DerivedPropsGate<MainGateProps>>("MainGateForProps"),
59-
paginationService: token<PaginationController>("PaginationService"),
6059
paginationConfig: token<PaginationConfig>("PaginationConfig"),
60+
paginationService: token<PaginationController>("PaginationService"),
6161
paramsService: token<DatasourceParamsController>("DatagridParamsService"),
6262
parentChannelName: token<string>("parentChannelName"),
6363
personalizationService: token<GridPersonalizationStore>("GridPersonalizationStore"),
6464
query: token<QueryController>("QueryService"),
65-
refreshService: token<RefreshController>("DatagridRefreshService"),
6665
refreshInterval: token<number>("refreshInterval"),
66+
refreshService: token<RefreshController>("DatagridRefreshService"),
6767
selectionCounter: token<SelectionCountStore>("SelectionCountStore"),
6868
setupService: token<ReactiveControllerHost>("DatagridSetupHost"),
6969
staticInfo: token<StaticInfo>("StaticInfo")
@@ -78,23 +78,25 @@ rootContainer.bind(TOKENS.combinedFilter).toInstance(CombinedFilter).inContainer
7878
rootContainer.bind(TOKENS.exportProgressService).toInstance(ProgressStore).inContainerScope();
7979
rootContainer.bind(TOKENS.filterAPI).toInstance(WidgetFilterAPI).inContainerScope();
8080
rootContainer.bind(TOKENS.filterHost).toInstance(CustomFilterHost).inContainerScope();
81+
rootContainer.bind(TOKENS.paramsService).toInstance(DatasourceParamsController).inContainerScope();
82+
rootContainer.bind(TOKENS.personalizationService).toInstance(GridPersonalizationStore).inContainerScope();
8183
rootContainer.bind(TOKENS.query).toInstance(DatasourceController).inContainerScope();
8284
rootContainer.bind(TOKENS.refreshService).toInstance(RefreshController).inContainerScope();
8385
rootContainer.bind(TOKENS.setupService).toInstance(DatagridSetupService).inContainerScope();
84-
rootContainer.bind(TOKENS.paramsService).toInstance(DatasourceParamsController).inContainerScope();
8586
rootContainer
8687
.bind(TOKENS.parentChannelName)
8788
.toInstance(() => `datagrid/${generateUUID()}`)
8889
.inContainerScope();
8990

9091
// Inject dependencies
91-
injected(SelectionCountStore, TOKENS.mainGate);
92-
injected(DatasourceController, TOKENS.setupService, TOKENS.mainGate);
93-
injected(WidgetFilterAPI, TOKENS.parentChannelName, TOKENS.filterHost);
9492
injected(ColumnGroupStore, TOKENS.mainGate, TOKENS.staticInfo, TOKENS.filterHost);
93+
injected(DatasourceController, TOKENS.setupService, TOKENS.mainGate);
94+
injected(DatasourceParamsController, TOKENS.setupService, TOKENS.query, TOKENS.combinedFilter, TOKENS.columnsStore);
9595
injected(DerivedLoaderController, TOKENS.query, TOKENS.exportProgressService, TOKENS.columnsStore, TOKENS.loaderConfig);
96+
injected(GridPersonalizationStore, TOKENS.setupService, TOKENS.mainGate, TOKENS.columnsStore, TOKENS.filterHost);
9697
injected(RefreshController, TOKENS.setupService, TOKENS.query, TOKENS.refreshInterval.optional);
97-
injected(DatasourceParamsController, TOKENS.setupService, TOKENS.query, TOKENS.combinedFilter, TOKENS.columnsStore);
98+
injected(SelectionCountStore, TOKENS.mainGate);
99+
injected(WidgetFilterAPI, TOKENS.parentChannelName, TOKENS.filterHost);
98100

99101
/** Create new container that inherit bindings from root container. */
100102
export function createContainer(): Container {
Lines changed: 84 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,37 @@
11
import { useClickActionHelper } from "@mendix/widget-plugin-grid/helpers/ClickActionHelper";
22
import { useFocusTargetController } from "@mendix/widget-plugin-grid/keyboard-navigation/useFocusTargetController";
33
import { useSelectionHelper } from "@mendix/widget-plugin-grid/selection";
4-
import { useConst } from "@mendix/widget-plugin-mobx-kit/react/useConst";
54
import { generateUUID } from "@mendix/widget-plugin-platform/framework/generate-uuid";
5+
import { ContainerProvider } from "brandi-react";
66
import { observer } from "mobx-react-lite";
77
import { ReactElement, ReactNode, useCallback, useMemo } from "react";
88
import { DatagridContainerProps } from "../typings/DatagridProps";
99
import { Cell } from "./components/Cell";
1010
import { Widget } from "./components/Widget";
1111
import { WidgetHeaderContext } from "./components/WidgetHeaderContext";
12-
import { ProgressStore } from "./features/data-export/ProgressStore";
12+
import { useDatagridDepsContainer } from "./Datagrid.depsContainer";
13+
import {
14+
useColumnsStore,
15+
useExportProgressService,
16+
useLoaderViewModel,
17+
useMainGate,
18+
usePaginationService
19+
} from "./deps-hooks";
1320
import { useDataExport } from "./features/data-export/useDataExport";
1421
import { useCellEventsController } from "./features/row-interaction/CellEventsController";
1522
import { useCheckboxEventsController } from "./features/row-interaction/CheckboxEventsController";
16-
import { DatagridContext } from "./helpers/root-context";
1723
import { useSelectActionHelper } from "./helpers/SelectActionHelper";
18-
import { IColumnGroupStore } from "./helpers/state/ColumnGroupStore";
19-
import { RootGridStore } from "./helpers/state/RootGridStore";
20-
import { useRootStore } from "./helpers/state/useRootStore";
2124
import { useDataGridJSActions } from "./helpers/useDataGridJSActions";
2225

23-
interface Props extends DatagridContainerProps {
24-
columnsStore: IColumnGroupStore;
25-
rootStore: RootGridStore;
26-
progressStore: ProgressStore;
27-
}
28-
29-
const Container = observer((props: Props): ReactElement => {
30-
const { columnsStore, rootStore } = props;
31-
const { paginationCtrl } = rootStore;
26+
const DatagridRoot = observer((props: DatagridContainerProps): ReactElement => {
27+
const gate = useMainGate();
28+
const columnsStore = useColumnsStore();
29+
const paginationService = usePaginationService();
30+
const exportProgress = useExportProgressService();
31+
const loaderVM = useLoaderViewModel();
32+
const items = gate.props.datasource.items ?? [];
3233

33-
const items = props.datasource.items ?? [];
34-
35-
const [exportProgress, abortExport] = useDataExport(props, props.columnsStore, props.progressStore);
34+
const [, abortExport] = useDataExport(props, columnsStore, exportProgress);
3635

3736
const selectionHelper = useSelectionHelper(
3837
props.itemSelection,
@@ -48,7 +47,7 @@ const Container = observer((props: Props): ReactElement => {
4847
onClick: props.onClick
4948
});
5049

51-
useDataGridJSActions(rootStore, selectActionHelper);
50+
useDataGridJSActions(selectActionHelper);
5251

5352
const visibleColumnsCount = selectActionHelper.showCheckboxColumn
5453
? columnsStore.visibleColumns.length + 1
@@ -64,97 +63,79 @@ const Container = observer((props: Props): ReactElement => {
6463

6564
const checkboxEventsController = useCheckboxEventsController(selectActionHelper, focusController);
6665

67-
const ctx = useConst(() => {
68-
rootStore.basicData.setSelectionHelper(selectionHelper);
69-
return {
70-
basicData: rootStore.basicData,
71-
selectionHelper,
72-
selectActionHelper,
73-
cellEventsController,
74-
checkboxEventsController,
75-
focusController,
76-
selectionCountStore: rootStore.selectionCountStore
77-
};
78-
});
79-
8066
return (
81-
<DatagridContext.Provider value={ctx}>
82-
<Widget
83-
className={props.class}
84-
CellComponent={Cell}
85-
columnsDraggable={props.columnsDraggable}
86-
columnsFilterable={props.columnsFilterable}
87-
columnsHidable={props.columnsHidable}
88-
columnsResizable={props.columnsResizable}
89-
columnsSortable={props.columnsSortable}
90-
data={items}
91-
emptyPlaceholderRenderer={useCallback(
92-
(renderWrapper: (children: ReactNode) => ReactElement) =>
93-
props.showEmptyPlaceholder === "custom" ? renderWrapper(props.emptyPlaceholder) : <div />,
94-
[props.emptyPlaceholder, props.showEmptyPlaceholder]
95-
)}
96-
filterRenderer={useCallback(
97-
(renderWrapper, columnIndex) => {
98-
const columnFilter = columnsStore.columnFilters[columnIndex];
99-
return renderWrapper(columnFilter.renderFilterWidgets());
100-
},
101-
[columnsStore.columnFilters]
102-
)}
103-
headerTitle={props.filterSectionTitle?.value}
104-
headerContent={
105-
props.filtersPlaceholder && (
106-
<WidgetHeaderContext selectionHelper={selectionHelper} rootStore={rootStore}>
107-
{props.filtersPlaceholder}
108-
</WidgetHeaderContext>
109-
)
110-
}
111-
hasMoreItems={props.datasource.hasMoreItems ?? false}
112-
headerWrapperRenderer={useCallback((_columnIndex: number, header: ReactElement) => header, [])}
113-
id={useMemo(() => `DataGrid${generateUUID()}`, [])}
114-
numberOfItems={props.datasource.totalCount}
115-
onExportCancel={abortExport}
116-
page={paginationCtrl.currentPage}
117-
pageSize={props.pageSize}
118-
paginationType={props.pagination}
119-
loadMoreButtonCaption={props.loadMoreButtonCaption?.value}
120-
selectionCountPosition={props.selectionCountPosition}
121-
paging={paginationCtrl.showPagination}
122-
pagingPosition={props.pagingPosition}
123-
showPagingButtons={props.showPagingButtons}
124-
rowClass={useCallback((value: any) => props.rowClass?.get(value)?.value ?? "", [props.rowClass])}
125-
setPage={paginationCtrl.setPage}
126-
styles={props.style}
127-
exporting={exportProgress.exporting}
128-
processedRows={exportProgress.loaded}
129-
visibleColumns={columnsStore.visibleColumns}
130-
availableColumns={columnsStore.availableColumns}
131-
setIsResizing={(status: boolean) => columnsStore.setIsResizing(status)}
132-
columnsSwap={(moved, [target, placement]) => columnsStore.swapColumns(moved, [target, placement])}
133-
selectActionHelper={selectActionHelper}
134-
cellEventsController={cellEventsController}
135-
checkboxEventsController={checkboxEventsController}
136-
focusController={focusController}
137-
isFirstLoad={rootStore.loaderCtrl.isFirstLoad}
138-
isFetchingNextBatch={rootStore.loaderCtrl.isFetchingNextBatch}
139-
showRefreshIndicator={rootStore.loaderCtrl.showRefreshIndicator}
140-
loadingType={props.loadingType}
141-
columnsLoading={!columnsStore.loaded}
142-
/>
143-
</DatagridContext.Provider>
67+
<Widget
68+
className={props.class}
69+
CellComponent={Cell}
70+
columnsDraggable={props.columnsDraggable}
71+
columnsFilterable={props.columnsFilterable}
72+
columnsHidable={props.columnsHidable}
73+
columnsResizable={props.columnsResizable}
74+
columnsSortable={props.columnsSortable}
75+
data={items}
76+
emptyPlaceholderRenderer={useCallback(
77+
(renderWrapper: (children: ReactNode) => ReactElement) =>
78+
props.showEmptyPlaceholder === "custom" ? renderWrapper(props.emptyPlaceholder) : <div />,
79+
[props.emptyPlaceholder, props.showEmptyPlaceholder]
80+
)}
81+
filterRenderer={useCallback(
82+
(renderWrapper, columnIndex) => {
83+
const columnFilter = columnsStore.columnFilters[columnIndex];
84+
return renderWrapper(columnFilter.renderFilterWidgets());
85+
},
86+
[columnsStore.columnFilters]
87+
)}
88+
headerTitle={props.filterSectionTitle?.value}
89+
headerContent={
90+
props.filtersPlaceholder && (
91+
<WidgetHeaderContext selectionHelper={selectionHelper}>
92+
{props.filtersPlaceholder}
93+
</WidgetHeaderContext>
94+
)
95+
}
96+
hasMoreItems={props.datasource.hasMoreItems ?? false}
97+
headerWrapperRenderer={useCallback((_columnIndex: number, header: ReactElement) => header, [])}
98+
id={useMemo(() => `DataGrid${generateUUID()}`, [])}
99+
numberOfItems={props.datasource.totalCount}
100+
onExportCancel={abortExport}
101+
page={paginationService.currentPage}
102+
pageSize={props.pageSize}
103+
paginationType={props.pagination}
104+
loadMoreButtonCaption={props.loadMoreButtonCaption?.value}
105+
selectionCountPosition={props.selectionCountPosition}
106+
paging={paginationService.showPagination}
107+
pagingPosition={props.pagingPosition}
108+
showPagingButtons={props.showPagingButtons}
109+
rowClass={useCallback((value: any) => props.rowClass?.get(value)?.value ?? "", [props.rowClass])}
110+
setPage={paginationService.setPage}
111+
styles={props.style}
112+
exporting={exportProgress.exporting}
113+
processedRows={exportProgress.loaded}
114+
visibleColumns={columnsStore.visibleColumns}
115+
availableColumns={columnsStore.availableColumns}
116+
setIsResizing={(status: boolean) => columnsStore.setIsResizing(status)}
117+
columnsSwap={(moved, [target, placement]) => columnsStore.swapColumns(moved, [target, placement])}
118+
selectActionHelper={selectActionHelper}
119+
cellEventsController={cellEventsController}
120+
checkboxEventsController={checkboxEventsController}
121+
focusController={focusController}
122+
isFirstLoad={loaderVM.isFirstLoad}
123+
isFetchingNextBatch={loaderVM.isFetchingNextBatch}
124+
showRefreshIndicator={loaderVM.showRefreshIndicator}
125+
loadingType={props.loadingType}
126+
columnsLoading={!columnsStore.loaded}
127+
/>
144128
);
145129
});
146130

147-
Container.displayName = "DatagridComponent";
131+
DatagridRoot.displayName = "DatagridComponent";
148132

149133
export default function Datagrid(props: DatagridContainerProps): ReactElement | null {
150-
const rootStore = useRootStore(props);
134+
const container = useDatagridDepsContainer(props);
151135

152136
return (
153-
<Container
154-
{...props}
155-
rootStore={rootStore}
156-
columnsStore={rootStore.columnsStore}
157-
progressStore={rootStore.exportProgressCtrl}
158-
/>
137+
<ContainerProvider container={container}>
138+
<DatagridRoot {...props} />
139+
</ContainerProvider>
159140
);
160141
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,21 @@ import {
55
useCreateSelectionContextValue
66
} from "@mendix/widget-plugin-grid/selection";
77
import { memo, ReactElement, ReactNode } from "react";
8-
import { RootGridStore } from "../helpers/state/RootGridStore";
8+
import { useDatagridFilterAPI } from "../deps-hooks";
99

1010
interface WidgetHeaderContextProps {
1111
children?: ReactNode;
1212
selectionHelper?: SelectionHelper;
13-
rootStore: RootGridStore;
1413
}
1514

1615
const SelectionContext = getGlobalSelectionContext();
1716
const FilterContext = getGlobalFilterContextObject();
1817

1918
function HeaderContainer(props: WidgetHeaderContextProps): ReactElement {
19+
const filterAPI = useDatagridFilterAPI();
2020
const selectionContext = useCreateSelectionContextValue(props.selectionHelper);
2121
return (
22-
<FilterContext.Provider value={props.rootStore.filterAPI}>
22+
<FilterContext.Provider value={filterAPI}>
2323
<SelectionContext.Provider value={selectionContext}>{props.children}</SelectionContext.Provider>
2424
</FilterContext.Provider>
2525
);
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { createInjectionHooks } from "brandi-react";
2+
import { TOKENS } from "./Datagrid.depsContainer";
3+
4+
const [
5+
useBasicData,
6+
usePaginationService,
7+
useSelectionCounter,
8+
useLoaderViewModel,
9+
useColumnsStore,
10+
useExportProgressService,
11+
useMainGate,
12+
useStaticInfo,
13+
useDatagridFilterAPI
14+
] = createInjectionHooks(
15+
TOKENS.basicDate,
16+
TOKENS.paginationService,
17+
TOKENS.selectionCounter,
18+
TOKENS.loaderViewModel,
19+
TOKENS.columnsStore,
20+
TOKENS.exportProgressService,
21+
TOKENS.mainGate,
22+
TOKENS.staticInfo,
23+
TOKENS.filterAPI
24+
);
25+
26+
export {
27+
useBasicData,
28+
useColumnsStore,
29+
useDatagridFilterAPI,
30+
useExportProgressService,
31+
useLoaderViewModel,
32+
useMainGate,
33+
usePaginationService,
34+
useSelectionCounter,
35+
useStaticInfo
36+
};

packages/pluggableWidgets/datagrid-web/src/features/data-export/useDataExport.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
import { useCallback, useEffect, useState } from "react";
2+
import { DatagridContainerProps } from "../../../typings/DatagridProps";
3+
import { IColumnGroupStore } from "../../helpers/state/ColumnGroupStore";
24
import { ExportController } from "./ExportController";
35
import { ProgressStore } from "./ProgressStore";
46
import { getExportRegistry } from "./registry";
5-
import { DatagridContainerProps } from "../../../typings/DatagridProps";
6-
import { IColumnGroupStore } from "../../helpers/state/ColumnGroupStore";
77

88
type ResourceEntry = {
99
key: string;
1010
controller: ExportController;
1111
};
1212

13+
type Props = Pick<DatagridContainerProps, "name" | "datasource" | "columns">;
14+
1315
export function useDataExport(
14-
props: DatagridContainerProps,
16+
props: Props,
1517
columnsStore: IColumnGroupStore,
1618
progress: ProgressStore
1719
): [store: ProgressStore, abort: () => void] {

0 commit comments

Comments
 (0)