Notebook: Re-Enable Attach to Dropdown Functionality (#3250)

* first attach to working

* Transfer changes from sqlopsstudioextensions PR 448

* Transfer changes from sqlopsstudioextensions PR 447

* Transfer changes from sqlopsstudioextensions PR 456

* Transfer changes from sqlopsstudioextensions PR 465

* Transfer changes from sqlopsstudioextensions PR 463

* Transfer changes from sqlopsstudioextensions PR 482

* Transfer changes from sqlopsstudioextensions PR 485

* Session and Kernel implementation except executeRequest

* Attach to port compiling

* Further tweaks to attach to dropdown, re-enable opening connection dialog

* Revert "Merge remote-tracking branch 'origin/Notebook/sessionExtension' into feature/workingAttachTo"

This reverts commit 94703db87c85416c4ae36762afc1094d6e71166a, reversing
changes made to e4dc25331036d259e9c762cfe8741f957bb5c590.

* Fix code formatting

* Fix for new Add new connection issue
This commit is contained in:
Chris LaFreniere
2018-11-16 20:47:58 -08:00
committed by GitHub
parent c02fbaeae7
commit bbb27aed10
8 changed files with 227 additions and 64 deletions

View File

@@ -9,18 +9,23 @@ import { Action } from 'vs/base/common/actions';
import { TPromise } from 'vs/base/common/winjs.base';
import { localize } from 'vs/nls';
import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';
import { INotificationService, Severity, INotificationActions } from 'vs/platform/notification/common/notification';
import { SelectBox, ISelectBoxOptionsWithLabel } from 'sql/base/browser/ui/selectBox/selectBox';
import { INotebookModel } from 'sql/parts/notebook/models/modelInterfaces';
import { CellTypes, CellType } from 'sql/parts/notebook/models/contracts';
import { INotebookModel, notebookConstants } from 'sql/parts/notebook/models/modelInterfaces';
import { CellType } from 'sql/parts/notebook/models/contracts';
import { NotebookComponent } from 'sql/parts/notebook/notebook.component';
import { INotificationService, Severity, INotificationActions } from 'vs/platform/notification/common/notification';
import { NotificationService } from 'vs/workbench/services/notification/common/notificationService';
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
import { IConnectionManagementService, IConnectionDialogService } from 'sql/parts/connection/common/connectionManagement';
import { getErrorMessage } from 'sql/parts/notebook/notebookUtils';
const msgLoading = localize('loading', 'Loading kernels...');
const kernelLabel: string = localize('Kernel', 'Kernel: ');
const attachToLabel: string = localize('AttachTo', 'Attach to: ');
const msgLocalHost: string = localize('localhost', 'Localhost');
const msgLoadingContexts = localize('loadingContexts', 'Loading contexts...');
const msgAddNewConnection = localize('addNewConnection', 'Add new connection');
const msgSelectConnection = localize('selectConnection', 'Select connection');
const msgConnectionNotApplicable = localize('connectionNotSupported', 'n/a');
// Action to add a cell to notebook based on cell type(code/markdown).
export class AddCellAction extends Action {
@@ -178,11 +183,128 @@ export class KernelsDropdown extends SelectBox {
}
export class AttachToDropdown extends SelectBox {
constructor(container: HTMLElement, contextViewProvider: IContextViewProvider) {
let selectBoxOptionsWithLabel: ISelectBoxOptionsWithLabel = {
labelText: attachToLabel,
labelOnTop: false
};
super([msgLocalHost], msgLocalHost, contextViewProvider, container, selectBoxOptionsWithLabel);
private model: INotebookModel;
constructor(container: HTMLElement, contextViewProvider: IContextViewProvider, modelRegistered: Promise<INotebookModel>,
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
@IConnectionDialogService private _connectionDialogService: IConnectionDialogService,
@INotificationService private _notificationService: INotificationService) {
super([msgLoadingContexts], msgLoadingContexts, contextViewProvider, container, { labelText: attachToLabel, labelOnTop: false } as ISelectBoxOptionsWithLabel);
if (modelRegistered) {
modelRegistered
.then((model) => this.updateModel(model))
.catch((err) => {
// No-op for now
});
}
this.onDidSelect(e => {
let connection = this.model.contexts.otherConnections.find((c) => c.options.host === e.selected);
this.doChangeContext(connection);
});
}
public updateModel(model: INotebookModel): void {
this.model = model;
model.contextsChanged(() => {
if (this.model.clientSession.kernel && this.model.clientSession.kernel.name) {
let currentKernel = this.model.clientSession.kernel.name;
this.loadAttachToDropdown(this.model, currentKernel);
}
});
}
// Load "Attach To" dropdown with the values corresponding to Kernel dropdown
public async loadAttachToDropdown(model: INotebookModel, currentKernel: string): Promise<void> {
if (currentKernel === notebookConstants.python3) {
this.setOptions([msgConnectionNotApplicable]);
this.disable();
}
else {
let hadoopConnections = this.getHadoopConnections(model);
this.enable();
if (hadoopConnections.length === 1 && hadoopConnections[0] === msgAddNewConnection) {
hadoopConnections.unshift(msgSelectConnection);
this.selectWithOptionName(msgSelectConnection);
}
else {
hadoopConnections.push(msgAddNewConnection);
}
this.setOptions(hadoopConnections);
}
}
//Get hadoop connections from context
public getHadoopConnections(model: INotebookModel): string[] {
let otherHadoopConnections: IConnectionProfile[] = [];
model.contexts.otherConnections.forEach((conn) => { otherHadoopConnections.push(conn); });
this.selectWithOptionName(model.contexts.defaultConnection.options.host);
otherHadoopConnections = this.setHadoopConnectionsList(model.contexts.defaultConnection, model.contexts.otherConnections);
let hadoopConnections = otherHadoopConnections.map((context) => context.options.host);
return hadoopConnections;
}
private setHadoopConnectionsList(defaultHadoopConnection: IConnectionProfile, otherHadoopConnections: IConnectionProfile[]) {
if (defaultHadoopConnection.options.host !== msgSelectConnection) {
otherHadoopConnections = otherHadoopConnections.filter(conn => conn.options.host !== defaultHadoopConnection.options.host);
otherHadoopConnections.unshift(defaultHadoopConnection);
if (otherHadoopConnections.length > 1) {
otherHadoopConnections = otherHadoopConnections.filter(val => val.options.host !== msgSelectConnection);
}
}
return otherHadoopConnections;
}
public doChangeContext(connection?: IConnectionProfile): void {
if (this.value === msgAddNewConnection) {
this.openConnectionDialog();
} else {
this.model.changeContext(this.value, connection);
}
}
/**
* Open connection dialog
* Enter server details and connect to a server from the dialog
* Bind the server value to 'Attach To' drop down
* Connected server is displayed at the top of drop down
**/
public async openConnectionDialog(): Promise<void> {
try {
//TODO: Figure out how to plumb through the correct provider here
await this._connectionDialogService.openDialogAndWait(this._connectionManagementService, { connectionType: 1, providers: [notebookConstants.hadoopKnoxProviderName] }).then(connection => {
let attachToConnections = this.values;
if (!connection) {
this.loadAttachToDropdown(this.model, this.model.clientSession.kernel.name);
return;
}
let connectedServer = connection.options[notebookConstants.hostPropName];
//Check to see if the same host is already there in dropdown. We only have host names in dropdown
if (attachToConnections.some(val => val === connectedServer)) {
this.loadAttachToDropdown(this.model, this.model.clientSession.kernel.name);
this.doChangeContext();
return;
}
else {
attachToConnections.unshift(connectedServer);
}
//To ignore n/a after we have at least one valid connection
attachToConnections = attachToConnections.filter(val => val !== msgSelectConnection);
let index = attachToConnections.findIndex((connection => connection === connectedServer));
this.setOptions(attachToConnections);
if (!index || index < 0 || index >= attachToConnections.length) {
index = 0;
}
this.select(index);
// Call doChangeContext to set the newly chosen connection in the model
this.doChangeContext(connection);
});
}
catch (error) {
const actions: INotificationActions = { primary: [] };
this._notificationService.notify({ severity: Severity.Error, message: getErrorMessage(error), actions });
}
}
}