import { Component, Input, ViewChild, OnInit, AfterContentInit, AfterViewInit, DoCheck, OnDestroy, ComponentFactoryResolver, ViewContainerRef, ComponentRef } from '@angular/core'; import { ConfigObjectScreenFactory } from '../factories/confg-object-screen-factory' import { Router, ActivatedRoute } from '@angular/router' import { ObjectService } from '../services/object-screen.service' import { Location } from '@angular/common'; import { Mediator } from '../services/mediator'; import { CoreMediatorChannels } from '../utils/mediator-channels'; import { CoreNotificationsMessages } from '../utils/notifications-messages'; import { TranslateService } from '../services/translate-service'; import { CookieService } from '../services/cookie-service'; import { ViewLocalizedComponent } from '../view-localized-component/view-localized-component'; import { LocalizedStringFactory } from '../factories/localizedcmp-factory'; import { ObjectUtils } from '../utils/object-utils'; import { ConfigObjectScreenOptions } from '../types/object-screen-types'; import { ActionConfig } from '../types/general-types'; @Component({ selector: 'config-object-screen', templateUrl: './config-object-screen.component.html', styleUrls: ['./config-object-screen.component.css'] }) export class ConfigObjectScreen implements OnInit, AfterContentInit, AfterViewInit, DoCheck, OnDestroy { @Input() private options: ConfigObjectScreenOptions; @ViewChild('config_object_screen_content', { read: ViewContainerRef }) private _content: ViewContainerRef @ViewChild('localizedNameCmp', { read: ViewContainerRef }) private localizedNameContainer: ViewContainerRef; private localizedNameCmpRef: ComponentRef private currenObjectId: number = -1; private currentObjectScreen: ComponentRef<{}>; private toolbarActions: ActionConfig[]; private defaultModel: any = {}; private editToken: string private objectsMap = new Map(); private currentObjectIndex: number; private helpCard: boolean = true; private infoCard: boolean = true; private helpCardState: boolean = true; private infoCardState: boolean = true; private helpCardOptions = { title: "help-section-label", icon: "fa fa-question-circle" }; private infoCardOptions = { title: "creation-data-label", icon: "fa fa-exclamation-circle" }; private toolbarActivationBtn = { title: '', iconClass: '' }; private changeLangEventKey: string; constructor(private objectService: ObjectService, private componentFactoryResolver: ComponentFactoryResolver, private route: ActivatedRoute, private router: Router, private location: Location, private translateService: TranslateService, private cookieService: CookieService) { } ngOnInit() { this.route.params.subscribe(params => { this.currenObjectId = Number.parseInt(params['id']); this.destroy(); this.init(); }); this.changeLangEventKey = Mediator.subscribe(CoreMediatorChannels.CHANGE_SYSTEM_LANGUAGE, (lang) => { this.destroy(); this.init(); }); } private init() { this.initRead(() => { this.createObjectScreen(); this.createLocalizedNameCmp(); this.initStateIcons(); this.initToolbarActions(); }); this.readAllObjects(); this.cancelLockWhenNavigation(); } private destroy() { if (this.currentObjectScreen) { this.currentObjectScreen.destroy(); } if (this.localizedNameCmpRef) { this.localizedNameCmpRef.destroy(); } } private initRead(callback?: () => void) { this.objectService.readObject(this.options.objectRemoteRestUrl, this.currenObjectId, (res) => { this.resetModel(res); if (callback) { callback(); } }); } private read() { this.objectService.readObject(this.options.objectRemoteRestUrl, this.currenObjectId, (res) => { this.updateModel(res); }); } private resetModel(res: any) { this.options.model = ObjectUtils.clone(res); this.options.model.viewMode = true; this.defaultModel = ObjectUtils.clone(res); this.defaultModel.viewMode = true; } private updateModel(res: any) { ObjectUtils.extend(this.options.model, res); ObjectUtils.extend(this.defaultModel, res); } private initToolbarActions() { this.toolbarActions = [ { iconClass: "fa fa-pencil", actionName: "Edit", actionFunction: (e) => { e.preventDefault() this.objectService.editEntity(this.options.objectRemoteRestUrl, this.options.model.id, (res) => { this.editToken = res.tokenId; this.options.model.viewMode = false; this.defaultModel.viewMode = false; Mediator.emit(CoreMediatorChannels.ON_OBJECT_SCREEN_EDIT_MODE); $(".os-content-footer").css("background-color", "#0095FF"); $(".os-content-footer").css("height", "38px"); $(".os-content-footer").css("bottom", "38px"); this.cardsInEditMode(); }, (error) => { Mediator.emit(CoreMediatorChannels.ERROR_ALERT, { errorMessage: this.translateService.instant(CoreNotificationsMessages.ERROR_NOT_EDITABLE_RECORD_MSG) }); }) } }, { iconClass: "fa fa-refresh", actionName: "Refresh", actionFunction: (e) => { e.preventDefault(); this.destroy(); this.init(); } }, { iconClass: "fa fa-bookmark", actionName: "Bookmark", actionFunction: (e) => { e.preventDefault(); } }, { iconClass: "fa fa-check-circle-o", actionName: "Verify", actionFunction: (e) => { e.preventDefault(); } }, { iconClass: "fa " + this.toolbarActivationBtn.iconClass, actionName: this.toolbarActivationBtn.title, actionFunction: (e) => { e.preventDefault(); if (this.options.model.currentStates.indexOf("Active") > -1) { this.objectService.deactivateInstance(this.options.objectRemoteRestUrl, this.options.model.id, (response) => { this.read(); this.onObjectDeactivation(); Mediator.emit(CoreMediatorChannels.SUCCESS_ALERT, { message: this.translateService.instant(CoreNotificationsMessages.SINGLE_INSTANCE_SUCCESS_DEACTIVATE_MSG) }); }, (error) => { ObjectUtils.extend(this.options.model, error); this.displayErrorMessage(error); }); } else { this.objectService.activateInstance(this.options.objectRemoteRestUrl, this.options.model.id, (response) => { this.read(); this.onObjectActivation(); Mediator.emit(CoreMediatorChannels.SUCCESS_ALERT, { message: this.translateService.instant(CoreNotificationsMessages.SINGLE_INSTANCE_SUCCESS_ACTIVATE_MSG) }); }, (error) => { ObjectUtils.extend(this.options.model, error); this.displayErrorMessage(error); }); } } }, { iconClass: "fa fa-clone", actionName: "Clone", actionFunction: (e) => { e.preventDefault() } }, { iconClass: "fa fa-trash", actionName: "Delete", actionFunction: (e) => { e.preventDefault() Mediator.emit(CoreMediatorChannels.CONFIRMATION_DIALOG, { message: this.translateService.instant(CoreNotificationsMessages.DELETE_SINGLE_INSTANCE_MSG), confirm: () => { this.objectService.deleteInstances(this.options.objectRemoteRestUrl, [this.options.model.id.toString()], (response) => { this.router.navigate([this.options.homeScreenRoutingPath]); }, (responseBody) => { // in case of error this.displayErrorMessage(responseBody.data[0]); }); }, cancel: () => { } }); } } ] } private initStateIcons() { if (this.options.model.currentStates.indexOf("Draft") > -1 || this.options.model.currentStates.indexOf("Inactive") > -1) { this.onObjectDeactivation(); } if (this.options.model.currentStates.indexOf("Active") > -1) { this.onObjectActivation(); } } private onObjectActivation() { $(".fa-toggle-on").parent().attr('title', 'De-activate') this.toolbarActivationBtn.title = 'De-activate'; $(".fa-toggle-on").addClass("fa-toggle-off"); this.toolbarActivationBtn.iconClass = 'fa-toggle-off'; $(".fa-toggle-on").removeClass("fa-toggle-on"); $("#core-os-activeFlag").css('color', '#009E11'); } private onObjectDeactivation() { var stateFlagColor = ''; if (this.options.model.currentStates.indexOf("Inactive") > -1) { stateFlagColor = '#999999'; } if (this.options.model.currentStates.indexOf("Draft") > -1) { stateFlagColor = '#2A78E4'; } $(".fa-toggle-off").parent().attr('title', 'Activate') this.toolbarActivationBtn.title = 'Activate'; $(".fa-toggle-off").addClass("fa-toggle-on"); this.toolbarActivationBtn.iconClass = 'fa-toggle-on'; $(".fa-toggle-off").removeClass("fa-toggle-off"); $("#core-os-activeFlag").css('color', stateFlagColor); } private createObjectScreen() { this.currentObjectScreen = new ConfigObjectScreenFactory(this.options.componentType, this.componentFactoryResolver, this._content).create(this.options); } private createLocalizedNameCmp() { let factory = new LocalizedStringFactory(this.componentFactoryResolver); this.localizedNameCmpRef = factory.createViewLocalizedCmp(this.localizedNameContainer, this.options.model, "name", "name_label"); } private readAllObjects() { this.objectService.readAll(this.options.objectRemoteRestUrl, (res) => { for (let i = 1; i <= res.data.length; i++) { let obj = res.data[i - 1]; if (obj.id == this.currenObjectId) { this.currentObjectIndex = i; } this.objectsMap.set(i, obj.id); } }); } private save(e: Event) { e.preventDefault() this.objectService.updateObject(this.options.objectRemoteRestUrl, this.options.model.id, this.options.model, this.editToken, (res) => { this.updateModel(res); this.options.model.viewMode = true; this.defaultModel.viewMode = true; $(".os-content-footer").css("background-color", ""); $(".os-content-footer").css("height", "100px"); $(".os-content-footer").css("bottom", "100px"); Mediator.emit(CoreMediatorChannels.SUCCESS_ALERT, { message: this.translateService.instant(CoreNotificationsMessages.SUCCESS_UPDATE_MSG) }); Mediator.emit(CoreMediatorChannels.ON_OBJECT_SCREEN_VIEW_MODE); this.cardsInViewMode(); }, (error) => { ObjectUtils.extend(this.options.model, error); Mediator.emit(CoreMediatorChannels.AFTER_SAVE_OBJECT_SCREEN_WITH_ERRORS); }); } private close(e: Event) { e.preventDefault(); if (!this.isDirtyModel(this.options.model, this.defaultModel)) { Mediator.emit(CoreMediatorChannels.CONFIRMATION_DIALOG, { message: this.translateService.instant(CoreNotificationsMessages.CLOSE_Update_SINGLE_INSTANCE_MSG), confirm: () => { this.cancelEditEntity(); }, cancel: () => { } }); } else { this.cancelEditEntity(); } } private cancelEditEntity() { this.objectService.cancelEditEntity(this.options.objectRemoteRestUrl, this.options.model.id, this.editToken, (res) => { Mediator.emit(CoreMediatorChannels.BEFORE_CLOSE_OBJECT_SCREEN); ObjectUtils.copy(this.options.model, this.defaultModel); this.options.model.viewMode = true; this.defaultModel.viewMode = true; Mediator.emit(CoreMediatorChannels.ON_OBJECT_SCREEN_VIEW_MODE); Mediator.emit(CoreMediatorChannels.ON_OBJECT_SCREEN_CANCEL_EDIT_MODE); $(".os-content-footer").css("background-color", ""); $(".os-content-footer").css("height", "100px"); $(".os-content-footer").css("bottom", "100px"); this.cardsInViewMode(); }); } private isDirtyModel(x, y) { var a = JSON.stringify(x), b = JSON.stringify(y); if (!a) a = ''; if (!b) b = ''; return (a.split('').sort().join('') == b.split('').sort().join('')); } private navigate(id: number) { this.router.navigateByUrl(this.options.homeScreenRoutingPath + '/' + id); } private goToPrevObject(e: Event) { e.preventDefault(); let prevObjectIndex = (this.currentObjectIndex - 1 == 0) ? this.objectsMap.size : this.currentObjectIndex - 1; this.currentObjectIndex = prevObjectIndex; let prevObjectId = this.objectsMap.get(prevObjectIndex); this.navigate(prevObjectId); } private goToNextObject(e: Event) { e.preventDefault(); let nextObjectIndex = (this.currentObjectIndex == this.objectsMap.size) ? 1 : this.currentObjectIndex + 1; this.currentObjectIndex = nextObjectIndex; let nextObjectId = this.objectsMap.get(nextObjectIndex); this.navigate(nextObjectId); } private goToHomeScreen(e: Event) { e.preventDefault(); this.router.navigate([this.options.homeScreenRoutingPath]); } private cancelLockWhenNavigation() { $(window).on("beforeunload", () => { if (!this.options.model.viewMode) { this.objectService.cancelEditEntity(this.options.objectRemoteRestUrl, this.options.model.id, this.editToken, (res) => { }, false); } }); } private displayErrorMessage(error) { var generalErrors = error.__general_errors__; var cumulativeErrors = ''; for (let key in generalErrors) { cumulativeErrors = cumulativeErrors + generalErrors[key].message + "\n"; } if (cumulativeErrors != '') { Mediator.emit(CoreMediatorChannels.ERROR_ALERT, { errorMessage: cumulativeErrors }); } } /** * * @private * @desc: hide cards column section * */ private hideCardsSection() { $("#os-card-section").removeClass("col-md-2 "); $("#core-os-header-page").removeClass("col-md-10"); $("#core-os-header-page").css("float", ""); $("#os-card-section").css("display", "none"); } private openCardsSection() { $("#os-card-section").addClass("col-md-2 "); $("#core-os-header-page").addClass("col-md-10 "); if (this.cookieService.getCookie("lang") == "ar") { $("#core-os-header-page").css("float", this.translateService.instant("Dir")); } $("#os-card-section").css("display", "inline"); } private cardsInEditMode() { //save cards state before edit mode this.helpCardState = this.helpCard; this.infoCardState = this.infoCard; //hide both cards this.helpCard = false; this.infoCard = false; this.hideCardsSection(); } private cardsInViewMode() { //return cards state before edit mode this.helpCard = this.helpCardState; this.infoCard = this.infoCardState; if (this.helpCard || this.infoCard) { this.openCardsSection(); } } private toggleHelpCard(e: Event) { e.preventDefault(); this.helpCard = !(this.helpCard); // in case both help and info cards are removed, remove their columns and hide cards section if (!this.helpCard && !this.infoCard) { this.hideCardsSection(); } // in case help card is wanted and card section is hidden, display card section and add cards column else if (!$("#os-card-section").hasClass("col-md-2")) { this.openCardsSection(); } } private toggleInfoCard(e: Event) { e.preventDefault(); this.infoCard = !(this.infoCard); // in case both help and info cards are removed, remove their columns and hide cards section if (!this.helpCard && !this.infoCard) { this.hideCardsSection(); } // in case info card is wanted and card section is hidden, display card section and add cards column else if (!$("#os-card-section").hasClass("col-md-2")) { this.openCardsSection(); } } private getPageDirection() { if (this.cookieService.getCookie("lang") == "ar") return { float: this.translateService.instant("Dir") }; else return { float: "" };; } ngAfterContentInit() { } ngAfterViewInit() { } ngDoCheck() { } ngOnDestroy() { Mediator.unsubscribe(CoreMediatorChannels.CHANGE_SYSTEM_LANGUAGE,this.changeLangEventKey); } }