src/lib/components/gridview/gridview.component.ts
Angular Component for the GridView Control.
@ class GridViewComponent
GridComponent
changeDetection | ChangeDetectionStrategy.OnPush |
providers |
InternalEventHandlerService
|
selector | wm-gridview |
styleUrls | ./gridview.component.scss |
templateUrl | ./gridview.component.html |
constructor(wmService: WebMapService, refChange: ChangeDetectorRef, render2: Renderer2, elem: ElementRef, formBuilderRef: UntypedFormBuilder, internalEventHandler: InternalEventHandlerService, webComponents: WebComponentsService, bringTopServ1: BringTopService)
|
|||||||||||||||||||||||||||
Creates an instance of GridViewComponent.
Parameters :
|
allowPaging | |
Type : boolean
|
|
Gets/sets the allowPaging. |
allowSorting | |
Type : boolean
|
|
Gets/sets the allowSorting. |
autoFitGridView | |
Type : boolean
|
|
Gets/sets the autofit GridView. |
autoGenerateColumns | |
Type : boolean
|
|
Gets/sets the autoGenerateColumns property. |
autoGenerateSelectButton | |
Type : boolean
|
|
Gets/sets the autoGenerateSelectButton. |
gridLines | |
Type : GridLines
|
|
GridLines property from model or input if exists |
hideHeader | |
Type : boolean
|
|
Gets/sets the hideHeader GridView property. |
pageIndex | |
Type : number
|
|
Gets/sets the pageIndex. |
pageSize | |
Type : number
|
|
Gets/sets the pageSize. |
selectedIndex | |
Type : number
|
|
Gets/sets the selectedIndex. |
DoubleClick | |
Type : EventEmitter<EventData>
|
|
Emitter for double click row event |
OnRowCommand | |
Type : EventEmitter<literal type>
|
|
Emitter for the onRowCommand Event. |
PageIndexChanging | |
Type : EventEmitter<EventData>
|
|
Emitter for the page index changing event |
SelectedRowChange | |
Type : EventEmitter<EventData>
|
|
Emitter for the selected row changing event |
Sorting | |
Type : EventEmitter<EventData>
|
|
Emiter for the sorting event. |
applyCommonStyles |
applyCommonStyles(element: any, cellModel: any)
|
Apply common styles to cells
Returns :
void
|
applyHeaderStylesFromModel |
applyHeaderStylesFromModel()
|
Method to apply the HeaderStyles from the model property and return the style object
Returns :
any
The style object |
applyStylesHyperLinkCell |
applyStylesHyperLinkCell(element: any, cellModel: any)
|
Apply styles to cells with colum type hyperlink
Returns :
void
|
areItemTemplateModelsLoaded | ||||||
areItemTemplateModelsLoaded(columnIndex: number)
|
||||||
Verifies if the itemTemplate models for a specific TemplateField are loaded.
Parameters :
Returns :
boolean
{boolean} |
cellClickHandler | ||||||
cellClickHandler(event: any)
|
||||||
Handler for the cell click.
Parameters :
Returns :
void
|
doubleClick | ||||||
doubleClick(event: any)
|
||||||
Handler for double cell click.
Parameters :
Returns :
void
|
fitColumns |
fitColumns()
|
Adjust width columns for setup as autofit columns with width value NaN and recalculate width grid based in new autofit
Returns :
void
|
getAlternatingRowStyle | ||||||||||||
getAlternatingRowStyle(rowIndex: number, cellEl: any)
|
||||||||||||
Applies the alternating row style
Parameters :
Returns :
any
{*} |
getBasicItemStyle | |||||||||||||||
getBasicItemStyle(dataItem: any, rowIndex: number, cellEl: any, columIndex: number)
|
|||||||||||||||
Applies item cell style
Parameters :
Returns :
any
{*} |
getCellStyle | ||||||
getCellStyle(col: any)
|
||||||
Returns the cell style based on the column.
Parameters :
Returns :
any
{*} |
getColumnFieldName | ||||||
getColumnFieldName(column: any)
|
||||||
Returns a valid column name for the grid.
Parameters :
Returns :
string
{string} |
getColumnWidth | ||||||
getColumnWidth(col: any)
|
||||||
Returns the column width.
Parameters :
Returns :
number
{number} |
getControlFieldBySort | ||||||
getControlFieldBySort(sortField: string)
|
||||||
Returns the ControlField component that is sortable by the specified sortField.
Parameters :
Returns :
DataControlFieldComponent
{DataControlFieldComponent} |
getControlFieldColumnCaption | ||||||
getControlFieldColumnCaption(controlField: DataControlFieldComponent)
|
||||||
Returns the column caption for a specific DataControlField.
Parameters :
Returns :
string
{string} |
getControlFieldColumnName | ||||||
getControlFieldColumnName(controlField: DataControlFieldComponent)
|
||||||
Returns the column name for a specific DataControlField.
Parameters :
Returns :
string
{string} |
getControlFieldStyles | ||||||
getControlFieldStyles(controlField: DataControlFieldComponent)
|
||||||
Returns styles for a specific DataControlField.
Parameters :
Returns :
any
{*} |
getDataFieldControls | ||||||
getDataFieldControls(columnIndex: number)
|
||||||
Returns the controls collection in each row for the specified column index.
Parameters :
Returns :
any[]
{any[]} |
getDisplayValue |
getDisplayValue(value: any, rowIndex: number, colIndex: number)
|
Returns the value to be shown in the cell.
Returns :
string
{string} |
getFormat | ||||||
getFormat(col: any)
|
||||||
Returns the column format.
Parameters :
Returns :
string
{string} |
getHeaderStyle |
getHeaderStyle(col: any, colIndex: number)
|
Returns the column headerStyle.
Returns :
any
{*} |
getHeaderStylePropFromModel | ||||||
getHeaderStylePropFromModel(property: string)
|
||||||
Gets the property from the headerStyle of the model of the GridView
Parameters :
Returns :
string | null
{string} |
getHyperLinkDisplayValue |
getHyperLinkDisplayValue(rowIndex: number, colIndex: number)
|
Returns the value to be shown in the cell with HyperLinkField.
Returns :
string
{string} |
getItemTemplate | ||||||
getItemTemplate(columnIndex: number)
|
||||||
Returns the itemTemplate from a specified TemplateField column index.
Parameters :
Returns :
any
{*} |
getItemTemplateModel |
getItemTemplateModel(rowIndex: number, columnIndex: number)
|
Returns the itemTemplate model for a specific TemplateField cell in the grid.
Returns :
any
{*} |
getNoSizeColumns | ||||||
getNoSizeColumns(columns: any)
|
||||||
Return array with columns with NaN or undefined assigned in width property
Parameters :
Returns :
any
{*} |
getRowHeight |
getRowHeight()
|
Gets the rowHeight.
Returns :
number
{number} |
getSortField | ||||||
getSortField(sort: SortDescriptor)
|
||||||
Returns the sortField property needed to sort.
Parameters :
Returns :
string
{string} |
getTemplateFieldsIndexes |
getTemplateFieldsIndexes()
|
Returns the columns indexes where the grid has TemplateField columns.
Returns :
number[]
{number[]} |
getToolTipForRow | ||||||
getToolTipForRow(rowId: string)
|
||||||
Gets the respective tooltip text for a given row using the row id
Parameters :
Returns :
string
{string} |
gridViewSortEventHandler | ||||||
gridViewSortEventHandler(eventData: EventData)
|
||||||
Decorators :
@serverEvent('Sorting', GridViewComponent.SortExtractor)
|
||||||
Triggers the sorting emitter.
Parameters :
Returns :
void
|
gridWidth |
gridWidth()
|
Returns :
string
|
headerCssClass | ||||||
headerCssClass(column: any)
|
||||||
Gets the row css class from the model
Parameters :
Returns :
string
|
hyperLinkFieldClickHandler |
hyperLinkFieldClickHandler(dataItem: any, columnIndex: number, rowIndex: number)
|
Handler for the HyperLinkField click.
Returns :
void
|
internalClickHandler |
internalClickHandler()
|
Handles the client click events raised by the gridview internal button controls.
Returns :
void
|
isBoundFieldComponent | ||||||
isBoundFieldComponent(field: DataControlFieldComponent)
|
||||||
Determines if the DataControlField is an instance of the BoundField Component.
Parameters :
Returns :
BoundFieldComponent
{field is BoundFieldComponent} |
isColumnSortable |
isColumnSortable(columnName: string, columnIndex: number)
|
Verifies if the column is sortable. This is assumed when the column name equals 'false' because it cannot be empty or because it is a controlField and has a sortExpression.
Returns :
boolean
|
isDefaultColumn | ||||||
isDefaultColumn(type: string)
|
||||||
Verifies if the specified daatControlField in the column is a default Column(BoundField or auto generated).
Parameters :
Returns :
boolean
{boolean} |
isGridViewEmpty |
isGridViewEmpty()
|
Check total of items in the gridVew nn
Returns :
boolean
|
isHyperLinkColumn | ||||||
isHyperLinkColumn(type: string)
|
||||||
Verifies if the specified dataControlField in the column is a HyperLinkField.
Parameters :
Returns :
boolean
{boolean} |
isHyperLinkFieldComponent | ||||||
isHyperLinkFieldComponent(field: DataControlFieldComponent)
|
||||||
Determines if the DataControlField is an instance of the HyperLinkField Component.
Parameters :
Returns :
HyperlinkFieldComponent
{field is HyperlinkFieldComponent} |
isPagerCenteredHorizontaly |
isPagerCenteredHorizontaly()
|
Returns true if the pager horizontal align is center
Returns :
boolean
{boolean} |
isPagerLeftHorizontaly |
isPagerLeftHorizontaly()
|
Returns true if the pager horizontal align is left
Returns :
boolean
{boolean} |
isPagerRightHorizontaly |
isPagerRightHorizontaly()
|
Returns true if the pager horizontal align is right
Returns :
boolean
{boolean} |
isTemplateColumn | ||||||
isTemplateColumn(type: string)
|
||||||
Verifies if the specified dataControlField in the column is a TemplateField.
Parameters :
Returns :
boolean
{boolean} |
isTemplateFieldComponent | ||||||
isTemplateFieldComponent(field: DataControlFieldComponent)
|
||||||
Determines if the DataControlField is an instance of the TemplateField Component.
Parameters :
Returns :
TemplateFieldComponent
{field is TemplateFieldComponent} |
itemsTypeFormatter |
itemsTypeFormatter()
|
Sets the correct format for the data received from the API.
Returns :
void
|
kendoColumns |
kendoColumns()
|
Returns the columns to be rendered by the KendoGrid.
Returns :
any[]
{any[]} |
loadColumns |
loadColumns()
|
Loads the grid's columns.
Returns :
void
|
loadData |
loadData()
|
Loads the grid's data.
Returns :
void
|
ngAfterViewInit |
ngAfterViewInit()
|
AfterViewInit lifecycle hook.
Returns :
void
|
ngDoCheck |
ngDoCheck()
|
DoCheck lifecycle hook.
Returns :
void
|
ngOnInit |
ngOnInit()
|
OnInit lifecycle hook.
Returns :
void
|
normalizeRowIndex | ||||||
normalizeRowIndex(rowIndex: number)
|
||||||
Normalize the row index to access the data collection of the grid
Parameters :
Returns :
number
{number} |
pageChange | ||||||
pageChange(event: PageChangeEvent)
|
||||||
Handles the pageChange event.
Parameters :
Returns :
void
|
pageIndexChanging | ||||||
pageIndexChanging(event: EventData)
|
||||||
Decorators :
@serverEvent('PageIndexChanging', GridViewComponent.PageIndexChangingExtractor)
|
||||||
Page Index Changing of gridview component
Parameters :
Returns :
void
|
Static PageIndexChangingExtractor | |||||||||
PageIndexChangingExtractor(event: any, component: GridViewComponent)
|
|||||||||
PageIndexChanging extractor
Parameters :
Returns :
any
{*} |
removeKendoAltRowClass |
removeKendoAltRowClass()
|
Method to remove the k-alt class from the rows to be able to apply the custom classes to rows
Returns :
void
|
Static RowCommandExtractor | |||||||||
RowCommandExtractor(event: any, component: GridViewComponent)
|
|||||||||
RowCommand extractor
Parameters :
Returns :
any
{*} |
rowCommandHandler | ||||||
rowCommandHandler(event: any)
|
||||||
Handles the rowCommand event.
Parameters :
Returns :
void
|
scrollMode |
scrollMode()
|
Returns the scroll mode.
Returns :
string
{string} |
Static SelectedIndexChangingArgsExtractor | |||||||||
SelectedIndexChangingArgsExtractor(event: any, component: GridViewComponent)
|
|||||||||
SelectedIndexChanging Extractor
Parameters :
Returns :
any
{*} |
selectedIndexChangingHandler | ||||||
selectedIndexChangingHandler(rowIndex: any)
|
||||||
Handler for the selected row.
Parameters :
Returns :
void
|
selectRowChangingHandler |
selectRowChangingHandler(event: any, selectorClass: string)
|
Handler for select row change.
Returns :
void
|
setColumnControlFields |
setColumnControlFields()
|
Sets the custom controls to be renderer in the columns headers.
Returns :
void
|
setControlFieldsColumns |
setControlFieldsColumns()
|
Sets the necessary properties for each DataControlField column.
Returns :
void
|
setControlFieldsModels |
setControlFieldsModels()
|
Sets the model for each DataControlField component.
Returns :
void
|
setGridLinesBorder | ||||||
setGridLinesBorder(columnStyle: any)
|
||||||
Sets the gridLines style to the cells of the grid This is called on the getCellStyle method
Parameters :
Returns :
any
the object of the style with the borders applied |
setHeaderStyleSortable |
setHeaderStyleSortable(colName: string, colIndex: number, headerStyle: any)
|
Sets the header style Add e2e tests for this method
Returns :
any
{*} |
setInnerPagerStyle |
setInnerPagerStyle()
|
Sets the inner pager style Used to set the top property
Returns :
any
{*} |
setPagerStyle |
setPagerStyle()
|
Sets the pager style
Returns :
any
{*} |
setSelectableSettings |
setSelectableSettings()
|
Sets the selectableSettings.
Returns :
void
|
setTemplateFieldItemsModels |
setTemplateFieldItemsModels()
|
Sets the controlsIds in each TemplateField column to load the Items models.
Returns :
void
|
setVisibleToDefaultColumns |
setVisibleToDefaultColumns()
|
Sets the visible property to default columns (columns from API).
Returns :
void
|
sortChange | ||||||
sortChange(sort: SortDescriptor)
|
||||||
Prepares the data for the server side request which order the gridview.
Parameters :
Returns :
void
|
Static SortExtractor | |||||||||
SortExtractor(event: any, component: GridComponent)
|
|||||||||
Creates an array of elements with the arguments for the sort handler in the backend
Parameters :
Returns :
any
the event args necessary for the sort event |
trackByColumn |
trackByColumn(index: number, column: any)
|
Track-by function to improve performance.
Returns :
string
{string} |
triggerRowCommand | ||||||
triggerRowCommand(event: any)
|
||||||
Decorators :
@serverEvent('RowCommand', GridViewComponent.RowCommandExtractor)
|
||||||
Trigger the RowCommand Event on server side
Parameters :
Returns :
void
|
triggerSelectedIndexChanging | ||||||
triggerSelectedIndexChanging(eventData: EventData)
|
||||||
Decorators :
@serverEvent('SelectedIndexChanging', GridViewComponent.SelectedIndexChangingArgsExtractor)
|
||||||
Triggers the SelectedRow emitter.
Parameters :
Returns :
void
|
Private allowPagingInternal |
Default value : false
|
Property to save the allowPaging value. |
Private allowSortingInternal |
Default value : false
|
Property to save the allowSorting value. |
Private areColumnsLoaded |
Default value : false
|
Flag to know if the columns are loaded. |
Private autoFitGridViewInternal |
Default value : false
|
Flag to know if apply autofitcolumns. |
Private autoGenerateColumnsInternal |
Default value : true
|
Property to save the autoGenerateColumns value. |
Private autoGenerateSelectButtonInternal |
Default value : false
|
Property to save the autoGenerateSelectButton value. |
columnsChild |
Type : GridViewColumnsComponent
|
Decorators :
@ContentChild(GridViewColumnsComponent)
|
Columns Component reference. |
columnsControls |
Type : any[]
|
Default value : []
|
Property to save the columns controls. |
controlFieldChildren |
Type : QueryList<DataControlFieldComponent>
|
Default value : new QueryList<DataControlFieldComponent>()
|
List of DataControlField components. |
controls |
Type : any[]
|
Default value : []
|
Controls in the gridview |
defaultDataUrl |
Type : string
|
Default value : 'api/gridview'
|
Url base value. |
getColumnsUrl |
Default value : `${this.defaultDataUrl}/GetColumns`
|
Url to get the Grid's Columns set. |
getIndexPageUrl |
Default value : `${this.defaultDataUrl}/GetIndexPage`
|
Url to get the page data with specific index. |
getRangedPageUrl |
Default value : `${this.defaultDataUrl}/GetRangedPage`
|
Url to get the page data with specific range. |
getRowClass | ||
Default value : () => {...}
|
||
Applies the css row class |
||
Parameters :
|
grid |
Type : KendoGridComponent | any
|
Decorators :
@ViewChild(KendoGridComponent, {static: false})
|
Reference to Kendo GridComponent |
Private gridLinesInternal |
Default value : GridLines.Both
|
Flag to apply the gridLines if it comes by input |
Private gridWidthInternal |
Type : string
|
Default value : 'auto'
|
Property to save the gridview width value. |
Private hideHeaderInternal |
Default value : false
|
Property to save the hideHeader value. |
Private isDataLoaded |
Default value : false
|
Property to know if the loadData has been called at least once. |
Private isRendered |
Default value : false
|
Flag to know if the component is rendered. |
kendoAltClassRemoved |
Default value : false
|
Flag to remove the kendo alternative class only one time |
Private kendoCurrentPage |
Type : number
|
Default value : 0
|
Property to save the KendoGrid index. |
Private pageIndexInternal |
Type : number
|
Default value : 0
|
Property to save the pageIndex value. |
Static rowCommandMapperId |
Type : string
|
Default value : 'grdcmmnd'
|
MapperId value for rowcommand event. |
rowElement |
Type : any
|
Default value : undefined
|
Property to save selectedRow element. |
SelectedIndexChanging |
Type : EventEmitter<EventData>
|
Default value : new EventEmitter<EventData>()
|
SelectedIndexChanging event emitter. |
Private selectedIndexInternal |
Default value : -1
|
Property to save the selectedIndex value. |
Static selectedRowMapperId |
Type : string
|
Default value : 'grdsltd'
|
MapperId value for selected row event. |
Static sortMapperId |
Type : string
|
Default value : 'grdsrt'
|
MapperId value for sort event. |
allowPaging | ||||||
getallowPaging()
|
||||||
setallowPaging(value: boolean)
|
||||||
Gets/sets the allowPaging.
Parameters :
Returns :
void
|
autoFitGridView | ||||||
getautoFitGridView()
|
||||||
setautoFitGridView(value: boolean)
|
||||||
Gets/sets the autofit GridView.
Parameters :
Returns :
void
|
hideHeader | ||||||
gethideHeader()
|
||||||
sethideHeader(value: boolean)
|
||||||
Gets/sets the hideHeader GridView property.
Parameters :
Returns :
void
|
pageSize | ||||||
getpageSize()
|
||||||
setpageSize(value: number)
|
||||||
Gets/sets the pageSize.
Parameters :
Returns :
void
|
allowSorting | ||||||
getallowSorting()
|
||||||
setallowSorting(value: boolean)
|
||||||
Gets/sets the allowSorting.
Parameters :
Returns :
void
|
autoGenerateSelectButton | ||||||
getautoGenerateSelectButton()
|
||||||
setautoGenerateSelectButton(value: boolean)
|
||||||
Gets/sets the autoGenerateSelectButton.
Parameters :
Returns :
void
|
pageIndex | ||||||
getpageIndex()
|
||||||
setpageIndex(value: number)
|
||||||
Gets/sets the pageIndex.
Parameters :
Returns :
void
|
selectedIndex | ||||||
getselectedIndex()
|
||||||
setselectedIndex(value: number)
|
||||||
Gets/sets the selectedIndex.
Parameters :
Returns :
void
|
autoGenerateColumns | ||||||
getautoGenerateColumns()
|
||||||
setautoGenerateColumns(value: boolean)
|
||||||
Gets/sets the autoGenerateColumns property.
Parameters :
Returns :
void
|
gridLines | ||||||
getgridLines()
|
||||||
setgridLines(value: GridLines)
|
||||||
GridLines property from model or input if exists
Parameters :
Returns :
void
|
rowClass |
getrowClass()
|
Get the row css class from the model
Returns :
string
|
rowStyle |
getrowStyle()
|
Gets the row style object from model
Returns :
any
|
alternatingRowStyle |
getalternatingRowStyle()
|
Gets the alternating row style object from model
Returns :
any
|
alternatingRowClass |
getalternatingRowClass()
|
Gets the alternating row class from the model
Returns :
string | null | undefined
|
emptyDataText |
getemptyDataText()
|
Get the text to display encase the gridview is empty
Returns :
string
|
pagerStyle |
getpagerStyle()
|
Gets the pager style object from the model
Returns :
any
|
import {
AfterViewInit,
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ContentChild,
DoCheck,
ElementRef,
EventEmitter,
Input,
OnInit,
Optional,
Output,
QueryList,
Renderer2,
ViewChild
} from '@angular/core';
import {
GridComponent,
WebComponentsService
} from '@mobilize/winforms-components';
import { WebMapService } from '@mobilize/angularclient';
import { UntypedFormBuilder } from '@angular/forms';
import { ErrorCodes, ExceptionHandlerClass } from '@mobilize/webmap-core';
import {
ColumnComponent,
GridComponent as KendoGridComponent,
PageChangeEvent,
RowClassArgs
} from '@progress/kendo-angular-grid';
import { SortDescriptor } from '@progress/kendo-data-query';
import { HttpParams } from '@angular/common/http';
import {
BringTopService,
dataTransfer,
EventData,
serverEvent
} from '@mobilize/base-components';
import { BoundFieldComponent } from '../bound-field/bound-field.component';
import { UnitType } from '../../contracts';
import { DataControlFieldComponent } from '../data-control-field/data-control-field.component';
import { GridViewColumnsComponent } from '../gridview-columns/gridview-columns.component';
import { HyperlinkFieldComponent } from '../hyperlink-field/hyperlink-field.component';
import { TemplateFieldComponent } from '../template-field/template-field.component';
import { GridLines } from '../../contracts/GridLines';
import { ColumnStyleManager } from './ColumnStyleManager/column-style-manager';
import { PagerStyleManager } from './PagerStyleManager/pager-style-manager';
import { PagerHorizontalAlign } from '../../contracts/PagerHorizontalAlign';
import { InternalEventHandlerService } from '../../services';
/**
* Angular Component for the GridView Control.
*
* @export
* @ class GridViewComponent
* @extends {GridComponent}
* @implements {OnInit}
* @implements {DoCheck}
*/
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'wm-gridview',
templateUrl: './gridview.component.html',
styleUrls: ['./gridview.component.scss'],
inputs: ['model'],
providers: [InternalEventHandlerService]
})
@dataTransfer(['grdvw'])
@ExceptionHandlerClass(ErrorCodes.Winforms)
export class GridViewComponent
extends GridComponent
implements OnInit, AfterViewInit, DoCheck
{
/**
* Reference to Kendo GridComponent
*
* @type {(GridComponent | any)}
* @memberof GridViewComponent
*/
@ViewChild(KendoGridComponent, { static: false })
grid: KendoGridComponent | any;
/**
* Flag to remove the kendo alternative class only one time
*
* @type {boolean}
* @memberof GridViewComponent
*/
kendoAltClassRemoved = false;
/**
* Creates an array of elements with the arguments for the sort handler in the backend
*
* @param {*} event
* @param {GridViewComponent} component
* @memberof GridViewComponent
* @returns the event args necessary for the sort event
*/
static SortExtractor(event: any, component: GridComponent): any {
return [
{ Id: event.Id, MapperId: event.args.MapperId },
{
MapperId: GridViewComponent.sortMapperId,
SortExpression: event.args.sortExpression,
Direction: event.args.direction
}
];
}
/**
* SelectedIndexChanging Extractor
*
* @static
* @param {*} event
* @param {GridViewComponent} component
* @return {*} {*}
* @memberof GridViewComponent
*/
static SelectedIndexChangingArgsExtractor(
event: any,
component: GridViewComponent
): any {
return [
null,
{
NewSelectedRow: event.args.selectedRow,
MapperId: GridViewComponent.selectedRowMapperId
}
];
}
/**
* PageIndexChanging extractor
*
* @static
* @param {*} event
* @param {GridViewComponent} component
* @return {*} {*}
* @memberof GridViewComponent
*/
static PageIndexChangingExtractor(
event: any,
component: GridViewComponent
): any {
return [
{ Id: event.Id, MapperId: event.mapperId },
{
MapperId: 'grdvwpgvntrgs',
NewPageIndex: event.args.newPageIndex
}
];
}
/**
* RowCommand extractor
*
* @static
* @param {*} event
* @param {GridViewComponent} component
* @return {*} {*}
* @memberof GridViewComponent
*/
static RowCommandExtractor(event: any, component: GridViewComponent): any {
return [
{ Id: event.Id, MapperId: event.mapperId },
{
MapperId: GridViewComponent.rowCommandMapperId,
CommandName: event.args.CommandName,
CommandArgument: event.args.CommandArgument,
References: {
CommandSource: event.args.CommandSource
}
}
];
}
/**
* Url base value.
*
* @memberof GridViewComponent
*/
defaultDataUrl = 'api/gridview';
/**
* Emiter for the sorting event.
*
* @memberof GridViewComponent
*/
@Output()
Sorting: EventEmitter<EventData> = new EventEmitter<EventData>();
/**
* Emitter for the page index changing event
*
* @type {EventEmitter<EventData>}
* @memberof GridViewComponent
*/
@Output()
PageIndexChanging: EventEmitter<EventData> = new EventEmitter<EventData>();
/**
* Emitter for the selected row changing event
*
* @type {EventEmitter<EventData>}
* @memberof GridViewComponent
*/
@Output()
SelectedRowChange: EventEmitter<EventData> = new EventEmitter<EventData>();
/**
* Emitter for double click row event
*
* @type {EventEmitter<EventData>}
* @memberof GridViewComponent
*/
@Output()
DoubleClick: EventEmitter<EventData> = new EventEmitter<EventData>();
/**
* Emitter for the onRowCommand Event.
*
* @type {EventEmitter<{ source: any; e: any }>}
* @memberof GridViewComponent
*/
@Output()
OnRowCommand: EventEmitter<{ source: any; e: any }> = new EventEmitter();
/**
* Url to get the Grid's Columns set.
*
* @memberof GridViewComponent
*/
getColumnsUrl = `${this.defaultDataUrl}/GetColumns`;
/**
* Url to get the page data with specific index.
*
* @memberof GridViewComponent
*/
getIndexPageUrl = `${this.defaultDataUrl}/GetIndexPage`;
/**
* Url to get the page data with specific range.
*
* @memberof GridViewComponent
*/
getRangedPageUrl = `${this.defaultDataUrl}/GetRangedPage`;
/**
* Property to save the KendoGrid index.
*
* @memberof GridViewComponent
*/
private kendoCurrentPage = 0;
/**
* MapperId value for selected row event.
*
* @static
* @memberof GridViewComponent
*/
static selectedRowMapperId = 'grdsltd';
/**
* MapperId value for sort event.
*
* @static
* @memberof GridViewComponent
*/
static sortMapperId = 'grdsrt';
/**
* MapperId value for rowcommand event.
*
* @static
* @memberof GridViewComponent
*/
static rowCommandMapperId = 'grdcmmnd';
/**
* Property to save the allowPaging value.
*
* @memberof GridViewComponent
*/
private allowPagingInternal = false;
/**
* Property to save the allowSorting value.
*
* @private
* @memberof GridViewComponent
*/
private allowSortingInternal = false;
/**
* Property to save the autoGenerateSelectButton value.
*
* @private
* @memberof GridViewComponent
*/
private autoGenerateSelectButtonInternal = false;
/**
* Property to save the selectedIndex value.
*
* @private
* @memberof GridViewComponent
*/
private selectedIndexInternal = -1;
/**
* Property to save the pageIndex value.
*
* @private
* @memberof GridViewComponent
*/
private pageIndexInternal = 0;
/**
* Property to save the autoGenerateColumns value.
*
* @private
* @memberof GridViewComponent
*/
private autoGenerateColumnsInternal = true;
/**
* Property to save the hideHeader value.
*
* @private
* @memberof GridViewComponent
*/
private hideHeaderInternal = false;
/**
* Property to know if the loadData has been called at least once.
*
* @private
* @memberof GridViewComponent
*/
private isDataLoaded = false;
/**
* Flag to know if the component is rendered.
*
* @private
* @memberof GridViewComponent
*/
private isRendered = false;
/**
* Flag to know if the columns are loaded.
*
* @private
* @memberof GridViewComponent
*/
private areColumnsLoaded = false;
/**
* Flag to apply the gridLines if it comes by input
*
* @private
* @memberof GridViewComponent
*/
private gridLinesInternal = GridLines.Both;
/**
* Property to save the gridview width value.
*
* @memberof GridViewComponent
*/
private gridWidthInternal = 'auto';
/**
* Flag to know if apply autofitcolumns.
*
* @memberof GridViewComponent
*/
private autoFitGridViewInternal = false;
/**
* Property to save the columns controls.
*
* @type {any[]}
* @memberof GridViewComponent
*/
columnsControls: any[] = [];
/**
* Property to save selectedRow element.
*
* @type {any}
* @memberof GridViewComponent
*/
rowElement: any = undefined;
/**
* Controls in the gridview
*
* @type {any[]}
* @memberof GridViewComponent
*/
controls: any[] = [];
/**
* SelectedIndexChanging event emitter.
*
* @type {EventEmitter<EventData>}
* @memberof GridViewComponent
*/
SelectedIndexChanging: EventEmitter<EventData> =
new EventEmitter<EventData>();
/**
* List of DataControlField components.
*
* @type {QueryList<DataControlFieldComponent>}
* @memberof GridViewComponent
*/
controlFieldChildren: QueryList<DataControlFieldComponent> =
new QueryList<DataControlFieldComponent>();
/**
* Columns Component reference.
*
* @type {GridViewColumnsComponent}
* @memberof GridViewComponent
*/
@ContentChild(GridViewColumnsComponent)
columnsChild!: GridViewColumnsComponent;
/**
* Creates an instance of GridViewComponent.
*
* @param {WebMapService} wmService
* @param {ChangeDetectorRef} refChange
* @param {Renderer2} render2
* @param {ElementRef} elem
* @param {FormBuilder} formBuilderRef
* @param {InternalEventHandlerService} internalEventHandler
* @param {WebComponentsService} webComponents
* @param {BringTopService} bringTopServ1
* @memberof GridViewComponent
*/
constructor(
private wmService: WebMapService,
private refChange: ChangeDetectorRef,
private render2: Renderer2,
private elem: ElementRef,
private formBuilderRef: UntypedFormBuilder,
private internalEventHandler: InternalEventHandlerService,
webComponents: WebComponentsService,
@Optional() private bringTopServ1: BringTopService
) {
super(
wmService,
refChange,
render2,
elem,
formBuilderRef,
webComponents,
bringTopServ1
);
this.getRowClass.bind(this);
}
/**
* OnInit lifecycle hook.
*
* @memberof GridViewComponent
*/
ngOnInit(): void {
this.setSelectableSettings();
this.loadColumns();
this.loadData();
this.internalClickHandler();
}
/**
* AfterViewInit lifecycle hook.
*
* @memberof GridViewComponent
*/
ngAfterViewInit(): void {
if (this.columnsChild?.controlFieldChildren) {
this.controlFieldChildren = this.columnsChild.controlFieldChildren;
}
this.isRendered = true;
this.setColumnControlFields();
}
/**
* Gets/sets the allowPaging.
*
* @memberof GridViewComponent
*/
@Input()
set allowPaging(value: boolean) {
this.allowPagingInternal = value;
}
get allowPaging(): boolean {
return (
(this.model.AllowPaging ?? this.allowPagingInternal) &&
!this.isGridViewEmpty()
);
}
/**
* Gets/sets the autofit GridView.
*
* @memberof GridViewComponent
*/
@Input()
set autoFitGridView(value: boolean) {
this.autoFitGridViewInternal = value;
}
get autoFitGridView(): boolean {
return this.autoFitGridViewInternal;
}
/**
* Gets/sets the hideHeader GridView property.
*
* @memberof GridViewComponent
*/
@Input()
set hideHeader(value: boolean) {
this.hideHeaderInternal = value;
}
get hideHeader(): boolean {
return (
(this.model.ShowHeader != undefined
? !this.model.ShowHeader
: this.hideHeaderInternal) || this.isGridViewEmpty()
);
}
/**
* Check total of items in the gridVew
*nn
* @return {boolean}
*/
isGridViewEmpty(): boolean {
return this.gridView?.total === 0;
}
/**
* Gets/sets the pageSize.
*
* @memberof GridViewComponent
*/
@Input()
set pageSize(value: number) {
/* c8 ignore else*/
if (this.allowPaging) {
this.pageSizeInternal = value;
}
}
get pageSize(): number {
if (this.allowPaging) {
return this.model.PageSize ?? this.pageSizeInternal ?? 10;
}
return 100;
}
/**
* Gets/sets the allowSorting.
*
* @memberof GridViewComponent
*/
@Input()
set allowSorting(value: boolean) {
this.allowSortingInternal = value;
}
get allowSorting(): boolean {
return this.model.AllowSorting ?? this.allowSortingInternal;
}
/**
* Gets/sets the autoGenerateSelectButton.
*
* @memberof GridViewComponent
*/
@Input()
set autoGenerateSelectButton(value: boolean) {
this.autoGenerateSelectButtonInternal = value;
}
get autoGenerateSelectButton(): boolean {
return (
this.model.AutoGenerateSelectButton ??
this.autoGenerateSelectButtonInternal
);
}
/**
* Gets/sets the pageIndex.
*
* @memberof GridViewComponent
*/
@Input()
set pageIndex(value: number) {
this.pageIndexInternal = value;
}
get pageIndex(): number {
return this.model?.PageIndex ?? this.pageIndexInternal ?? 0;
}
/**
* Gets/sets the selectedIndex.
*
* @memberof GridViewComponent
*/
@Input()
set selectedIndex(value: number) {
this.selectedIndexInternal = value;
}
get selectedIndex(): number {
let result: number;
if (this.allowPaging) {
if (this.model.SelectedIndex && this.model.SelectedIndex >= 0) {
result = this.model.SelectedIndex + this.skip;
} else if (this.selectedIndexInternal >= 0) {
result = this.selectedIndexInternal + this.skip;
} else {
result = this.selectedIndexInternal;
}
} else {
result =
this.model.SelectedIndex && this.model.SelectedIndex >= 0
? this.model.SelectedIndex
: this.selectedIndexInternal;
}
return result;
}
/**
* Gets/sets the autoGenerateColumns property.
*
* @memberof GridViewComponent
*/
@Input()
set autoGenerateColumns(value: boolean) {
this.autoGenerateColumnsInternal = value;
}
get autoGenerateColumns(): boolean {
return this.model.AutoGenerateColumns ?? this.autoGenerateColumnsInternal;
}
/**
* GridLines property from model or input if exists
*
* @readonly
* @type {string}
* @memberof GridViewComponent
*/
@Input()
set gridLines(value: GridLines) {
this.gridLinesInternal = value;
}
get gridLines(): GridLines {
return (this.model && this.model.GridLines) ?? this.gridLinesInternal;
}
/**
*
* Get the row css class from the model
* @readonly
* @type {string}
* @memberof GridViewComponent
*/
get rowClass(): string {
return this.model?.RowStyle?.CssClass ?? '';
}
/**
* Gets the row style object from model
*
* @readonly
* @type {*}
* @memberof GridViewComponent
*/
get rowStyle(): any {
return this.model?.RowStyle;
}
/**
* Gets the alternating row style object from model
*
* @readonly
* @type {*}
* @memberof GridViewComponent
*/
get alternatingRowStyle(): any {
return this.model?.AlternatingRowStyle;
}
/**
* Gets the alternating row class from the model
*
* @readonly
* @type {*}
* @memberof GridViewComponent
*/
get alternatingRowClass(): string | null | undefined {
return this.alternatingRowStyle?.CssClass;
}
/**
* Get the text to display encase the gridview is empty
*
* @type {string}
* @readonly
* @memberof GridViewComponent
*/
get emptyDataText(): string {
return this.model?.EmptyDataText;
}
/* GridView width property
*
* @return {*} {string}
* @memberof GridViewComponent
*/
gridWidth(): string {
return this.gridWidthInternal;
}
/**
* Gets the pager style object from the model
*
* @readonly
* @type {*}
* @memberof GridViewComponent
*/
get pagerStyle(): any {
return this.model?.PagerStyle;
}
/**
* Returns the scroll mode.
*
* @return {*} {string}
* @memberof GridViewComponent
*/
scrollMode(): string {
return this.allowPaging ? 'none' : 'virtual';
}
/**
* Gets the rowHeight.
*
* @return {*} {number}
* @memberof GridViewComponent
*/
getRowHeight(): number {
return this.allowPaging ? 0 : this.rowHeight;
}
/**
* Handles the pageChange event.
*
* @param {PageChangeEvent} event
* @memberof GridViewComponent
*/
pageChange(event: PageChangeEvent): void {
this.pageSize = event.take;
this.skip = event.skip;
this.kendoCurrentPage =
Math.ceil((event.skip + event.take) / event.take) - 1;
const eventData = new EventData(event, this.id, 'grdvw');
eventData['args'] = {
newPageIndex: this.kendoCurrentPage + 1
};
this.pageIndexChanging(eventData);
}
/**
* Loads the grid's columns.
*
* @memberof GridViewComponent
*/
loadColumns(): void {
this.wmService.fetch<any>(this.getColumnsUrl, this.id).subscribe((data) => {
this.columns = (data as any).Cols;
this.refChange.detectChanges();
this.areColumnsLoaded = true;
this.setColumnControlFields();
});
}
/**
* Returns a valid column name for the grid.
*
* @param {*} column
* @return {*} {string}
* @memberof GridViewComponent
*/
getColumnFieldName(column: any): string {
let name = '';
if (column.name) {
name = column.name;
} else if (column.caption) {
/* c8 ignore else */
name = column.caption.replace(/\s/g, '');
}
return name;
}
/**
* Loads the grid's data.
*
* @memberof GridViewComponent
*/
loadData(): void {
this.loading = true;
let params = new HttpParams();
let dataUrl: string;
if (this.allowPaging) {
let newIndex: number;
if (!this.isDataLoaded) {
//first time is loaded
newIndex = this.pageIndex;
} else {
newIndex = this.kendoCurrentPage;
}
params = params.set('newPageIndex', newIndex.toString());
this.skip = newIndex * this.pageSize;
dataUrl = this.getIndexPageUrl;
} else {
params = this.getPageParams();
dataUrl = this.getRangedPageUrl;
}
setTimeout(() => {
this.wmService.fetch<any>(dataUrl, this.id, params).subscribe((data) => {
this.items = (data as any).Rows;
this.itemsTypeFormatter();
this.gridView = {
data: this.items,
total: (data as any).Length
};
this.loading = false;
this.setTemplateFieldItemsModels();
this.detectChanges();
this.refChange.detectChanges();
/* c8 ignore else*/
if (this.autoFitGridView) {
this.fitColumns();
}
});
}, 25);
/* c8 ignore else*/
if (!this.isDataLoaded) {
this.isDataLoaded = true;
}
}
/**
* Track-by function to improve performance.
*
* @param {number} index
* @param {*} column
* @return {*} {string}
* @memberof GridViewComponent
*/
trackByColumn(index: number, column: any): string {
return this.getColumnFieldName(column);
}
/**
* Returns the value to be shown in the cell.
*
* @param {*} value
* @param {number} rowIndex
* @param {number} colIndex
* @return {*} {string}
* @memberof GridViewComponent
*/
getDisplayValue(value: any, rowIndex: number, colIndex: number): string {
let formattedValue = value;
const normalizedRowIndex = this.normalizeRowIndex(rowIndex);
/* c8 ignore else*/
if (colIndex < this.controlFieldChildren.length) {
const text =
this.items[normalizedRowIndex]?.DataControlFields[colIndex]?.Text;
/* c8 ignore else*/
if (text && text !== '') {
formattedValue = text;
}
}
return value === '' || value === null ? ' ' : formattedValue;
}
/**
* Returns the value to be shown in the cell with HyperLinkField.
*
* @param {number} rowIndex
* @param {number} colIndex
* @return {*} {string}
* @memberof GridViewComponent
*/
getHyperLinkDisplayValue(rowIndex: number, colIndex: number): string {
let formattedValue = '';
const normalizedRowIndex = this.normalizeRowIndex(rowIndex);
if (
colIndex < this.controlFieldChildren.length &&
this.isHyperLinkFieldComponent(
this.controlFieldChildren.toArray()[colIndex]
)
) {
const text =
this.items[normalizedRowIndex]?.DataControlFields[colIndex]?.Text;
const dataTextField = (
this.controlFieldChildren.toArray()[colIndex] as HyperlinkFieldComponent
).dataTextField;
if (dataTextField && dataTextField !== '') {
formattedValue = text;
} else {
formattedValue = this.controlFieldChildren.toArray()[colIndex].text;
}
}
return !formattedValue ? '' : formattedValue;
}
/**
* Handler for the HyperLinkField click.
*
* @param {*} dataItem
* @param {number} columnIndex
* @param rowIndex
* @memberof GridViewComponent
*/
hyperLinkFieldClickHandler(
dataItem: any,
columnIndex: number,
rowIndex: number
): void {
/* c8 ignore else*/
if (
columnIndex < this.controlFieldChildren.length &&
this.isHyperLinkFieldComponent(
this.controlFieldChildren.toArray()[columnIndex]
)
) {
const normalizedRowIndex = this.normalizeRowIndex(rowIndex);
(
this.controlFieldChildren.toArray()[
columnIndex
] as HyperlinkFieldComponent
).clickHandler(dataItem, normalizedRowIndex);
}
}
/**
* Verifies if the specified dataControlField in the column is a HyperLinkField.
*
* @return {*} {boolean}
* @memberof GridViewComponent
* @param type
*/
isHyperLinkColumn(type: string): boolean {
return type === 'HyperLinkField';
}
/**
* Verifies if the specified dataControlField in the column is a TemplateField.
*
* @param {string} type
* @return {*} {boolean}
* @memberof GridViewComponent
*/
isTemplateColumn(type: string): boolean {
return type === 'TemplateField';
}
/**
* Verifies if the specified daatControlField in the column is a default Column(BoundField or auto generated).
*
* @param {string} type
* @return {*} {boolean}
* @memberof GridViewComponent
*/
isDefaultColumn(type: string): boolean {
return !this.isHyperLinkColumn(type) && !this.isTemplateColumn(type);
}
/**
* Returns the itemTemplate from a specified TemplateField column index.
*
* @param {number} columnIndex
* @return {*} {*}
* @memberof GridViewComponent
*/
getItemTemplate(columnIndex: number): any {
return (
this.controlFieldChildren.toArray()[columnIndex] as TemplateFieldComponent
).itemTemplate;
}
/**
* Returns the itemTemplate model for a specific TemplateField cell in the grid.
*
* @param {number} rowIndex
* @param {number} columnIndex
* @return {*} {*}
* @memberof GridViewComponent
*/
getItemTemplateModel(rowIndex: number, columnIndex: number): any {
const normalizedRowIndex = this.normalizeRowIndex(rowIndex);
const models = (
this.controlFieldChildren.toArray()[columnIndex] as TemplateFieldComponent
).itemTemplateModels;
return normalizedRowIndex < models.length
? models[normalizedRowIndex]
: undefined;
}
/**
* Verifies if the itemTemplate models for a specific TemplateField are loaded.
*
* @param {number} columnIndex
* @return {*} {boolean}
* @memberof GridViewComponent
*/
areItemTemplateModelsLoaded(columnIndex: number): boolean {
return (
(
this.controlFieldChildren.toArray()[
columnIndex
] as TemplateFieldComponent
).itemTemplateModels.length > 0 &&
(
this.controlFieldChildren.toArray()[
columnIndex
] as TemplateFieldComponent
).itemTemplate !== undefined
);
}
/**
* Verifies if the column is sortable.
* This is assumed when the column name equals 'false' because it cannot be empty
* or because it is a controlField and has a sortExpression.
*
* @param {string} columnName
* @param columnIndex
* @return {*}
* @memberof GridViewComponent
*/
isColumnSortable(columnName: string, columnIndex: number): boolean {
if (columnIndex < this.controlFieldChildren.length) {
return (
!!this.controlFieldChildren.toArray()[columnIndex].sortExpression ||
columnName !== 'false'
);
}
return columnName !== 'false';
}
/**
* Prepares the data for the server side request which order the gridview.
*
* @param {SortDescriptor} sort
* @memberof GridViewComponent
*/
sortChange(sort: SortDescriptor): void {
/* c8 ignore else */
if (sort) {
this.sort = sort;
const eventData = new EventData('Sorting', this.id);
eventData.args = {
direction: (this.sort as any)[0].dir,
sortExpression: this.getSortField(sort),
MapperId: GridViewComponent.sortMapperId
};
this.gridViewSortEventHandler(eventData);
}
}
/**
* Returns the sortField property needed to sort.
*
* @param {SortDescriptor} sort
* @return {*} {string}
* @memberof GridViewComponent
*/
getSortField(sort: SortDescriptor): string {
const controlField = this.getControlFieldBySort((sort as any)[0]?.field);
return controlField?.sortExpression && controlField.sortExpression !== ''
? controlField.sortExpression
: (sort as any)[0]?.field;
}
/**
* Returns the ControlField component that is sortable by the specified sortField.
*
* @param {string} sortField
* @return {*} {DataControlFieldComponent}
* @memberof GridViewComponent
*/
getControlFieldBySort(sortField: string): DataControlFieldComponent {
return this.controlFieldChildren
.toArray()
.find(
(field) =>
(this.isBoundFieldComponent(field) &&
field.dataField === sortField) ||
(this.isHyperLinkFieldComponent(field) &&
field.dataTextField === sortField)
) as any;
}
/**
* Triggers the sorting emitter.
*
* @param {EventData} eventData
* @memberof GridViewComponent
*/
@serverEvent('Sorting', GridViewComponent.SortExtractor)
gridViewSortEventHandler(eventData: EventData): void {
this.Sorting.emit(eventData);
}
/**
* Sets the selectableSettings.
*
* @memberof GridViewComponent
*/
setSelectableSettings(): void {
/* c8 ignore else*/
if (this.autoGenerateSelectButton) {
this.selectableSettings = {
checkboxOnly: false,
mode: 'single'
};
}
}
/**
* Handler for the cell click.
*
* @param {*} event
* @memberof GridViewComponent
*/
cellClickHandler(event: any): void {
let rowIndex: number;
let selectorRowClass = '';
if (this.allowPaging) {
selectorRowClass = '.k-grid table';
rowIndex =
event.rowIndex >= this.pageSize
? event.rowIndex - this.pageSize
: event.rowIndex;
} else {
selectorRowClass = '.k-grid-content';
rowIndex = event.rowIndex;
}
this.selectedIndexChangingHandler(rowIndex);
this.selectRowChangingHandler(event, selectorRowClass);
}
/**
* Handler for select row change.
*
* @param {*} event
* @param selectorClass
* @memberof GridViewComponent
*/
selectRowChangingHandler(event: any, selectorClass: string): void {
const kendoGrid = this.grid?.wrapper?.nativeElement;
const nthChild = this.allowPaging ? event.rowIndex + 2 : event.rowIndex + 1;
/* c8 ignore else*/
if (kendoGrid) {
this.rowElement = kendoGrid.querySelector(
selectorClass + ` tr:nth-child(${nthChild}):not([kendogridgroupheader])`
);
}
const eventData = new EventData('SelectedRow', this.id);
eventData.args = {
rowElement: this.rowElement,
event,
model: this.model
};
this.SelectedRowChange.emit(eventData);
}
/**
* Handler for double cell click.
*
* @param {*} event
* @memberof GridViewComponent
*/
doubleClick(event: any): void {
// This is to wait for the click to be executed before doubleclick
setTimeout(() => {
const eventData = new EventData('DoubleClick', this.id);
eventData.args = { rowElement: this.rowElement, event: event };
this.DoubleClick.emit(eventData);
}, 0);
}
/**
* Handler for the selected row.
*
* @param {*} rowIndex
* @memberof GridViewComponent
*/
selectedIndexChangingHandler(rowIndex: any): void {
const eventData = new EventData('SelectedIndexChanging', this.id);
eventData.args = { selectedRow: rowIndex };
this.triggerSelectedIndexChanging(eventData);
}
/**
* DoCheck lifecycle hook.
*
* @memberof GridViewComponent
*/
ngDoCheck(): void {
super.ngDoCheck();
/* c8 ignore else*/
if (this.model) {
if (
this.isDataLoaded &&
this.model.PageIndex &&
this.model.PageIndex !== this.kendoCurrentPage
) {
this.kendoCurrentPage = this.model.PageIndex;
this.loadData();
}
if (this.refresh) {
this.loadData();
this.refresh = false;
}
this.refChange.detectChanges();
}
if (!this.kendoAltClassRemoved) {
this.removeKendoAltRowClass();
}
}
/**
* Method to remove the k-alt class from the rows to be able to apply the custom classes to rows
*
* @memberof GridViewComponent
*/
/* c8 ignore start */
removeKendoAltRowClass(): void {
const rowEls = this.elem?.nativeElement?.querySelectorAll('tr .k-alt');
if (rowEls?.length > 0) {
rowEls.forEach((el: any) => {
this.render2.removeClass(el, 'k-alt');
});
}
this.kendoAltClassRemoved = true;
} /* c8 ignore stop */
/**
* Triggers the SelectedRow emitter.
*
* @param {EventData} eventData
* @memberof GridViewComponent
*/
@serverEvent(
'SelectedIndexChanging',
GridViewComponent.SelectedIndexChangingArgsExtractor
)
triggerSelectedIndexChanging(eventData: EventData): void {
this.SelectedIndexChanging.emit(eventData);
}
/**
* Returns the columns to be rendered by the KendoGrid.
*
* @return {*} {any[]}
* @memberof GridViewComponent
*/
kendoColumns(): any[] {
/* c8 ignore else*/
if (this.autoGenerateColumns && this.columns) {
return this.columnsControls.concat(
this.columns.filter((col) => !col.ContainingField)
);
} else if (this.columnsControls.length <= 0) {
this.gridView = { data: [], total: 0 };
}
return this.columnsControls;
}
/**
* Sets the custom controls to be renderer in the columns headers.
*
* @memberof GridViewComponent
*/
setColumnControlFields(): void {
if (this.isRendered && this.areColumnsLoaded) {
this.setControlFieldsModels();
this.setControlFieldsColumns();
}
}
/**
* Adjust width columns for setup as autofit columns
* with width value NaN and recalculate width grid
* based in new autofit
* @memberof GridViewComponent
*/
fitColumns(): void {
const initialKendoColumns = this.grid?.columns?._results;
/* c8 ignore else*/
if (initialKendoColumns) {
this.width = 0;
const noSizedColumns = this.getNoSizeColumns(initialKendoColumns);
noSizedColumns.forEach((column: ColumnComponent) => {
this.grid.autoFitColumn(column);
});
initialKendoColumns.forEach((column: ColumnComponent) => {
this.width = this.width + column.width;
});
this.gridWidthInternal = this.allowPaging
? String(this.width) + 'px'
: String(this.width + 20) + 'px';
}
}
/**
*Return array with columns with NaN or undefined assigned in width property
*
* @param {*} columns
* @return {*} {*}
* @memberof GridViewComponent
*/
getNoSizeColumns(columns: any): any {
const noSizedColumns: any[] = [];
columns.forEach((column: ColumnComponent) => {
/*c8 ignore else */
if (Number.isNaN(column.width) || column.width === undefined) {
noSizedColumns.push(column);
}
});
return noSizedColumns;
}
/**
* Sets the controlsIds in each TemplateField column to load the Items models.
*
* @memberof GridViewComponent
*/
setTemplateFieldItemsModels(): void {
/* c8 ignore else */
if (this.isDataLoaded && this.items.length > 0) {
const templateFieldIndexes = this.getTemplateFieldsIndexes();
templateFieldIndexes.forEach((index) => {
/* c8 ignore else */
if (
this.isTemplateFieldComponent(
this.controlFieldChildren.toArray()[index]
)
) {
const controlsIds: any[] = this.getDataFieldControls(index);
(
this.controlFieldChildren.toArray()[index] as TemplateFieldComponent
).setItemTemplateModels(controlsIds);
}
});
}
}
/**
* Returns the controls collection in each row for the specified column index.
*
* @param {number} columnIndex
* @return {*} {any[]}
* @memberof GridViewComponent
*/
getDataFieldControls(columnIndex: number): any[] {
const controlsIds: any[] = [];
this.items.forEach((row) => {
const rowControls = row.DataControlFields[columnIndex]?.Controls;
/* c8 ignore else */
if (rowControls) {
controlsIds.push(rowControls);
}
});
return controlsIds;
}
/**
* Returns the columns indexes where the grid has TemplateField columns.
*
* @return {*} {number[]}
* @memberof GridViewComponent
*/
getTemplateFieldsIndexes(): number[] {
const indexes: number[] = [];
/* c8 ignore else */
if (this.isDataLoaded && this.controlFieldChildren.length > 0) {
for (let i = 0; i < this.controlFieldChildren.length; i++) {
if (
this.isTemplateFieldComponent(this.controlFieldChildren.toArray()[i])
) {
indexes.push(i);
}
}
}
return indexes;
}
/**
* Sets the necessary properties for each DataControlField column.
*
* @memberof GridViewComponent
*/
setControlFieldsColumns(): void {
if (this.controlFieldChildren.length > 0) {
for (const field of this.controlFieldChildren.toArray()) {
const name = this.getControlFieldColumnName(field);
const caption = this.getControlFieldColumnCaption(field);
const styles = this.getControlFieldStyles(field);
let col = {
name,
caption,
visible: field.visible
};
col = { ...col, ...styles };
this.columnsControls.push(col);
}
}
}
/**
* Returns the column name for a specific DataControlField.
*
* @param {DataControlFieldComponent} controlField
* @return {*} {string}
* @memberof GridViewComponent
*/
getControlFieldColumnName(controlField: DataControlFieldComponent): string {
let name = '';
if (this.isBoundFieldComponent(controlField)) {
name = controlField.dataField;
} else if (this.isHyperLinkFieldComponent(controlField)) {
name =
controlField.dataTextField === ''
? 'false'
: controlField.dataTextField;
} else {
name = 'false';
}
if (name === 'false' && !!controlField?.sortExpression) {
name = controlField.sortExpression;
}
return name;
}
/**
* Returns the column caption for a specific DataControlField.
*
* @param {DataControlFieldComponent} controlField
* @return {*} {string}
* @memberof GridViewComponent
*/
getControlFieldColumnCaption(
controlField: DataControlFieldComponent
): string {
return controlField.headerText;
}
/**
* Returns styles for a specific DataControlField.
*
* @param {DataControlFieldComponent} controlField
* @return {*} {*}
* @memberof GridViewComponent
*/
getControlFieldStyles(controlField: DataControlFieldComponent): any {
const unitType: UnitType = (UnitType as any)[
controlField.itemStyle?.Width?.Type
];
const itemStyleWidth = controlField.itemStyle?.Width?.Value;
const width: number =
unitType === UnitType.Pixel ? itemStyleWidth : Number.NaN;
let headerStyle: any = {};
headerStyle =
unitType === UnitType.Percentage ? { width: `${itemStyleWidth}%` } : {};
const style = new ColumnStyleManager().applyCellStyle(
controlField,
this.rowStyle
);
let dataFormat = '';
if (this.isBoundFieldComponent(controlField)) {
dataFormat = controlField.dataFormatString;
}
/* c8 ignore start */
headerStyle['text-align'] =
controlField?.headerStyle && controlField?.headerStyle?.HorizontalAlign
? controlField.headerStyle?.HorizontalAlign
: this.getHeaderStylePropFromModel('HorizontalAlign');
headerStyle['background-color'] =
controlField?.headerStyle && controlField?.headerStyle?.BackColor
? controlField?.headerStyle?.BackColor
: this.getHeaderStylePropFromModel('BackColor'); /* c8 ignore stop */
const cssClass = controlField.headerStyle?.CssClass ?? null;
return {
cssClass,
width,
headerStyle,
style,
format: dataFormat
};
}
/**
* Returns the column width.
*
* @param {*} col
* @return {*} {number}
* @memberof GridViewComponent
*/
getColumnWidth(col: any): number {
return col.width ?? Number.NaN;
}
/**
* Returns the column headerStyle.
*
* @param {*} col
* @param colIndex
* @return {*} {*}
* @memberof GridViewComponent
*/
getHeaderStyle(col: any, colIndex: number): any {
const headerStyle = col.headerStyle ?? this.applyHeaderStylesFromModel();
const style = this.setHeaderStyleSortable(
this.getColumnFieldName(col),
colIndex,
headerStyle
);
return this.setGridLinesBorder(style);
}
/**
* Gets the property from the headerStyle of the model of the GridView
*
* @param {string} property
* @return {*} {string}
* @memberof GridViewComponent
*/
getHeaderStylePropFromModel(property: string): string | null {
return this.model?.HeaderStyle && this.model?.HeaderStyle[property]
? this.model.HeaderStyle[property]
: null;
}
/**
* Returns the cell style based on the column.
*
* @param {*} col
* @return {*} {*}
* @memberof GridViewComponent
*/
getCellStyle(col: any): any {
const style =
col.style ?? new ColumnStyleManager().applyCellStyle(col, this.rowStyle);
return this.setGridLinesBorder(style);
}
/**
* Applies the css row class
*
* @param {RowClassArgs} context
* @return {*}
* @memberof GridViewComponent
*/
getRowClass = (context: RowClassArgs) => {
const className: any = {};
if (this.alternatingRowClass && context.index % 2 !== 0) {
className[this.alternatingRowClass] = true;
return className;
}
className[this.rowClass] = true;
return className;
};
/**
* Applies item cell style
*
* @param {*} dataItem
* @param {number} rowIndex
* @param {*} cellEl
* @param {number} columIndex
* @return {*} {*}
* @memberof GridViewComponent
*/
getBasicItemStyle(
dataItem: any,
rowIndex: number,
cellEl: any,
columIndex: number
): any {
if (dataItem.RowId !== undefined) {
const rowModel = this.wmService.core.getModel(dataItem.RowId);
/* c8 ignore else*/
if (rowModel?.Controls != undefined) {
const cellModel = this.wmService.core.getModel(
Object.keys(rowModel.Controls)[columIndex]
);
/* c8 ignore else*/
if (
this.isHyperLinkColumn(
dataItem.DataControlFields[columIndex]?.ContainingFieldType
)
) {
//Apply enable/disable style to hyperlink
const cellHyperLink = cellEl.querySelector('span > a');
this.applyStylesHyperLinkCell(cellHyperLink, cellModel);
}
this.applyCommonStyles(cellEl, cellModel);
}
}
//Call alternatingRowStyleFunction
this.getAlternatingRowStyle(rowIndex, cellEl);
}
/**
* Apply common styles to cells
*
* @param {*} element
* @param {*} cellModel
* @memberof GridViewComponent
*/
applyCommonStyles(element: any, cellModel: any) {
//Apply style based on common model properties
/* c8 ignore else*/
if (cellModel?.ForeColor !== undefined) {
//Apply color style based in forecolor property
const cellColor =
cellModel.ForeColor !== '' ? cellModel.ForeColor : '0, 0, 0';
this.render2.setStyle(element, 'color', 'rgb(' + cellColor + ')');
}
}
/**
* Apply styles to cells with colum type hyperlink
*
* @param {*} element
* @param {*} cellModel
* @memberof GridViewComponent
*/
applyStylesHyperLinkCell(element: any, cellModel: any) {
//Apply style based in enabled property
/* c8 ignore else*/
if (cellModel?.Enabled !== undefined) {
if (cellModel.Enabled) {
this.render2.setStyle(element, 'pointer-events', 'auto');
this.render2.setStyle(element, 'color', 'blue');
this.render2.setStyle(element, 'text-decoration', 'underline');
this.render2.setStyle(element, 'cursor', 'pointer');
} else {
this.render2.setStyle(element, 'pointer-events', 'none');
this.render2.setStyle(element, 'color', 'rgb(0, 0, 0)');
this.render2.setStyle(element, 'text-decoration', 'none');
this.render2.setStyle(element, 'cursor', 'not-allowed');
}
}
}
/**
* Applies the alternating row style
*
* @param {number} rowIndex the rowIndex
* @param {*} cellEl the html element
* @return {*} {*}
* @memberof GridViewComponent
*/
getAlternatingRowStyle(rowIndex: number, cellEl: any): any {
const tr = cellEl.closest('tr');
/* c8 ignore start */
if (this.alternatingRowStyle && rowIndex % 2 !== 0 && tr) {
this.render2.setStyle(
tr,
'background-color',
this.alternatingRowStyle?.BackColor ?? null
);
} /* c8 ignore stop */
}
/**
* Gets the row css class from the model
*
* @readonly
* @type {string}
* @memberof GridViewComponent
*/
headerCssClass(column: any): string {
return column.cssClass ?? this.model?.HeaderStyle?.CssClass ?? '';
}
/**
* Returns the column format.
*
* @param {*} col
* @return {*} {string}
* @memberof GridViewComponent
*/
getFormat(col: any): string {
return col.format ?? '';
}
/**
* Sets the correct format for the data received from the API.
*
* @memberof GridViewComponent
*/
itemsTypeFormatter(): void {
const colsWithDataFormat = this.columnsControls.filter(
(item) => item.format !== ''
);
for (const col of colsWithDataFormat) {
this.items.forEach((item) => {
/* c8 ignore else*/
if (typeof item[col.name] === 'string') {
if (Number(item[col.name])) {
item[col.name] = Number(item[col.name]);
} else {
const date = new Date(item[col.name]);
/* c8 ignore else*/
if (!isNaN(date.getTime())) {
item[col.name] = new Date(item.date);
}
}
}
});
}
}
/**
* Sets the model for each DataControlField component.
*
* @memberof GridViewComponent
*/
setControlFieldsModels(): void {
const models = [];
for (const col of this.columns) {
if (col.ContainingField) {
models.push(col.ContainingField);
}
}
if (
models.length > 0 &&
models.length === this.controlFieldChildren.length
) {
for (let i = 0; i < this.controlFieldChildren.length; i++) {
this.controlFieldChildren.toArray()[i].model = models[i];
}
}
this.columns = this.columns.filter((col) => !col.ContainingField);
this.setVisibleToDefaultColumns();
}
/**
* Sets the visible property to default columns (columns from API).
*
* @memberof GridViewComponent
*/
setVisibleToDefaultColumns(): void {
this.columns.forEach((col) => {
col['visible'] = true;
});
}
/**
* Determines if the DataControlField is an instance of the HyperLinkField Component.
*
* @param {DataControlFieldComponent} field
* @return {*} {field is HyperlinkFieldComponent}
* @memberof GridViewComponent
*/
isHyperLinkFieldComponent(
field: DataControlFieldComponent
): field is HyperlinkFieldComponent {
return field instanceof HyperlinkFieldComponent;
}
/**
* Determines if the DataControlField is an instance of the BoundField Component.
*
* @param {DataControlFieldComponent} field
* @return {*} {field is BoundFieldComponent}
* @memberof GridViewComponent
*/
isBoundFieldComponent(
field: DataControlFieldComponent
): field is BoundFieldComponent {
return field instanceof BoundFieldComponent;
}
/**
* Determines if the DataControlField is an instance of the TemplateField Component.
*
* @param {DataControlFieldComponent} field
* @return {*} {field is TemplateFieldComponent}
* @memberof GridViewComponent
*/
isTemplateFieldComponent(
field: DataControlFieldComponent
): field is TemplateFieldComponent {
return field instanceof TemplateFieldComponent;
}
/**
* Method to apply the HeaderStyles from the model property and return the style object
*
* @return {*} The style object
* @memberof GridViewComponent
*/
applyHeaderStylesFromModel(): any {
const style = {} as any;
style['text-align'] = this.getHeaderStylePropFromModel('VerticalAlign');
style['background-color'] = this.getHeaderStylePropFromModel('BackColor');
return style;
}
/**
* Sets the gridLines style to the cells of the grid
* This is called on the getCellStyle method
*
* @param {*} columnStyle
* @return {*} the object of the style with the borders applied
* @memberof GridViewComponent
*/
setGridLinesBorder(columnStyle: any): any {
switch (this.gridLines) {
case GridLines.None:
columnStyle['border'] = 'none';
break;
case GridLines.Vertical:
columnStyle['border-top'] = 'none';
columnStyle['border-bottom'] = 'none';
break;
case GridLines.Horizontal:
columnStyle['border-left'] = 'none';
columnStyle['border-right'] = 'none';
break;
default:
break;
}
return columnStyle;
}
/**
* Sets the pager style
*
* @return {*} {*}
* @memberof GridViewComponent
*/
/* c8 ignore start */
setPagerStyle(): any {
const style = new PagerStyleManager(this.pagerStyle).setPagerStyle();
const pagerElem = this.elem.nativeElement.querySelector('kendo-pager');
if (pagerElem && style) {
this.render2.setStyle(
pagerElem,
'background-color',
style['background-color']
);
this.render2.setStyle(pagerElem, 'border-color', style['border-color']);
this.render2.setStyle(pagerElem, 'border-width', style['border-width']);
this.render2.setStyle(pagerElem, 'color', style.color);
this.render2.setStyle(pagerElem, 'height', style.height);
this.render2.setStyle(pagerElem, 'width', style.width);
}
} /* c8 ignore stop */
/**
* Sets the header style
* Add e2e tests for this method
* @param colName
* @param {number} colIndex
* @param headerStyle
* @return {*} {*}
* @memberof GridViewComponent
*/
setHeaderStyleSortable(
colName: string,
colIndex: number,
headerStyle: any
): any {
const style = headerStyle;
if (this.isColumnSortable(colName, colIndex)) {
style['text-decoration'] = 'underline';
style['color'] = 'blue';
}
return style;
}
/**
* Sets the inner pager style
* Used to set the top property
* @return {*} {*}
* @memberof GridViewComponent
*/
setInnerPagerStyle(): any {
this.setPagerStyle();
return new PagerStyleManager(this.pagerStyle).setTop();
}
/**
* Returns true if the pager horizontal align is center
*
* @return {*} {boolean}
* @memberof PagerStyleManager
*/
isPagerCenteredHorizontaly(): boolean {
return (
this.pagerStyle?.HorizontalAlign != null &&
this.pagerStyle?.HorizontalAlign === PagerHorizontalAlign.Center
);
}
/**
* Returns true if the pager horizontal align is right
*
* @return {*} {boolean}
* @memberof GridViewComponent
*/
isPagerRightHorizontaly(): boolean {
return (
this.pagerStyle?.HorizontalAlign != null &&
this.pagerStyle?.HorizontalAlign === PagerHorizontalAlign.Right
);
}
/**
* Returns true if the pager horizontal align is left
*
* @return {*} {boolean}
* @memberof GridViewComponent
*/
isPagerLeftHorizontaly(): boolean {
return (
this.pagerStyle?.HorizontalAlign != null &&
this.pagerStyle?.HorizontalAlign === PagerHorizontalAlign.Left
);
}
/**
* Gets the respective tooltip text for a given row
* using the row id
*
* @param {string} rowId
* @return {*} {string}
* @memberof GridViewComponent
*/
getToolTipForRow(rowId: string): string {
const model = this.wmService.core?.getModel(rowId);
let toolTipText = '';
if (model && model.ToolTipText != null) {
toolTipText = model.ToolTipText;
}
return toolTipText;
}
/**
* Page Index Changing of gridview component
*
* @param {EventData} event
* @memberof GridViewComponent
*/
@serverEvent(
'PageIndexChanging',
GridViewComponent.PageIndexChangingExtractor
)
pageIndexChanging(event: EventData): void {
this.PageIndexChanging.emit(event);
}
/**
* Normalize the row index to access the data collection of the grid
*
* @param {number} rowIndex
* @return {*} {number}
* @memberof GridViewComponent
*/
normalizeRowIndex(rowIndex: number): number {
return this.allowPaging ? rowIndex % this.pageSize : rowIndex;
}
/**
* Handles the rowCommand event.
*
* @param {any} event
* @memberof GridViewComponent
*/
rowCommandHandler(event: any): void {
const eventData = new EventData(
event,
this.id,
GridViewComponent.rowCommandMapperId
);
eventData['args'] = {
CommandName: event.clientClickArgs.CommandName,
CommandArgument: event.clientClickArgs.CommandArgument,
CommandSource: event.id
};
this.triggerRowCommand(eventData);
}
/**
* Handles the client click events raised by the gridview internal button controls.
*
* @memberof GridViewComponent
*/
internalClickHandler() {
this.internalEventHandler.onButtonClick.subscribe((event) => {
this.rowCommandHandler(event);
});
}
/**
* Trigger the RowCommand Event on server side
*
* @param {*} event
* @memberof GridViewComponent
*/
@serverEvent('RowCommand', GridViewComponent.RowCommandExtractor)
triggerRowCommand(event: any): void {
this.OnRowCommand.emit({ source: this.model, e: event });
}
}
<kendo-grid *ngIf="model && (visible || emptyDataText)" [data]="gridView" [loading]="loading" [pageable]="allowPaging"
[pageSize]="pageSize" [skip]="skip" [sortable]="allowSorting" (sortChange)="sortChange($event)" [sort]="sort"
[scrollable]="scrollMode()" [rowHeight]="getRowHeight()" [height]="height" [selectable]="selectableSettings"
(cellClick)="cellClickHandler($event)" (dblclick)="doubleClick($event)" kendoGridSelectBy [selectedKeys]="[selectedIndex]" [ngClass]="class"
[rowClass]="getRowClass" [resizable]="true" [style.width]="gridWidth()" (pageChange)="pageChange($event)" [hideHeader]="hideHeader">
<ng-container *ngFor="let column of kendoColumns(); let i=index; trackBy: trackByColumn.bind(this)">
<kendo-grid-column *ngIf="column.visible" field="{{getColumnFieldName(column)}}" title="{{column.caption}}"
[width]="getColumnWidth(column)" [headerStyle]="getHeaderStyle(column, i)" [style]="getCellStyle(column)"
format="{{getFormat(column)}}" [sortable]="isColumnSortable(getColumnFieldName(column), i)"
[headerClass]="headerCssClass(column)">
<ng-template kendoGridCellTemplate let-dataItem let-rowIndex="rowIndex" let-columnIndex="columnIndex">
<div kendoTooltip filter="span" class="flex">
<ng-container *ngIf="isHyperLinkColumn(dataItem.DataControlFields[i]?.ContainingFieldType)">
<span #cellEl [title]="getToolTipForRow(dataItem.RowId)"
[ngStyle]="getBasicItemStyle(dataItem,rowIndex,cellEl,i)">
<a href="javascript:void(0)" (click)="hyperLinkFieldClickHandler(dataItem, i, rowIndex)">
{{getHyperLinkDisplayValue(rowIndex, i)}}
</a>
</span>
</ng-container>
<ng-container *ngIf="isDefaultColumn(dataItem.DataControlFields[i]?.ContainingFieldType)">
<span #cellEl [title]="getToolTipForRow(dataItem.RowId)"
[innerHTML]="getDisplayValue(dataItem[getColumnFieldName(column)], rowIndex, i)"
[ngStyle]="getBasicItemStyle(dataItem,rowIndex,cellEl,i)"></span>
</ng-container>
<ng-container
*ngIf="isTemplateColumn(dataItem.DataControlFields[i]?.ContainingFieldType) && areItemTemplateModelsLoaded(i)">
<div #cellEl [title]="getToolTipForRow(dataItem.RowId)" class="ItemTemplateItems" [ngStyle]="getAlternatingRowStyle(rowIndex,cellEl)">
<ng-container
*ngTemplateOutlet='getItemTemplate(i); context:{$implicit: getItemTemplateModel(rowIndex, i)}'>
</ng-container>
</div>
</ng-container>
</div>
</ng-template>
</kendo-grid-column>
<ng-template kendoGridNoRecordsTemplate>{{emptyDataText}}</ng-template>
</ng-container>
<ng-template kendoPagerTemplate>
<kendo-grid-spacer *ngIf="isPagerCenteredHorizontaly() || isPagerRightHorizontaly()"></kendo-grid-spacer>
<kendo-pager-prev-buttons></kendo-pager-prev-buttons>
<kendo-pager-numeric-buttons [buttonCount]="10" [ngStyle]="setInnerPagerStyle()"></kendo-pager-numeric-buttons>
<kendo-pager-next-buttons></kendo-pager-next-buttons>
<kendo-grid-spacer *ngIf="isPagerCenteredHorizontaly() || isPagerLeftHorizontaly()"></kendo-grid-spacer>
</ng-template>
</kendo-grid>
<ng-content></ng-content>
./gridview.component.scss
::ng-deep .k-cell-inner > span.k-link{
display: block;
}
::ng-deep .k-grid td a {
color: revert;
text-decoration: revert;
}
::ng-deep .ItemTemplateItems > * {
display: inline-block;
margin-right: 0.4em;
}
::ng-deep .k-grid td {
border-width: 0.1px !important;
padding-left: 10px;
}
::ng-deep .k-grid tr {
height: 28px !important;
}
::ng-deep .k-grid th {
font-weight: bold !important;
height: 28px !important;
padding-left: 10px !important;
padding-bottom: 10px !important;
}
::ng-deep .k-pager-numbers .k-link.k-state-selected {
background-color: rgba(225, 230, 237, 0.2) !important;
color: lightgray !important;
}
::ng-deep kendo-pager-numeric-buttons li {
border-color: lightgray !important;
border-style: solid !important;
border-width: 0.01px !important;
margin: 5px !important;
}
::ng-deep .k-pager-numbers .k-link {
color: black !important;
}
::ng-deep .k-grid-norecords {
pointer-events: none;
}
::ng-deep .k-grid-norecords td {
text-align: left;
}
::ng-deep .k-grid-content {
overflow: hidden;
}