Convert ModelView validate to Promise (#13390)

* Convert ModelView validate to Promise

* more cleanup
This commit is contained in:
Charles Gagnon
2020-11-13 15:31:22 -08:00
committed by GitHub
parent 76781d6cf4
commit af55dcfb42
11 changed files with 48 additions and 68 deletions

View File

@@ -99,7 +99,7 @@ export interface IComponent extends IDisposable {
setProperties?: (properties: { [key: string]: any; }) => void;
enabled: boolean;
readonly valid?: boolean;
validate(): Thenable<boolean>;
validate(): Promise<boolean>;
setDataProvider(handle: number, componentId: string, context: any): void;
refreshDataProvider(item: any): void;
focus(): void;

View File

@@ -42,7 +42,7 @@ export interface IModelView extends IView {
refreshDataProvider(componentId: string, item: any): void;
registerEvent(componentId: string, initial?: boolean): void;
onEvent: Event<IModelViewEventArgs>;
validate(componentId: string): Thenable<boolean>;
validate(componentId: string): Promise<boolean>;
readonly onDestroy: Event<void>;
focus(componentId: string): void;
doAction(componentId: string, action: string, ...args: any[]): void;

View File

@@ -17,6 +17,7 @@ import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/work
import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } from 'sql/platform/dashboard/browser/interfaces';
import { isNumber } from 'vs/base/common/types';
import { convertSize } from 'sql/base/browser/dom';
import { onUnexpectedError } from 'vs/base/common/errors';
import { ILogService } from 'vs/platform/log/common/log';
@Component({
@@ -94,7 +95,7 @@ export default class CheckBoxComponent extends ComponentBase<azdata.CheckBoxProp
if (this.required) {
this._input.required = this.required;
}
this.validate();
this.validate().catch(onUnexpectedError);
}
// CSS-bound properties

View File

@@ -20,6 +20,7 @@ import { EventType, addDisposableListener } from 'vs/base/browser/dom';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { IComponentDescriptor, IComponent, IModelStore, IComponentEventArgs, ComponentEventType } from 'sql/platform/dashboard/browser/interfaces';
import { convertSize } from 'sql/base/browser/dom';
import { onUnexpectedError } from 'vs/base/common/errors';
import { ILogService } from 'vs/platform/log/common/log';
export type IUserFriendlyIcon = string | URI | { light: string | URI; dark: string | URI };
@@ -97,7 +98,7 @@ export abstract class ComponentBase<TPropertyBag extends azdata.ComponentPropert
this.properties = properties;
this.updateStyles();
this.layout();
this.validate();
this.validate().catch(onUnexpectedError);
}
// Helper Function to update single property
@@ -106,7 +107,7 @@ export abstract class ComponentBase<TPropertyBag extends azdata.ComponentPropert
this.properties[key] = value;
this.updateStyles();
this.layout();
this.validate();
this.validate().catch(onUnexpectedError);
}
}
@@ -125,7 +126,7 @@ export abstract class ComponentBase<TPropertyBag extends azdata.ComponentPropert
eventType: ComponentEventType.PropertiesChanged,
args: this.getProperties()
});
this.validate();
this.validate().catch(onUnexpectedError);
}
public get enabled(): boolean {
@@ -246,19 +247,18 @@ export abstract class ComponentBase<TPropertyBag extends azdata.ComponentPropert
}
}
public validate(): Thenable<boolean> {
public async validate(): Promise<boolean> {
let validations = this._validations.map(validation => Promise.resolve(validation()));
return Promise.all(validations).then(values => {
let isValid = values.every(value => value === true);
if (this._valid !== isValid) {
this._valid = isValid;
this.fireEvent({
eventType: ComponentEventType.validityChanged,
args: this._valid
});
}
return isValid;
});
const validationResults = await Promise.all(validations);
const isValid = validationResults.every(value => value === true);
if (this._valid !== isValid) {
this._valid = isValid;
this.fireEvent({
eventType: ComponentEventType.validityChanged,
args: this._valid
});
}
return isValid;
}
public focus(): void {
@@ -320,7 +320,7 @@ export abstract class ContainerBase<T, TPropertyBag extends azdata.ComponentProp
component.registerEventHandler(async event => {
if (event.eventType === ComponentEventType.validityChanged) {
this.logService.debug(`Running validation on container ${this.descriptor.id} because validity of child component ${componentDescriptor.id} changed`);
this.validate();
this.validate().catch(onUnexpectedError);
}
});
}, true);
@@ -347,7 +347,7 @@ export abstract class ContainerBase<T, TPropertyBag extends azdata.ComponentProp
this.items = [];
this.onItemsUpdated();
this._changeRef.detectChanges();
this.validate();
this.validate().catch(onUnexpectedError);
}
public setProperties(properties: { [key: string]: any; }): void {

View File

@@ -27,6 +27,7 @@ import { SimpleProgressIndicator } from 'sql/workbench/services/progress/browser
import { IEditorProgressService } from 'vs/platform/progress/common/progress';
import { IComponent, IComponentDescriptor, IModelStore } from 'sql/platform/dashboard/browser/interfaces';
import { convertSizeToNumber } from 'sql/base/browser/dom';
import { onUnexpectedError } from 'vs/base/common/errors';
import { ILogService } from 'vs/platform/log/common/log';
@Component({
@@ -101,7 +102,7 @@ export default class DiffEditorComponent extends ComponentBase<azdata.DiffEditor
this._editorModel = model as TextDiffEditorModel;
this.updateModel();
this.layout();
this.validate();
this.validate().catch(onUnexpectedError);
});
this._register(this._editor);
@@ -173,7 +174,7 @@ export default class DiffEditorComponent extends ComponentBase<azdata.DiffEditor
this._minimumHeight = this.minimumHeight;
this._title = this.title;
this.layout();
this.validate();
this.validate().catch(onUnexpectedError);
}
// CSS-bound properties

