import {path} from '../../environments/path';
import {AgGridLocale} from '../lang/ag-gridlocale';
import {IGridValidationErrors} from '../model/virtual/grid-validation-errors';
import {GridSelectEditorComponent} from '../grid-cellrenderer/grid-select/grid-select-editor/grid-select-editor.component';
import {GridSelectRendererComponent} from '../grid-cellrenderer/grid-select/grid-select-renderer/grid-select-renderer.component';
import {GridCheckboxRendererComponent} from '../grid-cellrenderer/grid-checkbox/grid-checkbox-renderer/grid-checkbox-renderer.component';
import {GridCheckboxEditorComponent} from '../grid-cellrenderer/grid-checkbox/grid-checkbox-editor/grid-checkbox-editor.component';
import {GridDateRendererComponent} from '../grid-cellrenderer/grid-date/grid-date-renderer/grid-date-renderer.component';
import {GridDateEditorComponent} from '../grid-cellrenderer/grid-date/grid-date-editor/grid-date-editor.component';
import {GridTextRendererComponent} from '../grid-cellrenderer/grid-text/grid-text-renderer/grid-text-renderer.component';
import {GridTextEditorComponent} from '../grid-cellrenderer/grid-text/grid-text-editor/grid-text-editor.component';
import {AgGridComponentConst} from './ag-grid-component-const';
import {GridInputRendererComponent} from '../grid-cellrenderer/grid-input/grid-input-renderer/grid-input-renderer.component';
import {GridInputEditorComponent} from '../grid-cellrenderer/grid-input/grid-input-editor/grid-input-editor.component';
import {GridBlockedRendererComponent} from '../grid-cellrenderer/grid-blocked/grid-blocked-renderer/grid-blocked-renderer.component';
import {GridBlockedEditorComponent} from '../grid-cellrenderer/grid-blocked/grid-blocked-editor/grid-blocked-editor.component';
import {Utils} from '../utils/utils';
export class AgGridComponent {
static readonly MIN_HEIGHT: number = 16;
public params: any;
public columnDefs: any[] = [];
public defaultColDef: {} = {};
public rowData: any[] = [];
public rowSelection: string;
public gridParamsColumnApi;
public gridParamsApi;
public apiAssetsPath: string;
public resetSearchBtn: boolean;
public localeText: {};
public frameworkComponents: {};
public bSizeColumnsToFit: boolean;
public gridErrors: IGridValidationErrors[];
public errorIndex: number;
public resetValueByError: boolean;
public errorMessage: string;
public nextAddedItemId: number;
/**
* Constructor
*/
constructor(bSizeColumnsToFit: boolean = true) {
AgGridComponentConst.setGridInputError();
this.rowData = [];
this.columnDefs = [];
this.rowSelection = 'multiple';
this.defaultColDef = {
editable: true
};
this.apiAssetsPath = path.path_assets;
this.frameworkComponents = {};
this.localeText = AgGridLocale.getLocale();
this.bSizeColumnsToFit = bSizeColumnsToFit;
this.gridErrors = [];
this.errorIndex = -1;
this.resetValueByError = false;
this.errorMessage = null;
this.nextAddedItemId = null;
this.frameworkComponents = {
gridSelectEditor: GridSelectEditorComponent,
gridSelectRenderer: GridSelectRendererComponent,
gridCheckboxRenderer: GridCheckboxRendererComponent,
gridCheckboxEditor: GridCheckboxEditorComponent,
gridDateRenderer: GridDateRendererComponent,
gridDateEditor: GridDateEditorComponent,
gridInputRenderer: GridInputRendererComponent,
gridInputEditor: GridInputEditorComponent,
gridTextRenderer: GridTextRendererComponent,
gridTextEditor: GridTextEditorComponent,
gridBlockedRenderer: GridBlockedRendererComponent,
gridBlockedEditor: GridBlockedEditorComponent
};
}
/**
* Callback on grid ready
*/
public onGridReady(params): void {
this.params = params;
this.gridParamsColumnApi = params.columnApi;
this.gridParamsApi = params.api;
// Set for cadasters
if (!this.bSizeColumnsToFit) {
const allColumnIds = [];
this.gridParamsColumnApi.getAllColumns().forEach((column) => {
allColumnIds.push(column.colId);
});
this.gridParamsColumnApi.autoSizeColumns(allColumnIds);
}
}
/**
* On row clicked
*/
public onRowClicked(e): void {
// Reset error message
AgGridComponentConst.setGridInputError();
this.errorMessage = null;
}
/**
* On cell editing stopped
*/
public onCellEditingStopped(e): void {
if (null !== AgGridComponentConst.gridInputError) {
this.errorMessage = AgGridComponentConst.gridInputError;
e.api.ensureIndexVisible(e.rowIndex, 'middle');
e.api.ensureColumnVisible(e.colDef.field.toString());
} else {
this.errorMessage = null;
}
}
/**
* Sizes columns to fit
*/
public onFirstDataRendered(params: any): void {
// Set for info components
if (this.bSizeColumnsToFit) {
params.api.sizeColumnsToFit();
}
}
/**
* Resizes grid
*/
public gridSizeChanged(params: any): void {
if (undefined !== this.gridParamsApi) {
this.gridParamsApi.sizeColumnsToFit();
}
}
/**
* Search Form
*/
public searchFormSubmit(params: any): void {
if (params.target.value !== '') {
this.resetSearchBtn = true;
this.gridParamsApi.setQuickFilter(params.target.value);
} else {
this.resetSearchBtn = false;
this.gridParamsApi.setQuickFilter(null);
}
}
/**
* Reset search input
*/
public resetSearch(e: any): void {
e.originalTarget[0].value = '';
this.resetSearchBtn = false;
this.gridParamsApi.setQuickFilter(null);
}
/**
* Stop editing state
*/
public stopEditing(): void {
this.params.api.stopEditing();
}
/**
* Configures scrollToService - https://www.npmjs.com/package/@nicky-lenaers/ngx-scroll-to
*/
public scrollTo(targetFieldName: string = null, lastFieldName: string = null): void {
if (null !== targetFieldName) {
if (null !== lastFieldName) {
// Scroll to last field first to ensure our target field name is on left-hand side
this.params.api.ensureColumnVisible(lastFieldName);
}
this.params.api.ensureColumnVisible(targetFieldName);
}
}
/**
* Cell renderer selector for individual cells with optional default parameters
*/
public cellRendererSelector(params: any): {} {
return AgGridComponentConst.cellRendererSelector(params);
}
/**
* Cell editor selector for individual cells
*/
public cellEditorSelector(params: any): {} {
return AgGridComponentConst.cellEditorSelector(params);
}
/**
* Validates grid
*/
public validateGrid(): boolean {
const oldErrors: IGridValidationErrors[] = this.gridErrors;
this.gridErrors = [];
this.errorIndex = -1;
const primaryColumns = this.params.api.columnController.primaryColumns;
const errorColumn: any[] = [];
const errors: IGridValidationErrors[] = [];
primaryColumns.forEach((value) => {
if (undefined !== value.colDef.cellEditorParams) {
if (undefined !== value.colDef.cellEditorParams.mandatory && true === value.colDef.cellEditorParams.mandatory) {
errorColumn.push(value.colDef.field);
}
}
});
errorColumn.forEach((value, i) => {
this.params.api.forEachNode((rowNode, index) => {
if (null === rowNode.data[value] || undefined === rowNode.data[value]) {
errors.push({
column: value,
row: index
});
}
});
});
this.gridErrors = errors;
if (this.gridErrors.length !== 0) {
if (oldErrors.length !== this.gridErrors.length) {
this.params.api.ensureIndexVisible(this.gridErrors[0].row, 'middle');
this.params.api.ensureColumnVisible(this.gridErrors[0].column);
}
}
return this.gridErrors.length === 0;
}
/**
* Jumps to error
*/
public jumpToError(direction: string): void {
const errorLength: number = this.gridErrors.length - 1;
// If any errors
if (errorLength >= 0) {
// if errorIndex is smaller or same as list of all errors
if (errorLength === 0) {
this.errorIndex = 0;
} else {
if (direction === 'next') {
this.errorIndex = this.errorIndex < errorLength ? this.errorIndex + 1 : 0;
} else {
this.errorIndex = this.errorIndex <= 0 ? errorLength : this.errorIndex - 1;
}
}
this.params.api.ensureIndexVisible(this.gridErrors[this.errorIndex].row, 'middle');
this.params.api.ensureColumnVisible(this.gridErrors[this.errorIndex].column);
} else {
// reset errorIndex if no errors
this.errorIndex = -1;
}
}
/**
* Shows input error
*/
public showInputError(positionIndex: number, field: string, oldValue: string, type: string): void {
this.resetValueByError = true;
this.params.api.clearFocusedCell();
this.params.api.ensureIndexVisible(positionIndex, 'middle');
this.params.api.ensureColumnVisible(field);
// Lifecycle hack
setTimeout(() => {
// Reset to old value
this.params.api.getRowNode(positionIndex).setDataValue(field, oldValue);
this.params.api.startEditingCell({
rowIndex: positionIndex,
colKey: field,
});
switch (type) {
case 'int':
this.errorMessage = 'Bitte geben Sie einen ganzzahligen Wert ein.';
break;
case 'float':
this.errorMessage = 'Bitte geben Sie einen dezimalen oder ganzzahligen Wert ein.';
break;
}
}, 10);
}
/**
* Add row to grid and returns position index
*/
public addRow(item: {}): number {
this.initNextAddedItemId();
const rowModel = this.gridParamsApi.rowModel;
// Note: default is last row
let addIndex: number = rowModel.rowsToDisplay.length + 1;
rowModel.rowsToDisplay.forEach((row, i) => {
if (row.selected === true) {
// Note: Add index is the row after selected row
addIndex = i + 1;
return;
}
});
this.gridParamsApi.updateRowData({
add: [item],
addIndex
});
return addIndex;
}
/**
* Removes selected rows
*/
public removeRows(): void {
this.initNextAddedItemId();
const selectedRows: {}[] = this.gridParamsApi.getSelectedRows();
this.gridParamsApi.updateRowData({remove: selectedRows});
}
/**
* Gets next row position
*/
public getNextRowPosition(): number {
return this.gridParamsApi.rowModel.length + 1;
}
/**
* inits next dummy id for next added entry, if necessary
*/
private initNextAddedItemId(): void {
if (this.nextAddedItemId === null) {
this.nextAddedItemId = (this.rowData.length + 1) * -1;
}
}
/**
* Returns dummy id for added entry
*/
public getNextAddedItemId(): number {
this.initNextAddedItemId();
const res: number = this.nextAddedItemId;
this.nextAddedItemId--;
return res;
}
/**
* column resize event
*/
public onColumnResized(event): void {
if (event.finished !== false) {
event.api.setHeaderHeight(AgGridComponent.MIN_HEIGHT);
const headerCells = Array.from(document.querySelectorAll('.content .ag-header-cell-label'));
let minHeight: number = AgGridComponent.MIN_HEIGHT;
headerCells.forEach(cell => {
minHeight = Math.max(minHeight, cell.scrollHeight);
});
// set header height to calculated height + padding (top: 8px, bottom: 8px)
event.api.setHeaderHeight(minHeight + 16);
}
if (event.finished) {
this.gridParamsApi.resetRowHeights();
}
}
/**
* Renders colored dot
*/
public dotRenderer(params): string {
return '';
}
/**
* Renders email address
*/
public emailRenderer(params): string {
return null !== params.value ? '' + params.value + '' : '';
}
/**
* Renders phone number
*/
public phoneRenderer(params): string {
return null !== params.value ? '' + params.value + '' : '';
}
/**
* Renders phone number
*/
public urlRenderer(params): string {
return null !== params.value ? '' + params.value + '' : '';
}
/**
* option renderer
*/
public optionRenderer(params): string {
return params.data.is_option_meeting ? 'Ja' : '';
}
/**
* address renderer
*/
public addressRenderer(params): string {
let address = '';
if (params.data.typeType === 'visit') {
const street = params.data.street !== null ? params.data.street : '';
const streetNo = params.data.street_no !== null ? params.data.street_no : '';
const zip = params.data.zip !== null ? params.data.zip : '';
const city = params.data.city !== null ? params.data.city : '';
let br = '';
if (zip !== null || city !== null) {
br = '
';
}
address = street + ' ' + streetNo + ' ' + br + zip + ' ' + city;
}
return address;
}
/**
* participants renderer
*/
public participantsRenderer(params): string {
let participantNames = '';
params.data.participants.forEach((value) => {
participantNames += params.data.that.appService.getConfig().vc_user_by_id[value.participant_user_id].firstname +
' ' + params.data.that.appService.getConfig().vc_user_by_id[value.participant_user_id].lastname + '
';
});
return participantNames;
}
/**
* Time renderer
*/
public timeRenderer(params): string {
return Utils.getDateTimeToDisplay(params.value, false, true);
}
/**
* Date renderer
*/
public dateRenderer(params): string {
return Utils.getDateTimeToDisplay(params.value);
}
/**
* Datetime renderer
*/
public dateTimeRenderer(params): string {
return Utils.getDateTimeToDisplay(params.value, true, true);
}
/**
* Date comparator
*/
public dateComparator(date1, date2, callbackCheck: boolean = true) {
if (date1 === null && date2 === null) {
return 0;
}
if (date1 === null) {
return -1;
}
if (date2 === null) {
return 1;
}
const stamp1: number = Utils.getParsedDate(date1);
const stamp2: number = Utils.getParsedDate(date2);
return stamp1 < stamp2 ? 1 : stamp1 === stamp2 ? 0 : -1;
}
}