diff --git a/extensions/arc/src/test/mocks/fakeControllerModel.ts b/extensions/arc/src/test/mocks/fakeControllerModel.ts index 8840c200b8..5926f02f42 100644 --- a/extensions/arc/src/test/mocks/fakeControllerModel.ts +++ b/extensions/arc/src/test/mocks/fakeControllerModel.ts @@ -3,16 +3,16 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { ControllerInfo } from 'arc'; -import { v4 as uuid } from 'uuid'; -import { ControllerModel } from '../../models/controllerModel'; -import { AzureArcTreeDataProvider } from '../../ui/tree/azureArcTreeDataProvider'; +// import { ControllerInfo } from 'arc'; +// import { v4 as uuid } from 'uuid'; +// import { ControllerModel } from '../../models/controllerModel'; +// import { AzureArcTreeDataProvider } from '../../ui/tree/azureArcTreeDataProvider'; -export class FakeControllerModel extends ControllerModel { +// export class FakeControllerModel extends ControllerModel { - constructor(treeDataProvider?: AzureArcTreeDataProvider, info?: Partial) { - const _info: ControllerInfo = Object.assign({ id: uuid(), endpoint: '', kubeConfigFilePath: '', kubeClusterContext: '', name: '', namespace: '', username: '', rememberPassword: false, resources: [], resourceGroup: '', connectionMode: '', location: '', customLocation: '' }, info); - super(treeDataProvider!, _info); - } +// constructor(treeDataProvider?: AzureArcTreeDataProvider, info?: Partial) { +// const _info: ControllerInfo = Object.assign({ id: uuid(), endpoint: '', kubeConfigFilePath: '', kubeClusterContext: '', name: '', namespace: '', username: '', rememberPassword: false, resources: [], resourceGroup: '', connectionMode: '', location: '', customLocation: '' }, info); +// super(treeDataProvider!, _info); +// } -} +// } diff --git a/extensions/arc/src/ui/dashboards/postgres/postgresDiagnoseAndSolveProblemsPage.ts b/extensions/arc/src/ui/dashboards/postgres/postgresDiagnoseAndSolveProblemsPage.ts deleted file mode 100644 index 1510bef236..0000000000 --- a/extensions/arc/src/ui/dashboards/postgres/postgresDiagnoseAndSolveProblemsPage.ts +++ /dev/null @@ -1,66 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import * as azdata from 'azdata'; -import * as loc from '../../../localizedConstants'; -import { IconPathHelper, cssStyles } from '../../../constants'; -import { DashboardPage } from '../../components/dashboardPage'; -import { PostgresModel } from '../../../models/postgresModel'; -import { ControllerModel } from '../../../models/controllerModel'; - -export class PostgresDiagnoseAndSolveProblemsPage extends DashboardPage { - constructor(modelView: azdata.ModelView, dashboard: azdata.window.ModelViewDashboard, private _context: vscode.ExtensionContext, private _controllerModel: ControllerModel, private _postgresModel: PostgresModel) { - super(modelView, dashboard); - } - - protected get title(): string { - return loc.diagnoseAndSolveProblems; - } - - protected get id(): string { - return 'postgres-diagnose-and-solve-problems'; - } - - protected get icon(): { dark: string; light: string; } { - return IconPathHelper.wrench; - } - - protected get container(): azdata.Component { - const root = this.modelView.modelBuilder.divContainer().component(); - const content = this.modelView.modelBuilder.divContainer().component(); - root.addItem(content, { CSSStyles: { 'margin': '20px' } }); - - content.addItem(this.modelView.modelBuilder.text().withProps({ - value: loc.diagnoseAndSolveProblems, - CSSStyles: { ...cssStyles.title, 'margin-bottom': '20px' } - }).component()); - - content.addItem(this.modelView.modelBuilder.text().withProps({ - value: loc.clickTheTroubleshootButton('Postgres'), - CSSStyles: { ...cssStyles.text, 'margin-bottom': '20px' } - }).component()); - - const troubleshootButton = this.modelView.modelBuilder.button().withProps({ - iconPath: IconPathHelper.wrench, - label: loc.troubleshoot, - width: '160px' - }).component(); - - this.disposables.push( - troubleshootButton.onDidClick(() => { - process.env['POSTGRES_SERVER_NAMESPACE'] = this._controllerModel.controllerConfig?.metadata.namespace ?? ''; - process.env['POSTGRES_SERVER_NAME'] = this._postgresModel.info.name; - vscode.commands.executeCommand('bookTreeView.openBook', this._context.asAbsolutePath('notebooks/arcDataServices'), true, 'postgres/tsg100-troubleshoot-postgres'); - })); - - content.addItem(troubleshootButton); - return root; - } - - protected get toolbarContainer(): azdata.ToolbarContainer { - return this.modelView.modelBuilder.toolbarContainer().component(); - } -} diff --git a/extensions/arc/src/ui/dashboards/postgres/postgresPropertiesPage.ts b/extensions/arc/src/ui/dashboards/postgres/postgresPropertiesPage.ts deleted file mode 100644 index bf0997a489..0000000000 --- a/extensions/arc/src/ui/dashboards/postgres/postgresPropertiesPage.ts +++ /dev/null @@ -1,119 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import * as azdata from 'azdata'; -import * as loc from '../../../localizedConstants'; -import { IconPathHelper, cssStyles } from '../../../constants'; -import { KeyValueContainer, KeyValue, InputKeyValue, TextKeyValue, LinkKeyValue } from '../../components/keyValueContainer'; -import { DashboardPage } from '../../components/dashboardPage'; -import { ControllerModel } from '../../../models/controllerModel'; -import { PostgresModel } from '../../../models/postgresModel'; -import { ControllerDashboard } from '../controller/controllerDashboard'; - -export class PostgresPropertiesPage extends DashboardPage { - private loading?: azdata.LoadingComponent; - private keyValueContainer?: KeyValueContainer; - - constructor(modelView: azdata.ModelView, dashboard: azdata.window.ModelViewDashboard, private _controllerModel: ControllerModel, private _postgresModel: PostgresModel) { - super(modelView, dashboard); - - this.disposables.push(this._postgresModel.onConfigUpdated( - () => this.eventuallyRunOnInitialized(() => this.handleServiceUpdated()))); - - this.disposables.push(this._controllerModel.onRegistrationsUpdated( - () => this.eventuallyRunOnInitialized(() => this.handleRegistrationsUpdated()))); - } - - protected get title(): string { - return loc.properties; - } - - protected get id(): string { - return 'postgres-properties'; - } - - protected get icon(): { dark: string; light: string; } { - return IconPathHelper.properties; - } - - protected get container(): azdata.Component { - const root = this.modelView.modelBuilder.divContainer().component(); - const content = this.modelView.modelBuilder.divContainer().component(); - root.addItem(content, { CSSStyles: { 'margin': '20px' } }); - - content.addItem(this.modelView.modelBuilder.text().withProps({ - value: loc.properties, - CSSStyles: { ...cssStyles.title, 'margin-bottom': '25px' } - }).component()); - - this.keyValueContainer = new KeyValueContainer(this.modelView.modelBuilder, this.getProperties()); - this.keyValueContainer.container.updateCssStyles({ 'max-width': '750px' }); - this.disposables.push(this.keyValueContainer); - - this.loading = this.modelView.modelBuilder.loadingComponent() - .withItem(this.keyValueContainer.container) - .withProps({ - loading: !this._postgresModel.configLastUpdated && !this._controllerModel.registrationsLastUpdated - }).component(); - - content.addItem(this.loading); - this.initialized = true; - return root; - } - - protected get toolbarContainer(): azdata.ToolbarContainer { - const refreshButton = this.modelView.modelBuilder.button().withProps({ - label: loc.refresh, - iconPath: IconPathHelper.refresh - }).component(); - - this.disposables.push( - refreshButton.onDidClick(async () => { - refreshButton.enabled = false; - try { - this.loading!.loading = true; - await Promise.all([ - this._postgresModel.refresh(), - this._controllerModel.refresh(false, this._controllerModel.info.namespace) - ]); - } catch (error) { - vscode.window.showErrorMessage(loc.refreshFailed(error)); - } - finally { - refreshButton.enabled = true; - } - })); - - return this.modelView.modelBuilder.toolbarContainer().withToolbarItems([ - { component: refreshButton } - ]).component(); - } - - private getProperties(): KeyValue[] { - const endpoint = this._postgresModel.endpoint; - const status = this._postgresModel.config?.status; - const controllerDashboard = new ControllerDashboard(this._controllerModel); - - return [ - new InputKeyValue(this.modelView.modelBuilder, loc.coordinatorEndpoint, endpoint ? `postgresql://postgres@${endpoint.ip}:${endpoint.port}` : ''), - new InputKeyValue(this.modelView.modelBuilder, loc.postgresAdminUsername, 'postgres'), - new InputKeyValue(this.modelView.modelBuilder, loc.subscriptionId, this._controllerModel.controllerConfig?.spec.settings.azure.subscription ?? ''), - new TextKeyValue(this.modelView.modelBuilder, loc.resourceGroup, this._controllerModel.controllerConfig?.spec.settings.azure.resourceGroup ?? ''), - new LinkKeyValue(this.modelView.modelBuilder, loc.dataController, this._controllerModel.controllerConfig?.metadata.name ?? '', () => controllerDashboard.showDashboard()), - new TextKeyValue(this.modelView.modelBuilder, loc.status, status ? `${status.state} (${status.readyPods} ${loc.podsReady})` : loc.unknown) - ]; - } - - private handleRegistrationsUpdated() { - this.keyValueContainer?.refresh(this.getProperties()); - this.loading!.loading = false; - } - - private handleServiceUpdated() { - this.keyValueContainer?.refresh(this.getProperties()); - this.loading!.loading = false; - } -} diff --git a/extensions/arc/src/ui/dashboards/postgres/postgresResourceHealthPage.ts b/extensions/arc/src/ui/dashboards/postgres/postgresResourceHealthPage.ts deleted file mode 100644 index bf0a4e2871..0000000000 --- a/extensions/arc/src/ui/dashboards/postgres/postgresResourceHealthPage.ts +++ /dev/null @@ -1,348 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import * as azdata from 'azdata'; -import * as loc from '../../../localizedConstants'; -import { IconPathHelper, cssStyles, iconSize } from '../../../constants'; -import { DashboardPage } from '../../components/dashboardPage'; -import { PostgresModel } from '../../../models/postgresModel'; - -export type PodHealthModel = { - condition: string, - details: azdata.Component, - lastUpdate: string -}; - -export enum PodConditionType { - initialized = 'Initialized', - ready = 'Ready', - containersReady = 'ContainersReady', - podScheduled = 'PodScheduled' -} - -export class PostgresResourceHealthPage extends DashboardPage { - private podSummaryContainer!: azdata.DivContainer; - - private podConditionsContainer!: azdata.DivContainer; - private podConditionsLoading!: azdata.LoadingComponent; - private podConditionsTable!: azdata.DeclarativeTableComponent; - private podConditionsTableIndexes: Map = new Map(); - - private podDropDown!: azdata.DropDownComponent; - private coordinatorPodName!: string; - private coordinatorData: PodHealthModel[] = []; - private podsData: PodHealthModel[] = []; - - constructor(modelView: azdata.ModelView, dashboard: azdata.window.ModelViewDashboard, private _postgresModel: PostgresModel) { - super(modelView, dashboard); - - this.disposables.push( - this._postgresModel.onConfigUpdated(() => this.eventuallyRunOnInitialized(() => this.handleConfigUpdated()))); - } - - protected get title(): string { - return loc.resourceHealth; - } - - protected get id(): string { - return 'postgres-resource-health'; - } - - protected get icon(): { dark: string; light: string; } { - return IconPathHelper.health; - } - - protected get container(): azdata.Component { - const root = this.modelView.modelBuilder.divContainer().component(); - const content = this.modelView.modelBuilder.divContainer().component(); - root.addItem(content, { CSSStyles: { 'margin': '10px 20px 0px 20px' } }); - - content.addItem(this.modelView.modelBuilder.text().withProps({ - value: loc.resourceHealth, - CSSStyles: { ...cssStyles.title } - }).component()); - - content.addItem(this.modelView.modelBuilder.text().withProps({ - value: loc.resourceHealthDescription, - CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px' } - }).component()); - - this.podSummaryContainer = this.modelView.modelBuilder.divContainer().component(); - - this.refreshPodSummarySection(); - - content.addItem(this.podSummaryContainer); - - // Pod Conditions - content.addItem(this.modelView.modelBuilder.text().withProps({ - value: loc.podsPresent, - CSSStyles: { ...cssStyles.title } - }).component()); - - content.addItem(this.modelView.modelBuilder.text().withProps({ - value: loc.podsUsedDescription, - CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px', 'margin-top': '10px' } - }).component()); - - this.podConditionsContainer = this.modelView.modelBuilder.divContainer().component(); - this.podConditionsTable = this.modelView.modelBuilder.declarativeTable().withProps({ - width: '100%', - ariaLabel: loc.podConditionsTable, - columns: [ - { - displayName: loc.condition, - valueType: azdata.DeclarativeDataType.string, - isReadOnly: true, - width: '20%', - headerCssStyles: cssStyles.tableHeader, - rowCssStyles: cssStyles.tableRow - }, - { - displayName: loc.details, - valueType: azdata.DeclarativeDataType.component, - isReadOnly: true, - width: '50%', - headerCssStyles: cssStyles.tableHeader, - rowCssStyles: { - ...cssStyles.tableRow, - 'min-width': '150px' - } - }, - { - displayName: loc.lastTransition, - valueType: azdata.DeclarativeDataType.string, - isReadOnly: true, - width: '30%', - headerCssStyles: cssStyles.tableHeader, - rowCssStyles: cssStyles.tableRow - } - ], - dataValues: this.createPodConditionsDataValues(this.coordinatorData) - }).component(); - - this.podDropDown = this.modelView.modelBuilder.dropDown().withProps({ - width: '150px', - ariaLabel: loc.podsUsedDescriptionAria - }).component(); - this.disposables.push( - this.podDropDown.onValueChanged(() => { - this.podConditionsTable.setFilter(this.podConditionsTableIndexes.get(String(this.podDropDown.value))); - }) - ); - - this.podConditionsContainer.addItem(this.podDropDown, { CSSStyles: { 'margin': '10px 0px 10px 0px' } }); - this.podConditionsContainer.addItem(this.podConditionsTable); - this.podConditionsLoading = this.modelView.modelBuilder.loadingComponent() - .withItem(this.podConditionsContainer) - .withProps({ - loading: !this._postgresModel.configLastUpdated - }).component(); - - this.refreshPodConditions(); - - content.addItem(this.podConditionsLoading, { CSSStyles: cssStyles.text }); - - this.initialized = true; - return root; - } - - protected get toolbarContainer(): azdata.ToolbarContainer { - // Refresh - const refreshButton = this.modelView.modelBuilder.button().withProps({ - label: loc.refresh, - iconPath: IconPathHelper.refresh - }).component(); - - this.disposables.push( - refreshButton.onDidClick(async () => { - refreshButton.enabled = false; - try { - this.podConditionsLoading!.loading = true; - await this._postgresModel.refresh(); - } catch (error) { - vscode.window.showErrorMessage(loc.refreshFailed(error)); - } - finally { - refreshButton.enabled = true; - } - })); - - return this.modelView.modelBuilder.toolbarContainer().withToolbarItems([ - { component: refreshButton } - ]).component(); - } - - private createPodList(): string[] { - const podStatus = this._postgresModel.config?.status.podsStatus; - let podNames: string[] = []; - - podStatus?.forEach(p => { - let podHealthModels: PodHealthModel[] = []; - let indexes: number[] = []; - - - p.conditions.forEach(c => { - let message: string; - let imageComponent = this.modelView.modelBuilder.image().withProps({ - width: iconSize, - height: iconSize, - iconHeight: '15px', - iconWidth: '15px' - }).component(); - - if (c.status === 'False') { - imageComponent.iconPath = IconPathHelper.fail; - message = c.message ?? c.reason ?? ''; - } else { - imageComponent.iconPath = IconPathHelper.success; - - if (c.type === PodConditionType.initialized) { - message = loc.podInitialized; - } else if (c.type === PodConditionType.ready) { - message = loc.podReady; - } else if (c.type === PodConditionType.containersReady) { - message = loc.containerReady; - } else if (c.type === PodConditionType.podScheduled) { - message = loc.podScheduled; - } else { - message = c.message ?? c.reason ?? ''; - } - } - - const conditionContainer = this.modelView.modelBuilder.flexContainer().withProps({ - CSSStyles: { 'alignItems': 'center', 'height': '15px' } - }).component(); - conditionContainer.addItem(imageComponent, { CSSStyles: { 'margin-right': '0px' } }); - conditionContainer.addItem(this.modelView.modelBuilder.text().withProps({ - value: message, - }).component()); - - indexes.push(this.podsData.length); - this.podsData.push({ - condition: c.type, - details: conditionContainer, - lastUpdate: c.lastTransitionTime - }); - }); - - if (p.role.toUpperCase() !== loc.coordinator.toUpperCase()) { - podNames.push(p.name); - } else { - this.coordinatorData = podHealthModels; - this.coordinatorPodName = p.name; - podNames.unshift(p.name); - } - this.podConditionsTableIndexes.set(p.name, indexes); - }); - - this.podConditionsTable.setDataValues(this.createPodConditionsDataValues(this.podsData)); - - return podNames; - } - - private createPodConditionsDataValues(podInfo: PodHealthModel[]): azdata.DeclarativeTableCellValue[][] { - let podDataValues: (string | azdata.Component)[][] = podInfo.map(p => [p.condition, p.details, p.lastUpdate]); - return podDataValues.map(p => { - return p.map((value): azdata.DeclarativeTableCellValue => { - return { value: value }; - }); - }); - } - - private findPodIssues(): string[] { - const podStatus = this._postgresModel.config?.status.podsStatus; - let issueCount = 0; - let podIssuesDetected: string[] = []; - - podStatus?.forEach(p => { - p.conditions.forEach(c => { - if (c.status === 'False') { - issueCount++; - } - }); - - if (issueCount > 0) { - podIssuesDetected.push(loc.numberOfIssuesDetected(p.name, issueCount)); - issueCount = 0; - } - }); - - return podIssuesDetected; - } - - private refreshPodSummarySection(): void { - let podSummaryTitle = this.modelView.modelBuilder.flexContainer().withProps({ - CSSStyles: { 'alignItems': 'center', 'height': '15px', 'margin-top': '20px' } - }).component(); - if (!this._postgresModel.config) { - podSummaryTitle.addItem(this.modelView.modelBuilder.loadingComponent().component(), { CSSStyles: { 'margin-right': '5px' } }); - podSummaryTitle.addItem(this.modelView.modelBuilder.text().withProps({ - value: loc.loading, - CSSStyles: { ...cssStyles.title } - }).component()); - this.podSummaryContainer.addItem(podSummaryTitle); - } else { - let components: azdata.Component[] = []; - let imageComponent = this.modelView.modelBuilder.image().withProps({ - iconPath: IconPathHelper.success, - width: iconSize, - height: iconSize, - iconHeight: '20px', - iconWidth: '20px' - }).component(); - - let podIssues = this.findPodIssues(); - if (podIssues.length === 0) { - imageComponent.iconPath = IconPathHelper.success; - podSummaryTitle.addItem(imageComponent, { CSSStyles: { 'margin-right': '5px' } }); - podSummaryTitle.addItem(this.modelView.modelBuilder.text().withProps({ - value: loc.available, - CSSStyles: { ...cssStyles.title, 'margin-left': '0px' } - }).component()); - components.push(podSummaryTitle); - components.push(this.modelView.modelBuilder.text().withProps({ - value: loc.noPodIssuesDetected, - CSSStyles: { ...cssStyles.text, 'margin-top': '20px' } - }).component()); - } else { - imageComponent.iconPath = IconPathHelper.fail; - podSummaryTitle.addItem(imageComponent, { CSSStyles: { 'margin-right': '5px' } }); - podSummaryTitle.addItem(this.modelView.modelBuilder.text().withProps({ - value: loc.issuesDetected, - CSSStyles: { ...cssStyles.title } - }).component()); - components.push(podSummaryTitle); - components.push(this.modelView.modelBuilder.text().withProps({ - value: loc.podIssuesDetected, - CSSStyles: { ...cssStyles.text, 'margin-top': '20px 0px 10px 0px' } - }).component()); - components.push(...podIssues.map(i => { - return this.modelView.modelBuilder.text().withProps({ - value: i, - CSSStyles: { ...cssStyles.text, 'margin': '0px' } - }).component(); - })); - } - this.podSummaryContainer.addItems(components); - } - } - - private refreshPodConditions(): void { - if (this._postgresModel.config) { - this.podConditionsTableIndexes = new Map(); - this.podsData = []; - this.podDropDown.values = this.createPodList(); - this.podConditionsTable.setFilter(this.podConditionsTableIndexes.get(this.coordinatorPodName!)); - this.podConditionsLoading.loading = false; - } - } - - private handleConfigUpdated() { - this.podSummaryContainer.clearItems(); - this.refreshPodSummarySection(); - this.refreshPodConditions(); - } -} diff --git a/extensions/arc/src/ui/dialogs/addPGExtensionsDialog.ts b/extensions/arc/src/ui/dialogs/addPGExtensionsDialog.ts deleted file mode 100644 index 4e4ba95ec7..0000000000 --- a/extensions/arc/src/ui/dialogs/addPGExtensionsDialog.ts +++ /dev/null @@ -1,99 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as azdata from 'azdata'; -import { Deferred } from '../../common/promise'; -import * as loc from '../../localizedConstants'; -import { cssStyles } from '../../constants'; -import { InitializingComponent } from '../components/initializingComponent'; -import { PostgresModel } from '../../models/postgresModel'; - -export const validExtensions = ['citus', 'pgaudit', 'pgautofailover', 'pg_cron', 'pg_partman', 'plv8', 'postgis', 'postgis_raster', 'postgis_sfcgal', 'postgis_tiger_geocoder', 'tdigest']; - -export class AddPGExtensionsDialog extends InitializingComponent { - protected modelBuilder!: azdata.ModelBuilder; - - protected extensionsListInputBox!: azdata.InputBoxComponent; - - protected _completionPromise = new Deferred(); - - constructor(protected _model: PostgresModel) { - super(); - } - - public showDialog(dialogTitle: string): azdata.window.Dialog { - const dialog = azdata.window.createModelViewDialog(dialogTitle); - dialog.cancelButton.onClick(() => this.handleCancel()); - dialog.registerContent(async view => { - this.modelBuilder = view.modelBuilder; - - const info = this.modelBuilder.text().withProps({ - value: loc.extensionsAddFunction(validExtensions.join(', ')), - CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px' } - }).component(); - - const link = this.modelBuilder.hyperlink().withProps({ - label: loc.extensionsLearnMore, - url: 'https://docs.microsoft.com/azure/azure-arc/data/using-extensions-in-postgresql-hyperscale-server-group', - }).component(); - - const infoAndLink = this.modelBuilder.flexContainer().withLayout({ flexWrap: 'wrap' }).component(); - infoAndLink.addItem(info, { CSSStyles: { 'margin-right': '5px' } }); - infoAndLink.addItem(link); - - this.extensionsListInputBox = this.modelBuilder.inputBox() - .withProps({ - value: '', - ariaLabel: loc.extensionsAddList, - enabled: true, - validationErrorMessage: loc.extensionsAddErrorrMessage(validExtensions.join(',')) - }).withValidation((component) => { - if (!component.value) { - return true; - } - - let newExtensions = component.value.split(','); - return newExtensions.every(e => validExtensions.includes(e)); - }).component(); - - let formModel = this.modelBuilder.formContainer() - .withFormItems([{ - components: [ - { - component: infoAndLink - }, - { - component: this.extensionsListInputBox, - title: loc.extensionsAddList, - required: true - } - ], - title: '' - }]).withLayout({ width: '100%' }).component(); - await view.initializeModel(formModel); - this.extensionsListInputBox.focus(); - this.initialized = true; - }); - - dialog.registerCloseValidator(async () => await this.validate()); - dialog.okButton.label = loc.loadExtensions; - dialog.cancelButton.label = loc.cancel; - azdata.window.openDialog(dialog); - return dialog; - } - - public async validate(): Promise { - this._completionPromise.resolve(this.extensionsListInputBox.value); - return true; - } - - private handleCancel(): void { - this._completionPromise.resolve(undefined); - } - - public waitForClose(): Promise { - return this._completionPromise.promise; - } -} diff --git a/extensions/azcli/src/azReleaseInfo.ts b/extensions/azcli/src/azReleaseInfo.ts deleted file mode 100644 index 2c7581fb28..0000000000 --- a/extensions/azcli/src/azReleaseInfo.ts +++ /dev/null @@ -1,15 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -interface PlatformReleaseInfo { - version: string; // "20.0.1" - link?: string; // "https://aka.ms/az-msi" -} - -export interface AzReleaseInfo { - win32: PlatformReleaseInfo, - darwin: PlatformReleaseInfo, - linux: PlatformReleaseInfo -} diff --git a/extensions/azcli/src/test/testUtils.ts b/extensions/azcli/src/test/testUtils.ts index 6176dc2e78..39f6295a3f 100644 --- a/extensions/azcli/src/test/testUtils.ts +++ b/extensions/azcli/src/test/testUtils.ts @@ -9,12 +9,12 @@ * @param promise The promise to verify was rejected * @param message The message to include in the error if the promise isn't rejected */ -export async function assertRejected(promise: Promise, message: string): Promise { - try { - await promise; - } catch { - return; - } - throw new Error(message); -} +// export async function assertRejected(promise: Promise, message: string): Promise { +// try { +// await promise; +// } catch { +// return; +// } +// throw new Error(message); +// } diff --git a/extensions/azurecore/src/azureResource/tree/flatTreeProvider.ts b/extensions/azurecore/src/azureResource/tree/flatTreeProvider.ts deleted file mode 100644 index 9d28ccdbef..0000000000 --- a/extensions/azurecore/src/azureResource/tree/flatTreeProvider.ts +++ /dev/null @@ -1,214 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import * as azdata from 'azdata'; -import { AppContext } from '../../appContext'; -import * as nls from 'vscode-nls'; -const localize = nls.loadMessageBundle(); - -import { TreeNode } from '../treeNode'; -import { AzureResourceMessageTreeNode } from '../messageTreeNode'; -import { AzureResourceContainerTreeNodeBase } from './baseTreeNodes'; -import { AzureResourceErrorMessageUtil, filterAccounts } from '../utils'; -import { IAzureResourceTreeChangeHandler } from './treeChangeHandler'; -import { IAzureResourceNodeWithProviderId, IAzureResourceSubscriptionService } from '../interfaces'; -import { AzureResourceServiceNames } from '../constants'; -import { AzureResourceService } from '../resourceService'; -import { Logger } from '../../utils/Logger'; - -export class FlatAzureResourceTreeProvider implements vscode.TreeDataProvider, IAzureResourceTreeChangeHandler { - public isSystemInitialized: boolean = false; - - private _onDidChangeTreeData = new vscode.EventEmitter(); - - private resourceLoader: ResourceLoader | undefined; - - public constructor(private readonly appContext: AppContext, - private readonly authLibrary: string) { - } - - public async getChildren(element?: TreeNode): Promise { - if (element) { - return element.getChildren(true); - } - - if (!this.resourceLoader) { - this.resourceLoader = new ResourceLoader(this.appContext, this.authLibrary); - this.resourceLoader.onDidAddNewResource(e => this._onDidChangeTreeData.fire(e)); - } - - if (this.resourceLoader.state === LoaderState.NotStarted) { - this.resourceLoader.start().catch(err => console.error('Error loading Azure Resources for FlatAzureResourceTreeProvider ', err)); - return [AzureResourceMessageTreeNode.create(localize('azure.resource.tree.treeProvider.loadingLabel', "Loading ..."), undefined)]; - } - - return this.resourceLoader.children; - } - - public get onDidChangeTreeData(): vscode.Event { - return this._onDidChangeTreeData.event; - } - - public notifyNodeChanged(node: TreeNode): void { - this._onDidChangeTreeData.fire(node); - } - - public async refresh(node: TreeNode, isClearingCache: boolean): Promise { - if (isClearingCache) { - if ((node instanceof AzureResourceContainerTreeNodeBase)) { - node.clearCache(); - } - } - - this._onDidChangeTreeData.fire(node); - } - - public getTreeItem(element: TreeNode): vscode.TreeItem | Thenable { - return element.getTreeItem(); - } -} - -enum LoaderState { - NotStarted, - Loading, - Complete -} - -class ResourceLoader { - private _state: LoaderState = LoaderState.NotStarted; - - private readonly resourceGroups = new Map(); - - private readonly subscriptionService: IAzureResourceSubscriptionService; - private readonly resourceService: AzureResourceService; - - private readonly _onDidAddNewResource = new vscode.EventEmitter(); - public readonly onDidAddNewResource = this._onDidAddNewResource.event; - - constructor(private readonly appContext: AppContext, - private readonly authLibrary: string) { - this.subscriptionService = appContext.getService(AzureResourceServiceNames.subscriptionService); - this.resourceService = appContext.getService(AzureResourceServiceNames.resourceService); - } - - get state(): LoaderState { - return this._state; - } - - get children(): AzureResourceResourceTreeNode[] { - return Array.from(this.resourceGroups.values()); - } - - async start(): Promise { - if (this.state === LoaderState.Loading) { - throw new Error('Resource Loader already loading'); - } - - let doRefresh = false; - - // if we just fire every time we get an a new resource we crash the application - // this effectively buffers the event so that we don't cause hangs. - let interval = setInterval(() => { - if (doRefresh) { - doRefresh = false; - this._onDidAddNewResource.fire(undefined); - } - }, 500); - - this._state = LoaderState.Loading; - - const accounts = filterAccounts(await azdata.accounts.getAllAccounts(), this.authLibrary); - - for (const account of accounts) { - for (const tenant of account.properties.tenants) { - for (const subscription of await this.subscriptionService.getSubscriptions(account, [tenant.id])) { - for (const providerId of await this.resourceService.listResourceProviderIds()) { - for (const group of await this.resourceService.getRootChildren(providerId, account, subscription)) { - const children = await this.resourceService.getChildren(providerId, group.resourceNode); - let groupNode: AzureResourceResourceTreeNode | undefined = this.resourceGroups.get(group.resourceProviderId); - if (groupNode) { - groupNode.pushItems(...children); - } else { - groupNode = new AzureResourceResourceTreeNode(group, this.appContext); - this.resourceGroups.set(group.resourceProviderId, groupNode); - groupNode.pushItems(...children); - } - doRefresh = true; - } - } - } - } - } - - Logger.verbose('finished loading all accounts and subscriptions'); - - clearInterval(interval); - - this._state = LoaderState.Complete; - } -} - -class AzureResourceResourceTreeNode extends TreeNode { - private _resourceService: AzureResourceService; - - public constructor( - public readonly resourceNodeWithProviderId: IAzureResourceNodeWithProviderId, - private appContext: AppContext - ) { - super(); - this._resourceService = appContext.getService(AzureResourceServiceNames.resourceService); - } - - private _children: IAzureResourceNodeWithProviderId[] = []; - - pushItems(...items: IAzureResourceNodeWithProviderId[]): void { - this._children.push(...items); - } - - public async getChildren(): Promise { - // It is a leaf node. - - try { - - if (this._children.length === 0) { - return [AzureResourceMessageTreeNode.create(localize('azure.resource.resourceTreeNode.noResourcesLabel', "No Resources found"), this)]; - } else { - return this._children.map((child) => { - // To make tree node's id unique, otherwise, treeModel.js would complain 'item already registered' - child.resourceNode.treeItem.id = `${this.resourceNodeWithProviderId.resourceNode.treeItem.id}.${child.resourceNode.treeItem.id}`; - return new AzureResourceResourceTreeNode(child, this.appContext); - }); - } - } catch (error) { - return [AzureResourceMessageTreeNode.create(AzureResourceErrorMessageUtil.getErrorMessage(error), this)]; - } - } - - public getTreeItem(): vscode.TreeItem | Promise { - return this._resourceService.getTreeItem(this.resourceNodeWithProviderId.resourceProviderId, this.resourceNodeWithProviderId.resourceNode); - } - - public getNodeInfo(): azdata.NodeInfo { - const treeItem = this.resourceNodeWithProviderId.resourceNode.treeItem; - - return { - label: treeItem.label, - isLeaf: treeItem.collapsibleState === vscode.TreeItemCollapsibleState.None ? true : false, - errorMessage: undefined, - metadata: undefined, - nodePath: this.generateNodePath(), - parentNodePath: this.parent?.generateNodePath() ?? '', - nodeStatus: undefined, - nodeType: treeItem.contextValue || '', - nodeSubType: undefined, - iconType: treeItem.contextValue - }; - } - - public get nodePathValue(): string { - return this.resourceNodeWithProviderId.resourceNode.treeItem.id || ''; - } -} diff --git a/extensions/azurecore/src/test/stubs/credentialsTestProvider.ts b/extensions/azurecore/src/test/stubs/credentialsTestProvider.ts deleted file mode 100644 index 7432dee5f1..0000000000 --- a/extensions/azurecore/src/test/stubs/credentialsTestProvider.ts +++ /dev/null @@ -1,33 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as azdata from 'azdata'; - -/** - * Mock CredentialsProvider to be used for testing - */ -export class CredentialsTestProvider implements azdata.CredentialProvider { - handle: number = 0; - - public storedCredentials: { [K: string]: azdata.Credential } = {}; - - saveCredential(credentialId: string, password: string): Thenable { - this.storedCredentials[credentialId] = { - credentialId: credentialId, - password: password - }; - return Promise.resolve(true); - } - - readCredential(credentialId: string): Thenable { - return Promise.resolve(this.storedCredentials[credentialId]); - } - - deleteCredential(credentialId: string): Thenable { - let exists = this.storedCredentials[credentialId] !== undefined; - delete this.storedCredentials[credentialId]; - return Promise.resolve(exists); - } -} diff --git a/extensions/azuremonitor/src/objectExplorerNodeProvider/cancelableStream.ts b/extensions/azuremonitor/src/objectExplorerNodeProvider/cancelableStream.ts deleted file mode 100644 index 3efb7e8e56..0000000000 --- a/extensions/azuremonitor/src/objectExplorerNodeProvider/cancelableStream.ts +++ /dev/null @@ -1,25 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Transform } from 'stream'; -import * as vscode from 'vscode'; -import * as nls from 'vscode-nls'; - -const localize = nls.loadMessageBundle(); - -export class CancelableStream extends Transform { - constructor(private cancelationToken: vscode.CancellationTokenSource) { - super(); - } - - public override _transform(chunk: any, _encoding: string, callback: Function): void { - if (this.cancelationToken && this.cancelationToken.token.isCancellationRequested) { - callback(new Error(localize('streamCanceled', 'Stream operation canceled by the user'))); - } else { - this.push(chunk); - callback(); - } - } -} diff --git a/extensions/azuremonitor/src/prompts/adapter.ts b/extensions/azuremonitor/src/prompts/adapter.ts deleted file mode 100644 index 41cb52a84f..0000000000 --- a/extensions/azuremonitor/src/prompts/adapter.ts +++ /dev/null @@ -1,77 +0,0 @@ -// This code is originally from https://github.com/DonJayamanne/bowerVSCode -// License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE - -import { window } from 'vscode'; -import PromptFactory from './factory'; -import EscapeException from './escapeException'; -import { IQuestion, IPrompter, IPromptCallback, Answers } from './question'; - -// Supports simple pattern for prompting for user input and acting on this -export default class CodeAdapter implements IPrompter { - - // TODO define question interface - private fixQuestion(question: IQuestion): any { - if (question.type === 'checkbox' && Array.isArray(question.choices)) { - // For some reason when there's a choice of checkboxes, they aren't formatted properly - // Not sure where the issue is - question.choices = question.choices.map(item => { - if (typeof (item) === 'string') { - return { checked: false, name: item, value: item }; - } else { - return item; - } - }); - } - } - - public async promptSingle(question: IQuestion, ignoreFocusOut?: boolean): Promise { - let questions: IQuestion[] = [question]; - const answers = await this.prompt(questions, ignoreFocusOut); - if (answers) { - let response: T = answers[question.name]; - return response || undefined; - } - return undefined; - } - - public async prompt(questions: IQuestion[], ignoreFocusOut?: boolean): Promise | undefined> { - // Collapse multiple questions into a set of prompt steps - const promptResult = new Promise>((resolve) => { - let answers: Answers = {}; - questions.forEach(async (question: IQuestion) => { - this.fixQuestion(question); - const prompt = PromptFactory.createPrompt(question, ignoreFocusOut); - if (!question.shouldPrompt || question.shouldPrompt(answers) === true) { - const result = await prompt.render(); - answers[question.name] = result; - - if (question.onAnswered) { - question.onAnswered(result); - } - return; - } - }); - - resolve(answers); - }); - - try { - return await promptResult; - } catch (err) { - if (err instanceof EscapeException || err instanceof TypeError) { - window.showErrorMessage(err.message); - } - return undefined; - } - } - - // Helper to make it possible to prompt using callback pattern. Generally Promise is a preferred flow - public promptCallback(questions: IQuestion[], callback: IPromptCallback | undefined): void { - // Collapse multiple questions into a set of prompt steps - this.prompt(questions).then(answers => { - if (callback && answers) { - callback(answers); - } - }); - } -} diff --git a/extensions/azuremonitor/src/prompts/progressIndicator.ts b/extensions/azuremonitor/src/prompts/progressIndicator.ts deleted file mode 100644 index c6f20574a0..0000000000 --- a/extensions/azuremonitor/src/prompts/progressIndicator.ts +++ /dev/null @@ -1,70 +0,0 @@ -'use strict'; - -// This code is originally from https://github.com/DonJayamanne/bowerVSCode -// License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE - -import { window, StatusBarItem, StatusBarAlignment } from 'vscode'; - -export default class ProgressIndicator { - - private _statusBarItem: StatusBarItem; - - constructor() { - this._statusBarItem = window.createStatusBarItem(StatusBarAlignment.Left); - } - - private _tasks: string[] = []; - public beginTask(task: string): void { - this._tasks.push(task); - this.displayProgressIndicator(); - } - - public endTask(_task: string): void { - if (this._tasks.length > 0) { - this._tasks.pop(); - } - - this.setMessage(); - } - - private setMessage(): void { - if (this._tasks.length === 0) { - this._statusBarItem.text = ''; - this.hideProgressIndicator(); - return; - } - - this._statusBarItem.text = this._tasks[this._tasks.length - 1]; - this._statusBarItem.show(); - } - - private _interval: any; - private displayProgressIndicator(): void { - this.setMessage(); - this.hideProgressIndicator(); - this._interval = setInterval(() => this.onDisplayProgressIndicator(), 100); - } - private hideProgressIndicator(): void { - if (this._interval) { - clearInterval(this._interval); - this._interval = undefined; - } - this.ProgressCounter = 0; - } - - private ProgressText = ['|', '/', '-', '\\', '|', '/', '-', '\\']; - private ProgressCounter = 0; - private onDisplayProgressIndicator(): void { - if (this._tasks.length === 0) { - return; - } - - let txt = this.ProgressText[this.ProgressCounter]; - this._statusBarItem.text = this._tasks[this._tasks.length - 1] + ' ' + txt; - this.ProgressCounter++; - - if (this.ProgressCounter >= this.ProgressText.length - 1) { - this.ProgressCounter = 0; - } - } -} diff --git a/extensions/datavirtualization/src/test/mockFileSource.ts b/extensions/datavirtualization/src/test/mockFileSource.ts deleted file mode 100644 index 29573a3487..0000000000 --- a/extensions/datavirtualization/src/test/mockFileSource.ts +++ /dev/null @@ -1,47 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as fs from 'fs'; - -import { IFileSource, IFile } from '../fileSources'; - -export class MockFileSource implements IFileSource { - filesToReturn: Map; - constructor() { - this.filesToReturn = new Map(); - } - enumerateFiles(filePath: string): Promise { - let files: IFile[] = this.filesToReturn.get(filePath); - return Promise.resolve(files); - } - - mkdir(dirName: string, remoteBasePath: string): Promise { - return Promise.resolve(undefined); - } - - writeFile(localFile: IFile, remoteDir: string): Promise { - return Promise.resolve(undefined); - } - - delete(filePath: string): Promise { - throw new Error('Method not implemented.'); - } - - readFile(filePath: string, maxBytes?: number): Promise { - throw new Error('Method not implemented.'); - } - - readFileLines(path: string, maxLines: number): Promise { - throw new Error("Method not implemented."); - } - - createReadStream(filePath: string): fs.ReadStream { - throw new Error('Method not implemented.'); - } - - exists(filePath: string): Promise { - throw new Error('Method not implemented.'); - } -} diff --git a/extensions/datavirtualization/src/test/testUtils.ts b/extensions/datavirtualization/src/test/testUtils.ts deleted file mode 100644 index 4df882d5e5..0000000000 --- a/extensions/datavirtualization/src/test/testUtils.ts +++ /dev/null @@ -1,19 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as assert from 'assert'; - -export async function assertThrowsAsync(fn: Function, msg: string): Promise { - let f = () => { - // Empty - }; - try { - await fn(); - } catch (e) { - f = () => { throw e; }; - } finally { - assert.throws(f, undefined, msg); - } -} diff --git a/extensions/kusto/src/objectExplorerNodeProvider/cancelableStream.ts b/extensions/kusto/src/objectExplorerNodeProvider/cancelableStream.ts deleted file mode 100644 index 84fd85bb49..0000000000 --- a/extensions/kusto/src/objectExplorerNodeProvider/cancelableStream.ts +++ /dev/null @@ -1,27 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -'use strict'; - -import { Transform } from 'stream'; -import * as vscode from 'vscode'; -import * as nls from 'vscode-nls'; - -const localize = nls.loadMessageBundle(); - -export class CancelableStream extends Transform { - constructor(private cancelationToken: vscode.CancellationTokenSource) { - super(); - } - - public override _transform(chunk: any, encoding: string, callback: Function): void { - if (this.cancelationToken && this.cancelationToken.token.isCancellationRequested) { - callback(new Error(localize('streamCanceled', 'Stream operation canceled by the user'))); - } else { - this.push(chunk); - callback(); - } - } -} diff --git a/extensions/kusto/src/prompts/adapter.ts b/extensions/kusto/src/prompts/adapter.ts deleted file mode 100644 index 41cb52a84f..0000000000 --- a/extensions/kusto/src/prompts/adapter.ts +++ /dev/null @@ -1,77 +0,0 @@ -// This code is originally from https://github.com/DonJayamanne/bowerVSCode -// License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE - -import { window } from 'vscode'; -import PromptFactory from './factory'; -import EscapeException from './escapeException'; -import { IQuestion, IPrompter, IPromptCallback, Answers } from './question'; - -// Supports simple pattern for prompting for user input and acting on this -export default class CodeAdapter implements IPrompter { - - // TODO define question interface - private fixQuestion(question: IQuestion): any { - if (question.type === 'checkbox' && Array.isArray(question.choices)) { - // For some reason when there's a choice of checkboxes, they aren't formatted properly - // Not sure where the issue is - question.choices = question.choices.map(item => { - if (typeof (item) === 'string') { - return { checked: false, name: item, value: item }; - } else { - return item; - } - }); - } - } - - public async promptSingle(question: IQuestion, ignoreFocusOut?: boolean): Promise { - let questions: IQuestion[] = [question]; - const answers = await this.prompt(questions, ignoreFocusOut); - if (answers) { - let response: T = answers[question.name]; - return response || undefined; - } - return undefined; - } - - public async prompt(questions: IQuestion[], ignoreFocusOut?: boolean): Promise | undefined> { - // Collapse multiple questions into a set of prompt steps - const promptResult = new Promise>((resolve) => { - let answers: Answers = {}; - questions.forEach(async (question: IQuestion) => { - this.fixQuestion(question); - const prompt = PromptFactory.createPrompt(question, ignoreFocusOut); - if (!question.shouldPrompt || question.shouldPrompt(answers) === true) { - const result = await prompt.render(); - answers[question.name] = result; - - if (question.onAnswered) { - question.onAnswered(result); - } - return; - } - }); - - resolve(answers); - }); - - try { - return await promptResult; - } catch (err) { - if (err instanceof EscapeException || err instanceof TypeError) { - window.showErrorMessage(err.message); - } - return undefined; - } - } - - // Helper to make it possible to prompt using callback pattern. Generally Promise is a preferred flow - public promptCallback(questions: IQuestion[], callback: IPromptCallback | undefined): void { - // Collapse multiple questions into a set of prompt steps - this.prompt(questions).then(answers => { - if (callback && answers) { - callback(answers); - } - }); - } -} diff --git a/extensions/kusto/src/prompts/progressIndicator.ts b/extensions/kusto/src/prompts/progressIndicator.ts deleted file mode 100644 index d63b830a08..0000000000 --- a/extensions/kusto/src/prompts/progressIndicator.ts +++ /dev/null @@ -1,70 +0,0 @@ -'use strict'; - -// This code is originally from https://github.com/DonJayamanne/bowerVSCode -// License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE - -import { window, StatusBarItem, StatusBarAlignment } from 'vscode'; - -export default class ProgressIndicator { - - private _statusBarItem: StatusBarItem; - - constructor() { - this._statusBarItem = window.createStatusBarItem(StatusBarAlignment.Left); - } - - private _tasks: string[] = []; - public beginTask(task: string): void { - this._tasks.push(task); - this.displayProgressIndicator(); - } - - public endTask(task: string): void { - if (this._tasks.length > 0) { - this._tasks.pop(); - } - - this.setMessage(); - } - - private setMessage(): void { - if (this._tasks.length === 0) { - this._statusBarItem.text = ''; - this.hideProgressIndicator(); - return; - } - - this._statusBarItem.text = this._tasks[this._tasks.length - 1]; - this._statusBarItem.show(); - } - - private _interval: any; - private displayProgressIndicator(): void { - this.setMessage(); - this.hideProgressIndicator(); - this._interval = setInterval(() => this.onDisplayProgressIndicator(), 100); - } - private hideProgressIndicator(): void { - if (this._interval) { - clearInterval(this._interval); - this._interval = undefined; - } - this.ProgressCounter = 0; - } - - private ProgressText = ['|', '/', '-', '\\', '|', '/', '-', '\\']; - private ProgressCounter = 0; - private onDisplayProgressIndicator(): void { - if (this._tasks.length === 0) { - return; - } - - let txt = this.ProgressText[this.ProgressCounter]; - this._statusBarItem.text = this._tasks[this._tasks.length - 1] + ' ' + txt; - this.ProgressCounter++; - - if (this.ProgressCounter >= this.ProgressText.length - 1) { - this.ProgressCounter = 0; - } - } -} diff --git a/extensions/machine-learning/src/types.ts b/extensions/machine-learning/src/types.ts deleted file mode 100644 index d3f568323a..0000000000 --- a/extensions/machine-learning/src/types.ts +++ /dev/null @@ -1,22 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -const _typeof = { - undefined: 'undefined' -}; - -/** - * @returns whether the provided parameter is undefined or null. - */ -export function isUndefinedOrNull(obj: any): boolean { - return isUndefined(obj) || obj === null; -} - -/** - * @returns whether the provided parameter is undefined. - */ -export function isUndefined(obj: any): boolean { - return typeof (obj) === _typeof.undefined; -} diff --git a/extensions/sql-migration/src/models/externalContract.ts b/extensions/sql-migration/src/models/externalContract.ts deleted file mode 100644 index 80292543bb..0000000000 --- a/extensions/sql-migration/src/models/externalContract.ts +++ /dev/null @@ -1,39 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as azdata from 'azdata'; -import { MigrationTargetType } from './stateMachine'; - -export interface Base { - uuid: string; -} - -export interface BaseRequest extends Base { } - -export interface BaseResponse extends Base { - error?: string; - response: T; -} - -export interface GatherInformationRequest extends BaseRequest { - connection: azdata.connection.Connection; -} - -export interface Checks { - -} - -export interface SKURecommendation { - product: MigrationTargetType; - checks: Checks; -} - -export interface SKURecommendations { - recommendations: SKURecommendation[]; -} - -export interface GatherInformationResponse extends BaseResponse { -} - diff --git a/extensions/sql-migration/src/wizard/sqlSourceConfigurationPage.ts b/extensions/sql-migration/src/wizard/sqlSourceConfigurationPage.ts deleted file mode 100644 index 8e0a81cdbe..0000000000 --- a/extensions/sql-migration/src/wizard/sqlSourceConfigurationPage.ts +++ /dev/null @@ -1,163 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as azdata from 'azdata'; -import * as vscode from 'vscode'; -import { MigrationWizardPage } from '../models/migrationWizardPage'; -import { MigrationSourceAuthenticationType, MigrationStateModel, StateChangeEvent } from '../models/stateMachine'; -import * as constants from '../constants/strings'; -import { createLabelTextComponent, createHeadingTextComponent, WIZARD_INPUT_COMPONENT_WIDTH } from './wizardController'; -import { getSourceConnectionCredentials, getSourceConnectionProfile, getSourceConnectionUri } from '../api/sqlUtils'; - -export class SqlSourceConfigurationPage extends MigrationWizardPage { - private _view!: azdata.ModelView; - private _usernameInput!: azdata.InputBoxComponent; - private _password!: azdata.InputBoxComponent; - private _disposables: vscode.Disposable[] = []; - - constructor(wizard: azdata.window.Wizard, migrationStateModel: MigrationStateModel) { - super(wizard, azdata.window.createWizardPage(constants.SOURCE_CONFIGURATION, 'MigrationModePage'), migrationStateModel); - } - - protected async registerContent(view: azdata.ModelView): Promise { - this.wizard.customButtons[0].enabled = true; - this._view = view; - const form = view.modelBuilder.formContainer() - .withFormItems( - [ - await this.createSourceCredentialContainer(), - ] - ); - - this._disposables.push(this._view.onClosed(e => { - this._disposables.forEach( - d => { try { d.dispose(); } catch { } }); - })); - - await view.initializeModel(form.component()); - } - - public async onPageEnter(pageChangeInfo: azdata.window.WizardPageChangeInfo): Promise { - this.wizard.registerNavigationValidator(pageChangeInfo => true); - } - public async onPageLeave(pageChangeInfo: azdata.window.WizardPageChangeInfo): Promise { - this.wizard.registerNavigationValidator(pageChangeInfo => true); - this.wizard.message = { text: '' }; - } - - protected async handleStateChange(e: StateChangeEvent): Promise { - } - - private async createSourceCredentialContainer(): Promise { - - const connectionProfile = await getSourceConnectionProfile(); - const queryProvider = azdata.dataprotocol.getProvider(connectionProfile.providerId, azdata.DataProviderType.QueryProvider); - const query = 'select SUSER_NAME()'; - const results = await queryProvider.runQueryAndReturn(await getSourceConnectionUri(), query); - const username = results.rows[0][0].displayValue; - this.migrationStateModel._authenticationType = connectionProfile.authenticationType === azdata.connection.AuthenticationType.SqlLogin - ? MigrationSourceAuthenticationType.Sql - : connectionProfile.authenticationType === azdata.connection.AuthenticationType.Integrated - ? MigrationSourceAuthenticationType.Integrated - : undefined!; - - const sourceCredText = await createHeadingTextComponent(this._view, constants.SOURCE_CREDENTIALS); - const enterYourCredText = createLabelTextComponent( - this._view, - constants.ENTER_YOUR_SQL_CREDS, - { - 'width': '600px', - 'font-size': '13px', - } - ); - - const serverLabel = this._view.modelBuilder.text().withProps({ - value: constants.SERVER, - width: WIZARD_INPUT_COMPONENT_WIDTH, - CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold', - } - }).component(); - - const server = this._view.modelBuilder.inputBox().withProps({ - value: connectionProfile.serverName, - enabled: false, - width: WIZARD_INPUT_COMPONENT_WIDTH - }).component(); - - const authenticationTypeLable = this._view.modelBuilder.text().withProps({ - value: constants.AUTHENTICATION_TYPE, - width: WIZARD_INPUT_COMPONENT_WIDTH, - CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold', - } - }).component(); - - const authenticationTypeInput = this._view.modelBuilder.inputBox().withProps({ - value: this.migrationStateModel._authenticationType === MigrationSourceAuthenticationType.Sql ? 'SQL Login' : 'Windows Authentication', - enabled: false, - width: WIZARD_INPUT_COMPONENT_WIDTH - }).component(); - - const usernameLable = this._view.modelBuilder.text().withProps({ - value: constants.USERNAME, - width: WIZARD_INPUT_COMPONENT_WIDTH, - CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold', - } - }).component(); - this._usernameInput = this._view.modelBuilder.inputBox().withProps({ - value: username, - required: true, - enabled: false, - width: WIZARD_INPUT_COMPONENT_WIDTH - }).component(); - this._disposables.push(this._usernameInput.onTextChanged(value => { - this.migrationStateModel._sqlServerUsername = value; - })); - - const passwordLabel = this._view.modelBuilder.text().withProps({ - value: constants.DATABASE_BACKUP_NETWORK_SHARE_PASSWORD_LABEL, - width: WIZARD_INPUT_COMPONENT_WIDTH, - CSSStyles: { - 'font-size': '13px', - 'font-weight': 'bold', - } - }).component(); - this._password = this._view.modelBuilder.inputBox().withProps({ - value: (await getSourceConnectionCredentials()).password, - required: true, - inputType: 'password', - width: WIZARD_INPUT_COMPONENT_WIDTH - }).component(); - this._disposables.push(this._password.onTextChanged(value => { - this.migrationStateModel._sqlServerPassword = value; - })); - - const container = this._view.modelBuilder.flexContainer().withItems( - [ - sourceCredText, - enterYourCredText, - serverLabel, - server, - authenticationTypeLable, - authenticationTypeInput, - usernameLable, - this._usernameInput, - passwordLabel, - this._password - ] - ).withLayout({ - flexFlow: 'column' - }).component(); - - return { - component: container - }; - } -} diff --git a/src/sql/base/browser/ui/table/highPerf/rowCache.ts b/src/sql/base/browser/ui/table/highPerf/rowCache.ts deleted file mode 100644 index d45dac4c01..0000000000 --- a/src/sql/base/browser/ui/table/highPerf/rowCache.ts +++ /dev/null @@ -1,17 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { IDisposable } from 'vs/base/common/lifecycle'; - - -export class RowCache implements IDisposable { - dispose(): void { - - } -} - -export interface IRow { - domNode: HTMLElement | null; -} diff --git a/src/sql/base/browser/ui/table/highPerf/tableWidget.ts b/src/sql/base/browser/ui/table/highPerf/tableWidget.ts deleted file mode 100644 index d66e7e227d..0000000000 --- a/src/sql/base/browser/ui/table/highPerf/tableWidget.ts +++ /dev/null @@ -1,1055 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { ITableEvent, ITableRenderer, ITableMouseEvent, ITableContextMenuEvent, ITableDataSource, IStaticTableRenderer, IStaticColumn, ITableColumn, TableError } from 'sql/base/browser/ui/table/highPerf/table'; - -import { IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle'; -import { memoize } from 'vs/base/common/decorators'; -import { Event, Emitter, EventBufferer } from 'vs/base/common/event'; -import * as DOM from 'vs/base/browser/dom'; -import { TableView, ITableViewOptions } from 'sql/base/browser/ui/table/highPerf/tableView'; -import { ScrollEvent } from 'vs/base/common/scrollable'; -import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; -import { DomEmitter } from 'vs/base/browser/event'; -import { KeyCode } from 'vs/base/common/keyCodes'; -import * as platform from 'vs/base/common/platform'; -import { IListStyles, IStyleController } from 'vs/base/browser/ui/list/listWidget'; -import { Color } from 'vs/base/common/color'; -import { getOrDefault } from 'vs/base/common/objects'; -import { isNumber } from 'vs/base/common/types'; -import { clamp } from 'vs/base/common/numbers'; -import { GridPosition } from 'sql/base/common/gridPosition'; -import { GridRange, IGridRange } from 'sql/base/common/gridRange'; -import { GlobalPointerMoveMonitor } from 'vs/base/browser/globalPointerMoveMonitor'; - -interface ITraitChangeEvent { - indexes: IGridRange[]; - browserEvent?: UIEvent; -} - -type ITraitTemplateData = HTMLElement; - -interface IRenderedContainer { - templateData: ITraitTemplateData; - index: GridPosition; -} - -class TraitRenderer implements ITableRenderer -{ - private renderedElements: IRenderedContainer[] = []; - - constructor(private trait: Trait) { } - - get templateId(): string { - return `template:${this.trait.trait}`; - } - - renderTemplate(container: HTMLElement): ITraitTemplateData { - return container; - } - - renderCell(element: T, row: number, cell: number, columnId: string, templateData: ITraitTemplateData): void { - const renderedElementIndex = this.renderedElements.findIndex(el => el.templateData === templateData); - - if (renderedElementIndex >= 0) { - const rendered = this.renderedElements[renderedElementIndex]; - this.trait.unrender(templateData); - rendered.index = new GridPosition(row, cell); - } else { - const rendered = { index: new GridPosition(row, cell), templateData }; - this.renderedElements.push(rendered); - } - - this.trait.renderIndex(new GridPosition(row, cell), templateData); - } - - renderIndexes(indexes: IGridRange[]): void { - for (const { index, templateData } of this.renderedElements) { - if (!!indexes.find(v => GridRange.containsPosition(v, index))) { - this.trait.renderIndex(index, templateData); - } - } - } - - disposeTemplate(templateData: ITraitTemplateData): void { - const index = this.renderedElements.findIndex(el => el.templateData === templateData); - - if (index < 0) { - return; - } - - this.renderedElements.splice(index, 1); - } -} - -class DOMFocusController implements IDisposable { - - private disposables: IDisposable[] = []; - - constructor( - private list: Table, - private view: TableView - ) { - const emitter = new DomEmitter(view.domNode, 'keydown'); - this.disposables.push(emitter); - const onKeyDown = Event.chain(emitter.event) - .map(e => new StandardKeyboardEvent(e)); - - onKeyDown.filter(e => e.keyCode === KeyCode.Tab && !e.ctrlKey && !e.metaKey && !e.shiftKey && !e.altKey) - .on(this.onTab, this, this.disposables); - } - - private onTab(e: StandardKeyboardEvent): void { - if (e.target !== this.view.domNode) { - return; - } - - const focus = this.list.getFocus(); - - if (focus.length === 0) { - return; - } - - const focusedDomElement = this.view.domElement(focus[0].startRow, focus[0].startColumn); - - if (!focusedDomElement) { - return; - } - - const tabIndexElement = focusedDomElement.querySelector('[tabIndex]'); - - if (!tabIndexElement || !(tabIndexElement instanceof HTMLElement) || tabIndexElement.tabIndex === -1) { - return; - } - - const style = window.getComputedStyle(tabIndexElement); - if (style.visibility === 'hidden' || style.display === 'none') { - return; - } - - e.preventDefault(); - e.stopPropagation(); - tabIndexElement.focus(); - } - - dispose() { - this.disposables = dispose(this.disposables); - } -} - -class Trait implements IDisposable { - - private indexes: Array = []; - private sortedIndexes: Array = []; - - private _onChange = new Emitter(); - get onChange(): Event { return this._onChange.event; } - - get trait(): string { return this._trait; } - - @memoize - get renderer(): TraitRenderer { - return new TraitRenderer(this); - } - - constructor(private _trait: string) { } - - renderIndex(index: GridPosition, container: HTMLElement): void { - container.classList.toggle(this._trait, this.contains(index)); - } - - unrender(container: HTMLElement): void { - container.classList.remove(this._trait); - } - - /** - * Sets the indexes which should have this trait. - * - * @param indexes Indexes which should have this trait. - * @return The old indexes which had this trait. - */ - set(indexes: Array, browserEvent?: UIEvent): Array { - return this._set(indexes, indexes, browserEvent); - } - - private _set(indexes: Array, sortedIndexes: Array, browserEvent?: UIEvent): Array { - const result = this.indexes; - const sortedResult = this.sortedIndexes; - - this.indexes = indexes; - this.sortedIndexes = sortedIndexes; - - // const toRender = disjunction(sortedResult, indexes); - this.renderer.renderIndexes(indexes.concat(sortedResult)); - - this._onChange.fire({ indexes, browserEvent }); - return result; - } - - get(): Array { - return this.indexes; - } - - contains(index: GridPosition): boolean { - return !!this.indexes.find(v => GridRange.containsPosition(v, index)); - } - - dispose() { - this._onChange = dispose(this._onChange); - } -} - -class FocusTrait extends Trait { - - constructor() { - super('focused'); - } - - override renderIndex(index: GridPosition, container: HTMLElement): void { - super.renderIndex(index, container); - - if (this.contains(index)) { - container.setAttribute('aria-selected', 'true'); - } else { - container.removeAttribute('aria-selected'); - } - } -} - -class PipelineRenderer implements ITableRenderer { - - constructor( - private renderers: ITableRenderer[] - ) { } - - renderTemplate(container: HTMLElement): any[] { - return this.renderers.map(r => r.renderTemplate(container)); - } - - renderCell(element: T, index: number, cell: number, columnId: string, templateData: any[], height: number | undefined): void { - let i = 0; - - for (const renderer of this.renderers) { - renderer.renderCell(element, index, cell, columnId, templateData[i++], height); - } - } - - disposeCell(element: T, index: number, cell: number, columnId: string, templateData: any[], height: number | undefined): void { - let i = 0; - - for (const renderer of this.renderers) { - if (renderer.disposeCell) { - renderer.disposeCell(element, index, cell, columnId, templateData[i], height); - } - - i += 1; - } - } - - disposeTemplate(templateData: any[]): void { - let i = 0; - - for (const renderer of this.renderers) { - renderer.disposeTemplate(templateData[i++]); - } - } -} - -export function isSelectionSingleChangeEvent(event: ITableMouseEvent): boolean { - return platform.isMacintosh ? event.browserEvent.metaKey : event.browserEvent.ctrlKey; -} - -export function isSelectionRangeChangeEvent(event: ITableMouseEvent): boolean { - return event.browserEvent.shiftKey; -} - -function isMouseRightClick(event: UIEvent): boolean { - return event instanceof MouseEvent && event.button === 2; -} - -const DefaultMultipleSelectionController = { - isSelectionSingleChangeEvent, - isSelectionRangeChangeEvent -}; - -export interface IOpenController { - shouldOpen(event: UIEvent): boolean; -} - -const DefaultOpenController: IOpenController = { - shouldOpen: (event: UIEvent) => { - if (event instanceof MouseEvent) { - return !isMouseRightClick(event); - } - - return true; - } -}; - -export interface IMultipleSelectionController { - isSelectionSingleChangeEvent(event: ITableMouseEvent): boolean; - isSelectionRangeChangeEvent(event: ITableMouseEvent): boolean; -} - -class RowCountRenderer implements IStaticTableRenderer { - renderTemplate(container: HTMLElement): HTMLElement { - return DOM.append(container, DOM.$('.row-count')); - } - - renderCell(element: undefined, index: number, ccell: number, olumnId: string, templateData: HTMLElement, width: number): void { - templateData.innerText = `${index}`; - } - - disposeTemplate(templateData: HTMLElement): void { - throw new Error('Method not implemented.'); - } -} - -const rowCountColumnDef: IStaticColumn = { - id: 'rowCount', - name: '', - renderer: new RowCountRenderer(), - cellClass: 'row-count-cell', - static: true, - width: 30, - resizeable: false -}; - -function rowCountFilter(column: ITableColumn): boolean { - return column.id !== rowCountColumnDef.id; -} - -class KeyboardController implements IDisposable { - - private disposables: IDisposable[] = []; - // private openController: IOpenController; - - constructor( - private table: Table, - private view: TableView, - options?: ITableOptions - ) { - // const multipleSelectionSupport = !(options.multipleSelectionSupport === false); - - // this.openController = options.openController || DefaultOpenController; - const emitter = new DomEmitter(view.domNode, 'keydown'); - this.disposables.push(emitter); - const onKeyDown = Event.chain(emitter.event) - // .filter(e => !isInputElement(e.target as HTMLElement)) - .map(e => new StandardKeyboardEvent(e)); - - onKeyDown.filter(e => e.keyCode === KeyCode.Enter).on(this.onEnter, this, this.disposables); - onKeyDown.filter(e => e.keyCode === KeyCode.UpArrow).on(this.onUpArrow, this, this.disposables); - onKeyDown.filter(e => e.keyCode === KeyCode.DownArrow).on(this.onDownArrow, this, this.disposables); - onKeyDown.filter(e => e.keyCode === KeyCode.LeftArrow).on(this.onLeftArrow, this, this.disposables); - onKeyDown.filter(e => e.keyCode === KeyCode.RightArrow).on(this.onRightArrow, this, this.disposables); - onKeyDown.filter(e => e.keyCode === KeyCode.PageUp).on(this.onPageUpArrow, this, this.disposables); - onKeyDown.filter(e => e.keyCode === KeyCode.PageDown).on(this.onPageDownArrow, this, this.disposables); - onKeyDown.filter(e => e.keyCode === KeyCode.Escape).on(this.onEscape, this, this.disposables); - - // if (multipleSelectionSupport) { - onKeyDown.filter(e => (platform.isMacintosh ? e.metaKey : e.ctrlKey) && e.keyCode === KeyCode.KeyA).on(this.onCtrlA, this, this.disposables); - // } - } - - private onEnter(e: StandardKeyboardEvent): void { - e.preventDefault(); - e.stopPropagation(); - this.table.setSelection(this.table.getFocus(), e.browserEvent); - - // if (this.openController.shouldOpen(e.browserEvent)) { - // this.list.open(this.list.getFocus(), e.browserEvent); - // } - } - - private onUpArrow(e: StandardKeyboardEvent): void { - e.preventDefault(); - e.stopPropagation(); - this.table.focusPreviousRow(1, false, e.browserEvent); - this.table.reveal(this.table.getFocus()[0].startRow); - this.view.domNode.focus(); - } - - private onDownArrow(e: StandardKeyboardEvent): void { - e.preventDefault(); - e.stopPropagation(); - this.table.focusNextRow(1, false, e.browserEvent); - this.table.reveal(this.table.getFocus()[0].startRow); - this.view.domNode.focus(); - } - - private onRightArrow(e: StandardKeyboardEvent): void { - e.preventDefault(); - e.stopPropagation(); - this.table.focusNextCell(1, false, e.browserEvent); - this.table.reveal(this.table.getFocus()[0].startRow); - this.view.domNode.focus(); - } - - private onLeftArrow(e: StandardKeyboardEvent): void { - e.preventDefault(); - e.stopPropagation(); - this.table.focusPreviousCell(1, false, e.browserEvent); - this.table.reveal(this.table.getFocus()[0].startRow); - this.view.domNode.focus(); - } - - private onPageUpArrow(e: StandardKeyboardEvent): void { - e.preventDefault(); - e.stopPropagation(); - // this.table.focusPreviousPage(e.browserEvent); - // this.table.reveal(this.table.getFocus()[0]); - this.view.domNode.focus(); - } - - private onPageDownArrow(e: StandardKeyboardEvent): void { - e.preventDefault(); - e.stopPropagation(); - // this.table.focusNextPage(e.browserEvent); - // this.table.reveal(this.table.getFocus()[0]); - this.view.domNode.focus(); - } - - private onCtrlA(e: StandardKeyboardEvent): void { - e.preventDefault(); - e.stopPropagation(); - // this.table.setSelection(range(this.table.length), e.browserEvent); - this.view.domNode.focus(); - } - - private onEscape(e: StandardKeyboardEvent): void { - e.preventDefault(); - e.stopPropagation(); - this.table.setSelection([], e.browserEvent); - this.view.domNode.focus(); - } - - dispose() { - this.disposables = dispose(this.disposables); - } -} - -export class MouseController implements IDisposable { - - private multipleSelectionSupport: boolean; - readonly multipleSelectionController?: IMultipleSelectionController; - private openController: IOpenController; - private disposables: IDisposable[] = []; - private readonly _mouseMoveMonitor = new GlobalPointerMoveMonitor>(); - - private startMouseEvent?: ITableMouseEvent; - - constructor(protected table: Table, protected view: TableView) { - this.multipleSelectionSupport = true; - - if (this.multipleSelectionSupport) { - this.multipleSelectionController = DefaultMultipleSelectionController; - } - - this.openController = DefaultOpenController; - - this.disposables.push(this._mouseMoveMonitor); - - table.onMouseDown(this.onMouseDown, this, this.disposables); - // table.onMouseClick(this.onPointer, this, this.disposables); - table.onContextMenu(this.onContextMenu, this, this.disposables); - } - - protected isSelectionSingleChangeEvent(event: ITableMouseEvent): boolean { - if (this.multipleSelectionController) { - return this.multipleSelectionController.isSelectionSingleChangeEvent(event); - } - - return platform.isMacintosh ? event.browserEvent.metaKey : event.browserEvent.ctrlKey; - } - - protected isSelectionRangeChangeEvent(event: ITableMouseEvent): boolean { - if (this.multipleSelectionController) { - return this.multipleSelectionController.isSelectionRangeChangeEvent(event); - } - - return event.browserEvent.shiftKey; - } - - private isSelectionChangeEvent(event: ITableMouseEvent): boolean { - return this.isSelectionSingleChangeEvent(event) || this.isSelectionRangeChangeEvent(event); - } - - private onMouseDown(e: ITableMouseEvent): void { - if (document.activeElement !== e.browserEvent.target) { - this.table.domFocus(); - } - const merger = (lastEvent: ITableMouseEvent | null, currentEvent: PointerEvent): ITableMouseEvent => { - return this.view.toMouseEvent(currentEvent); - }; - this._mouseMoveMonitor.startMonitoring(e.browserEvent.target as HTMLElement, e.browserEvent.pointerId, e.buttons, merger, e => this.onMouseMove(e), () => this.onMouseStop()); - this.onPointer(e); - } - - private onContextMenu(e: ITableContextMenuEvent): void { - const focus = typeof e.index === 'undefined' ? [] : [new GridRange(e.index.row, e.index.column)]; - this.table.setFocus(focus, e.browserEvent); - } - - protected onMouseMove(event: ITableMouseEvent): void { - if (event.index) { - this.startMouseEvent = this.startMouseEvent || event; - this.table.setSelection([new GridRange(this.startMouseEvent.index!.row, this.startMouseEvent.index!.column, event.index.row, event.index.column)]); - } - } - - protected onMouseStop(): void { - this.startMouseEvent = undefined; - } - - protected onPointer(e: ITableMouseEvent): void { - - let reference = this.table.getFocus(); - const selection = this.table.getSelection(); - reference = reference === undefined ? selection : reference; - - const focus = e.index; - - if (typeof focus === 'undefined') { - this.table.setFocus([], e.browserEvent); - this.table.setSelection([], e.browserEvent); - return; - } - - if (this.multipleSelectionSupport && this.isSelectionRangeChangeEvent(e)) { - return this.changeSelection(e, reference); - } - - if (this.multipleSelectionSupport && this.isSelectionChangeEvent(e)) { - return this.changeSelection(e, reference); - } - - this.table.setFocus([new GridRange(focus.row, focus.column)], e.browserEvent); - - if (!isMouseRightClick(e.browserEvent)) { - this.table.setSelection([new GridRange(focus.row, focus.column)], e.browserEvent); - - if (this.openController.shouldOpen(e.browserEvent)) { - // this.table.open([focus], e.browserEvent); - } - } - } - - private changeSelection(e: ITableMouseEvent, reference: IGridRange[] | undefined): void { - const focus = e.index!; - - if (this.isSelectionRangeChangeEvent(e) && reference !== undefined) { - const selection = this.table.getSelection(); - const lastSelection = selection.pop(); - if (lastSelection) { - this.table.setSelection([...selection, GridRange.plusRange(lastSelection, new GridRange(focus.row, focus.column))]); - } else { - this.table.setSelection([...selection, new GridRange(focus.row, focus.column)]); - } - } else if (this.isSelectionSingleChangeEvent(e)) { - const selection = this.table.getSelection(); - selection.push(new GridRange(focus.row, focus.column)); - this.table.setSelection(selection); - } - } - - dispose() { - this.disposables = dispose(this.disposables); - } -} - -export interface ITableOptions extends ITableViewOptions { - keyboardSupport?: boolean; - dnd?: boolean; -} - -export interface ITableStyles extends IListStyles { - cellOutlineColor?: Color; - tableHeaderAndRowCountColor?: Color; -} - -export class DefaultStyleController implements IStyleController { - - constructor(private styleElement: HTMLStyleElement, private selectorSuffix?: string) { } - - style(styles: ITableStyles): void { - const suffix = this.selectorSuffix ? `.${this.selectorSuffix}` : ''; - const content: string[] = []; - - if (styles.listFocusBackground) { - content.push(`.monaco-perftable${suffix}:focus .monaco-perftable-cell.focused { background-color: ${styles.listFocusBackground}; }`); - content.push(`.monaco-perftable${suffix}:focus .monaco-perftable-cell.focused:hover { background-color: ${styles.listFocusBackground}; }`); // overwrite :hover style in this case! - } - - if (styles.listFocusForeground) { - content.push(`.monaco-perftable${suffix}:focus .monaco-perftable-cell.focused { color: ${styles.listFocusForeground}; }`); - } - - if (styles.listActiveSelectionBackground) { - content.push(`.monaco-perftable${suffix}:focus .monaco-perftable-cell.selected { background-color: ${styles.listActiveSelectionBackground}; }`); - content.push(`.monaco-perftable${suffix}:focus .monaco-perftable-cell.selected:hover { background-color: ${styles.listActiveSelectionBackground}; }`); // overwrite :hover style in this case! - } - - if (styles.listActiveSelectionForeground) { - content.push(`.monaco-perftable${suffix}:focus .monaco-perftable-cell.selected { color: ${styles.listActiveSelectionForeground}; }`); - } - - if (styles.listFocusAndSelectionBackground) { - content.push(` - .monaco-drag-image, - .monaco-perftable${suffix}:focus .monaco-perftable-cell.selected.focused { background-color: ${styles.listFocusAndSelectionBackground}; } - `); - } - - if (styles.listFocusAndSelectionForeground) { - content.push(` - .monaco-drag-image, - .monaco-perftable${suffix}:focus .monaco-perftable-cell.selected.focused { color: ${styles.listFocusAndSelectionForeground}; } - `); - } - - if (styles.listInactiveFocusBackground) { - content.push(`.monaco-perftable${suffix} .monaco-perftable-cell.focused { background-color: ${styles.listInactiveFocusBackground}; }`); - content.push(`.monaco-perftable${suffix} .monaco-perftable-cell.focused:hover { background-color: ${styles.listInactiveFocusBackground}; }`); // overwrite :hover style in this case! - } - - if (styles.listInactiveSelectionBackground) { - content.push(`.monaco-perftable${suffix} .monaco-perftable-cell.selected { background-color: ${styles.listInactiveSelectionBackground}; }`); - content.push(`.monaco-perftable${suffix} .monaco-perftable-cell.selected:hover { background-color: ${styles.listInactiveSelectionBackground}; }`); // overwrite :hover style in this case! - } - - if (styles.listInactiveSelectionForeground) { - content.push(`.monaco-perftable${suffix} .monaco-perftable-cell.selected { color: ${styles.listInactiveSelectionForeground}; }`); - } - - if (styles.listHoverBackground) { - content.push(`.monaco-perftable${suffix}:not(.drop-target) .monaco-perftable-cell:hover:not(.selected):not(.focused) { background-color: ${styles.listHoverBackground}; }`); - } - - if (styles.listHoverForeground) { - content.push(`.monaco-perftable${suffix} .monaco-perftable-cell:hover:not(.selected):not(.focused) { color: ${styles.listHoverForeground}; }`); - } - - if (styles.listSelectionOutline) { - content.push(`.monaco-perftable${suffix} .monaco-perftable-cell.selected { outline: 1px dotted ${styles.listSelectionOutline}; outline-offset: -1px; }`); - } - - if (styles.listFocusOutline) { - content.push(` - .monaco-drag-image, - .monaco-perftable${suffix}:focus .monaco-perftable-cell.focused { outline: 1px solid ${styles.listFocusOutline}; outline-offset: -1px; } - `); - } - - if (styles.listInactiveFocusOutline) { - content.push(`.monaco-perftable${suffix} .monaco-perftable-cell.focused { outline: 1px dotted ${styles.listInactiveFocusOutline}; outline-offset: -1px; }`); - } - - if (styles.listHoverOutline) { - content.push(`.monaco-perftable${suffix} .monaco-perftable-cell:hover { outline: 1px dashed ${styles.listHoverOutline}; outline-offset: -1px; }`); - } - - if (styles.listDropBackground) { - content.push(` - .monaco-perftable${suffix}.drop-target, - .monaco-perftable${suffix} .monaco-perftable-cell.drop-target { background-color: ${styles.listDropBackground} !important; color: inherit !important; } - `); - } - - if (styles.listFilterWidgetBackground) { - content.push(`.monaco-perftable-type-filter { background-color: ${styles.listFilterWidgetBackground} }`); - } - - if (styles.listFilterWidgetOutline) { - content.push(`.monaco-perftable-type-filter { border: 1px solid ${styles.listFilterWidgetOutline}; }`); - } - - if (styles.listFilterWidgetNoMatchesOutline) { - content.push(`.monaco-perftable-type-filter.no-matches { border: 1px solid ${styles.listFilterWidgetNoMatchesOutline}; }`); - } - - if (styles.listMatchesShadow) { - content.push(`.monaco-perftable-type-filter { box-shadow: 1px 1px 1px ${styles.listMatchesShadow}; }`); - } - - if (styles.cellOutlineColor) { - content.push(`.monaco-perftable${suffix} .monaco-perftable-cell { border: 1px solid ${styles.cellOutlineColor}; }`); - content.push(`.monaco-perftable${suffix} .monaco-perftable-header-cell { border: 1px solid ${styles.cellOutlineColor}; }`); - } - - if (styles.tableHeaderAndRowCountColor) { - content.push(`.monaco-perftable${suffix} .monaco-perftable-header-cell { background-color: ${styles.tableHeaderAndRowCountColor}; }`); - content.push(`.monaco-perftable${suffix} .monaco-perftable-cell.row-count-cell { background-color: ${styles.tableHeaderAndRowCountColor}; }`); - } - - const newStyles = content.join('\n'); - if (newStyles !== this.styleElement.innerHTML) { - this.styleElement.innerHTML = newStyles; - } - } -} - -const DefaultOptions = { - rowCountColumn: true, -}; - -export class Table implements IDisposable { - - private focus: Trait; - private selection: Trait; - private eventBufferer = new EventBufferer(); - private view: TableView; - private styleElement: HTMLStyleElement; - private styleController: IStyleController; - - public inDrag = false; - - protected readonly disposables = new DisposableStore(); - - @memoize get onFocusChange(): Event> { - return Event.map(this.eventBufferer.wrapEvent(this.focus.onChange), e => this.toTableEvent(e)); - } - - @memoize get onSelectionChange(): Event> { - return Event.map(this.eventBufferer.wrapEvent(this.selection.onChange), e => this.toTableEvent(e)); - } - - private toTableEvent({ indexes, browserEvent }: ITraitChangeEvent) { - return { indexes, elements: indexes.map(i => this.view.element(i.startRow)!), browserEvent }; - } - - get onDidScroll(): Event { return this.view.onDidScroll; } - get onMouseClick(): Event> { return this.view.onMouseClick; } - get onMouseDblClick(): Event> { return this.view.onMouseDblClick; } - get onMouseMiddleClick(): Event> { return this.view.onMouseMiddleClick; } - get onMouseUp(): Event> { return this.view.onMouseUp; } - get onMouseDown(): Event> { return this.view.onMouseDown; } - get onMouseOver(): Event> { return this.view.onMouseOver; } - get onMouseMove(): Event> { return this.view.onMouseMove; } - get onMouseOut(): Event> { return this.view.onMouseOut; } - - private didJustPressContextMenuKey: boolean = false; - @memoize get onContextMenu(): Event> { - const fromKeydown = Event.chain(this.disposables.add(new DomEmitter(this.view.domNode, 'keydown')).event) - .map(e => new StandardKeyboardEvent(e)) - .filter(e => this.didJustPressContextMenuKey = e.keyCode === KeyCode.ContextMenu || (e.shiftKey && e.keyCode === KeyCode.F10)) - .filter(e => { e.preventDefault(); e.stopPropagation(); return false; }) - .event as Event; - - const fromKeyup = Event.chain(this.disposables.add(new DomEmitter(this.view.domNode, 'keyup')).event) - .filter(() => { - const didJustPressContextMenuKey = this.didJustPressContextMenuKey; - this.didJustPressContextMenuKey = false; - return didJustPressContextMenuKey; - }) - .filter(() => this.getFocus().length > 0 && !!this.view.domElement(this.getFocus()[0].startRow, this.getFocus()[0].startColumn)) - .map(browserEvent => { - const index = this.getFocus()[0]; - const element = this.view.element(index.startRow); - const anchor = this.view.domElement(index.startRow, index.startColumn) as HTMLElement; - return { index: GridRange.lift(index).getStartPosition(), element, anchor, browserEvent }; - }) - .event; - - const fromMouse = Event.chain(this.view.onContextMenu) - .filter(() => !this.didJustPressContextMenuKey) - .map(({ element, index, browserEvent }) => ({ element, index, anchor: { x: browserEvent.clientX + 1, y: browserEvent.clientY }, browserEvent })) - .event; - - return Event.any>(fromKeydown, fromKeyup, fromMouse); - } - - get onKeyDown(): Event { return this.disposables.add(new DomEmitter(this.view.domNode, 'keydown')).event; } - get onKeyUp(): Event { return this.disposables.add(new DomEmitter(this.view.domNode, 'keyup')).event; } - get onKeyPress(): Event { return this.disposables.add(new DomEmitter(this.view.domNode, 'keypress')).event; } - - readonly onDidFocus: Event; - readonly onDidBlur: Event; - - private readonly _onDidDispose = new Emitter(); - readonly onDidDispose: Event = this._onDidDispose.event; - - constructor( - private readonly user: string, - container: HTMLElement, - columns: ITableColumn[], - dataSource: ITableDataSource, - options: ITableOptions = DefaultOptions - ) { - this.focus = new FocusTrait(); - this.selection = new Trait('selected'); - - const baseRenderers: ITableRenderer[] = [this.focus.renderer, this.selection.renderer]; - - columns = columns.map(r => { - r.renderer = new PipelineRenderer([...baseRenderers, r.renderer]); - return r; - }); - - options.rowCountColumn = getOrDefault(options, o => o.rowCountColumn, DefaultOptions.rowCountColumn); - - if (options.rowCountColumn) { - columns.unshift(rowCountColumnDef); - } - - this.view = new TableView(container, columns, dataSource, options); - - this.view.domNode.setAttribute('aria-multiselectable', 'true'); - - this.styleElement = DOM.createStyleSheet(this.view.domNode); - - this.styleController = new DefaultStyleController(this.styleElement, this.view.domId); - - this.disposables.add(new DOMFocusController(this, this.view)); - - if (!options || typeof options.keyboardSupport !== 'boolean' || options.keyboardSupport) { - const controller = new KeyboardController(this, this.view, options); - this.disposables.add(controller); - } - - this.onDidFocus = Event.map(this.disposables.add(new DomEmitter(this.view.domNode, 'focus', true)).event, () => null!); - this.onDidBlur = Event.map(this.disposables.add(new DomEmitter(this.view.domNode, 'blur', true)).event, () => null!); - - this.disposables.add(this.createMouseController()); - - this.onFocusChange(this._onFocusChange, this, this.disposables); - this.onSelectionChange(this._onSelectionChange, this, this.disposables); - } - - protected createMouseController(): MouseController { - return new MouseController(this, this.view); - } - - get length(): number { - return this.view.length; - } - - set length(length: number) { - this.view.length = length; - } - - get columnLength(): number { - return this.view.columnLength; - } - - layout(height?: number, width?: number): void { - this.view.layout(height, width); - } - - domFocus(): void { - this.view.domNode.focus(); - } - - setSelection(indexes: IGridRange[], browserEvent?: UIEvent): void { - // for (const index of indexes) { - // if (index < 0 || index >= this.length) { - // throw new Error(`Invalid index ${index}`); - // } - // } - - this.selection.set(indexes, browserEvent); - } - - getSelection(): IGridRange[] { - return this.selection.get(); - } - - setFocus(indexes: IGridRange[], browserEvent?: UIEvent): void { - // for (const index of indexes) { - // if (index < 0 || index >= this.length) { - // throw new Error(`Invalid index ${index}`); - // } - // } - - this.focus.set(indexes, browserEvent); - this.selection.set(indexes, browserEvent); - } - - reveal(index: number, relativeTop?: number): void { - if (index < 0 || index >= this.length) { - throw new TableError(this.user, `Invalid index ${index}`); - } - - const scrollTop = this.view.getScrollTop(); - const elementTop = this.view.elementTop(index); - const elementHeight = this.view.rowHeight; - - if (isNumber(relativeTop)) { - // y = mx + b - const m = elementHeight - this.view.renderHeight; - this.view.setScrollTop(m * clamp(relativeTop, 0, 1) + elementTop); - } else { - const viewItemBottom = elementTop + elementHeight; - const wrapperBottom = scrollTop + this.view.renderHeight; - - if (elementTop < scrollTop) { - this.view.setScrollTop(elementTop); - } else if (viewItemBottom >= wrapperBottom) { - this.view.setScrollTop(viewItemBottom - this.view.renderHeight); - } - } - } - - - focusNextCell(n = 1, loop = false, browserEvent?: UIEvent, filter: (column: ITableColumn) => boolean = rowCountFilter): void { - if (this.length === 0) { return; } - - const focus = this.focus.get(); - const cellIndex = focus.length > 0 ? focus[0].startColumn! : 0; - const targetColumn = this.findNextColumn(cellIndex + n, loop, filter); - const targetRow = focus.length > 0 ? focus[0].startRow : 0; - - if (targetColumn > -1) { - this.setFocus([new GridRange(targetRow, targetColumn)], browserEvent); - } - } - - focusPreviousCell(n = 1, loop = false, browserEvent?: UIEvent, filter: (column: ITableColumn) => boolean = rowCountFilter): void { - if (this.length === 0) { return; } - - const focus = this.focus.get(); - const cellIndex = focus.length > 0 ? focus[0].startColumn! : 0; - const targetColumn = this.findPreviousColumn(cellIndex - n, loop, filter); - const targetRow = focus.length > 0 ? focus[0].startRow : 0; - - if (targetColumn > -1) { - this.setFocus([new GridRange(targetRow, targetColumn)], browserEvent); - } - } - - focusNextRow(n = 1, loop = false, browserEvent?: UIEvent, filter?: (element: T) => boolean): void { - if (this.length === 0) { return; } - - const focus = this.focus.get(); - const index = this.findNextRowIndex(focus.length > 0 ? focus[0].startRow + n : 0, loop, filter); - - const targetColumn = focus.length > 0 ? focus[0].startColumn : 0; - - if (index > -1) { - this.setFocus([new GridRange(index, targetColumn)], browserEvent); - } - } - - focusPreviousRow(n = 1, loop = false, browserEvent?: UIEvent, filter?: (element: T) => boolean): void { - if (this.length === 0) { return; } - - const focus = this.focus.get(); - const index = this.findPreviousRowIndex(focus.length > 0 ? focus[0].startRow - n : 0, loop, filter); - - const targetColumn = focus.length > 0 ? focus[0].startColumn : 0; - - if (index > -1) { - this.setFocus([new GridRange(index, targetColumn)], browserEvent); - } - } - - private findNextColumn(index: number, loop = false, filter?: (column: ITableColumn) => boolean): number { - for (let i = 0; i < this.columnLength; i++) { - if (index >= this.columnLength && !loop) { - return -1; - } - - index = index % this.columnLength; - - if (!filter || filter(this.view.column(index)!)) { - return index; - } - - index++; - } - - return -1; - } - - private findPreviousColumn(index: number, loop = false, filter?: (column: ITableColumn) => boolean): number { - for (let i = 0; i < this.columnLength; i++) { - if (index < 0 && !loop) { - return -1; - } - - index = (this.columnLength + (index % this.columnLength)) % this.columnLength; - - if (!filter || filter(this.view.column(index)!)) { - return index; - } - - index--; - } - - return -1; - } - - private findNextRowIndex(index: number, loop = false, filter?: (element: T) => boolean): number { - for (let i = 0; i < this.length; i++) { - if (index >= this.length && !loop) { - return -1; - } - - index = index % this.length; - - // if (!filter || filter(this.view.element(index))) { - return index; - // } - } - - return -1; - } - - private findPreviousRowIndex(index: number, loop = false, filter?: (element: T) => boolean): number { - for (let i = 0; i < this.length; i++) { - if (index < 0 && !loop) { - return -1; - } - - index = (this.length + (index % this.length)) % this.length; - - // if (!filter || filter(this.view.element(index))) { - return index; - // - } - - return -1; - } - - getFocus(): Array { - return this.focus.get(); - } - - style(styles: ITableStyles): void { - this.styleController.style(styles); - } - - getHTMLElement(): HTMLElement { - return this.view.domNode; - } - - private _onFocusChange(): void { - const focus = this.focus.get(); - - if (focus.length > 0) { - this.view.domNode.setAttribute('aria-activedescendant', this.view.getElementDomId(focus[0].startRow, focus[0].startColumn)); - } else { - this.view.domNode.removeAttribute('aria-activedescendant'); - } - - this.view.domNode.setAttribute('role', 'tree'); - this.view.domNode.classList.toggle('element-focused', focus.length > 0); - } - - private _onSelectionChange(): void { - const selection = this.selection.get(); - - this.view.domNode.classList.toggle('selection-none', selection.length === 0); - this.view.domNode.classList.toggle('selection-single', selection.length === 1); - this.view.domNode.classList.toggle('selection-multiple', selection.length > 1); - } - - dispose(): void { - this._onDidDispose.fire(); - this.disposables.dispose(); - - this._onDidDispose.dispose(); - } -} diff --git a/src/sql/base/browser/ui/table/highPerf/virtualizedWindow.ts b/src/sql/base/browser/ui/table/highPerf/virtualizedWindow.ts deleted file mode 100644 index da91941260..0000000000 --- a/src/sql/base/browser/ui/table/highPerf/virtualizedWindow.ts +++ /dev/null @@ -1,155 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async'; - -class DataWindow { - private _data: T[] | undefined; - private _length: number = 0; - private _offsetFromDataSource: number = -1; - - private dataReady?: CancelablePromise; - - constructor( - private loadFunction: (offset: number, count: number) => Promise - ) { } - - dispose() { - this._data = undefined; - if (this.dataReady) { - this.dataReady.cancel(); - } - } - - get start(): number { - return this._offsetFromDataSource; - } - - get end(): number { - return this._offsetFromDataSource + this._length; - } - - get length(): number { - return this._length; - } - - public contains(dataSourceIndex: number): boolean { - return dataSourceIndex >= this.start && dataSourceIndex < this.end; - } - - public getItem(index: number): Promise { - return this.dataReady!.then(() => this._data![index - this._offsetFromDataSource]); - } - - public positionWindow(offset: number, length: number): void { - this._offsetFromDataSource = offset; - this._length = length; - this._data = undefined; - - if (this.dataReady) { - this.dataReady.cancel(); - } - - if (length === 0) { - return; - } - - this.dataReady = createCancelablePromise(token => { - return this.loadFunction(offset, length).then(data => { - if (!token.isCancellationRequested) { - this._data = data; - } - }); - }); - } -} - -export class VirtualizedWindow { - private _bufferWindowBefore: DataWindow; - private _window: DataWindow; - private _bufferWindowAfter: DataWindow; - - constructor( - private readonly windowSize: number, - private _length: number, - loadFn: (offset: number, count: number) => Promise - ) { - - this._bufferWindowBefore = new DataWindow(loadFn); - this._window = new DataWindow(loadFn); - this._bufferWindowAfter = new DataWindow(loadFn); - } - - dispose() { - this._bufferWindowAfter.dispose(); - this._bufferWindowBefore.dispose(); - this._window.dispose(); - } - - get length(): number { - return this._length; - } - - set length(length: number) { - if (this.length !== length) { - const oldLength = this.length; - this._length = length; - if (this._window.length !== this.windowSize) { - this.resetWindowsAroundIndex(oldLength); - } else if (this._bufferWindowAfter.length !== this.windowSize) { - this._bufferWindowAfter.positionWindow(this._bufferWindowAfter.start, Math.min(this._bufferWindowAfter.start + this.windowSize, this.length)); - } - } - } - - public getIndex(index: number): Promise { - - if (index < this._bufferWindowBefore.start || index >= this._bufferWindowAfter.end) { - this.resetWindowsAroundIndex(index); - } - // scrolling up - else if (this._bufferWindowBefore.contains(index)) { - const beforeWindow = this._bufferWindowAfter; - this._bufferWindowAfter = this._window; - this._window = this._bufferWindowBefore; - this._bufferWindowBefore = beforeWindow; - // ensure we aren't buffer invalid data - const beforeStart = Math.max(0, this._window.start - this.windowSize); - // ensure if we got hinder in our start index that we update out length to not overlap - const beforeLength = this._window.start - beforeStart; - this._bufferWindowBefore.positionWindow(beforeStart, beforeLength); - } - // scroll down - else if (this._bufferWindowAfter.contains(index)) { - const afterWindow = this._bufferWindowBefore; - this._bufferWindowBefore = this._window; - this._window = this._bufferWindowAfter; - this._bufferWindowAfter = afterWindow; - // ensure we aren't buffer invalid data - const afterStart = this._window.end; - // ensure if we got hinder in our start index that we update out length to not overlap - const afterLength = afterStart + this.windowSize > this.length ? this.length - afterStart : this.windowSize; - this._bufferWindowAfter.positionWindow(afterStart, afterLength); - } - - // at this point we know the current window will have the index - return this._window.getItem(index); - } - - private resetWindowsAroundIndex(index: number): void { - - let bufferWindowBeforeStart = Math.max(0, index - this.windowSize * 1.5); - let bufferWindowBeforeEnd = Math.max(0, index - this.windowSize / 2); - this._bufferWindowBefore.positionWindow(bufferWindowBeforeStart, bufferWindowBeforeEnd - bufferWindowBeforeStart); - - let mainWindowStart = bufferWindowBeforeEnd; - let mainWindowEnd = Math.min(mainWindowStart + this.windowSize, this.length); - this._window.positionWindow(mainWindowStart, mainWindowEnd - mainWindowStart); - - let bufferWindowAfterStart = mainWindowEnd; - let bufferWindowAfterEnd = Math.min(bufferWindowAfterStart + this.windowSize, this.length); - this._bufferWindowAfter.positionWindow(bufferWindowAfterStart, bufferWindowAfterEnd - bufferWindowAfterStart); - } -} diff --git a/src/sql/base/browser/ui/table/utils.ts b/src/sql/base/browser/ui/table/utils.ts deleted file mode 100644 index 1cb5cee2aa..0000000000 --- a/src/sql/base/browser/ui/table/utils.ts +++ /dev/null @@ -1,10 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -export function defaultFormatter(valueProperty: keyof T): Slick.Formatter { - return (row: number, cell: number, value: any, columnDef: Slick.Column, dataContext: Slick.SlickData): string => { - return value[valueProperty]; - }; -} diff --git a/src/sql/base/common/numbers.ts b/src/sql/base/common/numbers.ts deleted file mode 100644 index 4607bf2319..0000000000 --- a/src/sql/base/common/numbers.ts +++ /dev/null @@ -1,8 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -export function isNumber(text: string): boolean { - return !isNaN(parseInt(text)) && !isNaN(parseFloat(text)); -} diff --git a/src/sql/base/parts/tree/browser/treeUtils.ts b/src/sql/base/parts/tree/browser/treeUtils.ts deleted file mode 100644 index 51ea627d7e..0000000000 --- a/src/sql/base/parts/tree/browser/treeUtils.ts +++ /dev/null @@ -1,18 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as _ from 'sql/base/parts/tree/browser/tree'; - -export function isEqualOrParent(tree: _.ITree, element: any, candidateParent: any): boolean { - const nav = tree.getNavigator(element); - - do { - if (element === candidateParent) { - return true; - } - } while (element = nav.parent()); // eslint-disable-line no-cond-assign - - return false; -} diff --git a/src/sql/base/parts/tree/test/browser/treeModel.test.ts b/src/sql/base/parts/tree/test/browser/treeModel.test.ts index aed4eaf69b..35cd92c93f 100644 --- a/src/sql/base/parts/tree/test/browser/treeModel.test.ts +++ b/src/sql/base/parts/tree/test/browser/treeModel.test.ts @@ -11,7 +11,7 @@ import * as TreeDefaults from 'sql/base/parts/tree/browser/treeDefaults'; import { Event, Emitter } from 'vs/base/common/event'; import { timeout } from 'vs/base/common/async'; -export class FakeRenderer { +class FakeRenderer { public getHeight(tree: _.ITree, element: any): number { return 20; diff --git a/src/sql/platform/table/browser/tableService.ts b/src/sql/platform/table/browser/tableService.ts deleted file mode 100644 index 6743753ef8..0000000000 --- a/src/sql/platform/table/browser/tableService.ts +++ /dev/null @@ -1,205 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { Table, DefaultStyleController, ITableOptions } from 'sql/base/browser/ui/table/highPerf/tableWidget'; -import { RawContextKey, IContextKey, ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { DisposableStore, IDisposable, combinedDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { createStyleSheet } from 'vs/base/browser/dom'; -import { attachHighPerfTableStyler as attachTableStyler, defaultHighPerfTableStyles, IHighPerfTableStyleOverrides } from 'sql/platform/theme/common/styler'; -import { InputFocusedContextKey } from 'vs/platform/contextkey/common/contextkeys'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { ITableDataSource, ITableColumn } from 'sql/base/browser/ui/table/highPerf/table'; -import { computeStyles } from 'vs/platform/theme/common/styler'; -import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; - -export const ITableService = createDecorator('tableService'); - -export type TableWidget = Table; - -export interface ITableService { - - _serviceBrand: undefined; - - /** - * Returns the currently focused table widget if any. - */ - readonly lastFocusedTable: TableWidget | undefined; -} - -interface IRegisteredTable { - widget: TableWidget; - extraContextKeys?: (IContextKey)[]; -} - -export class TableService implements ITableService { - - _serviceBrand: undefined; - - private disposables = new DisposableStore(); - private tables: IRegisteredTable[] = []; - private _lastFocusedWidget: TableWidget | undefined = undefined; - - get lastFocusedTable(): TableWidget | undefined { - return this._lastFocusedWidget; - } - - constructor(@IThemeService themeService: IThemeService) { - // create a shared default tree style sheet for performance reasons - const styleController = new DefaultStyleController(createStyleSheet(), ''); - this.disposables.add(attachTableStyler(styleController, themeService)); - } - - register(widget: TableWidget, extraContextKeys?: (IContextKey)[]): IDisposable { - if (this.tables.some(l => l.widget === widget)) { - throw new Error('Cannot register the same widget multiple times'); - } - - // Keep in our tables table - const registeredTable: IRegisteredTable = { widget, extraContextKeys }; - this.tables.push(registeredTable); - - // Check for currently being focused - if (widget.getHTMLElement() === document.activeElement) { - this._lastFocusedWidget = widget; - } - - return combinedDisposable( - widget.onDidFocus(() => this._lastFocusedWidget = widget), - toDisposable(() => this.tables.splice(this.tables.indexOf(registeredTable), 1)), - widget.onDidDispose(() => { - this.tables = this.tables.filter(l => l !== registeredTable); - if (this._lastFocusedWidget === widget) { - this._lastFocusedWidget = undefined; - } - }) - ); - } - - dispose(): void { - this.disposables.dispose(); - } -} - -const RawWorkbenchTableFocusContextKey = new RawContextKey('tableFocus', true); -export const WorkbenchTableFocusContextKey = ContextKeyExpr.and(RawWorkbenchTableFocusContextKey, ContextKeyExpr.not(InputFocusedContextKey)); -export const WorkbenchTableHasSelectionOrFocus = new RawContextKey('tableHasSelectionOrFocus', false); -export const WorkbenchTableDoubleSelection = new RawContextKey('tableDoubleSelection', false); -export const WorkbenchTableMultiSelection = new RawContextKey('tableMultiSelection', false); -export const WorkbenchTableSupportsKeyboardNavigation = new RawContextKey('tableSupportsKeyboardNavigation', true); -export const WorkbenchTableAutomaticKeyboardNavigationKey = 'tableAutomaticKeyboardNavigation'; -export const WorkbenchTableAutomaticKeyboardNavigation = new RawContextKey(WorkbenchTableAutomaticKeyboardNavigationKey, true); -export let didBindWorkbenchTableAutomaticKeyboardNavigation = false; - -function createScopedContextKeyService(contextKeyService: IContextKeyService, widget: TableWidget): IContextKeyService { - const result = contextKeyService.createScoped(widget.getHTMLElement()); - RawWorkbenchTableFocusContextKey.bindTo(result); - return result; -} - -export const multiSelectModifierSettingKey = 'workbench.table.multiSelectModifier'; -export const openModeSettingKey = 'workbench.table.openMode'; -export const horizontalScrollingKey = 'workbench.table.horizontalScrolling'; -export const keyboardNavigationSettingKey = 'workbench.table.keyboardNavigation'; -export const automaticKeyboardNavigationSettingKey = 'workbench.table.automaticKeyboardNavigation'; - -function useAltAsMultipleSelectionModifier(configurationService: IConfigurationService): boolean { - return configurationService.getValue(multiSelectModifierSettingKey) === 'alt'; -} - -function toWorkbenchTableOptions(options: ITableOptions): [ITableOptions, IDisposable] { - const disposables = new DisposableStore(); - const result = { ...options }; - - return [result, disposables]; -} - -export interface IWorkbenchTableOptions extends ITableOptions { - readonly overrideStyles?: IHighPerfTableStyleOverrides; -} - -export class WorkbenchTable extends Table { - - readonly contextKeyService: IContextKeyService; - private readonly configurationService: IConfigurationService; - - private tableHasSelectionOrFocus: IContextKey; - private tableDoubleSelection: IContextKey; - private tableMultiSelection: IContextKey; - - private _useAltAsMultipleSelectionModifier: boolean; - - constructor( - user: string, - container: HTMLElement, - columns: ITableColumn[], - dataSource: ITableDataSource, - options: IWorkbenchTableOptions, - @IContextKeyService contextKeyService: IContextKeyService, - @ITableService tableService: ITableService, - @IThemeService themeService: IThemeService, - @IConfigurationService configurationService: IConfigurationService - ) { - const [workbenchTableOptions, workbenchTableOptionsDisposable] = toWorkbenchTableOptions(options); - - super(user, container, columns, dataSource, - { - keyboardSupport: false, - ...computeStyles(themeService.getColorTheme(), defaultHighPerfTableStyles), - ...workbenchTableOptions - } - ); - - this.disposables.add(workbenchTableOptionsDisposable); - - this.contextKeyService = createScopedContextKeyService(contextKeyService, this); - this.configurationService = configurationService; - - this.tableHasSelectionOrFocus = WorkbenchTableHasSelectionOrFocus.bindTo(this.contextKeyService); - this.tableDoubleSelection = WorkbenchTableDoubleSelection.bindTo(this.contextKeyService); - this.tableMultiSelection = WorkbenchTableMultiSelection.bindTo(this.contextKeyService); - - this._useAltAsMultipleSelectionModifier = useAltAsMultipleSelectionModifier(configurationService); - - this.disposables.add(this.contextKeyService); - this.disposables.add((tableService as TableService).register(this)); - - if (options.overrideStyles) { - this.disposables.add(attachTableStyler(this, themeService, options.overrideStyles)); - } - - this.disposables.add(this.onSelectionChange(() => { - const selection = this.getSelection(); - const focus = this.getFocus(); - - this.tableHasSelectionOrFocus.set(selection.length > 0 || focus.length > 0); - this.tableMultiSelection.set(selection.length > 1); - this.tableDoubleSelection.set(selection.length === 2); - })); - this.disposables.add(this.onFocusChange(() => { - const selection = this.getSelection(); - const focus = this.getFocus(); - - this.tableHasSelectionOrFocus.set(selection.length > 0 || focus.length > 0); - })); - - this.registerListeners(); - } - - private registerListeners(): void { - this.disposables.add(this.configurationService.onDidChangeConfiguration(e => { - if (e.affectsConfiguration(multiSelectModifierSettingKey)) { - this._useAltAsMultipleSelectionModifier = useAltAsMultipleSelectionModifier(this.configurationService); - } - })); - } - - get useAltAsMultipleSelectionModifier(): boolean { - return this._useAltAsMultipleSelectionModifier; - } -} - -registerSingleton(ITableService, TableService, true); diff --git a/src/sql/workbench/browser/modal/calloutDialog.ts b/src/sql/workbench/browser/modal/calloutDialog.ts deleted file mode 100644 index 66d8f91b08..0000000000 --- a/src/sql/workbench/browser/modal/calloutDialog.ts +++ /dev/null @@ -1,59 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * 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/calloutDialog'; -import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys'; -import { IDialogProperties, Modal, DialogWidth, DialogPosition } from 'sql/workbench/browser/modal/modal'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { ILogService } from 'vs/platform/log/common/log'; -import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry'; -import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; -import { ITextResourcePropertiesService } from 'vs/editor/common/services/textResourceConfiguration'; - -export abstract class CalloutDialog extends Modal { - - constructor( - title: string, - width: DialogWidth, - dialogProperties: IDialogProperties, - dialogPosition: DialogPosition, - @IThemeService themeService: IThemeService, - @ILayoutService layoutService: ILayoutService, - @IAdsTelemetryService telemetryService: IAdsTelemetryService, - @IContextKeyService contextKeyService: IContextKeyService, - @IClipboardService clipboardService: IClipboardService, - @ILogService logService: ILogService, - @ITextResourcePropertiesService textResourcePropertiesService: ITextResourcePropertiesService - ) { - super( - title, - TelemetryKeys.ModalDialogName.CalloutDialog, - telemetryService, - layoutService, - clipboardService, - themeService, - logService, - textResourcePropertiesService, - contextKeyService, - { - dialogStyle: 'callout', - dialogPosition: dialogPosition, - dialogProperties: dialogProperties, - width: width - }); - } - - public abstract open(): Promise; - - public cancel(): void { - this.hide('cancel'); - this.dispose(); - } - - protected layout(height?: number): void { - } -} diff --git a/src/sql/workbench/contrib/dashboard/browser/widgets/properties/propertiesJson.ts b/src/sql/workbench/contrib/dashboard/browser/widgets/properties/propertiesJson.ts deleted file mode 100644 index 8cb931cb78..0000000000 --- a/src/sql/workbench/contrib/dashboard/browser/widgets/properties/propertiesJson.ts +++ /dev/null @@ -1,144 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { ProviderProperties } from 'sql/workbench/contrib/dashboard/browser/dashboardRegistry'; -import * as nls from 'vs/nls'; -import { mssqlProviderName } from 'sql/platform/connection/common/constants'; - -const azureEditionDisplayName = nls.localize('azureEdition', "Edition"); -const azureType = nls.localize('azureType', "Type"); - -export const properties: Array = [ - { - provider: mssqlProviderName, - flavors: [ - { - flavor: 'on_prem', - conditions: [ - { - field: 'isCloud', - operator: '!=', - value: true - } - ], - databaseProperties: [ - { - displayName: nls.localize('recoveryModel', "Recovery Model"), - value: 'recoveryModel' - }, - { - displayName: nls.localize('lastDatabaseBackup', "Last Database Backup"), - value: 'lastBackupDate', - ignore: [ - '1/1/0001 12:00:00 AM' - ] - }, - { - displayName: nls.localize('lastLogBackup', "Last Log Backup"), - value: 'lastLogBackupDate', - ignore: [ - '1/1/0001 12:00:00 AM' - ] - }, - { - displayName: nls.localize('compatibilityLevel', "Compatibility Level"), - value: 'compatibilityLevel' - }, - { - displayName: nls.localize('owner', "Owner"), - value: 'owner' - } - ], - serverProperties: [ - { - displayName: nls.localize('version', "Version"), - value: 'serverVersion' - }, - { - displayName: nls.localize('edition', "Edition"), - value: 'serverEdition' - }, - { - displayName: nls.localize('computerName', "Computer Name"), - value: 'machineName' - }, - { - displayName: nls.localize('osVersion', "OS Version"), - value: 'osVersion' - } - ] - }, - { - flavor: 'cloud', - conditions: [ - { - field: 'isCloud', - operator: '==', - value: true - }, - { - field: 'engineEditionId', - operator: '!=', - value: '11' - } - ], - databaseProperties: [ - { - displayName: azureEditionDisplayName, - value: 'azureEdition' - }, - { - displayName: nls.localize('serviceLevelObjective', "Pricing Tier"), - value: 'serviceLevelObjective' - }, - { - displayName: nls.localize('compatibilityLevel', "Compatibility Level"), - value: 'compatibilityLevel' - }, - { - displayName: nls.localize('owner', "Owner"), - value: 'owner' - } - ], - serverProperties: [ - { - displayName: nls.localize('version', "Version"), - value: 'serverVersion' - }, - { - displayName: azureType, - value: 'serverEdition' - } - ] - }, - { - flavor: 'on_demand', - conditions: [ - { - field: 'engineEditionId', - operator: '==', - value: '11' - } - ], - databaseProperties: [ - { - displayName: nls.localize('compatibilityLevel', "Compatibility Level"), - value: 'compatibilityLevel' - } - ], - serverProperties: [ - { - displayName: nls.localize('version', "Version"), - value: 'serverVersion' - }, - { - displayName: azureType, - value: 'serverEdition' - } - ] - } - ] - } -]; diff --git a/src/sql/workbench/contrib/notebook/browser/notebookViews/notebookViewsOptionsModal.ts b/src/sql/workbench/contrib/notebook/browser/notebookViews/notebookViewsOptionsModal.ts deleted file mode 100644 index a2d903f107..0000000000 --- a/src/sql/workbench/contrib/notebook/browser/notebookViews/notebookViewsOptionsModal.ts +++ /dev/null @@ -1,141 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -import { Button } from 'sql/base/browser/ui/button/button'; -import { IClipboardService } from 'sql/platform/clipboard/common/clipboardService'; -import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry'; -import { Modal } from 'sql/workbench/browser/modal/modal'; -import { attachModalDialogStyler } from 'sql/workbench/common/styler'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; -import { ILogService } from 'vs/platform/log/common/log'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; -import * as DOM from 'vs/base/browser/dom'; -import { attachInputBoxStyler } from 'sql/platform/theme/common/styler'; -import { localize } from 'vs/nls'; -import { IInputOptions, MessageType } from 'vs/base/browser/ui/inputbox/inputBox'; -import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox'; -import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; -import { INotebookView } from 'sql/workbench/services/notebook/browser/notebookViews/notebookViews'; -import { attachButtonStyler } from 'vs/platform/theme/common/styler'; -import { ITextResourcePropertiesService } from 'vs/editor/common/services/textResourceConfiguration'; - -export class ViewOptionsModal extends Modal { - private _submitButton: Button; - private _cancelButton: Button; - private _viewNameInput: InputBox; - - constructor( - private _view: INotebookView, - @ILogService logService: ILogService, - @IThemeService themeService: IThemeService, - @ILayoutService layoutService: ILayoutService, - @IClipboardService clipboardService: IClipboardService, - @IContextKeyService contextKeyService: IContextKeyService, - @IAdsTelemetryService telemetryService: IAdsTelemetryService, - @IContextViewService private _contextViewService: IContextViewService, - @ITextResourcePropertiesService textResourcePropertiesService: ITextResourcePropertiesService, - ) { - super( - localize("viewOptionsModal.title", "Configure View"), - 'ViewOptionsModal', - telemetryService, - layoutService, - clipboardService, - themeService, - logService, - textResourcePropertiesService, - contextKeyService, - { hasErrors: true, hasSpinner: true } - ); - } - - protected renderBody(container: HTMLElement): void { - const formWrapper = DOM.$('div#notebookviews-options-form'); - formWrapper.style.padding = '10px'; - - DOM.append(container, formWrapper); - - this._viewNameInput = this.createNameInput(formWrapper); - - } - - protected layout(height: number): void { - - } - - protected createNameInput(container: HTMLElement): InputBox { - return this.createInputBoxHelper(container, localize('viewOptionsModal.name', "View Name"), this._view.name, { - validationOptions: { - validation: (value: string) => { - if (!value) { - return ({ type: MessageType.ERROR, content: localize('viewOptionsModal.missingRequireField', "This field is required.") }); - } - if (this._view.name !== value && !this._view.nameAvailable(value)) { - return ({ type: MessageType.ERROR, content: localize('viewOptionsModal.nameTaken', "This view name has already been taken.") }); - } - return undefined; - } - }, - ariaLabel: localize('viewOptionsModal.name', "View Name") - }); - } - - private createInputBoxHelper(container: HTMLElement, label: string, defaultValue: string = '', options?: IInputOptions): InputBox { - const inputContainer = DOM.append(container, DOM.$('.dialog-input-section')); - DOM.append(inputContainer, DOM.$('.dialog-label')).innerText = label; - const input = new InputBox(DOM.append(inputContainer, DOM.$('.dialog-input')), this._contextViewService, options); - input.value = defaultValue; - return input; - } - - public override render() { - super.render(); - - this._submitButton = this.addFooterButton(localize('save', "Save"), () => this.onSubmitHandler()); - this._cancelButton = this.addFooterButton(localize('cancel', "Cancel"), () => this.onCancelHandler()); - - this._register(attachInputBoxStyler(this._viewNameInput!, this._themeService)); - this._register(attachButtonStyler(this._submitButton, this._themeService)); - this._register(attachButtonStyler(this._cancelButton, this._themeService)); - - this._register(this._viewNameInput.onDidChange(v => this.validate())); - - attachModalDialogStyler(this, this._themeService); - this.validate(); - } - - private validate() { - let valid = true; - - if (!this._viewNameInput.validate()) { - valid = false; - } - - this._submitButton.enabled = valid; - } - - private onSubmitHandler() { - this._view.name = this._viewNameInput.value; - this._view.save(); - - this.close(); - } - - private onCancelHandler() { - this.close(); - } - - public close(): void { - return this.hide(); - } - - public open(): void { - this.show(); - } - - public override dispose(): void { - super.dispose(); - } -} diff --git a/src/sql/workbench/contrib/notebook/test/browser/dataResourceDataProvider.test.ts b/src/sql/workbench/contrib/notebook/test/browser/dataResourceDataProvider.test.ts index e124da93d8..0c3fb3053b 100644 --- a/src/sql/workbench/contrib/notebook/test/browser/dataResourceDataProvider.test.ts +++ b/src/sql/workbench/contrib/notebook/test/browser/dataResourceDataProvider.test.ts @@ -26,7 +26,7 @@ import { createandLoadNotebookModel } from 'sql/workbench/contrib/notebook/test/ import { TestConfigurationService } from 'sql/platform/connection/test/common/testConfigurationService'; import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; -export class TestSerializationProvider implements azdata.SerializationProvider { +class TestSerializationProvider implements azdata.SerializationProvider { providerId: string; constructor(providerId: string = 'providerId') { } diff --git a/src/sql/workbench/services/notebook/browser/notebookViews/autodash.ts b/src/sql/workbench/services/notebook/browser/notebookViews/autodash.ts deleted file mode 100644 index 6068056c29..0000000000 --- a/src/sql/workbench/services/notebook/browser/notebookViews/autodash.ts +++ /dev/null @@ -1,123 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { nb } from 'azdata'; -import { ICellModel } from 'sql/workbench/services/notebook/browser/models/modelInterfaces'; -import { INotebookView } from 'sql/workbench/services/notebook/browser/notebookViews/notebookViews'; -import { CellTypes } from 'sql/workbench/services/notebook/common/contracts'; - -class VisInfo { - public width: number; - public height: number; - public orderRank: number; - public display: boolean; - public cell: T; -} - -class DisplayCell { - constructor(private _item: T) { } - - get item(): T { - return this._item; - } -} - -abstract class DisplayGroup { - public width: number; - public height: number; - public orderRank: number; - public display: boolean; - private _displayCells: DisplayCell[] = []; - private _visInfos: VisInfo[] = []; - - constructor() { } - - addCell(cell: T, initialView: INotebookView) { - const dCell = new DisplayCell(cell); - this._displayCells.push(dCell); - this._visInfos.push(this.evaluateCell(cell, initialView)); - } - - get visInfos(): VisInfo[] { - return this._visInfos; - } - - get displayCells(): DisplayCell[] { - return this._displayCells; - } - - abstract evaluateCell(cell: T, view: INotebookView): VisInfo; -} - -class CellDisplayGroup extends DisplayGroup { - evaluateCell(cell: ICellModel, view: INotebookView): VisInfo { - let meta = view.getCellMetadata(cell); - let visInfo = new VisInfo(); - visInfo.cell = cell; - - if (cell.cellType !== CellTypes.Code && !this.isHeader(cell)) { - visInfo.display = false; - return visInfo; - } - - if (cell.cellType === CellTypes.Code && (!cell.outputs || !cell.outputs.length)) { - visInfo.display = false; - return visInfo; - } - - //For headers - if (this.isHeader(cell)) { - visInfo.height = 1; - } - //For graphs - if (this.hasGraph(cell)) { - visInfo.width = 6; - visInfo.height = 12; - } - //For tables - else if (this.hasTable(cell)) { - visInfo.height = Math.min(meta?.height, 6); - } else { - visInfo.height = Math.min(meta?.height, 6); - } - - visInfo.display = true; - return visInfo; - } - - isHeader(cell: ICellModel): boolean { - return cell.cellType === 'markdown' && cell.source.length === 1 && cell.source[0].startsWith('#'); - } - - hasGraph(cell: ICellModel): boolean { - return !!cell.outputs.find((o: nb.ICellOutput) => o?.output_type === 'display_data' && (o as nb.IDisplayResult)?.data.hasOwnProperty('application/vnd.plotly.v1+json')); - } - - hasTable(cell: ICellModel): boolean { - return !!cell.outputs.find((o: nb.ICellOutput) => o?.output_type === 'display_data' && (o as nb.IDisplayResult)?.data.hasOwnProperty('application/vnd.dataresource+json')); - } -} - -export function generateLayout(initialView: INotebookView): void { - let displayGroup: CellDisplayGroup = new CellDisplayGroup(); - - const cells = initialView.cells; - - cells.forEach((cell, idx) => { - displayGroup.addCell(cell, initialView); - }); - - displayGroup.visInfos.forEach((v) => { - if (!v.display) { - initialView.hideCell(v.cell); - } - - if (v.width || v.height) { - initialView.resizeCell(v.cell, v.width, v.height); - } - }); - - initialView.compactCells(); -}