From 45023b2e7134f1b8693e6f9f5dda60ede4ec236f Mon Sep 17 00:00:00 2001 From: Anthony Dresser Date: Tue, 27 Feb 2018 14:11:54 -0800 Subject: [PATCH] Revert "Remove widgetContent" (#795) * Revert "fix dataprotocol developement problems (#788)" This reverts commit 1c08e64651a4920fb56998528ed2868f70fea767. * Revert "Task contribution (#742)" This reverts commit 3432dac261281b8955f9c9d46e59551fb66cf7fc. * Revert "remove widgetContent (#784)" This reverts commit 5adab4fafba1254e29851d3153058b4e1e72a843. --- .../dashboardHomeContainer.component.ts | 6 +- .../dashboardWidgetContainer.component.ts | 179 ++------------- .../contents/widgetContent.component.html | 10 + .../contents/widgetContent.component.ts | 203 ++++++++++++++++++ .../dashboard/contents/widgetContent.css | 9 + src/sql/parts/dashboard/dashboard.module.ts | 3 +- 6 files changed, 241 insertions(+), 169 deletions(-) create mode 100644 src/sql/parts/dashboard/contents/widgetContent.component.html create mode 100644 src/sql/parts/dashboard/contents/widgetContent.component.ts create mode 100644 src/sql/parts/dashboard/contents/widgetContent.css diff --git a/src/sql/parts/dashboard/containers/dashboardHomeContainer.component.ts b/src/sql/parts/dashboard/containers/dashboardHomeContainer.component.ts index 6d93cbbcec..42baf086da 100644 --- a/src/sql/parts/dashboard/containers/dashboardHomeContainer.component.ts +++ b/src/sql/parts/dashboard/containers/dashboardHomeContainer.component.ts @@ -19,10 +19,8 @@ import { WidgetConfig } from 'sql/parts/dashboard/common/dashboardWidget';
-
- - -
+ +
` diff --git a/src/sql/parts/dashboard/containers/dashboardWidgetContainer.component.ts b/src/sql/parts/dashboard/containers/dashboardWidgetContainer.component.ts index 10b5f07458..6374ebf0b1 100644 --- a/src/sql/parts/dashboard/containers/dashboardWidgetContainer.component.ts +++ b/src/sql/parts/dashboard/containers/dashboardWidgetContainer.component.ts @@ -5,7 +5,7 @@ import 'vs/css!./dashboardWidgetContainer'; -import { Component, Inject, Input, forwardRef, ViewChild, ElementRef, ViewChildren, QueryList, OnDestroy, ChangeDetectorRef, EventEmitter, OnChanges } from '@angular/core'; +import { Component, Inject, Input, forwardRef, ViewChild, ElementRef, ViewChildren, QueryList, OnDestroy, ChangeDetectorRef, EventEmitter, OnChanges, AfterContentInit } from '@angular/core'; import { NgGridConfig, NgGrid, NgGridItem } from 'angular2-grid'; import { DashboardServiceInterface } from 'sql/parts/dashboard/services/dashboardServiceInterface.service'; @@ -13,6 +13,7 @@ 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 { WidgetContent } from 'sql/parts/dashboard/contents/widgetContent.component'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; @@ -22,66 +23,19 @@ import { ScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElemen import { ScrollbarVisibility } from 'vs/base/common/scrollable'; import { getContentHeight, addDisposableListener, EventType } from 'vs/base/browser/dom'; -/** - * Sorting function for dashboard widgets - * In order of priority; - * If neither have defined grid positions, they are equivalent - * If a has a defined grid position and b does not; a should come first - * If both have defined grid positions and have the same row; the one with the smaller col position should come first - * If both have defined grid positions but different rows (it doesn't really matter in this case) the lowers row should come first - */ -function configSorter(a, b): number { - if ((!a.gridItemConfig || !a.gridItemConfig.col) - && (!b.gridItemConfig || !b.gridItemConfig.col)) { - return 0; - } else if (!a.gridItemConfig || !a.gridItemConfig.col) { - return 1; - } else if (!b.gridItemConfig || !b.gridItemConfig.col) { - return -1; - } else if (a.gridItemConfig.row === b.gridItemConfig.row) { - if (a.gridItemConfig.col < b.gridItemConfig.col) { - return -1; - } - - if (a.gridItemConfig.col === b.gridItemConfig.col) { - return 0; - } - - if (a.gridItemConfig.col > b.gridItemConfig.col) { - return 1; - } - } else { - if (a.gridItemConfig.row < b.gridItemConfig.row) { - return -1; - } - - if (a.gridItemConfig.row === b.gridItemConfig.row) { - return 0; - } - - if (a.gridItemConfig.row > b.gridItemConfig.row) { - return 1; - } - } - - return void 0; // this should never be reached -} - @Component({ selector: 'dashboard-widget-container', providers: [{ provide: DashboardTab, useExisting: forwardRef(() => DashboardWidgetContainer) }], template: `
-
- - -
+ +
` }) -export class DashboardWidgetContainer extends DashboardTab implements OnDestroy, OnChanges { +export class DashboardWidgetContainer extends DashboardTab implements OnDestroy, OnChanges, AfterContentInit { @Input() private tab: TabConfig; private widgets: WidgetConfig[]; private _onResize = new Emitter(); @@ -89,41 +43,12 @@ export class DashboardWidgetContainer extends DashboardTab implements OnDestroy, private _scrollableElement: ScrollableElement; + @ViewChild(WidgetContent) private _widgetContent: WidgetContent; - protected SKELETON_WIDTH = 5; - protected gridConfig: NgGridConfig = { - 'margins': [10], // The size of the margins of each item. Supports up to four values in the same way as CSS margins. Can be updated using setMargins() - 'draggable': false, // Whether the items can be dragged. Can be updated using enableDrag()/disableDrag() - 'resizable': false, // Whether the items can be resized. Can be updated using enableResize()/disableResize() - 'max_cols': this.SKELETON_WIDTH, // The maximum number of columns allowed. Set to 0 for infinite. Cannot be used with max_rows - 'max_rows': 0, // The maximum number of rows allowed. Set to 0 for infinite. Cannot be used with max_cols - 'visible_cols': 0, // The number of columns shown on screen when auto_resize is set to true. Set to 0 to not auto_resize. Will be overriden by max_cols - 'visible_rows': 0, // The number of rows shown on screen when auto_resize is set to true. Set to 0 to not auto_resize. Will be overriden by max_rows - 'min_cols': 0, // The minimum number of columns allowed. Can be any number greater than or equal to 1. - 'min_rows': 0, // The minimum number of rows allowed. Can be any number greater than or equal to 1. - 'col_width': 250, // The width of each column - 'row_height': 250, // The height of each row - 'cascade': 'left', // The direction to cascade grid items ('up', 'right', 'down', 'left') - 'min_width': 100, // The minimum width of an item. If greater than col_width, this will update the value of min_cols - 'min_height': 100, // The minimum height of an item. If greater than row_height, this will update the value of min_rows - 'fix_to_grid': false, // Fix all item movements to the grid - 'auto_style': true, // Automatically add required element styles at run-time - 'auto_resize': false, // Automatically set col_width/row_height so that max_cols/max_rows fills the screen. Only has effect is max_cols or max_rows is set - 'maintain_ratio': false, // Attempts to maintain aspect ratio based on the colWidth/rowHeight values set in the config - 'prefer_new': false, // When adding new items, will use that items position ahead of existing items - 'limit_to_screen': true, // When resizing the screen, with this true and auto_resize false, the grid will re-arrange to fit the screen size. Please note, at present this only works with cascade direction up. - }; - - private _editDispose: Array = []; - - @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(); @@ -136,6 +61,12 @@ export class DashboardWidgetContainer extends DashboardTab implements OnDestroy, } } + ngAfterContentInit(): void { + this._register(this._widgetContent.onResize(() => { + this._onResize.fire(); + })); + } + ngAfterViewInit() { let container = this._scrollContainer.nativeElement as HTMLElement; let scrollable = this._scrollable.nativeElement as HTMLElement; @@ -199,94 +130,14 @@ export class DashboardWidgetContainer extends DashboardTab implements OnDestroy, scrollHeight: getContentHeight(scrollable), height: getContentHeight(container) }); - if (this._widgets) { - this._widgets.forEach(item => { - item.layout(); - }); - } - this._grid.triggerResize(); + this._widgetContent.layout(); } public refresh(): void { - if (this._widgets) { - this._widgets.forEach(item => { - item.refresh(); - }); - } + this._widgetContent.layout(); } public enableEdit(): void { - if (this._grid.dragEnable) { - this._grid.disableDrag(); - this._grid.disableResize(); - this._editDispose.forEach(i => i.dispose()); - this._widgets.forEach(i => { - if (i.id) { - i.disableEdit(); - } - }); - this._editDispose = []; - } else { - this._grid.enableResize(); - this._grid.enableDrag(); - this._editDispose.push(this.dashboardService.onDeleteWidget(e => { - let index = this.widgets.findIndex(i => i.id === e); - this.widgets.splice(index, 1); - - index = this.tab.originalConfig.findIndex(i => i.id === e); - this.tab.originalConfig.splice(index, 1); - - this._rewriteConfig(); - this._cd.detectChanges(); - })); - this._editDispose.push(subscriptionToDisposable(this._grid.onResizeStop.subscribe((e: NgGridItem) => { - this._onResize.fire(); - let event = e.getEventOutput(); - let config = this.tab.originalConfig.find(i => i.id === event.payload.id); - - if (!config.gridItemConfig) { - config.gridItemConfig = {}; - } - config.gridItemConfig.sizex = e.sizex; - config.gridItemConfig.sizey = e.sizey; - - let component = this._widgets.find(i => i.id === event.payload.id); - - component.layout(); - this._rewriteConfig(); - }))); - this._editDispose.push(subscriptionToDisposable(this._grid.onDragStop.subscribe((e: NgGridItem) => { - this._onResize.fire(); - let event = e.getEventOutput(); - this._items.forEach(i => { - let config = this.tab.originalConfig.find(j => j.id === i.getEventOutput().payload.id); - if ((config.gridItemConfig && config.gridItemConfig.col) || config.id === event.payload.id) { - if (!config.gridItemConfig) { - config.gridItemConfig = {}; - } - config.gridItemConfig.col = i.col; - config.gridItemConfig.row = i.row; - } - }); - this.tab.originalConfig.sort(configSorter); - - this._rewriteConfig(); - }))); - this._widgets.forEach(i => { - if (i.id) { - i.enableEdit(); - } - }); - } - } - - private _rewriteConfig(): void { - let writeableConfig = objects.deepClone(this.tab.originalConfig); - - writeableConfig.forEach(i => { - delete i.id; - }); - let target: ConfigurationTarget = ConfigurationTarget.USER; - this.dashboardService.writeSettings([this.tab.context, 'widgets'].join('.'), writeableConfig, target); + this._widgetContent.enableEdit(); } } diff --git a/src/sql/parts/dashboard/contents/widgetContent.component.html b/src/sql/parts/dashboard/contents/widgetContent.component.html new file mode 100644 index 0000000000..93963222d7 --- /dev/null +++ b/src/sql/parts/dashboard/contents/widgetContent.component.html @@ -0,0 +1,10 @@ + +
+ + +
diff --git a/src/sql/parts/dashboard/contents/widgetContent.component.ts b/src/sql/parts/dashboard/contents/widgetContent.component.ts new file mode 100644 index 0000000000..34b18de51b --- /dev/null +++ b/src/sql/parts/dashboard/contents/widgetContent.component.ts @@ -0,0 +1,203 @@ +/*--------------------------------------------------------------------------------------------- + * 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!./widgetContent'; + +import { Component, Inject, Input, forwardRef, ViewChild, ViewChildren, QueryList, ChangeDetectorRef } 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 { 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'; + +/** + * Sorting function for dashboard widgets + * In order of priority; + * If neither have defined grid positions, they are equivalent + * If a has a defined grid position and b does not; a should come first + * If both have defined grid positions and have the same row; the one with the smaller col position should come first + * If both have defined grid positions but different rows (it doesn't really matter in this case) the lowers row should come first + */ +function configSorter(a, b): number { + if ((!a.gridItemConfig || !a.gridItemConfig.col) + && (!b.gridItemConfig || !b.gridItemConfig.col)) { + return 0; + } else if (!a.gridItemConfig || !a.gridItemConfig.col) { + return 1; + } else if (!b.gridItemConfig || !b.gridItemConfig.col) { + return -1; + } else if (a.gridItemConfig.row === b.gridItemConfig.row) { + if (a.gridItemConfig.col < b.gridItemConfig.col) { + return -1; + } + + if (a.gridItemConfig.col === b.gridItemConfig.col) { + return 0; + } + + if (a.gridItemConfig.col > b.gridItemConfig.col) { + return 1; + } + } else { + if (a.gridItemConfig.row < b.gridItemConfig.row) { + return -1; + } + + if (a.gridItemConfig.row === b.gridItemConfig.row) { + return 0; + } + + if (a.gridItemConfig.row > b.gridItemConfig.row) { + return 1; + } + } + + return void 0; // this should never be reached +} + +@Component({ + selector: 'widget-content', + templateUrl: decodeURI(require.toUrl('sql/parts/dashboard/contents/widgetContent.component.html')) +}) +export class WidgetContent { + @Input() private widgets: WidgetConfig[]; + @Input() private originalConfig: WidgetConfig[]; + @Input() private context: string; + private _onResize = new Emitter(); + public readonly onResize: Event = this._onResize.event; + + protected SKELETON_WIDTH = 5; + protected gridConfig: NgGridConfig = { + 'margins': [10], // The size of the margins of each item. Supports up to four values in the same way as CSS margins. Can be updated using setMargins() + 'draggable': false, // Whether the items can be dragged. Can be updated using enableDrag()/disableDrag() + 'resizable': false, // Whether the items can be resized. Can be updated using enableResize()/disableResize() + 'max_cols': this.SKELETON_WIDTH, // The maximum number of columns allowed. Set to 0 for infinite. Cannot be used with max_rows + 'max_rows': 0, // The maximum number of rows allowed. Set to 0 for infinite. Cannot be used with max_cols + 'visible_cols': 0, // The number of columns shown on screen when auto_resize is set to true. Set to 0 to not auto_resize. Will be overriden by max_cols + 'visible_rows': 0, // The number of rows shown on screen when auto_resize is set to true. Set to 0 to not auto_resize. Will be overriden by max_rows + 'min_cols': 0, // The minimum number of columns allowed. Can be any number greater than or equal to 1. + 'min_rows': 0, // The minimum number of rows allowed. Can be any number greater than or equal to 1. + 'col_width': 250, // The width of each column + 'row_height': 250, // The height of each row + 'cascade': 'left', // The direction to cascade grid items ('up', 'right', 'down', 'left') + 'min_width': 100, // The minimum width of an item. If greater than col_width, this will update the value of min_cols + 'min_height': 100, // The minimum height of an item. If greater than row_height, this will update the value of min_rows + 'fix_to_grid': false, // Fix all item movements to the grid + 'auto_style': true, // Automatically add required element styles at run-time + 'auto_resize': false, // Automatically set col_width/row_height so that max_cols/max_rows fills the screen. Only has effect is max_cols or max_rows is set + 'maintain_ratio': false, // Attempts to maintain aspect ratio based on the colWidth/rowHeight values set in the config + 'prefer_new': false, // When adding new items, will use that items position ahead of existing items + 'limit_to_screen': true, // When resizing the screen, with this true and auto_resize false, the grid will re-arrange to fit the screen size. Please note, at present this only works with cascade direction up. + }; + + private _editDispose: Array = []; + + @ViewChild(NgGrid) private _grid: NgGrid; + @ViewChildren(DashboardWidgetWrapper) private _widgets: QueryList; + @ViewChildren(NgGridItem) private _items: QueryList; + constructor( + @Inject(forwardRef(() => DashboardServiceInterface)) protected dashboardService: DashboardServiceInterface, + @Inject(forwardRef(() => ChangeDetectorRef)) protected _cd: ChangeDetectorRef + ) { + } + + public layout() { + if (this._widgets) { + this._widgets.forEach(item => { + item.layout(); + }); + } + this._grid.triggerResize(); + } + + public refresh(): void { + if (this._widgets) { + this._widgets.forEach(item => { + item.refresh(); + }); + } + } + + public enableEdit(): void { + if (this._grid.dragEnable) { + this._grid.disableDrag(); + this._grid.disableResize(); + this._editDispose.forEach(i => i.dispose()); + this._widgets.forEach(i => { + if (i.id) { + i.disableEdit(); + } + }); + this._editDispose = []; + } else { + this._grid.enableResize(); + this._grid.enableDrag(); + this._editDispose.push(this.dashboardService.onDeleteWidget(e => { + let index = this.widgets.findIndex(i => i.id === e); + this.widgets.splice(index, 1); + + index = this.originalConfig.findIndex(i => i.id === e); + this.originalConfig.splice(index, 1); + + this._rewriteConfig(); + this._cd.detectChanges(); + })); + this._editDispose.push(subscriptionToDisposable(this._grid.onResizeStop.subscribe((e: NgGridItem) => { + this._onResize.fire(); + let event = e.getEventOutput(); + let config = this.originalConfig.find(i => i.id === event.payload.id); + + if (!config.gridItemConfig) { + config.gridItemConfig = {}; + } + config.gridItemConfig.sizex = e.sizex; + config.gridItemConfig.sizey = e.sizey; + + let component = this._widgets.find(i => i.id === event.payload.id); + + component.layout(); + this._rewriteConfig(); + }))); + this._editDispose.push(subscriptionToDisposable(this._grid.onDragStop.subscribe((e: NgGridItem) => { + this._onResize.fire(); + let event = e.getEventOutput(); + this._items.forEach(i => { + let config = this.originalConfig.find(j => j.id === i.getEventOutput().payload.id); + if ((config.gridItemConfig && config.gridItemConfig.col) || config.id === event.payload.id) { + if (!config.gridItemConfig) { + config.gridItemConfig = {}; + } + config.gridItemConfig.col = i.col; + config.gridItemConfig.row = i.row; + } + }); + this.originalConfig.sort(configSorter); + + this._rewriteConfig(); + }))); + this._widgets.forEach(i => { + if (i.id) { + i.enableEdit(); + } + }); + } + } + + private _rewriteConfig(): void { + let writeableConfig = objects.deepClone(this.originalConfig); + + writeableConfig.forEach(i => { + delete i.id; + }); + let target: ConfigurationTarget = ConfigurationTarget.USER; + this.dashboardService.writeSettings([this.context, 'widgets'].join('.'), writeableConfig, target); + } +} diff --git a/src/sql/parts/dashboard/contents/widgetContent.css b/src/sql/parts/dashboard/contents/widgetContent.css new file mode 100644 index 0000000000..7ceb52837f --- /dev/null +++ b/src/sql/parts/dashboard/contents/widgetContent.css @@ -0,0 +1,9 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +widget-content { + height: 100%; + width: 100%; +} \ No newline at end of file diff --git a/src/sql/parts/dashboard/dashboard.module.ts b/src/sql/parts/dashboard/dashboard.module.ts index 1b8d86b7bf..06ec40d0f4 100644 --- a/src/sql/parts/dashboard/dashboard.module.ts +++ b/src/sql/parts/dashboard/dashboard.module.ts @@ -31,12 +31,13 @@ import { DashboardWidgetContainer } from 'sql/parts/dashboard/containers/dashboa import { DashboardGridContainer } from 'sql/parts/dashboard/containers/dashboardGridContainer.component'; import { DashboardWebviewContainer } from 'sql/parts/dashboard/containers/dashboardWebviewContainer.component'; import { DashboardNavSection } from 'sql/parts/dashboard/containers/dashboardNavSection.component'; +import { WidgetContent } from 'sql/parts/dashboard/contents/widgetContent.component'; 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'; import { DashboardHomeContainer } from 'sql/parts/dashboard/containers/dashboardHomeContainer.component'; -let baseComponents = [DashboardHomeContainer, DashboardComponent, DashboardWidgetWrapper, DashboardWebviewContainer, DashboardWidgetContainer, DashboardGridContainer, DashboardNavSection, WebviewContent, ComponentHostDirective, BreadcrumbComponent]; +let baseComponents = [DashboardHomeContainer, DashboardComponent, DashboardWidgetWrapper, DashboardWebviewContainer, DashboardWidgetContainer, DashboardGridContainer, DashboardNavSection, WidgetContent, WebviewContent, ComponentHostDirective, BreadcrumbComponent]; /* Panel */ import { PanelModule } from 'sql/base/browser/ui/panel/panel.module';