Move properties container and loading spinner to common components (#10058)

* Move properties container and loading spinner to common components

* Fix compile error

* Fix tests
This commit is contained in:
Charles Gagnon
2020-04-21 09:36:47 -07:00
committed by GitHub
parent a34feb4448
commit a4ae2ca65f
11 changed files with 214 additions and 93 deletions

View File

@@ -14,8 +14,8 @@ const DefaultLoadingCompletedMessage = nls.localize('loadingCompletedMessage', "
@Component({ @Component({
selector: 'loading-spinner', selector: 'loading-spinner',
template: ` template: `
<div class="modelview-loadingComponent-container" *ngIf="loading"> <div class="loading-spinner-container" *ngIf="loading">
<div class="modelview-loadingComponent-spinner" *ngIf="loading" [title]="_loadingMessage" #spinnerElement></div> <div class="loading-spinner codicon in-progress" *ngIf="loading" [title]="_loadingMessage" #spinnerElement></div>
</div> </div>
` `
}) })

View File

@@ -0,0 +1,16 @@
/*---------------------------------------------------------------------------------------------
* 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 LoadingSpinner from './loadingSpinner.component';
@NgModule({
imports: [CommonModule],
exports: [LoadingSpinner],
declarations: [LoadingSpinner]
})
export class LoadingSpinnerModule { }

View File

@@ -0,0 +1,25 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
loading-spinner .loading-spinner-container {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
loading-spinner .modelview-loadingComponent-status-text {
margin-left: 5px;
}
loading-spinner .loading-spinner {
height: 20px;
padding-top: 5px;
padding-bottom: 5px;
}
loading-spinner .modelview-loadingComponent-content-loading {
display: none;
}

View File

@@ -3,30 +3,30 @@
* 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.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
properties-widget .twoColumns.grid-container { properties-container .twoColumns.grid-container {
grid-template-columns: 50% 50%; grid-template-columns: 50% 50%;
} }
properties-widget .oneColumn.grid-container { properties-container .oneColumn.grid-container {
grid-template-columns: 100%; grid-template-columns: 100%;
} }
properties-widget .columnLayout.property { properties-container .columnLayout.property {
flex-direction: column; flex-direction: column;
} }
properties-widget .propertyName { properties-container .propertyName {
opacity: 0.6; opacity: 0.6;
font-size: 12px; font-size: 12px;
flex: 0 0 auto flex: 0 0 auto
} }
.vs-dark properties-widget .propertyName, .vs-dark properties-container .propertyName,
.hc-black properties-widget .propertyName { .hc-black properties-container .propertyName {
opacity: 1; opacity: 1;
} }
properties-widget .propertyValue { properties-container .propertyValue {
font-size: 12px; font-size: 12px;
flex: 1 1 auto; flex: 1 1 auto;
margin-right: 5px; margin-right: 5px;
@@ -35,11 +35,11 @@ properties-widget .propertyValue {
text-overflow: ellipsis; text-overflow: ellipsis;
} }
properties-widget .splitter { properties-container .splitter {
flex: 0 0 15px; flex: 0 0 15px;
text-align: center; text-align: center;
} }
properties-widget .columnLayout .splitter { properties-container .columnLayout .splitter {
display: none; display: none;
} }

View File

@@ -4,10 +4,10 @@
* 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.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
--> -->
<loading-spinner [loading]="_loading" [loadingMessage]="_loadingMessage" <loading-spinner [loading]="loading" [loadingMessage]="loadingMessage"
[loadingCompletedMessage]="_loadingCompletedMessage"></loading-spinner> [loadingCompletedMessage]="loadingCompletedMessage"></loading-spinner>
<div class="grid-container {{gridDisplayLayout}}" style="position: absolute; height: 100%; width: 100%;" [style.display]="_loading ? 'none':'grid'"> <div class="grid-container {{gridDisplayLayout}}" style="position: absolute; height: 100%; width: 100%;" [style.display]="_loading ? 'none':'grid'">
<ng-template ngFor let-item [ngForOf]="_properties"> <ng-template ngFor let-item [ngForOf]="displayProperties">
<div class="property {{propertyLayout}}" style="display:flex"> <div class="property {{propertyLayout}}" style="display:flex">
<div class="propertyName">{{item.displayName}}</div> <div class="propertyName">{{item.displayName}}</div>
<div class="splitter">:</div> <div class="splitter">:</div>

View File

@@ -0,0 +1,98 @@
/*---------------------------------------------------------------------------------------------
* 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!./media/propertiesContainer';
import { Component, Inject, forwardRef, ChangeDetectorRef, OnInit, ElementRef } from '@angular/core';
import { EventType, addDisposableListener } from 'vs/base/browser/dom';
import * as nls from 'vs/nls';
import { Disposable } from 'vs/base/common/lifecycle';
enum GridDisplayLayout {
twoColumns = 'twoColumns',
oneColumn = 'oneColumn'
}
enum PropertyLayoutDirection {
row = 'rowLayout',
column = 'columnLayout'
}
export interface DisplayProperty {
displayName: string;
value: string;
}
const collapseHeight = 25;
const horizontalPropertyHeight = 28;
const verticalPropertyHeight = 46;
@Component({
selector: 'properties-container',
templateUrl: decodeURI(require.toUrl('./propertiesContainer.component.html'))
})
export class PropertiesContainer extends Disposable implements OnInit {
public gridDisplayLayout = GridDisplayLayout.twoColumns;
public propertyLayout = PropertyLayoutDirection.row;
public loadingMessage: string = nls.localize('loadingProperties', "Loading properties");
public loadingCompletedMessage: string = nls.localize('loadingPropertiesCompleted', "Loading properties completed");
public height: number;
private _loading: boolean = true;
private _displayProperties: DisplayProperty[] = [];
constructor(
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef,
@Inject(forwardRef(() => ElementRef)) el: ElementRef
) {
super();
}
ngOnInit() {
this._register(addDisposableListener(window, EventType.RESIZE, () => this.layoutDisplayProperties()));
this._changeRef.detectChanges();
}
private layoutDisplayProperties(): void {
// Reflow:
// 2 columns w/ horizontal alignment : 1366px and above
// 2 columns w/ vertical alignment : 1024 - 1365px
// 1 column w/ vertical alignment : 1024px or less
if (!this.loading) {
if (window.innerWidth >= 1366) {
this.gridDisplayLayout = GridDisplayLayout.twoColumns;
this.propertyLayout = PropertyLayoutDirection.row;
this.height = Math.ceil(this.displayProperties.length / 2) * horizontalPropertyHeight + collapseHeight;
} else if (window.innerWidth < 1366 && window.innerWidth >= 1024) {
this.gridDisplayLayout = GridDisplayLayout.twoColumns;
this.propertyLayout = PropertyLayoutDirection.column;
this.height = Math.ceil(this.displayProperties.length / 2) * verticalPropertyHeight + collapseHeight;
} else if (window.innerWidth < 1024) {
this.gridDisplayLayout = GridDisplayLayout.oneColumn;
this.propertyLayout = PropertyLayoutDirection.column;
this.height = this.displayProperties.length * verticalPropertyHeight + collapseHeight;
}
this._changeRef.detectChanges();
}
}
public set displayProperties(displayProperties: DisplayProperty[]) {
this._displayProperties = displayProperties;
this.layoutDisplayProperties();
}
public get displayProperties(): DisplayProperty[] {
return this._displayProperties;
}
public set loading(loading: boolean) {
this._loading = loading;
this._changeRef.detectChanges();
}
public get loading(): boolean {
return this._loading;
}
}

View File

@@ -0,0 +1,17 @@
/*---------------------------------------------------------------------------------------------
* 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 { PropertiesContainer } from './propertiesContainer.component';
import { LoadingSpinnerModule } from 'sql/base/browser/ui/loadingSpinner/loadingSpinner.module';
@NgModule({
imports: [CommonModule, LoadingSpinnerModule],
exports: [PropertiesContainer],
declarations: [PropertiesContainer]
})
export class PropertiesContainerModule { }

View File

@@ -56,7 +56,6 @@ import { OperatorsViewComponent } from 'sql/workbench/contrib/jobManagement/brow
import { ProxiesViewComponent } from 'sql/workbench/contrib/jobManagement/browser/proxiesView.component'; import { ProxiesViewComponent } from 'sql/workbench/contrib/jobManagement/browser/proxiesView.component';
import { NotebooksViewComponent } from 'sql/workbench/contrib/jobManagement/browser/notebooksView.component'; import { NotebooksViewComponent } from 'sql/workbench/contrib/jobManagement/browser/notebooksView.component';
import { NotebookHistoryComponent } from 'sql/workbench/contrib/jobManagement/browser/notebookHistory.component'; import { NotebookHistoryComponent } from 'sql/workbench/contrib/jobManagement/browser/notebookHistory.component';
import LoadingSpinner from 'sql/workbench/browser/modelComponents/loadingSpinner.component';
import { Checkbox } from 'sql/base/browser/ui/checkbox/checkbox.component'; import { Checkbox } from 'sql/base/browser/ui/checkbox/checkbox.component';
import { SelectBox } from 'sql/platform/browser/selectBox/selectBox.component'; import { SelectBox } from 'sql/platform/browser/selectBox/selectBox.component';
import { InputBox } from 'sql/platform/browser/inputbox/inputBox.component'; import { InputBox } from 'sql/platform/browser/inputbox/inputBox.component';
@@ -66,7 +65,7 @@ const baseComponents = [DashboardHomeContainer, DashboardComponent, DashboardWid
DashboardWidgetContainer, DashboardGridContainer, DashboardErrorContainer, DashboardNavSection, ModelViewContent, WebviewContent, WidgetContent, DashboardWidgetContainer, DashboardGridContainer, DashboardErrorContainer, DashboardNavSection, ModelViewContent, WebviewContent, WidgetContent,
ComponentHostDirective, BreadcrumbComponent, ControlHostContent, DashboardControlHostContainer, ComponentHostDirective, BreadcrumbComponent, ControlHostContent, DashboardControlHostContainer,
JobsViewComponent, NotebooksViewComponent, AgentViewComponent, JobHistoryComponent, NotebookHistoryComponent, JobStepsViewComponent, AlertsViewComponent, ProxiesViewComponent, OperatorsViewComponent, JobsViewComponent, NotebooksViewComponent, AgentViewComponent, JobHistoryComponent, NotebookHistoryComponent, JobStepsViewComponent, AlertsViewComponent, ProxiesViewComponent, OperatorsViewComponent,
DashboardModelViewContainer, ModelComponentWrapper, Checkbox, EditableDropDown, SelectBox, InputBox, LoadingSpinner]; DashboardModelViewContainer, ModelComponentWrapper, Checkbox, EditableDropDown, SelectBox, InputBox];
/* Panel */ /* Panel */
import { PanelModule } from 'sql/base/browser/ui/panel/panel.module'; import { PanelModule } from 'sql/base/browser/ui/panel/panel.module';
@@ -87,6 +86,8 @@ import { WebviewWidget } from 'sql/workbench/contrib/dashboard/browser/widgets/w
import { JobStepsViewComponent } from 'sql/workbench/contrib/jobManagement/browser/jobStepsView.component'; import { JobStepsViewComponent } from 'sql/workbench/contrib/jobManagement/browser/jobStepsView.component';
import { IInstantiationService, _util } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService, _util } from 'vs/platform/instantiation/common/instantiation';
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry'; import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
import { PropertiesContainerModule } from 'sql/base/browser/ui/propertiesContainer/propertiesContainer.module';
import { LoadingSpinnerModule } from 'sql/base/browser/ui/loadingSpinner/loadingSpinner.module';
const widgetComponents = [ const widgetComponents = [
@@ -140,7 +141,9 @@ export const DashboardModule = (params, selector: string, instantiationService:
ChartsModule, ChartsModule,
RouterModule.forRoot(appRoutes), RouterModule.forRoot(appRoutes),
PanelModule, PanelModule,
ScrollableModule ScrollableModule,
PropertiesContainerModule,
LoadingSpinnerModule
], ],
providers: [ providers: [
{ provide: APP_BASE_HREF, useValue: '/' }, { provide: APP_BASE_HREF, useValue: '/' },

View File

@@ -2,9 +2,7 @@
* Copyright (c) Microsoft Corporation. All rights reserved. * Copyright (c) Microsoft Corporation. All rights reserved.
* 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.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import 'vs/css!./propertiesWidget'; import { Component, Inject, forwardRef, ChangeDetectorRef, OnInit, ElementRef, ViewChild } from '@angular/core';
import { Component, Inject, forwardRef, ChangeDetectorRef, OnInit, ElementRef } from '@angular/core';
import { DashboardWidget, IDashboardWidget, WidgetConfig, WIDGET_CONFIG } from 'sql/workbench/contrib/dashboard/browser/core/dashboardWidget'; import { DashboardWidget, IDashboardWidget, WidgetConfig, WIDGET_CONFIG } from 'sql/workbench/contrib/dashboard/browser/core/dashboardWidget';
import { CommonServiceInterface } from 'sql/workbench/services/bootstrap/browser/commonServiceInterface.service'; import { CommonServiceInterface } from 'sql/workbench/services/bootstrap/browser/commonServiceInterface.service';
@@ -12,13 +10,13 @@ import { ConnectionManagementInfo } from 'sql/platform/connection/common/connect
import { IDashboardRegistry, Extensions as DashboardExtensions } from 'sql/workbench/contrib/dashboard/browser/dashboardRegistry'; import { IDashboardRegistry, Extensions as DashboardExtensions } from 'sql/workbench/contrib/dashboard/browser/dashboardRegistry';
import { DatabaseInfo, ServerInfo } from 'azdata'; import { DatabaseInfo, ServerInfo } from 'azdata';
import { EventType, addDisposableListener } from 'vs/base/browser/dom';
import * as types from 'vs/base/common/types'; import * as types from 'vs/base/common/types';
import * as nls from 'vs/nls'; import * as nls from 'vs/nls';
import { Registry } from 'vs/platform/registry/common/platform'; import { Registry } from 'vs/platform/registry/common/platform';
import { ILogService } from 'vs/platform/log/common/log'; import { ILogService } from 'vs/platform/log/common/log';
import { subscriptionToDisposable } from 'sql/base/browser/lifecycle'; import { subscriptionToDisposable } from 'sql/base/browser/lifecycle';
import { PropertiesContainer, DisplayProperty } from 'sql/base/browser/ui/propertiesContainer/propertiesContainer.component';
import { convertSizeToNumber } from 'sql/base/browser/dom';
export interface PropertiesConfig { export interface PropertiesConfig {
properties: Array<Property>; properties: Array<Property>;
@@ -52,37 +50,13 @@ export interface Property {
const dashboardRegistry = Registry.as<IDashboardRegistry>(DashboardExtensions.DashboardContributions); const dashboardRegistry = Registry.as<IDashboardRegistry>(DashboardExtensions.DashboardContributions);
export interface DisplayProperty {
displayName: string;
value: string;
}
enum GridDisplayLayout {
twoColumns = 'twoColumns',
oneColumn = 'oneColumn'
}
enum PropertyLayoutDirection {
row = 'rowLayout',
column = 'columnLayout'
}
const collapseHeight = 25;
const horizontalPropertyHeight = 28;
const verticalPropertyHeight = 46;
@Component({ @Component({
selector: 'properties-widget', selector: 'properties-widget',
templateUrl: decodeURI(require.toUrl('./propertiesWidget.component.html')) template: '<properties-container></properties-container>'
}) })
export class PropertiesWidgetComponent extends DashboardWidget implements IDashboardWidget, OnInit { export class PropertiesWidgetComponent extends DashboardWidget implements IDashboardWidget, OnInit {
@ViewChild(PropertiesContainer) private _propertiesContainer: PropertiesContainer;
private _connection: ConnectionManagementInfo; private _connection: ConnectionManagementInfo;
private _databaseInfo: DatabaseInfo;
private _properties: Array<DisplayProperty>;
public gridDisplayLayout: GridDisplayLayout;
public propertyLayout: PropertyLayoutDirection;
public height: number;
constructor( constructor(
@Inject(forwardRef(() => CommonServiceInterface)) private _bootstrap: CommonServiceInterface, @Inject(forwardRef(() => CommonServiceInterface)) private _bootstrap: CommonServiceInterface,
@@ -92,14 +66,11 @@ export class PropertiesWidgetComponent extends DashboardWidget implements IDashb
@Inject(ILogService) private logService: ILogService @Inject(ILogService) private logService: ILogService
) { ) {
super(changeRef); super(changeRef);
this._loadingMessage = nls.localize('loadingProperties', "Loading properties");
this._loadingCompletedMessage = nls.localize('loadingPropertiesCompleted', "Loading properties completed");
this.init(); this.init();
} }
ngOnInit() { ngOnInit() {
this._inited = true; this._inited = true;
this._register(addDisposableListener(window, EventType.RESIZE, () => this.layoutProperties()));
this._changeRef.detectChanges(); this._changeRef.detectChanges();
} }
@@ -110,43 +81,22 @@ export class PropertiesWidgetComponent extends DashboardWidget implements IDashb
private init(): void { private init(): void {
this._connection = this._bootstrap.connectionManagementService.connectionInfo; this._connection = this._bootstrap.connectionManagementService.connectionInfo;
this.setLoadingStatus(true); this.setLoadingStatus(true);
this._register(subscriptionToDisposable(this._bootstrap.adminService.databaseInfo.subscribe(data => { this._register(subscriptionToDisposable(this._bootstrap.adminService.databaseInfo.subscribe(databaseInfo => {
this._databaseInfo = data; const displayProperties = this.parseProperties(databaseInfo);
if (this._inited) {
this._propertiesContainer.displayProperties = displayProperties;
this._changeRef.detectChanges(); this._changeRef.detectChanges();
this.parseProperties(); } else {
this.logService.info('Database properties successfully retrieved but component not initialized yet');
}
this.setLoadingStatus(false); this.setLoadingStatus(false);
this.layoutProperties();
}, error => { }, error => {
this.setLoadingStatus(false); this.setLoadingStatus(false);
(<HTMLElement>this._el.nativeElement).innerText = nls.localize('dashboard.properties.error', "Unable to load dashboard properties"); (<HTMLElement>this._el.nativeElement).innerText = nls.localize('dashboard.properties.error', "Unable to load dashboard properties");
}))); })));
} }
private layoutProperties(): void { private parseProperties(databaseInfo?: DatabaseInfo): DisplayProperty[] {
// Reflow:
// 2 columns w/ horizontal alignment : 1366px and above
// 2 columns w/ vertical alignment : 1024 - 1365px
// 1 column w/ vertical alignment : 1024px or less
if (!this._loading) {
if (window.innerWidth >= 1366) {
this.gridDisplayLayout = GridDisplayLayout.twoColumns;
this.propertyLayout = PropertyLayoutDirection.row;
this.height = Math.ceil(this._properties.length / 2) * horizontalPropertyHeight + collapseHeight;
} else if (window.innerWidth < 1366 && window.innerWidth >= 1024) {
this.gridDisplayLayout = GridDisplayLayout.twoColumns;
this.propertyLayout = PropertyLayoutDirection.column;
this.height = Math.ceil(this._properties.length / 2) * verticalPropertyHeight + collapseHeight;
} else if (window.innerWidth < 1024) {
this.gridDisplayLayout = GridDisplayLayout.oneColumn;
this.propertyLayout = PropertyLayoutDirection.column;
this.height = this._properties.length * verticalPropertyHeight + collapseHeight;
}
this._changeRef.detectChanges();
}
}
private parseProperties() {
const provider = this._config.provider; const provider = this._config.provider;
let propertyArray: Array<Property>; let propertyArray: Array<Property>;
@@ -160,7 +110,7 @@ export class PropertiesWidgetComponent extends DashboardWidget implements IDashb
if (!providerProperties) { if (!providerProperties) {
this.logService.error('No property definitions found for provider', provider); this.logService.error('No property definitions found for provider', provider);
return; return [];
} }
let flavor: FlavorProperties; let flavor: FlavorProperties;
@@ -171,7 +121,7 @@ export class PropertiesWidgetComponent extends DashboardWidget implements IDashb
} else if (providerProperties.flavors.length === 0) { } else if (providerProperties.flavors.length === 0) {
this.logService.error('No flavor definitions found for "', provider, this.logService.error('No flavor definitions found for "', provider,
'. If there are not multiple flavors of this provider, add one flavor without a condition'); '. If there are not multiple flavors of this provider, add one flavor without a condition');
return; return [];
} else { } else {
const flavorArray = providerProperties.flavors.filter((item) => { const flavorArray = providerProperties.flavors.filter((item) => {
@@ -196,10 +146,10 @@ export class PropertiesWidgetComponent extends DashboardWidget implements IDashb
if (flavorArray.length === 0) { if (flavorArray.length === 0) {
this.logService.error('Could not determine flavor'); this.logService.error('Could not determine flavor');
return; return [];
} else if (flavorArray.length > 1) { } else if (flavorArray.length > 1) {
this.logService.error('Multiple flavors matched correctly for this provider', provider); this.logService.error('Multiple flavors matched correctly for this provider', provider);
return; return [];
} }
flavor = flavorArray[0]; flavor = flavorArray[0];
@@ -228,14 +178,14 @@ export class PropertiesWidgetComponent extends DashboardWidget implements IDashb
let infoObject: ServerInfo | {}; let infoObject: ServerInfo | {};
if (this._config.context === 'database') { if (this._config.context === 'database') {
if (this._databaseInfo && this._databaseInfo.options) { if (databaseInfo?.options) {
infoObject = this._databaseInfo.options; infoObject = databaseInfo.options;
} }
} else { } else {
infoObject = this._connection.serverInfo; infoObject = this._connection.serverInfo;
} }
this._properties = propertyArray.map(property => { return propertyArray.map(property => {
let propertyObject = this.getValueOrDefault<string>(infoObject, property.value, property.default || '--'); let propertyObject = this.getValueOrDefault<string>(infoObject, property.value, property.default || '--');
// make sure the value we got shouldn't be ignored // make sure the value we got shouldn't be ignored
@@ -294,4 +244,15 @@ export class PropertiesWidgetComponent extends DashboardWidget implements IDashb
} }
return val; return val;
} }
protected setLoadingStatus(loading: boolean): void {
super.setLoadingStatus(loading);
if (this._inited) {
this._propertiesContainer.loading = loading;
}
}
public get height(): number {
return convertSizeToNumber(this._propertiesContainer.height);
}
} }

View File

@@ -16,6 +16,7 @@ import * as TypeMoq from 'typemoq';
import * as assert from 'assert'; import * as assert from 'assert';
import { mssqlProviderName } from 'sql/platform/connection/common/constants'; import { mssqlProviderName } from 'sql/platform/connection/common/constants';
import { NullLogService } from 'vs/platform/log/common/log'; import { NullLogService } from 'vs/platform/log/common/log';
import { DisplayProperty } from 'sql/base/browser/ui/propertiesContainer/propertiesContainer.component';
class TestChangeDetectorRef extends ChangeDetectorRef { class TestChangeDetectorRef extends ChangeDetectorRef {
reattach(): void { reattach(): void {
@@ -103,10 +104,10 @@ suite('Dashboard Properties Widget Tests', () => {
return new Promise(resolve => { return new Promise(resolve => {
// because config parsing is done async we need to put our asserts on the thread stack // because config parsing is done async we need to put our asserts on the thread stack
setImmediate(() => { setImmediate(() => {
// because properties is private we need to do some work arounds to access it. const displayProperties: DisplayProperty[] = (testComponent as any).parseProperties(databaseInfo);
assert.equal((<any>testComponent)._properties.length, 1); assert.equal(displayProperties.length, 1);
assert.equal((<any>testComponent)._properties[0].displayName, 'Test'); assert.equal(displayProperties[0].displayName, 'Test');
assert.equal((<any>testComponent)._properties[0].value, 'Test Property'); assert.equal(displayProperties[0].value, 'Test Property');
resolve(); resolve();
}); });
}); });

View File

@@ -20,7 +20,7 @@ import { OutputAreaComponent } from 'sql/workbench/contrib/notebook/browser/cell
import { OutputComponent } from 'sql/workbench/contrib/notebook/browser/cellViews/output.component'; import { OutputComponent } from 'sql/workbench/contrib/notebook/browser/cellViews/output.component';
import { StdInComponent } from 'sql/workbench/contrib/notebook/browser/cellViews/stdin.component'; import { StdInComponent } from 'sql/workbench/contrib/notebook/browser/cellViews/stdin.component';
import { PlaceholderCellComponent } from 'sql/workbench/contrib/notebook/browser/cellViews/placeholderCell.component'; import { PlaceholderCellComponent } from 'sql/workbench/contrib/notebook/browser/cellViews/placeholderCell.component';
import LoadingSpinner from 'sql/workbench/browser/modelComponents/loadingSpinner.component'; import LoadingSpinner from 'sql/base/browser/ui/loadingSpinner/loadingSpinner.component';
import { Checkbox } from 'sql/base/browser/ui/checkbox/checkbox.component'; import { Checkbox } from 'sql/base/browser/ui/checkbox/checkbox.component';
import { SelectBox } from 'sql/platform/browser/selectBox/selectBox.component'; import { SelectBox } from 'sql/platform/browser/selectBox/selectBox.component';
import { InputBox } from 'sql/platform/browser/inputbox/inputBox.component'; import { InputBox } from 'sql/platform/browser/inputbox/inputBox.component';