mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-28 09:35:38 -05:00
Add Notebook Views dropdown (#16228)
This adds the entry point to NVs. It is currently hidden behind a feature flag, which can be enabled in the settings.
This commit is contained in:
@@ -28,7 +28,7 @@ import { INotebookService, INotebookParams, INotebookEditor, INotebookSection, I
|
||||
import { NotebookModel } from 'sql/workbench/services/notebook/browser/models/notebookModel';
|
||||
import { Deferred } from 'sql/base/common/promise';
|
||||
import { Taskbar } from 'sql/base/browser/ui/taskbar/taskbar';
|
||||
import { AddCellAction, KernelsDropdown, AttachToDropdown, TrustedAction, RunAllCellsAction, ClearAllOutputsAction, CollapseCellsAction, RunParametersAction } from 'sql/workbench/contrib/notebook/browser/notebookActions';
|
||||
import { AddCellAction, KernelsDropdown, AttachToDropdown, TrustedAction, RunAllCellsAction, ClearAllOutputsAction, CollapseCellsAction, RunParametersAction, NotebookViewsActionProvider } 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';
|
||||
@@ -51,6 +51,7 @@ import { NotebookInput } from 'sql/workbench/contrib/notebook/browser/models/not
|
||||
import { IColorTheme } from 'vs/platform/theme/common/themeService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { CellToolbarComponent } from 'sql/workbench/contrib/notebook/browser/cellViews/cellToolbar.component';
|
||||
import { NotebookViewsExtension } from 'sql/workbench/services/notebook/browser/notebookViews/notebookViewsExtension';
|
||||
import { MaskedLabeledMenuItemActionItem } from 'sql/platform/actions/browser/menuEntryActionViewItem';
|
||||
import { IActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
|
||||
@@ -70,6 +71,7 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe
|
||||
@ViewChildren(CellToolbarComponent) private cellToolbar: QueryList<CellToolbarComponent>;
|
||||
|
||||
@Input() _model: NotebookModel;
|
||||
@Input() _views: NotebookViewsExtension;
|
||||
|
||||
protected _actionBar: Taskbar;
|
||||
protected isLoading: boolean;
|
||||
@@ -130,10 +132,14 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe
|
||||
this.notebookService.removeNotebookEditor(this);
|
||||
}
|
||||
}
|
||||
public get model(): NotebookModel | null {
|
||||
public get model(): NotebookModel | undefined {
|
||||
return this._model;
|
||||
}
|
||||
|
||||
public get views(): NotebookViewsExtension | undefined {
|
||||
return this._views;
|
||||
}
|
||||
|
||||
public get activeCellId(): string {
|
||||
return this._model && this._model.activeCell ? this._model.activeCell.id : '';
|
||||
}
|
||||
@@ -442,6 +448,28 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe
|
||||
dropdownMenuActionViewItem.render(buttonDropdownContainer);
|
||||
dropdownMenuActionViewItem.setActionContext(this._notebookParams.notebookUri);
|
||||
|
||||
let viewsDropdownContainer;
|
||||
if (this._configurationService.getValue<boolean>('notebookViews.enabled')) {
|
||||
let viewsContainer = document.createElement('li');
|
||||
let viewsActionsProvider = new NotebookViewsActionProvider(viewsContainer, this.views, this.modelReady, this.notebookService, this.notificationService, this.instantiationService);
|
||||
let viewsButton = new Action('notebook.OpenViews', localize('views', "Views"), 'notebook-button masked-pseudo code');
|
||||
viewsDropdownContainer = DOM.$('li.action-item');
|
||||
viewsDropdownContainer.setAttribute('role', 'presentation');
|
||||
let viewsDropdownMenuActionViewItem = new DropdownMenuActionViewItem(
|
||||
viewsButton,
|
||||
viewsActionsProvider,
|
||||
this.contextMenuService,
|
||||
undefined,
|
||||
this._actionBar.actionRunner,
|
||||
undefined,
|
||||
'codicon notebook-button masked-pseudo masked-pseudo-after icon-dashboard-view dropdown-arrow',
|
||||
localize('editor', "Editor"),
|
||||
undefined
|
||||
);
|
||||
viewsDropdownMenuActionViewItem.render(viewsDropdownContainer);
|
||||
viewsDropdownMenuActionViewItem.setActionContext(this._notebookParams.notebookUri);
|
||||
}
|
||||
|
||||
this._actionBar.setContent([
|
||||
{ element: buttonDropdownContainer },
|
||||
{ action: this._runAllCellsAction },
|
||||
@@ -449,6 +477,7 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe
|
||||
{ element: kernelContainer },
|
||||
{ element: attachToContainer },
|
||||
{ element: spacerElement },
|
||||
{ element: viewsDropdownContainer },
|
||||
{ action: collapseCellsAction },
|
||||
{ action: clearResultsButton },
|
||||
{ action: this._trustedAction },
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import * as azdata from 'azdata';
|
||||
import * as path from 'vs/base/common/path';
|
||||
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { Action, IAction, Separator } from 'vs/base/common/actions';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';
|
||||
import { INotificationService, Severity, INotificationActions } from 'vs/platform/notification/common/notification';
|
||||
@@ -18,21 +18,25 @@ import { ConnectionProfile } from 'sql/platform/connection/common/connectionProf
|
||||
import { IConnectionDialogService } from 'sql/workbench/services/connection/common/connectionDialogService';
|
||||
import { NotebookModel } from 'sql/workbench/services/notebook/browser/models/notebookModel';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { CellType } from 'sql/workbench/services/notebook/common/contracts';
|
||||
import { CellType, NotebookChangeType } from 'sql/workbench/services/notebook/common/contracts';
|
||||
import { getErrorMessage } from 'vs/base/common/errors';
|
||||
import { IEditorAction } from 'vs/editor/common/editorCommon';
|
||||
import { IFindNotebookController } from 'sql/workbench/contrib/notebook/browser/find/notebookFindWidget';
|
||||
import { INotebookModel } from 'sql/workbench/services/notebook/browser/models/modelInterfaces';
|
||||
import { INotebookModel, ViewMode } from 'sql/workbench/services/notebook/browser/models/modelInterfaces';
|
||||
import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/browser/objectExplorerService';
|
||||
import { TreeUpdateUtils } from 'sql/workbench/services/objectExplorer/browser/treeUpdateUtils';
|
||||
import { INotebookService } from 'sql/workbench/services/notebook/browser/notebookService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { CellContext } from 'sql/workbench/contrib/notebook/browser/cellViews/codeActions';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { IActionProvider } from 'vs/base/browser/ui/dropdown/dropdown';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
|
||||
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
|
||||
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { KernelsLanguage } from 'sql/workbench/services/notebook/common/notebookConstants';
|
||||
import { INotebookViews } from 'sql/workbench/services/notebook/browser/notebookViews/notebookViews';
|
||||
|
||||
const msgLoading = localize('loading', "Loading kernels...");
|
||||
export const msgChanging = localize('changing', "Changing kernel...");
|
||||
@@ -178,6 +182,148 @@ export abstract class ToggleableAction extends Action {
|
||||
}
|
||||
}
|
||||
|
||||
export class NotebookViewsActionProvider implements IActionProvider {
|
||||
private _options: Action[] = [];
|
||||
private views: INotebookViews;
|
||||
private viewMode: ViewMode;
|
||||
private readonly _optionsUpdated = new Emitter<boolean>();
|
||||
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
views: INotebookViews,
|
||||
modelReady: Promise<INotebookModel>,
|
||||
@INotebookService private _notebookService: INotebookService,
|
||||
@INotificationService private _notificationService: INotificationService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService) {
|
||||
|
||||
modelReady?.then((model) => {
|
||||
this.views = views;
|
||||
this.viewMode = model.viewMode;
|
||||
this.updateView();
|
||||
})
|
||||
.catch((err) => {
|
||||
this._notificationService.error(getErrorMessage(err));
|
||||
});
|
||||
}
|
||||
|
||||
getActions(): IAction[] {
|
||||
return this._options;
|
||||
}
|
||||
|
||||
public get options(): Action[] {
|
||||
return this._options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update SelectBox values
|
||||
*/
|
||||
public updateView() {
|
||||
const backToNotebookButton = this.instantiationService.createInstance(NotebookViewAction, 'notebookView.backToNotebook', localize('notebookViewLabel', 'Editor'), 'notebook-button');
|
||||
const newViewButton = this.instantiationService.createInstance(CreateNotebookViewAction, 'notebookView.newView', localize('newViewLabel', 'Create New View'), 'notebook-button notebook-button-newview');
|
||||
|
||||
const views = this.views.getViews();
|
||||
this._options = [];
|
||||
|
||||
this._options.push(backToNotebookButton);
|
||||
this._options.push(newViewButton);
|
||||
|
||||
if (views.length) {
|
||||
this._options.push(this.instantiationService.createInstance(Separator));
|
||||
}
|
||||
|
||||
views.forEach((view) => {
|
||||
const option = new DashboardViewAction(view.guid, view.name, 'button', this._notebookService, this._notificationService);
|
||||
this._options.push(option);
|
||||
|
||||
if (this.viewMode === ViewMode.Views && this.views.getActiveView() === view) {
|
||||
option.checked = true;
|
||||
option.enabled = false;
|
||||
}
|
||||
});
|
||||
|
||||
if (this.viewMode === ViewMode.Notebook) {
|
||||
backToNotebookButton.checked = true;
|
||||
backToNotebookButton.enabled = false;
|
||||
}
|
||||
|
||||
this._optionsUpdated.fire(true);
|
||||
}
|
||||
|
||||
public get onUpdated(): Event<boolean> {
|
||||
return this._optionsUpdated.event;
|
||||
}
|
||||
|
||||
public optionSelected(displayName: string): void {
|
||||
const view = this.views.getViews().find(view => view.name === displayName);
|
||||
this.views.setActiveView(view);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Action to open a Notebook View
|
||||
*/
|
||||
export class DashboardViewAction extends Action {
|
||||
constructor(
|
||||
id: string, label: string, cssClass: string,
|
||||
@INotebookService private _notebookService: INotebookService,
|
||||
@INotificationService private _notificationService: INotificationService,
|
||||
) {
|
||||
super(id, label, cssClass);
|
||||
}
|
||||
|
||||
public override async run(context: URI): Promise<void> {
|
||||
if (context) {
|
||||
const editor = this._notebookService.findNotebookEditor(context);
|
||||
let views = editor.views;
|
||||
const view = views.getViews().find(view => view.guid === this.id);
|
||||
|
||||
if (view) {
|
||||
views.setActiveView(view);
|
||||
editor.model.viewMode = ViewMode.Views;
|
||||
} else {
|
||||
this._notificationService.error(localize('viewNotFound', "Unable to find view: {0}", this.id));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Action to open enter the default notebook editor
|
||||
*/
|
||||
export class NotebookViewAction extends Action {
|
||||
constructor(
|
||||
id: string, label: string, cssClass: string,
|
||||
@INotebookService private _notebookService: INotebookService
|
||||
) {
|
||||
super(id, label, cssClass);
|
||||
}
|
||||
public override async run(context: URI): Promise<void> {
|
||||
const editor = this._notebookService.findNotebookEditor(context);
|
||||
editor.model.viewMode = ViewMode.Notebook;
|
||||
}
|
||||
}
|
||||
|
||||
export class CreateNotebookViewAction extends Action {
|
||||
constructor(
|
||||
id: string, label: string, cssClass: string,
|
||||
@INotebookService private _notebookService: INotebookService
|
||||
) {
|
||||
super(id, label, cssClass);
|
||||
}
|
||||
public override async run(context: URI): Promise<void> {
|
||||
if (context) {
|
||||
const editor = this._notebookService.findNotebookEditor(context);
|
||||
const views = editor.views;
|
||||
|
||||
const newView = views.createNewView();
|
||||
views.setActiveView(newView);
|
||||
|
||||
editor.model.viewMode = ViewMode.Views;
|
||||
editor.model.serializationStateChanged(NotebookChangeType.MetadataChanged);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class TrustedAction extends ToggleableAction {
|
||||
// Constants
|
||||
private static readonly trustedLabel = localize('trustLabel', "Trusted");
|
||||
|
||||
@@ -5,5 +5,5 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
-->
|
||||
<!-- Notebook View -->
|
||||
<notebook-component *ngIf="viewMode === 0" [_model]="model"></notebook-component>
|
||||
<notebook-component *ngIf="viewMode === 0" [_views]="views" [_model]="model"></notebook-component>
|
||||
<!-- Dashboard View: To be implemented-->
|
||||
|
||||
@@ -24,6 +24,7 @@ import { IAction, SubmenuAction } 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';
|
||||
import { NotebookViewsExtension } from 'sql/workbench/services/notebook/browser/notebookViews/notebookViewsExtension';
|
||||
|
||||
export const NOTEBOOKEDITOR_SELECTOR: string = 'notebookeditor-component';
|
||||
|
||||
@@ -36,6 +37,8 @@ export class NotebookEditorComponent extends AngularDisposable {
|
||||
private notebookManagers: INotebookManager[] = [];
|
||||
private _model: NotebookModel;
|
||||
|
||||
public views: NotebookViewsExtension;
|
||||
|
||||
constructor(
|
||||
@Inject(ILogService) private readonly logService: ILogService,
|
||||
@Inject(IBootstrapParams) private _notebookParams: INotebookParams,
|
||||
@@ -104,6 +107,8 @@ export class NotebookEditorComponent extends AngularDisposable {
|
||||
this._model = this._register(model);
|
||||
await this.model.loadContents(trusted);
|
||||
|
||||
this.views = new NotebookViewsExtension(this.model);
|
||||
|
||||
this._register(model.viewModeChanged((mode) => this.onViewModeChanged()));
|
||||
this._register(model.contentChanged((change) => this.handleContentChanged(change)));
|
||||
this._register(model.onCellTypeChanged(() => this.detectChanges()));
|
||||
|
||||
Reference in New Issue
Block a user