From f9d8f479b5e9f4cb6b02fdbb91b7b45ae7e57abb Mon Sep 17 00:00:00 2001 From: Anthony Dresser Date: Fri, 23 Feb 2018 13:34:11 -0800 Subject: [PATCH] Move dashboard properties, fix scroll (#758) * started moving properties to home tab * moved properties * refactored panel in dashboard * fix errors * fix miss-naming --- src/sql/base/browser/ui/panel/media/panel.css | 12 ++- .../base/browser/ui/panel/panel.component.ts | 8 +- .../common/dashboardPage.component.html | 36 ++++---- .../common/dashboardPage.component.ts | 90 +------------------ .../dashboardHomeContainer.component.ts | 30 +++++++ .../containers/dashboardHomeContainer.css | 10 +++ .../dashboardWidgetContainer.component.ts | 67 +++++++++++++- .../containers/dashboardWidgetContainer.css | 11 ++- .../contents/webviewContent.component.ts | 1 + src/sql/parts/dashboard/dashboard.module.ts | 6 +- 10 files changed, 156 insertions(+), 115 deletions(-) create mode 100644 src/sql/parts/dashboard/containers/dashboardHomeContainer.component.ts create mode 100644 src/sql/parts/dashboard/containers/dashboardHomeContainer.css diff --git a/src/sql/base/browser/ui/panel/media/panel.css b/src/sql/base/browser/ui/panel/media/panel.css index 5276c38ebe..e99288eefa 100644 --- a/src/sql/base/browser/ui/panel/media/panel.css +++ b/src/sql/base/browser/ui/panel/media/panel.css @@ -8,10 +8,19 @@ border-top-width: 1px; border-top-style: solid; box-sizing: border-box; + display: flex; + flex-direction: column; +} + +panel { + display: block; + height: 100%; + width: 100%; } .tabbedPanel .composite.title { display: flex; + flex: 0 0 auto; } .tabbedPanel .tabList { @@ -70,8 +79,9 @@ height: 100%; } -.tabbedPanel.vertical > .tab-content { +.tabbedPanel > .tab-content { flex: 1; + position: relative; } .tabbedPanel.vertical > .title > .tabList { diff --git a/src/sql/base/browser/ui/panel/panel.component.ts b/src/sql/base/browser/ui/panel/panel.component.ts index 32bec2aaa5..fd8d9bc7ca 100644 --- a/src/sql/base/browser/ui/panel/panel.component.ts +++ b/src/sql/base/browser/ui/panel/panel.component.ts @@ -40,7 +40,7 @@ let idPool = 0; @Component({ selector: 'panel', template: ` -
+
@@ -52,8 +52,10 @@ let idPool = 0;
-
- +
+
+ +
` diff --git a/src/sql/parts/dashboard/common/dashboardPage.component.html b/src/sql/parts/dashboard/common/dashboardPage.component.html index 6b828a5c04..5ec536b133 100644 --- a/src/sql/parts/dashboard/common/dashboardPage.component.html +++ b/src/sql/parts/dashboard/common/dashboardPage.component.html @@ -4,23 +4,19 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ --> -
-
-
- - -
- - - - - - - - - - - - -
-
+ + + + + + + + + + + + + + + + diff --git a/src/sql/parts/dashboard/common/dashboardPage.component.ts b/src/sql/parts/dashboard/common/dashboardPage.component.ts index 58078fadad..2c9fe36efd 100644 --- a/src/sql/parts/dashboard/common/dashboardPage.component.ts +++ b/src/sql/parts/dashboard/common/dashboardPage.component.ts @@ -30,7 +30,6 @@ import * as types from 'vs/base/common/types'; import { Severity } from 'vs/platform/message/common/message'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import * as nls from 'vs/nls'; -import { ScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; import { ScrollbarVisibility } from 'vs/base/common/scrollable'; import { addDisposableListener, getContentHeight, EventType } from 'vs/base/browser/dom'; import { IColorTheme } from 'vs/workbench/services/themes/common/workbenchThemeService'; @@ -50,11 +49,9 @@ const dashboardRegistry = Registry.as(DashboardExtensions.Da }) export abstract class DashboardPage extends Disposable implements OnDestroy { - protected SKELETON_WIDTH = 5; protected tabs: Array = []; private _originalConfig: WidgetConfig[]; - private _scrollableElement: ScrollableElement; private _widgetConfigLocation: string; private _propertiesConfigLocation: string; @@ -63,10 +60,6 @@ export abstract class DashboardPage extends Disposable implements OnDestroy { private _tabsDispose: Array = []; private _pinnedTabs: Array = []; - @ViewChild('properties') private _properties: DashboardWidgetWrapper; - @ViewChild('scrollable', { read: ElementRef }) private _scrollable: ElementRef; - @ViewChild('scrollContainer', { read: ElementRef }) private _scrollContainer: ElementRef; - @ViewChild('propertiesContainer', { read: ElementRef }) private _propertiesContainer: ElementRef; @ViewChildren(DashboardTab) private _tabs: QueryList; @ViewChild(PanelComponent) private _panel: PanelComponent; @@ -91,6 +84,9 @@ export abstract class DashboardPage extends Disposable implements OnDestroy { widgetHelper.validateGridConfig ]; + protected abstract propertiesWidget: WidgetConfig; + protected abstract get context(): string; + constructor( @Inject(forwardRef(() => DashboardServiceInterface)) protected dashboardService: DashboardServiceInterface, @Inject(BOOTSTRAP_SERVICE_ID) protected bootstrapService: IBootstrapService, @@ -122,51 +118,6 @@ export abstract class DashboardPage extends Disposable implements OnDestroy { } } - ngAfterViewInit(): void { - this._register(this.dashboardService.themeService.onDidColorThemeChange(this.updateTheme, this)); - this.updateTheme(this.dashboardService.themeService.getColorTheme()); - let container = this._scrollContainer.nativeElement as HTMLElement; - let scrollable = this._scrollable.nativeElement as HTMLElement; - container.removeChild(scrollable); - this._scrollableElement = new ScrollableElement(scrollable, { - horizontal: ScrollbarVisibility.Hidden, - vertical: ScrollbarVisibility.Auto, - useShadows: false - }); - - this._scrollableElement.onScroll(e => { - scrollable.style.bottom = e.scrollTop + 'px'; - }); - - container.appendChild(this._scrollableElement.getDomNode()); - let initalHeight = getContentHeight(scrollable); - this._scrollableElement.setScrollDimensions({ - scrollHeight: Math.max(getContentHeight(scrollable), getContentHeight(container)), - height: getContentHeight(container) - }); - - 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({ - scrollHeight: Math.max(getContentHeight(scrollable), getContentHeight(container)), - height: getContentHeight(container) - }); - }, 100); - })); - - // 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(scrollable); - if (initalHeight !== currentheight) { - this._scrollableElement.setScrollDimensions({ - scrollHeight: Math.max(getContentHeight(scrollable), getContentHeight(container)), - height: getContentHeight(container) - }); - } - }, 100); - } - private createTabs(homeWidgets: WidgetConfig[]) { // Clear all tabs this.tabs = []; @@ -296,40 +247,13 @@ export abstract class DashboardPage extends Disposable implements OnDestroy { if (!existedTab) { this.tabs.push(tab); this._cd.detectChanges(); - let tabComponents = this._tabs.find(i => i.id === tab.id); - this._register(tabComponents.onResize(() => { - this._scrollableElement.setScrollDimensions({ - scrollHeight: Math.max(getContentHeight(this._scrollable.nativeElement), getContentHeight(this._scrollContainer.nativeElement)), - height: getContentHeight(this._scrollContainer.nativeElement) - }); - })); } } - private updateTheme(theme: IColorTheme): void { - let el = this._propertiesContainer.nativeElement as HTMLElement; - let border = theme.getColor(colors.contrastBorder, true); - let borderColor = theme.getColor(themeColors.SIDE_BAR_BACKGROUND, true); - - if (border) { - el.style.borderColor = border.toString(); - el.style.borderBottomWidth = '1px'; - el.style.borderBottomStyle = 'solid'; - } else if (borderColor) { - el.style.borderBottom = '1px solid ' + borderColor.toString(); - } else { - el.style.border = 'none'; - } - - } - ngOnDestroy() { this.dispose(); } - protected abstract propertiesWidget: WidgetConfig; - protected abstract get context(): string; - private getProperties(): Array { let properties = this.dashboardService.getSettings([this.context, 'properties'].join('.')); this._propertiesConfigLocation = 'default'; @@ -353,9 +277,7 @@ export abstract class DashboardPage extends Disposable implements OnDestroy { public refresh(refreshConfig: boolean = false): void { if (refreshConfig) { this.init(); - this.refreshProperties(); } else { - this.refreshProperties(); if (this._tabs) { this._tabs.forEach(tabContent => { tabContent.refresh(); @@ -364,12 +286,6 @@ export abstract class DashboardPage extends Disposable implements OnDestroy { } } - private refreshProperties(): void { - if (this._properties) { - this._properties.refresh(); - } - } - public enableEdit(): void { if (this._tabs) { this._tabs.forEach(tabContent => { diff --git a/src/sql/parts/dashboard/containers/dashboardHomeContainer.component.ts b/src/sql/parts/dashboard/containers/dashboardHomeContainer.component.ts new file mode 100644 index 0000000000..42baf086da --- /dev/null +++ b/src/sql/parts/dashboard/containers/dashboardHomeContainer.component.ts @@ -0,0 +1,30 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import 'vs/css!./dashboardHomeContainer'; + +import { Component, forwardRef, Input } from '@angular/core'; + +import { DashboardWidgetContainer } from 'sql/parts/dashboard/containers/dashboardWidgetContainer.component'; +import { DashboardTab } from 'sql/parts/dashboard/common/interfaces'; +import { WidgetConfig } from 'sql/parts/dashboard/common/dashboardWidget'; + +@Component({ + selector: 'dashboard-home-container', + providers: [{ provide: DashboardTab, useExisting: forwardRef(() => DashboardHomeContainer) }], + template: ` +
+
+ + + + +
+
+ ` +}) +export class DashboardHomeContainer extends DashboardWidgetContainer { + @Input() private properties: WidgetConfig; +} diff --git a/src/sql/parts/dashboard/containers/dashboardHomeContainer.css b/src/sql/parts/dashboard/containers/dashboardHomeContainer.css new file mode 100644 index 0000000000..050c2a72fa --- /dev/null +++ b/src/sql/parts/dashboard/containers/dashboardHomeContainer.css @@ -0,0 +1,10 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + + dashboard-home-tab { + height: 100%; + width: 100%; + display: block; +} diff --git a/src/sql/parts/dashboard/containers/dashboardWidgetContainer.component.ts b/src/sql/parts/dashboard/containers/dashboardWidgetContainer.component.ts index bbcf1fde7d..6374ebf0b1 100644 --- a/src/sql/parts/dashboard/containers/dashboardWidgetContainer.component.ts +++ b/src/sql/parts/dashboard/containers/dashboardWidgetContainer.component.ts @@ -19,13 +19,20 @@ 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 { ScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; +import { ScrollbarVisibility } from 'vs/base/common/scrollable'; +import { getContentHeight, addDisposableListener, EventType } from 'vs/base/browser/dom'; @Component({ selector: 'dashboard-widget-container', providers: [{ provide: DashboardTab, useExisting: forwardRef(() => DashboardWidgetContainer) }], template: ` - - +
+
+ + +
+
` }) export class DashboardWidgetContainer extends DashboardTab implements OnDestroy, OnChanges, AfterContentInit { @@ -34,7 +41,13 @@ export class DashboardWidgetContainer extends DashboardTab implements OnDestroy, private _onResize = new Emitter(); public readonly onResize: Event = this._onResize.event; + private _scrollableElement: ScrollableElement; + @ViewChild(WidgetContent) private _widgetContent: WidgetContent; + + @ViewChild('scrollable', { read: ElementRef }) private _scrollable: ElementRef; + @ViewChild('scrollContainer', { read: ElementRef }) private _scrollContainer: ElementRef; + constructor( @Inject(forwardRef(() => ChangeDetectorRef)) protected _cd: ChangeDetectorRef ) { @@ -54,6 +67,50 @@ export class DashboardWidgetContainer extends DashboardTab implements OnDestroy, })); } + ngAfterViewInit() { + let container = this._scrollContainer.nativeElement as HTMLElement; + let scrollable = this._scrollable.nativeElement as HTMLElement; + container.removeChild(scrollable); + + this._scrollableElement = new ScrollableElement(scrollable, { + horizontal: ScrollbarVisibility.Hidden, + vertical: ScrollbarVisibility.Auto, + useShadows: false + }); + + this._scrollableElement.onScroll(e => { + scrollable.style.bottom = e.scrollTop + 'px'; + }); + + container.appendChild(this._scrollableElement.getDomNode()); + let initalHeight = getContentHeight(scrollable); + this._scrollableElement.setScrollDimensions({ + scrollHeight: getContentHeight(scrollable), + height: getContentHeight(container) + }); + + 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({ + scrollHeight: getContentHeight(scrollable), + height: getContentHeight(container) + }); + }, 100); + })); + + // 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(scrollable); + if (initalHeight !== currentheight) { + this._scrollableElement.setScrollDimensions({ + scrollHeight: currentheight, + height: getContentHeight(container) + }); + } + }, 200); + } + ngOnDestroy() { this.dispose(); } @@ -67,6 +124,12 @@ export class DashboardWidgetContainer extends DashboardTab implements OnDestroy, } public layout() { + let container = this._scrollContainer.nativeElement as HTMLElement; + let scrollable = this._scrollable.nativeElement as HTMLElement; + this._scrollableElement.setScrollDimensions({ + scrollHeight: getContentHeight(scrollable), + height: getContentHeight(container) + }); this._widgetContent.layout(); } diff --git a/src/sql/parts/dashboard/containers/dashboardWidgetContainer.css b/src/sql/parts/dashboard/containers/dashboardWidgetContainer.css index 1cfc687275..6aea2186b3 100644 --- a/src/sql/parts/dashboard/containers/dashboardWidgetContainer.css +++ b/src/sql/parts/dashboard/containers/dashboardWidgetContainer.css @@ -6,4 +6,13 @@ dashboard-widget-container { height: 100%; width: 100%; -} \ No newline at end of file +} + +.scroll-container { + height: 100%; + width: 100%; +} + +.scrollable { + position: relative; +} diff --git a/src/sql/parts/dashboard/contents/webviewContent.component.ts b/src/sql/parts/dashboard/contents/webviewContent.component.ts index 487f6f3a34..86051bb8d9 100644 --- a/src/sql/parts/dashboard/contents/webviewContent.component.ts +++ b/src/sql/parts/dashboard/contents/webviewContent.component.ts @@ -30,6 +30,7 @@ export class WebviewContent implements OnInit, IDashboardWebview { public readonly onResize: Event = this._onResize.event; private _onMessage = new Emitter(); public readonly onMessage: Event = this._onMessage.event; + private _onMessageDisposable: IDisposable; private _webview: Webview; private _html: string; diff --git a/src/sql/parts/dashboard/dashboard.module.ts b/src/sql/parts/dashboard/dashboard.module.ts index 913571d918..06ec40d0f4 100644 --- a/src/sql/parts/dashboard/dashboard.module.ts +++ b/src/sql/parts/dashboard/dashboard.module.ts @@ -35,7 +35,9 @@ import { WidgetContent } from 'sql/parts/dashboard/contents/widgetContent.compon import { WebviewContent } from 'sql/parts/dashboard/contents/webviewContent.component'; import { BreadcrumbComponent } from 'sql/base/browser/ui/breadcrumb/breadcrumb.component'; import { IBreadcrumbService } from 'sql/base/browser/ui/breadcrumb/interfaces'; -let baseComponents = [DashboardComponent, DashboardWidgetWrapper, DashboardWebviewContainer, DashboardWidgetContainer, DashboardGridContainer, DashboardNavSection, WidgetContent, WebviewContent, ComponentHostDirective, BreadcrumbComponent]; +import { DashboardHomeContainer } from 'sql/parts/dashboard/containers/dashboardHomeContainer.component'; + +let baseComponents = [DashboardHomeContainer, DashboardComponent, DashboardWidgetWrapper, DashboardWebviewContainer, DashboardWidgetContainer, DashboardGridContainer, DashboardNavSection, WidgetContent, WebviewContent, ComponentHostDirective, BreadcrumbComponent]; /* Panel */ import { PanelModule } from 'sql/base/browser/ui/panel/panel.module'; @@ -43,6 +45,7 @@ import { PanelModule } from 'sql/base/browser/ui/panel/panel.module'; /* Pages */ import { ServerDashboardPage } from 'sql/parts/dashboard/pages/serverDashboardPage.component'; import { DatabaseDashboardPage } from 'sql/parts/dashboard/pages/databaseDashboardPage.component'; + let pageComponents = [ServerDashboardPage, DatabaseDashboardPage]; /* Widget Components */ @@ -51,6 +54,7 @@ import { ExplorerWidget } from 'sql/parts/dashboard/widgets/explorer/explorerWid import { TasksWidget } from 'sql/parts/dashboard/widgets/tasks/tasksWidget.component'; import { InsightsWidget } from 'sql/parts/dashboard/widgets/insights/insightsWidget.component'; import { WebviewWidget } from 'sql/parts/dashboard/widgets/webview/webviewWidget.component'; + let widgetComponents = [ PropertiesWidgetComponent, ExplorerWidget,