| /* |
| ******************************************************************************* |
| * Copyright (c) 2018 Contributors to the Eclipse Foundation |
| * |
| * See the NOTICE file(s) distributed with this work for additional |
| * information regarding copyright ownership. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| ******************************************************************************* |
| */ |
| |
| import { SessionContext } from './../../common/session-context'; |
| import { GridMeasureService } from './../../services/grid-measure.service'; |
| import { LockHelperService } from './../../services/lock-helper.service'; |
| import { GridMeasure } from './../../model/grid-measure'; |
| import { |
| Component, OnInit, ViewChild, OnDestroy, EventEmitter, ChangeDetectorRef, AfterViewChecked, HostBinding, Output |
| } from '@angular/core'; |
| import { Router, ActivatedRoute } from '@angular/router'; |
| import { DaterangepickerConfig } from 'ng2-daterangepicker'; |
| import { ErrorType } from '../../common/enums'; |
| import { Globals } from './../../common/globals'; |
| import { RoleAccess } from '../../model/role-access'; |
| import { RoleAccessHelperService } from '../../services/jobs/role-access-helper.service'; |
| import { ToasterButtonEventEn } from './../../common/enums'; |
| import { GridMeasureValidatorFactory } from '../../custom_modules/helpers/grid-measure-validator'; |
| import { ModeValidator } from '../../custom_modules/helpers/mode-validator'; |
| import { SingleGridMeasure } from '../../model/single-grid-measure'; |
| import { SingleGridMeasureDetailTabComponent } from '../single-grid-measure-detail-tab/single-grid-measure-detail-tab.component'; |
| import { Util } from '../../common/util'; |
| import { CloneGridMeasureHelper } from '../../custom_modules/helpers/clone-grid-measure-helper'; |
| import { BaseDataLoaderService } from '../../services/jobs/base-data-loader.service'; |
| import { ToasterMessageService } from '../../services/toaster-message.service'; |
| |
| @Component({ |
| selector: 'app-grid-measure-detail', |
| templateUrl: './grid-measure-detail.component.html', |
| styleUrls: ['./grid-measure-detail.component.css'] |
| }) |
| |
| export class GridMeasureDetailComponent implements OnInit, OnDestroy, AfterViewChecked { |
| |
| private unlockInProgress = false; |
| dragEntered = false; |
| console = console; |
| |
| Globals = Globals; |
| readOnlyForm = false; // true to set the whole form readonly(disable form) |
| viewModeReadOnly = false; // setting that was provided when starting the form |
| emailAddFormNotAllowed = true; |
| showSpinner = true; |
| gridMeasureDetail: GridMeasure; |
| currentSingleGridMeasure: SingleGridMeasure = new SingleGridMeasure(); |
| endDate: Date; |
| startDate: Date; |
| validForSave: boolean; |
| validForUpload: boolean; |
| fileToUpload: File = null; |
| showTabs = true; |
| isExpanded = true; |
| isExpandedDetail = true; |
| isExpandedEmail = false; |
| fileReaderReady = false; |
| id: any; |
| fileSelected: boolean; |
| isAppointmentNumberOfValid: boolean; |
| storageInProgress = false; |
| dateFormatLocale = 'dd.MM.yyyy HH:mm'; |
| roleAccessCurrUser: RoleAccess; |
| datePattern = '^(([0-2]?[0-9]|3[0-1])\.([0]?[1-9]|1[0-2])\.[1-2][0-9]{3})$'; |
| dateTimePattern = '^(([0-2]?[0-9]|3[0-1])\.([0]?[1-9]|1[0-2])\.[1-2][0-9]{3}) (20|21|22|23|[0-1]?[0-9]{1}):([0-5]?[0-9]{1})$'; |
| mode: string; |
| gridMeasureFormValid: boolean; |
| gridMeasureDetailReceived: boolean; |
| singleGridValidity: any; |
| disableNewTabBtn: boolean; |
| validityTabState: any[] = new Array<any>(); |
| isEmailDistributionStatusCollapsed = true; |
| private sub: any; |
| |
| @ViewChild(SingleGridMeasureDetailTabComponent) singleGridMeasureDetailTabComponent: SingleGridMeasureDetailTabComponent; |
| |
| constructor( |
| public router: Router, |
| private route: ActivatedRoute, |
| private gridMeasureService: GridMeasureService, |
| private lockHelperService: LockHelperService, |
| public sessionContext: SessionContext, |
| public daterangepickerConfig: DaterangepickerConfig, |
| public roleAccessHelper: RoleAccessHelperService, |
| public modeValidator: ModeValidator, |
| private ref: ChangeDetectorRef, |
| private baseDataLoader: BaseDataLoaderService, |
| private toasterMessageService: ToasterMessageService) { } |
| |
| ngAfterViewChecked() { |
| this.ref.detectChanges(); |
| } |
| |
| ngOnInit() { |
| |
| this.sessionContext.setIsLocked(false); |
| this.roleAccessCurrUser = this.roleAccessHelper.getRoleAccessDefinitions(); |
| this.id = this.route.snapshot.params.id; |
| const editModeAllowedForRole = false; |
| const mode$ = ''; |
| |
| this.checkModeAndInitiateGm(mode$, editModeAllowedForRole, this.id); |
| |
| this.daterangepickerConfig.settings = { |
| timePicker: true, |
| timePicker24Hour: true, |
| timePickerSeconds: false, |
| timePickerIncrement: 1, |
| useCurrent: true, |
| drops: 'up', |
| locale: { |
| format: 'DD.MM.YYYY HH:mm', |
| applyLabel: 'Übernehmen', |
| cancelLabel: 'Abbrechen', |
| daysOfWeek: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'], |
| monthNames: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', |
| 'August', 'September', 'Oktober', 'November', 'Dezember'], |
| firstDay: 1 |
| } |
| }; |
| |
| this.toasterMessageService.toasterEmitter$.subscribe(toasterButtonEvntEn => this.processBannerButtonEvent(toasterButtonEvntEn)); |
| } |
| |
| private processBannerButtonEvent(toasterButtonEvntEn: any) { |
| this.onUnlock(toasterButtonEvntEn === ToasterButtonEventEn.unlockGridMeasure); |
| } |
| |
| private checkModeAndInitiateGm(mode$: string, editModeAllowedForRole: boolean, id: number) { |
| if (id) { |
| this.validForUpload = true; |
| this.sub = this. |
| route.params.subscribe(params => { |
| mode$ = params['mode']; |
| if (this.mode && this.mode !== mode$) { |
| this.modeValidator.handleGridMeasureMode(this.gridMeasureDetail, this.mode); |
| } |
| if (params['mode'] !== Globals.MODE.EDIT && params['mode'] !== Globals.MODE.VIEW) { |
| this.goToOverview(); |
| } else { |
| this.gridMeasureService.getGridMeasure(this.id).subscribe(async (gm) => { |
| |
| this.gridMeasureDetail = gm; |
| |
| this.showSpinner = false; |
| editModeAllowedForRole = this.modeValidator.isEditModeAllowed(this.gridMeasureDetail.statusId); |
| this.viewModeReadOnly = !(editModeAllowedForRole && (params['mode'] === Globals.MODE.EDIT |
| || params['mode'] === Globals.MODE.VIEW)); |
| this.readOnlyForm = this.viewModeReadOnly; |
| this.emailAddFormNotAllowed = !this.modeValidator.isEmailEditModeAllowed(this.gridMeasureDetail); |
| if (!this.viewModeReadOnly) { |
| this.checkLockedByUser(); |
| } |
| this.onReceiveGridMeasureDetail(); |
| this.gridMeasureDetail.listSingleGridmeasures.forEach((element, index) => { |
| this.showTabs = false; |
| |
| setTimeout(() => { |
| this.currentSingleGridMeasure = this.gridMeasureDetail.listSingleGridmeasures[index]; |
| |
| if (index === this.gridMeasureDetail.listSingleGridmeasures.length - 1) { |
| setTimeout(() => { |
| this.showTabs = true; |
| }, 50); |
| } |
| }, 50); |
| }); |
| }); |
| } |
| }); |
| this.mode = mode$; |
| } else { |
| this.showSpinner = false; |
| this.gridMeasureDetail = new GridMeasure(); |
| this.gridMeasureDetail.createUser = this.sessionContext.getCurrUser().username; |
| this.gridMeasureDetail.plannedStarttimeFirstSinglemeasure = null; |
| this.gridMeasureDetail.endtimeGridmeasure = null; |
| this.onReceiveGridMeasureDetail(); |
| } |
| } |
| |
| onUnlock(isUnlocked: boolean) { |
| if (this.unlockInProgress) { |
| return; |
| } else { |
| this.unlockInProgress = true; |
| } |
| const deleteEvent$: EventEmitter<boolean> = new EventEmitter<boolean>(); |
| deleteEvent$.subscribe(b => this.recheckLockedByUser()); |
| if (isUnlocked) { |
| this.deleteLock(true, deleteEvent$); |
| } |
| } |
| recheckLockedByUser() { |
| this.checkLockedByUser(); |
| this.unlockInProgress = false; |
| } |
| |
| ngOnDestroy() { |
| this.clearComponent(); |
| } |
| |
| private clearComponent() { |
| this.lockHelperService.deleteLock(this.id, Globals.GRIDMEASURE_LOCK_TAG, false, null); |
| if (this.sub) { |
| this.sub.unsubscribe(); |
| } |
| // this.messageService.clearBannerLocalEvent$.emit(true); |
| // this.toasterComponent.clear(); |
| } |
| |
| private onReceiveGridMeasureDetail() { |
| if (this.gridMeasureDetail.title) { |
| this.validForSave = true; |
| } else { |
| this.validForSave = false; |
| } |
| |
| if (!this.gridMeasureDetail.id) { |
| // Setzt den intialen Status auf 0 TODO: muss je nach Prozess angepasst werden (separate User Story) |
| this.gridMeasureDetail.statusId = Globals.STATUS.NEW; |
| } |
| |
| if (this.gridMeasureDetail) { |
| |
| // If this.roleAccessCurrUser is undefined page was refresehd or reached by external call (directlink from email). |
| if (!this.roleAccessCurrUser) { |
| this.baseDataLoader.loadBaseData(); |
| this.roleAccessCurrUser = this.roleAccessHelper.getRoleAccessDefinitions(); |
| } |
| |
| const ctrl = this.roleAccessCurrUser.controls.filter(control => control.gridMeasureStatusId === this.gridMeasureDetail.statusId)[0]; |
| this.sessionContext.setInactiveFieldsArray(ctrl.inactiveFields || []); |
| } |
| |
| this.disableNewTabButtonForModeAndStatus(); |
| |
| this.gridMeasureDetailReceived = true; |
| } |
| |
| disableNewTabButtonForModeAndStatus() { |
| const gm = this.gridMeasureDetail; |
| if (this.mode === Globals.MODE.VIEW || (gm.statusId !== Globals.STATUS.NEW && gm.statusId !== Globals.STATUS.APPLIED)) { |
| this.disableNewTabBtn = true; |
| } |
| } |
| |
| goToOverview() { |
| // this.toasterComponent.clear(); |
| // this.messageService.clearBannerLocalEvent$.emit(true); |
| this.router.navigate(['/overview']); |
| } |
| |
| createGridMeasure(newGridMeaure?: GridMeasure, isDuplicate?: boolean) { |
| let tmpGM = new GridMeasure(); |
| if (isDuplicate) { |
| tmpGM = newGridMeaure; |
| } else { |
| tmpGM = this.gridMeasureDetail; |
| } |
| |
| if (this.storageInProgress) { |
| return; |
| } else { |
| this.storageInProgress = true; |
| } |
| tmpGM.createUser = tmpGM.createUser || this.sessionContext.getCurrUser().username; |
| const actualStatus = tmpGM.statusId; |
| if (!actualStatus) { |
| tmpGM.statusId = Globals.STATUS.NEW; |
| } |
| this.setPlannedDatesFromSingleGridMeasures(); |
| |
| tmpGM.listSingleGridmeasures.forEach(sgm => { |
| if (this.storageInProgress) { |
| if (!GridMeasureValidatorFactory.createsingleGM(this.toasterMessageService).validateEntity(sgm, true)) { |
| this.storageInProgress = false; |
| return; |
| } else { |
| return; |
| } |
| } |
| |
| }); |
| if (!this.storageInProgress) { |
| return; |
| } |
| if (!GridMeasureValidatorFactory.createGM(this.toasterMessageService).validateEntity(tmpGM, true)) { |
| this.storageInProgress = false; |
| return; |
| } |
| |
| this.mergeDeletedStepsAndResetMinusIds(); |
| this.mergeDeletedEmailDistributionEntriesAndResetMinusIds(); |
| this.gridMeasureService.storeGridMeasure(tmpGM).subscribe(gm => { |
| if (!actualStatus) { |
| this.id = gm.id; |
| } |
| |
| this.storageInProgress = false; |
| this.toasterMessageService.showSuccess('Netzmaßnahme "' + gm.title + '" erfolgreich gespeichert!'); |
| this.validForUpload = true; |
| this.readOnlyForm = isNaN(actualStatus); |
| |
| this.navigateAfterCreate(isDuplicate, gm); |
| }, |
| error => { |
| this.storageInProgress = false; |
| this.toasterMessageService.showError(ErrorType.create, 'Netzmaßnahme'); |
| console.log(error); |
| } |
| ); |
| } |
| |
| updateGridMeasureStatus(status: number) { |
| if (this.storageInProgress) { |
| return; |
| } else { |
| this.storageInProgress = true; |
| } |
| this.gridMeasureDetail.createUser = this.gridMeasureDetail.createUser || this.sessionContext.getCurrUser().username; |
| this.gridMeasureDetail.statusId = status; |
| |
| this.gridMeasureDetail.listSingleGridmeasures.forEach(sgm => { |
| if (this.storageInProgress) { |
| if (!GridMeasureValidatorFactory.createsingleGM(this.toasterMessageService).validateEntity(sgm, true)) { |
| this.storageInProgress = false; |
| return; |
| } else { |
| return; |
| } |
| } |
| |
| }); |
| if (!this.storageInProgress) { |
| return; |
| } |
| |
| if (!GridMeasureValidatorFactory.createGM(this.toasterMessageService).validateEntity(this.gridMeasureDetail, true)) { |
| this.storageInProgress = false; |
| return; |
| } |
| this.mergeDeletedStepsAndResetMinusIds(); |
| this.mergeDeletedEmailDistributionEntriesAndResetMinusIds(); |
| this.gridMeasureService.storeGridMeasure(this.gridMeasureDetail).subscribe(gm => { |
| this.storageInProgress = false; |
| this.toasterMessageService.showSuccess('Netzmaßnahmes "' + gm.title + '" Status erfolgreich zu "' |
| + this.sessionContext.getStatusById(gm.statusId).name + '" geändert!'); |
| this.goToOverview(); |
| }, |
| error => { |
| this.storageInProgress = false; |
| this.toasterMessageService.showError(ErrorType.update, 'Netzmaßnahme'); |
| console.log(error); |
| } |
| ); |
| } |
| |
| createNewSingleGridMeasureTab() { |
| if (!this.isSingleGridmeasureLimitReached()) { |
| const singleGM = new SingleGridMeasure; |
| singleGM.sortorder = this.gridMeasureDetail.listSingleGridmeasures[ |
| this.gridMeasureDetail.listSingleGridmeasures.length + -1].sortorder + 1; |
| this.gridMeasureDetail.listSingleGridmeasures.push(singleGM); |
| this.currentSingleGridMeasure = singleGM; |
| Util.showSingleGridmeasureTab(singleGM.sortorder); |
| this.setSingleGridMeasureTitle(); |
| } |
| } |
| |
| checkLockedByUser() { |
| const isLockedByOther$: EventEmitter<boolean> = new EventEmitter<boolean>(); |
| isLockedByOther$.subscribe(locked => { |
| this.readOnlyForm = this.viewModeReadOnly || locked; // readOnly stays readonly, no matter if locked or not |
| if (!this.readOnlyForm) { |
| this.lockHelperService.createLock(this.id, Globals.GRIDMEASURE_LOCK_TAG, null); |
| |
| } |
| if (locked) { |
| this.disableNewTabBtn = true; |
| this.sessionContext.setIsLocked(locked); |
| } |
| }); |
| |
| this.lockHelperService.checkLockedByUser(this.id, Globals.GRIDMEASURE_LOCK_TAG, isLockedByOther$); |
| } |
| |
| deleteLock(force: boolean, deleteEvent$: EventEmitter<boolean>) { |
| if (force || !this.readOnlyForm) { |
| this.lockHelperService.deleteLock(this.id, Globals.GRIDMEASURE_LOCK_TAG, force, deleteEvent$); |
| this.disableNewTabBtn = false; |
| } |
| } |
| |
| isSingleGridmeasureValid(singleGridmeasure: SingleGridMeasure): boolean { |
| return singleGridmeasure._isValide; |
| } |
| |
| isGridMeasureDetailValid(): boolean { |
| return this.gridMeasureDetail._isValide; |
| } |
| |
| isSingleGridmeasureLimitReached(): boolean { |
| if (this.gridMeasureDetail && this.gridMeasureDetail.listSingleGridmeasures) { |
| return this.gridMeasureDetail.listSingleGridmeasures.filter(singleGridMeasure => |
| !singleGridMeasure.delete).length >= Globals.MAX_NUMBER_OF_TABS; |
| } else { |
| return false; |
| } |
| } |
| |
| areAllTabsValid(): boolean { |
| return this.showTabs && this.gridMeasureDetail._isValide && this.gridMeasureDetail._isHeaderValide |
| && this.gridMeasureDetail.listSingleGridmeasures |
| && this.gridMeasureDetail.listSingleGridmeasures.filter(singleGridMeasure => |
| !singleGridMeasure._isValide && !singleGridMeasure.delete).length === 0; |
| } |
| |
| onSelectSingleGridMeasureTab(singleGridmeasure: SingleGridMeasure): void { |
| if (singleGridmeasure !== this.currentSingleGridMeasure) { |
| this.currentSingleGridMeasure = singleGridmeasure; |
| } |
| this.setSingleGridMeasureTitle(); |
| } |
| |
| setSingleGridMeasureTitle() { |
| if (!this.currentSingleGridMeasure.title) { |
| this.currentSingleGridMeasure.title = this.gridMeasureDetail.title; |
| } |
| } |
| |
| onSelectGridMeasureTab(): void { |
| this.setPlannedDatesFromSingleGridMeasures(); |
| } |
| |
| onSingleGridMeasureChanged(ev): void { |
| this.currentSingleGridMeasure = ev; |
| this.setPlannedDatesFromSingleGridMeasures(); |
| } |
| |
| onGridMeasureChanged(ev): void { |
| this.gridMeasureDetail = ev; |
| } |
| |
| setPlannedDatesFromSingleGridMeasures() { |
| const currentPlannedBeginDates: string[] = []; |
| const currentPlannedEndDates: string[] = []; |
| currentPlannedBeginDates.push(this.currentSingleGridMeasure.plannedStarttimeSinglemeasure); |
| currentPlannedEndDates.push(this.currentSingleGridMeasure.plannedEndtimeSinglemeasure); |
| for (const sgm of this.gridMeasureDetail.listSingleGridmeasures) { |
| currentPlannedBeginDates.push(sgm.plannedStarttimeSinglemeasure); |
| currentPlannedEndDates.push(sgm.plannedEndtimeSinglemeasure); |
| } |
| this.gridMeasureDetail.plannedStarttimeFirstSinglemeasure = Util.getEarliestValidDateString(currentPlannedBeginDates); |
| this.gridMeasureDetail.endtimeGridmeasure = Util.getLatestValidDateString(currentPlannedEndDates); |
| } |
| |
| mergeDeletedStepsAndResetMinusIds() { |
| this.gridMeasureDetail.listSingleGridmeasures.forEach(sgm => { |
| if (sgm.listSteps) { |
| sgm.listSteps.forEach(step => { |
| if (step.id === Globals.TEMP_ID_TO_SHOW_NEW_STEPS) { |
| delete step.id; |
| } |
| }); |
| } |
| if (sgm.listStepsDeleted) { |
| sgm.listSteps.push.apply(sgm.listSteps, sgm.listStepsDeleted); |
| } |
| }); |
| } |
| |
| mergeDeletedEmailDistributionEntriesAndResetMinusIds() { |
| |
| if (this.gridMeasureDetail.listEmailDistribution) { |
| this.gridMeasureDetail.listEmailDistribution.forEach(emailDistributionEntry => { |
| if (emailDistributionEntry.id === Globals.TEMP_ID_TO_SHOW_NEW_EMAILDISTRIBUTIONENTRYS) { |
| delete emailDistributionEntry.id; |
| } |
| }); |
| } |
| const listAsStringArray = new Array<string>(); |
| this.gridMeasureDetail.listEmailDistribution.filter(e => !e.preconfigured).forEach(ede => listAsStringArray.push(ede.emailAddress)); |
| if (listAsStringArray.length === 0) { |
| this.gridMeasureDetail.emailAddresses = null; |
| } else { |
| this.gridMeasureDetail.emailAddresses = listAsStringArray.join(';'); |
| } |
| if (this.gridMeasureDetail.listEmailDistributionDeleted) { |
| this.gridMeasureDetail.listEmailDistribution.push.apply( |
| this.gridMeasureDetail.listEmailDistribution, |
| this.gridMeasureDetail.listEmailDistributionDeleted); |
| } |
| } |
| |
| duplicateGM() { |
| if (this.gridMeasureDetail.id) { |
| const duplicatedGM = CloneGridMeasureHelper.cloneGridMeasure( |
| this.gridMeasureDetail); |
| this.createGridMeasure(duplicatedGM, true); |
| this.clearComponent(); |
| } |
| } |
| |
| private navigateAfterCreate(isDuplicate: boolean, gm: GridMeasure) { |
| if (!isDuplicate) { |
| this.goToOverview(); |
| } else { |
| this.goToOverview(); |
| setTimeout(() => { |
| this.router.navigate(['/gridMeasureDetail/', gm.id, Globals.MODE.EDIT]); |
| }, 200); |
| } |
| } |
| |
| goToCancelPage() { |
| this.sessionContext.setGridMeasureDetail(this.gridMeasureDetail); |
| this.sessionContext.setCancelStage(true); |
| this.router.navigate(['gridMeasureDetail/' + this.id + '/' + this.mode + '/cancelGridMeasure']); |
| } |
| } |