@@ -27,6 +27,8 @@ import { GridBasicData } from "./helpers/state/GridBasicData";
2727import { GridPersonalizationStore } from "./helpers/state/GridPersonalizationStore" ;
2828import { DatagridSetupService } from "./services/DatagridSetupService" ;
2929import { StaticInfo } from "./typings/static-info" ;
30+ import { SelectAllBarViewModel } from "./view-models/SelectAllBarViewModel" ;
31+ import { SelectionProgressDialogViewModel } from "./view-models/SelectionProgressDialogViewModel" ;
3032
3133/** Type to declare props available through main gate. */
3234type MainGateProps = Pick <
@@ -45,6 +47,15 @@ type MainGateProps = Pick<
4547 | "showPagingButtons"
4648 | "showNumberOfRows"
4749 | "clearSelectionButtonLabel"
50+ | "selectAllTemplate"
51+ | "selectAllText"
52+ | "itemSelection"
53+ | "datasource"
54+ | "allSelectedText"
55+ | "selectAllRowsLabel"
56+ | "cancelSelectionLabel"
57+ | "selectionCounterPosition"
58+ | "enableSelectAll"
4859> ;
4960
5061/** Tokens to resolve dependencies from the container. */
@@ -65,15 +76,18 @@ export const TOKENS = {
6576 parentChannelName : token < string > ( "parentChannelName" ) ,
6677 personalizationService : token < GridPersonalizationStore > ( "GridPersonalizationStore" ) ,
6778 query : token < QueryService > ( "QueryService" ) ,
79+ queryGate : token < DerivedPropsGate < Pick < DatagridContainerProps , "datasource" > > > ( "GateForQuery" ) ,
6880 refreshInterval : token < number > ( "refreshInterval" ) ,
6981 selectionCounter : token < SelectionCounterViewModel > ( "SelectionCounterViewModel" ) ,
7082 selectionCounterPosition : token < SelectionCounterPositionEnum > ( "SelectionCounterPositionEnum" ) ,
7183 setupService : token < SetupComponentHost > ( "DatagridSetupHost" ) ,
7284 staticInfo : token < StaticInfo > ( "StaticInfo" ) ,
85+ enableSelectAll : token < boolean > ( "enableSelectAll" ) ,
7386 selectAllProgressService : token < TaskProgressService > ( "SelectAllProgressService" ) ,
7487 selectAllGate : token < DerivedPropsGate < SelectAllGateProps > > ( "SelectAllGateForProps" ) ,
75- selectAllQuery : token < QueryService > ( "SelectAllQueryService" ) ,
76- SelectAllService : token < SelectAllService > ( "SelectAllService" )
88+ selectAllService : token < SelectAllService > ( "SelectAllService" ) ,
89+ selectAllBar : token < SelectAllBarViewModel > ( "SelectAllBarViewModel" ) ,
90+ selectionDialogViewModel : token < SelectionProgressDialogViewModel > ( "SelectionProgressDialogViewModel" )
7791} ;
7892
7993/** Deps injections */
@@ -84,22 +98,64 @@ injected(WidgetFilterAPI, TOKENS.parentChannelName, TOKENS.filterHost);
8498injected ( DatasourceParamsController , TOKENS . setupService , TOKENS . query , TOKENS . combinedFilter , TOKENS . columnsStore ) ;
8599injected ( GridPersonalizationStore , TOKENS . setupService , TOKENS . mainGate , TOKENS . columnsStore , TOKENS . filterHost ) ;
86100injected ( PaginationController , TOKENS . setupService , TOKENS . paginationConfig , TOKENS . query ) ;
87- injected ( DatasourceService , TOKENS . setupService , TOKENS . mainGate , TOKENS . refreshInterval . optional ) ;
101+ injected ( DatasourceService , TOKENS . setupService , TOKENS . queryGate , TOKENS . refreshInterval . optional ) ;
88102injected ( DerivedLoaderController , TOKENS . query , TOKENS . exportProgressService , TOKENS . columnsStore , TOKENS . loaderConfig ) ;
89103injected ( SelectionCounterViewModel , TOKENS . mainGate , TOKENS . selectionCounterPosition ) ;
104+ injected ( SelectAllService , TOKENS . setupService , TOKENS . selectAllGate , TOKENS . query , TOKENS . selectAllProgressService ) ;
90105injected (
91- SelectAllService ,
106+ SelectAllBarViewModel ,
92107 TOKENS . setupService ,
93- TOKENS . selectAllGate ,
94- TOKENS . selectAllQuery ,
95- TOKENS . selectAllProgressService
108+ TOKENS . mainGate ,
109+ TOKENS . selectAllService ,
110+ TOKENS . selectionCounter ,
111+ TOKENS . enableSelectAll
112+ ) ;
113+ injected (
114+ SelectionProgressDialogViewModel ,
115+ TOKENS . setupService ,
116+ TOKENS . mainGate ,
117+ TOKENS . selectAllProgressService ,
118+ TOKENS . selectAllService
96119) ;
97120
98- class DatagridContainer extends Container {
121+ /**
122+ * Root container for bindings that can be shared down the hierarchy.
123+ * Use only for bindings that needs to be shared across multiple containers.
124+ * @remark Don't bind things that depend on props here.
125+ */
126+ class RootContainer extends Container {
127+ id = `DatagridRootContainer@${ generateUUID ( ) } ` ;
128+
99129 constructor ( ) {
100130 super ( ) ;
131+ this . bind ( TOKENS . setupService ) . toInstance ( DatagridSetupService ) . inSingletonScope ( ) ;
132+ this . bind ( TOKENS . exportProgressService ) . toInstance ( ProgressService ) . inSingletonScope ( ) ;
133+ this . bind ( TOKENS . selectAllProgressService ) . toInstance ( ProgressService ) . inSingletonScope ( ) ;
134+ }
135+ }
101136
102- // Column store
137+ class DatagridContainer extends Container {
138+ id = `DatagridContainer@${ generateUUID ( ) } ` ;
139+ /**
140+ * Setup container bindings.
141+ * @remark Make sure not to bind things that already exist in root container.
142+ */
143+ init ( props : MainGateProps , root : RootContainer , selectAllModule : DependencyModule ) : DatagridContainer {
144+ this . extend ( root ) ;
145+
146+ const exportProgress = this . get ( TOKENS . exportProgressService ) ;
147+ const selectAllProgress = this . get ( TOKENS . selectAllProgressService ) ;
148+ const gateProvider = new ClosableGateProvider < MainGateProps > ( props , function isLocked ( ) {
149+ return exportProgress . inProgress || selectAllProgress . inProgress ;
150+ } ) ;
151+
152+ this . setProps = props => gateProvider . setProps ( props ) ;
153+
154+ // Bind main gate
155+ this . bind ( TOKENS . mainGate ) . toConstant ( gateProvider . gate ) ;
156+ this . bind ( TOKENS . queryGate ) . toConstant ( gateProvider . gate ) ;
157+
158+ // Columns store
103159 this . bind ( TOKENS . columnsStore ) . toInstance ( ColumnGroupStore ) . inSingletonScope ( ) ;
104160
105161 // Basic data store
@@ -111,9 +167,6 @@ class DatagridContainer extends Container {
111167 // Export progress
112168 this . bind ( TOKENS . exportProgressService ) . toInstance ( ProgressService ) . inSingletonScope ( ) ;
113169
114- // Select all progress
115- this . bind ( TOKENS . selectAllProgressService ) . toInstance ( ProgressService ) . inSingletonScope ( ) ;
116-
117170 // FilterAPI
118171 this . bind ( TOKENS . filterAPI ) . toInstance ( WidgetFilterAPI ) . inSingletonScope ( ) ;
119172
@@ -145,84 +198,100 @@ class DatagridContainer extends Container {
145198
146199 // Selection counter view model
147200 this . bind ( TOKENS . selectionCounter ) . toInstance ( SelectionCounterViewModel ) . inSingletonScope ( ) ;
201+
202+ // Select all bar view model
203+ this . bind ( TOKENS . selectAllBar ) . toInstance ( SelectAllBarViewModel ) . inSingletonScope ( ) ;
204+
205+ // Selection progress dialog view model
206+ this . bind ( TOKENS . selectionDialogViewModel ) . toInstance ( SelectionProgressDialogViewModel ) . inSingletonScope ( ) ;
207+
208+ // Bind static info
209+ this . bind ( TOKENS . staticInfo ) . toConstant ( {
210+ name : props . name ,
211+ filtersChannelName : this . get ( TOKENS . parentChannelName )
212+ } ) ;
213+
214+ // Bind refresh interval
215+ this . bind ( TOKENS . refreshInterval ) . toConstant ( props . refreshInterval * 1000 ) ;
216+
217+ // Bind combined filter config
218+ this . bind ( TOKENS . combinedFilterConfig ) . toConstant ( {
219+ stableKey : props . name ,
220+ inputs : [ this . get ( TOKENS . filterHost ) , this . get ( TOKENS . columnsStore ) ]
221+ } ) ;
222+
223+ // Bind loader config
224+ this . bind ( TOKENS . loaderConfig ) . toConstant ( {
225+ showSilentRefresh : props . refreshInterval > 1 ,
226+ refreshIndicator : props . refreshIndicator
227+ } ) ;
228+
229+ // Bind pagination config
230+ this . bind ( TOKENS . paginationConfig ) . toConstant ( {
231+ pagination : props . pagination ,
232+ showPagingButtons : props . showPagingButtons ,
233+ showNumberOfRows : props . showNumberOfRows ,
234+ pageSize : props . pageSize
235+ } ) ;
236+
237+ // Bind selection counter position
238+ this . bind ( TOKENS . selectionCounterPosition ) . toConstant ( props . selectionCounterPosition ) ;
239+
240+ // Bind select all enabled flag
241+ this . bind ( TOKENS . enableSelectAll ) . toConstant ( props . enableSelectAll ) ;
242+
243+ // Make sure essential services are created upfront
244+ this . get ( TOKENS . paramsService ) ;
245+ this . get ( TOKENS . paginationService ) ;
246+
247+ // Hydrate filters from props
248+ this . get ( TOKENS . combinedFilter ) . hydrate ( props . datasource . filter ) ;
249+
250+ // Bind select all service
251+ this . use ( TOKENS . selectAllService ) . from ( selectAllModule ) ;
252+
253+ return this ;
148254 }
255+
256+ setProps = ( _props : MainGateProps ) : void => {
257+ throw new Error ( `${ this . id } is not initialized yet` ) ;
258+ } ;
149259}
150260
151261type SelectAllGateProps = Pick < DatagridContainerProps , "itemSelection" | "datasource" > ;
262+
263+ /** Module used to bind independent query and gate for select all service */
152264class SelectAllModule extends DependencyModule {
153- selectAllGateProvider : GateProvider < SelectAllGateProps > ;
154- constructor ( props : SelectAllGateProps ) {
155- super ( ) ;
156- this . selectAllGateProvider = new GateProvider < SelectAllGateProps > ( props ) ;
157- // Bind gate
158- this . bind ( TOKENS . selectAllGate ) . toConstant ( this . selectAllGateProvider . gate ) ;
159- // Bind query
160- this . bind ( TOKENS . selectAllQuery ) . toInstance ( DatasourceService ) . inSingletonScope ( ) ;
161- // Bind progress
162- this . bind ( TOKENS . selectAllProgressService ) . toInstance ( ProgressService ) . inSingletonScope ( ) ;
163- // Bind service
164- this . bind ( TOKENS . SelectAllService ) . toInstance ( SelectAllService ) . inSingletonScope ( ) ;
265+ id = `SelectAllModule@${ generateUUID ( ) } ` ;
266+ /** Method for bindings that depend on props. */
267+ init ( props : SelectAllGateProps , root : RootContainer ) : SelectAllModule {
268+ const setupService = root . get ( TOKENS . setupService ) ;
269+ const progress = root . get ( TOKENS . selectAllProgressService ) ;
270+ const gateProvider = new GateProvider < SelectAllGateProps > ( props ) ;
271+ const query = new DatasourceService ( setupService , gateProvider . gate ) ;
272+ const selectService = new SelectAllService ( setupService , gateProvider . gate , query , progress ) ;
273+
274+ this . setProps = props => gateProvider . setProps ( props ) ;
275+ // Finally bind select all service
276+ this . bind ( TOKENS . selectAllService ) . toConstant ( selectService ) ;
277+
278+ return this ;
165279 }
280+
281+ setProps = ( _props : SelectAllGateProps ) : void => {
282+ throw new Error ( `${ this . id } is not initialized yet` ) ;
283+ } ;
166284}
167285
168286export function useDatagridDepsContainer ( props : DatagridContainerProps ) : Container {
169- const [ container , mainGateHost , selectAllGateHost ] = useConst (
170- /** Function to clone container and setup prop dependant bindings. */
171- function init ( ) : [ Container , GateProvider < MainGateProps > , GateProvider < SelectAllGateProps > ] {
172- const container = new DatagridContainer ( ) ;
173- const selectAllModule = new SelectAllModule ( props ) ;
174-
175- container . use ( TOKENS . selectAllProgressService ) . from ( selectAllModule ) ;
176- container . use ( TOKENS . SelectAllService ) . from ( selectAllModule ) ;
177-
178- const exportProgress = container . get ( TOKENS . exportProgressService ) ;
179- const selectAllProgress = container . get ( TOKENS . selectAllProgressService ) ;
180- const gateProvider = new ClosableGateProvider < MainGateProps > ( props , function isLocked ( ) {
181- return exportProgress . inProgress || selectAllProgress . inProgress ;
182- } ) ;
183-
184- // Bind main gate
185- container . bind ( TOKENS . mainGate ) . toConstant ( gateProvider . gate ) ;
186-
187- // Bind static info
188- container . bind ( TOKENS . staticInfo ) . toConstant ( {
189- name : props . name ,
190- filtersChannelName : container . get ( TOKENS . parentChannelName )
191- } ) ;
192-
193- container . bind ( TOKENS . refreshInterval ) . toConstant ( props . refreshInterval * 1000 ) ;
194-
195- // Bind combined filter config
196- container . bind ( TOKENS . combinedFilterConfig ) . toConstant ( {
197- stableKey : props . name ,
198- inputs : [ container . get ( TOKENS . filterHost ) , container . get ( TOKENS . columnsStore ) ]
199- } ) ;
200-
201- // Bind loader config
202- container . bind ( TOKENS . loaderConfig ) . toConstant ( {
203- showSilentRefresh : props . refreshInterval > 1 ,
204- refreshIndicator : props . refreshIndicator
205- } ) ;
206-
207- // Bind pagination config
208- container . bind ( TOKENS . paginationConfig ) . toConstant ( {
209- pagination : props . pagination ,
210- showPagingButtons : props . showPagingButtons ,
211- showNumberOfRows : props . showNumberOfRows ,
212- pageSize : props . pageSize
213- } ) ;
214-
215- // Bind selection counter position
216- container . bind ( TOKENS . selectionCounterPosition ) . toConstant ( props . selectionCounterPosition ) ;
217-
218- // Make sure essential services are created upfront
219- container . get ( TOKENS . paramsService ) ;
220- container . get ( TOKENS . paginationService ) ;
221-
222- // Hydrate filters from props
223- container . get ( TOKENS . combinedFilter ) . hydrate ( props . datasource . filter ) ;
224-
225- return [ container , gateProvider , selectAllModule . selectAllGateProvider ] ;
287+ const [ container , selectAllModule ] = useConst (
288+ /** Function to create main container and setup prop dependant bindings. */
289+ function init ( ) : [ DatagridContainer , SelectAllModule ] {
290+ const root = new RootContainer ( ) ;
291+ const selectAllModule = new SelectAllModule ( ) . init ( props , root ) ;
292+ const container = new DatagridContainer ( ) . init ( props , root , selectAllModule ) ;
293+
294+ return [ container , selectAllModule ] ;
226295 }
227296 ) ;
228297
@@ -231,8 +300,8 @@ export function useDatagridDepsContainer(props: DatagridContainerProps): Contain
231300
232301 // Push props through the gates
233302 useEffect ( ( ) => {
234- mainGateHost . setProps ( props ) ;
235- selectAllGateHost . setProps ( props ) ;
303+ container . setProps ( props ) ;
304+ selectAllModule . setProps ( props ) ;
236305 } ) ;
237306
238307 return container ;
0 commit comments