import { isNullOrUndefined } from '@syncfusion/ej2-base' ; import { DataManager , Query , Deferred , Predicate , DataUtil } from '@syncfusion/ej2-data' ; import { IGrid } from '../base/interface' ; import { ServiceLocator } from '../services/service-locator' ; import { Column } from '../models/column' ; import { PredicateModel , SearchSettingsModel } from '../base/grid-model' ; import { ReturnType } from '../base/type' ; import { initForeignKeyColumn , getForeignKeyData , generateQuery } from '../base/constant' ; import { getDatePredicate } from '../base/util' ; import { Data } from './data' ; /**
 * `ForeignKey` module is used to handle foreign key column's actions.
 */ export class ForeignKey extends Data { constructor ( parent , serviceLocator ) { super ( parent , serviceLocator ) ; this . parent = parent ; this . serviceLocator = serviceLocator ; this . initEvent ( ) ; } private initEvent ( ) { if ( this . parent . isDestroyed ) { return ; } this . parent . on ( initForeignKeyColumn , this . initForeignKeyColumns , this ) ; this . parent . on ( getForeignKeyData , this . getForeignKeyData , this ) ; this . parent . on ( generateQuery , this . generateQueryFormData , this ) ; } private initForeignKeyColumns ( columns ) { columns . forEach ( ( column ) => { column . dataSource = ( column . dataSource instanceof DataManager ? < DataManager > column . dataSource : ( isNullOrUndefined ( column . dataSource ) ? new DataManager ( ) : new DataManager ( column . dataSource ) ) ) ; } ) ; } private getForeignKeyData ( args ) { let foreignColumns = args . column ? [ args . column ] : this . parent . getForeignKeyColumns ( ) ; let allPromise = [ ] ; foreignColumns . forEach ( ( col ) => { let promise ; let query = args . isComplex ? this . genarateColumnQuery ( col ) : < Query > this . genarateQuery ( col , < { records ? : Object [ ] ; } > args . result . result , false , true ) ; let dataSource = < DataManager > col . dataSource ; if ( ! dataSource . ready || dataSource . dataSource . offline ) { promise = dataSource . executeQuery ( query ) ; } else { promise = dataSource . ready . then ( ( ) => { return dataSource . executeQuery ( query ) ; } ) ; } allPromise . push ( promise ) ; } ) ; < Promise < Object > > Promise . all ( allPromise ) . then ( ( responses ) => { responses . forEach ( ( data , index ) => { foreignColumns [ index ] . columnData = data . result ; } ) ; args . promise . resolve ( args . result ) ; } ) . catch ( ( e ) => { if ( args . promise && args . promise . reject ) { args . promise . reject ( e ) ; } return e ; } ) ; } private generateQueryFormData ( args ) { args . predicate . predicate = < Predicate > this . genarateQuery ( args . column , < { records ? : Object [ ] ; } > args . column . columnData , true ) ; } private genarateQuery ( column , e ? , fromData ? , needQuery ? ) { let gObj = this . parent ; let predicates = [ ] ; let predicate ; let query = new Query ( ) ; let field = fromData ? column . foreignKeyField : column . field ; if ( gObj . allowPaging || gObj . enableVirtualization || fromData ) { e = < { records ? : Object [ ] ; } > new DataManager ( ( ( gObj . allowGrouping && gObj . groupSettings . columns . length && ! fromData ) ? e . records : e ) as JSON [ ] ) . executeLocal ( new Query ( ) . select ( field ) ) ; let filteredValue = DataUtil . distinct ( < Object [ ] > e , field , false ) ; field = fromData ? column . field : column . foreignKeyField ; filteredValue . forEach ( ( obj ) => { if ( obj && ( < Date > obj ) . getDay ) { predicates . push ( getDatePredicate ( { field : field , operator : 'equal' , value : < string > obj , matchCase : false } ) ) ; } else { predicates . push ( new Predicate ( field , 'equal' , < string > obj , false ) ) ; } } ) ; } if ( needQuery ) { return predicates . length ? query . where ( Predicate . or ( predicates ) ) : query ; } predicate = ( predicates . length ? Predicate . or ( predicates ) : { predicates : [ ] } ) as Predicate ; return predicate ; } private genarateColumnQuery ( column ) { let gObj = this . parent ; let query = new Query ( ) ; let predicate = [ ] ; let queryColumn = this . isFiltered ( column ) ; if ( queryColumn . isTrue ) { query = this . filterQuery ( query , < PredicateModel [ ] > queryColumn . column , true ) ; } if ( gObj . searchSettings . key . length ) { let sSettings = gObj . searchSettings ; query . search ( sSettings . key , column . foreignKeyValue , sSettings . operator , sSettings . ignoreCase ) ; } return query ; } private isFiltered ( column ) { let filterColumn = this . parent . filterSettings . columns . filter ( ( fColumn ) => { return ( fColumn . field === column . foreignKeyValue ) ; } ) ; return { column : filterColumn , isTrue : ! ! filterColumn . length } ; } protected getModuleName ( ) { return 'foreignKey' ; } protected destroy ( ) { this . destroyEvent ( ) ; } private destroyEvent ( ) { if ( this . parent . isDestroyed ) { return ; } this . parent . off ( initForeignKeyColumn , this . initForeignKeyColumns ) ; this . parent . off ( getForeignKeyData , this . getForeignKeyData ) ; this . parent . off ( generateQuery , this . generateQueryFormData ) ; } }