mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
Fix the scrollbar issue in widget container (#1016)
* fix the scrollbar issue in widget container * move scrollbar to widget content
This commit is contained in:
@@ -208,7 +208,7 @@ export abstract class DashboardPage extends AngularDisposable {
|
|||||||
configs = cb.apply(this, [configs, this.dashboardService, this.context]);
|
configs = cb.apply(this, [configs, this.dashboardService, this.context]);
|
||||||
});
|
});
|
||||||
this._gridModifiers.forEach(cb => {
|
this._gridModifiers.forEach(cb => {
|
||||||
configs = cb.apply(this, [configs, this._originalConfig]);
|
configs = cb.apply(this, [configs]);
|
||||||
});
|
});
|
||||||
if (key === WIDGETS_CONTAINER) {
|
if (key === WIDGETS_CONTAINER) {
|
||||||
return { id: v.id, title: v.title, container: { 'widgets-container': configs }, alwaysShow: v.alwaysShow };
|
return { id: v.id, title: v.title, container: { 'widgets-container': configs }, alwaysShow: v.alwaysShow };
|
||||||
|
|||||||
@@ -19,15 +19,11 @@ import { ConfigurationTarget } from 'vs/platform/configuration/common/configurat
|
|||||||
selector: 'dashboard-home-container',
|
selector: 'dashboard-home-container',
|
||||||
providers: [{ provide: DashboardTab, useExisting: forwardRef(() => DashboardHomeContainer) }],
|
providers: [{ provide: DashboardTab, useExisting: forwardRef(() => DashboardHomeContainer) }],
|
||||||
template: `
|
template: `
|
||||||
<div class="scroll-container" #scrollContainer>
|
|
||||||
<div class="scrollable" #scrollable>
|
|
||||||
<dashboard-widget-wrapper #propertiesClass *ngIf="properties" [collapsable]="true" [_config]="properties"
|
<dashboard-widget-wrapper #propertiesClass *ngIf="properties" [collapsable]="true" [_config]="properties"
|
||||||
style="padding-left: 10px; padding-right: 10px; display: block" [style.height.px]="_propertiesClass?.collapsed ? '30' : '90'">
|
style="padding-left: 10px; padding-right: 10px; display: block" [style.height.px]="_propertiesClass?.collapsed ? '30' : '90'">
|
||||||
</dashboard-widget-wrapper>
|
</dashboard-widget-wrapper>
|
||||||
<widget-content [widgets]="widgets" [originalConfig]="tab.originalConfig" [context]="tab.context">
|
<widget-content [widgets]="widgets" [originalConfig]="tab.originalConfig" [context]="tab.context">
|
||||||
</widget-content>
|
</widget-content>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`
|
`
|
||||||
})
|
})
|
||||||
export class DashboardHomeContainer extends DashboardWidgetContainer {
|
export class DashboardHomeContainer extends DashboardWidgetContainer {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
import 'vs/css!./dashboardWidgetContainer';
|
import 'vs/css!./dashboardWidgetContainer';
|
||||||
|
|
||||||
import { Component, Inject, Input, forwardRef, ViewChild, ElementRef, ViewChildren, QueryList, OnDestroy, ChangeDetectorRef, EventEmitter, OnChanges, AfterContentInit } from '@angular/core';
|
import { Component, Inject, Input, forwardRef, ViewChild, ViewChildren, QueryList, OnDestroy, ChangeDetectorRef, EventEmitter, OnChanges, AfterContentInit } from '@angular/core';
|
||||||
import { NgGridConfig, NgGrid, NgGridItem } from 'angular2-grid';
|
import { NgGridConfig, NgGrid, NgGridItem } from 'angular2-grid';
|
||||||
|
|
||||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||||
@@ -19,20 +19,13 @@ import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
|||||||
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
||||||
import * as objects from 'vs/base/common/objects';
|
import * as objects from 'vs/base/common/objects';
|
||||||
import Event, { Emitter } from 'vs/base/common/event';
|
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({
|
@Component({
|
||||||
selector: 'dashboard-widget-container',
|
selector: 'dashboard-widget-container',
|
||||||
providers: [{ provide: DashboardTab, useExisting: forwardRef(() => DashboardWidgetContainer) }],
|
providers: [{ provide: DashboardTab, useExisting: forwardRef(() => DashboardWidgetContainer) }],
|
||||||
template: `
|
template: `
|
||||||
<div class="scroll-container" #scrollContainer>
|
|
||||||
<div class="scrollable" #scrollable>
|
|
||||||
<widget-content [widgets]="widgets" [originalConfig]="tab.originalConfig" [context]="tab.context">
|
<widget-content [widgets]="widgets" [originalConfig]="tab.originalConfig" [context]="tab.context">
|
||||||
</widget-content>
|
</widget-content>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`
|
`
|
||||||
})
|
})
|
||||||
export class DashboardWidgetContainer extends DashboardTab implements OnDestroy, OnChanges, AfterContentInit {
|
export class DashboardWidgetContainer extends DashboardTab implements OnDestroy, OnChanges, AfterContentInit {
|
||||||
@@ -41,13 +34,8 @@ export class DashboardWidgetContainer extends DashboardTab implements OnDestroy,
|
|||||||
private _onResize = new Emitter<void>();
|
private _onResize = new Emitter<void>();
|
||||||
public readonly onResize: Event<void> = this._onResize.event;
|
public readonly onResize: Event<void> = this._onResize.event;
|
||||||
|
|
||||||
private _scrollableElement: ScrollableElement;
|
|
||||||
|
|
||||||
@ViewChild(WidgetContent) protected _widgetContent: WidgetContent;
|
@ViewChild(WidgetContent) protected _widgetContent: WidgetContent;
|
||||||
|
|
||||||
@ViewChild('scrollable', { read: ElementRef }) private _scrollable: ElementRef;
|
|
||||||
@ViewChild('scrollContainer', { read: ElementRef }) private _scrollContainer: ElementRef;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) protected _cd: ChangeDetectorRef
|
@Inject(forwardRef(() => ChangeDetectorRef)) protected _cd: ChangeDetectorRef
|
||||||
) {
|
) {
|
||||||
@@ -67,50 +55,6 @@ 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() {
|
ngOnDestroy() {
|
||||||
this.dispose();
|
this.dispose();
|
||||||
}
|
}
|
||||||
@@ -124,12 +68,6 @@ export class DashboardWidgetContainer extends DashboardTab implements OnDestroy,
|
|||||||
}
|
}
|
||||||
|
|
||||||
public layout() {
|
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();
|
this._widgetContent.layout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,3 @@ dashboard-widget-container {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scroll-container {
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scrollable {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,7 +4,11 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
-->
|
-->
|
||||||
|
<div class="scroll-container" #scrollContainer>
|
||||||
|
<div class="scrollable" #scrollable>
|
||||||
<div [ngGrid]="gridConfig" *ngIf="widgets" >
|
<div [ngGrid]="gridConfig" *ngIf="widgets" >
|
||||||
<dashboard-widget-wrapper *ngFor="let widget of widgets" [(ngGridItem)]="widget.gridItemConfig" [_config]="widget">
|
<dashboard-widget-wrapper *ngFor="let widget of widgets" [(ngGridItem)]="widget.gridItemConfig" [_config]="widget">
|
||||||
</dashboard-widget-wrapper>
|
</dashboard-widget-wrapper>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -5,18 +5,21 @@
|
|||||||
|
|
||||||
import 'vs/css!./widgetContent';
|
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 { NgGridConfig, NgGrid, NgGridItem } from 'angular2-grid';
|
||||||
|
|
||||||
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service';
|
||||||
import { WidgetConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
import { WidgetConfig } from 'sql/parts/dashboard/common/dashboardWidget';
|
||||||
import { DashboardWidgetWrapper } from 'sql/parts/dashboard/contents/dashboardWidgetWrapper.component';
|
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 { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||||
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
||||||
import * as objects from 'vs/base/common/objects';
|
import * as objects from 'vs/base/common/objects';
|
||||||
import Event, { Emitter } from 'vs/base/common/event';
|
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
|
* Sorting function for dashboard widgets
|
||||||
@@ -67,10 +70,13 @@ function configSorter(a, b): number {
|
|||||||
selector: 'widget-content',
|
selector: 'widget-content',
|
||||||
templateUrl: decodeURI(require.toUrl('sql/parts/dashboard/contents/widgetContent.component.html'))
|
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 widgets: WidgetConfig[];
|
||||||
@Input() private originalConfig: WidgetConfig[];
|
@Input() private originalConfig: WidgetConfig[];
|
||||||
@Input() private context: string;
|
@Input() private context: string;
|
||||||
|
|
||||||
|
private _scrollableElement: ScrollableElement;
|
||||||
|
|
||||||
private _onResize = new Emitter<void>();
|
private _onResize = new Emitter<void>();
|
||||||
public readonly onResize: Event<void> = this._onResize.event;
|
public readonly onResize: Event<void> = this._onResize.event;
|
||||||
|
|
||||||
@@ -103,10 +109,51 @@ export class WidgetContent {
|
|||||||
@ViewChild(NgGrid) private _grid: NgGrid;
|
@ViewChild(NgGrid) private _grid: NgGrid;
|
||||||
@ViewChildren(DashboardWidgetWrapper) private _widgets: QueryList<DashboardWidgetWrapper>;
|
@ViewChildren(DashboardWidgetWrapper) private _widgets: QueryList<DashboardWidgetWrapper>;
|
||||||
@ViewChildren(NgGridItem) private _items: QueryList<NgGridItem>;
|
@ViewChildren(NgGridItem) private _items: QueryList<NgGridItem>;
|
||||||
|
@ViewChild('scrollable', { read: ElementRef }) private _scrollable: ElementRef;
|
||||||
|
@ViewChild('scrollContainer', { read: ElementRef }) private _scrollContainer: ElementRef;
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => DashboardServiceInterface)) protected dashboardService: DashboardServiceInterface,
|
@Inject(forwardRef(() => DashboardServiceInterface)) protected dashboardService: DashboardServiceInterface,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) protected _cd: ChangeDetectorRef
|
@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() {
|
public layout() {
|
||||||
@@ -116,6 +163,17 @@ export class WidgetContent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
this._grid.triggerResize();
|
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 {
|
public refresh(): void {
|
||||||
@@ -165,6 +223,7 @@ export class WidgetContent {
|
|||||||
|
|
||||||
component.layout();
|
component.layout();
|
||||||
this._rewriteConfig();
|
this._rewriteConfig();
|
||||||
|
this.resetScrollDimensions();
|
||||||
})));
|
})));
|
||||||
this._editDispose.push(subscriptionToDisposable(this._grid.onDragStop.subscribe((e: NgGridItem) => {
|
this._editDispose.push(subscriptionToDisposable(this._grid.onDragStop.subscribe((e: NgGridItem) => {
|
||||||
this._onResize.fire();
|
this._onResize.fire();
|
||||||
@@ -182,6 +241,7 @@ export class WidgetContent {
|
|||||||
this.originalConfig.sort(configSorter);
|
this.originalConfig.sort(configSorter);
|
||||||
|
|
||||||
this._rewriteConfig();
|
this._rewriteConfig();
|
||||||
|
this.resetScrollDimensions();
|
||||||
})));
|
})));
|
||||||
this._widgets.forEach(i => {
|
this._widgets.forEach(i => {
|
||||||
if (i.id) {
|
if (i.id) {
|
||||||
|
|||||||
@@ -7,3 +7,12 @@ widget-content {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.scroll-container {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollable {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user