fix declarative table issue (#10833)

* fix declarative table issue

* check data

* comments

* comments and more fixes
This commit is contained in:
Alan Ren
2020-06-10 22:21:45 -07:00
committed by GitHub
parent 5ab6d3d07e
commit 3f21caddb6

View File

@@ -11,9 +11,9 @@ import {
import * as azdata from 'azdata';
import { ComponentBase } from 'sql/workbench/browser/modelComponents/componentBase';
import { ContainerBase } from 'sql/workbench/browser/modelComponents/componentBase';
import { ISelectData } from 'vs/base/browser/ui/selectBox/selectBox';
import { find } from 'vs/base/common/arrays';
import { find, equals as arrayEquals } from 'vs/base/common/arrays';
import { localize } from 'vs/nls';
import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } from 'sql/platform/dashboard/browser/interfaces';
import { convertSize } from 'sql/base/browser/dom';
@@ -45,7 +45,7 @@ export enum DeclarativeDataType {
<editable-select-box *ngIf="isEditableSelectBox(c)" [options]="getOptions(c)" (onDidSelect)="onSelectBoxChanged($event,r,c)" [selectedOption]="getSelectedOptionDisplayName(r,c)"></editable-select-box>
<input-box *ngIf="isInputBox(c)" [value]="cellData" (onDidChange)="onInputBoxChanged($event,r,c)"></input-box>
<ng-container *ngIf="isLabel(c)" >{{cellData}}</ng-container>
<model-component-wrapper *ngIf="isComponent(c)" [descriptor]="getItemDescriptor(cellData)" [modelStore]="modelStore"></model-component-wrapper>
<model-component-wrapper *ngIf="isComponent(c) && getItemDescriptor(cellData)" [descriptor]="getItemDescriptor(cellData)" [modelStore]="modelStore"></model-component-wrapper>
</td>
</ng-container>
</tr>
@@ -54,10 +54,13 @@ export enum DeclarativeDataType {
</table>
`
})
export default class DeclarativeTableComponent extends ComponentBase implements IComponent, OnDestroy, AfterViewInit {
export default class DeclarativeTableComponent extends ContainerBase<any> implements IComponent, OnDestroy, AfterViewInit {
@Input() descriptor: IComponentDescriptor;
@Input() modelStore: IModelStore;
public data: any[][] = [];
public columns: azdata.DeclarativeTableColumn[] = [];
constructor(
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(forwardRef(() => ElementRef)) el: ElementRef
@@ -72,12 +75,6 @@ export default class DeclarativeTableComponent extends ComponentBase implements
ngAfterViewInit(): void {
}
public validate(): Thenable<boolean> {
return super.validate().then(valid => {
return valid;
});
}
ngOnDestroy(): void {
this.baseDestroy();
}
@@ -204,36 +201,29 @@ export default class DeclarativeTableComponent extends ComponentBase implements
}
public setProperties(properties: { [key: string]: any; }): void {
const newData = properties.data ?? [];
this.columns = properties.columns ?? [];
// check whether the data property is changed before actually setting the properties.
const isDataPropertyChanged = !arrayEquals(this.data, newData ?? [], (a, b) => {
return arrayEquals(a, b);
});
// the angular is using reference compare to determine whether the data is changed or not
// so we are only updating it when the actual data has changed by doing the deep comparison.
// if the data property is changed, we need add child components to the container,
// so that the events can be passed upwards through the control hierarchy.
if (isDataPropertyChanged) {
this.clearContainer();
this.data = newData;
this.data?.forEach(row => {
for (let i = 0; i < row.length; i++) {
if (this.isComponent(i)) {
this.addToContainer(this.getItemDescriptor(row[i] as string), undefined);
}
}
});
}
super.setProperties(properties);
}
public get data(): any[][] {
return this.getPropertyOrDefault<azdata.DeclarativeTableProperties, any[]>((props) => props.data, []);
}
public set data(newValue: any[][]) {
this.setPropertyFromUI<azdata.DeclarativeTableProperties, any[][]>((props, value) => props.data = value, newValue);
}
public get columns(): azdata.DeclarativeTableColumn[] {
return this.getPropertyOrDefault<azdata.DeclarativeTableProperties, azdata.DeclarativeTableColumn[]>((props) => props.columns, []);
}
public set columns(newValue: azdata.DeclarativeTableColumn[]) {
this.setPropertyFromUI<azdata.DeclarativeTableProperties, azdata.DeclarativeTableColumn[]>((props, value) => props.columns = value, newValue);
}
// IComponent container-related implementation
// This is needed for the component column type - in order to have the components in the cells registered we call addItem
// on the extension side to create and register the component with the ModelStore. That requires that these methods be implemented
// though which isn't done by default for non-Container components and so we just stub out the implementation here (we already have
// the component IDs in the data property so there's no need to store them here as well)
public addToContainer(componentDescriptor: IComponentDescriptor, config: any, index?: number): void {
this._changeRef.detectChanges();
}
public clearContainer(): void {
this._changeRef.detectChanges();
}
}