import { Component, EventEmitter, HostListener, Injectable, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Observable, Subject } from 'rxjs'; import { Subscription } from 'rxjs'; import { first, map, take } from 'rxjs/operators'; import { ICrudService } from './services/crudServices/crud.service'; import { StateService } from './services/state.service'; @Injectable() // @Component({ // template: '' // }) export abstract class ScreenBase implements OnInit, OnDestroy { private _screenSaveDoneSubscription: Subscription; protected wasWaitingForDependency: boolean = false; protected refndx: string; protected linkPath: string; protected screenUpdateWaitList: string[] = undefined; /** * Current screen, will set to state service after `screenOnInit()` */ protected screen: string; /** * Current screen with shared screen lock id like: A71S and A71SC */ protected sharedScreenId: string = null; protected subscriptions: Subscription[] = []; protected lockScreen: boolean = true; protected allData: T[] = [];; //constants = Constants; //screenInfo: NavigatorItem; @Input() isSnapshotView: boolean = false; @Input() isLoading: boolean = true; @Input() isScreen: boolean = true; @Input() readonly: boolean = false; @Input() isProcessing: boolean = false; @Output() screenSaveDone = new EventEmitter(); constructor( protected crudService: ICrudService, protected stateService: StateService, protected route: ActivatedRoute, ) { } ngOnInit(): void { if (false == this.isSnapshotView) { // this.subscriptions.push(this.stateService.saveSubject.subscribe({ next: () => this.save() })); // this.subscriptions.push(this.stateService.cancelSubject.subscribe({ next: () => this.cancel() })); this.route.url .pipe(take(1)) .subscribe(url => { this.linkPath = url[0].path.toLowerCase(); this.screenOnInit(); //this.screenInfo = this.stateService.treeListService.screenSEQ.find(n => n.screen == this.screen); //Doing Security at here if (false == this.isSnapshotView) { this.runGetAllData(); } }); } else { this.initializeForSnapshot(); } } ngOnDestroy(): void { this.subscriptions.forEach(subscription => { if (subscription) subscription.unsubscribe(); }); } protected runGetAllData() { this.isLoading = true; this.getAllData().pipe(first()).subscribe(result => { this.isLoading = false; this.allData = result; this.allDataLoaded(); }); } /** * after get refndx from state service, and will be called when refndx changed. */ abstract screenOnInit(): void; /** * will be called when saving triggered by user or system. */ save(): ScreenSavingRef { let saveRef = new ScreenSavingRef(); if (this.saveMethod != null) { this.beforeSave().pipe(first()).subscribe(result => { if (result) { this.saveMethod.pipe(first()).subscribe(result => { saveRef.saveDone(result); this.saveDone(); this.screenSaveDone.next(result); }); } }); } else { saveRef.onSaveDone = Observable.of(false); } return saveRef; }; /** * save method for send saving request to api */ abstract get saveMethod(): Observable; /** * will be called when screen id and refndx initialized or user click cancel button. */ protected getAllData() { this.isLoading = true; return this.crudService.getAll(); } /** * will be called when canceling triggered by user or system. */ cancel(): void { this.runGetAllData(); }; saveDone(): void { //do something after saving //update screen history //alert(`Save Done: do something after ${this.screen} saving`); } /** * will be called on `ngOnInit` if `isSnapshotView==true` * */ protected initializeForSnapshot(): void { } /** * will be called after `runGetAllData` * */ protected allDataLoaded(): void { } /** * will be called when deactivated, Default as `Observable.of(true)` * */ protected beforeLeaveScreen(): Observable { return Observable.of(true); } /** * will be called before saving, Default as `Observable.of(true)` * */ protected beforeSave(): Observable { return Observable.of(true); } canDeactivate(): Observable | boolean { return this.beforeLeaveScreen().pipe(map(response => { if (response) { return true; } return false; })); } } export class ScreenSavingRef { protected onSaveDone$: Subject = new Subject(); onSaveDone: Observable = this.onSaveDone$.asObservable(); saveDone(res?: any) { this.onSaveDone$.next(res); this.onSaveDone$.complete(); } }