mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-23 17:23:02 -05:00
Add more to strict nulls (#11871)
* add more to strict nulls * maintain error handling properly * fix lint
This commit is contained in:
@@ -83,44 +83,44 @@ const tabbableElementsQuerySelector = 'a[href], area[href], input:not([disabled]
|
||||
|
||||
export abstract class Modal extends Disposable implements IThemable {
|
||||
protected _useDefaultMessageBoxLocation: boolean = true;
|
||||
protected _messageElement: HTMLElement;
|
||||
protected _messageElement?: HTMLElement;
|
||||
protected _modalOptions: IModalOptions;
|
||||
protected readonly disposableStore = this._register(new DisposableStore());
|
||||
private _detailsButtonContainer: HTMLElement;
|
||||
private _messageIcon: HTMLElement;
|
||||
private _messageSeverity: HTMLElement;
|
||||
private _messageSummary: HTMLElement;
|
||||
private _messageBody: HTMLElement;
|
||||
private _messageDetail: HTMLElement;
|
||||
private _toggleMessageDetailButton: Button;
|
||||
private _copyMessageButton: Button;
|
||||
private _closeMessageButton: Button;
|
||||
private _messageSummaryText: string;
|
||||
private _messageDetailText: string;
|
||||
private _detailsButtonContainer?: HTMLElement;
|
||||
private _messageIcon?: HTMLElement;
|
||||
private _messageSeverity?: HTMLElement;
|
||||
private _messageSummary?: HTMLElement;
|
||||
private _messageBody?: HTMLElement;
|
||||
private _messageDetail?: HTMLElement;
|
||||
private _toggleMessageDetailButton?: Button;
|
||||
private _copyMessageButton?: Button;
|
||||
private _closeMessageButton?: Button;
|
||||
private _messageSummaryText?: string;
|
||||
private _messageDetailText?: string;
|
||||
|
||||
private _spinnerElement: HTMLElement;
|
||||
private _firstTabbableElement: HTMLElement; // The first element in the dialog the user could tab to
|
||||
private _lastTabbableElement: HTMLElement; // The last element in the dialog the user could tab to
|
||||
private _focusedElementBeforeOpen: HTMLElement;
|
||||
private _spinnerElement?: HTMLElement;
|
||||
private _firstTabbableElement?: HTMLElement; // The first element in the dialog the user could tab to
|
||||
private _lastTabbableElement?: HTMLElement; // The last element in the dialog the user could tab to
|
||||
private _focusedElementBeforeOpen?: HTMLElement;
|
||||
|
||||
private _dialogForeground?: Color;
|
||||
private _dialogBorder?: Color;
|
||||
private _dialogHeaderAndFooterBackground?: Color;
|
||||
private _dialogBodyBackground?: Color;
|
||||
|
||||
private _modalDialog: HTMLElement;
|
||||
private _modalContent: HTMLElement;
|
||||
private _modalHeaderSection: HTMLElement;
|
||||
private _modalBodySection: HTMLElement;
|
||||
private _modalFooterSection: HTMLElement;
|
||||
private _closeButtonInHeader: HTMLElement;
|
||||
private _bodyContainer: HTMLElement;
|
||||
private _modalTitle: HTMLElement;
|
||||
private _modalTitleIcon: HTMLElement;
|
||||
private _leftFooter: HTMLElement;
|
||||
private _rightFooter: HTMLElement;
|
||||
private _footerButtons: Button[];
|
||||
private _backButton: Button;
|
||||
private _modalDialog?: HTMLElement;
|
||||
private _modalContent?: HTMLElement;
|
||||
private _modalHeaderSection?: HTMLElement;
|
||||
private _modalBodySection?: HTMLElement;
|
||||
private _modalFooterSection?: HTMLElement;
|
||||
private _closeButtonInHeader?: HTMLElement;
|
||||
private _bodyContainer?: HTMLElement;
|
||||
private _modalTitle?: HTMLElement;
|
||||
private _modalTitleIcon?: HTMLElement;
|
||||
private _leftFooter?: HTMLElement;
|
||||
private _rightFooter?: HTMLElement;
|
||||
private _footerButtons: Button[] = [];
|
||||
private _backButton?: Button;
|
||||
|
||||
private _modalShowingContext: IContextKey<Array<string>>;
|
||||
private readonly _staticKey: string;
|
||||
@@ -128,7 +128,7 @@ export abstract class Modal extends Disposable implements IThemable {
|
||||
/**
|
||||
* Get the back button, only available after render and if the hasBackButton option is true
|
||||
*/
|
||||
protected get backButton(): Button {
|
||||
protected get backButton(): Button | undefined {
|
||||
return this._backButton;
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ export abstract class Modal extends Disposable implements IThemable {
|
||||
* (hyoshi - 10/2/2017 tracked by https://github.com/Microsoft/carbon/issues/1836)
|
||||
*/
|
||||
public setWide(isWide: boolean): void {
|
||||
DOM.toggleClass(this._bodyContainer, 'wide', isWide);
|
||||
DOM.toggleClass(this._bodyContainer!, 'wide', isWide);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,7 +165,6 @@ export abstract class Modal extends Disposable implements IThemable {
|
||||
mixin(this._modalOptions, defaultOptions, false);
|
||||
this._staticKey = generateUuid();
|
||||
this._modalShowingContext = MODAL_SHOWING_CONTEXT.bindTo(_contextKeyService);
|
||||
this._footerButtons = [];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -248,7 +247,7 @@ export abstract class Modal extends Disposable implements IThemable {
|
||||
this._modalFooterSection = DOM.append(this._modalContent, DOM.$('.modal-footer'));
|
||||
if (this._modalOptions.hasSpinner) {
|
||||
this._spinnerElement = DOM.append(this._modalFooterSection, DOM.$('.codicon.in-progress'));
|
||||
this._spinnerElement.setAttribute('title', this._modalOptions.spinnerTitle);
|
||||
this._spinnerElement.setAttribute('title', this._modalOptions.spinnerTitle ?? '');
|
||||
DOM.hide(this._spinnerElement);
|
||||
}
|
||||
this._leftFooter = DOM.append(this._modalFooterSection, DOM.$('.left-footer'));
|
||||
@@ -294,42 +293,42 @@ export abstract class Modal extends Disposable implements IThemable {
|
||||
|
||||
private getTextForClipboard(): string {
|
||||
const eol = this.textResourcePropertiesService.getEOL(URI.from({ scheme: Schemas.untitled }));
|
||||
return this._messageDetailText === '' ? this._messageSummaryText : `${this._messageSummaryText}${eol}========================${eol}${this._messageDetailText}`;
|
||||
return this._messageDetailText === '' ? this._messageSummaryText! : `${this._messageSummaryText}${eol}========================${eol}${this._messageDetailText}`;
|
||||
}
|
||||
|
||||
private updateExpandMessageState() {
|
||||
this._messageSummary.style.cursor = this.shouldShowExpandMessageButton ? 'pointer' : 'default';
|
||||
DOM.removeClass(this._messageSummary, MESSAGE_EXPANDED_MODE_CLASS);
|
||||
this._messageSummary!.style.cursor = this.shouldShowExpandMessageButton ? 'pointer' : 'default';
|
||||
DOM.removeClass(this._messageSummary!, MESSAGE_EXPANDED_MODE_CLASS);
|
||||
if (this.shouldShowExpandMessageButton) {
|
||||
DOM.append(this._detailsButtonContainer, this._toggleMessageDetailButton.element);
|
||||
DOM.append(this._detailsButtonContainer!, this._toggleMessageDetailButton!.element);
|
||||
} else {
|
||||
DOM.removeNode(this._toggleMessageDetailButton.element);
|
||||
DOM.removeNode(this._toggleMessageDetailButton!.element);
|
||||
}
|
||||
}
|
||||
|
||||
private toggleMessageDetail() {
|
||||
const isExpanded = DOM.hasClass(this._messageSummary, MESSAGE_EXPANDED_MODE_CLASS);
|
||||
DOM.toggleClass(this._messageSummary, MESSAGE_EXPANDED_MODE_CLASS, !isExpanded);
|
||||
this._toggleMessageDetailButton.label = isExpanded ? SHOW_DETAILS_TEXT : localize('hideMessageDetails', "Hide Details");
|
||||
const isExpanded = DOM.hasClass(this._messageSummary!, MESSAGE_EXPANDED_MODE_CLASS);
|
||||
DOM.toggleClass(this._messageSummary!, MESSAGE_EXPANDED_MODE_CLASS, !isExpanded);
|
||||
this._toggleMessageDetailButton!.label = isExpanded ? SHOW_DETAILS_TEXT : localize('hideMessageDetails', "Hide Details");
|
||||
|
||||
if (this._messageDetailText) {
|
||||
if (isExpanded) {
|
||||
DOM.removeNode(this._messageDetail);
|
||||
DOM.removeNode(this._messageDetail!);
|
||||
} else {
|
||||
DOM.append(this._messageBody, this._messageDetail);
|
||||
DOM.append(this._messageBody!, this._messageDetail!);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private get shouldShowExpandMessageButton(): boolean {
|
||||
return this._messageDetailText !== '' || this._messageSummary.scrollWidth > this._messageSummary.offsetWidth;
|
||||
return this._messageDetailText !== '' || this._messageSummary!.scrollWidth > this._messageSummary!.offsetWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Figures out the first and last elements which the user can tab to in the dialog
|
||||
*/
|
||||
public setFirstLastTabbableElement() {
|
||||
const tabbableElements = this._bodyContainer.querySelectorAll(tabbableElementsQuerySelector);
|
||||
const tabbableElements = this._bodyContainer!.querySelectorAll(tabbableElementsQuerySelector);
|
||||
if (tabbableElements && tabbableElements.length > 0) {
|
||||
this._firstTabbableElement = <HTMLElement>tabbableElements[0];
|
||||
this._lastTabbableElement = <HTMLElement>tabbableElements[tabbableElements.length - 1];
|
||||
@@ -344,7 +343,7 @@ export abstract class Modal extends Disposable implements IThemable {
|
||||
// This ensures that we are setting the focus on a useful element in the form when possible.
|
||||
const focusableElements = this._modalBodySection ?
|
||||
this._modalBodySection.querySelectorAll(tabbableElementsQuerySelector) :
|
||||
this._bodyContainer.querySelectorAll(tabbableElementsQuerySelector);
|
||||
this._bodyContainer!.querySelectorAll(tabbableElementsQuerySelector);
|
||||
|
||||
if (focusableElements && focusableElements.length > 0) {
|
||||
(<HTMLElement>focusableElements[0]).focus();
|
||||
@@ -357,7 +356,7 @@ export abstract class Modal extends Disposable implements IThemable {
|
||||
protected show() {
|
||||
this._focusedElementBeforeOpen = <HTMLElement>document.activeElement;
|
||||
this._modalShowingContext.get()!.push(this._staticKey);
|
||||
DOM.append(this.layoutService.container, this._bodyContainer);
|
||||
DOM.append(this.layoutService.container, this._bodyContainer!);
|
||||
this.setInitialFocusedElement();
|
||||
|
||||
this.disposableStore.add(DOM.addDisposableListener(document, DOM.EventType.KEY_DOWN, (e: KeyboardEvent) => {
|
||||
@@ -376,10 +375,10 @@ export abstract class Modal extends Disposable implements IThemable {
|
||||
}
|
||||
}));
|
||||
this.disposableStore.add(DOM.addDisposableListener(window, DOM.EventType.RESIZE, (e: Event) => {
|
||||
this.layout(DOM.getTotalHeight(this._modalBodySection));
|
||||
this.layout(DOM.getTotalHeight(this._modalBodySection!));
|
||||
}));
|
||||
|
||||
this.layout(DOM.getTotalHeight(this._modalBodySection));
|
||||
this.layout(DOM.getTotalHeight(this._modalBodySection!));
|
||||
this._telemetryService.createActionEvent(TelemetryKeys.TelemetryView.Shell, TelemetryKeys.ModalDialogOpened)
|
||||
.withAdditionalProperties({ name: this._name })
|
||||
.send();
|
||||
@@ -395,7 +394,7 @@ export abstract class Modal extends Disposable implements IThemable {
|
||||
*/
|
||||
protected hide() {
|
||||
this._modalShowingContext.get()!.pop();
|
||||
this._bodyContainer.remove();
|
||||
this._bodyContainer!.remove();
|
||||
this.disposableStore.clear();
|
||||
this._telemetryService.createActionEvent(TelemetryKeys.TelemetryView.Shell, TelemetryKeys.ModalDialogClosed)
|
||||
.withAdditionalProperties({ name: this._name })
|
||||
@@ -420,9 +419,9 @@ export abstract class Modal extends Disposable implements IThemable {
|
||||
button.label = label;
|
||||
button.onDidClick(() => onSelect()); // @todo this should be registered to dispose but that brakes some dialogs
|
||||
if (orientation === 'left') {
|
||||
DOM.append(this._leftFooter, footerButton);
|
||||
DOM.append(this._leftFooter!, footerButton);
|
||||
} else {
|
||||
DOM.append(this._rightFooter, footerButton);
|
||||
DOM.append(this._rightFooter!, footerButton);
|
||||
}
|
||||
this._footerButtons.push(button);
|
||||
return button;
|
||||
@@ -433,7 +432,7 @@ export abstract class Modal extends Disposable implements IThemable {
|
||||
* @param label Label to show on the button
|
||||
* @param onSelect The callback to call when the button is selected
|
||||
*/
|
||||
protected findFooterButton(label: string): Button {
|
||||
protected findFooterButton(label: string): Button | undefined {
|
||||
return find(this._footerButtons, e => {
|
||||
try {
|
||||
return e && e.element.innerText === label;
|
||||
@@ -482,17 +481,17 @@ export abstract class Modal extends Disposable implements IThemable {
|
||||
severityText = WARNING_ALT_TEXT;
|
||||
}
|
||||
levelClasses.forEach(level => {
|
||||
DOM.toggleClass(this._messageIcon, level, selectedLevel === level);
|
||||
DOM.toggleClass(this._messageElement, level, selectedLevel === level);
|
||||
DOM.toggleClass(this._messageIcon!, level, selectedLevel === level);
|
||||
DOM.toggleClass(this._messageElement!, level, selectedLevel === level);
|
||||
});
|
||||
|
||||
this._messageIcon.title = severityText;
|
||||
this._messageSeverity.innerText = severityText;
|
||||
this._messageSummary.innerText = message!;
|
||||
this._messageSummary.title = message!;
|
||||
this._messageDetail.innerText = description;
|
||||
this._messageIcon!.title = severityText;
|
||||
this._messageSeverity!.innerText = severityText;
|
||||
this._messageSummary!.innerText = message!;
|
||||
this._messageSummary!.title = message!;
|
||||
this._messageDetail!.innerText = description;
|
||||
}
|
||||
DOM.removeNode(this._messageDetail);
|
||||
DOM.removeNode(this._messageDetail!);
|
||||
this.messagesElementVisible = !!this._messageSummaryText;
|
||||
this.updateExpandMessageState();
|
||||
}
|
||||
@@ -501,12 +500,12 @@ export abstract class Modal extends Disposable implements IThemable {
|
||||
protected set messagesElementVisible(visible: boolean) {
|
||||
if (visible) {
|
||||
if (this._useDefaultMessageBoxLocation) {
|
||||
DOM.prepend(this._modalContent, (this._messageElement));
|
||||
DOM.prepend(this._modalContent!, this._messageElement!);
|
||||
}
|
||||
} else {
|
||||
DOM.removeNode(this._messageElement);
|
||||
DOM.removeNode(this._messageElement!);
|
||||
// Set the focus to first focus element if the focus is not within the dialog
|
||||
if (!DOM.isAncestor(document.activeElement, this._bodyContainer)) {
|
||||
if (!DOM.isAncestor(document.activeElement, this._bodyContainer!)) {
|
||||
this.setInitialFocusedElement();
|
||||
}
|
||||
}
|
||||
@@ -518,12 +517,12 @@ export abstract class Modal extends Disposable implements IThemable {
|
||||
public set spinner(show: boolean) {
|
||||
if (this._modalOptions.hasSpinner) {
|
||||
if (show) {
|
||||
DOM.show(this._spinnerElement);
|
||||
DOM.show(this._spinnerElement!);
|
||||
if (this._modalOptions.spinnerTitle) {
|
||||
alert(this._modalOptions.spinnerTitle);
|
||||
}
|
||||
} else {
|
||||
DOM.hide(this._spinnerElement);
|
||||
DOM.hide(this._spinnerElement!);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -573,34 +572,34 @@ export abstract class Modal extends Disposable implements IThemable {
|
||||
}
|
||||
|
||||
private applyStyles(): void {
|
||||
const foreground = this._dialogForeground ? this._dialogForeground.toString() : null;
|
||||
const border = this._dialogBorder ? this._dialogBorder.toString() : null;
|
||||
const headerAndFooterBackground = this._dialogHeaderAndFooterBackground ? this._dialogHeaderAndFooterBackground.toString() : null;
|
||||
const bodyBackground = this._dialogBodyBackground ? this._dialogBodyBackground.toString() : null;
|
||||
const footerBorderTopWidth = border ? '1px' : null;
|
||||
const footerBorderTopStyle = border ? 'solid' : null;
|
||||
const foreground = this._dialogForeground ? this._dialogForeground.toString() : '';
|
||||
const border = this._dialogBorder ? this._dialogBorder.toString() : '';
|
||||
const headerAndFooterBackground = this._dialogHeaderAndFooterBackground ? this._dialogHeaderAndFooterBackground.toString() : '';
|
||||
const bodyBackground = this._dialogBodyBackground ? this._dialogBodyBackground.toString() : '';
|
||||
const footerBorderTopWidth = border ? '1px' : '';
|
||||
const footerBorderTopStyle = border ? 'solid' : '';
|
||||
|
||||
if (this._closeButtonInHeader) {
|
||||
this._closeButtonInHeader.style.color = foreground;
|
||||
}
|
||||
if (this._modalDialog) {
|
||||
this._modalDialog.style.color = foreground;
|
||||
this._modalDialog.style.borderWidth = border ? '1px' : null;
|
||||
this._modalDialog.style.borderStyle = border ? 'solid' : null;
|
||||
this._modalDialog.style.borderWidth = border ? '1px' : '';
|
||||
this._modalDialog.style.borderStyle = border ? 'solid' : '';
|
||||
this._modalDialog.style.borderColor = border;
|
||||
}
|
||||
|
||||
if (this._modalHeaderSection) {
|
||||
this._modalHeaderSection.style.backgroundColor = headerAndFooterBackground;
|
||||
this._modalHeaderSection.style.borderBottomWidth = border ? '1px' : null;
|
||||
this._modalHeaderSection.style.borderBottomStyle = border ? 'solid' : null;
|
||||
this._modalHeaderSection.style.borderBottomWidth = border ? '1px' : '';
|
||||
this._modalHeaderSection.style.borderBottomStyle = border ? 'solid' : '';
|
||||
this._modalHeaderSection.style.borderBottomColor = border;
|
||||
}
|
||||
|
||||
if (this._messageElement) {
|
||||
this._messageElement.style.backgroundColor = headerAndFooterBackground;
|
||||
this._messageElement.style.borderBottomWidth = border ? '1px' : null;
|
||||
this._messageElement.style.borderBottomStyle = border ? 'solid' : null;
|
||||
this._messageElement.style.borderBottomWidth = border ? '1px' : '';
|
||||
this._messageElement.style.borderBottomStyle = border ? 'solid' : '';
|
||||
this._messageElement.style.borderBottomColor = border;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,9 +60,9 @@ export const ACCOUNT_VIEW_CONTAINER = Registry.as<IViewContainersRegistry>(ViewC
|
||||
}, ViewContainerLocation.Dialog);
|
||||
|
||||
class AccountPanel extends ViewPane {
|
||||
public index: number;
|
||||
private accountList: List<azdata.Account>;
|
||||
private tenantList: List<Tenant>;
|
||||
public index?: number;
|
||||
private accountList?: List<azdata.Account>;
|
||||
private tenantList?: List<Tenant>;
|
||||
|
||||
|
||||
constructor(
|
||||
@@ -93,24 +93,24 @@ class AccountPanel extends ViewPane {
|
||||
}
|
||||
|
||||
public get length(): number {
|
||||
return this.accountList.length;
|
||||
return this.accountList!.length;
|
||||
}
|
||||
|
||||
public focus() {
|
||||
this.accountList.domFocus();
|
||||
this.accountList!.domFocus();
|
||||
}
|
||||
|
||||
public updateAccounts(accounts: azdata.Account[]) {
|
||||
this.accountList.splice(0, this.accountList.length, accounts);
|
||||
this.accountList!.splice(0, this.accountList!.length, accounts);
|
||||
}
|
||||
|
||||
public setSelection(indexes: number[]) {
|
||||
this.accountList.setSelection(indexes);
|
||||
this.updateTenants(this.accountList.getSelection[0]);
|
||||
this.accountList!.setSelection(indexes);
|
||||
this.updateTenants(this.accountList!.getSelectedElements()[0]);
|
||||
}
|
||||
|
||||
private updateTenants(account: azdata.Account) {
|
||||
this.tenantList.splice(0, this.tenantList.length, account?.properties?.tenants ?? []);
|
||||
this.tenantList!.splice(0, this.tenantList!.length, account.properties?.tenants ?? []);
|
||||
}
|
||||
|
||||
public getActions(): IAction[] {
|
||||
@@ -134,12 +134,12 @@ export class AccountDialog extends Modal {
|
||||
// MEMBER VARIABLES ////////////////////////////////////////////////////
|
||||
private _providerViewsMap = new Map<string, IProviderViewUiComponent>();
|
||||
|
||||
private _closeButton: Button;
|
||||
private _addAccountButton: Button;
|
||||
private _splitView: SplitView;
|
||||
private _container: HTMLElement;
|
||||
private _splitViewContainer: HTMLElement;
|
||||
private _noaccountViewContainer: HTMLElement;
|
||||
private _closeButton?: Button;
|
||||
private _addAccountButton?: Button;
|
||||
private _splitView?: SplitView;
|
||||
private _container?: HTMLElement;
|
||||
private _splitViewContainer?: HTMLElement;
|
||||
private _noaccountViewContainer?: HTMLElement;
|
||||
|
||||
// EVENTING ////////////////////////////////////////////////////////////
|
||||
private _onAddAccountErrorEmitter: Emitter<string>;
|
||||
@@ -199,8 +199,8 @@ export class AccountDialog extends Modal {
|
||||
}
|
||||
|
||||
// MODAL OVERRIDE METHODS //////////////////////////////////////////////
|
||||
protected layout(height?: number): void {
|
||||
this._splitView.layout(DOM.getContentHeight(this._container));
|
||||
protected layout(_height?: number): void {
|
||||
this._splitView!.layout(DOM.getContentHeight(this._container!));
|
||||
}
|
||||
|
||||
public render() {
|
||||
@@ -230,7 +230,7 @@ export class AccountDialog extends Modal {
|
||||
this._register(this._addAccountButton.onDidClick(async () => {
|
||||
const vals = Iterable.consume(this._providerViewsMap.values())[0];
|
||||
|
||||
let pickedValue: string;
|
||||
let pickedValue: string | undefined;
|
||||
if (vals.length === 0) {
|
||||
this._notificationService.error(localize('accountDialog.noCloudsRegistered', "You have no clouds enabled. Go to Settings -> Search Azure Account Configuration -> Enable at least one cloud"));
|
||||
return;
|
||||
@@ -262,8 +262,8 @@ export class AccountDialog extends Modal {
|
||||
|
||||
private registerListeners(): void {
|
||||
// Theme styler
|
||||
this._register(attachButtonStyler(this._closeButton, this._themeService));
|
||||
this._register(attachButtonStyler(this._addAccountButton, this._themeService));
|
||||
this._register(attachButtonStyler(this._closeButton!, this._themeService));
|
||||
this._register(attachButtonStyler(this._addAccountButton!, this._themeService));
|
||||
}
|
||||
|
||||
/* Overwrite escape key behavior */
|
||||
@@ -292,14 +292,14 @@ export class AccountDialog extends Modal {
|
||||
}
|
||||
|
||||
private showNoAccountContainer() {
|
||||
this._splitViewContainer.hidden = true;
|
||||
this._noaccountViewContainer.hidden = false;
|
||||
this._addAccountButton.focus();
|
||||
this._splitViewContainer!.hidden = true;
|
||||
this._noaccountViewContainer!.hidden = false;
|
||||
this._addAccountButton!.focus();
|
||||
}
|
||||
|
||||
private showSplitView() {
|
||||
this._splitViewContainer.hidden = false;
|
||||
this._noaccountViewContainer.hidden = true;
|
||||
this._splitViewContainer!.hidden = false;
|
||||
this._noaccountViewContainer!.hidden = true;
|
||||
if (Iterable.consume(this._providerViewsMap.values()).length > 0) {
|
||||
const firstView = this._providerViewsMap.values().next().value;
|
||||
if (firstView instanceof AccountPanel) {
|
||||
@@ -373,19 +373,19 @@ export class AccountDialog extends Modal {
|
||||
|
||||
attachPanelStyler(providerView, this._themeService);
|
||||
|
||||
const insertIndex = this._splitView.length;
|
||||
const insertIndex = this._splitView!.length;
|
||||
providerView.render();
|
||||
|
||||
// Append the list view to the split view
|
||||
this._splitView.addView(providerView, Sizing.Distribute, insertIndex);
|
||||
this._splitView!.addView(providerView, Sizing.Distribute, insertIndex);
|
||||
providerView.index = insertIndex;
|
||||
|
||||
this._splitView.layout(DOM.getContentHeight(this._container));
|
||||
this._splitView!.layout(DOM.getContentHeight(this._container!));
|
||||
|
||||
// Set the initial items of the list
|
||||
providerView.updateAccounts(newProvider.initialAccounts);
|
||||
|
||||
if (newProvider.initialAccounts.length > 0 && this._splitViewContainer.hidden) {
|
||||
if (newProvider.initialAccounts.length > 0 && this._splitViewContainer!.hidden) {
|
||||
this.showSplitView();
|
||||
}
|
||||
|
||||
@@ -403,8 +403,8 @@ export class AccountDialog extends Modal {
|
||||
}
|
||||
|
||||
// Remove the list view from the split view
|
||||
this._splitView.removeView(providerView.view.index);
|
||||
this._splitView.layout(DOM.getContentHeight(this._container));
|
||||
this._splitView!.removeView(providerView.view.index!);
|
||||
this._splitView!.layout(DOM.getContentHeight(this._container!));
|
||||
|
||||
// Remove the list view from our internal map
|
||||
this._providerViewsMap.delete(removedProvider.id);
|
||||
@@ -418,11 +418,11 @@ export class AccountDialog extends Modal {
|
||||
}
|
||||
providerMapping.view.updateAccounts(args.accountList);
|
||||
|
||||
if (args.accountList.length > 0 && this._splitViewContainer.hidden) {
|
||||
if (args.accountList.length > 0 && this._splitViewContainer!.hidden) {
|
||||
this.showSplitView();
|
||||
}
|
||||
|
||||
if (this.isEmptyLinkedAccount() && this._noaccountViewContainer.hidden) {
|
||||
if (this.isEmptyLinkedAccount() && this._noaccountViewContainer!.hidden) {
|
||||
this.showNoAccountContainer();
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@ export class AccountDialogController {
|
||||
// MEMBER VARIABLES ////////////////////////////////////////////////////
|
||||
private _addAccountErrorTitle = localize('accountDialog.addAccountErrorTitle', "Error adding account");
|
||||
|
||||
private _accountDialog: AccountDialog;
|
||||
public get accountDialog(): AccountDialog { return this._accountDialog; }
|
||||
private _accountDialog?: AccountDialog;
|
||||
public get accountDialog(): AccountDialog | undefined { return this._accountDialog; }
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private _instantiationService: IInstantiationService,
|
||||
|
||||
@@ -35,9 +35,9 @@ export class AccountManagementService implements IAccountManagementService {
|
||||
public _providers: { [id: string]: AccountProviderWithMetadata } = {};
|
||||
public _serviceBrand: undefined;
|
||||
private _accountStore: AccountStore;
|
||||
private _accountDialogController: AccountDialogController;
|
||||
private _autoOAuthDialogController: AutoOAuthDialogController;
|
||||
private _mementoContext: Memento;
|
||||
private _accountDialogController?: AccountDialogController;
|
||||
private _autoOAuthDialogController?: AutoOAuthDialogController;
|
||||
private _mementoContext?: Memento;
|
||||
|
||||
// EVENT EMITTERS //////////////////////////////////////////////////////
|
||||
private _addAccountProviderEmitter: Emitter<AccountProviderAddedEventParams>;
|
||||
@@ -57,7 +57,7 @@ export class AccountManagementService implements IAccountManagementService {
|
||||
@IClipboardService private _clipboardService: IClipboardService,
|
||||
@IOpenerService private _openerService: IOpenerService,
|
||||
@ILogService private readonly _logService: ILogService,
|
||||
@INotificationService private readonly _notificationService,
|
||||
@INotificationService private readonly _notificationService: INotificationService
|
||||
) {
|
||||
// Create the account store
|
||||
if (!this._mementoObj) {
|
||||
@@ -88,7 +88,7 @@ export class AccountManagementService implements IAccountManagementService {
|
||||
* account's properties have been updated (usually when the account goes stale).
|
||||
* @param updatedAccount Account with the updated properties
|
||||
*/
|
||||
public accountUpdated(updatedAccount: azdata.Account): Thenable<void> {
|
||||
public accountUpdated(updatedAccount: azdata.Account): Promise<void> {
|
||||
let self = this;
|
||||
|
||||
// 1) Update the account in the store
|
||||
@@ -119,7 +119,7 @@ export class AccountManagementService implements IAccountManagementService {
|
||||
* @param providerId ID of the provider to ask to prompt for an account
|
||||
* @return Promise to return an account
|
||||
*/
|
||||
public addAccount(providerId: string): Thenable<void> {
|
||||
public addAccount(providerId: string): Promise<void> {
|
||||
const closeAction: Action = new Action('closeAddingAccount', localize('accountManagementService.close', "Close"), undefined, true);
|
||||
|
||||
const loginNotification: INotification = {
|
||||
@@ -166,7 +166,7 @@ export class AccountManagementService implements IAccountManagementService {
|
||||
* @param account account to refresh
|
||||
* @return Promise to return an account
|
||||
*/
|
||||
public refreshAccount(account: azdata.Account): Thenable<azdata.Account> {
|
||||
public refreshAccount(account: azdata.Account): Promise<azdata.Account> {
|
||||
let self = this;
|
||||
|
||||
return this.doWithProvider(account.key.providerId, async (provider) => {
|
||||
@@ -181,20 +181,20 @@ export class AccountManagementService implements IAccountManagementService {
|
||||
let result = await self._accountStore.addOrUpdate(account);
|
||||
if (result.accountAdded) {
|
||||
// Add the account to the list
|
||||
provider.accounts.push(result.changedAccount);
|
||||
provider.accounts.push(result.changedAccount!);
|
||||
}
|
||||
if (result.accountModified) {
|
||||
// Find the updated account and splice the updated on in
|
||||
let indexToRemove: number = firstIndex(provider.accounts, account => {
|
||||
return account.key.accountId === result.changedAccount.key.accountId;
|
||||
return account.key.accountId === result.changedAccount!.key.accountId;
|
||||
});
|
||||
if (indexToRemove >= 0) {
|
||||
provider.accounts.splice(indexToRemove, 1, result.changedAccount);
|
||||
provider.accounts.splice(indexToRemove, 1, result.changedAccount!);
|
||||
}
|
||||
}
|
||||
|
||||
self.fireAccountListUpdate(provider, result.accountAdded);
|
||||
return result.changedAccount;
|
||||
return result.changedAccount!;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -202,7 +202,7 @@ export class AccountManagementService implements IAccountManagementService {
|
||||
* Retrieves metadata of all providers that have been registered
|
||||
* @returns Registered account providers
|
||||
*/
|
||||
public getAccountProviderMetadata(): Thenable<azdata.AccountProviderMetadata[]> {
|
||||
public getAccountProviderMetadata(): Promise<azdata.AccountProviderMetadata[]> {
|
||||
return Promise.resolve(values(this._providers).map(provider => provider.metadata));
|
||||
}
|
||||
|
||||
@@ -211,7 +211,7 @@ export class AccountManagementService implements IAccountManagementService {
|
||||
* @param providerId ID of the provider the returned accounts belong to
|
||||
* @returns Promise to return a list of accounts
|
||||
*/
|
||||
public getAccountsForProvider(providerId: string): Thenable<azdata.Account[]> {
|
||||
public getAccountsForProvider(providerId: string): Promise<azdata.Account[]> {
|
||||
let self = this;
|
||||
|
||||
// 1) Get the accounts from the store
|
||||
@@ -228,7 +228,7 @@ export class AccountManagementService implements IAccountManagementService {
|
||||
/**
|
||||
* Retrieves all the accounts registered with ADS.
|
||||
*/
|
||||
public getAccounts(): Thenable<azdata.Account[]> {
|
||||
public getAccounts(): Promise<azdata.Account[]> {
|
||||
return this._accountStore.getAllAccounts();
|
||||
}
|
||||
|
||||
@@ -238,9 +238,9 @@ export class AccountManagementService implements IAccountManagementService {
|
||||
* @param resource The resource to get the security token for
|
||||
* @return Promise to return the security token
|
||||
*/
|
||||
public getSecurityToken(account: azdata.Account, resource: azdata.AzureResource): Thenable<{}> {
|
||||
public getSecurityToken(account: azdata.Account, resource: azdata.AzureResource): Promise<{} | undefined> {
|
||||
return this.doWithProvider(account.key.providerId, provider => {
|
||||
return provider.provider.getSecurityToken(account, resource);
|
||||
return Promise.resolve(provider.provider.getSecurityToken(account, resource));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -251,9 +251,9 @@ export class AccountManagementService implements IAccountManagementService {
|
||||
* @param resource The resource to get the security token for
|
||||
* @return Promise to return the security token
|
||||
*/
|
||||
public getAccountSecurityToken(account: azdata.Account, tenant: string, resource: azdata.AzureResource): Thenable<{ token: string }> {
|
||||
public getAccountSecurityToken(account: azdata.Account, tenant: string, resource: azdata.AzureResource): Promise<{ token: string } | undefined> {
|
||||
return this.doWithProvider(account.key.providerId, provider => {
|
||||
return provider.provider.getAccountSecurityToken(account, tenant, resource);
|
||||
return Promise.resolve(provider.provider.getAccountSecurityToken(account, tenant, resource));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -263,7 +263,7 @@ export class AccountManagementService implements IAccountManagementService {
|
||||
* @returns Promise with result of account removal, true if account was
|
||||
* removed, false otherwise.
|
||||
*/
|
||||
public removeAccount(accountKey: azdata.AccountKey): Thenable<boolean> {
|
||||
public removeAccount(accountKey: azdata.AccountKey): Promise<boolean> {
|
||||
|
||||
// Step 1) Remove the account
|
||||
// Step 2) Clear the sensitive data from the provider (regardless of whether the account was removed)
|
||||
@@ -316,7 +316,7 @@ export class AccountManagementService implements IAccountManagementService {
|
||||
* Opens the account list dialog
|
||||
* @return Promise that finishes when the account list dialog closes
|
||||
*/
|
||||
public openAccountListDialog(): Thenable<void> {
|
||||
public openAccountListDialog(): Promise<void> {
|
||||
let self = this;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
@@ -326,7 +326,7 @@ export class AccountManagementService implements IAccountManagementService {
|
||||
self._accountDialogController = self._instantiationService.createInstance(AccountDialogController);
|
||||
}
|
||||
self._accountDialogController.openAccountDialog();
|
||||
self._accountDialogController.accountDialog.onCloseEvent(resolve);
|
||||
self._accountDialogController.accountDialog!.onCloseEvent(resolve);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
@@ -337,7 +337,7 @@ export class AccountManagementService implements IAccountManagementService {
|
||||
* Begin auto OAuth device code open add account dialog
|
||||
* @return Promise that finishes when the account list dialog opens
|
||||
*/
|
||||
public beginAutoOAuthDeviceCode(providerId: string, title: string, message: string, userCode: string, uri: string): Thenable<void> {
|
||||
public beginAutoOAuthDeviceCode(providerId: string, title: string, message: string, userCode: string, uri: string): Promise<void> {
|
||||
let self = this;
|
||||
|
||||
return this.doWithProvider(providerId, provider => {
|
||||
@@ -356,9 +356,9 @@ export class AccountManagementService implements IAccountManagementService {
|
||||
* Called from the UI when a user cancels the auto OAuth dialog
|
||||
*/
|
||||
public cancelAutoOAuthDeviceCode(providerId: string): void {
|
||||
this.doWithProvider(providerId, provider => provider.provider.autoOAuthCancelled())
|
||||
void this.doWithProvider(providerId, provider => Promise.resolve(provider.provider.autoOAuthCancelled()))
|
||||
.then( // Swallow errors
|
||||
null,
|
||||
undefined,
|
||||
err => { this._logService.warn(`Error when cancelling auto OAuth: ${err}`); }
|
||||
)
|
||||
.then(() => this.autoOAuthDialogController.closeAutoOAuthDialog());
|
||||
@@ -408,7 +408,7 @@ export class AccountManagementService implements IAccountManagementService {
|
||||
* @param providerMetadata Metadata of the provider that is being registered
|
||||
* @param provider References to the methods of the provider
|
||||
*/
|
||||
public registerProvider(providerMetadata: azdata.AccountProviderMetadata, provider: azdata.AccountProvider): Thenable<void> {
|
||||
public registerProvider(providerMetadata: azdata.AccountProviderMetadata, provider: azdata.AccountProvider): Promise<void> {
|
||||
return this._registerProvider(providerMetadata, provider);
|
||||
}
|
||||
|
||||
@@ -432,7 +432,7 @@ export class AccountManagementService implements IAccountManagementService {
|
||||
// TODO: Support for orphaned accounts (accounts with no provider)
|
||||
|
||||
// PRIVATE HELPERS /////////////////////////////////////////////////////
|
||||
private doWithProvider<T>(providerId: string, op: (provider: AccountProviderWithMetadata) => Thenable<T>): Thenable<T> {
|
||||
private doWithProvider<T>(providerId: string, op: (provider: AccountProviderWithMetadata) => Promise<T>): Promise<T> {
|
||||
let provider = this._providers[providerId];
|
||||
if (!provider) {
|
||||
// If the provider doesn't already exist wait until it gets registered
|
||||
|
||||
@@ -30,18 +30,18 @@ import { Tenant, TenantListDelegate, TenantPickerListRenderer } from 'sql/workbe
|
||||
export class AccountPicker extends Disposable {
|
||||
public static ACCOUNTPICKERLIST_HEIGHT = 47;
|
||||
public viewModel: AccountPickerViewModel;
|
||||
private _accountList: List<azdata.Account>;
|
||||
private _rootContainer: HTMLElement;
|
||||
private _accountList?: List<azdata.Account>;
|
||||
private _rootContainer?: HTMLElement;
|
||||
|
||||
private _accountContainer: HTMLElement;
|
||||
private _refreshContainer: HTMLElement;
|
||||
private _accountListContainer: HTMLElement;
|
||||
private _dropdown: DropdownList;
|
||||
private _tenantContainer: HTMLElement;
|
||||
private _tenantListContainer: HTMLElement;
|
||||
private _tenantList: List<Tenant>;
|
||||
private _tenantDropdown: DropdownList;
|
||||
private _refreshAccountAction: RefreshAccountAction;
|
||||
private _accountContainer?: HTMLElement;
|
||||
private _refreshContainer?: HTMLElement;
|
||||
private _accountListContainer?: HTMLElement;
|
||||
private _dropdown?: DropdownList;
|
||||
private _tenantContainer?: HTMLElement;
|
||||
private _tenantListContainer?: HTMLElement;
|
||||
private _tenantList?: List<Tenant>;
|
||||
private _tenantDropdown?: DropdownList;
|
||||
private _refreshAccountAction?: RefreshAccountAction;
|
||||
|
||||
// EVENTING ////////////////////////////////////////////////////////////
|
||||
private _addAccountCompleteEmitter: Emitter<void>;
|
||||
@@ -71,7 +71,7 @@ export class AccountPicker extends Disposable {
|
||||
this._addAccountCompleteEmitter = new Emitter<void>();
|
||||
this._addAccountErrorEmitter = new Emitter<string>();
|
||||
this._addAccountStartEmitter = new Emitter<void>();
|
||||
this._onAccountSelectionChangeEvent = new Emitter<azdata.Account>();
|
||||
this._onAccountSelectionChangeEvent = new Emitter<azdata.Account | undefined>();
|
||||
this._onTenantSelectionChangeEvent = new Emitter<string | undefined>();
|
||||
|
||||
// Create the view model, wire up the events, and initialize with baseline data
|
||||
@@ -88,7 +88,7 @@ export class AccountPicker extends Disposable {
|
||||
* Render account picker
|
||||
*/
|
||||
public render(rootContainer: HTMLElement): void {
|
||||
DOM.append(rootContainer, this._rootContainer);
|
||||
DOM.append(rootContainer, this._rootContainer!);
|
||||
}
|
||||
|
||||
// PUBLIC METHODS //////////////////////////////////////////////////////
|
||||
@@ -156,14 +156,14 @@ export class AccountPicker extends Disposable {
|
||||
|
||||
this._register(this._accountList.onDidChangeSelection((e: IListEvent<azdata.Account>) => {
|
||||
if (e.elements.length === 1) {
|
||||
this._dropdown.renderLabel();
|
||||
this._dropdown!.renderLabel();
|
||||
this.onAccountSelectionChange(e.elements[0]);
|
||||
}
|
||||
}));
|
||||
|
||||
this._register(this._tenantList.onDidChangeSelection((e: IListEvent<Tenant>) => {
|
||||
if (e.elements.length === 1) {
|
||||
this._tenantDropdown.renderLabel();
|
||||
this._tenantDropdown!.renderLabel();
|
||||
this.onTenantSelectionChange(e.elements[0].id);
|
||||
}
|
||||
}));
|
||||
@@ -214,16 +214,16 @@ export class AccountPicker extends Disposable {
|
||||
private onAccountSelectionChange(account: azdata.Account | undefined) {
|
||||
this.viewModel.selectedAccount = account;
|
||||
if (account && account.isStale) {
|
||||
this._refreshAccountAction.account = account;
|
||||
DOM.show(this._refreshContainer);
|
||||
} else {
|
||||
DOM.hide(this._refreshContainer);
|
||||
this._refreshAccountAction!.account = account;
|
||||
DOM.show(this._refreshContainer!);
|
||||
} else if (account) {
|
||||
DOM.hide(this._refreshContainer!);
|
||||
|
||||
if (account.properties.tenants?.length > 1) {
|
||||
DOM.show(this._tenantContainer);
|
||||
DOM.show(this._tenantContainer!);
|
||||
this.updateTenantList(account);
|
||||
} else {
|
||||
DOM.hide(this._tenantContainer);
|
||||
DOM.hide(this._tenantContainer!);
|
||||
}
|
||||
this.onTenantSelectionChange(account?.properties?.tenants[0]?.id);
|
||||
}
|
||||
@@ -243,7 +243,7 @@ export class AccountPicker extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
const selectedAccounts = this._accountList.getSelectedElements();
|
||||
const selectedAccounts = this._accountList!.getSelectedElements();
|
||||
const account = selectedAccounts ? selectedAccounts[0] : undefined;
|
||||
if (account) {
|
||||
const badge = DOM.$('div.badge');
|
||||
@@ -278,7 +278,7 @@ export class AccountPicker extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
const selectedTenants = this._tenantList.getSelectedElements();
|
||||
const selectedTenants = this._tenantList!.getSelectedElements();
|
||||
const tenant = selectedTenants ? selectedTenants[0] : undefined;
|
||||
if (tenant) {
|
||||
const row = DOM.append(container, DOM.$('div.selected-tenant-container'));
|
||||
@@ -291,15 +291,15 @@ export class AccountPicker extends Disposable {
|
||||
}
|
||||
|
||||
private updateTenantList(account: azdata.Account): void {
|
||||
this._tenantList.splice(0, this._tenantList.length, account?.properties?.tenants ?? []);
|
||||
this._tenantList.setSelection([0]);
|
||||
this._tenantDropdown.renderLabel();
|
||||
this._tenantList.layout(this._tenantList.contentHeight);
|
||||
this._tenantList!.splice(0, this._tenantList!.length, account?.properties?.tenants ?? []);
|
||||
this._tenantList!.setSelection([0]);
|
||||
this._tenantDropdown!.renderLabel();
|
||||
this._tenantList!.layout(this._tenantList!.contentHeight);
|
||||
}
|
||||
|
||||
private updateAccountList(accounts: azdata.Account[]): void {
|
||||
// keep the selection to the current one
|
||||
const selectedElements = this._accountList.getSelectedElements();
|
||||
const selectedElements = this._accountList!.getSelectedElements();
|
||||
|
||||
// find selected index
|
||||
let selectedIndex: number | undefined;
|
||||
@@ -310,21 +310,21 @@ export class AccountPicker extends Disposable {
|
||||
}
|
||||
|
||||
// Replace the existing list with the new one
|
||||
this._accountList.splice(0, this._accountList.length, accounts);
|
||||
this._accountList!.splice(0, this._accountList!.length, accounts);
|
||||
|
||||
if (this._accountList.length > 0) {
|
||||
if (this._accountList!.length > 0) {
|
||||
if (selectedIndex && selectedIndex !== -1) {
|
||||
this._accountList.setSelection([selectedIndex]);
|
||||
this._accountList!.setSelection([selectedIndex]);
|
||||
} else {
|
||||
this._accountList.setSelection([0]);
|
||||
this._accountList!.setSelection([0]);
|
||||
}
|
||||
} else {
|
||||
// if the account is empty, re-render dropdown label
|
||||
this.onAccountSelectionChange(undefined);
|
||||
this._dropdown.renderLabel();
|
||||
this._dropdown!.renderLabel();
|
||||
}
|
||||
|
||||
this._accountList.layout(this._accountList.contentHeight);
|
||||
this._accountList!.layout(this._accountList!.contentHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -333,9 +333,8 @@ export class AccountPicker extends Disposable {
|
||||
private updateTheme(theme: IColorTheme): void {
|
||||
const linkColor = theme.getColor(buttonBackground);
|
||||
const link = linkColor ? linkColor.toString() : null;
|
||||
this._refreshContainer.style.color = link;
|
||||
if (this._refreshContainer) {
|
||||
this._refreshContainer.style.color = link;
|
||||
this._refreshContainer.style.color = link ?? '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import { AccountPicker } from 'sql/workbench/services/accountManagement/browser/
|
||||
export class AccountPickerService implements IAccountPickerService {
|
||||
_serviceBrand: undefined;
|
||||
|
||||
private _accountPicker: AccountPicker;
|
||||
private _accountPicker?: AccountPicker;
|
||||
|
||||
// EVENTING ////////////////////////////////////////////////////////////
|
||||
private _addAccountCompleteEmitter: Emitter<void>;
|
||||
@@ -38,7 +38,7 @@ export class AccountPickerService implements IAccountPickerService {
|
||||
this._addAccountCompleteEmitter = new Emitter<void>();
|
||||
this._addAccountErrorEmitter = new Emitter<string>();
|
||||
this._addAccountStartEmitter = new Emitter<void>();
|
||||
this._onAccountSelectionChangeEvent = new Emitter<azdata.Account>();
|
||||
this._onAccountSelectionChangeEvent = new Emitter<azdata.Account | undefined>();
|
||||
this._onTenantSelectionChangeEvent = new Emitter<string | undefined>();
|
||||
}
|
||||
|
||||
@@ -46,7 +46,11 @@ export class AccountPickerService implements IAccountPickerService {
|
||||
* Get selected account
|
||||
*/
|
||||
public get selectedAccount(): azdata.Account | undefined {
|
||||
return this._accountPicker.viewModel.selectedAccount;
|
||||
if (this._accountPicker) {
|
||||
return this._accountPicker.viewModel.selectedAccount;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,11 +27,11 @@ import { attachModalDialogStyler } from 'sql/workbench/common/styler';
|
||||
import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
|
||||
|
||||
export class AutoOAuthDialog extends Modal {
|
||||
private _copyAndOpenButton: Button;
|
||||
private _closeButton: Button;
|
||||
private _userCodeInputBox: InputBox;
|
||||
private _websiteInputBox: InputBox;
|
||||
private _descriptionElement: HTMLElement;
|
||||
private _copyAndOpenButton?: Button;
|
||||
private _closeButton?: Button;
|
||||
private _userCodeInputBox?: InputBox;
|
||||
private _websiteInputBox?: InputBox;
|
||||
private _descriptionElement?: HTMLElement;
|
||||
|
||||
// EVENTING ////////////////////////////////////////////////////////////
|
||||
private _onHandleAddAccount = new Emitter<void>();
|
||||
@@ -75,14 +75,14 @@ export class AutoOAuthDialog extends Modal {
|
||||
public render() {
|
||||
super.render();
|
||||
attachModalDialogStyler(this, this._themeService);
|
||||
this.backButton.onDidClick(() => this.cancel());
|
||||
this._register(attachButtonStyler(this.backButton, this._themeService, { buttonBackground: SIDE_BAR_BACKGROUND, buttonHoverBackground: SIDE_BAR_BACKGROUND }));
|
||||
this.backButton!.onDidClick(() => this.cancel());
|
||||
this._register(attachButtonStyler(this.backButton!, this._themeService, { buttonBackground: SIDE_BAR_BACKGROUND, buttonHoverBackground: SIDE_BAR_BACKGROUND }));
|
||||
|
||||
this._copyAndOpenButton = this.addFooterButton(localize('copyAndOpen', "Copy & Open"), () => this.addAccount());
|
||||
this._closeButton = this.addFooterButton(localize('oauthDialog.cancel', "Cancel"), () => this.cancel());
|
||||
this.registerListeners();
|
||||
this._userCodeInputBox.disable();
|
||||
this._websiteInputBox.disable();
|
||||
this._userCodeInputBox!.disable();
|
||||
this._websiteInputBox!.disable();
|
||||
}
|
||||
|
||||
protected layout(height?: number): void {
|
||||
@@ -110,10 +110,10 @@ export class AutoOAuthDialog extends Modal {
|
||||
|
||||
private registerListeners(): void {
|
||||
// Theme styler
|
||||
this._register(attachButtonStyler(this._copyAndOpenButton, this._themeService));
|
||||
this._register(attachButtonStyler(this._closeButton, this._themeService));
|
||||
this._register(attachInputBoxStyler(this._userCodeInputBox, this._themeService));
|
||||
this._register(attachInputBoxStyler(this._websiteInputBox, this._themeService));
|
||||
this._register(attachButtonStyler(this._copyAndOpenButton!, this._themeService));
|
||||
this._register(attachButtonStyler(this._closeButton!, this._themeService));
|
||||
this._register(attachInputBoxStyler(this._userCodeInputBox!, this._themeService));
|
||||
this._register(attachInputBoxStyler(this._websiteInputBox!, this._themeService));
|
||||
|
||||
}
|
||||
|
||||
@@ -128,8 +128,8 @@ export class AutoOAuthDialog extends Modal {
|
||||
}
|
||||
|
||||
private addAccount() {
|
||||
if (this._copyAndOpenButton.enabled) {
|
||||
this._copyAndOpenButton.enabled = false;
|
||||
if (this._copyAndOpenButton!.enabled) {
|
||||
this._copyAndOpenButton!.enabled = false;
|
||||
this.spinner = true;
|
||||
this._onHandleAddAccount.fire();
|
||||
}
|
||||
@@ -140,7 +140,7 @@ export class AutoOAuthDialog extends Modal {
|
||||
}
|
||||
|
||||
public close() {
|
||||
this._copyAndOpenButton.enabled = true;
|
||||
this._copyAndOpenButton!.enabled = true;
|
||||
this._onCloseEvent.fire();
|
||||
this.spinner = false;
|
||||
this.hide();
|
||||
@@ -149,10 +149,10 @@ export class AutoOAuthDialog extends Modal {
|
||||
public open(title: string, message: string, userCode: string, uri: string) {
|
||||
// Update dialog
|
||||
this.title = title;
|
||||
this._descriptionElement.innerText = message;
|
||||
this._userCodeInputBox.value = userCode;
|
||||
this._websiteInputBox.value = uri;
|
||||
this._descriptionElement!.innerText = message;
|
||||
this._userCodeInputBox!.value = userCode;
|
||||
this._websiteInputBox!.value = uri;
|
||||
this.show();
|
||||
this._copyAndOpenButton.focus();
|
||||
this._copyAndOpenButton!.focus();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,10 +13,10 @@ import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMess
|
||||
|
||||
export class AutoOAuthDialogController {
|
||||
// MEMBER VARIABLES ////////////////////////////////////////////////////
|
||||
private _autoOAuthDialog: AutoOAuthDialog;
|
||||
private _autoOAuthDialog?: AutoOAuthDialog;
|
||||
private _providerId?: string;
|
||||
private _userCode: string;
|
||||
private _uri: string;
|
||||
private _userCode?: string;
|
||||
private _uri?: string;
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private _instantiationService: IInstantiationService,
|
||||
@@ -27,7 +27,7 @@ export class AutoOAuthDialogController {
|
||||
/**
|
||||
* Open auto OAuth dialog
|
||||
*/
|
||||
public openAutoOAuthDialog(providerId: string, title: string, message: string, userCode: string, uri: string): Thenable<void> {
|
||||
public openAutoOAuthDialog(providerId: string, title: string, message: string, userCode: string, uri: string): Promise<void> {
|
||||
if (this._providerId !== undefined) {
|
||||
// If a oauth flyout is already open, return an error
|
||||
const errorMessage = localize('oauthFlyoutIsAlreadyOpen', "Cannot start auto OAuth. An auto OAuth is already in progress.");
|
||||
@@ -57,7 +57,9 @@ export class AutoOAuthDialogController {
|
||||
* Close auto OAuth dialog
|
||||
*/
|
||||
public closeAutoOAuthDialog(): void {
|
||||
this._autoOAuthDialog.close();
|
||||
if (this._autoOAuthDialog) {
|
||||
this._autoOAuthDialog.close();
|
||||
}
|
||||
this._providerId = undefined;
|
||||
}
|
||||
|
||||
@@ -71,6 +73,10 @@ export class AutoOAuthDialogController {
|
||||
}
|
||||
|
||||
private handleOnAddAccount(): void {
|
||||
this._accountManagementService.copyUserCodeAndOpenBrowser(this._userCode, this._uri);
|
||||
if (this._userCode && this._uri) {
|
||||
this._accountManagementService.copyUserCodeAndOpenBrowser(this._userCode, this._uri);
|
||||
} else {
|
||||
throw new Error('Missing user code and uri');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,10 +118,11 @@ suite('Account Management Service Tests:', () => {
|
||||
state.mockAccountStore.verify(x => x.addOrUpdate(TypeMoq.It.isAny()), TypeMoq.Times.once());
|
||||
|
||||
// ... The account list was updated
|
||||
state.eventVerifierUpdate.assertFiredWithVerify((params: UpdateAccountListEventParams) => {
|
||||
assert.equal(params.providerId, hasAccountProvider.id);
|
||||
assert.ok(Array.isArray(params.accountList));
|
||||
assert.equal(params.accountList.length, 1);
|
||||
state.eventVerifierUpdate.assertFiredWithVerify((params: UpdateAccountListEventParams | undefined) => {
|
||||
assert.ok(params);
|
||||
assert.equal(params!.providerId, hasAccountProvider.id);
|
||||
assert.ok(Array.isArray(params!.accountList));
|
||||
assert.equal(params!.accountList.length, 1);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -157,10 +158,11 @@ suite('Account Management Service Tests:', () => {
|
||||
|
||||
// ... The account list change should have been fired
|
||||
state.eventVerifierUpdate.assertFiredWithVerify(param => {
|
||||
assert.equal(param.providerId, hasAccountProvider.id);
|
||||
assert.ok(Array.isArray(param.accountList));
|
||||
assert.equal(param.accountList.length, 1);
|
||||
assert.equal(param.accountList[0], account);
|
||||
assert.ok(param);
|
||||
assert.equal(param!.providerId, hasAccountProvider.id);
|
||||
assert.ok(Array.isArray(param!.accountList));
|
||||
assert.equal(param!.accountList.length, 1);
|
||||
assert.equal(param!.accountList[0], account);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -196,10 +198,11 @@ suite('Account Management Service Tests:', () => {
|
||||
|
||||
// ... The account list change should have been fired
|
||||
state.eventVerifierUpdate.assertFiredWithVerify(param => {
|
||||
assert.equal(param.providerId, hasAccountProvider.id);
|
||||
assert.ok(Array.isArray(param.accountList));
|
||||
assert.equal(param.accountList.length, 1);
|
||||
assert.equal(param.accountList[0], account);
|
||||
assert.ok(param);
|
||||
assert.equal(param!.providerId, hasAccountProvider.id);
|
||||
assert.ok(Array.isArray(param!.accountList));
|
||||
assert.equal(param!.accountList.length, 1);
|
||||
assert.equal(param!.accountList[0], account);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -246,7 +249,7 @@ suite('Account Management Service Tests:', () => {
|
||||
let state = getTestState();
|
||||
state.accountManagementService._providers[noAccountProvider.id] = {
|
||||
accounts: [],
|
||||
provider: null, // Doesn't matter
|
||||
provider: undefined!, // Doesn't matter
|
||||
metadata: noAccountProvider
|
||||
};
|
||||
|
||||
@@ -290,7 +293,7 @@ suite('Account Management Service Tests:', () => {
|
||||
let ams = getTestState().accountManagementService;
|
||||
ams._providers[noAccountProvider.id] = {
|
||||
accounts: [],
|
||||
provider: null, // Doesn't matter
|
||||
provider: undefined!, // Doesn't matter
|
||||
metadata: noAccountProvider
|
||||
};
|
||||
|
||||
@@ -308,7 +311,7 @@ suite('Account Management Service Tests:', () => {
|
||||
let ams = getTestState().accountManagementService;
|
||||
ams._providers[hasAccountProvider.id] = {
|
||||
accounts: [account],
|
||||
provider: null, // Doesn't matter
|
||||
provider: undefined!, // Doesn't matter
|
||||
metadata: hasAccountProvider
|
||||
};
|
||||
|
||||
@@ -350,10 +353,11 @@ suite('Account Management Service Tests:', () => {
|
||||
mockProvider.verify(x => x.clear(TypeMoq.It.isValue(account.key)), TypeMoq.Times.once());
|
||||
|
||||
// ... The updated account list event should have fired
|
||||
state.eventVerifierUpdate.assertFiredWithVerify((params: UpdateAccountListEventParams) => {
|
||||
assert.equal(params.providerId, hasAccountProvider.id);
|
||||
assert.ok(Array.isArray(params.accountList));
|
||||
assert.equal(params.accountList.length, 0);
|
||||
state.eventVerifierUpdate.assertFiredWithVerify((params: UpdateAccountListEventParams | undefined) => {
|
||||
assert.ok(params);
|
||||
assert.equal(params!.providerId, hasAccountProvider.id);
|
||||
assert.ok(Array.isArray(params!.accountList));
|
||||
assert.equal(params!.accountList.length, 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -404,7 +408,7 @@ suite('Account Management Service Tests:', () => {
|
||||
mockDialogController.setup(x => x.openAccountDialog());
|
||||
mockDialogController.setup(x => x.accountDialog).returns(() => <AccountDialog>mockAccountDialog);
|
||||
let mockAccountDialogCloseEvent = new Emitter<void>();
|
||||
mockAccountDialog['onCloseEvent'] = mockAccountDialogCloseEvent.event;
|
||||
(mockAccountDialog as any).onCloseEvent = mockAccountDialogCloseEvent.event;
|
||||
setTimeout(() => {
|
||||
mockAccountDialogCloseEvent.fire();
|
||||
}, 1000);
|
||||
@@ -434,7 +438,7 @@ suite('Account Management Service Tests:', () => {
|
||||
mockDialogController.setup(x => x.openAccountDialog());
|
||||
mockDialogController.setup(x => x.accountDialog).returns(() => <AccountDialog>mockAccountDialog);
|
||||
let mockAccountDialogCloseEvent = new Emitter<void>();
|
||||
mockAccountDialog['onCloseEvent'] = mockAccountDialogCloseEvent.event;
|
||||
(mockAccountDialog as any).onCloseEvent = mockAccountDialogCloseEvent.event;
|
||||
setTimeout(() => {
|
||||
mockAccountDialogCloseEvent.fire();
|
||||
}, 1000);
|
||||
@@ -468,7 +472,7 @@ suite('Account Management Service Tests:', () => {
|
||||
// ... Create ams, account store that will accept account add/update
|
||||
let mocks = getTestState();
|
||||
mocks.mockAccountStore.setup(x => x.addOrUpdate(TypeMoq.It.isAny()))
|
||||
.returns(() => Promise.resolve(undefined));
|
||||
.returns(() => Promise.resolve(undefined!));
|
||||
|
||||
// ... Create mock account provider
|
||||
let mockProvider = getMockAccountProvider();
|
||||
@@ -484,10 +488,11 @@ suite('Account Management Service Tests:', () => {
|
||||
mockProvider.verify(x => x.initialize(TypeMoq.It.isAny()), TypeMoq.Times.once());
|
||||
|
||||
// ... The provider added event should have fired
|
||||
mocks.eventVerifierProviderAdded.assertFiredWithVerify((param: AccountProviderAddedEventParams) => {
|
||||
assert.equal(param.addedProvider, noAccountProvider);
|
||||
assert.ok(Array.isArray(param.initialAccounts));
|
||||
assert.equal(param.initialAccounts.length, 0);
|
||||
mocks.eventVerifierProviderAdded.assertFiredWithVerify((param: AccountProviderAddedEventParams | undefined) => {
|
||||
assert.ok(param);
|
||||
assert.equal(param!.addedProvider, noAccountProvider);
|
||||
assert.ok(Array.isArray(param!.initialAccounts));
|
||||
assert.equal(param!.initialAccounts.length, 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -530,7 +535,7 @@ function getTestState(): AccountManagementState {
|
||||
const testNotificationService = new TestNotificationService();
|
||||
|
||||
// Create the account management service
|
||||
let ams = new AccountManagementService(mockMemento, mockInstantiationService.object, new TestStorageService(), null, null, undefined, testNotificationService);
|
||||
let ams = new AccountManagementService(mockMemento, mockInstantiationService.object, new TestStorageService(), undefined!, undefined!, undefined!, testNotificationService);
|
||||
|
||||
// Wire up event handlers
|
||||
let evUpdate = new EventVerifierSingle<UpdateAccountListEventParams>();
|
||||
|
||||
@@ -79,7 +79,7 @@ suite('Account picker service tests', () => {
|
||||
properties: [],
|
||||
isStale: false
|
||||
};
|
||||
let evOnAccountSelectionChangeEvent = new EventVerifierSingle<azdata.Account>();
|
||||
let evOnAccountSelectionChangeEvent = new EventVerifierSingle<azdata.Account | undefined>();
|
||||
service.onAccountSelectionChangeEvent(evOnAccountSelectionChangeEvent.eventHandler);
|
||||
mockOnAccountSelectionChangeEvent.fire(account);
|
||||
evOnAccountSelectionChangeEvent.assertFired(account);
|
||||
|
||||
@@ -13,15 +13,17 @@ const languageRegistry = Registry.as<ILanguageAssociationRegistry>(ILanguageAsso
|
||||
|
||||
export function doHandleUpgrade(editor?: EditorInput): EditorInput | undefined {
|
||||
if (editor instanceof UntitledTextEditorInput || editor instanceof FileEditorInput) {
|
||||
let language: string;
|
||||
let language: string | undefined;
|
||||
if (editor instanceof UntitledTextEditorInput) {
|
||||
language = editor.getMode();
|
||||
} else {
|
||||
editor.getPreferredMode();
|
||||
language = editor.getPreferredMode();
|
||||
}
|
||||
const association = languageRegistry.getAssociationForLanguage(language);
|
||||
if (association && association.syncConvertinput) {
|
||||
return association.syncConvertinput(editor);
|
||||
if (language) {
|
||||
const association = languageRegistry.getAssociationForLanguage(language);
|
||||
if (association && association.syncConvertinput) {
|
||||
return association.syncConvertinput(editor);
|
||||
}
|
||||
}
|
||||
}
|
||||
return editor;
|
||||
|
||||
@@ -25,8 +25,8 @@ type ILanguageAssociationSignature<Services extends BrandedService[]> = new (...
|
||||
|
||||
export interface ILanguageAssociationRegistry {
|
||||
registerLanguageAssociation<Services extends BrandedService[]>(languages: string[], contribution: ILanguageAssociationSignature<Services>, isDefault?: boolean): IDisposable;
|
||||
getAssociationForLanguage(language: string): ILanguageAssociation;
|
||||
readonly defaultAssociation: [string, ILanguageAssociation];
|
||||
getAssociationForLanguage(language: string): ILanguageAssociation | undefined;
|
||||
readonly defaultAssociation: [string, ILanguageAssociation] | undefined;
|
||||
|
||||
/**
|
||||
* Starts the registry by providing the required services.
|
||||
|
||||
@@ -41,7 +41,7 @@ export interface IQueryManagementService {
|
||||
registerRunner(runner: QueryRunner, uri: string): void;
|
||||
|
||||
cancelQuery(ownerUri: string): Promise<QueryCancelResult>;
|
||||
runQuery(ownerUri: string, range: IRange, runOptions?: ExecutionPlanOptions): Promise<void>;
|
||||
runQuery(ownerUri: string, range?: IRange, runOptions?: ExecutionPlanOptions): Promise<void>;
|
||||
runQueryStatement(ownerUri: string, line: number, column: number): Promise<void>;
|
||||
runQueryString(ownerUri: string, queryString: string): Promise<void>;
|
||||
runQueryAndReturn(ownerUri: string, queryString: string): Promise<azdata.SimpleExecuteResult>;
|
||||
@@ -79,7 +79,7 @@ export interface IQueryManagementService {
|
||||
*/
|
||||
export interface IQueryRequestHandler {
|
||||
cancelQuery(ownerUri: string): Promise<azdata.QueryCancelResult>;
|
||||
runQuery(ownerUri: string, selection: azdata.ISelectionData, runOptions?: ExecutionPlanOptions): Promise<void>;
|
||||
runQuery(ownerUri: string, selection?: azdata.ISelectionData, runOptions?: ExecutionPlanOptions): Promise<void>;
|
||||
runQueryStatement(ownerUri: string, line: number, column: number): Promise<void>;
|
||||
runQueryString(ownerUri: string, queryString: string): Promise<void>;
|
||||
runQueryAndReturn(ownerUri: string, queryString: string): Promise<azdata.SimpleExecuteResult>;
|
||||
|
||||
@@ -254,6 +254,7 @@ export class QueryModelService implements IQueryModelService {
|
||||
text: strings.format(nls.localize('runQueryBatchStartLine', "Line {0}"), b.range.startLineNumber)
|
||||
};
|
||||
}
|
||||
info.range!.push(b.range);
|
||||
}
|
||||
let message = {
|
||||
message: messageText,
|
||||
@@ -263,7 +264,6 @@ export class QueryModelService implements IQueryModelService {
|
||||
link: link
|
||||
};
|
||||
this._fireQueryEvent(uri, 'message', message);
|
||||
info.range!.push(b.range);
|
||||
});
|
||||
queryRunner.onMessage(m => {
|
||||
this._fireQueryEvent(uri, 'message', m);
|
||||
|
||||
@@ -138,7 +138,9 @@ export default class QueryRunner extends Disposable {
|
||||
*/
|
||||
public runQuery(input: IRange | undefined, runOptions?: ExecutionPlanOptions): Promise<void>;
|
||||
public runQuery(input: string | IRange | undefined, runOptions?: ExecutionPlanOptions): Promise<void> {
|
||||
if (types.isString(input) || types.isUndefined(input)) {
|
||||
if (types.isString(input)) {
|
||||
return this.doRunQuery(input, false, runOptions);
|
||||
} else if (types.isUndefined(input)) {
|
||||
return this.doRunQuery(input, false, runOptions);
|
||||
} else {
|
||||
return this.doRunQuery(input, false, runOptions);
|
||||
@@ -157,8 +159,9 @@ export default class QueryRunner extends Disposable {
|
||||
* Implementation that runs the query with the provided query
|
||||
* @param input Query string to execute
|
||||
*/
|
||||
private doRunQuery(input: string, runCurrentStatement: boolean, runOptions?: ExecutionPlanOptions): Promise<void>;
|
||||
private doRunQuery(input: IRange | undefined, runCurrentStatement: boolean, runOptions?: ExecutionPlanOptions): Promise<void>;
|
||||
private doRunQuery(input: string, runCurrentStatement: false, runOptions?: ExecutionPlanOptions): Promise<void>;
|
||||
private doRunQuery(input: IRange | undefined, runCurrentStatement: false, runOptions?: ExecutionPlanOptions): Promise<void>;
|
||||
private doRunQuery(input: IRange, runCurrentStatement: true, runOptions?: ExecutionPlanOptions): Promise<void>;
|
||||
private doRunQuery(input: string | IRange | undefined, runCurrentStatement: boolean, runOptions?: ExecutionPlanOptions): Promise<void> {
|
||||
if (this.isExecuting) {
|
||||
return Promise.resolve();
|
||||
@@ -181,7 +184,7 @@ export default class QueryRunner extends Disposable {
|
||||
|
||||
// Send the request to execute the query
|
||||
return runCurrentStatement
|
||||
? this.queryManagementService.runQueryStatement(this.uri, input.startLineNumber, input.startColumn).then(() => this.handleSuccessRunQueryResult(), e => this.handleFailureRunQueryResult(e))
|
||||
? this.queryManagementService.runQueryStatement(this.uri, input!.startLineNumber, input!.startColumn).then(() => this.handleSuccessRunQueryResult(), e => this.handleFailureRunQueryResult(e))
|
||||
: this.queryManagementService.runQuery(this.uri, input, runOptions).then(() => this.handleSuccessRunQueryResult(), e => this.handleFailureRunQueryResult(e));
|
||||
} else {
|
||||
// Update internal state to show that we're executing the query
|
||||
@@ -232,7 +235,9 @@ export default class QueryRunner extends Disposable {
|
||||
|
||||
this._batchSets.map(batch => {
|
||||
if (batch.range) {
|
||||
batch.range = new Range(batch.range.startLineNumber + this._resultLineOffset, batch.range.startColumn + this._resultColumnOffset, batch.range.endLineNumber + this._resultLineOffset, batch.range.endColumn + this._resultColumnOffset);
|
||||
const columnOffset = (this._resultColumnOffset ?? 0);
|
||||
const lineOffest = (this._resultLineOffset ?? 0);
|
||||
batch.range = new Range(batch.range.startLineNumber + lineOffest, batch.range.startColumn + columnOffset, batch.range.endLineNumber + lineOffest, batch.range.endColumn + columnOffset);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -256,7 +261,9 @@ export default class QueryRunner extends Disposable {
|
||||
public handleBatchStart(batch: BatchStartSummary): void {
|
||||
// Recalculate the start and end lines, relative to the result line offset
|
||||
if (batch.range) {
|
||||
batch.range = new Range(batch.range.startLineNumber + this._resultLineOffset, batch.range.startColumn + this._resultColumnOffset, batch.range.endLineNumber + this._resultLineOffset, batch.range.endColumn + this._resultColumnOffset);
|
||||
const columnOffset = (this._resultColumnOffset ?? 0);
|
||||
const lineOffest = (this._resultLineOffset ?? 0);
|
||||
batch.range = new Range(batch.range.startLineNumber + lineOffest, batch.range.startColumn + columnOffset, batch.range.endLineNumber + lineOffest, batch.range.endColumn + columnOffset);
|
||||
}
|
||||
|
||||
// Store the batch
|
||||
@@ -305,6 +312,7 @@ export default class QueryRunner extends Disposable {
|
||||
batchSet = <BatchSummary>{
|
||||
id: 0,
|
||||
range: undefined,
|
||||
executionStart: Date.now().toString(),
|
||||
hasError: false,
|
||||
resultSetSummaries: []
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user