diff --git a/src/sql/workbench/browser/modelComponents/declarativeTable.component.ts b/src/sql/workbench/browser/modelComponents/declarativeTable.component.ts index e4f54c9b2e..7e7c4eb239 100644 --- a/src/sql/workbench/browser/modelComponents/declarativeTable.component.ts +++ b/src/sql/workbench/browser/modelComponents/declarativeTable.component.ts @@ -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 { {{cellData}} - + @@ -54,10 +54,13 @@ export enum DeclarativeDataType { ` }) -export default class DeclarativeTableComponent extends ComponentBase implements IComponent, OnDestroy, AfterViewInit { +export default class DeclarativeTableComponent extends ContainerBase 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 { - 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((props) => props.data, []); - } - - public set data(newValue: any[][]) { - this.setPropertyFromUI((props, value) => props.data = value, newValue); - } - - public get columns(): azdata.DeclarativeTableColumn[] { - return this.getPropertyOrDefault((props) => props.columns, []); - } - - public set columns(newValue: azdata.DeclarativeTableColumn[]) { - this.setPropertyFromUI((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(); - } - }