diff --git a/src/app/components/tabs-new/tabs.component.ts b/src/app/components/tabs-new/tabs.component.ts index b16ac8b7..0e1ba991 100644 --- a/src/app/components/tabs-new/tabs.component.ts +++ b/src/app/components/tabs-new/tabs.component.ts @@ -15,7 +15,7 @@ import { MessageService } from '../../message.service'; import { Subscription } from 'rxjs/Subscription'; import { CLEAR_EDITABLE_TABS_ACTION, TABS_LOGO_ACTION, TABS_ADD_TAB_ACTION, SWITCH_MENU_ACTION, - MODEL_CHANGED + MODEL_CHANGED, SET_ACTIVE_TAB, REMOVE_TAB } from '../../constants'; const TAB_TIMEOUT = 100; @@ -52,6 +52,59 @@ export class TabsNewComponent implements AfterViewInit, OnDestroy { this.resetEditMode(); } } + + if (event.message === SET_ACTIVE_TAB) { + const selectedTab = event.options; + + if (!this.disabled) { + let editModeFired = false; + + this.tabs.forEach((tab: TabNewComponent) => { + if (selectedTab !== tab && tab.active) { + tab.deselect.emit(tab); + tab.active = false; + } + + if (selectedTab === tab && tab.active) { + tab.editMode = true; + editModeFired = true; + } + }); + + selectedTab.active = true; + selectedTab.select.emit(selectedTab); + + if (!editModeFired) { + this.resetEditMode(); + } + } + + this.messageService.sendMessage(MODEL_CHANGED); + } + + if (event.message === REMOVE_TAB) { + const tab = event.options; + const tabsAsArray: TabNewComponent[] = this.getTabsAsArray(); + const index = tabsAsArray.indexOf(tab); + + if (index === -1) { + return; + } + + let newActiveIndex = -1; + + if (this.tabs.length > 1) { + newActiveIndex = this.getClosestTabIndex(index); + + if (newActiveIndex >= 0) { + // this.syncActions.onSetTabActive(newActiveIndex); + this.selectTab(tabsAsArray[newActiveIndex]); + } + } + + tab.remove.emit({tab: this.tabs[index], newActiveIndex}); + this.syncActions.onTabRemove(index); + } }); } @@ -84,53 +137,12 @@ export class TabsNewComponent implements AfterViewInit, OnDestroy { } selectTab(selectedTab: TabNewComponent) { - if (!this.disabled) { - let editModeFired = false; - - this.tabs.forEach((tab: TabNewComponent) => { - if (selectedTab !== tab && tab.active) { - tab.deselect.emit(tab); - tab.active = false; - } - - if (selectedTab === tab && tab.active) { - tab.editMode = true; - editModeFired = true; - } - }); - - selectedTab.active = true; - selectedTab.select.emit(selectedTab); - - if (!editModeFired) { - this.resetEditMode(); - } - } - - this.messageService.sendMessage(MODEL_CHANGED); + this.messageService.sendMessage(SET_ACTIVE_TAB, selectedTab); } removeTab(tab: TabNewComponent) { if (!this.disabled) { - const tabsAsArray: TabNewComponent[] = this.getTabsAsArray(); - const index = tabsAsArray.indexOf(tab); - - if (index === -1) { - return; - } - - let newActiveIndex = -1; - - if (this.tabs.length > 1) { - newActiveIndex = this.getClosestTabIndex(index); - - if (newActiveIndex >= 0) { - this.syncActions.onSetTabActive(newActiveIndex); - } - } - - tab.remove.emit({tab: this.tabs[index], newActiveIndex}); - this.syncActions.onTabRemove(index); + this.messageService.sendMessage(REMOVE_TAB, tab); } } diff --git a/src/app/components/tabs/tabs.component.ts b/src/app/components/tabs/tabs.component.ts index 00055370..4cbaff1d 100644 --- a/src/app/components/tabs/tabs.component.ts +++ b/src/app/components/tabs/tabs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, Input, Output, EventEmitter, HostListener } from '@angular/core'; +import { Component, OnInit, Input, Output, EventEmitter, HostListener, ChangeDetectorRef } from '@angular/core'; import { Observable } from 'rxjs'; import { ChartService } from './chart.service'; import { TabModel } from './tab.model'; @@ -37,7 +37,8 @@ export class TabsComponent implements OnInit { private chartService: ChartService, private messageService: MessageService, private freshenerService: FreshenerService, - private es: ElectronService + private es: ElectronService, + private ref: ChangeDetectorRef ) { } @@ -146,6 +147,7 @@ export class TabsComponent implements OnInit { newTab() { if (!this.disabled) { this.chartService.initTab(this.tabsModel); + this.ref.detectChanges(); } } diff --git a/src/app/constants.ts b/src/app/constants.ts index 43ef4bcb..c43899ba 100644 --- a/src/app/constants.ts +++ b/src/app/constants.ts @@ -8,3 +8,5 @@ export const MODEL_CHANGED = 'model changed'; export const OPEN_NEW_DDF_TAB_FROM_VALIDATOR = 'openNewDdfTabFromValidator'; export const CLEAR_VALIDATION_FORM = 'clear-validation-form'; export const ABANDON_VALIDATION = 'abandon-validation'; +export const SET_ACTIVE_TAB = 'set active tab'; +export const REMOVE_TAB = 'remove tab'; diff --git a/src/app/directives/vizabi.ts b/src/app/directives/vizabi.ts index a0b9562d..41e362d9 100644 --- a/src/app/directives/vizabi.ts +++ b/src/app/directives/vizabi.ts @@ -2,9 +2,8 @@ import { EventEmitter, Input, Output, OnDestroy, Directive, ElementRef, OnChanges, SimpleChanges } from '@angular/core'; -import { PlatformLocation } from '@angular/common'; - -declare const Vizabi; +import { MessageService } from '../message.service'; +import { ElectronService } from '../providers/electron.service'; const isReaderReady = {}; @@ -39,7 +38,7 @@ export class VizabiDirective implements OnDestroy, OnChanges { private prevStateStr; private poppedState = null; - constructor(private element: ElementRef, private location: PlatformLocation) { + constructor(private element: ElementRef, private ms: MessageService, private es: ElectronService) { this.createPlaceholder(); } @@ -138,11 +137,7 @@ export class VizabiDirective implements OnDestroy, OnChanges { ngOnDestroy() { try { - Object.keys(Vizabi._instances).forEach((instanceKey: any) => { - Vizabi._instances[instanceKey] = null; - }); - - this.viz.clear(); + this.es.vizabi.clearInstances(this.viz._id); VizabiDirective.removeElement(this.placeholder); } catch (generalError) { this.emitError(generalError); @@ -165,6 +160,9 @@ export class VizabiDirective implements OnDestroy, OnChanges { this.vizabiModel.bind = { ready: () => { this.onPersistentChange(); + setTimeout(() => { + this.ms.unlock(); + }, 300); }, persistentChange: () => { this.onPersistentChange(); @@ -179,17 +177,18 @@ export class VizabiDirective implements OnDestroy, OnChanges { }, 'load_error': (event: any, error: string) => { this.emitError(error); + this.ms.unlock(); } }; this.readerProcessing(); - this.vizabiModel = Vizabi.utils.deepExtend({}, + this.vizabiModel = this.es.vizabi.utils.deepExtend({}, changes.model.currentValue, this.getAdditionalData(), this.vizabiModel); - this.vizabiPageModel = Vizabi.utils.deepExtend({}, this.vizabiModel); + this.vizabiPageModel = this.es.vizabi.utils.deepExtend({}, this.vizabiModel); delete this.vizabiPageModel.bind; - const fullModel = Vizabi.utils.deepExtend({}, this.vizabiModel, true); + const fullModel = this.es.vizabi.utils.deepExtend({}, this.vizabiModel, true); const lastModified = new Date().getTime(); this.refreshLastModified(fullModel, lastModified); @@ -198,7 +197,9 @@ export class VizabiDirective implements OnDestroy, OnChanges { delete fullModel.state; } - this.viz = Vizabi(this.chartType, this.placeholder, fullModel); + this.ms.lock(); + + this.viz = this.es.vizabi(this.chartType, this.placeholder, fullModel); this.onCreated.emit({ order: this.order, @@ -236,14 +237,14 @@ export class VizabiDirective implements OnDestroy, OnChanges { this.readerPlugins && this.readerModuleObject[this.readerGetMethod] && !isReaderReady[this.readerName]) { const readerObject = this.readerModuleObject[this.readerGetMethod].apply(this, this.readerPlugins); - Vizabi.Reader.extend(this.readerName, readerObject); + this.es.vizabi.Reader.extend(this.readerName, readerObject); isReaderReady[this.readerName] = true; } } private onPersistentChange() { - if (this.poppedState && Vizabi.utils.comparePlainObjects(this.viz.getModel(), this.poppedState)) { + if (this.poppedState && this.es.vizabi.utils.comparePlainObjects(this.viz.getModel(), this.poppedState)) { return; } diff --git a/src/app/message.service.ts b/src/app/message.service.ts index ce4c1ae0..fe83970e 100644 --- a/src/app/message.service.ts +++ b/src/app/message.service.ts @@ -4,17 +4,38 @@ import { Subject } from 'rxjs/Subject'; @Injectable() export class MessageService { - private subject: Subject = new Subject(); + private subject$ = new Subject(); + private lock$: Subject; - public sendMessage(message: string, options?: any): void { - this.subject.next({message, options}); + sendMessage(message: string, options?: any) { + if (!this.lock$) { + this.subject$.next({message, options}); + } else { + this.lock$.asObservable().subscribe(() => { + this.subject$.next({message, options}); + }); + } } - public clearMessage(): void { - this.subject.next(); + clearMessage() { + this.subject$.next(); } - public getMessage(): Observable { - return this.subject.asObservable(); + lock() { + if (!this.lock$) { + this.lock$ = new Subject(); + } + } + + unlock() { + if (this.lock$) { + this.lock$.next(); + this.lock$.complete(); + this.lock$ = null; + } + } + + getMessage(): Observable { + return this.subject$.asObservable(); } }