-
-
+
diff --git a/src/sql/parts/dashboard/contents/widgetContent.component.ts b/src/sql/parts/dashboard/contents/widgetContent.component.ts
index 34b18de51b..bae5dd821b 100644
--- a/src/sql/parts/dashboard/contents/widgetContent.component.ts
+++ b/src/sql/parts/dashboard/contents/widgetContent.component.ts
@@ -5,18 +5,21 @@
import 'vs/css!./widgetContent';
-import { Component, Inject, Input, forwardRef, ViewChild, ViewChildren, QueryList, ChangeDetectorRef } from '@angular/core';
+import { Component, Inject, Input, forwardRef, ViewChild, ViewChildren, QueryList, ChangeDetectorRef, ElementRef, AfterViewInit } from '@angular/core';
import { NgGridConfig, NgGrid, NgGridItem } from 'angular2-grid';
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
import { WidgetConfig } from 'sql/parts/dashboard/common/dashboardWidget';
import { DashboardWidgetWrapper } from 'sql/parts/dashboard/contents/dashboardWidgetWrapper.component';
-import { subscriptionToDisposable } from 'sql/base/common/lifecycle';
+import { subscriptionToDisposable, AngularDisposable } from 'sql/base/common/lifecycle';
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';
/**
* Sorting function for dashboard widgets
@@ -67,10 +70,13 @@ function configSorter(a, b): number {
selector: 'widget-content',
templateUrl: decodeURI(require.toUrl('sql/parts/dashboard/contents/widgetContent.component.html'))
})
-export class WidgetContent {
+export class WidgetContent extends AngularDisposable implements AfterViewInit {
@Input() private widgets: WidgetConfig[];
@Input() private originalConfig: WidgetConfig[];
@Input() private context: string;
+
+ private _scrollableElement: ScrollableElement;
+
private _onResize = new Emitter
();
public readonly onResize: Event = this._onResize.event;
@@ -103,10 +109,51 @@ export class WidgetContent {
@ViewChild(NgGrid) private _grid: NgGrid;
@ViewChildren(DashboardWidgetWrapper) private _widgets: QueryList;
@ViewChildren(NgGridItem) private _items: QueryList;
+ @ViewChild('scrollable', { read: ElementRef }) private _scrollable: ElementRef;
+ @ViewChild('scrollContainer', { read: ElementRef }) private _scrollContainer: ElementRef;
constructor(
@Inject(forwardRef(() => DashboardServiceInterface)) protected dashboardService: DashboardServiceInterface,
@Inject(forwardRef(() => ChangeDetectorRef)) protected _cd: ChangeDetectorRef
) {
+ super();
+ }
+
+ 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, () => {
+ this.resetScrollDimensions();
+ }));
+
+ // 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);
}
public layout() {
@@ -116,6 +163,17 @@ export class WidgetContent {
});
}
this._grid.triggerResize();
+ this.resetScrollDimensions();
+ }
+
+ private resetScrollDimensions() {
+ let container = this._scrollContainer.nativeElement as HTMLElement;
+ let scrollable = this._scrollable.nativeElement as HTMLElement;
+
+ this._scrollableElement.setScrollDimensions({
+ scrollHeight: getContentHeight(scrollable),
+ height: getContentHeight(container)
+ });
}
public refresh(): void {
@@ -165,6 +223,7 @@ export class WidgetContent {
component.layout();
this._rewriteConfig();
+ this.resetScrollDimensions();
})));
this._editDispose.push(subscriptionToDisposable(this._grid.onDragStop.subscribe((e: NgGridItem) => {
this._onResize.fire();
@@ -182,6 +241,7 @@ export class WidgetContent {
this.originalConfig.sort(configSorter);
this._rewriteConfig();
+ this.resetScrollDimensions();
})));
this._widgets.forEach(i => {
if (i.id) {
diff --git a/src/sql/parts/dashboard/contents/widgetContent.css b/src/sql/parts/dashboard/contents/widgetContent.css
index 7ceb52837f..cc66d3311d 100644
--- a/src/sql/parts/dashboard/contents/widgetContent.css
+++ b/src/sql/parts/dashboard/contents/widgetContent.css
@@ -6,4 +6,13 @@
widget-content {
height: 100%;
width: 100%;
+}
+
+.scroll-container {
+ height: 100%;
+ width: 100%;
+}
+
+.scrollable {
+ position: relative;
}
\ No newline at end of file