Files
ChurchAngular/src/app/ScreenBase.ts
T
2022-09-30 10:53:48 -07:00

193 lines
5.4 KiB
TypeScript

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<T> 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<any>();
constructor(
protected crudService: ICrudService<T>,
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<any>;
/**
* 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<boolean> {
return Observable.of(true);
}
/**
* will be called before saving, Default as `Observable.of(true)`
* */
protected beforeSave(): Observable<boolean> {
return Observable.of(true);
}
canDeactivate(): Observable<boolean> | boolean {
return this.beforeLeaveScreen().pipe(map(response => {
if (response) {
return true;
}
return false;
}));
}
}
export class ScreenSavingRef {
protected onSaveDone$: Subject<any> = new Subject();
onSaveDone: Observable<any> = this.onSaveDone$.asObservable();
saveDone(res?: any) {
this.onSaveDone$.next(res);
this.onSaveDone$.complete();
}
}