Add undo/redo to convert cells (#17835)

* add undo/redo to convert cells
This commit is contained in:
Barbara Valdez
2021-12-07 15:51:33 -08:00
committed by GitHub
parent 4ea6805d55
commit 1651f3f8bc
3 changed files with 45 additions and 3 deletions

View File

@@ -11,6 +11,8 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService';
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
import { TestLifecycleService } from 'vs/workbench/test/browser/workbenchTestServices';
import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogService';
import { NullAdsTelemetryService } from 'sql/platform/telemetry/common/adsTelemetryService';
import { CellContext } from 'sql/workbench/contrib/notebook/browser/cellViews/codeActions';
import { INotebookService } from 'sql/workbench/services/notebook/browser/notebookService';
import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
@@ -30,6 +32,8 @@ import { nb } from 'azdata';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { ExecuteManagerStub, SerializationManagerStub } from 'sql/workbench/contrib/notebook/test/stubs';
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
import { UndoRedoService } from 'vs/platform/undoRedo/common/undoRedoService';
suite('CellToolbarActions', function (): void {
suite('removeDuplicatedAndStartingSeparators', function (): void {
@@ -178,6 +182,17 @@ suite('CellToolbarActions', function (): void {
await convertCellAction.doRun({ model: notebookModel, cell: notebookModel.cells[0] });
assert.strictEqual(notebookModel.cells[0].cellType, 'markdown', 'Cell was not converted correctly second time');
});
test('Undo/redo convert cell', async function (): Promise<void> {
await notebookModel.loadContents();
notebookModel.cells[0].cellType = 'markdown';
await convertCellAction.doRun({ model: notebookModel, cell: notebookModel.cells[0] });
assert.strictEqual(notebookModel.cells[0].cellType, 'code', 'Cell was not converted correctly');
notebookModel.undo();
assert.strictEqual(notebookModel.cells[0].cellType, 'markdown', 'Undo not converting cell correctly');
notebookModel.redo();
assert.strictEqual(notebookModel.cells[0].cellType, 'code', 'Redo not converting cell correctly');
});
});
});
@@ -203,6 +218,10 @@ export async function createandLoadNotebookModel(codeContent?: nb.INotebookConte
let serviceCollection = new ServiceCollection();
let instantiationService = new InstantiationService(serviceCollection, true);
let mockContentManager = TypeMoq.Mock.ofType(NotebookEditorContentLoader);
let dialogService = TypeMoq.Mock.ofType<IDialogService>(TestDialogService, TypeMoq.MockBehavior.Loose);
let notificationService = TypeMoq.Mock.ofType<INotificationService>(TestNotificationService, TypeMoq.MockBehavior.Loose);
let undoRedoService = new UndoRedoService(dialogService.object, notificationService.object);
mockContentManager.setup(c => c.loadContent()).returns(() => Promise.resolve(codeContent ? codeContent : defaultCodeContent));
let defaultModelOptions: INotebookModelOptions = {
notebookUri: URI.file('/some/path.ipynb'),
@@ -218,5 +237,5 @@ export async function createandLoadNotebookModel(codeContent?: nb.INotebookConte
layoutChanged: undefined,
capabilitiesService: undefined
};
return new NotebookModel(defaultModelOptions, undefined, undefined, undefined, undefined, undefined, undefined, undefined);
return new NotebookModel(defaultModelOptions, undefined, undefined, undefined, new NullAdsTelemetryService(), undefined, undefined, undoRedoService);
}

View File

@@ -88,3 +88,23 @@ export class AddCellEdit implements IResourceUndoRedoElement {
this.model.sendNotebookTelemetryActionEvent(TelemetryKeys.NbTelemetryAction.RedoCell, this.cellOperation);
}
}
export class ConvertCellTypeEdit implements IResourceUndoRedoElement {
type: UndoRedoElementType.Resource = UndoRedoElementType.Resource;
label: string = localize('convertCellTypeEdit', "Convert Cell Type");
resource = this.model.notebookUri;
private readonly cellOperation = { cell_operation: 'convert_cell_type' };
constructor(private model: NotebookModel, private cell: ICellModel) {
}
undo(): void {
this.model.convertCellType(this.cell, false);
this.model.sendNotebookTelemetryActionEvent(TelemetryKeys.NbTelemetryAction.UndoCell, this.cellOperation);
}
redo(): void {
this.model.convertCellType(this.cell, false);
this.model.sendNotebookTelemetryActionEvent(TelemetryKeys.NbTelemetryAction.RedoCell, this.cellOperation);
}
}

View File

@@ -35,7 +35,7 @@ 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';
import { AddCellEdit, DeleteCellEdit, MoveCellEdit, SplitCellEdit } from 'sql/workbench/services/notebook/browser/models/cellEdit';
import { AddCellEdit, ConvertCellTypeEdit, DeleteCellEdit, MoveCellEdit, SplitCellEdit } from 'sql/workbench/services/notebook/browser/models/cellEdit';
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
import { deepClone } from 'vs/base/common/objects';
@@ -796,10 +796,13 @@ export class NotebookModel extends Disposable implements INotebookModel {
this._onActiveCellChanged.fire(cell);
}
public convertCellType(cell: ICellModel): void {
public convertCellType(cell: ICellModel, addToUndoStack: boolean = true): void {
if (cell) {
let index = this.findCellIndex(cell);
if (index > -1) {
if (addToUndoStack) {
this.undoService.pushElement(new ConvertCellTypeEdit(this, cell));
}
// Ensure override language is reset
cell.setOverrideLanguage('');
cell.cellType = cell.cellType === CellTypes.Markdown ? CellTypes.Code : CellTypes.Markdown;