import { IModelGenerator , IGrid } from '../base/interface' ; import { AggregateType } from '../base/enum' ; import { Row } from '../models/row' ; import { AggregateColumnModel , AggregateRowModel } from '../models/aggregate-model' ; import { AggregateColumn } from '../models/aggregate' ; import { Column } from '../models/column' ; import { isNullOrUndefined } from '@syncfusion/ej2-base' ; import { calculateAggregate , getUid } from '../base/util' ; import { Group } from '@syncfusion/ej2-data' ; import { CellType } from '../base/enum' ; import { Cell } from '../models/cell' ; hidden export class SummaryModelGenerator implements IModelGenerator < AggregateColumnModel > { protected parent : IGrid ; /**
     * Constructor for Summary row model generator
     */ constructor ( parent ? ) { this . parent = parent ; } public getData ( ) { let rows = [ ] ; this . parent . aggregates . slice ( ) . forEach ( ( row ) => { let columns = row . columns . filter ( ( column ) => { return ! ( column . footerTemplate || column . groupFooterTemplate || column . groupCaptionTemplate ) || this . columnSelector ( column ) ; } ) ; if ( columns . length ) { rows . push ( { columns : columns } ) ; } } ) ; return rows ; } public columnSelector ( column ) { return column . footerTemplate !== undefined ; } public getColumns ( start ? , end ? ) { let columns = [ ] ; if ( this . parent . allowGrouping ) { this . parent . groupSettings . columns . forEach ( ( value ) => columns . push ( new Column ( { } ) ) ) ; } if ( this . parent . detailTemplate || ! isNullOrUndefined ( this . parent . childGrid ) ) { columns . push ( new Column ( { } ) ) ; } columns . push ( ... < Column [ ] > this . parent . getColumns ( ) ) ; return isNullOrUndefined ( start ) ? columns : columns . slice ( start , end ) ; } public generateRows ( input , args ? , start ? , end ? ) { if ( this . parent . currentViewData . length === 0 ) { return [ ] ; } let data = this . buildSummaryData ( input , < SummaryData > args ) ; let rows = [ ] ; ( < AggregateRowModel [ ] > this . getData ( ) ) . forEach ( ( row , index ) => { rows . push ( this . getGeneratedRow ( row , data [ index ] , args ? ( < SummaryData > args ) . level : undefined , start , end ) ) ; } ) ; return rows ; } public getGeneratedRow ( summaryRow , data , raw , start , end ) { let tmp = [ ] ; let indents = this . getIndentByLevel ( raw ) ; let isDetailGridAlone = ! isNullOrUndefined ( this . parent . childGrid ) ; let indentLength = this . parent . groupSettings . columns . length + ( this . parent . detailTemplate || ! isNullOrUndefined ( this . parent . childGrid ) ? 1 : 0 ) ; this . getColumns ( start , end ) . forEach ( ( value , index ) => tmp . push ( this . getGeneratedCell ( value , summaryRow , index >= indentLength ? this . getCellType ( ) : CellType . Indent , indents [ index ] , isDetailGridAlone ) ) ) ; let row = new Row < AggregateColumnModel > ( { data : data , attributes : { class : 'e-summaryrow' } } ) ; row . cells = tmp ; row . uid = getUid ( 'grid-row' ) ; row . visible = tmp . some ( ( cell ) => cell . isDataCell && cell . visible ) ; return row ; } public getGeneratedCell ( column , summaryRow , cellType ? , indent ? , isDetailGridAlone ? ) { let sColumn = summaryRow . columns . filter ( ( scolumn ) => scolumn . columnName === column . field ) [ 0 ] ; let attrs = { 'style' : { 'textAlign' : column . textAlign } } ; if ( indent ) { attrs . class = indent ; } if ( isNullOrUndefined ( indent ) && isDetailGridAlone ) { attrs . class = 'e-detailindentcelltop' ; } let opt = { 'visible' : column . visible , 'isDataCell' : ! isNullOrUndefined ( sColumn ) , 'isTemplate' : sColumn && ! isNullOrUndefined ( sColumn . footerTemplate || sColumn . groupFooterTemplate || sColumn . groupCaptionTemplate ) , 'column' : sColumn || { } , 'attributes' : attrs , 'cellType' : cellType } ; return new Cell < AggregateColumnModel > ( opt ) ; } private buildSummaryData ( data , args ? ) { let dummy = [ ] ; let summaryRows = < AggregateRowModel [ ] > this . getData ( ) ; let single = { } ; let key = '' ; summaryRows . forEach ( ( row ) => { single = { } ; row . columns . forEach ( ( column ) => { single = this . setTemplate ( column , ( args && args . aggregates ) ? < Object [ ] > args : < Object [ ] > data , single ) ; } ) ; dummy . push ( single ) ; } ) ; return dummy ; } protected getIndentByLevel ( data ? ) { return this . parent . groupSettings . columns . map ( ( ) => 'e-indentcelltop' ) ; } protected setTemplate ( column , data , single ) { let types = < AggregateType [ ] > column . type ; let helper = { } ; let formatFn = column . getFormatter ( ) || ( ( ) : Function => ( a ) => a ) ( ) ; let group = ( < Group > data ) ; if ( ! ( types instanceof Array ) ) { types = < AggregateType [ ] > [ column . type ] ; } types . forEach ( ( type ) => { let key = column . field + ' - ' + type . toLowerCase ( ) ; let disp = column . columnName ; let val = type !== 'Custom' && group . aggregates && key in group . aggregates ? group . aggregates [ key ] : calculateAggregate ( type , group . aggregates ? group : < Object [ ] > data , column , this . parent ) ; single [ disp ] = single [ disp ] || { } ; single [ disp ] [ key ] = val ; single [ disp ] [ type ] = ! isNullOrUndefined ( val ) ? formatFn ( val ) : ' ' ; if ( group . field ) { ( < Group > single [ disp ] ) . field = group . field ; ( < Group > single [ disp ] ) . key = group . key ; } } ) ; helper . format = column . getFormatter ( ) ; column . setTemplate ( helper ) ; return single ; } protected getCellType ( ) { return CellType . Summary ; } } export class GroupSummaryModelGenerator extends SummaryModelGenerator implements IModelGenerator < AggregateColumnModel > { public columnSelector ( column ) { return column . groupFooterTemplate !== undefined ; } protected getIndentByLevel ( level = this . parent . groupSettings . columns . length ) { return this . parent . groupSettings . columns . map ( ( v , indx ) => indx <= level - 1 ? '' : 'e-indentcelltop' ) ; } protected getCellType ( ) { return CellType . GroupSummary ; } } export class CaptionSummaryModelGenerator extends SummaryModelGenerator implements IModelGenerator < AggregateColumnModel > { public columnSelector ( column ) { return column . groupCaptionTemplate !== undefined ; } public getData ( ) { let initVal = { columns : [ ] } ; return [ ( < AggregateRowModel [ ] > super . getData ( ) ) . reduce ( ( prev , cur ) => { prev . columns = [ ... prev . columns , ... cur . columns ] ; return prev ; } , initVal ) ] ; } public isEmpty ( ) { return ( ( < AggregateRowModel > this . getData ( ) [ 0 ] ) . columns || [ ] ) . length === 0 ; } protected getCellType ( ) { return CellType . CaptionSummary ; } } interface SummaryData { aggregates ? : Object ; level ? : number ; }