diff --git a/src/sql/base/browser/ui/panel/media/panel.css b/src/sql/base/browser/ui/panel/media/panel.css index f69b14815e..27942248b7 100644 --- a/src/sql/base/browser/ui/panel/media/panel.css +++ b/src/sql/base/browser/ui/panel/media/panel.css @@ -21,6 +21,12 @@ panel { .tabbedPanel .composite.title { display: flex; flex: 0 0 auto; + position: relative; +} + +.tabbedPanel .tabContainer { + flex: 1 1 auto; + overflow: hidden; } .tabbedPanel .tabList { @@ -31,6 +37,7 @@ panel { line-height: 35px; white-space: nowrap; flex: 1; + height: 100%; } .tabbedPanel .tabList .tab { @@ -88,17 +95,13 @@ panel { } .composite.title .title-actions { - flex: 1 1 auto; + flex: 0 0 auto; } .tab > .tabLabel.active { border-bottom: 1px solid; } -.composite.title ~ tab.fullsize > :first-child { - height: calc(100% - 38px); -} - .tabbedPanel .title-actions .panel-actions .actions-container { justify-content: flex-start; } diff --git a/src/sql/base/browser/ui/panel/panel.component.ts b/src/sql/base/browser/ui/panel/panel.component.ts index 0821508a16..cca5d7db9b 100644 --- a/src/sql/base/browser/ui/panel/panel.component.ts +++ b/src/sql/base/browser/ui/panel/panel.component.ts @@ -7,13 +7,13 @@ import { Component, ContentChildren, QueryList, AfterContentInit, Inject, forwar import { TabComponent } from './tab.component'; import { TabHeaderComponent } from './tabHeader.component'; +import { ScrollableDirective } from 'sql/base/browser/ui/scrollable/scrollable.directive'; import './panelStyles'; import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; import { Action } from 'vs/base/common/actions'; import * as types from 'vs/base/common/types'; import { mixin } from 'vs/base/common/objects'; -import { ScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; import { ScrollbarVisibility } from 'vs/base/common/scrollable'; import { addDisposableListener, EventType } from 'vs/base/browser/dom'; import { Disposable } from 'vs/base/common/lifecycle'; @@ -46,12 +46,13 @@ let idPool = 0; @Component({ selector: 'panel', template: ` - -
-
-
-
- +
+
+
+
+
+ +
@@ -67,11 +68,12 @@ let idPool = 0;
` }) -export class PanelComponent extends Disposable implements AfterContentInit, OnInit, OnChanges, OnDestroy, AfterViewInit { +export class PanelComponent extends Disposable { @Input() public options: IPanelOptions; @Input() public actions: Array; @ContentChildren(TabComponent) private _tabs: QueryList; @ViewChildren(TabHeaderComponent) private _headerTabs: QueryList; + @ViewChild(ScrollableDirective) private scrollable: ScrollableDirective; @Output() public onTabChange = new EventEmitter(); @Output() public onTabClose = new EventEmitter(); @@ -79,12 +81,11 @@ export class PanelComponent extends Disposable implements AfterContentInit, OnIn private _activeTab: TabComponent; private _actionbar: ActionBar; private _mru: TabComponent[]; - private _scrollableElement: ScrollableElement; + + private ScrollbarVisibility = ScrollbarVisibility; + private NavigationBarLayout = NavigationBarLayout; @ViewChild('panelActionbar', { read: ElementRef }) private _actionbarRef: ElementRef; - @ViewChild('tabbedPanel', { read: ElementRef }) private _tabbedPanelRef: ElementRef; - @ViewChild('titleContainer', { read: ElementRef }) private _titleContainer: ElementRef; - @ViewChild('tabList', { read: ElementRef }) private _tabList: ElementRef; constructor( @Inject(forwardRef(() => NgZone)) private _zone: NgZone) { super(); } @@ -96,51 +97,14 @@ export class PanelComponent extends Disposable implements AfterContentInit, OnIn ngAfterContentInit(): void { if (this._tabs && this._tabs.length > 0) { - this._activeTab = this._tabs.first; - this._activeTab.active = true; - } - } - - ngAfterViewInit(): void { - if (!this.options.showTabsWhenOne ? this._tabs.length !== 1 : true) { - let container = this._titleContainer.nativeElement as HTMLElement; - let tabList = this._tabList.nativeElement as HTMLElement; - container.removeChild(tabList); - - this._scrollableElement = new ScrollableElement(tabList, { - horizontal: ScrollbarVisibility.Auto, - vertical: ScrollbarVisibility.Hidden, - scrollYToX: true, - useShadows: false, - horizontalScrollbarSize: 3 + this.selectTab(this._tabs.first); + } else { + const sub = this._tabs.changes.subscribe(() => { + if (this._tabs && this._tabs.length > 0) { + this.selectTab(this._tabs.first); + sub.unsubscribe(); + } }); - - this._scrollableElement.onScroll(e => { - tabList.scrollLeft = e.scrollLeft; - }); - - container.insertBefore(this._scrollableElement.getDomNode(), container.firstChild); - - this._scrollableElement.setScrollDimensions({ - width: tabList.offsetWidth, - scrollWidth: tabList.scrollWidth - }); - - this._register(addDisposableListener(window, EventType.RESIZE, () => { - // Todo: Need to set timeout because we have to make sure that the grids have already rearraged before the getContentHeight gets called. - setTimeout(() => { - this._scrollableElement.setScrollDimensions({ - width: tabList.offsetWidth, - scrollWidth: tabList.scrollWidth - }); - }, 100); - })); - - if (this.options.layout === NavigationBarLayout.horizontal) { - (this._tabbedPanelRef.nativeElement).classList.add(horizontalLayout); - } else { - (this._tabbedPanelRef.nativeElement).classList.add(verticalLayout); - } } } @@ -154,6 +118,17 @@ export class PanelComponent extends Disposable implements AfterContentInit, OnIn } } + ngAfterViewInit(): void { + this._tabs.changes.subscribe(() => { + if (this.scrollable) { + this.scrollable.layout(); + } + }); + if (this.scrollable) { + this.scrollable.layout(); + } + } + ngOnDestroy() { if (this._actionbar) { this._actionbar.dispose(); @@ -210,12 +185,6 @@ export class PanelComponent extends Disposable implements AfterContentInit, OnIn this.setMostRecentlyUsed(tab); this._activeTab.active = true; - // Make the tab header focus on the new selected tab - let activeTabHeader = this._headerTabs.find(i => i.tab === this._activeTab); - if (activeTabHeader) { - activeTabHeader.focusOnTabHeader(); - } - this.onTabChange.emit(tab); }); } diff --git a/src/sql/base/browser/ui/panel/panel.module.ts b/src/sql/base/browser/ui/panel/panel.module.ts index 164806670b..c1f9d345bf 100644 --- a/src/sql/base/browser/ui/panel/panel.module.ts +++ b/src/sql/base/browser/ui/panel/panel.module.ts @@ -9,9 +9,11 @@ import { TabComponent } from './tab.component'; import { TabHeaderComponent } from './tabHeader.component'; import { PanelComponent } from './panel.component'; +import { ScrollableModule } from 'sql/base/browser/ui/scrollable/scrollable.module'; + @NgModule({ - imports: [CommonModule], + imports: [CommonModule, ScrollableModule], exports: [TabComponent, PanelComponent], declarations: [TabComponent, TabHeaderComponent, PanelComponent] }) -export class PanelModule { } \ No newline at end of file +export class PanelModule { } diff --git a/src/sql/base/browser/ui/panel/panelStyles.ts b/src/sql/base/browser/ui/panel/panelStyles.ts index 532ec0f998..c385fcd843 100644 --- a/src/sql/base/browser/ui/panel/panelStyles.ts +++ b/src/sql/base/browser/ui/panel/panelStyles.ts @@ -15,13 +15,13 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const titleActiveBorder = theme.getColor(PANEL_ACTIVE_TITLE_BORDER); if (titleActive || titleActiveBorder) { collector.addRule(` - .tabbedPanel > .title > .tabList .tab:hover .tabLabel, - .tabbedPanel > .title > .tabList .tab .tabLabel.active { + .tabbedPanel > .title .tabList .tab:hover .tabLabel, + .tabbedPanel > .title .tabList .tab .tabLabel.active { color: ${titleActive}; border-bottom-color: ${titleActiveBorder}; } - .tabbedPanel > .title > .tabList .tab-header.active { + .tabbedPanel > .title .tabList .tab-header.active { outline: none; } `); @@ -31,7 +31,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const titleInactive = theme.getColor(PANEL_INACTIVE_TITLE_FOREGROUND); if (titleInactive) { collector.addRule(` - .tabbedPanel > .title > .tabList .tab .tabLabel { + .tabbedPanel > .title .tabList .tab .tabLabel { color: ${titleInactive}; } `); @@ -41,7 +41,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const focusBorderColor = theme.getColor(focusBorder); if (focusBorderColor) { collector.addRule(` - .tabbedPanel > .title > .tabList .tab .tabLabel:focus { + .tabbedPanel > .title .tabList .tab .tabLabel:focus { color: ${titleActive}; border-bottom-color: ${focusBorderColor} !important; border-bottom: 1px solid; @@ -54,8 +54,8 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const outline = theme.getColor(activeContrastBorder); if (outline) { collector.addRule(` - .tabbedPanel > .title > .tabList .tab-header.active, - .tabbedPanel > .title > .tabList .tab-header:hover { + .tabbedPanel > .title .tabList .tab-header.active, + .tabbedPanel > .title .tabList .tab-header:hover { outline-color: ${outline}; outline-width: 1px; outline-style: solid; @@ -63,7 +63,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { outline-offset: -5px; } - .tabbedPanel > .title > .tabList .tab-header:hover:not(.active) { + .tabbedPanel > .title .tabList .tab-header:hover:not(.active) { outline-style: dashed; } `); diff --git a/src/sql/base/browser/ui/panel/tab.component.ts b/src/sql/base/browser/ui/panel/tab.component.ts index e19ae4b81b..0ab41ee8e5 100644 --- a/src/sql/base/browser/ui/panel/tab.component.ts +++ b/src/sql/base/browser/ui/panel/tab.component.ts @@ -2,7 +2,7 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Component, Input, ContentChild, OnDestroy } from '@angular/core'; +import { Component, Input, ContentChild, OnDestroy, TemplateRef, ChangeDetectorRef, forwardRef, Inject } from '@angular/core'; import { Action } from 'vs/base/common/actions'; @@ -13,13 +13,14 @@ export abstract class TabChild { @Component({ selector: 'tab', template: ` -
- +
+
` }) export class TabComponent implements OnDestroy { @ContentChild(TabChild) private _child: TabChild; + @ContentChild(TemplateRef) templateRef; @Input() public title: string; @Input() public canClose: boolean; @Input() public actions: Array; @@ -27,9 +28,18 @@ export class TabComponent implements OnDestroy { public _active = false; @Input() public identifier: string; @Input() private visibilityType: 'if' | 'visibility' = 'if'; + private rendered = false; + + constructor( + @Inject(forwardRef(() => ChangeDetectorRef)) private _cd: ChangeDetectorRef + ) { } public set active(val: boolean) { this._active = val; + if (this.active) { + this.rendered = true; + } + this._cd.detectChanges(); if (this.active && this._child) { this._child.layout(); } @@ -45,4 +55,21 @@ export class TabComponent implements OnDestroy { } } + shouldBeIfed(): boolean { + if (this.active) { + return true; + } else if (this.visibilityType === 'visibility' && this.rendered) { + return true; + } else { + return false; + } + } + + shouldBeHidden(): boolean { + if (this.visibilityType === 'visibility' && !this.active) { + return true; + } else { + return false; + } + } } diff --git a/src/sql/base/browser/ui/panel/tabHeader.component.ts b/src/sql/base/browser/ui/panel/tabHeader.component.ts index 55599442d2..dd594126b7 100644 --- a/src/sql/base/browser/ui/panel/tabHeader.component.ts +++ b/src/sql/base/browser/ui/panel/tabHeader.component.ts @@ -19,7 +19,7 @@ import { CloseTabAction } from './tabActions'; @Component({ selector: 'tab-header', template: ` -
+
@@ -31,6 +31,7 @@ import { CloseTabAction } from './tabActions'; export class TabHeaderComponent extends Disposable implements AfterContentInit, OnDestroy { @Input() public tab: TabComponent; @Input() public showIcon: boolean; + @Input() public active: boolean; @Output() public onSelectTab: EventEmitter = new EventEmitter(); @Output() public onCloseTab: EventEmitter = new EventEmitter(); diff --git a/src/sql/base/browser/ui/scrollable/scrollable.directive.ts b/src/sql/base/browser/ui/scrollable/scrollable.directive.ts index f2488871e3..a80aa91eb0 100644 --- a/src/sql/base/browser/ui/scrollable/scrollable.directive.ts +++ b/src/sql/base/browser/ui/scrollable/scrollable.directive.ts @@ -3,11 +3,11 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Directive, Inject, forwardRef, ElementRef } from '@angular/core'; +import { Directive, Inject, forwardRef, ElementRef, Input } from '@angular/core'; import { ScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; import { ScrollbarVisibility } from 'vs/base/common/scrollable'; -import { getContentHeight, addDisposableListener, EventType } from 'vs/base/browser/dom'; +import { getContentHeight, addDisposableListener, EventType, getContentWidth } from 'vs/base/browser/dom'; import { AngularDisposable } from 'sql/base/common/lifecycle'; @Directive({ @@ -17,33 +17,45 @@ export class ScrollableDirective extends AngularDisposable { private scrollableElement: ScrollableElement; private parent: HTMLElement; private scrolled: HTMLElement; + @Input() horizontalScroll: ScrollbarVisibility; + @Input() verticalScroll: ScrollbarVisibility; + @Input() useShadow = false; + @Input() scrollYToX = false; constructor( @Inject(forwardRef(() => ElementRef)) private _el: ElementRef ) { super(); + } + + ngOnInit() { this.scrolled = this._el.nativeElement as HTMLElement; this.parent = this.scrolled.parentElement; + const next = this.scrolled.nextSibling; this.parent.removeChild(this.scrolled); this.scrolled.style.position = 'relative'; this.scrollableElement = new ScrollableElement(this.scrolled, { - horizontal: ScrollbarVisibility.Hidden, - vertical: ScrollbarVisibility.Auto, - useShadows: false + horizontal: this.horizontalScroll, + vertical: this.verticalScroll, + useShadows: this.useShadow, + scrollYToX: this.scrollYToX, + horizontalScrollbarSize: 3 }); this.scrollableElement.onScroll(e => { - this.scrolled.style.bottom = e.scrollTop + 'px'; + if (this.verticalScroll === ScrollbarVisibility.Auto) { + this.scrolled.style.bottom = e.scrollTop + 'px'; + } else if (this.horizontalScroll === ScrollbarVisibility.Auto) { + this.scrolled.scrollLeft = e.scrollLeft; + } }); - this.parent.appendChild(this.scrollableElement.getDomNode()); + this.parent.insertBefore(this.scrollableElement.getDomNode(), next); const initialHeight = getContentHeight(this.scrolled); - this.scrollableElement.setScrollDimensions({ - scrollHeight: getContentHeight(this.scrolled), - height: getContentHeight(this.parent) - }); + const initalWidth = getContentWidth(this.scrolled); + this.resetScrollDimensions(); this._register(addDisposableListener(window, EventType.RESIZE, () => { this.resetScrollDimensions(); @@ -52,24 +64,23 @@ export class ScrollableDirective extends AngularDisposable { // unforunately because of angular rendering behavior we need to do a double check to make sure nothing changed after this point setTimeout(() => { let currentheight = getContentHeight(this.scrolled); - if (initialHeight !== currentheight) { - this.scrollableElement.setScrollDimensions({ - scrollHeight: currentheight, - height: getContentHeight(this.parent) - }); + let currentWidth = getContentWidth(this.scrolled); + if (initialHeight !== currentheight || initalWidth !== currentWidth) { + this.resetScrollDimensions(); } }, 200); - } private resetScrollDimensions() { this.scrollableElement.setScrollDimensions({ - scrollHeight: getContentHeight(this.scrolled), - height: getContentHeight(this.parent) + scrollHeight: this.verticalScroll === ScrollbarVisibility.Auto ? getContentHeight(this.scrolled) : undefined, + height: this.verticalScroll === ScrollbarVisibility.Auto ? getContentHeight(this.parent) : undefined, + scrollWidth: this.horizontalScroll === ScrollbarVisibility.Auto ? this.scrolled.scrollWidth : undefined, + width: this.horizontalScroll === ScrollbarVisibility.Auto ? this.scrolled.offsetWidth : undefined }); } public layout() { - + this.resetScrollDimensions(); } } diff --git a/src/sql/base/browser/ui/scrollable/scrollable.module.ts b/src/sql/base/browser/ui/scrollable/scrollable.module.ts new file mode 100644 index 0000000000..32b5f65bf4 --- /dev/null +++ b/src/sql/base/browser/ui/scrollable/scrollable.module.ts @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { ScrollableDirective } from './scrollable.directive'; + +@NgModule({ + imports: [CommonModule], + exports: [ScrollableDirective], + declarations: [ScrollableDirective] +}) +export class ScrollableModule { } diff --git a/src/sql/parts/dashboard/common/dashboardPage.component.html b/src/sql/parts/dashboard/common/dashboardPage.component.html index 8683f6cf4f..e395408a87 100644 --- a/src/sql/parts/dashboard/common/dashboardPage.component.html +++ b/src/sql/parts/dashboard/common/dashboardPage.component.html @@ -6,23 +6,25 @@ --> - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + diff --git a/src/sql/parts/dashboard/common/dashboardPage.component.ts b/src/sql/parts/dashboard/common/dashboardPage.component.ts index 63e8bb7e2c..0bb1fd2f3b 100644 --- a/src/sql/parts/dashboard/common/dashboardPage.component.ts +++ b/src/sql/parts/dashboard/common/dashboardPage.component.ts @@ -17,7 +17,7 @@ import { IPropertiesConfig } from 'sql/parts/dashboard/pages/serverDashboardPage import { PanelComponent } from 'sql/base/browser/ui/panel/panel.component'; import { IDashboardRegistry, Extensions as DashboardExtensions, IDashboardTab } from 'sql/platform/dashboard/common/dashboardRegistry'; import { PinUnpinTabAction, AddFeatureTabAction } from './actions'; -import { TabComponent } from 'sql/base/browser/ui/panel/tab.component'; +import { TabComponent, TabChild } from 'sql/base/browser/ui/panel/tab.component'; import { IBootstrapService, BOOTSTRAP_SERVICE_ID } from 'sql/services/bootstrap/bootstrapService'; import { AngularEventType } from 'sql/services/angularEventing/angularEventingService'; import { DashboardTab } from 'sql/parts/dashboard/common/interfaces'; @@ -61,7 +61,7 @@ export abstract class DashboardPage extends AngularDisposable { private _tabsDispose: Array = []; private _tabSettingConfigs: Array = []; - @ViewChildren(DashboardTab) private _tabs: QueryList; + @ViewChildren(TabChild) private _tabs: QueryList; @ViewChild(PanelComponent) private _panel: PanelComponent; private _editEnabled = new Emitter(); @@ -142,7 +142,6 @@ export abstract class DashboardPage extends AngularDisposable { actions: [] }; this.addNewTab(homeTab); - this._panel.selectTab(homeTab.id); let allTabs = dashboardHelper.filterConfigs(dashboardRegistry.tabs, this.dashboardService); @@ -254,7 +253,6 @@ export abstract class DashboardPage extends AngularDisposable { } } - private getContentType(tab: TabConfig): string { return tab.container ? Object.keys(tab.container)[0] : ''; } @@ -310,10 +308,10 @@ export abstract class DashboardPage extends AngularDisposable { } public handleTabChange(tab: TabComponent): void { + this._cd.detectChanges(); let localtab = this._tabs.find(i => i.id === tab.identifier); this._editEnabled.fire(localtab.editable); this._cd.detectChanges(); - localtab.layout(); } public handleTabClose(tab: TabComponent): void { diff --git a/src/sql/parts/dashboard/common/dashboardPanelStyles.ts b/src/sql/parts/dashboard/common/dashboardPanelStyles.ts index 6b9bdcbf76..c25fc78688 100644 --- a/src/sql/parts/dashboard/common/dashboardPanelStyles.ts +++ b/src/sql/parts/dashboard/common/dashboardPanelStyles.ts @@ -15,22 +15,22 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const tabActiveForeground = theme.getColor(TAB_ACTIVE_FOREGROUND); if (tabActiveBackground || tabActiveForeground) { collector.addRule(` - panel.dashboard-panel > .tabbedPanel > .title > .monaco-scrollable-element > .tabList .tab:hover .tabLabel, - panel.dashboard-panel > .tabbedPanel > .title > .monaco-scrollable-element > .tabList .tab .tabLabel.active { + panel.dashboard-panel > .tabbedPanel > .title .tabList .tab:hover .tabLabel, + panel.dashboard-panel > .tabbedPanel > .title .tabList .tab .tabLabel.active { color: ${tabActiveForeground}; border-bottom: 0px solid; } - panel.dashboard-panel > .tabbedPanel > .title > .monaco-scrollable-element > .tabList .tab-header.active { + panel.dashboard-panel > .tabbedPanel > .title .tabList .tab-header.active { background-color: ${tabActiveBackground}; outline-color: ${tabActiveBackground}; } - panel.dashboard-panel > .tabbedPanel.horizontal > .title > .monaco-scrollable-element > .tabList .tab-header.active { + panel.dashboard-panel > .tabbedPanel.horizontal > .title .tabList .tab-header.active { border-bottom-color: transparent; } - panel.dashboard-panel > .tabbedPanel.vertical > .title > .monaco-scrollable-element > .tabList .tab-header.active { + panel.dashboard-panel > .tabbedPanel.vertical > .title .tabList .tab-header.active { border-right-color: transparent; } `); @@ -39,7 +39,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const activeTabBorderColor = theme.getColor(TAB_ACTIVE_BORDER); if (activeTabBorderColor) { collector.addRule(` - panel.dashboard-panel > .tabbedPanel > .title > .monaco-scrollable-element > .tabList .tab-header.active { + panel.dashboard-panel > .tabbedPanel > .title .tabList .tab-header.active { box-shadow: ${activeTabBorderColor} 0 -1px inset; } `); @@ -50,11 +50,11 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const tabInactiveForeground = theme.getColor(TAB_INACTIVE_FOREGROUND); if (tabInactiveBackground || tabInactiveForeground) { collector.addRule(` - panel.dashboard-panel > .tabbedPanel > .title > .monaco-scrollable-element > .tabList .tab .tabLabel { + panel.dashboard-panel > .tabbedPanel > .title .tabList .tab .tabLabel { color: ${tabInactiveForeground}; } - panel.dashboard-panel > .tabbedPanel > .title > .monaco-scrollable-element > .tabList .tab-header { + panel.dashboard-panel > .tabbedPanel > .title .tabList .tab-header { background-color: ${tabInactiveBackground}; } `); @@ -74,7 +74,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const tabBoarder = theme.getColor(TAB_BORDER); if (tabBoarder) { collector.addRule(` - panel.dashboard-panel > .tabbedPanel > .title > .monaco-scrollable-element > .tabList .tab-header { + panel.dashboard-panel > .tabbedPanel > .title .tabList .tab-header { border-right-color: ${tabBoarder}; border-bottom-color: ${tabBoarder}; } diff --git a/src/sql/parts/dashboard/common/interfaces.ts b/src/sql/parts/dashboard/common/interfaces.ts index 9fb2c1e984..6f9ba0de7b 100644 --- a/src/sql/parts/dashboard/common/interfaces.ts +++ b/src/sql/parts/dashboard/common/interfaces.ts @@ -3,9 +3,13 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { OnDestroy } from '@angular/core'; + import Event from 'vs/base/common/event'; +import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { AngularDisposable } from 'sql/base/common/lifecycle'; +import { TabChild } from 'sql/base/browser/ui/panel/tab.component'; export enum Conditional { 'equals', @@ -17,7 +21,7 @@ export enum Conditional { 'always' } -export abstract class DashboardTab extends AngularDisposable { +export abstract class DashboardTab extends TabChild implements OnDestroy { public abstract layout(): void; public abstract readonly id: string; public abstract readonly editable: boolean; @@ -26,4 +30,23 @@ export abstract class DashboardTab extends AngularDisposable { public enableEdit(): void { // no op } + + private _toDispose: IDisposable[] = []; + + constructor() { + super(); + } + + public dispose(): void { + this._toDispose = dispose(this._toDispose); + } + + protected _register(t: T): T { + this._toDispose.push(t); + return t; + } + + ngOnDestroy() { + this.dispose(); + } } diff --git a/src/sql/parts/dashboard/containers/dashboardControlHostContainer.component.ts b/src/sql/parts/dashboard/containers/dashboardControlHostContainer.component.ts index 4ac0a72be2..6b66a06bac 100644 --- a/src/sql/parts/dashboard/containers/dashboardControlHostContainer.component.ts +++ b/src/sql/parts/dashboard/containers/dashboardControlHostContainer.component.ts @@ -5,14 +5,17 @@ import 'vs/css!./dashboardControlHostContainer'; import { Component, forwardRef, Input, AfterContentInit, ViewChild, OnChanges } from '@angular/core'; + import Event, { Emitter } from 'vs/base/common/event'; + import { DashboardTab } from 'sql/parts/dashboard/common/interfaces'; import { TabConfig } from 'sql/parts/dashboard/common/dashboardWidget'; import { ControlHostContent } from 'sql/parts/dashboard/contents/controlHostContent.component'; +import { TabChild } from 'sql/base/browser/ui/panel/tab.component'; @Component({ selector: 'dashboard-controlhost-container', - providers: [{ provide: DashboardTab, useExisting: forwardRef(() => DashboardControlHostContainer) }], + providers: [{ provide: TabChild, useExisting: forwardRef(() => DashboardControlHostContainer) }], template: ` diff --git a/src/sql/parts/dashboard/containers/dashboardErrorContainer.component.ts b/src/sql/parts/dashboard/containers/dashboardErrorContainer.component.ts index d007009904..897441d7a3 100644 --- a/src/sql/parts/dashboard/containers/dashboardErrorContainer.component.ts +++ b/src/sql/parts/dashboard/containers/dashboardErrorContainer.component.ts @@ -9,13 +9,14 @@ import { Component, Inject, Input, forwardRef, ViewChild, ElementRef, ChangeDete import { TabConfig } from 'sql/parts/dashboard/common/dashboardWidget'; import { DashboardTab } from 'sql/parts/dashboard/common/interfaces'; +import { TabChild } from 'sql/base/browser/ui/panel/tab.component'; import Event, { Emitter } from 'vs/base/common/event'; import * as nls from 'vs/nls'; @Component({ selector: 'dashboard-error-container', - providers: [{ provide: DashboardTab, useExisting: forwardRef(() => DashboardErrorContainer) }], + providers: [{ provide: TabChild, useExisting: forwardRef(() => DashboardErrorContainer) }], template: `
diff --git a/src/sql/parts/dashboard/containers/dashboardGridContainer.component.ts b/src/sql/parts/dashboard/containers/dashboardGridContainer.component.ts index a7875d9346..3c9c0538ef 100644 --- a/src/sql/parts/dashboard/containers/dashboardGridContainer.component.ts +++ b/src/sql/parts/dashboard/containers/dashboardGridContainer.component.ts @@ -7,6 +7,7 @@ import 'vs/css!./dashboardGridContainer'; import { Component, Inject, Input, forwardRef, ViewChild, ElementRef, ViewChildren, QueryList, OnDestroy, ChangeDetectorRef, EventEmitter } from '@angular/core'; import { NgGridConfig, NgGrid, NgGridItem } from 'angular2-grid'; +import { concat } from 'rxjs/operator/concat'; import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service'; import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service'; @@ -14,13 +15,13 @@ import { TabConfig, WidgetConfig } from 'sql/parts/dashboard/common/dashboardWid import { DashboardWidgetWrapper } from 'sql/parts/dashboard/contents/dashboardWidgetWrapper.component'; import { subscriptionToDisposable } from 'sql/base/common/lifecycle'; import { DashboardTab } from 'sql/parts/dashboard/common/interfaces'; +import { WebviewContent } from 'sql/parts/dashboard/contents/webviewContent.component'; +import { TabChild } from 'sql/base/browser/ui/panel/tab.component'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import * as objects from 'vs/base/common/objects'; import Event, { Emitter } from 'vs/base/common/event'; -import { concat } from 'rxjs/operator/concat'; -import { WebviewContent } from 'sql/parts/dashboard/contents/webviewContent.component'; export interface GridCellConfig { id?: string; @@ -42,7 +43,7 @@ export interface GridWebviewConfig extends GridCellConfig { @Component({ selector: 'dashboard-grid-container', templateUrl: decodeURI(require.toUrl('sql/parts/dashboard/containers/dashboardGridContainer.component.html')), - providers: [{ provide: DashboardTab, useExisting: forwardRef(() => DashboardGridContainer) }] + providers: [{ provide: TabChild, useExisting: forwardRef(() => DashboardGridContainer) }] }) export class DashboardGridContainer extends DashboardTab implements OnDestroy { @Input() private tab: TabConfig; diff --git a/src/sql/parts/dashboard/containers/dashboardHomeContainer.component.ts b/src/sql/parts/dashboard/containers/dashboardHomeContainer.component.ts index e2d0424b10..fdb10bd883 100644 --- a/src/sql/parts/dashboard/containers/dashboardHomeContainer.component.ts +++ b/src/sql/parts/dashboard/containers/dashboardHomeContainer.component.ts @@ -14,15 +14,18 @@ import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboar import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service'; import { AngularEventType } from 'sql/services/angularEventing/angularEventingService'; import { DashboardWidgetWrapper } from 'sql/parts/dashboard/contents/dashboardWidgetWrapper.component'; -import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { ScrollableDirective } from 'sql/base/browser/ui/scrollable/scrollable.directive'; +import { TabChild } from 'sql/base/browser/ui/panel/tab.component'; + +import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; +import { ScrollbarVisibility } from 'vs/base/common/scrollable'; @Component({ selector: 'dashboard-home-container', - providers: [{ provide: DashboardTab, useExisting: forwardRef(() => DashboardHomeContainer) }], + providers: [{ provide: TabChild, useExisting: forwardRef(() => DashboardHomeContainer) }], template: `
-
+
@@ -37,6 +40,8 @@ export class DashboardHomeContainer extends DashboardWidgetContainer { @ViewChild('propertiesClass') private _propertiesClass: DashboardWidgetWrapper; @ContentChild(ScrollableDirective) private _scrollable; + private ScrollbarVisibility = ScrollbarVisibility; + constructor( @Inject(forwardRef(() => ChangeDetectorRef)) _cd: ChangeDetectorRef, @Inject(forwardRef(() => CommonServiceInterface)) protected dashboardService: DashboardServiceInterface diff --git a/src/sql/parts/dashboard/containers/dashboardModelViewContainer.component.ts b/src/sql/parts/dashboard/containers/dashboardModelViewContainer.component.ts index 012cd2775b..18b128a678 100644 --- a/src/sql/parts/dashboard/containers/dashboardModelViewContainer.component.ts +++ b/src/sql/parts/dashboard/containers/dashboardModelViewContainer.component.ts @@ -11,10 +11,11 @@ import Event, { Emitter } from 'vs/base/common/event'; import { DashboardTab } from 'sql/parts/dashboard/common/interfaces'; import { TabConfig } from 'sql/parts/dashboard/common/dashboardWidget'; import { ModelViewContent } from 'sql/parts/modelComponents/modelViewContent.component'; +import { TabChild } from 'sql/base/browser/ui/panel/tab.component'; @Component({ selector: 'dashboard-modelview-container', - providers: [{ provide: DashboardTab, useExisting: forwardRef(() => DashboardModelViewContainer) }], + providers: [{ provide: TabChild, useExisting: forwardRef(() => DashboardModelViewContainer) }], template: ` diff --git a/src/sql/parts/dashboard/containers/dashboardNavSection.component.html b/src/sql/parts/dashboard/containers/dashboardNavSection.component.html index 9d10c20f46..7193e2bad8 100644 --- a/src/sql/parts/dashboard/containers/dashboardNavSection.component.html +++ b/src/sql/parts/dashboard/containers/dashboardNavSection.component.html @@ -4,18 +4,20 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ --> - + - - - - - - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/src/sql/parts/dashboard/containers/dashboardNavSection.component.ts b/src/sql/parts/dashboard/containers/dashboardNavSection.component.ts index 1bb8abeef5..b9f76c32e8 100644 --- a/src/sql/parts/dashboard/containers/dashboardNavSection.component.ts +++ b/src/sql/parts/dashboard/containers/dashboardNavSection.component.ts @@ -11,7 +11,7 @@ import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboar import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service'; import { WidgetConfig, TabConfig, NavSectionConfig } from 'sql/parts/dashboard/common/dashboardWidget'; import { PanelComponent, IPanelOptions, NavigationBarLayout } from 'sql/base/browser/ui/panel/panel.component'; -import { TabComponent } from 'sql/base/browser/ui/panel/tab.component'; +import { TabComponent, TabChild } from 'sql/base/browser/ui/panel/tab.component'; import { DashboardTab } from 'sql/parts/dashboard/common/interfaces'; import { WIDGETS_CONTAINER } from 'sql/parts/dashboard/containers/dashboardWidgetContainer.contribution'; import { GRID_CONTAINER } from 'sql/parts/dashboard/containers/dashboardGridContainer.contribution'; @@ -23,7 +23,7 @@ import * as nls from 'vs/nls'; @Component({ selector: 'dashboard-nav-section', - providers: [{ provide: DashboardTab, useExisting: forwardRef(() => DashboardNavSection) }], + providers: [{ provide: TabChild, useExisting: forwardRef(() => DashboardNavSection) }], templateUrl: decodeURI(require.toUrl('sql/parts/dashboard/containers/dashboardNavSection.component.html')) }) export class DashboardNavSection extends DashboardTab implements OnDestroy, OnChanges, AfterContentInit { @@ -51,7 +51,7 @@ export class DashboardNavSection extends DashboardTab implements OnDestroy, OnCh dashboardHelper.validateGridConfig ]; - @ViewChildren(DashboardTab) private _tabs: QueryList; + @ViewChildren(TabChild) private _tabs: QueryList; @ViewChild(PanelComponent) private _panel: PanelComponent; constructor( @Inject(forwardRef(() => CommonServiceInterface)) protected dashboardService: CommonServiceInterface, @@ -124,11 +124,6 @@ export class DashboardNavSection extends DashboardTab implements OnDestroy, OnCh this.addNewTab(config); return config; }); - - // put this immediately on the stack so that is ran *after* the tab is rendered - setTimeout(() => { - this._panel.selectTab(selectedTabs[0].id); - }); } } @@ -174,10 +169,4 @@ export class DashboardNavSection extends DashboardTab implements OnDestroy, OnCh }); } } - - public handleTabChange(tab: TabComponent): void { - let localtab = this._tabs.find(i => i.id === tab.identifier); - this._cd.detectChanges(); - localtab.layout(); - } } diff --git a/src/sql/parts/dashboard/containers/dashboardWebviewContainer.component.ts b/src/sql/parts/dashboard/containers/dashboardWebviewContainer.component.ts index cef04911f0..7c10b7df2d 100644 --- a/src/sql/parts/dashboard/containers/dashboardWebviewContainer.component.ts +++ b/src/sql/parts/dashboard/containers/dashboardWebviewContainer.component.ts @@ -11,10 +11,11 @@ import Event, { Emitter } from 'vs/base/common/event'; import { DashboardTab } from 'sql/parts/dashboard/common/interfaces'; import { TabConfig } from 'sql/parts/dashboard/common/dashboardWidget'; import { WebviewContent } from 'sql/parts/dashboard/contents/webviewContent.component'; +import { TabChild } from 'sql/base/browser/ui/panel/tab.component'; @Component({ selector: 'dashboard-webview-container', - providers: [{ provide: DashboardTab, useExisting: forwardRef(() => DashboardWebviewContainer) }], + providers: [{ provide: TabChild, useExisting: forwardRef(() => DashboardWebviewContainer) }], template: ` diff --git a/src/sql/parts/dashboard/containers/dashboardWidgetContainer.component.ts b/src/sql/parts/dashboard/containers/dashboardWidgetContainer.component.ts index 49ae19d4d4..43209668bb 100644 --- a/src/sql/parts/dashboard/containers/dashboardWidgetContainer.component.ts +++ b/src/sql/parts/dashboard/containers/dashboardWidgetContainer.component.ts @@ -14,6 +14,7 @@ import { DashboardWidgetWrapper } from 'sql/parts/dashboard/contents/dashboardWi import { subscriptionToDisposable } from 'sql/base/common/lifecycle'; import { DashboardTab } from 'sql/parts/dashboard/common/interfaces'; import { WidgetContent } from 'sql/parts/dashboard/contents/widgetContent.component'; +import { TabChild } from 'sql/base/browser/ui/panel/tab.component'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; @@ -22,7 +23,7 @@ import Event, { Emitter } from 'vs/base/common/event'; @Component({ selector: 'dashboard-widget-container', - providers: [{ provide: DashboardTab, useExisting: forwardRef(() => DashboardWidgetContainer) }], + providers: [{ provide: TabChild, useExisting: forwardRef(() => DashboardWidgetContainer) }], template: ` diff --git a/src/sql/parts/dashboard/contents/controlHostContent.component.ts b/src/sql/parts/dashboard/contents/controlHostContent.component.ts index 0d72c39578..2e684ff1ce 100644 --- a/src/sql/parts/dashboard/contents/controlHostContent.component.ts +++ b/src/sql/parts/dashboard/contents/controlHostContent.component.ts @@ -10,7 +10,6 @@ import Event, { Emitter } from 'vs/base/common/event'; import { Parts } from 'vs/workbench/services/part/common/partService'; import { IDisposable } from 'vs/base/common/lifecycle'; -import { DashboardTab } from 'sql/parts/dashboard/common/interfaces'; import { TabConfig } from 'sql/parts/dashboard/common/dashboardWidget'; import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service'; import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service'; diff --git a/src/sql/parts/dashboard/contents/webviewContent.component.ts b/src/sql/parts/dashboard/contents/webviewContent.component.ts index 715ec72895..9019b38d92 100644 --- a/src/sql/parts/dashboard/contents/webviewContent.component.ts +++ b/src/sql/parts/dashboard/contents/webviewContent.component.ts @@ -13,7 +13,6 @@ import { IDisposable, Disposable } from 'vs/base/common/lifecycle'; import { addDisposableListener, EventType } from 'vs/base/browser/dom'; import { memoize } from 'vs/base/common/decorators'; -import { DashboardTab } from 'sql/parts/dashboard/common/interfaces'; import { TabConfig } from 'sql/parts/dashboard/common/dashboardWidget'; import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service'; import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service'; @@ -37,15 +36,13 @@ export class WebviewContent extends AngularDisposable implements OnInit, IDashbo private _onMessageDisposable: IDisposable; private _webview: Webview; private _html: string; - private _dashboardService: DashboardServiceInterface; constructor( - @Inject(forwardRef(() => CommonServiceInterface)) private commonService: CommonServiceInterface, + @Inject(forwardRef(() => CommonServiceInterface)) private _dashboardService: DashboardServiceInterface, @Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef, @Inject(forwardRef(() => ElementRef)) private _el: ElementRef ) { super(); - this._dashboardService = commonService as DashboardServiceInterface; } ngOnInit() { diff --git a/src/sql/parts/dashboard/dashboard.module.ts b/src/sql/parts/dashboard/dashboard.module.ts index 2f904218e4..4bfb75502a 100644 --- a/src/sql/parts/dashboard/dashboard.module.ts +++ b/src/sql/parts/dashboard/dashboard.module.ts @@ -56,12 +56,13 @@ import { JobHistoryComponent } from 'sql/parts/jobManagement/views/jobHistory.co let baseComponents = [DashboardHomeContainer, DashboardComponent, DashboardWidgetWrapper, DashboardWebviewContainer, DashboardWidgetContainer, DashboardGridContainer, DashboardErrorContainer, DashboardNavSection, ModelViewContent, WebviewContent, WidgetContent, ComponentHostDirective, BreadcrumbComponent, ControlHostContent, DashboardControlHostContainer, - JobsViewComponent, AgentViewComponent, JobHistoryComponent, JobStepsViewComponent, DashboardModelViewContainer, ModelComponentWrapper, - ScrollableDirective]; + JobsViewComponent, AgentViewComponent, JobHistoryComponent, JobStepsViewComponent, DashboardModelViewContainer, ModelComponentWrapper]; /* Panel */ import { PanelModule } from 'sql/base/browser/ui/panel/panel.module'; +import { ScrollableModule } from 'sql/base/browser/ui/scrollable/scrollable.module'; + /* Pages */ import { ServerDashboardPage } from 'sql/parts/dashboard/pages/serverDashboardPage.component'; import { DatabaseDashboardPage } from 'sql/parts/dashboard/pages/databaseDashboardPage.component'; @@ -75,7 +76,6 @@ import { TasksWidget } from 'sql/parts/dashboard/widgets/tasks/tasksWidget.compo import { InsightsWidget } from 'sql/parts/dashboard/widgets/insights/insightsWidget.component'; import { WebviewWidget } from 'sql/parts/dashboard/widgets/webview/webviewWidget.component'; import { JobStepsViewComponent } from '../jobManagement/views/jobStepsView.component'; -import { ScrollableDirective } from 'sql/base/browser/ui/scrollable/scrollable.directive'; let widgetComponents = [ PropertiesWidgetComponent, @@ -126,7 +126,8 @@ const appRoutes: Routes = [ NgGridModule, ChartsModule, RouterModule.forRoot(appRoutes), - PanelModule + PanelModule, + ScrollableModule ], providers: [ { provide: APP_BASE_HREF, useValue: '/' }, diff --git a/src/sql/parts/dashboard/widgets/insights/views/tableInsight.component.ts b/src/sql/parts/dashboard/widgets/insights/views/tableInsight.component.ts index d7b85b1b5c..3981405f24 100644 --- a/src/sql/parts/dashboard/widgets/insights/views/tableInsight.component.ts +++ b/src/sql/parts/dashboard/widgets/insights/views/tableInsight.component.ts @@ -10,7 +10,7 @@ import { Dimension } from 'vs/base/browser/builder'; import { IInsightsView, IInsightData } from 'sql/parts/dashboard/widgets/insights/interfaces'; import { Table } from 'sql/base/browser/ui/table/table'; import { TableDataView } from 'sql/base/browser/ui/table/tableDataView'; -import { DragCellSelectionModel } from '../../../../../base/browser/ui/table/plugins/dragCellSelectionModel.plugin'; +import { DragCellSelectionModel } from 'sql/base/browser/ui/table/plugins/dragCellSelectionModel.plugin'; @Component({ template: '' @@ -62,9 +62,9 @@ export default class TableInsight implements IInsightsView, OnInit { } } -function transformData(rows: string[][], columns: string[]): {[key: string]: string}[] { +function transformData(rows: string[][], columns: string[]): { [key: string]: string }[] { return rows.map(row => { - let object: {[key: string]: string} = {}; + let object: { [key: string]: string } = {}; row.forEach((val, index) => { object[columns[index]] = val; }); diff --git a/src/sql/parts/grid/views/query/chartViewer.component.ts b/src/sql/parts/grid/views/query/chartViewer.component.ts index dc6f816bf4..3dbdac1f26 100644 --- a/src/sql/parts/grid/views/query/chartViewer.component.ts +++ b/src/sql/parts/grid/views/query/chartViewer.component.ts @@ -97,12 +97,12 @@ export class ChartViewerComponent implements OnInit, OnDestroy, IChartViewAction @Inject(BOOTSTRAP_SERVICE_ID) private _bootstrapService: IBootstrapService, @Inject(forwardRef(() => ChangeDetectorRef)) private _cd: ChangeDetectorRef ) { + this.setDefaultChartConfig(); } ngOnInit() { - this.setDefaultChartConfig(); this.legendOptions = Object.values(LegendPosition); - this.initializeUI(); + this._initActionBar(); } private setDefaultChartConfig() { @@ -114,11 +114,6 @@ export class ChartViewerComponent implements OnInit, OnDestroy, IChartViewAction }; } - private initializeUI() { - // Initialize the taskbar - this._initActionBar(); - } - private getDefaultChartType(): string { let defaultChartType = Constants.chartTypeHorizontalBar; if (this._bootstrapService.configurationService) { @@ -155,6 +150,10 @@ export class ChartViewerComponent implements OnInit, OnDestroy, IChartViewAction this.initChart(); } + ngAfterViewInit() { + this.initChart(); + } + setConfigValue(key: string, value: any, refresh = true): void { this._chartConfig[key] = value; if (refresh) { @@ -316,7 +315,6 @@ export class ChartViewerComponent implements OnInit, OnDestroy, IChartViewAction this._executeResult.rows = dataSet.dataRows.getRange(0, dataSet.dataRows.getLength()).map(gridRow => { return gridRow.values.map(cell => cell.displayValue); }); - this.initChart(); } public initChart() { diff --git a/src/sql/parts/jobManagement/agent/agentView.component.html b/src/sql/parts/jobManagement/agent/agentView.component.html index 35a114c6a0..94f8922702 100644 --- a/src/sql/parts/jobManagement/agent/agentView.component.html +++ b/src/sql/parts/jobManagement/agent/agentView.component.html @@ -7,12 +7,14 @@ -
- -
-
- -
+ [iconClass]="jobsIconClass"> + +
+ +
+
+ +
+
diff --git a/src/sql/parts/modelComponents/modelViewContent.component.ts b/src/sql/parts/modelComponents/modelViewContent.component.ts index 0aeadb17ea..e6fddcefa6 100644 --- a/src/sql/parts/modelComponents/modelViewContent.component.ts +++ b/src/sql/parts/modelComponents/modelViewContent.component.ts @@ -11,9 +11,8 @@ import { Parts } from 'vs/workbench/services/part/common/partService'; import { IDisposable, Disposable } from 'vs/base/common/lifecycle'; import { addDisposableListener, EventType } from 'vs/base/browser/dom'; import { memoize } from 'vs/base/common/decorators'; -import nls = require('vs/nls'); +import * as nls from 'vs/nls'; -import { DashboardTab } from 'sql/parts/dashboard/common/interfaces'; import { TabConfig } from 'sql/parts/dashboard/common/dashboardWidget'; import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service'; import { IModelView } from 'sql/services/model/modelViewService'; diff --git a/src/sql/parts/query/views/queryOutput.component.html b/src/sql/parts/query/views/queryOutput.component.html index bf96d28a0d..2c55992adf 100644 --- a/src/sql/parts/query/views/queryOutput.component.html +++ b/src/sql/parts/query/views/queryOutput.component.html @@ -6,28 +6,36 @@ --> - -
- -
+ + +
+ +
+
- -
- -
+ + +
+ +
+
- -
- -
+ + +
+ +
+
- -
- - -
+ + +
+ + +
+
\ No newline at end of file diff --git a/src/sql/parts/query/views/queryOutput.component.ts b/src/sql/parts/query/views/queryOutput.component.ts index 08434eead4..8ef7997604 100644 --- a/src/sql/parts/query/views/queryOutput.component.ts +++ b/src/sql/parts/query/views/queryOutput.component.ts @@ -32,18 +32,16 @@ declare type PaneType = 'messages' | 'results'; selector: QUERY_OUTPUT_SELECTOR, templateUrl: decodeURI(require.toUrl('sql/parts/query/views/queryOutput.component.html')) }) -export class QueryOutputComponent implements OnInit, OnDestroy { +export class QueryOutputComponent implements OnDestroy { - @ViewChild('queryComponent') queryComponent: QueryComponent; - - @ViewChild('queryPlanComponent') queryPlanComponent: QueryPlanComponent; - - @ViewChild('topOperationsComponent') topOperationsComponent: TopOperationsComponent; - - @ViewChild('chartViewerComponent') chartViewerComponent: ChartViewerComponent; + @ViewChild(QueryComponent) queryComponent: QueryComponent; + @ViewChild(QueryPlanComponent) queryPlanComponent: QueryPlanComponent; + @ViewChild(TopOperationsComponent) topOperationsComponent: TopOperationsComponent; @ViewChild(PanelComponent) private _panel: PanelComponent; + private activeDataSet: any; + // tslint:disable:no-unused-variable private readonly queryComponentTitle: string = nls.localize('results', 'Results'); private readonly queryPlanTitle: string = nls.localize('queryPlan', 'Query Plan'); @@ -78,7 +76,7 @@ export class QueryOutputComponent implements OnInit, OnDestroy { /** * Called by Angular when the object is initialized */ - public ngOnInit(): void { + public ngAfterViewInit(): void { this._disposables.push(toDisposableSubscription(this.queryComponent.queryPlanAvailable.subscribe((xml) => { this.hasQueryPlan = true; this._cd.detectChanges(); @@ -90,7 +88,7 @@ export class QueryOutputComponent implements OnInit, OnDestroy { this._disposables.push(toDisposableSubscription(this.queryComponent.showChartRequested.subscribe((dataSet) => { this.showChartView = true; this._cd.detectChanges(); - this.chartViewerComponent.dataSet = dataSet; + this.activeDataSet = dataSet; this._panel.selectTab(this.chartViewerTabIdentifier); })));