217 lines
7.5 KiB
TypeScript
217 lines
7.5 KiB
TypeScript
import { DatePipe } from '@angular/common';
|
|
import { HttpErrorResponse } from '@angular/common/http';
|
|
import { Component, OnInit } from '@angular/core';
|
|
import { UntypedFormGroup } from '@angular/forms';
|
|
import { MatDialog } from '@angular/material/dialog';
|
|
import { ActivatedRoute, ParamMap, Router } from '@angular/router';
|
|
import { BaseEntity } from '@common/base/base-entity.model';
|
|
import { BasePendingChangesComponent } from '@common/base/base-pending-changes.component';
|
|
import { FormService } from '@common/forms/form-service';
|
|
import { HttpError, HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
|
|
import { FilterService } from '@common/modules/text-filter/filter-service';
|
|
import { TranslateService } from '@ngx-translate/core';
|
|
import { interval, Observable } from 'rxjs';
|
|
import { takeUntil } from 'rxjs/operators';
|
|
import { nameof } from 'ts-simple-nameof';
|
|
import { Guid } from '../types/guid';
|
|
import { BaseEditorModel } from './base-form-editor-model';
|
|
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
|
import { QueryParamsService } from '@app/core/services/utilities/query-params.service';
|
|
import { LockService } from '@app/core/services/lock/lock.service';
|
|
import { LockPersist } from '@app/core/model/lock/lock.model';
|
|
import { LockTargetType } from '@app/core/common/enum/lock-target-type';
|
|
import { isNullOrUndefined } from '@swimlane/ngx-datatable';
|
|
import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component';
|
|
import { AuthService } from '@app/core/services/auth/auth.service';
|
|
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
|
|
|
|
@Component({
|
|
selector: 'app-base-editor-component',
|
|
template: ''
|
|
})
|
|
export abstract class BaseEditor<EditorModelType extends BaseEditorModel, EntityType> extends BasePendingChangesComponent implements OnInit {
|
|
|
|
isNew = true;
|
|
isDeleted = false;
|
|
isLocked: Boolean = false;
|
|
isLockedByUser: Boolean = false;
|
|
formGroup: UntypedFormGroup = null;
|
|
lookupParams: any;
|
|
|
|
// Getter Setter for editorModel. We use it to notify when the editor model is changed.
|
|
get editorModel(): EditorModelType { return this._editorModel; }
|
|
set editorModel(value: EditorModelType) { this._editorModel = value; }
|
|
private _editorModel: EditorModelType;
|
|
protected lv = 0;
|
|
|
|
|
|
abstract getItem(itemId: Guid, successFunction: (item: EntityType) => void): void;
|
|
abstract prepareForm(data: EntityType): void;
|
|
abstract formSubmit(): void;
|
|
abstract delete(): void;
|
|
abstract refreshData(): void;
|
|
abstract refreshOnNavigateToData(id?: Guid): void;
|
|
abstract persistEntity(onSuccess?: (response) => void): void;
|
|
abstract buildForm(): void;
|
|
|
|
constructor(
|
|
protected dialog: MatDialog,
|
|
protected language: TranslateService,
|
|
protected formService: FormService,
|
|
protected router: Router,
|
|
protected uiNotificationService: UiNotificationService,
|
|
protected httpErrorHandlingService: HttpErrorHandlingService,
|
|
protected filterService: FilterService,
|
|
protected datePipe: DatePipe,
|
|
protected route: ActivatedRoute,
|
|
protected queryParamsService: QueryParamsService,
|
|
protected lockService: LockService,
|
|
protected authService: AuthService,
|
|
protected configurationService: ConfigurationService,
|
|
) { super(); }
|
|
|
|
public ngOnInit(): void {
|
|
const entity = this.route.snapshot.data['entity'] as EntityType;
|
|
if(entity) {
|
|
this.isNew = false;
|
|
this.prepareForm(entity);
|
|
}else{
|
|
this.prepareForm(null);
|
|
}
|
|
|
|
this.route.queryParamMap.pipe(takeUntil(this._destroyed)).subscribe((params: ParamMap) => {
|
|
// If lookup is on the query params load it
|
|
if (params.keys.length > 0 && params.has('lookup')) {
|
|
this.lookupParams = this.queryParamsService.deSerializeLookup(params.get('lookup'));
|
|
}
|
|
});
|
|
}
|
|
|
|
public isFormValid() {
|
|
return this.formGroup.valid;
|
|
}
|
|
|
|
public isFormDisabled() {
|
|
return this.formGroup.disabled;
|
|
}
|
|
|
|
public save() {
|
|
this.clearErrorModel();
|
|
}
|
|
|
|
public cancel(): void {
|
|
this.router.navigate(['..'], { relativeTo: this.route, queryParams: { 'lookup': this.queryParamsService.serializeLookup(this.lookupParams), 'lv': ++this.lv }, replaceUrl: true });// ! lv is always zero . replaceUrl?
|
|
}
|
|
|
|
|
|
|
|
onCallbackSuccess(data?: any): void {
|
|
|
|
console.log("Success:", data);
|
|
|
|
this.uiNotificationService.snackBarNotification(this.isNew ? this.language.instant('COMMONS.SNACK-BAR.SUCCESSFUL-CREATION') : this.language.instant('COMMONS.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
|
|
this.refreshOnNavigateToData(data ? data.id : null);
|
|
}
|
|
|
|
onCallbackError(errorResponse: HttpErrorResponse) {
|
|
|
|
console.log("Error:", errorResponse);
|
|
|
|
const error: HttpError = this.httpErrorHandlingService.getError(errorResponse);
|
|
if (error.statusCode === 400) {
|
|
this.editorModel.validationErrorModel.fromJSONObject(errorResponse.error);
|
|
if(errorResponse.error.code === 120){
|
|
this.uiNotificationService.snackBarNotification(errorResponse.error.error, SnackBarNotificationLevel.Error);
|
|
}
|
|
this.formService.validateAllFormFields(this.formGroup);
|
|
} else {
|
|
this.uiNotificationService.snackBarNotification(error.getMessagesString(), SnackBarNotificationLevel.Warning);
|
|
}
|
|
}
|
|
|
|
clearErrorModel() {
|
|
this.editorModel.validationErrorModel.clear();
|
|
this.formService.validateAllFormFields(this.formGroup);
|
|
}
|
|
|
|
|
|
|
|
// private refreshOnNavigateToData(id?: Guid): void {
|
|
// if (this.isNew) {
|
|
// this.formGroup.markAsPristine();
|
|
// this.router.navigate([this.formUtilsService.getFormRoute(this.editorModel.type) + '/' + (id ? id : this.editorModel.id)]);
|
|
// } else { this.internalRefreshData(); }
|
|
// }
|
|
|
|
internalRefreshData(): void {
|
|
// setTimeout(() => {
|
|
// this.formGroup = null;
|
|
// this.editorModel = null;
|
|
// });
|
|
this.refreshData();
|
|
}
|
|
|
|
|
|
|
|
canDeactivate(): boolean | Observable<boolean> {
|
|
return this.formGroup ? !this.formGroup.dirty : true;
|
|
}
|
|
|
|
public static commonFormFieldNames(): string[] {
|
|
return [
|
|
nameof<BaseEntity>(x => x.id),
|
|
nameof<BaseEntity>(x => x.isActive),
|
|
nameof<BaseEntity>(x => x.createdAt),
|
|
nameof<BaseEntity>(x => x.updatedAt),
|
|
nameof<BaseEntity>(x => x.hash),
|
|
];
|
|
}
|
|
|
|
//
|
|
//
|
|
// Lock
|
|
//
|
|
//
|
|
protected checkLock(itemId: Guid, targetType: LockTargetType, title: string, message: string) {
|
|
if (itemId != null) {
|
|
this.isNew = false;
|
|
// check if locked.
|
|
this.lockService.checkLockStatus(itemId).pipe(takeUntil(this._destroyed)).subscribe(lockStatus => {
|
|
this.isLocked = lockStatus.status;
|
|
if (this.isLocked) {
|
|
this.formGroup.disable();
|
|
this.dialog.open(PopupNotificationDialogComponent, {
|
|
data: {
|
|
title: this.language.instant(title),
|
|
message: this.language.instant(message)
|
|
}, maxWidth: '30em'
|
|
});
|
|
} else{
|
|
this.isLockedByUser = true;
|
|
}
|
|
|
|
if (!this.isLocked && !isNullOrUndefined(this.authService.currentAccountIsAuthenticated())) {
|
|
// lock it.
|
|
this.lockService.lock(itemId, targetType).pipe(takeUntil(this._destroyed)).subscribe(async result => {
|
|
this.isLocked = true;
|
|
interval(this.configurationService.lockInterval).pipe(takeUntil(this._destroyed)).subscribe(() => this.touchLock(itemId));
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
private unlockTarget(targetId: Guid) {
|
|
this.lockService.unlockTarget(targetId).pipe(takeUntil(this._destroyed)).subscribe(async result => { });
|
|
}
|
|
|
|
private touchLock(targetId: Guid) {
|
|
this.lockService.touchLock(targetId).pipe(takeUntil(this._destroyed)).subscribe(async result => { });
|
|
}
|
|
|
|
ngOnDestroy(): void {
|
|
super.ngOnDestroy();
|
|
if(this.isLocked) this.unlockTarget(this.editorModel.id);
|
|
}
|
|
}
|