View File

@@ -21,6 +21,7 @@ import { IContextViewService } from 'vs/platform/contextview/browser/contextView
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } from 'sql/platform/dashboard/browser/interfaces';
import { localize } from 'vs/nls';
import { onUnexpectedError } from 'vs/base/common/errors';
import { ILogService } from 'vs/platform/log/common/log';
@Component({
@@ -162,7 +163,7 @@ export default class DropDownComponent extends ComponentBase<azdata.DropDownProp
this._selectBox.selectElem.required = this.required;
this._editableDropdown.inputElement.required = this.required;
this.validate();
this.validate().catch(onUnexpectedError);
}
private getValues(): string[] {

View File

@@ -91,13 +91,6 @@ export default class FileBrowserTreeComponent extends ComponentBase<azdata.FileB
}
}
public validate(): Thenable<boolean> {
return super.validate().then(valid => {
// TODO: tree validation?
return valid;
});
}
ngOnDestroy(): void {
this.baseDestroy();
}
@@ -115,7 +108,6 @@ export default class FileBrowserTreeComponent extends ComponentBase<azdata.FileB
public setProperties(properties: { [key: string]: any; }): void {
super.setProperties(properties);
this.validate();
if (this.ownerUri) {
this.initialize();
}

View File

@@ -26,6 +26,7 @@ import { assign } from 'vs/base/common/objects';
import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } from 'sql/platform/dashboard/browser/interfaces';
import { isNumber } from 'vs/base/common/types';
import { convertSize, convertSizeToNumber } from 'sql/base/browser/dom';
import { onUnexpectedError } from 'vs/base/common/errors';
import { ILogService } from 'vs/platform/log/common/log';
@Component({
@@ -157,27 +158,25 @@ export default class InputBoxComponent extends ComponentBase<azdata.InputBoxProp
return this.multiline ? '' : 'none';
}
public validate(): Thenable<boolean> {
return super.validate().then(valid => {
const otherErrorMsg = valid || this.inputElement.value === '' ? undefined : this.validationErrorMessage;
valid = valid && this.inputElement.validate();
public async validate(): Promise<boolean> {
let valid = await super.validate();
const otherErrorMsg = valid || this.inputElement.value === '' ? undefined : this.validationErrorMessage;
valid = valid && this.inputElement.validate();
// set aria label based on validity of input
if (valid) {
this.inputElement.setAriaLabel(this.ariaLabel);
} else {
if (otherErrorMsg) {
this.inputElement.showMessage({ type: MessageType.ERROR, content: otherErrorMsg }, true);
}
if (this.ariaLabel) {
this.inputElement.setAriaLabel(nls.localize('period', "{0}. {1}", this.ariaLabel, this.inputElement.inputElement.validationMessage));
} else {
this.inputElement.setAriaLabel(this.inputElement.inputElement.validationMessage);
}
// set aria label based on validity of input
if (valid) {
this.inputElement.setAriaLabel(this.ariaLabel);
} else {
if (otherErrorMsg) {
this.inputElement.showMessage({ type: MessageType.ERROR, content: otherErrorMsg }, true);
}
return valid;
});
if (this.ariaLabel) {
this.inputElement.setAriaLabel(nls.localize('period', "{0}. {1}", this.ariaLabel, this.inputElement.inputElement.validationMessage));
} else {
this.inputElement.setAriaLabel(this.inputElement.inputElement.validationMessage);
}
}
return valid;
}
ngOnDestroy(): void {
@@ -208,7 +207,7 @@ export default class InputBoxComponent extends ComponentBase<azdata.InputBoxProp
public setProperties(properties: { [key: string]: any; }): void {
super.setProperties(properties);
this.setInputProperties(this.inputElement);
this.validate();
this.validate().catch(onUnexpectedError);
}
private setInputProperties(input: InputBox): void {

View File

@@ -80,12 +80,6 @@ export default class ListBoxComponent extends ComponentBase<azdata.ListBoxProper
this.baseInit();
}
public validate(): Thenable<boolean> {
return super.validate().then(valid => {
return valid;
});
}
ngOnDestroy(): void {
this.baseDestroy();
}
@@ -99,8 +93,6 @@ export default class ListBoxComponent extends ComponentBase<azdata.ListBoxProper
public setProperties(properties: { [key: string]: any; }): void {
super.setProperties(properties);
this._input.setOptions(this.values.map(value => { return { text: value }; }), this.selectedRow);
this.validate();
}
// CSS-bound properties

View File

@@ -30,6 +30,7 @@ import { convertSizeToNumber } from 'sql/base/browser/dom';
import { ButtonColumn, ButtonClickEventArgs } from 'sql/base/browser/ui/table/plugins/buttonColumn.plugin';
import { IUserFriendlyIcon, createIconCssClass, getIconKey } from 'sql/workbench/browser/modelComponents/iconUtils';
import { HeaderFilter } from 'sql/base/browser/ui/table/plugins/headerFilter.plugin';
import { onUnexpectedError } from 'vs/base/common/errors';
import { ILogService } from 'vs/platform/log/common/log';
export enum ColumnSizingMode {
@@ -238,13 +239,6 @@ export default class TableComponent extends ComponentBase<azdata.TableComponentP
this.baseInit();
}
public validate(): Thenable<boolean> {
return super.validate().then(valid => {
// TODO: table validation?
return valid;
});
}
ngOnDestroy(): void {
this.baseDestroy();
}
@@ -346,7 +340,7 @@ export default class TableComponent extends ComponentBase<azdata.TableComponentP
}
this.layoutTable();
this.validate();
this.validate().catch(onUnexpectedError);
}
private updateTableCells(cellInfos): void {

View File

@@ -174,7 +174,7 @@ export abstract class ViewBase extends AngularDisposable implements IModelView {
return this._onEventEmitter.event;
}
public validate(componentId: string): Thenable<boolean> {
public validate(componentId: string): Promise<boolean> {
return new Promise(resolve => this.modelStore.eventuallyRunOnComponent(componentId, component => resolve(component.validate()), false));
}