mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Split notebookcell (#17185)
* Initial Split code * minor change * minor changes * Added split cell button to initActionBar, created split cell class to pss cell context. * added changes * fixed index * Split Cell Working in markdown mode * Fixed highlighting * Preserve the edit state * Added new icon and updated styles and cellToolbar component with new icon name. * Addressed PR * Addressed PR * Added back isEditMode flag * Moved split action to after edit toggle. * Fixed typo * Addressed PR * Addressed PR * Removed deletion of the cell * fixed the comments Co-authored-by: Hale Rankin <harankin@microsoft.com>
This commit is contained in:
@@ -524,6 +524,15 @@ Includes non-masked style declarations. */
|
|||||||
background-image: url('start-outline.svg');
|
background-image: url('start-outline.svg');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.codicon:not(.masked-icon).icon-split-cell {
|
||||||
|
background-image: url("split_cell.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
.codicon.masked-icon.icon-split-cell:before {
|
||||||
|
-webkit-mask-image: url("split_cell.svg");
|
||||||
|
mask-image: url("split_cell.svg");
|
||||||
|
}
|
||||||
|
|
||||||
/* Masked element inside pseudo element */
|
/* Masked element inside pseudo element */
|
||||||
.masked-pseudo {
|
.masked-pseudo {
|
||||||
background-image: none !important;
|
background-image: none !important;
|
||||||
|
|||||||
3
src/sql/media/icons/split_cell.svg
Normal file
3
src/sql/media/icons/split_cell.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M1 1H14V14H1V1ZM13 13V8H2V13H13ZM13 7V2H2V7H13Z" fill="#323130"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 178 B |
@@ -18,7 +18,6 @@ import { INotebookService } from 'sql/workbench/services/notebook/browser/notebo
|
|||||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||||
import { MoveDirection } from 'sql/workbench/services/notebook/browser/models/modelInterfaces';
|
import { MoveDirection } from 'sql/workbench/services/notebook/browser/models/modelInterfaces';
|
||||||
|
|
||||||
const moreActionsLabel = localize('moreActionsLabel', "More");
|
const moreActionsLabel = localize('moreActionsLabel', "More");
|
||||||
|
|
||||||
export class EditCellAction extends ToggleableAction {
|
export class EditCellAction extends ToggleableAction {
|
||||||
@@ -58,6 +57,29 @@ export class EditCellAction extends ToggleableAction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class SplitCellAction extends CellActionBase {
|
||||||
|
public cellType: CellType;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
id: string,
|
||||||
|
label: string,
|
||||||
|
cssClass: string,
|
||||||
|
@INotificationService notificationService: INotificationService,
|
||||||
|
@INotebookService private notebookService: INotebookService,
|
||||||
|
) {
|
||||||
|
super(id, label, cssClass, notificationService);
|
||||||
|
this._cssClass = cssClass;
|
||||||
|
this._tooltip = label;
|
||||||
|
this._label = '';
|
||||||
|
}
|
||||||
|
doRun(context: CellContext): Promise<void> {
|
||||||
|
let model = context.model;
|
||||||
|
let index = model.cells.findIndex((cell) => cell.id === context.cell.id);
|
||||||
|
context.model?.splitCell(context.cell.cellType, this.notebookService, index);
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class MoveCellAction extends CellActionBase {
|
export class MoveCellAction extends CellActionBase {
|
||||||
constructor(
|
constructor(
|
||||||
id: string,
|
id: string,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { localize } from 'vs/nls';
|
|||||||
import { Taskbar, ITaskbarContent } from 'sql/base/browser/ui/taskbar/taskbar';
|
import { Taskbar, ITaskbarContent } from 'sql/base/browser/ui/taskbar/taskbar';
|
||||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { DeleteCellAction, EditCellAction, CellToggleMoreActions, MoveCellAction } from 'sql/workbench/contrib/notebook/browser/cellToolbarActions';
|
import { DeleteCellAction, EditCellAction, CellToggleMoreActions, MoveCellAction, SplitCellAction } from 'sql/workbench/contrib/notebook/browser/cellToolbarActions';
|
||||||
import { AddCellAction } from 'sql/workbench/contrib/notebook/browser/notebookActions';
|
import { AddCellAction } from 'sql/workbench/contrib/notebook/browser/notebookActions';
|
||||||
import { CellTypes } from 'sql/workbench/services/notebook/common/contracts';
|
import { CellTypes } from 'sql/workbench/services/notebook/common/contracts';
|
||||||
import { DropdownMenuActionViewItem } from 'sql/base/browser/ui/buttonMenu/buttonMenu';
|
import { DropdownMenuActionViewItem } from 'sql/base/browser/ui/buttonMenu/buttonMenu';
|
||||||
@@ -33,6 +33,7 @@ export class CellToolbarComponent {
|
|||||||
public buttonMoveDown = localize('buttonMoveDown', "Move cell down");
|
public buttonMoveDown = localize('buttonMoveDown', "Move cell down");
|
||||||
public buttonMoveUp = localize('buttonMoveUp', "Move cell up");
|
public buttonMoveUp = localize('buttonMoveUp', "Move cell up");
|
||||||
public buttonDelete = localize('buttonDelete', "Delete");
|
public buttonDelete = localize('buttonDelete', "Delete");
|
||||||
|
public buttonSplitCell = localize('splitCell', "Split cell");
|
||||||
|
|
||||||
@Input() cellModel: ICellModel;
|
@Input() cellModel: ICellModel;
|
||||||
@Input() model: NotebookModel;
|
@Input() model: NotebookModel;
|
||||||
@@ -58,6 +59,8 @@ export class CellToolbarComponent {
|
|||||||
this._actionBar = new Taskbar(taskbar);
|
this._actionBar = new Taskbar(taskbar);
|
||||||
this._actionBar.context = context;
|
this._actionBar.context = context;
|
||||||
|
|
||||||
|
let splitCellButton = this.instantiationService.createInstance(SplitCellAction, 'notebook.SplitCellAtCursor', this.buttonSplitCell, 'masked-icon icon-split-cell');
|
||||||
|
|
||||||
let addCellsButton = this.instantiationService.createInstance(AddCellAction, 'notebook.AddCodeCell', localize('codeCellsPreview', "Add cell"), 'masked-pseudo code');
|
let addCellsButton = this.instantiationService.createInstance(AddCellAction, 'notebook.AddCodeCell', localize('codeCellsPreview', "Add cell"), 'masked-pseudo code');
|
||||||
|
|
||||||
let addCodeCellButton = this.instantiationService.createInstance(AddCellAction, 'notebook.AddCodeCell', localize('codePreview', "Code cell"), 'masked-pseudo code');
|
let addCodeCellButton = this.instantiationService.createInstance(AddCellAction, 'notebook.AddCodeCell', localize('codePreview', "Code cell"), 'masked-pseudo code');
|
||||||
@@ -96,9 +99,12 @@ export class CellToolbarComponent {
|
|||||||
|
|
||||||
let taskbarContent: ITaskbarContent[] = [];
|
let taskbarContent: ITaskbarContent[] = [];
|
||||||
if (this.cellModel?.cellType === CellTypes.Markdown) {
|
if (this.cellModel?.cellType === CellTypes.Markdown) {
|
||||||
taskbarContent.push({ action: this._editCellAction });
|
taskbarContent.push(
|
||||||
|
{ action: this._editCellAction }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
taskbarContent.push(
|
taskbarContent.push(
|
||||||
|
{ action: splitCellButton },
|
||||||
{ element: addCellDropdownContainer },
|
{ element: addCellDropdownContainer },
|
||||||
{ action: moveCellDownButton },
|
{ action: moveCellDownButton },
|
||||||
{ action: moveCellUpButton },
|
{ action: moveCellUpButton },
|
||||||
|
|||||||
@@ -271,7 +271,7 @@ suite('NotebookViewModel', function (): void {
|
|||||||
mockContentManager.setup(c => c.loadContent()).returns(() => Promise.resolve(contents));
|
mockContentManager.setup(c => c.loadContent()).returns(() => Promise.resolve(contents));
|
||||||
defaultModelOptions.contentLoader = mockContentManager.object;
|
defaultModelOptions.contentLoader = mockContentManager.object;
|
||||||
|
|
||||||
let model = new NotebookModel(defaultModelOptions, undefined, logService, undefined, new NullAdsTelemetryService(), queryConnectionService.object, configurationService);
|
let model = new NotebookModel(defaultModelOptions, undefined, logService, undefined, new NullAdsTelemetryService(), queryConnectionService.object, configurationService, undefined);
|
||||||
await model.loadContents();
|
await model.loadContents();
|
||||||
await model.requestModelLoad();
|
await model.requestModelLoad();
|
||||||
|
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ suite('Notebook Views Actions', function (): void {
|
|||||||
mockContentManager.setup(c => c.loadContent()).returns(() => Promise.resolve(contents));
|
mockContentManager.setup(c => c.loadContent()).returns(() => Promise.resolve(contents));
|
||||||
defaultModelOptions.contentLoader = mockContentManager.object;
|
defaultModelOptions.contentLoader = mockContentManager.object;
|
||||||
|
|
||||||
let model = new NotebookModel(defaultModelOptions, undefined, logService, undefined, new NullAdsTelemetryService(), queryConnectionService.object, configurationService);
|
let model = new NotebookModel(defaultModelOptions, undefined, logService, undefined, new NullAdsTelemetryService(), queryConnectionService.object, configurationService, undefined);
|
||||||
await model.loadContents();
|
await model.loadContents();
|
||||||
await model.requestModelLoad();
|
await model.requestModelLoad();
|
||||||
|
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ suite('NotebookViews', function (): void {
|
|||||||
mockContentManager.setup(c => c.loadContent()).returns(() => Promise.resolve(initialNotebookContent));
|
mockContentManager.setup(c => c.loadContent()).returns(() => Promise.resolve(initialNotebookContent));
|
||||||
defaultModelOptions.contentLoader = mockContentManager.object;
|
defaultModelOptions.contentLoader = mockContentManager.object;
|
||||||
|
|
||||||
let model = new NotebookModel(defaultModelOptions, undefined, logService, undefined, new NullAdsTelemetryService(), queryConnectionService.object, configurationService);
|
let model = new NotebookModel(defaultModelOptions, undefined, logService, undefined, new NullAdsTelemetryService(), queryConnectionService.object, configurationService, undefined);
|
||||||
await model.loadContents();
|
await model.loadContents();
|
||||||
await model.requestModelLoad();
|
await model.requestModelLoad();
|
||||||
|
|
||||||
|
|||||||
@@ -978,7 +978,7 @@ suite('Notebook Editor Model', function (): void {
|
|||||||
let options: INotebookModelOptions = Object.assign({}, defaultModelOptions, <Partial<INotebookModelOptions>><unknown>{
|
let options: INotebookModelOptions = Object.assign({}, defaultModelOptions, <Partial<INotebookModelOptions>><unknown>{
|
||||||
factory: mockModelFactory.object
|
factory: mockModelFactory.object
|
||||||
});
|
});
|
||||||
notebookModel = new NotebookModel(options, undefined, logService, undefined, new NullAdsTelemetryService(), queryConnectionService.object, configurationService);
|
notebookModel = new NotebookModel(options, undefined, logService, undefined, new NullAdsTelemetryService(), queryConnectionService.object, configurationService, undefined);
|
||||||
await notebookModel.loadContents();
|
await notebookModel.loadContents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -439,7 +439,7 @@ suite('Notebook Find Model', function (): void {
|
|||||||
mockContentManager.setup(c => c.loadContent()).returns(() => Promise.resolve(contents));
|
mockContentManager.setup(c => c.loadContent()).returns(() => Promise.resolve(contents));
|
||||||
defaultModelOptions.contentLoader = mockContentManager.object;
|
defaultModelOptions.contentLoader = mockContentManager.object;
|
||||||
// Initialize the model
|
// Initialize the model
|
||||||
model = new NotebookModel(defaultModelOptions, undefined, logService, undefined, new NullAdsTelemetryService(), queryConnectionService.object, configurationService);
|
model = new NotebookModel(defaultModelOptions, undefined, logService, undefined, new NullAdsTelemetryService(), queryConnectionService.object, configurationService, undefined);
|
||||||
await model.loadContents();
|
await model.loadContents();
|
||||||
await model.requestModelLoad();
|
await model.requestModelLoad();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { NotebookChangeType, CellType, CellTypes } from 'sql/workbench/services/
|
|||||||
import { KernelsLanguage, nbversion } from 'sql/workbench/services/notebook/common/notebookConstants';
|
import { KernelsLanguage, nbversion } from 'sql/workbench/services/notebook/common/notebookConstants';
|
||||||
import * as notebookUtils from 'sql/workbench/services/notebook/browser/models/notebookUtils';
|
import * as notebookUtils from 'sql/workbench/services/notebook/browser/models/notebookUtils';
|
||||||
import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
|
import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
|
||||||
import { IExecuteManager, SQL_NOTEBOOK_PROVIDER, DEFAULT_NOTEBOOK_PROVIDER, ISerializationManager } from 'sql/workbench/services/notebook/browser/notebookService';
|
import { IExecuteManager, SQL_NOTEBOOK_PROVIDER, DEFAULT_NOTEBOOK_PROVIDER, ISerializationManager, INotebookService } from 'sql/workbench/services/notebook/browser/notebookService';
|
||||||
import { NotebookContexts } from 'sql/workbench/services/notebook/browser/models/notebookContexts';
|
import { NotebookContexts } from 'sql/workbench/services/notebook/browser/models/notebookContexts';
|
||||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||||
import { INotification, Severity, INotificationService } from 'vs/platform/notification/common/notification';
|
import { INotification, Severity, INotificationService } from 'vs/platform/notification/common/notification';
|
||||||
@@ -32,6 +32,9 @@ import { IConnectionManagementService } from 'sql/platform/connection/common/con
|
|||||||
import { values } from 'vs/base/common/collections';
|
import { values } from 'vs/base/common/collections';
|
||||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
import { isUUID } from 'vs/base/common/uuid';
|
import { isUUID } from 'vs/base/common/uuid';
|
||||||
|
import { TextModel } from 'vs/editor/common/model/textModel';
|
||||||
|
import { QueryTextEditor } from 'sql/workbench/browser/modelComponents/queryTextEditor';
|
||||||
|
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used to control whether a message in a dialog/wizard is displayed as an error,
|
* Used to control whether a message in a dialog/wizard is displayed as an error,
|
||||||
@@ -121,7 +124,6 @@ export class NotebookModel extends Disposable implements INotebookModel {
|
|||||||
@IConnectionManagementService private connectionManagementService: IConnectionManagementService,
|
@IConnectionManagementService private connectionManagementService: IConnectionManagementService,
|
||||||
@IConfigurationService private configurationService: IConfigurationService,
|
@IConfigurationService private configurationService: IConfigurationService,
|
||||||
@ICapabilitiesService private _capabilitiesService?: ICapabilitiesService
|
@ICapabilitiesService private _capabilitiesService?: ICapabilitiesService
|
||||||
|
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
if (!_notebookOptions || !_notebookOptions.notebookUri || !_notebookOptions.executeManagers) {
|
if (!_notebookOptions || !_notebookOptions.notebookUri || !_notebookOptions.executeManagers) {
|
||||||
@@ -538,8 +540,127 @@ export class NotebookModel extends Disposable implements INotebookModel {
|
|||||||
if (this.inErrorState) {
|
if (this.inErrorState) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
let cell = this.createCell(cellType);
|
|
||||||
|
|
||||||
|
let cell = this.createCell(cellType);
|
||||||
|
return this.insertCell(cell, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public splitCell(cellType: CellType, notebookService: INotebookService, index?: number): ICellModel | undefined {
|
||||||
|
if (this.inErrorState) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
let notebookEditor = notebookService.findNotebookEditor(this.notebookUri);
|
||||||
|
let cellEditorProvider = notebookEditor.cellEditors.find(e => e.cellGuid() === this.cells[index].cellGuid);
|
||||||
|
//Only split the cell if the markdown editor is open.
|
||||||
|
//TODO: Need to handle splitting of cell if the selection is on webview
|
||||||
|
if (cellEditorProvider) {
|
||||||
|
let editor = cellEditorProvider.getEditor() as QueryTextEditor;
|
||||||
|
if (editor) {
|
||||||
|
let editorControl = editor.getControl() as CodeEditorWidget;
|
||||||
|
|
||||||
|
let model = editorControl.getModel() as TextModel;
|
||||||
|
let range = model.getFullModelRange();
|
||||||
|
let selection = editorControl.getSelection();
|
||||||
|
let source = this.cells[index].source;
|
||||||
|
let newCell = undefined, tailCell = undefined, partialSource = undefined;
|
||||||
|
let newCellIndex = index;
|
||||||
|
let tailCellIndex = index;
|
||||||
|
|
||||||
|
// Save UI state
|
||||||
|
let showMarkdown = this.cells[index].showMarkdown;
|
||||||
|
let showPreview = this.cells[index].showPreview;
|
||||||
|
|
||||||
|
//Get selection value from current cell
|
||||||
|
let newCellContent = model.getValueInRange(selection);
|
||||||
|
|
||||||
|
//Get content after selection
|
||||||
|
let tailRange = range.setStartPosition(selection.endLineNumber, selection.endColumn);
|
||||||
|
let tailCellContent = model.getValueInRange(tailRange);
|
||||||
|
|
||||||
|
//Get content before selection
|
||||||
|
let headRange = range.setEndPosition(selection.startLineNumber, selection.startColumn);
|
||||||
|
let headContent = model.getValueInRange(headRange);
|
||||||
|
|
||||||
|
// If the selection is equal to entire content then do nothing
|
||||||
|
if (headContent.length === 0 && tailCellContent.length === 0) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set content before selection if the selection is not the same as original content
|
||||||
|
if (headContent.length) {
|
||||||
|
let headsource = source.slice(range.startLineNumber - 1, selection.startLineNumber - 1);
|
||||||
|
if (selection.startColumn > 1) {
|
||||||
|
partialSource = source.slice(selection.startLineNumber - 1, selection.startLineNumber)[0].slice(0, selection.startColumn - 1);
|
||||||
|
headsource = headsource.concat(partialSource.toString());
|
||||||
|
}
|
||||||
|
this.cells[index].source = headsource;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newCellContent.length) {
|
||||||
|
let newSource = source.slice(selection.startLineNumber - 1, selection.endLineNumber) as string[];
|
||||||
|
if (selection.startColumn > 1) {
|
||||||
|
partialSource = source.slice(selection.startLineNumber - 1)[0].slice(selection.startColumn - 1);
|
||||||
|
newSource.splice(0, 1, partialSource);
|
||||||
|
}
|
||||||
|
if (selection.endColumn !== source[selection.endLineNumber - 1].length) {
|
||||||
|
let splicestart = 0;
|
||||||
|
if (selection.startLineNumber === selection.endLineNumber) {
|
||||||
|
splicestart = selection.startColumn - 1;
|
||||||
|
}
|
||||||
|
let partial = source.slice(selection.endLineNumber - 1, selection.endLineNumber)[0].slice(splicestart, selection.endColumn - 1);
|
||||||
|
newSource.splice(newSource.length - 1, 1, partial);
|
||||||
|
}
|
||||||
|
//If the selection is not from the start of the cell, create a new cell.
|
||||||
|
if (headContent.length) {
|
||||||
|
newCell = this.createCell(cellType);
|
||||||
|
newCell.source = newSource;
|
||||||
|
newCellIndex++;
|
||||||
|
this.insertCell(newCell, newCellIndex);
|
||||||
|
}
|
||||||
|
else { //update the existing cell
|
||||||
|
this.cells[index].source = newSource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tailCellContent.length) {
|
||||||
|
//tail cell will be of original cell type.
|
||||||
|
tailCell = this.createCell(this._cells[index].cellType);
|
||||||
|
let tailSource = source.slice(tailRange.startLineNumber - 1) as string[];
|
||||||
|
if (selection.endColumn > 1) {
|
||||||
|
partialSource = source.slice(tailRange.startLineNumber - 1, tailRange.startLineNumber)[0].slice(tailRange.startColumn - 1);
|
||||||
|
tailSource.splice(0, 1, partialSource);
|
||||||
|
}
|
||||||
|
tailCell.source = tailSource;
|
||||||
|
tailCellIndex = newCellIndex + 1;
|
||||||
|
this.insertCell(tailCell, tailCellIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
let activeCell = newCell ? newCell : (headContent.length ? tailCell : this.cells[index]);
|
||||||
|
let activeCellIndex = newCell ? newCellIndex : (headContent.length ? tailCellIndex : index);
|
||||||
|
|
||||||
|
//make new cell Active
|
||||||
|
this.updateActiveCell(activeCell);
|
||||||
|
activeCell.isEditMode = true;
|
||||||
|
this._contentChangedEmitter.fire({
|
||||||
|
changeType: NotebookChangeType.CellsModified,
|
||||||
|
cells: [activeCell],
|
||||||
|
cellIndex: activeCellIndex
|
||||||
|
});
|
||||||
|
activeCell.showMarkdown = showMarkdown;
|
||||||
|
activeCell.showPreview = showPreview;
|
||||||
|
|
||||||
|
//return inserted cell
|
||||||
|
return activeCell;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
public insertCell(cell: ICellModel, index?: number): ICellModel | undefined {
|
||||||
|
if (this.inErrorState) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
if (index !== undefined && index !== null && index >= 0 && index < this._cells.length) {
|
if (index !== undefined && index !== null && index >= 0 && index < this._cells.length) {
|
||||||
this._cells.splice(index, 0, cell);
|
this._cells.splice(index, 0, cell);
|
||||||
} else {
|
} else {
|
||||||
@@ -554,7 +675,6 @@ export class NotebookModel extends Disposable implements INotebookModel {
|
|||||||
cells: [cell],
|
cells: [cell],
|
||||||
cellIndex: index
|
cellIndex: index
|
||||||
});
|
});
|
||||||
|
|
||||||
return cell;
|
return cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user