Notebook Views (#13465)

* Add notebook editor

Introduce notebook editor component to allow for separate notebook displays in order to accomodate notebook views

* Localize notebook views configuration title

* Refactor view mode and remove the views configuration while it is unused

* Only fire view mode changed event when the value has been changed

* Remove notebook views contribution
This commit is contained in:
Daniel Grajeda
2020-12-27 14:08:27 -07:00
committed by GitHub
parent f314a9e1e6
commit 11f236ade1
8 changed files with 254 additions and 88 deletions

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { nb } from 'azdata';
import { OnInit, Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, ViewChild, OnDestroy, ViewChildren, QueryList } from '@angular/core';
import { OnInit, Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, ViewChild, OnDestroy, ViewChildren, QueryList, Input } from '@angular/core';
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
import * as themeColors from 'vs/workbench/common/theme';
@@ -22,21 +22,17 @@ import * as DOM from 'vs/base/browser/dom';
import { AngularDisposable } from 'sql/base/browser/lifecycle';
import { CellTypes, CellType, NotebookChangeType } from 'sql/workbench/services/notebook/common/contracts';
import { ICellModel, IModelFactory, INotebookModel, NotebookContentChange } from 'sql/workbench/services/notebook/browser/models/modelInterfaces';
import { ICellModel, INotebookModel, NotebookContentChange } from 'sql/workbench/services/notebook/browser/models/modelInterfaces';
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
import { INotebookService, INotebookParams, INotebookManager, INotebookEditor, DEFAULT_NOTEBOOK_PROVIDER, SQL_NOTEBOOK_PROVIDER, INotebookSection, INavigationProvider, ICellEditorProvider, NotebookRange } from 'sql/workbench/services/notebook/browser/notebookService';
import { INotebookService, INotebookParams, INotebookEditor, INotebookSection, INavigationProvider, ICellEditorProvider, NotebookRange } from 'sql/workbench/services/notebook/browser/notebookService';
import { NotebookModel } from 'sql/workbench/services/notebook/browser/models/notebookModel';
import { ModelFactory } from 'sql/workbench/services/notebook/browser/models/modelFactory';
import * as notebookUtils from 'sql/workbench/services/notebook/browser/models/notebookUtils';
import { Deferred } from 'sql/base/common/promise';
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
import { Taskbar } from 'sql/base/browser/ui/taskbar/taskbar';
import { AddCellAction, KernelsDropdown, AttachToDropdown, TrustedAction, RunAllCellsAction, ClearAllOutputsAction, CollapseCellsAction } from 'sql/workbench/contrib/notebook/browser/notebookActions';
import { DropdownMenuActionViewItem } from 'sql/base/browser/ui/buttonMenu/buttonMenu';
import { ISingleNotebookEditOperation } from 'sql/workbench/api/common/sqlExtHostTypes';
import { IConnectionDialogService } from 'sql/workbench/services/connection/common/connectionDialogService';
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
import { CellMagicMapper } from 'sql/workbench/contrib/notebook/browser/models/cellMagicMapper';
import { CellModel } from 'sql/workbench/services/notebook/browser/models/cell';
import { FileOperationError, FileOperationResult } from 'vs/platform/files/common/files';
import { isValidBasename } from 'vs/base/common/extpath';
@@ -54,7 +50,6 @@ import { CodeCellComponent } from 'sql/workbench/contrib/notebook/browser/cellVi
import { TextCellComponent } from 'sql/workbench/contrib/notebook/browser/cellViews/textCell.component';
import { NotebookInput } from 'sql/workbench/contrib/notebook/browser/models/notebookInput';
import { IColorTheme } from 'vs/platform/theme/common/themeService';
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { CellToolbarComponent } from 'sql/workbench/contrib/notebook/browser/cellViews/cellToolbar.component';
@@ -73,12 +68,11 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe
@ViewChildren(TextCellComponent) private textCells: QueryList<TextCellComponent>;
@ViewChildren(CellToolbarComponent) private cellToolbar: QueryList<CellToolbarComponent>;
private _model: NotebookModel;
@Input() _model: NotebookModel;
protected _actionBar: Taskbar;
protected isLoading: boolean;
private notebookManagers: INotebookManager[] = [];
private _modelReadyDeferred = new Deferred<NotebookModel>();
private profile: IConnectionProfile;
private _trustedAction: TrustedAction;
private _runAllCellsAction: RunAllCellsAction;
private _providerRelatedActions: IAction[] = [];
@@ -106,11 +100,9 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe
@Inject(ICapabilitiesService) private capabilitiesService: ICapabilitiesService,
@Inject(ITextFileService) private textFileService: ITextFileService,
@Inject(ILogService) private readonly logService: ILogService,
@Inject(IAdsTelemetryService) private adstelemetryService: IAdsTelemetryService,
@Inject(IConfigurationService) private _configurationService: IConfigurationService
) {
super();
this.updateProfile();
this.isLoading = true;
this.doubleClickEditEnabled = this._configurationService.getValue('notebook.enableDoubleClickEdit');
this._register(this._configurationService.onDidChangeConfiguration(e => {
@@ -121,15 +113,12 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe
}));
}
private updateProfile(): void {
this.profile = this.notebookParams ? this.notebookParams.profile : undefined;
}
ngOnInit() {
this._register(this.themeService.onDidColorThemeChange(this.updateTheme, this));
this.updateTheme(this.themeService.getColorTheme());
this.initActionBar();
this.setScrollPosition();
this.doLoad().catch(e => onUnexpectedError(e));
this.initNavSection();
}
@@ -260,11 +249,11 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe
private async doLoad(): Promise<void> {
try {
await this.createModelAndLoadContents();
await this.registerModel();
this._modelReadyDeferred.resolve(this._model);
this.notebookService.addNotebookEditor(this);
await this.setNotebookManager();
await this.loadModel();
await this._model.onClientSessionReady;
this.detectChanges();
} catch (error) {
if (error) {
// Offer to create a file from the error if we have a file not found and the name is valid
@@ -305,41 +294,14 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe
this.detectChanges();
}
private async loadModel(): Promise<void> {
// Wait on provider information to be available before loading kernel and other information
await this.awaitNonDefaultProvider();
await this._model.requestModelLoad();
this.detectChanges();
this.setContextKeyServiceWithProviderId(this._model.providerId);
await this._model.startSession(this._model.notebookManager, undefined, true);
this.fillInActionsForCurrentContext();
this.detectChanges();
}
private async registerModel(): Promise<void> {
this._register(this._model.onError((errInfo: INotification) => this.handleModelError(errInfo)));
this._register(this._model.contentChanged((change) => this.handleContentChanged(change)));
this._register(this._model.onProviderIdChange((provider) => this.handleProviderIdChanged(provider)));
this._register(this._model.kernelChanged((kernelArgs) => this.handleKernelChanged(kernelArgs)));
this._register(this._model.onCellTypeChanged(() => this.detectChanges()));
this._register(this._model.layoutChanged(() => this.detectChanges()));
private async createModelAndLoadContents(): Promise<void> {
let model = new NotebookModel({
factory: this.modelFactory,
notebookUri: this._notebookParams.notebookUri,
connectionService: this.connectionManagementService,
notificationService: this.notificationService,
notebookManagers: this.notebookManagers,
contentManager: this._notebookParams.input.contentManager,
cellMagicMapper: new CellMagicMapper(this.notebookService.languageMagics),
providerId: 'sql',
defaultKernel: this._notebookParams.input.defaultKernel,
layoutChanged: this._notebookParams.input.layoutChanged,
capabilitiesService: this.capabilitiesService,
editorLoadedTimestamp: this._notebookParams.input.editorOpenedTimestamp
}, this.profile, this.logService, this.notificationService, this.adstelemetryService, this.connectionManagementService, this._configurationService, this.capabilitiesService);
let trusted = await this.notebookService.isNotebookTrustCached(this._notebookParams.notebookUri, this.isDirty());
this._register(model.onError((errInfo: INotification) => this.handleModelError(errInfo)));
this._register(model.contentChanged((change) => this.handleContentChanged(change)));
this._register(model.onProviderIdChange((provider) => this.handleProviderIdChanged(provider)));
this._register(model.kernelChanged((kernelArgs) => this.handleKernelChanged(kernelArgs)));
this._register(model.onCellTypeChanged(() => this.detectChanges()));
this._register(model.layoutChanged(() => this.detectChanges()));
this._model = this._register(model);
await this._model.loadContents(trusted);
this.setLoading(false);
// Check if URI fragment is present; if it is, navigate to section by default
this.navigateToSectionIfURIFragmentExists();
@@ -347,28 +309,6 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe
this.detectChanges();
}
private async setNotebookManager(): Promise<void> {
let providerInfo = await this._notebookParams.providerInfo;
for (let providerId of providerInfo.providers) {
let notebookManager = await this.notebookService.getOrCreateNotebookManager(providerId, this._notebookParams.notebookUri);
this.notebookManagers.push(notebookManager);
}
}
private async awaitNonDefaultProvider(): Promise<void> {
// Wait on registration for now. Long-term would be good to cache and refresh
await this.notebookService.registrationComplete;
this.model.standardKernels = this._notebookParams.input.standardKernels;
// Refresh the provider if we had been using default
let providerInfo = await this._notebookParams.providerInfo;
if (DEFAULT_NOTEBOOK_PROVIDER === providerInfo.providerId) {
let providers = notebookUtils.getProvidersForFileName(this._notebookParams.notebookUri.fsPath, this.notebookService);
let tsqlProvider = providers.find(provider => provider === SQL_NOTEBOOK_PROVIDER);
providerInfo.providerId = tsqlProvider ? SQL_NOTEBOOK_PROVIDER : providers[0];
}
}
private updateToolbarComponents() {
this._trustedAction.enabled = true;
if (this.model.trustedMode) {
@@ -376,13 +316,6 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe
}
}
private get modelFactory(): IModelFactory {
if (!this._notebookParams.modelFactory) {
this._notebookParams.modelFactory = new ModelFactory(this.instantiationService);
}
return this._notebookParams.modelFactory;
}
private handleModelError(notification: INotification): void {
this.notificationService.notify(notification);
}

View File

@@ -32,6 +32,7 @@ import { ICellComponentRegistry, Extensions as OutputComponentExtensions } from
import { CollapseComponent } from 'sql/workbench/contrib/notebook/browser/cellViews/collapse.component';
import { MarkdownToolbarComponent } from 'sql/workbench/contrib/notebook/browser/cellViews/markdownToolbar.component';
import { CellToolbarComponent } from 'sql/workbench/contrib/notebook/browser/cellViews/cellToolbar.component';
import { NotebookEditorComponent } from 'sql/workbench/contrib/notebook/browser/notebookEditor.component';
const outputComponentRegistry = Registry.as<ICellComponentRegistry>(OutputComponentExtensions.CellComponentContributions);
@@ -52,6 +53,7 @@ export const NotebookModule = (params, selector: string, instantiationService: I
MarkdownToolbarComponent,
PlaceholderCellComponent,
NotebookComponent,
NotebookEditorComponent,
ComponentHostDirective,
OutputAreaComponent,
OutputComponent,
@@ -62,6 +64,7 @@ export const NotebookModule = (params, selector: string, instantiationService: I
],
entryComponents: [
NotebookComponent,
NotebookEditorComponent,
...outputComponents
],
imports: [
@@ -86,7 +89,7 @@ export const NotebookModule = (params, selector: string, instantiationService: I
}
ngDoBootstrap(appRef: ApplicationRef) {
const factoryWrapper: any = this._resolver.resolveComponentFactory(NotebookComponent);
const factoryWrapper: any = this._resolver.resolveComponentFactory(NotebookEditorComponent);
factoryWrapper.factory.selector = this.selector;
appRef.bootstrap(factoryWrapper);
}

View File

@@ -0,0 +1,9 @@
<!--
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-->
<!-- Notebook View -->
<notebook-component *ngIf="viewMode === 0" [_model]="model"></notebook-component>
<!-- Dashboard View: To be implemented-->

View File

@@ -0,0 +1,185 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Component, Inject, ChangeDetectorRef, forwardRef } from '@angular/core';
import { NotebookModel } from 'sql/workbench/services/notebook/browser/models/notebookModel';
import * as notebookUtils from 'sql/workbench/services/notebook/browser/models/notebookUtils';
import { AngularDisposable } from 'sql/base/browser/lifecycle';
import { IBootstrapParams } from 'sql/workbench/services/bootstrap/common/bootstrapParams';
import { INotebookParams, INotebookService, INotebookManager, DEFAULT_NOTEBOOK_PROVIDER, SQL_NOTEBOOK_PROVIDER } from 'sql/workbench/services/notebook/browser/notebookService';
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
import { CellMagicMapper } from 'sql/workbench/contrib/notebook/browser/models/cellMagicMapper';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
import { ILogService } from 'vs/platform/log/common/log';
import { IModelFactory, ViewMode, NotebookContentChange } from 'sql/workbench/services/notebook/browser/models/modelInterfaces';
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ModelFactory } from 'sql/workbench/services/notebook/browser/models/modelFactory';
import { onUnexpectedError } from 'vs/base/common/errors';
import { IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { IAction } from 'vs/base/common/actions';
import { IMenuService, MenuId } from 'vs/platform/actions/common/actions';
import { fillInActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
export const NOTEBOOKEDITOR_SELECTOR: string = 'notebookeditor-component';
@Component({
selector: NOTEBOOKEDITOR_SELECTOR,
templateUrl: decodeURI(require.toUrl('./notebookEditor.component.html'))
})
export class NotebookEditorComponent extends AngularDisposable {
private profile: IConnectionProfile;
private notebookManagers: INotebookManager[] = [];
private _model: NotebookModel;
constructor(
@Inject(ILogService) private readonly logService: ILogService,
@Inject(IBootstrapParams) private _notebookParams: INotebookParams,
@Inject(INotebookService) private notebookService: INotebookService,
@Inject(ICapabilitiesService) private capabilitiesService: ICapabilitiesService,
@Inject(IContextKeyService) private contextKeyService: IContextKeyService,
@Inject(IMenuService) private menuService: IMenuService,
@Inject(INotificationService) private notificationService: INotificationService,
@Inject(IAdsTelemetryService) private adstelemetryService: IAdsTelemetryService,
@Inject(IInstantiationService) private instantiationService: IInstantiationService,
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef,
@Inject(IConfigurationService) private _configurationService: IConfigurationService,
@Inject(IConnectionManagementService) private connectionManagementService: IConnectionManagementService,
) {
super();
this.updateProfile();
}
ngOnInit() {
this.doLoad().catch(e => onUnexpectedError(e));
}
private updateProfile(): void {
this.profile = this._notebookParams ? this._notebookParams.profile : undefined;
}
private detectChanges(): void {
if (!(this._changeRef['destroyed'])) {
this._changeRef.detectChanges();
}
}
private async doLoad(): Promise<void> {
await this.createModelAndLoadContents();
await this.setNotebookManager();
await this.loadModel();
}
private async loadModel(): Promise<void> {
// Wait on provider information to be available before loading kernel and other information
await this.awaitNonDefaultProvider();
await this.model.requestModelLoad();
this.detectChanges();
this.setContextKeyServiceWithProviderId(this.model.providerId);
await this.model.startSession(this.model.notebookManager, undefined, true);
this.fillInActionsForCurrentContext();
this.detectChanges();
}
private async createModelAndLoadContents(): Promise<void> {
let model = new NotebookModel({
factory: this.modelFactory,
notebookUri: this._notebookParams.notebookUri,
connectionService: this.connectionManagementService,
notificationService: this.notificationService,
notebookManagers: this.notebookManagers,
contentManager: this._notebookParams.input.contentManager,
cellMagicMapper: new CellMagicMapper(this.notebookService.languageMagics),
providerId: 'sql',
defaultKernel: this._notebookParams.input.defaultKernel,
layoutChanged: this._notebookParams.input.layoutChanged,
capabilitiesService: this.capabilitiesService,
editorLoadedTimestamp: this._notebookParams.input.editorOpenedTimestamp
}, this.profile, this.logService, this.notificationService, this.adstelemetryService, this.connectionManagementService, this._configurationService, this.capabilitiesService);
let trusted = await this.notebookService.isNotebookTrustCached(this._notebookParams.notebookUri, this.isDirty());
this._model = this._register(model);
await this.model.loadContents(trusted);
this._register(model.viewModeChanged((mode) => this.onViewModeChanged()));
this._register(model.contentChanged((change) => this.handleContentChanged(change)));
this._register(model.onCellTypeChanged(() => this.detectChanges()));
this._register(model.layoutChanged(() => this.detectChanges()));
this.detectChanges();
}
private async setNotebookManager(): Promise<void> {
let providerInfo = await this._notebookParams.providerInfo;
for (let providerId of providerInfo.providers) {
let notebookManager = await this.notebookService.getOrCreateNotebookManager(providerId, this._notebookParams.notebookUri);
this.notebookManagers.push(notebookManager);
}
}
private setContextKeyServiceWithProviderId(providerId: string) {
let provider = new RawContextKey<string>('providerId', providerId);
provider.bindTo(this.contextKeyService);
}
private async awaitNonDefaultProvider(): Promise<void> {
// Wait on registration for now. Long-term would be good to cache and refresh
await this.notebookService.registrationComplete;
this.model.standardKernels = this._notebookParams.input.standardKernels;
// Refresh the provider if we had been using default
let providerInfo = await this._notebookParams.providerInfo;
if (DEFAULT_NOTEBOOK_PROVIDER === providerInfo.providerId) {
let providers = notebookUtils.getProvidersForFileName(this._notebookParams.notebookUri.fsPath, this.notebookService);
let tsqlProvider = providers.find(provider => provider === SQL_NOTEBOOK_PROVIDER);
providerInfo.providerId = tsqlProvider ? SQL_NOTEBOOK_PROVIDER : providers[0];
}
}
/**
* Get all of the menu contributions that use the ID 'notebook/toolbar'.
* Then, find all groups (currently we don't leverage the contributed
* groups functionality for the notebook toolbar), and fill in the 'primary'
* array with items that don't list a group. Finally, add any actions from
* the primary array to the end of the toolbar.
*/
private fillInActionsForCurrentContext(): void {
let primary: IAction[] = [];
let secondary: IAction[] = [];
let notebookBarMenu = this.menuService.createMenu(MenuId.NotebookToolbar, this.contextKeyService);
let groups = notebookBarMenu.getActions({ arg: null, shouldForwardArgs: true });
fillInActions(groups, { primary, secondary }, false, (group: string) => group === undefined || group === '');
//this.addPrimaryContributedActions(primary);
}
private get modelFactory(): IModelFactory {
if (!this._notebookParams.modelFactory) {
this._notebookParams.modelFactory = new ModelFactory(this.instantiationService);
}
return this._notebookParams.modelFactory;
}
public get model(): NotebookModel | null {
return this._model;
}
public get viewMode(): ViewMode {
return this.model?.viewMode;
}
private isDirty(): boolean {
return this._notebookParams.input.isDirty();
}
private handleContentChanged(change: NotebookContentChange) {
// Note: for now we just need to set dirty state and refresh the UI.
this.detectChanges();
}
public onViewModeChanged(): void {
this.detectChanges();
}
}

View File

@@ -13,7 +13,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { CancellationToken } from 'vs/base/common/cancellation';
import { NotebookInput } from 'sql/workbench/contrib/notebook/browser/models/notebookInput';
import { NotebookModule } from 'sql/workbench/contrib/notebook/browser/notebook.module';
import { NOTEBOOK_SELECTOR } from 'sql/workbench/contrib/notebook/browser/notebook.component';
import { NOTEBOOKEDITOR_SELECTOR } from 'sql/workbench/contrib/notebook/browser/notebookEditor.component';
import { INotebookParams, INotebookService, NotebookRange } from 'sql/workbench/services/notebook/browser/notebookService';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { ACTION_IDS, NOTEBOOK_MAX_MATCHES, IFindNotebookController, FindWidget, IConfigurationChangedEvent } from 'sql/workbench/contrib/notebook/browser/find/notebookFindWidget';
@@ -235,7 +235,7 @@ export class NotebookEditor extends EditorPane implements IFindNotebookControlle
this._instantiationService.invokeFunction(bootstrapAngular,
NotebookModule,
this._notebookContainer,
NOTEBOOK_SELECTOR,
NOTEBOOKEDITOR_SELECTOR,
params,
input
);

View File

@@ -5,7 +5,7 @@
import { nb, IConnectionProfile } from 'azdata';
import * as vsEvent from 'vs/base/common/event';
import { INotebookModel, ICellModel, IClientSession, NotebookContentChange, ISingleNotebookEditOperation, MoveDirection } from 'sql/workbench/services/notebook/browser/models/modelInterfaces';
import { INotebookModel, ICellModel, IClientSession, NotebookContentChange, ISingleNotebookEditOperation, MoveDirection, ViewMode } from 'sql/workbench/services/notebook/browser/models/modelInterfaces';
import { INotebookFindModel } from 'sql/workbench/contrib/notebook/browser/models/notebookFindModel';
import { NotebookChangeType, CellType } from 'sql/workbench/services/notebook/common/contracts';
import { INotebookManager, INotebookService, INotebookEditor, ILanguageMagic, INotebookProvider, INavigationProvider, INotebookParams, INotebookSection, ICellEditorProvider, NotebookRange } from 'sql/workbench/services/notebook/browser/notebookService';
@@ -94,6 +94,12 @@ export class NotebookModelStub implements INotebookModel {
findCellIndex(cellModel: ICellModel): number {
throw new Error('Method not implemented.');
}
get viewMode() {
throw new Error('Method not implemented.');
}
set viewMode(mode: ViewMode) {
throw new Error('Method not implemented.');
}
addCell(cellType: CellType, index?: number): void {
throw new Error('Method not implemented.');
}
@@ -439,6 +445,7 @@ export class FutureStub implements nb.IFuture {
export class NotebookComponentStub implements INotebookEditor {
cellEditors: ICellEditorProvider[];
viewMode: string;
deltaDecorations(newDecorationRange: NotebookRange, oldDecorationRange: NotebookRange): void {
throw new Error('Method not implemented.');
}
@@ -651,6 +658,7 @@ export class NotebookEditorStub implements INotebookEditor {
cellEditors: CellEditorProviderStub[];
modelReady: Promise<INotebookModel>;
model: INotebookModel;
viewMode: string;
isDirty(): boolean {
throw new Error('Method not implemented.');
}

View File

@@ -24,6 +24,11 @@ import type { FutureInternal } from 'sql/workbench/services/notebook/browser/int
import { ICellValue, ResultSetSummary } from 'sql/workbench/services/query/common/query';
import { QueryResultId } from 'sql/workbench/services/notebook/browser/models/cell';
export enum ViewMode {
Notebook,
Views,
}
export interface ICellRange {
readonly start: number;
readonly end: number;
@@ -334,6 +339,12 @@ export interface INotebookModel {
*/
providerId: string;
/**
* View mode for this model. It determines what editor mode
* will be displayed.
*/
viewMode: ViewMode;
/**
* Change the current kernel from the Kernel dropdown
* @param displayName kernel name (as displayed in Kernel dropdown)

View File

@@ -9,7 +9,7 @@ import { localize } from 'vs/nls';
import { Event, Emitter } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { IClientSession, INotebookModel, INotebookModelOptions, ICellModel, NotebookContentChange, MoveDirection } from 'sql/workbench/services/notebook/browser/models/modelInterfaces';
import { IClientSession, INotebookModel, INotebookModelOptions, ICellModel, NotebookContentChange, MoveDirection, ViewMode } from 'sql/workbench/services/notebook/browser/models/modelInterfaces';
import { NotebookChangeType, CellType, CellTypes } from 'sql/workbench/services/notebook/common/contracts';
import { nbversion } from 'sql/workbench/services/notebook/common/notebookConstants';
import * as notebookUtils from 'sql/workbench/services/notebook/browser/models/notebookUtils';
@@ -56,6 +56,7 @@ export class NotebookModel extends Disposable implements INotebookModel {
private _contentChangedEmitter = new Emitter<NotebookContentChange>();
private _kernelsChangedEmitter = new Emitter<nb.IKernel>();
private _kernelChangedEmitter = new Emitter<nb.IKernelChangedArgs>();
private _viewModeChangedEmitter = new Emitter<ViewMode>();
private _layoutChanged = new Emitter<void>();
private _inErrorState: boolean = false;
private _activeClientSession: IClientSession | undefined;
@@ -71,6 +72,7 @@ export class NotebookModel extends Disposable implements INotebookModel {
private _tags: string[] | undefined;
private _existingMetadata: nb.INotebookMetadata = {};
private _language: string = '';
private _viewMode: ViewMode = ViewMode.Notebook;
private _onErrorEmitter = new Emitter<INotification>();
private _savedKernelInfo: nb.IKernelSpec | undefined;
private _savedConnectionName: string | undefined;
@@ -274,6 +276,21 @@ export class NotebookModel extends Disposable implements INotebookModel {
});
}
public get viewModeChanged(): Event<ViewMode> {
return this._viewModeChangedEmitter.event;
}
public get viewMode() {
return this._viewMode;
}
public set viewMode(mode: ViewMode) {
if (mode !== this._viewMode) {
this._viewMode = mode;
this._viewModeChangedEmitter.fire(mode);
}
}
/**
* Indicates the server has finished loading. It may have failed to load in
* which case the view will be in an error state.