mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
Making Notebook to scroll to output area only when Notebook command is executed (#5893)
This commit is contained in:
@@ -43,7 +43,7 @@ export class OutputComponent extends AngularDisposable implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.renderOutput(true);
|
this.renderOutput();
|
||||||
this._initialized = true;
|
this._initialized = true;
|
||||||
this._register(Event.debounce(this.cellModel.notebookModel.layoutChanged, (l, e) => e, 50, /*leading=*/false)
|
this._register(Event.debounce(this.cellModel.notebookModel.layoutChanged, (l, e) => e, 50, /*leading=*/false)
|
||||||
(() => this.renderOutput()));
|
(() => this.renderOutput()));
|
||||||
@@ -70,21 +70,11 @@ export class OutputComponent extends AngularDisposable implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderOutput(focusAndScroll: boolean = false): void {
|
private renderOutput(): void {
|
||||||
let options = outputProcessor.getBundleOptions({ value: this.cellOutput, trusted: this.trustedMode });
|
let options = outputProcessor.getBundleOptions({ value: this.cellOutput, trusted: this.trustedMode });
|
||||||
options.themeService = this._themeService;
|
options.themeService = this._themeService;
|
||||||
// TODO handle safe/unsafe mapping
|
// TODO handle safe/unsafe mapping
|
||||||
this.createRenderedMimetype(options, this.outputElement.nativeElement);
|
this.createRenderedMimetype(options, this.outputElement.nativeElement);
|
||||||
if (focusAndScroll) {
|
|
||||||
this.setFocusAndScroll(this.outputElement.nativeElement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private setFocusAndScroll(node: HTMLElement): void {
|
|
||||||
if (node) {
|
|
||||||
node.focus();
|
|
||||||
node.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public layout(): void {
|
public layout(): void {
|
||||||
|
|||||||
@@ -33,14 +33,24 @@ export class OutputAreaComponent extends AngularDisposable implements OnInit {
|
|||||||
this._register(this.themeService.onDidColorThemeChange(this.updateTheme, this));
|
this._register(this.themeService.onDidColorThemeChange(this.updateTheme, this));
|
||||||
this.updateTheme(this.themeService.getColorTheme());
|
this.updateTheme(this.themeService.getColorTheme());
|
||||||
if (this.cellModel) {
|
if (this.cellModel) {
|
||||||
this._register(this.cellModel.onOutputsChanged(() => {
|
this._register(this.cellModel.onOutputsChanged(e => {
|
||||||
if (!(this._changeRef['destroyed'])) {
|
if (!(this._changeRef['destroyed'])) {
|
||||||
this._changeRef.detectChanges();
|
this._changeRef.detectChanges();
|
||||||
|
if (e && e.shouldScroll) {
|
||||||
|
this.setFocusAndScroll(this.outputArea.nativeElement);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private setFocusAndScroll(node: HTMLElement): void {
|
||||||
|
if (node) {
|
||||||
|
node.focus();
|
||||||
|
node.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Input() set activeCellId(value: string) {
|
@Input() set activeCellId(value: string) {
|
||||||
this._activeCellId = value;
|
this._activeCellId = value;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { localize } from 'vs/nls';
|
|||||||
import * as notebookUtils from '../notebookUtils';
|
import * as notebookUtils from '../notebookUtils';
|
||||||
import { CellTypes, CellType, NotebookChangeType } from 'sql/workbench/parts/notebook/models/contracts';
|
import { CellTypes, CellType, NotebookChangeType } from 'sql/workbench/parts/notebook/models/contracts';
|
||||||
import { NotebookModel } from 'sql/workbench/parts/notebook/models/notebookModel';
|
import { NotebookModel } from 'sql/workbench/parts/notebook/models/notebookModel';
|
||||||
import { ICellModel, notebookConstants } from 'sql/workbench/parts/notebook/models/modelInterfaces';
|
import { ICellModel, notebookConstants, IOutputChangedEvent } from 'sql/workbench/parts/notebook/models/modelInterfaces';
|
||||||
import { ICellModelOptions, IModelFactory, FutureInternal, CellExecutionState } from './modelInterfaces';
|
import { ICellModelOptions, IModelFactory, FutureInternal, CellExecutionState } from './modelInterfaces';
|
||||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||||
@@ -20,7 +20,6 @@ import { INotificationService, Severity } from 'vs/platform/notification/common/
|
|||||||
import { Schemas } from 'vs/base/common/network';
|
import { Schemas } from 'vs/base/common/network';
|
||||||
let modelId = 0;
|
let modelId = 0;
|
||||||
|
|
||||||
|
|
||||||
export class CellModel implements ICellModel {
|
export class CellModel implements ICellModel {
|
||||||
private _cellType: nb.CellType;
|
private _cellType: nb.CellType;
|
||||||
private _source: string;
|
private _source: string;
|
||||||
@@ -28,7 +27,7 @@ export class CellModel implements ICellModel {
|
|||||||
private _future: FutureInternal;
|
private _future: FutureInternal;
|
||||||
private _outputs: nb.ICellOutput[] = [];
|
private _outputs: nb.ICellOutput[] = [];
|
||||||
private _isEditMode: boolean;
|
private _isEditMode: boolean;
|
||||||
private _onOutputsChanged = new Emitter<ReadonlyArray<nb.ICellOutput>>();
|
private _onOutputsChanged = new Emitter<IOutputChangedEvent>();
|
||||||
private _onCellModeChanged = new Emitter<boolean>();
|
private _onCellModeChanged = new Emitter<boolean>();
|
||||||
private _onExecutionStateChanged = new Emitter<CellExecutionState>();
|
private _onExecutionStateChanged = new Emitter<CellExecutionState>();
|
||||||
private _isTrusted: boolean;
|
private _isTrusted: boolean;
|
||||||
@@ -62,7 +61,7 @@ export class CellModel implements ICellModel {
|
|||||||
return other && other.id === this.id;
|
return other && other.id === this.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get onOutputsChanged(): Event<ReadonlyArray<nb.ICellOutput>> {
|
public get onOutputsChanged(): Event<IOutputChangedEvent> {
|
||||||
return this._onOutputsChanged.event;
|
return this._onOutputsChanged.event;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +90,11 @@ export class CellModel implements ICellModel {
|
|||||||
public set trustedMode(isTrusted: boolean) {
|
public set trustedMode(isTrusted: boolean) {
|
||||||
if (this._isTrusted !== isTrusted) {
|
if (this._isTrusted !== isTrusted) {
|
||||||
this._isTrusted = isTrusted;
|
this._isTrusted = isTrusted;
|
||||||
this._onOutputsChanged.fire(this._outputs);
|
let outputEvent: IOutputChangedEvent = {
|
||||||
|
outputs: this._outputs,
|
||||||
|
shouldScroll: false
|
||||||
|
};
|
||||||
|
this._onOutputsChanged.fire(outputEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,8 +320,12 @@ export class CellModel implements ICellModel {
|
|||||||
this.fireOutputsChanged();
|
this.fireOutputsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private fireOutputsChanged(): void {
|
private fireOutputsChanged(shouldScroll: boolean = false): void {
|
||||||
this._onOutputsChanged.fire(this.outputs);
|
let outputEvent: IOutputChangedEvent = {
|
||||||
|
outputs: this.outputs,
|
||||||
|
shouldScroll: !!shouldScroll
|
||||||
|
};
|
||||||
|
this._onOutputsChanged.fire(outputEvent);
|
||||||
this.sendChangeToNotebook(NotebookChangeType.CellOutputUpdated);
|
this.sendChangeToNotebook(NotebookChangeType.CellOutputUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -383,7 +390,7 @@ export class CellModel implements ICellModel {
|
|||||||
// deletes transient node in the serialized JSON
|
// deletes transient node in the serialized JSON
|
||||||
delete output['transient'];
|
delete output['transient'];
|
||||||
this._outputs.push(this.rewriteOutputUrls(output));
|
this._outputs.push(this.rewriteOutputUrls(output));
|
||||||
this.fireOutputsChanged();
|
this.fireOutputsChanged(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -435,6 +435,11 @@ export enum CellExecutionState {
|
|||||||
Error = 3
|
Error = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IOutputChangedEvent {
|
||||||
|
outputs: ReadonlyArray<nb.ICellOutput>;
|
||||||
|
shouldScroll: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ICellModel {
|
export interface ICellModel {
|
||||||
cellUri: URI;
|
cellUri: URI;
|
||||||
id: string;
|
id: string;
|
||||||
@@ -447,7 +452,7 @@ export interface ICellModel {
|
|||||||
executionCount: number | undefined;
|
executionCount: number | undefined;
|
||||||
readonly future: FutureInternal;
|
readonly future: FutureInternal;
|
||||||
readonly outputs: ReadonlyArray<nb.ICellOutput>;
|
readonly outputs: ReadonlyArray<nb.ICellOutput>;
|
||||||
readonly onOutputsChanged: Event<ReadonlyArray<nb.ICellOutput>>;
|
readonly onOutputsChanged: Event<IOutputChangedEvent>;
|
||||||
readonly onExecutionStateChange: Event<CellExecutionState>;
|
readonly onExecutionStateChange: Event<CellExecutionState>;
|
||||||
readonly executionState: CellExecutionState;
|
readonly executionState: CellExecutionState;
|
||||||
readonly notebookModel: NotebookModel;
|
readonly notebookModel: NotebookModel;
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ suite('Cell Model', function (): void {
|
|||||||
future.setup(f => f.setReplyHandler(TypeMoq.It.isAny())).callback((handler) => onReply = handler);
|
future.setup(f => f.setReplyHandler(TypeMoq.It.isAny())).callback((handler) => onReply = handler);
|
||||||
future.setup(f => f.setIOPubHandler(TypeMoq.It.isAny())).callback((handler) => onIopub = handler);
|
future.setup(f => f.setIOPubHandler(TypeMoq.It.isAny())).callback((handler) => onIopub = handler);
|
||||||
let outputs: ReadonlyArray<nb.ICellOutput> = undefined;
|
let outputs: ReadonlyArray<nb.ICellOutput> = undefined;
|
||||||
cell.onOutputsChanged((o => outputs = o));
|
cell.onOutputsChanged((o => outputs = o.outputs));
|
||||||
|
|
||||||
// When I set it on the cell
|
// When I set it on the cell
|
||||||
cell.setFuture(future.object);
|
cell.setFuture(future.object);
|
||||||
@@ -265,7 +265,7 @@ suite('Cell Model', function (): void {
|
|||||||
let onIopub: nb.MessageHandler<nb.IIOPubMessage>;
|
let onIopub: nb.MessageHandler<nb.IIOPubMessage>;
|
||||||
future.setup(f => f.setIOPubHandler(TypeMoq.It.isAny())).callback((handler) => onIopub = handler);
|
future.setup(f => f.setIOPubHandler(TypeMoq.It.isAny())).callback((handler) => onIopub = handler);
|
||||||
let outputs: ReadonlyArray<nb.ICellOutput> = undefined;
|
let outputs: ReadonlyArray<nb.ICellOutput> = undefined;
|
||||||
cell.onOutputsChanged((o => outputs = o));
|
cell.onOutputsChanged((o => outputs = o.outputs));
|
||||||
|
|
||||||
//Set the future
|
//Set the future
|
||||||
cell.setFuture(future.object);
|
cell.setFuture(future.object);
|
||||||
|
|||||||
Reference in New Issue
Block a user