diff --git a/extensions/machine-learning-services/images/ML_ExtensionIcon.png b/extensions/machine-learning-services/images/ML_ExtensionIcon.png deleted file mode 100644 index 7bbcbce2c7..0000000000 Binary files a/extensions/machine-learning-services/images/ML_ExtensionIcon.png and /dev/null differ diff --git a/extensions/machine-learning-services/images/extensionIcon.png b/extensions/machine-learning-services/images/extensionIcon.png new file mode 100644 index 0000000000..00f3b452c8 Binary files /dev/null and b/extensions/machine-learning-services/images/extensionIcon.png differ diff --git a/extensions/machine-learning-services/images/makePredictions.svg b/extensions/machine-learning-services/images/makePredictions.svg new file mode 100644 index 0000000000..fd0bb4ff6f --- /dev/null +++ b/extensions/machine-learning-services/images/makePredictions.svg @@ -0,0 +1 @@ +j_ \ No newline at end of file diff --git a/extensions/machine-learning-services/images/manageModels.svg b/extensions/machine-learning-services/images/manageModels.svg new file mode 100644 index 0000000000..1461d0f8cc --- /dev/null +++ b/extensions/machine-learning-services/images/manageModels.svg @@ -0,0 +1 @@ +v_ \ No newline at end of file diff --git a/extensions/machine-learning-services/package.json b/extensions/machine-learning-services/package.json index e401f79ef3..0ac1dc3946 100644 --- a/extensions/machine-learning-services/package.json +++ b/extensions/machine-learning-services/package.json @@ -1,5 +1,5 @@ { - "name": "machineLearningServices", + "name": "machine-learning-services", "displayName": "%displayName%", "description": "%description%", "version": "1.0.0", @@ -14,7 +14,7 @@ "onDashboardOpen" ], "license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt", - "icon": "images/ML_ExtensionIcon.png", + "icon": "images/extensionIcon.png", "aiKey": "AIF-37eefaf0-8022-4671-a3fb-64752724682e", "main": "./out/main", "repository": { @@ -59,7 +59,11 @@ }, { "command": "mls.command.predictModel", - "title": "%mls.command.predictModel%" + "title": "%mls.command.predictModel%", + "icon": { + "light": "./images/makePredictions.svg", + "dark": "./images/makePredictions.svg" + } }, { "command": "mls.command.manageModels", @@ -67,7 +71,11 @@ }, { "command": "mls.command.registerModel", - "title": "%mls.command.registerModel%" + "title": "%mls.command.registerModel%", + "icon": { + "light": "./images/registerModel.svg", + "dark": "./images/registerModel.svg" + } }, { "command": "mls.command.manageLanguages", @@ -95,20 +103,10 @@ "when": "connectionProvider == 'MSSQL' && !mssql:iscloud && dashboardContext == 'server'", "container": { "grid-container": [ - { - "name": "%title.configurations%", - "row": 0, - "col": 0, - "widget": { - "modelview": { - "id": "ml.tasks" - } - } - }, { "name": "%title.tasks%", "row": 0, - "col": 1, + "col": 0, "widget": { "tasks-widget": [ "mls.command.managePackages", @@ -120,8 +118,8 @@ }, { "name": "%title.documents%", - "row": 1, - "col": 0, + "row": 0, + "col": 1, "widget": { "tasks-widget": [ "mls.command.odbcdriver", @@ -138,7 +136,7 @@ "request": "^2.88.0", "vscode-nls": "^4.0.0", "vscode-languageclient": "^5.3.0-next.1", - "@azure/arm-machinelearningservices" : "^3.0.0", + "@azure/arm-machinelearningservices": "^3.0.0", "polly-js": "^1.6.3" }, "devDependencies": { @@ -153,6 +151,6 @@ "vscodetestcover": "github:corivera/vscodetestcover#1.0.5" }, "resolutions": { - "esprima": "^4.0.0" + "esprima": "^4.0.0" } } diff --git a/extensions/machine-learning-services/package.nls.json b/extensions/machine-learning-services/package.nls.json index f42cc5dd92..509f2e87cb 100644 --- a/extensions/machine-learning-services/package.nls.json +++ b/extensions/machine-learning-services/package.nls.json @@ -5,8 +5,8 @@ "title.documents": "Documents", "title.configurations": "Configurations", "title.endpoints": "Endpoints", - "mls.command.managePackages": "Manage Packages in SQL Server", - "mls.command.manageLanguages": "Manage External Languages", + "mls.command.managePackages": "Manage packages in database", + "mls.command.manageLanguages": "Manage external languages", "mls.command.predictModel": "Make prediction", "mls.command.manageModels": "Manage models", "mls.command.registerModel": "Register model", diff --git a/extensions/machine-learning-services/src/common/constants.ts b/extensions/machine-learning-services/src/common/constants.ts index 70d7506abb..e8d55ba9be 100644 --- a/extensions/machine-learning-services/src/common/constants.ts +++ b/extensions/machine-learning-services/src/common/constants.ts @@ -50,6 +50,9 @@ export function taskFailedError(taskName: string, err: string): string { return export const installDependenciesMsgTaskName = localize('mls.installDependencies.msgTaskName', "Installing Machine Learning extension dependencies"); export const noResultError = localize('mls.noResultError', "No Result returned"); export const requiredPackagesNotInstalled = localize('mls.requiredPackagesNotInstalled', "The required dependencies are not installed"); +export const confirmEnableExternalScripts = localize('mls.confirmEnableExternalScripts', "External script is required for package management. Are you sure you want to enable that."); +export const enableExternalScriptsError = localize('mls.enableExternalScriptsError', "Failed to enable External script."); +export const externalScriptsIsRequiredError = localize('mls.externalScriptsIsRequiredError', "External script configuration is required for this action."); export function confirmInstallPythonPackages(packages: string): string { return localize('mls.installDependencies.confirmInstallPythonPackages' , "The following Python packages are required to install: {0}. Are you sure you want to install?", packages); @@ -61,7 +64,6 @@ export const packageManagerNoConnection = localize('mls.packageManager.NoConnect export const notebookExtensionNotLoaded = localize('mls.notebookExtensionNotLoaded', "Notebook extension is not loaded"); export const mssqlExtensionNotLoaded = localize('mls.mssqlExtensionNotLoaded', "MSSQL extension is not loaded"); export const mlsEnabledMessage = localize('mls.enabledMessage', "Machine Learning Services Enabled"); -export const mlsDisabledMessage = localize('mls.disabledMessage', "Machine Learning Services Disabled"); export const mlsConfigUpdateFailed = localize('mls.configUpdateFailed', "Failed to modify Machine Learning Services configurations"); export const mlsEnableButtonTitle = localize('mls.enableButtonTitle', "Enable"); export const mlsDisableButtonTitle = localize('mls.disableButtonTitle', "Disable"); @@ -92,7 +94,7 @@ export const extLangLanguagePlatform = localize('extLang.languagePlatform', "Pla export const deleteTitle = localize('extLang.delete', "Delete"); export const extLangInstallButtonText = localize('extLang.installButtonText', "Install"); export const extLangCancelButtonText = localize('extLang.CancelButtonText', "Cancel"); -export const extLangDoneButtonText = localize('extLang.DoneButtonText', "Done"); +export const extLangDoneButtonText = localize('extLang.DoneButtonText', "Close"); export const extLangOkButtonText = localize('extLang.OkButtonText', "OK"); export const extLangSaveButtonText = localize('extLang.SaveButtonText', "Save"); export const extLangLanguageName = localize('extLang.languageName', "Name"); @@ -131,14 +133,15 @@ export const azureModels = localize('models.azureModels', "Models"); export const azureModelsTitle = localize('models.azureModelsTitle', "Azure models"); export const localModelsTitle = localize('models.localModelsTitle', "Local models"); export const modelSourcesTitle = localize('models.modelSourcesTitle', "Source location"); -export const modelSourcePageTitle = localize('models.modelSourcePageTitle', "Ender model source details"); +export const modelSourcePageTitle = localize('models.modelSourcePageTitle', "Enter model source details"); export const columnSelectionPageTitle = localize('models.columnSelectionPageTitle', "Select input columns"); export const modelDetailsPageTitle = localize('models.modelDetailsPageTitle', "Provide model details"); export const modelLocalSourceTitle = localize('models.modelLocalSourceTitle', "Source file"); export const currentModelsTitle = localize('models.currentModelsTitle', "Models"); -export const azureRegisterModel = localize('models.azureRegisterModel', "Register"); +export const azureRegisterModel = localize('models.azureRegisterModel', "Deploy"); export const predictModel = localize('models.predictModel', "Predict"); -export const registerModelTitle = localize('models.RegisterWizard', "Register model"); +export const registerModelTitle = localize('models.RegisterWizard', "Deployed models"); +export const deployModelTitle = localize('models.deployModelTitle', "Deploy models"); export const makePredictionTitle = localize('models.makePredictionTitle', "Make prediction"); export const modelRegisteredSuccessfully = localize('models.modelRegisteredSuccessfully', "Model registered successfully"); export const modelFailedToRegister = localize('models.modelFailedToRegistered', "Model failed to register"); diff --git a/extensions/machine-learning-services/src/controllers/mainController.ts b/extensions/machine-learning-services/src/controllers/mainController.ts index 4c4e92e346..390dfb3d1e 100644 --- a/extensions/machine-learning-services/src/controllers/mainController.ts +++ b/extensions/machine-learning-services/src/controllers/mainController.ts @@ -13,8 +13,7 @@ import { ApiWrapper } from '../common/apiWrapper'; import { QueryRunner } from '../common/queryRunner'; import { ProcessService } from '../common/processService'; import { Config } from '../configurations/config'; -import { ServerConfigWidget } from '../widgets/serverConfigWidgets'; -import { ServerConfigManager } from '../serverConfig/serverConfigManager'; +import { PackageManagementService } from '../packageManagement/packageManagementService'; import { HttpClient } from '../common/httpClient'; import { LanguageController } from '../views/externalLanguages/languageController'; import { LanguageService } from '../externalLanguage/languageService'; @@ -38,7 +37,7 @@ export default class MainController implements vscode.Disposable { private _queryRunner: QueryRunner, private _processService: ProcessService, private _packageManager?: PackageManager, - private _serverConfigManager?: ServerConfigManager, + private _packageManagementService?: PackageManagementService, private _httpClient?: HttpClient ) { this._outputChannel = this._apiWrapper.createOutputChannel(constants.extensionOutputChannel); @@ -91,9 +90,6 @@ export default class MainController implements vscode.Disposable { let nbApis = await this.getNotebookExtensionApis(); await this._config.load(); - let tasks = new ServerConfigWidget(this._apiWrapper, this.serverConfigManager); - tasks.register(); - let packageManager = this.getPackageManager(nbApis); this._apiWrapper.registerCommand(constants.mlManagePackagesCommand, (async () => { await packageManager.managePackages(); @@ -145,10 +141,10 @@ export default class MainController implements vscode.Disposable { await modelManagementController.predictModel(); }); this._apiWrapper.registerTaskHandler(constants.mlOdbcDriverCommand, async () => { - await this.serverConfigManager.openOdbcDriverDocuments(); + await this.packageManagementService.openOdbcDriverDocuments(); }); this._apiWrapper.registerTaskHandler(constants.mlsDocumentsCommand, async () => { - await this.serverConfigManager.openDocuments(); + await this.packageManagementService.openDocuments(); }); } @@ -157,7 +153,7 @@ export default class MainController implements vscode.Disposable { */ public getPackageManager(nbApis: nbExtensionApis.IExtensionApi): PackageManager { if (!this._packageManager) { - this._packageManager = new PackageManager(this._outputChannel, this._rootPath, this._apiWrapper, this._queryRunner, this._processService, this._config, this.httpClient); + this._packageManager = new PackageManager(this._outputChannel, this._rootPath, this._apiWrapper, this.packageManagementService, this._processService, this._config, this.httpClient); this._packageManager.init(); this._packageManager.packageManageProviders.forEach(provider => { nbApis.registerPackageManager(provider.providerId, provider); @@ -169,11 +165,11 @@ export default class MainController implements vscode.Disposable { /** * Returns the server config manager instance */ - public get serverConfigManager(): ServerConfigManager { - if (!this._serverConfigManager) { - this._serverConfigManager = new ServerConfigManager(this._apiWrapper, this._queryRunner); + public get packageManagementService(): PackageManagementService { + if (!this._packageManagementService) { + this._packageManagementService = new PackageManagementService(this._apiWrapper, this._queryRunner); } - return this._serverConfigManager; + return this._packageManagementService; } /** diff --git a/extensions/machine-learning-services/src/serverConfig/serverConfigManager.ts b/extensions/machine-learning-services/src/packageManagement/packageManagementService.ts similarity index 65% rename from extensions/machine-learning-services/src/serverConfig/serverConfigManager.ts rename to extensions/machine-learning-services/src/packageManagement/packageManagementService.ts index 1cabf51f42..b2cf31381d 100644 --- a/extensions/machine-learning-services/src/serverConfig/serverConfigManager.ts +++ b/extensions/machine-learning-services/src/packageManagement/packageManagementService.ts @@ -9,8 +9,9 @@ import { QueryRunner } from '../common/queryRunner'; import * as constants from '../common/constants'; import { ApiWrapper } from '../common/apiWrapper'; import * as utils from '../common/utils'; +import * as nbExtensionApis from '../typings/notebookServices'; -export class ServerConfigManager { +export class PackageManagementService { /** * Creates a new instance of ServerConfigManager @@ -76,15 +77,41 @@ export class ServerConfigManager { * @param connection SQL Connection * @param enable if true external script will be enabled */ - public async updateExternalScriptConfig(connection: azdata.connection.ConnectionProfile, enable: boolean): Promise { - await this._queryRunner.updateExternalScriptConfig(connection, enable); + public async enableExternalScriptConfig(connection: azdata.connection.ConnectionProfile): Promise { let current = await this._queryRunner.isMachineLearningServiceEnabled(connection); - if (current === enable) { - this._apiWrapper.showInfoMessage(enable ? constants.mlsEnabledMessage : constants.mlsDisabledMessage); + + if (current) { + return current; + } + let confirmed = await utils.promptConfirm(constants.confirmEnableExternalScripts, this._apiWrapper); + if (confirmed) { + await this._queryRunner.updateExternalScriptConfig(connection, true); + current = await this._queryRunner.isMachineLearningServiceEnabled(connection); + if (current) { + this._apiWrapper.showInfoMessage(constants.mlsEnabledMessage); + } else { + this._apiWrapper.showErrorMessage(constants.mlsConfigUpdateFailed); + } } else { - this._apiWrapper.showErrorMessage(constants.mlsConfigUpdateFailed); + this._apiWrapper.showErrorMessage(constants.externalScriptsIsRequiredError); } return current; } + + /** + * Returns python packages installed in SQL server instance + * @param connection SQL Connection + */ + public async getPythonPackages(connection: azdata.connection.ConnectionProfile): Promise { + return this._queryRunner.getPythonPackages(connection); + } + + /** + * Returns python packages installed in SQL server instance + * @param connection SQL Connection + */ + public async getRPackages(connection: azdata.connection.ConnectionProfile): Promise { + return this._queryRunner.getRPackages(connection); + } } diff --git a/extensions/machine-learning-services/src/packageManagement/packageManager.ts b/extensions/machine-learning-services/src/packageManagement/packageManager.ts index 34c71e4544..72e2bdb2f6 100644 --- a/extensions/machine-learning-services/src/packageManagement/packageManager.ts +++ b/extensions/machine-learning-services/src/packageManagement/packageManager.ts @@ -7,7 +7,6 @@ import * as vscode from 'vscode'; import * as azdata from 'azdata'; import * as nbExtensionApis from '../typings/notebookServices'; import { SqlPythonPackageManageProvider } from './sqlPythonPackageManageProvider'; -import { QueryRunner } from '../common/queryRunner'; import * as utils from '../common/utils'; import * as constants from '../common/constants'; import { ApiWrapper } from '../common/apiWrapper'; @@ -17,6 +16,7 @@ import { isNullOrUndefined } from 'util'; import { SqlRPackageManageProvider } from './sqlRPackageManageProvider'; import { HttpClient } from '../common/httpClient'; import { PackageConfigModel } from '../configurations/packageConfigModel'; +import { PackageManagementService } from './packageManagementService'; export class PackageManager { @@ -31,12 +31,12 @@ export class PackageManager { private _outputChannel: vscode.OutputChannel, private _rootFolder: string, private _apiWrapper: ApiWrapper, - private _queryRunner: QueryRunner, + private _service: PackageManagementService, private _processService: ProcessService, private _config: Config, private _httpClient: HttpClient) { - this._sqlPythonPackagePackageManager = new SqlPythonPackageManageProvider(this._outputChannel, this._apiWrapper, this._queryRunner, this._processService, this._config, this._httpClient); - this._sqlRPackageManager = new SqlRPackageManageProvider(this._outputChannel, this._apiWrapper, this._queryRunner, this._processService, this._config, this._httpClient); + this._sqlPythonPackagePackageManager = new SqlPythonPackageManageProvider(this._outputChannel, this._apiWrapper, this._service, this._processService, this._config, this._httpClient); + this._sqlRPackageManager = new SqlRPackageManageProvider(this._outputChannel, this._apiWrapper, this._service, this._processService, this._config, this._httpClient); } /** @@ -67,11 +67,13 @@ export class PackageManager { */ public async managePackages(): Promise { try { + await this.enableExternalScript(); + // Only execute the command if there's a valid connection with ml configuration enabled // let connection = await this.getCurrentConnection(); - let isPythonInstalled = await this._queryRunner.isPythonInstalled(connection); - let isRInstalled = await this._queryRunner.isRInstalled(connection); + let isPythonInstalled = await this._service.isPythonInstalled(connection); + let isRInstalled = await this._service.isRInstalled(connection); let defaultProvider: SqlRPackageManageProvider | SqlPythonPackageManageProvider | undefined; if (connection && isPythonInstalled && this._sqlPythonPackagePackageManager.canUseProvider) { defaultProvider = this._sqlPythonPackagePackageManager; @@ -80,10 +82,10 @@ export class PackageManager { } if (connection && defaultProvider) { + await this.enableExternalScript(); // Install dependencies // if (!this.dependenciesInstalled) { - this._apiWrapper.showInfoMessage(constants.installingDependencies); await this.installDependencies(); this.dependenciesInstalled = true; } @@ -99,7 +101,14 @@ export class PackageManager { this._apiWrapper.showInfoMessage(constants.managePackageCommandError); } } catch (err) { - this._outputChannel.appendLine(err); + this._apiWrapper.showErrorMessage(err); + } + } + + public async enableExternalScript(): Promise { + let connection = await this.getCurrentConnection(); + if (!await this._service.enableExternalScriptConfig(connection)) { + throw Error(constants.externalScriptsIsRequiredError); } } diff --git a/extensions/machine-learning-services/src/packageManagement/sqlPythonPackageManageProvider.ts b/extensions/machine-learning-services/src/packageManagement/sqlPythonPackageManageProvider.ts index 086a166af9..8ebf25e472 100644 --- a/extensions/machine-learning-services/src/packageManagement/sqlPythonPackageManageProvider.ts +++ b/extensions/machine-learning-services/src/packageManagement/sqlPythonPackageManageProvider.ts @@ -6,13 +6,13 @@ import * as vscode from 'vscode'; import * as azdata from 'azdata'; import * as nbExtensionApis from '../typings/notebookServices'; -import { QueryRunner } from '../common/queryRunner'; import { ApiWrapper } from '../common/apiWrapper'; import { ProcessService } from '../common/processService'; import { Config } from '../configurations/config'; import { SqlPackageManageProviderBase, ScriptMode } from './SqlPackageManageProviderBase'; import { HttpClient } from '../common/httpClient'; import * as utils from '../common/utils'; +import { PackageManagementService } from './packageManagementService'; /** * Manage Package Provider for python packages inside SQL server databases @@ -26,7 +26,7 @@ export class SqlPythonPackageManageProvider extends SqlPackageManageProviderBase constructor( private _outputChannel: vscode.OutputChannel, apiWrapper: ApiWrapper, - private _queryRunner: QueryRunner, + private _service: PackageManagementService, private _processService: ProcessService, private _config: Config, private _httpClient: HttpClient) { @@ -51,7 +51,7 @@ export class SqlPythonPackageManageProvider extends SqlPackageManageProviderBase * Returns list of packages */ protected async fetchPackages(): Promise { - return await this._queryRunner.getPythonPackages(await this.getCurrentConnection()); + return await this._service.getPythonPackages(await this.getCurrentConnection()); } /** @@ -97,7 +97,7 @@ export class SqlPythonPackageManageProvider extends SqlPackageManageProviderBase return false; } let connection = await this.getCurrentConnection(); - if (connection && await this._queryRunner.isPythonInstalled(connection)) { + if (connection && await this._service.isPythonInstalled(connection)) { return true; } return false; diff --git a/extensions/machine-learning-services/src/packageManagement/sqlRPackageManageProvider.ts b/extensions/machine-learning-services/src/packageManagement/sqlRPackageManageProvider.ts index eecbeec22f..a947ce1e66 100644 --- a/extensions/machine-learning-services/src/packageManagement/sqlRPackageManageProvider.ts +++ b/extensions/machine-learning-services/src/packageManagement/sqlRPackageManageProvider.ts @@ -7,13 +7,13 @@ import * as vscode from 'vscode'; import * as azdata from 'azdata'; import * as nbExtensionApis from '../typings/notebookServices'; -import { QueryRunner } from '../common/queryRunner'; import { ApiWrapper } from '../common/apiWrapper'; import { ProcessService } from '../common/processService'; import { Config } from '../configurations/config'; import { SqlPackageManageProviderBase, ScriptMode } from './SqlPackageManageProviderBase'; import { HttpClient } from '../common/httpClient'; import * as constants from '../common/constants'; +import { PackageManagementService } from './packageManagementService'; @@ -30,7 +30,7 @@ export class SqlRPackageManageProvider extends SqlPackageManageProviderBase impl constructor( private _outputChannel: vscode.OutputChannel, apiWrapper: ApiWrapper, - private _queryRunner: QueryRunner, + private _service: PackageManagementService, private _processService: ProcessService, private _config: Config, private _httpClient: HttpClient) { @@ -55,7 +55,7 @@ export class SqlRPackageManageProvider extends SqlPackageManageProviderBase impl * Returns list of packages */ protected async fetchPackages(): Promise { - return await this._queryRunner.getRPackages(await this.getCurrentConnection()); + return await this._service.getRPackages(await this.getCurrentConnection()); } /** @@ -96,7 +96,7 @@ export class SqlRPackageManageProvider extends SqlPackageManageProviderBase impl return false; } let connection = await this.getCurrentConnection(); - if (connection && await this._queryRunner.isRInstalled(connection)) { + if (connection && await this._service.isRInstalled(connection)) { return true; } return false; diff --git a/extensions/machine-learning-services/src/test/serverConfig/serverConfigManager.test.ts b/extensions/machine-learning-services/src/test/packageManagement/packageManagementService.test.ts similarity index 61% rename from extensions/machine-learning-services/src/test/serverConfig/serverConfigManager.test.ts rename to extensions/machine-learning-services/src/test/packageManagement/packageManagementService.test.ts index 82d64f625a..8a6315b094 100644 --- a/extensions/machine-learning-services/src/test/serverConfig/serverConfigManager.test.ts +++ b/extensions/machine-learning-services/src/test/packageManagement/packageManagementService.test.ts @@ -8,7 +8,7 @@ import { QueryRunner } from '../../common/queryRunner'; import { ApiWrapper } from '../../common/apiWrapper'; import * as TypeMoq from 'typemoq'; import * as should from 'should'; -import { ServerConfigManager } from '../../serverConfig/serverConfigManager'; +import { PackageManagementService } from '../../packageManagement/packageManagementService'; interface TestContext { @@ -23,74 +23,64 @@ function createContext(): TestContext { }; } -describe('Server Config Manager', () => { +describe('Package Management Service', () => { it('openDocuments should open document in browser successfully', async function (): Promise { const context = createContext(); context.apiWrapper.setup(x => x.openExternal(TypeMoq.It.isAny())).returns(() => Promise.resolve(true)); - let serverConfigManager = new ServerConfigManager(context.apiWrapper.object, context.queryRunner.object); + let serverConfigManager = new PackageManagementService(context.apiWrapper.object, context.queryRunner.object); should.equal(await serverConfigManager.openDocuments(), true); }); it('openOdbcDriverDocuments should open document in browser successfully', async function (): Promise { const context = createContext(); context.apiWrapper.setup(x => x.openExternal(TypeMoq.It.isAny())).returns(() => Promise.resolve(true)); - let serverConfigManager = new ServerConfigManager(context.apiWrapper.object, context.queryRunner.object); + let serverConfigManager = new PackageManagementService(context.apiWrapper.object, context.queryRunner.object); should.equal(await serverConfigManager.openOdbcDriverDocuments(), true); }); it('openInstallDocuments should open document in browser successfully', async function (): Promise { const context = createContext(); context.apiWrapper.setup(x => x.openExternal(TypeMoq.It.isAny())).returns(() => Promise.resolve(true)); - let serverConfigManager = new ServerConfigManager(context.apiWrapper.object, context.queryRunner.object); + let serverConfigManager = new PackageManagementService(context.apiWrapper.object, context.queryRunner.object); should.equal(await serverConfigManager.openInstallDocuments(), true); }); it('isMachineLearningServiceEnabled should return true if external script is enabled', async function (): Promise { const context = createContext(); context.queryRunner.setup(x => x.isMachineLearningServiceEnabled(TypeMoq.It.isAny())).returns(() => Promise.resolve(true)); - let serverConfigManager = new ServerConfigManager(context.apiWrapper.object, context.queryRunner.object); - let connection = new azdata.connection.ConnectionProfile(); + let serverConfigManager = new PackageManagementService(context.apiWrapper.object, context.queryRunner.object); + let connection = new azdata.connection.ConnectionProfile(); should.equal(await serverConfigManager.isMachineLearningServiceEnabled(connection), true); }); it('isRInstalled should return true if R is installed', async function (): Promise { const context = createContext(); context.queryRunner.setup(x => x.isRInstalled(TypeMoq.It.isAny())).returns(() => Promise.resolve(true)); - let serverConfigManager = new ServerConfigManager(context.apiWrapper.object, context.queryRunner.object); - let connection = new azdata.connection.ConnectionProfile(); + let serverConfigManager = new PackageManagementService(context.apiWrapper.object, context.queryRunner.object); + let connection = new azdata.connection.ConnectionProfile(); should.equal(await serverConfigManager.isRInstalled(connection), true); }); it('isPythonInstalled should return true if Python is installed', async function (): Promise { const context = createContext(); context.queryRunner.setup(x => x.isPythonInstalled(TypeMoq.It.isAny())).returns(() => Promise.resolve(true)); - let serverConfigManager = new ServerConfigManager(context.apiWrapper.object, context.queryRunner.object); - let connection = new azdata.connection.ConnectionProfile(); + let serverConfigManager = new PackageManagementService(context.apiWrapper.object, context.queryRunner.object); + let connection = new azdata.connection.ConnectionProfile(); should.equal(await serverConfigManager.isPythonInstalled(connection), true); }); - it('updateExternalScriptConfig should show info message if updated successfully', async function (): Promise { - const context = createContext(); - context.queryRunner.setup(x => x.updateExternalScriptConfig(TypeMoq.It.isAny(), true)).returns(() => Promise.resolve()); - context.queryRunner.setup(x => x.isMachineLearningServiceEnabled(TypeMoq.It.isAny())).returns(() => Promise.resolve(true)); - context.apiWrapper.setup(x => x.showInfoMessage(TypeMoq.It.isAny())).returns(() => Promise.resolve('')); - context.apiWrapper.setup(x => x.showErrorMessage(TypeMoq.It.isAny())).returns(() => Promise.resolve('')); - let serverConfigManager = new ServerConfigManager(context.apiWrapper.object, context.queryRunner.object); - let connection = new azdata.connection.ConnectionProfile(); - await serverConfigManager.updateExternalScriptConfig(connection, true); - - context.apiWrapper.verify(x => x.showInfoMessage(TypeMoq.It.isAny()), TypeMoq.Times.once()); - }); - - it('updateExternalScriptConfig should show error message if did not updated successfully', async function (): Promise { + it('enableExternalScriptConfig should show error message if did not updated successfully', async function (): Promise { const context = createContext(); context.queryRunner.setup(x => x.updateExternalScriptConfig(TypeMoq.It.isAny(), true)).returns(() => Promise.resolve()); context.queryRunner.setup(x => x.isMachineLearningServiceEnabled(TypeMoq.It.isAny())).returns(() => Promise.resolve(false)); context.apiWrapper.setup(x => x.showInfoMessage(TypeMoq.It.isAny())).returns(() => Promise.resolve('')); context.apiWrapper.setup(x => x.showErrorMessage(TypeMoq.It.isAny())).returns(() => Promise.resolve('')); - let serverConfigManager = new ServerConfigManager(context.apiWrapper.object, context.queryRunner.object); - let connection = new azdata.connection.ConnectionProfile(); - await serverConfigManager.updateExternalScriptConfig(connection, true); + context.apiWrapper.setup(x => x.showQuickPick(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({ + label: 'Yes' + })); + let serverConfigManager = new PackageManagementService(context.apiWrapper.object, context.queryRunner.object); + let connection = new azdata.connection.ConnectionProfile(); + await serverConfigManager.enableExternalScriptConfig(connection); context.apiWrapper.verify(x => x.showErrorMessage(TypeMoq.It.isAny()), TypeMoq.Times.once()); }); diff --git a/extensions/machine-learning-services/src/test/packageManagement/packageManager.test.ts b/extensions/machine-learning-services/src/test/packageManagement/packageManager.test.ts index 5723d9ed4f..950a2f60be 100644 --- a/extensions/machine-learning-services/src/test/packageManagement/packageManager.test.ts +++ b/extensions/machine-learning-services/src/test/packageManagement/packageManager.test.ts @@ -22,7 +22,8 @@ describe('Package Manager', () => { let connection = new azdata.connection.ConnectionProfile(); testContext.apiWrapper.setup(x => x.getCurrentConnection()).returns(() => {return Promise.resolve(connection);}); testContext.apiWrapper.setup(x => x.executeCommand(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => {return Promise.resolve();}); - testContext.queryRunner.setup(x => x.isPythonInstalled(connection)).returns(() => {return Promise.resolve(true);}); + testContext.serverConfigManager.setup(x => x.isPythonInstalled(connection)).returns(() => {return Promise.resolve(true);}); + testContext.serverConfigManager.setup(x => x.enableExternalScriptConfig(connection)).returns(() => {return Promise.resolve(true);}); let packageManager = createPackageManager(testContext); await packageManager.managePackages(); testContext.apiWrapper.verify(x => x.executeCommand(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once()); @@ -33,8 +34,10 @@ describe('Package Manager', () => { let connection = new azdata.connection.ConnectionProfile(); testContext.apiWrapper.setup(x => x.getCurrentConnection()).returns(() => {return Promise.resolve(connection);}); testContext.apiWrapper.setup(x => x.executeCommand(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => {return Promise.resolve();}); - testContext.queryRunner.setup(x => x.isPythonInstalled(connection)).returns(() => {return Promise.resolve(false);}); - testContext.queryRunner.setup(x => x.isRInstalled(connection)).returns(() => {return Promise.resolve(true);}); + testContext.serverConfigManager.setup(x => x.isPythonInstalled(connection)).returns(() => {return Promise.resolve(false);}); + testContext.serverConfigManager.setup(x => x.isRInstalled(connection)).returns(() => {return Promise.resolve(true);}); + testContext.serverConfigManager.setup(x => x.isPythonInstalled(connection)).returns(() => {return Promise.resolve(true);}); + testContext.serverConfigManager.setup(x => x.enableExternalScriptConfig(connection)).returns(() => {return Promise.resolve(true);}); let packageManager = createPackageManager(testContext); await packageManager.managePackages(); testContext.apiWrapper.verify(x => x.executeCommand(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once()); @@ -46,8 +49,10 @@ describe('Package Manager', () => { testContext.apiWrapper.setup(x => x.getCurrentConnection()).returns(() => {return Promise.resolve(connection);}); testContext.apiWrapper.setup(x => x.executeCommand(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => {return Promise.resolve();}); testContext.apiWrapper.setup(x => x.showInfoMessage(TypeMoq.It.isAny())); - testContext.queryRunner.setup(x => x.isPythonInstalled(connection)).returns(() => {return Promise.resolve(false);}); - testContext.queryRunner.setup(x => x.isRInstalled(connection)).returns(() => {return Promise.resolve(false);}); + testContext.serverConfigManager.setup(x => x.isPythonInstalled(connection)).returns(() => {return Promise.resolve(false);}); + testContext.serverConfigManager.setup(x => x.isRInstalled(connection)).returns(() => {return Promise.resolve(false);}); + testContext.serverConfigManager.setup(x => x.isPythonInstalled(connection)).returns(() => {return Promise.resolve(true);}); + testContext.serverConfigManager.setup(x => x.enableExternalScriptConfig(connection)).returns(() => {return Promise.resolve(true);}); let packageManager = createPackageManager(testContext); await packageManager.managePackages(); testContext.apiWrapper.verify(x => x.showInfoMessage(TypeMoq.It.isAny()), TypeMoq.Times.once()); @@ -59,6 +64,7 @@ describe('Package Manager', () => { testContext.apiWrapper.setup(x => x.getCurrentConnection()).returns(() => {return Promise.resolve(connection);}); testContext.apiWrapper.setup(x => x.executeCommand(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => {return Promise.resolve();}); testContext.apiWrapper.setup(x => x.showInfoMessage(TypeMoq.It.isAny())); + testContext.serverConfigManager.setup(x => x.enableExternalScriptConfig(connection)).returns(() => {return Promise.resolve(true);}); let packageManager = createPackageManager(testContext); await packageManager.managePackages(); @@ -204,7 +210,7 @@ describe('Package Manager', () => { testContext.outputChannel, '', testContext.apiWrapper.object, - testContext.queryRunner.object, + testContext.serverConfigManager.object, testContext.processService.object, testContext.config.object, testContext.httpClient.object); diff --git a/extensions/machine-learning-services/src/test/packageManagement/sqlPythonPackageManageProvider.test.ts b/extensions/machine-learning-services/src/test/packageManagement/sqlPythonPackageManageProvider.test.ts index afafb5db55..856135603a 100644 --- a/extensions/machine-learning-services/src/test/packageManagement/sqlPythonPackageManageProvider.test.ts +++ b/extensions/machine-learning-services/src/test/packageManagement/sqlPythonPackageManageProvider.test.ts @@ -40,7 +40,7 @@ describe('SQL Python Package Manager', () => { let connection = new azdata.connection.ConnectionProfile(); testContext.apiWrapper.setup(x => x.getCurrentConnection()).returns(() => { return Promise.resolve(connection); }); - testContext.queryRunner.setup(x => x.getPythonPackages(TypeMoq.It.isAny())).returns(() => Promise.resolve(packages)); + testContext.serverConfigManager.setup(x => x.getPythonPackages(TypeMoq.It.isAny())).returns(() => Promise.resolve(packages)); let provider = createProvider(testContext); let actual = await provider.listPackages(); @@ -72,7 +72,7 @@ describe('SQL Python Package Manager', () => { let connection = new azdata.connection.ConnectionProfile(); testContext.apiWrapper.setup(x => x.getCurrentConnection()).returns(() => { return Promise.resolve(connection); }); - testContext.queryRunner.setup(x => x.getPythonPackages(TypeMoq.It.isAny())).returns(() => Promise.resolve(packages)); + testContext.serverConfigManager.setup(x => x.getPythonPackages(TypeMoq.It.isAny())).returns(() => Promise.resolve(packages)); let provider = createProvider(testContext); let actual = await provider.listPackages(); @@ -95,7 +95,7 @@ describe('SQL Python Package Manager', () => { let connection = new azdata.connection.ConnectionProfile(); let packages: nbExtensionApis.IPackageDetails[]; testContext.apiWrapper.setup(x => x.getCurrentConnection()).returns(() => { return Promise.resolve(connection); }); - testContext.queryRunner.setup(x => x.getPythonPackages(TypeMoq.It.isAny())).returns(() => Promise.resolve(packages)); + testContext.serverConfigManager.setup(x => x.getPythonPackages(TypeMoq.It.isAny())).returns(() => Promise.resolve(packages)); let provider = createProvider(testContext); let actual = await provider.listPackages(); @@ -108,7 +108,7 @@ describe('SQL Python Package Manager', () => { let connection = new azdata.connection.ConnectionProfile(); testContext.apiWrapper.setup(x => x.getCurrentConnection()).returns(() => { return Promise.resolve(connection); }); - testContext.queryRunner.setup(x => x.getPythonPackages(TypeMoq.It.isAny())).returns(() => Promise.resolve([])); + testContext.serverConfigManager.setup(x => x.getPythonPackages(TypeMoq.It.isAny())).returns(() => Promise.resolve([])); let provider = createProvider(testContext); let actual = await provider.listPackages(); @@ -298,7 +298,7 @@ describe('SQL Python Package Manager', () => { let connection = new azdata.connection.ConnectionProfile(); testContext.apiWrapper.setup(x => x.getCurrentConnection()).returns(() => { return Promise.resolve(connection); }); - testContext.queryRunner.setup(x => x.isPythonInstalled(TypeMoq.It.isAny())).returns(() => Promise.resolve(false)); + testContext.serverConfigManager.setup(x => x.isPythonInstalled(TypeMoq.It.isAny())).returns(() => Promise.resolve(false)); let provider = createProvider(testContext); let actual = await provider.canUseProvider(); @@ -311,7 +311,7 @@ describe('SQL Python Package Manager', () => { let connection = new azdata.connection.ConnectionProfile(); testContext.apiWrapper.setup(x => x.getCurrentConnection()).returns(() => { return Promise.resolve(connection); }); - testContext.queryRunner.setup(x => x.isPythonInstalled(TypeMoq.It.isAny())).returns(() => Promise.resolve(true)); + testContext.serverConfigManager.setup(x => x.isPythonInstalled(TypeMoq.It.isAny())).returns(() => Promise.resolve(true)); let provider = createProvider(testContext); let actual = await provider.canUseProvider(); @@ -390,7 +390,7 @@ describe('SQL Python Package Manager', () => { return new SqlPythonPackageManageProvider( testContext.outputChannel, testContext.apiWrapper.object, - testContext.queryRunner.object, + testContext.serverConfigManager.object, testContext.processService.object, testContext.config.object, testContext.httpClient.object); diff --git a/extensions/machine-learning-services/src/test/packageManagement/sqlRPackageManageProvider.test.ts b/extensions/machine-learning-services/src/test/packageManagement/sqlRPackageManageProvider.test.ts index 2fbfc33121..cbe86dc4a7 100644 --- a/extensions/machine-learning-services/src/test/packageManagement/sqlRPackageManageProvider.test.ts +++ b/extensions/machine-learning-services/src/test/packageManagement/sqlRPackageManageProvider.test.ts @@ -40,7 +40,7 @@ describe('SQL R Package Manager', () => { let connection = new azdata.connection.ConnectionProfile(); testContext.apiWrapper.setup(x => x.getCurrentConnection()).returns(() => { return Promise.resolve(connection); }); - testContext.queryRunner.setup(x => x.getRPackages(TypeMoq.It.isAny())).returns(() => Promise.resolve(packages)); + testContext.serverConfigManager.setup(x => x.getRPackages(TypeMoq.It.isAny())).returns(() => Promise.resolve(packages)); let provider = createProvider(testContext); let actual = await provider.listPackages(); @@ -63,7 +63,7 @@ describe('SQL R Package Manager', () => { let connection = new azdata.connection.ConnectionProfile(); let packages: nbExtensionApis.IPackageDetails[]; testContext.apiWrapper.setup(x => x.getCurrentConnection()).returns(() => { return Promise.resolve(connection); }); - testContext.queryRunner.setup(x => x.getRPackages(TypeMoq.It.isAny())).returns(() => Promise.resolve(packages)); + testContext.serverConfigManager.setup(x => x.getRPackages(TypeMoq.It.isAny())).returns(() => Promise.resolve(packages)); let provider = createProvider(testContext); let actual = await provider.listPackages(); @@ -76,7 +76,7 @@ describe('SQL R Package Manager', () => { let connection = new azdata.connection.ConnectionProfile(); testContext.apiWrapper.setup(x => x.getCurrentConnection()).returns(() => { return Promise.resolve(connection); }); - testContext.queryRunner.setup(x => x.getRPackages(TypeMoq.It.isAny())).returns(() => Promise.resolve([])); + testContext.serverConfigManager.setup(x => x.getRPackages(TypeMoq.It.isAny())).returns(() => Promise.resolve([])); let provider = createProvider(testContext); let actual = await provider.listPackages(); @@ -222,7 +222,7 @@ describe('SQL R Package Manager', () => { let connection = new azdata.connection.ConnectionProfile(); testContext.apiWrapper.setup(x => x.getCurrentConnection()).returns(() => { return Promise.resolve(connection); }); - testContext.queryRunner.setup(x => x.isRInstalled(TypeMoq.It.isAny())).returns(() => Promise.resolve(false)); + testContext.serverConfigManager.setup(x => x.isRInstalled(TypeMoq.It.isAny())).returns(() => Promise.resolve(false)); let provider = createProvider(testContext); let actual = await provider.canUseProvider(); @@ -235,7 +235,7 @@ describe('SQL R Package Manager', () => { let connection = new azdata.connection.ConnectionProfile(); testContext.apiWrapper.setup(x => x.getCurrentConnection()).returns(() => { return Promise.resolve(connection); }); - testContext.queryRunner.setup(x => x.isRInstalled(TypeMoq.It.isAny())).returns(() => Promise.resolve(true)); + testContext.serverConfigManager.setup(x => x.isRInstalled(TypeMoq.It.isAny())).returns(() => Promise.resolve(true)); let provider = createProvider(testContext); let actual = await provider.canUseProvider(); @@ -316,7 +316,7 @@ describe('SQL R Package Manager', () => { return new SqlRPackageManageProvider( testContext.outputChannel, testContext.apiWrapper.object, - testContext.queryRunner.object, + testContext.serverConfigManager.object, testContext.processService.object, testContext.config.object, testContext.httpClient.object); diff --git a/extensions/machine-learning-services/src/test/packageManagement/utils.ts b/extensions/machine-learning-services/src/test/packageManagement/utils.ts index eb80389864..3911af4db0 100644 --- a/extensions/machine-learning-services/src/test/packageManagement/utils.ts +++ b/extensions/machine-learning-services/src/test/packageManagement/utils.ts @@ -11,6 +11,7 @@ import { QueryRunner } from '../../common/queryRunner'; import { ProcessService } from '../../common/processService'; import { Config } from '../../configurations/config'; import { HttpClient } from '../../common/httpClient'; +import { PackageManagementService } from '../../packageManagement/packageManagementService'; export interface TestContext { @@ -22,6 +23,7 @@ export interface TestContext { op: azdata.BackgroundOperation; getOpStatus: () => azdata.TaskStatus; httpClient: TypeMoq.IMock; + serverConfigManager: TypeMoq.IMock; } export function createContext(): TestContext { @@ -49,6 +51,7 @@ export function createContext(): TestContext { id: '', onCanceled: new vscode.EventEmitter().event, }, - getOpStatus: () => { return opStatus; } + getOpStatus: () => { return opStatus; }, + serverConfigManager: TypeMoq.Mock.ofType(PackageManagementService) }; } diff --git a/extensions/machine-learning-services/src/views/models/registerModels/registeredModelsDialog.ts b/extensions/machine-learning-services/src/views/models/registerModels/registeredModelsDialog.ts index c999beb611..9ec3665aba 100644 --- a/extensions/machine-learning-services/src/views/models/registerModels/registeredModelsDialog.ts +++ b/extensions/machine-learning-services/src/views/models/registerModels/registeredModelsDialog.ts @@ -31,12 +31,12 @@ export class RegisteredModelsDialog extends ModelViewBase { this.currentLanguagesTab = new CurrentModelsPage(this._apiWrapper, this); - let registerModelButton = this._apiWrapper.createButton(constants.registerModelTitle); + let registerModelButton = this._apiWrapper.createButton(constants.deployModelTitle); registerModelButton.onClick(async () => { await this.sendDataRequest(RegisterModelEventName); }); - let dialog = this.dialogView.createDialog('', [this.currentLanguagesTab]); + let dialog = this.dialogView.createDialog(constants.registerModelTitle, [this.currentLanguagesTab]); dialog.customButtons = [registerModelButton]; this.mainViewPanel = dialog; dialog.okButton.hidden = true; diff --git a/extensions/machine-learning-services/src/widgets/configTable.ts b/extensions/machine-learning-services/src/widgets/configTable.ts deleted file mode 100644 index 771c67ecbd..0000000000 --- a/extensions/machine-learning-services/src/widgets/configTable.ts +++ /dev/null @@ -1,160 +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 { ApiWrapper } from '../common/apiWrapper'; -import { ServerConfigManager } from '../serverConfig/serverConfigManager'; -import * as constants from '../common/constants'; - -export class ConfigTable { - private _statusTable: azdata.DeclarativeTableComponent; - - constructor(private _apiWrapper: ApiWrapper, private _serverConfigManager: ServerConfigManager, private _modelBuilder: azdata.ModelBuilder, private _loadingComponent: azdata.LoadingComponent) { - this._statusTable = this._modelBuilder.declarativeTable() - .withProperties( - { - columns: [ - { // Config - displayName: constants.mlsConfigTitle, - valueType: azdata.DeclarativeDataType.component, - isReadOnly: true, - width: 175, - headerCssStyles: { - ...constants.cssStyles.tableHeader - }, - rowCssStyles: { - ...constants.cssStyles.tableRow - }, - }, - { // Status icon - displayName: constants.mlsConfigStatus, - ariaLabel: constants.mlsConfigStatus, - valueType: azdata.DeclarativeDataType.component, - isReadOnly: true, - width: 25, - headerCssStyles: { - ...constants.cssStyles.tableHeader - }, - rowCssStyles: { - ...constants.cssStyles.tableRow - }, - }, - { // Action - displayName: '', - valueType: azdata.DeclarativeDataType.component, - isReadOnly: true, - width: 150, - headerCssStyles: { - ...constants.cssStyles.tableHeader - }, - rowCssStyles: { - ...constants.cssStyles.tableRow - }, - } - ], - data: [], - ariaLabel: constants.mlsConfigTitle - }) - .component(); - } - - /** - * Returns the config table component - */ - public get component(): azdata.DeclarativeTableComponent { - return this._statusTable; - } - - /** - * Refreshes the config table - */ - public async refresh(): Promise { - this._loadingComponent.updateProperties({ loading: true }); - let connection = await this.getCurrentConnection(); - const externalScriptsConfig = await this.createTableRowComponents(constants.mlsExternalExecuteScriptTitle, - async () => { - return await this._serverConfigManager.isMachineLearningServiceEnabled(connection); - }, async (enable) => { - this._loadingComponent.updateProperties({ loading: true }); - await this._serverConfigManager.updateExternalScriptConfig(connection, enable); - await this.refresh(); - } - ); - const pythonConfig = await this.createTableRowComponents(constants.mlsPythonLanguageTitle, - async () => { - return await this._serverConfigManager.isPythonInstalled(connection); - }, async () => { - await this._serverConfigManager.openInstallDocuments(); - } - ); - const rConfig = await this.createTableRowComponents(constants.mlsRLanguageTitle, - async () => { - return await this._serverConfigManager.isRInstalled(connection); - }, async () => { - await this._serverConfigManager.openInstallDocuments(); - } - ); - this._statusTable.data = [externalScriptsConfig, pythonConfig, rConfig]; - this._loadingComponent.updateProperties({ loading: false }); - } - - private async getCurrentConnection(): Promise { - return await this._apiWrapper.getCurrentConnection(); - } - - private async createTableRowComponents(configName: string, checkEnabledFunction: () => Promise, updateFunction: (enable: boolean) => Promise): Promise { - const isEnabled = await checkEnabledFunction(); - - const nameCell = this._modelBuilder.text() - .withProperties({ - value: configName, - CSSStyles: { 'user-select': 'none', ...constants.cssStyles.text } - }).component(); - const statusIconCell = this._modelBuilder.text() - .withProperties({ - value: this.getConfigStatusIcon(isEnabled), - ariaRole: 'img', - title: this.getConfigStatusTest(isEnabled), - CSSStyles: { 'user-select': 'none', ...constants.cssStyles.text } - }).component(); - - const button = this._modelBuilder.button().withProperties({ - label: '', - title: '' - }).component(); - - button.label = this.getLabel(isEnabled); - button.onDidClick(async () => { - await updateFunction(!isEnabled); - const isEnabledNewValue = await checkEnabledFunction(); - button.label = this.getLabel(isEnabledNewValue); - }); - return [ - nameCell, - statusIconCell, - button - ]; - } - - private getConfigStatusIcon(enabled: boolean): string { - if (enabled) { - return '✔️'; - } else { - return '❌'; - } - } - - private getConfigStatusTest(enabled: boolean): string { - if (enabled) { - return constants.mlsEnableButtonTitle; - } else { - return constants.mlsDisableButtonTitle; - } - } - - private getLabel(isEnabled: boolean): string { - return isEnabled ? constants.mlsDisableButtonTitle : constants.mlsEnableButtonTitle; - } -} diff --git a/extensions/machine-learning-services/src/widgets/serverConfigWidgets.ts b/extensions/machine-learning-services/src/widgets/serverConfigWidgets.ts deleted file mode 100644 index ab5b64c4db..0000000000 --- a/extensions/machine-learning-services/src/widgets/serverConfigWidgets.ts +++ /dev/null @@ -1,69 +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 { ApiWrapper } from '../common/apiWrapper'; -import { ServerConfigManager } from '../serverConfig/serverConfigManager'; -import { ConfigTable } from './configTable'; - -export class ServerConfigWidget { - - constructor(private _apiWrapper: ApiWrapper, private _serverConfigManager: ServerConfigManager) { - } - - /** - * Registers the widget and initializes the components - */ - public register(): void { - azdata.ui.registerModelViewProvider('ml.tasks', async (view) => { - const container = view.modelBuilder.flexContainer().withLayout({ - flexFlow: 'column', - width: '100%', - height: '100%' - }).component(); - const mainContainer = view.modelBuilder.flexContainer().withLayout({ - flexFlow: 'column', - width: '270px', - height: '100%', - position: 'absolute' - }).component(); - mainContainer.addItem(container, { - CSSStyles: { - 'padding-top': '25px', - 'padding-left': '5px' - } - }); - let spinner = view.modelBuilder.loadingComponent() - .withItem(mainContainer) - .withProperties({ loading: true }) - .component(); - - const configTable = new ConfigTable(this._apiWrapper, this._serverConfigManager, view.modelBuilder, spinner); - - this.addRow(container, view, configTable.component); - - await view.initializeModel(spinner); - await configTable.refresh(); - }); - } - - private addRow(container: azdata.FlexContainer, view: azdata.ModelView, component: azdata.Component) { - const bookRow = view.modelBuilder.flexContainer().withLayout({ - flexFlow: 'row', - justifyContent: 'space-between', - height: '100' - }).component(); - bookRow.addItem(component, { - CSSStyles: { - 'width': '100', - 'hight': '100', - 'padding-top': '10px', - 'text-align': 'left' - } - }); - container.addItems([bookRow]); - } -} -