Fixed ML urls in dashboard (#10411)

* Fixed ML urls in dashboard
This commit is contained in:
Leila Lali
2020-05-15 11:07:31 -07:00
committed by GitHub
parent 1d1e21b579
commit 1bcda64a1b
10 changed files with 81 additions and 36 deletions

View File

@@ -30,22 +30,22 @@
"type": "object",
"title": "%mls.configuration.title%",
"properties": {
"machineLearningServices.enablePython": {
"machineLearning.enablePython": {
"type": "boolean",
"default": "true",
"description": "%mls.enablePython.description%"
},
"machineLearningServices.enableR": {
"machineLearning.enableR": {
"type": "boolean",
"default": "false",
"description": "%mls.enableR.description%"
},
"machineLearningServices.pythonPath": {
"machineLearning.pythonPath": {
"type": "string",
"default": "",
"description": "%mls.pythonPath.description%"
},
"machineLearningServices.rPath": {
"machineLearning.rPath": {
"type": "string",
"default": "",
"description": "%mls.rPath.description%"

View File

@@ -35,7 +35,7 @@ export const notebookCommandNew = 'notebook.command.new';
// Configurations
//
export const mlsConfigKey = 'machineLearningServices';
export const mlsConfigKey = 'machineLearning';
export const pythonPathConfigKey = 'pythonPath';
export const pythonEnabledConfigKey = 'enablePython';
export const rEnabledConfigKey = 'enableR';
@@ -125,10 +125,14 @@ export const extLangInstallFailedError = localize('extLang.installFailedError',
export const extLangUpdateFailedError = localize('extLang.updateFailedError', "Failed to update language");
export const modelUpdateFailedError = localize('models.modelUpdateFailedError', "Failed to update the model");
export const modelsListEmptyMessage = localize('models.modelsListEmptyMessage', "No Models Yet");
export const modelsListEmptyMessage = localize('models.modelsListEmptyMessage', "No models yet");
export const modelsListEmptyDescription = localize('models.modelsListEmptyDescription', "Use import wizard to add models to this table");
export const databaseName = localize('databaseName', "Models database");
export const databaseToStoreInfo = localize('databaseToStoreInfo', "Select a database to store the new model.");
export const tableToStoreInfo = localize('tableToStoreInfo', "Select an existing table that conforms the model schema or create a new one to store the new model.");
export const tableName = localize('tableName', "Models table");
export const modelTableInfo = localize('modelTableInfo', "Select a model table to view the list of existing / imported models.");
export const modelDatabaseInfo = localize('modelDatabaseInfo', "Select a database where existing / imported models are stored.");
export const existingTableName = localize('existingTableName', "Existing table");
export const newTableName = localize('newTableName', "New table");
export const modelName = localize('models.name', "Name");
@@ -143,7 +147,9 @@ export const browseModels = localize('models.browseButton', "...");
export const azureAccount = localize('models.azureAccount', "Azure account");
export const azureSignIn = localize('models.azureSignIn', "Sign in to Azure");
export const columnDatabase = localize('predict.columnDatabase', "Source database");
export const columnDatabaseInfo = localize('predict.columnDatabaseInfo', "Select the database containing the dataset to apply the prediction.");
export const columnTable = localize('predict.columnTable', "Source table");
export const columnTableInfo = localize('predict.columnTableInfo', "Select the table containing the dataset to apply the prediction.");
export const inputColumns = localize('predict.inputColumns', "Model Input mapping");
export const outputColumns = localize('predict.outputColumns', "Model output");
export const columnName = localize('predict.columnName', "Source columns");
@@ -173,13 +179,14 @@ export const currentModelsTitle = localize('models.currentModelsTitle', "Models"
export const azureRegisterModel = localize('models.azureRegisterModel', "Deploy");
export const predictModel = localize('models.predictModel', "Predict");
export const registerModelTitle = localize('models.RegisterWizard', "Import models");
export const importModelTitle = localize('models.importModelTitle', "Import models");
export const importedModelTitle = localize('models.importedModelTitle', "Imported models");
export const importModelTitle = localize('models.importModelTitle', "Import or view models");
export const editModelTitle = localize('models.editModelTitle', "Edit model");
export const importModelDesc = localize('models.importModelDesc', "Build, import and expose a machine learning model");
export const importModelDesc = localize('models.importModelDesc', "Import or view machine learning models stored in database");
export const makePredictionTitle = localize('models.makePredictionTitle', "Make predictions");
export const makePredictionDesc = localize('models.makePredictionDesc', "Generates a predicted value or scores using a managed model");
export const makePredictionDesc = localize('models.makePredictionDesc', "Generate a predicted value or scores using a managed model");
export const createNotebookTitle = localize('models.createNotebookTitle', "Create notebook");
export const createNotebookDesc = localize('models.createNotebookDesc', "Run experiments and create models");
export const createNotebookDesc = localize('models.createNotebookDesc', "Run experiments and create models in a notebook");
export const modelRegisteredSuccessfully = localize('models.modelRegisteredSuccessfully', "Model registered successfully");
export const modelUpdatedSuccessfully = localize('models.modelUpdatedSuccessfully', "Model updated successfully");
export const modelFailedToRegister = localize('models.modelFailedToRegistered', "Model failed to register");
@@ -204,7 +211,7 @@ export const selectModelsTableMessage = localize('models.selectModelsTableMessag
export const modelSchemaIsNotAcceptedMessage = localize('models.modelSchemaIsNotAcceptedMessage', "Invalid table structure");
export function importModelFailedError(modelName: string | undefined, filePath: string | undefined): string { return localize('models.importModelFailedError', "Failed to register the model: {0} ,file: {1}", modelName || '', filePath || ''); }
export function invalidImportTableError(databaseName: string | undefined, tableName: string | undefined): string { return localize('models.invalidImportTableError', "Invalid table for importing models. database name: {0} ,table name: {1}", databaseName || '', tableName || ''); }
export function invalidImportTableSchemaError(databaseName: string | undefined, tableName: string | undefined): string { return localize('models.invalidImportTableSchemaError', "Table schema is not supported for model import. database name: {0} ,table name: {1}", databaseName || '', tableName || ''); }
export function invalidImportTableSchemaError(databaseName: string | undefined, tableName: string | undefined): string { return localize('models.invalidImportTableSchemaError', "Table schema is not supported for model import. Database name: {0}, table name: {1}.", databaseName || '', tableName || ''); }
export const loadModelParameterFailedError = localize('models.loadModelParameterFailedError', "Failed to load model parameters'");
export const unsupportedModelParameterType = localize('models.unsupportedModelParameterType', "unsupported");
@@ -216,6 +223,8 @@ export const showMoreTitle = localize('showMoreTitle', "Show more");
export const showLessTitle = localize('showLessTitle', "Show less");
export const learnMoreTitle = localize('learnMoreTitle', "Learn more");
export const sqlMlDocTitle = localize('sqlMlDocTitle', "SQL machine learning documentation");
export const sqlMlExtDocTitle = localize('sqlMlExtDocTitle', "Machine Learning extension in Azure Data Studio");
export const sqlMlExtDocDesc = localize('sqlMlExtDocDesc', "Learn how to use Machine Learning extension in Azure Data Studio, to manage packages, make predictions, and import models.");
export const sqlMlDocDesc = localize('sqlMlDocDesc', "Learn how to use machine learning in SQL Server and SQL on Azure, to run Python and R scripts on relational data.");
export const sqlMlsDocTitle = localize('sqlMlsDocTitle', "SQL Server Machine Learning Services (Python and R)");
export const sqlMlsDocDesc = localize('sqlMlsDocDesc', "Get started with Machine Learning Services on SQL Server and how to install it on Windows and Linux.");
@@ -230,9 +239,11 @@ export const onnxOnEdgeOdbcDocDesc = localize('onnxOnEdgeOdbcDocDesc', "Get star
//
export const odbcDriverDocuments = 'https://go.microsoft.com/fwlink/?linkid=2129818';
export const mlDocLink = 'https://go.microsoft.com/fwlink/?linkid=2128671';
export const mlExtDocLink = 'https://go.microsoft.com/fwlink/?linkid=2129918';
export const mlsDocLink = 'https://go.microsoft.com/fwlink/?linkid=2128672';
export const mlsAzureDocLink = 'https://go.microsoft.com/fwlink/?linkid=2128673';
export const onnxOnEdgeDocs = 'https://go.microsoft.com/fwlink/?linkid=2128882';
export const managePackagesDocs = 'https://go.microsoft.com/fwlink/?linkid=2129919';
// CSS Styles
//

View File

@@ -96,7 +96,10 @@ export class PackageManager {
defaultProviderId: defaultProvider.providerId
});
} else {
this._apiWrapper.showInfoMessage(constants.managePackageCommandError);
const result = await this._apiWrapper.showInfoMessage(constants.managePackageCommandError, constants.learnMoreTitle);
if (result === constants.learnMoreTitle) {
await this._apiWrapper.openExternal(vscode.Uri.parse(constants.managePackagesDocs));
}
}
} catch (err) {
this._apiWrapper.showErrorMessage(err);

View File

@@ -48,14 +48,14 @@ 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.apiWrapper.setup(x => x.showInfoMessage(TypeMoq.It.isAny()));
testContext.apiWrapper.setup(x => x.showInfoMessage(TypeMoq.It.isAny(), TypeMoq.It.isAny()));
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());
testContext.apiWrapper.verify(x => x.showInfoMessage(TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
});
it('Manage Package command Should show an error for no connection', async function (): Promise<void> {
@@ -63,12 +63,12 @@ describe('Package Manager', () => {
let connection: 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.apiWrapper.setup(x => x.showInfoMessage(TypeMoq.It.isAny()));
testContext.apiWrapper.setup(x => x.showInfoMessage(TypeMoq.It.isAny(), TypeMoq.It.isAny()));
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());
testContext.apiWrapper.verify(x => x.showInfoMessage(TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
});
it('installDependencies Should download sqlmlutils if does not exist', async function (): Promise<void> {

View File

@@ -39,8 +39,15 @@ export class CurrentModelsComponent extends ModelViewBase implements IPageView {
* @param modelBuilder register the components
*/
public registerComponent(modelBuilder: azdata.ModelBuilder): azdata.Component {
this._tableSelectionComponent = new TableSelectionComponent(this._apiWrapper, this, { editable: false, preSelected: true });
this._tableSelectionComponent.registerComponent(modelBuilder, constants.databaseName, constants.tableName);
this._tableSelectionComponent = new TableSelectionComponent(this._apiWrapper, this, {
editable: false,
preSelected: true,
databaseTitle: constants.databaseName,
tableTitle: constants.tableName,
databaseInfo: constants.modelDatabaseInfo,
tableInfo: constants.modelTableInfo
});
this._tableSelectionComponent.registerComponent(modelBuilder);
this._tableSelectionComponent.onSelectedChanged(async () => {
await this.onTableSelected();
});

View File

@@ -34,12 +34,12 @@ export class ManageModelsDialog extends ModelViewBase {
selectable: false
});
let registerModelButton = this._apiWrapper.createButton(constants.importModelTitle);
let registerModelButton = this._apiWrapper.createButton(constants.registerModelTitle);
registerModelButton.onClick(async () => {
await this.sendDataRequest(RegisterModelEventName, this.currentLanguagesTab?.modelTable?.importTable);
});
let dialog = this.dialogView.createDialog(constants.registerModelTitle, [this.currentLanguagesTab]);
let dialog = this.dialogView.createDialog(constants.importedModelTitle, [this.currentLanguagesTab]);
dialog.isWide = true;
dialog.customButtons = [registerModelButton];
this.mainViewPanel = dialog;

View File

@@ -35,7 +35,15 @@ export class ModelImportLocationPage extends ModelViewBase implements IPageView,
public registerComponent(modelBuilder: azdata.ModelBuilder): azdata.Component {
this._formBuilder = modelBuilder.formContainer();
this.tableSelectionComponent = new TableSelectionComponent(this._apiWrapper, this, { editable: true, preSelected: true });
this.tableSelectionComponent = new TableSelectionComponent(this._apiWrapper, this,
{
editable: true,
preSelected: true,
databaseTitle: constants.databaseName,
tableTitle: constants.tableName,
databaseInfo: constants.databaseToStoreInfo,
tableInfo: constants.tableToStoreInfo
});
this._descriptionComponent = modelBuilder.text().withProperties({
width: 200
}).component();
@@ -74,7 +82,7 @@ export class ModelImportLocationPage extends ModelViewBase implements IPageView,
this.tableSelectionComponent.onSelectedChanged(async () => {
await this.onTableSelected();
});
this.tableSelectionComponent.registerComponent(modelBuilder, constants.databaseName, constants.tableName);
this.tableSelectionComponent.registerComponent(modelBuilder);
this.tableSelectionComponent.addComponents(this._formBuilder);
this._formBuilder.addFormItem({

View File

@@ -35,8 +35,16 @@ export class InputColumnsComponent extends ModelViewBase implements IDataCompone
* @param modelBuilder model builder
*/
public registerComponent(modelBuilder: azdata.ModelBuilder): azdata.Component {
this._tableSelectionComponent = new TableSelectionComponent(this._apiWrapper, this, { editable: false, preSelected: false });
this._tableSelectionComponent.registerComponent(modelBuilder, constants.columnDatabase, constants.columnTable);
this._tableSelectionComponent = new TableSelectionComponent(this._apiWrapper, this,
{
editable: false,
preSelected: false,
databaseTitle: constants.columnDatabase,
tableTitle: constants.columnTable,
databaseInfo: constants.columnDatabaseInfo,
tableInfo: constants.columnTableInfo
});
this._tableSelectionComponent.registerComponent(modelBuilder);
this._tableSelectionComponent.onSelectedChanged(async () => {
await this.onTableSelected();
});

View File

@@ -13,7 +13,11 @@ import * as constants from '../../common/constants';
export interface ITableSelectionSettings {
editable: boolean,
preSelected: boolean
preSelected: boolean,
databaseTitle: string,
tableTitle: string,
databaseInfo: string,
tableInfo: string
}
/**
* View to render filters to pick an azure resource
@@ -47,7 +51,7 @@ export class TableSelectionComponent extends ModelViewBase implements IDataCompo
* Register components
* @param modelBuilder model builder
*/
public registerComponent(modelBuilder: azdata.ModelBuilder, databaseTitle: string, tableTitle: string): azdata.Component {
public registerComponent(modelBuilder: azdata.ModelBuilder): azdata.Component {
this._databases = modelBuilder.dropDown().withProperties({
width: this.componentMaxLength,
}).component();
@@ -111,23 +115,23 @@ export class TableSelectionComponent extends ModelViewBase implements IDataCompo
});
const databaseForm = modelBuilder.formContainer().withFormItems([{
title: databaseTitle,
title: this._settings.databaseTitle,
component: this._databases,
}], { info: databaseTitle }).withLayout({
}], { info: this._settings.databaseInfo }).withLayout({
padding: '0px'
}).component();
const tableForm = modelBuilder.formContainer();
if (this._settings.editable) {
tableForm.addFormItem({
title: tableTitle,
title: this._settings.tableTitle,
component: group
}, { info: tableTitle });
}, { info: this._settings.tableInfo });
} else {
tableForm.addFormItem({
title: tableTitle,
title: this._settings.tableTitle,
component: this._tables
}, { info: tableTitle });
}, { info: this._settings.tableInfo });
}
this._dbTableComponent = modelBuilder.flexContainer().withItems([

View File

@@ -339,6 +339,10 @@ export class DashboardWidget {
}).component();
const links = [{
title: constants.sqlMlExtDocTitle,
description: constants.sqlMlExtDocDesc,
link: constants.mlExtDocLink
}, {
title: constants.sqlMlDocTitle,
description: constants.sqlMlDocDesc,
link: constants.mlDocLink
@@ -461,7 +465,7 @@ export class DashboardWidget {
dark: this.asAbsolutePath('images/makePredictions.svg'),
light: this.asAbsolutePath('images/makePredictions.svg'),
},
link: '',
link: 'https://go.microsoft.com/fwlink/?linkid=2129795',
command: constants.mlsPredictModelCommand
};
const predictionButton = this.createTaskButton(view, predictionMetadata);
@@ -472,7 +476,7 @@ export class DashboardWidget {
dark: this.asAbsolutePath('images/manageModels.svg'),
light: this.asAbsolutePath('images/manageModels.svg'),
},
link: '',
link: 'https://go.microsoft.com/fwlink/?linkid=2129796',
command: constants.mlManageModelsCommand
};
const importModelsButton = this.createTaskButton(view, importMetadata);
@@ -483,7 +487,7 @@ export class DashboardWidget {
dark: this.asAbsolutePath('images/createNotebook.svg'),
light: this.asAbsolutePath('images/createNotebook.svg'),
},
link: '',
link: 'https://go.microsoft.com/fwlink/?linkid=2129920',
command: constants.notebookCommandNew
};
const notebookModelsButton = this.createTaskButton(view, notebookMetadata);
@@ -551,7 +555,7 @@ export class DashboardWidget {
CSSStyles: {
'padding': '0px',
'padding-bottom': '5px',
'width': '180px',
'width': '200px',
'margin': '0px',
'color': '#006ab1'
}