blob: 3fd7afed38ed011e67149c82055de49c802d2e09 [file] [log] [blame]
/*
******************************************************************************
* Copyright © 2018 PTA GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
******************************************************************************
*/
import {
Component, OnInit, Input, OnChanges, SimpleChanges, ViewChild, AfterViewChecked,
ElementRef, OnDestroy, ChangeDetectorRef, AfterViewInit
} from '@angular/core';
import { SingleGridMeasure } from '../../model/single-grid-measure';
import { Step } from '../../model/step';
import * as X2JS from '../../../assets/js/xml2json.min.js';
import { ErrorType } from '../../common/enums';
import { CimCacheService } from '../../services/cim-cache.service';
import { PowerSystemResource } from './../../model/power-system-resource';
import { FormGroup } from '@angular/forms';
import { SessionContext } from './../../common/session-context';
import { Subscription } from 'rxjs/Subscription';
import { TreeModel, Tree } from 'ng2-tree';
import { TreeModelImpl } from './../../model/TreeModelImpl';
import { ToasterMessageService } from '../../services/toaster-message.service';
@Component({
selector: 'app-step',
templateUrl: './step.component.html',
styleUrls: ['./step.component.css']
})
export class StepComponent implements OnInit, OnChanges, OnDestroy, AfterViewChecked, AfterViewInit {
@Input() isReadOnlyForm: boolean;
@Input() dateTimePattern: string;
@Input() dateFormatLocale: string;
@Input() isCollapsible = true;
@Input() singleGridMeasure: SingleGridMeasure;
form: HTMLFormElement;
readOnlyForm: boolean;
stepFormValid: boolean;
isStatusCollapsed = true;
storageInProgress: boolean;
step: Step = new Step();
currentPowerSystemResourceDB: PowerSystemResource;
stepAffectedResourcesString: PowerSystemResource;
stepAffectedResourcesGroupList = [''];
stepAffectedResourcesList: Array<PowerSystemResource> = [];
subscription: Subscription;
tmpPowerSystemResource: PowerSystemResource;
inactiveFields: Array<string> = [];
treeIdCounter = 1;
tree: TreeModel = { value: '' };
isTreeAvailable = false;
@ViewChild('treeComponent') treeComponent;
@ViewChild('stepFormContainer') stepFormCotainer: ElementRef;
@ViewChild('stepForm') stepForm: FormGroup;
constructor(private cimCacheService: CimCacheService,
private sessionContext: SessionContext,
private toasterMessageService: ToasterMessageService) { }
ngOnInit() {
this.inactiveFields = this.sessionContext.getInactiveFields();
this.getRessourceTypes();
this.currentPowerSystemResourceDB = this.singleGridMeasure.powerSystemResource;
}
ngAfterViewInit() {
this.initInactiveFields();
}
ngAfterViewChecked() {
if (this.stepForm) {
this.step._isValide = this.stepForm.valid;
}
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['isReadOnlyForm']) {
this.readOnlyForm = changes['isReadOnlyForm'].currentValue;
this.initInactiveFields();
}
}
public initInactiveFields() {
const el: HTMLElement = this.stepFormCotainer.nativeElement as HTMLElement;
const fields = el.querySelectorAll('*[id]');
for (let index = 0; index < fields.length; index++) {
const field = fields[index];
if (this.readOnlyForm || this.isFieldInactive(field['id'])) {
field.setAttribute('disabled', 'disabled');
} else {
field.removeAttribute('disabled');
}
}
}
private isFieldInactive(fieldName: string): boolean {
return this.inactiveFields.filter(field => field === fieldName).length > 0;
}
ngOnDestroy() {
}
public onUseRessourceBtnClick(selectedVal: any) {
if (selectedVal) {
this.step.switchingObject = selectedVal;
}
}
public processAddStep() {
if (!this.isStepEmpty()) {
const stepDeepCopy = JSON.parse(JSON.stringify(this.step));
stepDeepCopy.id = -1;
this.storageInProgress = true;
if (!this.singleGridMeasure.listSteps || this.singleGridMeasure.listSteps.length === 0) {
this.singleGridMeasure.listSteps = new Array();
stepDeepCopy.sortorder = 1;
} else {
// stepDeepCopy.sortorder = this.singleGridMeasure.listSteps.length + 1;
stepDeepCopy.sortorder = this.singleGridMeasure.listSteps[this.singleGridMeasure.listSteps.length - 1].sortorder + 1;
}
/* A simple push on liststeps (this.singleGridMeasure.listSteps.push(stepDeepCopy)) doesn't
trigger Angular to refresh the view-model. This is why you have to use the following way
which creates a "new" array (copy of the old) and appends it. */
this.singleGridMeasure.listSteps = [...this.singleGridMeasure.listSteps, stepDeepCopy];
this.storageInProgress = false;
} else {
this.toasterMessageService.showWarn('Bitte alle Felder in Schrittsequenz aufüllen!');
}
}
onStepFormValidation(valid: boolean) {
this.step._isValide = valid;
}
isStepEmpty() {
if (!this.step.switchingObject || !this.step.targetState || !this.step.presentState
|| !this.step.presentTime || !this.step.type || !this.step.operator) {
return true;
} else {
return false;
}
}
onChangeResourceGroup(val) {
if (val) {
this.stepAffectedResourcesList = [];
this.getRessourceTypesWithType(val);
} else {
this.stepAffectedResourcesList = [];
this.isTreeAvailable = false;
}
}
private getRessourceTypes() {
this.cimCacheService.getRessourceTypes().subscribe(res => {
this.processRessourceTypesResponse(res);
},
error => {
// this.messageService.emitError('CimCache', ErrorType.retrieve);
this.toasterMessageService.showError(ErrorType.retrieve, 'CimCache');
console.log(error);
});
}
private async getRessourceTypesWithType(value: string) {
const newTreeModel: TreeModel = new TreeModelImpl();
const xmlStringRes = await this.cimCacheService.getRessourcesWithType(value).toPromise().catch(error => {
// this.messageService.emitError('CimCache', ErrorType.retrieve);
this.toasterMessageService.showError(ErrorType.retrieve, 'CimCache');
});
this.stepAffectedResourcesList = this.processRessourceWithTypeResponse(xmlStringRes);
this.tmpPowerSystemResource = this.stepAffectedResourcesList[0];
this.treeIdCounter = 1;
const newTreeChilds = await this.prepareTreeModel(this.stepAffectedResourcesList);
newTreeModel.children = newTreeChilds;
this.tree = newTreeModel;
}
convertXmlToJsonObj(xml: string) {
return new X2JS().xml_str2json(xml);
}
processRessourceWithTypeResponse(res: string): Array<PowerSystemResource> {
if (!res) {
return;
}
const jsonObj = this.convertXmlToJsonObj(res);
const powerSystemResources = jsonObj.ResponseMessage.Payload.PowerSystemResources;
const powerSystemResourceRetList = new Array<PowerSystemResource>();
/* tslint:disable */
for (const prop in powerSystemResources) {
const anonymousPowerSystemResources = powerSystemResources[prop];
if (Array.isArray(anonymousPowerSystemResources)) {
anonymousPowerSystemResources.forEach(element => {
const powerSystemResource = new PowerSystemResource();
powerSystemResource.cimId = element.mRID;
powerSystemResource.cimName = element.name;
powerSystemResource.cimDescription = element.description;
powerSystemResourceRetList.push(powerSystemResource);
});
} else {
const powerSystemResource = new PowerSystemResource();
powerSystemResource.cimId = anonymousPowerSystemResources.mRID;
powerSystemResource.cimName = anonymousPowerSystemResources.name;
powerSystemResource.cimDescription = anonymousPowerSystemResources.description;
powerSystemResourceRetList.push(powerSystemResource);
}
}
if (powerSystemResourceRetList.length === 0) {
// keine Daten "Objekt"
const powerSystemResource = new PowerSystemResource();
powerSystemResource.cimId = '-1';
powerSystemResource.cimName = 'keine Daten';
powerSystemResourceRetList.push(powerSystemResource);
}
/* tslint:enable */
return powerSystemResourceRetList;
}
handleSelected(tree: Tree) {
this.step.switchingObject = tree.node.value + '';
}
async handleNextLevel(tree: Tree) {
const currentNodeId = tree.node.id;
const oopNodeController = this.treeComponent.getControllerByNodeId(tree.node.id);
const nodeIdNr = +currentNodeId;
// Für die richtige Anbindung auskommentieren bzw. Webservice für die "Objekt der Schaltung" implementieren
// Fehlt jdoch noch im CIM-Cache
/* const value = tree.node.value + '';
const xmlStringRes = await this.cimCacheService.getRessourcesWithType(value).toPromise().catch(error => {
this.messageService.emitError('CimCache', ErrorType.retrieve);
}); */
// ...deswegen Fake Childs atm fest auf 'ac-line-segment'
const xmlStringRes = await this.cimCacheService.getRessourcesWithType('ac-line-segment').toPromise().catch(error => {
// this.messageService.emitError('CimCache', ErrorType.retrieve);
this.toasterMessageService.showError(ErrorType.retrieve, 'CimCache');
});
const newTreeChildren = await this.prepareTreeModel(this.processRessourceWithTypeResponse(xmlStringRes), nodeIdNr);
oopNodeController.setChildren(newTreeChildren);
}
async prepareTreeModel(nodes: Array<PowerSystemResource>, treeId?: number) {
const newChildsLvl1: TreeModel[] = [];
// richtige Variante jedoch noch nicht im CIM-Cache verfügbar
// const promises = nodes.map((pwrElementLvl1) => this.cimCacheService.getRessourcesWithType(pwrElementLvl1.cimName).toPromise());
// Fake Childs
const promises = nodes.map((pwrElementLvl1) => this.cimCacheService.getRessourcesWithType('substation-type').toPromise());
const results = await Promise.all(promises);
for (let index = 0; index < results.length; index++) {
const newChildsLvl2: TreeModel[] = [];
const asyncResult = results[index];
const pwrElementLvl1 = nodes[index];
const powerSystemResourceListLvl2 = this.processRessourceWithTypeResponse(asyncResult);
if (powerSystemResourceListLvl2 && powerSystemResourceListLvl2.length > 0 && powerSystemResourceListLvl2[0].cimId !== '-1') {
// Childs vorhanden
newChildsLvl1.push({
emitLoadNextLevel: true, id: this.treeIdCounter++, value: pwrElementLvl1.cimName,
valueObject: pwrElementLvl1, children: newChildsLvl2
});
this.isTreeAvailable = true;
} else {
// keine Childs vorhanden
newChildsLvl1.push({
emitLoadNextLevel: false, id: this.treeIdCounter++, value: pwrElementLvl1.cimName,
valueObject: pwrElementLvl1
});
this.isTreeAvailable = false;
}
}
return newChildsLvl1;
}
processRessourceTypesResponse(res: string): void {
const jsonObj = this.convertXmlToJsonObj(res);
const PSRTypeList = jsonObj.ResponseMessage.Payload.PowerSystemResourceTypes.PSRType;
for (let index = 0; index < PSRTypeList.length; index++) {
this.stepAffectedResourcesGroupList.push(PSRTypeList[index].name);
}
}
}