Component Code
import { CustomNoiseActionKeyValueDetails } from './../parameter-mapping.interface';
import { Component, OnInit, ViewChild, OnChanges, Input } from '@angular/core';
import { CommandModel, EditSettingsModel, GridComponent, IEditCell } from '@syncfusion/ej2-angular-grids';
import { TranslateService } from '@ngx-translate/core';
import { MatLegacyDialog as MatDialog } from '@angular/material/legacy-dialog';
import { FilteringEventArgs } from '@syncfusion/ej2-dropdowns';
import { EmitType } from '@syncfusion/ej2-base';
import {
CustomNoiseActionModel,
LnFromExternalInterfaceMappingModel,
LNModeMappingSaveOrUpdate
} from '../parameter-mapping.interface';
import { ParameterMappingService } from './../services/parameter-mapping.service';
import { LowNoiseHelperService } from '../../low-noise-helper.service';
import { CustomDialogComponent } from './../../../../shared/custom-dialog/custom-dialog/custom-dialog.component';
import { ComponentSettingsModel } from '../../../../shared/shared-interfaces/wps-settings.interface';
import {
ToastrMessageType,
ToastrMessageWrapperService
} from './../../../../shared/services/toastr-message-wrapper.service';
import { StoredValues } from '../../../../shared/stored-value-service';
import { WindowResizeService } from '../../../../shared/services/window-resize.service';
import { filteredData } from '../../../../../main/shared/services/dropdown-filtering.service';
@Component({
selector: 'external-noise-mode-mapping',
templateUrl: './external-noise-mode-mapping.component.html'
})
export class ExternalNoiseModeMappingComponent implements OnInit, OnChanges {
@ViewChild('grid') grid: GridComponent;
@Input() settings: ComponentSettingsModel[];
lnModeMappingList: LnFromExternalInterfaceMappingModel[];
editSettings: EditSettingsModel;
commands: CommandModel[];
isSlwEnabled = false;
isFanModeEnabled = false;
lnModeSettingValue: number;
lnModeDetails = [];
customNoiseActionDetails: CustomNoiseActionModel;
gridValidationRules: object;
selectedCustomNoiseActionDetails: LNModeMappingSaveOrUpdate;
lnModeDropDownForGrid: IEditCell;
valueAccess = (field: string, data: object): string => {
if (data[field] !== '') {
return this.translate.instant(data[field]);
}
return data[field];
};
noiseReduction: CustomNoiseActionKeyValueDetails[] = [];
slwFallback: CustomNoiseActionKeyValueDetails[] = [];
fanMode: CustomNoiseActionKeyValueDetails[] = [];
gridHeight: number;
private readonly pageExtraHeight = 322;
private enterFlag = false;
constructor(
private readonly parameterMappingService: ParameterMappingService,
private readonly lowNoiseHelperService: LowNoiseHelperService,
private readonly translate: TranslateService,
private readonly dialog: MatDialog,
private readonly toastr: ToastrMessageWrapperService,
private readonly windowResizeService: WindowResizeService
) {}
ngOnChanges(): void {
this.isSlwEnabled = Boolean(
JSON.parse(
this.settings.find(settings => settings.Name === 'WebWps' && settings.Key === 'EnableSLWNoiseReduction').Value
)
);
this.isFanModeEnabled = Boolean(
JSON.parse(
this.settings.find(settings => settings.Name === 'WebWps' && settings.Key === 'EnableLowNoiseFanMode').Value
)
);
this.lnModeSettingValue = +this.settings.find(
settings => settings.Name === 'WebWps' && settings.Key === 'LowNoiseModesForExternalInterfaces'
).Value;
this.getLnModeValues();
}
ngOnInit(): void {
this.windowResizeService.titleAreaHeightChanged$.subscribe(() => {
this.onresize();
});
window.addEventListener('resize', this.onresize.bind(this));
this.editSettings = { allowDeleting: true, allowAdding: true, mode: 'Normal' };
this.commands = [
{ type: 'Delete', buttonOption: { cssClass: 'e-flat', iconCss: 'e-delete e-icons' } },
{ type: 'Save', buttonOption: { iconCss: 'e-icons e-update', cssClass: 'e-flat' } },
{ type: 'Cancel', buttonOption: { iconCss: 'e-icons e-cancel-icon', cssClass: 'e-flat' } }
];
this.gridValidationRules = { required: true };
this.getCustomNoiseActionDetails();
this.getLnModeMappingDetails();
}
public addNewLnModeMappings(): void {
this.setDefaultMappingValuesForSave();
this.grid.addRecord();
}
public onGridActionBegin(args): void {
this.onGridSaveClick(args);
this.onDeleteClick(args);
this.enterFlag = false;
}
public onGridActionComplete(args): void {
if (args.requestType === 'save') {
const lnModeMappings: LNModeMappingSaveOrUpdate = {
lnMode: this.selectedCustomNoiseActionDetails.lnMode,
noiseReductionId: this.selectedCustomNoiseActionDetails.noiseReductionId,
slwFallbackActionId: this.selectedCustomNoiseActionDetails.slwFallbackActionId,
fanModeActionId: this.selectedCustomNoiseActionDetails.fanModeActionId
};
this.saveOrUpdateLNModeMappings(lnModeMappings);
}
}
public commandClick(args): void {
if (args.commandColumn.type === 'Save') {
this.enterFlag = true;
}
}
public onNoiseReductionChange(args: any): void {
this.selectedCustomNoiseActionDetails.noiseReductionId = args.value;
}
public onSlwFallbackChange(args: any): void {
this.selectedCustomNoiseActionDetails.slwFallbackActionId = args.value;
}
public onFanModeChange(args: any): void {
this.selectedCustomNoiseActionDetails.fanModeActionId = args.value;
}
public onLnModeValueChange(args: any): void {
this.selectedCustomNoiseActionDetails.lnMode = args.value;
}
public onDataBind(): void {
this.onresize();
}
public onFilter: EmitType<FilteringEventArgs> = (e: FilteringEventArgs, source, columnName): void => {
filteredData(e, source, columnName);
};
private onresize(): void {
if (this.grid && this.lnModeMappingList?.length > 0) {
this.grid.height = window.innerHeight - this.pageExtraHeight - this.windowResizeService.titleHeight;
if (this.lnModeMappingList.length * this.grid.getRowHeight() < this.grid.height) {
this.grid.height = 'auto';
}
}
}
private onGridSaveClick(args): void {
if (args.requestType === 'save' && args.target === undefined && !this.enterFlag) {
args.cancel = true;
}
}
private onDeleteClick(args): void {
if (args.requestType === 'delete') {
args.cancel = true;
const dialogText = `Delete low noise mode ${args.data[0].lnMode} mapping?`;
const confirmDialog = this.dialog.open(
CustomDialogComponent,
this.lowNoiseHelperService.getCustomDialog(dialogText, '250px', false, 'Delete', 'Cancel')
);
confirmDialog.afterClosed().subscribe(resp => {
if (resp) {
this.deleteLnModeMapping(args.data[0].lnMode);
}
});
}
}
private getLnModeValues(): void {
for (let i = 0; i < this.lnModeSettingValue; i++) {
this.lnModeDetails.push(i + 1);
}
}
private getCustomNoiseActionDetails(): void {
this.parameterMappingService.getCustomNoiseActionDetails().subscribe(
response => {
this.customNoiseActionDetails = response;
},
error => {
this.lowNoiseHelperService.toasterAndErrorLog('Error in loading custom noise action details!', error);
}
);
}
private getLnModeMappingDetails(): void {
this.parameterMappingService.getLnModeMappingDetails().subscribe(
response => {
this.lnModeMappingList = response;
this.gridHeight = window.innerHeight - this.pageExtraHeight - this.windowResizeService.titleHeight;
},
error => {
this.lowNoiseHelperService.toasterAndErrorLog('Error in loading LNMode mapping details!', error);
}
);
}
private saveOrUpdateLNModeMappings(mappings: LNModeMappingSaveOrUpdate): void {
this.parameterMappingService
.saveOrUpdateLNModeMapping(mappings)
.subscribe(
() => {
this.toastr.displayMessage(
this.translate.instant('Low noise mode mappings saved/updated successfully!'),
ToastrMessageType.SUCCESS
);
},
error => {
this.lowNoiseHelperService.toasterAndErrorLog('Error in saving/updating low noise mode mappings!', error);
}
)
.add(() => this.getLnModeMappingDetails());
}
private deleteLnModeMapping(lnMode: number): void {
this.parameterMappingService.deleteLNModeMapping(lnMode).subscribe(
response => {
if (!response) {
this.toastr.displayMessage(
this.translate.instant('Cannot delete the selected mapping as the mapping is in use!'),
ToastrMessageType.WARNING
);
} else {
this.toastr.displayMessage(
this.translate.instant('Low Noise mode mapping deleted successfully!'),
ToastrMessageType.SUCCESS
);
}
this.getLnModeMappingDetails();
},
error => {
this.lowNoiseHelperService.toasterAndErrorLog('Error in deleting low noise mode mapping!', error);
}
);
}
private setDefaultMappingValuesForSave(): void {
this.selectedCustomNoiseActionDetails = {
lnMode: null,
noiseReductionId: null,
slwFallbackActionId: -1,
fanModeActionId: -1
};
}
}
Unit Test Case
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { ReactiveFormsModule } from '@angular/forms';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { CommonModule } from '@angular/common';
import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations';
import { NGXLogger } from 'ngx-logger';
import { TranslateFakeLoader, TranslateLoader, TranslateModule } from '@ngx-translate/core';
import SpyObj = jasmine.SpyObj;
import { Observable, of, throwError } from 'rxjs';
import { MatLegacyDialog as MatDialog } from '@angular/material/legacy-dialog';
import { WpsLoggerService } from '../../../../core/services/wps-logger.service';
import { ToastrMessageWrapperService } from '../../../../shared/services/toastr-message-wrapper.service';
import { SyncfusionModule } from '../../../../../app.syncfusion.module';
import { ExternalNoiseModeMappingComponent } from './external-noise-mode-mapping.component';
import { LowNoiseParameterMapping } from './../../../../../fake-db/low-noise-parameter-mapping';
import { MasterData } from './../../../../../fake-db/masterdata';
import { ParameterMappingService } from './../services/parameter-mapping.service';
import { WindowResizeService } from 'app/main/shared/services/window-resize.service';
describe('ExternalNoiseModeMappingComponent', () => {
let component: ExternalNoiseModeMappingComponent;
let fixture: ComponentFixture<ExternalNoiseModeMappingComponent>;
let logger: SpyObj<WpsLoggerService>;
let toastrMessageService: SpyObj<ToastrMessageWrapperService>;
let messageService: ToastrMessageWrapperService;
let wpsLoggerService: WpsLoggerService;
let parameterMappingService: ParameterMappingService;
let windowResizeService: WindowResizeService;
const responseObject = { dialogClickStatus: 'Ok' };
const dialogRefStub = {
afterClosed(): Observable<any> {
return of(responseObject);
}
};
const dialogStub = { open: (): any => dialogRefStub };
beforeEach(
waitForAsync(() => {
toastrMessageService = jasmine.createSpyObj(ToastrMessageWrapperService.name, ['displayMessage']);
TestBed.configureTestingModule({
declarations: [ExternalNoiseModeMappingComponent],
imports: [
CommonModule,
ReactiveFormsModule,
HttpClientTestingModule,
RouterTestingModule,
SyncfusionModule,
BrowserAnimationsModule,
NoopAnimationsModule,
TranslateModule.forRoot({
loader: { provide: TranslateLoader, useClass: TranslateFakeLoader }
})
],
schemas: [NO_ERRORS_SCHEMA],
providers: [
HttpClientTestingModule,
{ provide: NGXLogger, useValue: logger },
{ provide: ToastrMessageWrapperService, useValue: toastrMessageService },
{ provide: MatDialog, useValue: dialogStub }
]
}).compileComponents();
})
);
beforeEach(() => {
fixture = TestBed.createComponent(ExternalNoiseModeMappingComponent);
wpsLoggerService = fixture.debugElement.injector.get(WpsLoggerService);
messageService = fixture.debugElement.injector.get(ToastrMessageWrapperService);
parameterMappingService = fixture.debugElement.injector.get(ParameterMappingService);
windowResizeService = fixture.debugElement.injector.get(WindowResizeService);
component = fixture.componentInstance;
fixture.detectChanges();
component.settings = MasterData.componentSettings;
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('logs error while getting details for component settings,custom noise action details and LNMode mappings on load of the page', () => {
spyOn(wpsLoggerService, 'error');
spyOn(parameterMappingService, 'getCustomNoiseActionDetails').and.returnValue(
throwError({
status: 500,
statusText: 'InternalServerError',
url: '/path'
})
);
spyOn(parameterMappingService, 'getLnModeMappingDetails').and.returnValue(
throwError({
status: 500,
statusText: 'InternalServerError',
url: '/path'
})
);
component.ngOnInit();
fixture.detectChanges();
expect(parameterMappingService.getCustomNoiseActionDetails).toHaveBeenCalled();
expect(parameterMappingService.getLnModeMappingDetails).toHaveBeenCalled();
expect(wpsLoggerService.error).toHaveBeenCalled();
expect(messageService.displayMessage).toHaveBeenCalledWith('Error in loading custom noise action details!', -1);
expect(messageService.displayMessage).toHaveBeenCalledWith('Error in loading LNMode mapping details!', -1);
});
it('logs error while deleting lnMode mapping', () => {
const args = {
requestType: 'delete',
data: [
{
lnMode: 1
}
]
};
spyOn(wpsLoggerService, 'error');
spyOn(parameterMappingService, 'deleteLNModeMapping').and.returnValue(
throwError({
status: 500,
statusText: 'InternalServerError',
url: '/path'
})
);
component.onGridActionBegin(args);
fixture.detectChanges();
expect(parameterMappingService.deleteLNModeMapping).toHaveBeenCalled();
expect(wpsLoggerService.error).toHaveBeenCalled();
expect(messageService.displayMessage).toHaveBeenCalledWith('Error in deleting low noise mode mapping!', -1);
});
it('logs error while saving/updating lnMode mapping', () => {
const args = {
requestType: 'save',
data: [
{
lnMode: 1
}
],
target: undefined,
commandColumn: { type: 'Save' }
};
const noiseReduction = { value: '201' };
const slwFallBack = { value: '202' };
const fanMode = { value: '205' };
spyOn(wpsLoggerService, 'error');
spyOn(parameterMappingService, 'saveOrUpdateLNModeMapping').and.returnValue(
throwError({
status: 500,
statusText: 'InternalServerError',
url: '/path'
})
);
component.addNewLnModeMappings();
component.onNoiseReductionChange(noiseReduction);
component.onSlwFallbackChange(slwFallBack);
component.onFanModeChange(fanMode);
component.commandClick(args);
component.onGridActionBegin(args);
component.onGridActionComplete(args);
fixture.detectChanges();
expect(parameterMappingService.saveOrUpdateLNModeMapping).toHaveBeenCalled();
expect(wpsLoggerService.error).toHaveBeenCalled();
expect(messageService.displayMessage).toHaveBeenCalledWith('Error in saving/updating low noise mode mappings!', -1);
});
it('should get component settings,custom noise action details and LNMode mappings on load of the page', () => {
spyOn(parameterMappingService, 'getCustomNoiseActionDetails').and.returnValue(
of(LowNoiseParameterMapping.CustomNoiseActionDetails)
);
spyOn(parameterMappingService, 'getLnModeMappingDetails').and.returnValue(
of(LowNoiseParameterMapping.LnFromExternalInterfaceMappingDetails)
);
component.settings = MasterData.componentSettings;
component.ngOnChanges();
component.ngOnInit();
fixture.detectChanges();
expect(parameterMappingService.getCustomNoiseActionDetails).toHaveBeenCalled();
expect(parameterMappingService.getLnModeMappingDetails).toHaveBeenCalled();
expect(component.isSlwEnabled).toEqual(true);
expect(component.isFanModeEnabled).toEqual(false);
expect(component.lnModeSettingValue).toEqual(10);
expect(component.lnModeDetails).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
expect(component.customNoiseActionDetails).toEqual(LowNoiseParameterMapping.CustomNoiseActionDetails);
expect(component.lnModeMappingList).toEqual(LowNoiseParameterMapping.LnFromExternalInterfaceMappingDetails);
});
it('Initialize slw and fanmode', () => {
component.settings = MasterData.componentSettings;
component.ngOnChanges();
expect(component.isSlwEnabled).toEqual(true);
});
it('should delete selected lnMode mapping', () => {
const args = {
requestType: 'delete',
data: [
{
lnMode: 1
}
]
};
spyOn(parameterMappingService, 'deleteLNModeMapping').and.returnValue(of({ message: 'Success' }));
component.onGridActionBegin(args);
fixture.detectChanges();
expect(parameterMappingService.deleteLNModeMapping).toHaveBeenCalled();
expect(messageService.displayMessage).toHaveBeenCalledWith('Low Noise mode mapping deleted successfully!', 1);
});
it('should save/updating lnMode mapping based on selected settings', () => {
const args = {
requestType: 'save',
data: [
{
lnMode: 1
}
],
target: undefined,
commandColumn: { type: 'Save' }
};
const noiseReduction = { value: '201' };
const slwFallBack = { value: '202' };
const fanMode = { value: '205' };
spyOn(parameterMappingService, 'saveOrUpdateLNModeMapping').and.returnValue(of({ message: 'Success' }));
component.addNewLnModeMappings();
component.onNoiseReductionChange(noiseReduction);
component.onSlwFallbackChange(slwFallBack);
component.onFanModeChange(fanMode);
component.commandClick(args);
component.onGridActionBegin(args);
component.onGridActionComplete(args);
fixture.detectChanges();
expect(parameterMappingService.saveOrUpdateLNModeMapping).toHaveBeenCalled();
expect(messageService.displayMessage).toHaveBeenCalledWith(
'Low noise mode mappings saved/updated successfully!',
1
);
});
});
Package
"dependencies": {
"@angular-devkit/build-angular": "^15.2.11",
"@angular/animations": "^15.2.10",
"@angular/cdk": "^15.2.9",
"@angular/cli": "^15.2.11",
"@angular/common": "^15.2.10",
"@angular/compiler": "^15.2.10",
"@angular/compiler-cli": "^15.2.10",
"@angular/core": "^15.2.10",
"@angular/flex-layout": "^15.0.0-beta.42",
"@angular/forms": "^15.2.10",
"@angular/localize": "^15.2.10",
"@angular/material": "^15.2.9",
"@angular/material-moment-adapter": "^15.2.9",
"@angular/platform-browser": "^15.2.10",
"@angular/platform-browser-dynamic": "^15.2.10",
"@angular/router": "^15.2.10",
"@microsoft/signalr": "^6.0.0",
"@ngx-translate/core": "^14.0.0",
"@ngx-translate/http-loader": "^4.0.0",
"@sgre/auth-service": "^5.0.0",
"@sgre/utilities": "^4.1.0",
"@syncfusion/ej2-angular-base": "^24.2.3",
"@syncfusion/ej2-angular-buttons": "^24.2.7",
"@syncfusion/ej2-angular-calendars": "^24.2.9",
"@syncfusion/ej2-angular-dropdowns": "^24.2.9",
"@syncfusion/ej2-angular-grids": "^24.2.9",
"@syncfusion/ej2-angular-inputs": "^24.2.9",
"@syncfusion/ej2-angular-lists": "^24.2.8",
"@syncfusion/ej2-angular-navigations": "^24.2.8",
"@syncfusion/ej2-angular-notifications": "^24.2.4",
"@syncfusion/ej2-angular-popups": "^24.2.10",
"@syncfusion/ej2-base": "^24.2.8",
"@syncfusion/ej2-data": "^24.2.3",
"@syncfusion/ej2-dropdowns": "^24.2.9",
"@syncfusion/ej2-navigations": "^24.2.8",
"angular-highcharts": "^15.0.1",
"angular-in-memory-web-api": "^0.9.0",
"angular-oauth2-oidc": "^15.0.1",
"classlist.js": "^1.1.20150312",
"compare-versions": "^3.6.0",
"core-js": "^2.6.11",
"crypto-js": "^4.1.1",
"file-saver": "^2.0.5",
"gojs": "2.2.12",
"gojs-angular": "2.0.4",
"highcharts": "^11.4.0",
"leaflet": "^1.7.1",
"lodash": "^4.17.21",
"moment": "^2.29.1",
"ngx-infinite-scroll": "^7.2.0",
"ngx-logger": "^4.2.0",
"ngx-toastr": "^15.2.2",
"perfect-scrollbar": "^1.5.0",
"rxjs": "^6.6.3",
"tslib": "^2.0.0",
"web-animations-js": "^2.3.2",
"xlsx": "^0.15.6",
"zone.js": "~0.11.4"
},
"devDependencies": {
"@angularclass/hmr": "^2.1.3",
"@ngneat/spectator": "^6.1.3",
"@types/crypto-js": "^4.1.1",
"@types/jasmine": "~3.6.0",
"@types/jasminewd2": "^2.0.8",
"@types/lodash": "^4.14.186",
"@types/node": "^12.11.1",
"@typescript-eslint/eslint-plugin": "^2.34.0",
"@typescript-eslint/parser": "^2.34.0",
"codelyzer": "^6.0.0",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.15.0",
"eslint-plugin-prettier": "^3.1.3",
"jasmine-core": "~3.8.0",
"jasmine-spec-reporter": "~5.0.0",
"karma": "^6.3.9",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "^2.1.0",
"karma-coverage-istanbul-reporter": "~3.0.2",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "^1.7.0",
"karma-requirejs": "^1.1.0",
"karma-spec-reporter": "0.0.32",
"prettier": "^1.19.1",
"protractor": "~7.0.0",
"ts-node": "~7.0.0",
"tslint": "~6.1.0",
"typescript": "~4.9.5"
}
Error Message