This is an automated email from the ASF dual-hosted git repository. xiaozhenliu pushed a commit to branch xiaozhen-fix-undoredo in repository https://gitbox.apache.org/repos/asf/texera.git
commit 55b4779beb0d9784d20a529255e1c019e2b6ba30 Author: Xiao-zhen-Liu <[email protected]> AuthorDate: Mon Oct 6 14:46:30 2025 -0700 Revert "fix(ui): temporarily disable frontend undo and redo (#3571)" This reverts commit ece56ec9a4645bd6c4223a9ecd27a3ff099ceeb0. --- .../workspace/component/menu/menu.component.html | 32 +++---- .../workflow-editor.component.spec.ts | 100 ++++++++++----------- .../workflow-editor/workflow-editor.component.ts | 32 ++++--- 3 files changed, 80 insertions(+), 84 deletions(-) diff --git a/core/gui/src/app/workspace/component/menu/menu.component.html b/core/gui/src/app/workspace/component/menu/menu.component.html index e212169321..c7c486ae28 100644 --- a/core/gui/src/app/workspace/component/menu/menu.component.html +++ b/core/gui/src/app/workspace/component/menu/menu.component.html @@ -291,22 +291,22 @@ nzType="database" nzTheme="twotone"></i> </button> - <!-- <button--> - <!-- (click)="undoRedoService.undoAction()"--> - <!-- [disabled]="displayParticularWorkflowVersion || !undoRedoService.canUndo()"--> - <!-- nz-button>--> - <!-- <i--> - <!-- nz-icon--> - <!-- nzType="undo"></i>--> - <!-- </button>--> - <!-- <button--> - <!-- (click)="undoRedoService.redoAction()"--> - <!-- [disabled]="displayParticularWorkflowVersion || !undoRedoService.canRedo()"--> - <!-- nz-button>--> - <!-- <i--> - <!-- nz-icon--> - <!-- nzType="redo"></i>--> - <!-- </button>--> + <button + (click)="undoRedoService.undoAction()" + [disabled]="displayParticularWorkflowVersion || !undoRedoService.canUndo()" + nz-button> + <i + nz-icon + nzType="undo"></i> + </button> + <button + (click)="undoRedoService.redoAction()" + [disabled]="displayParticularWorkflowVersion || !undoRedoService.canRedo()" + nz-button> + <i + nz-icon + nzType="redo"></i> + </button> </nz-button-group> </ng-template> <nz-dropdown-menu #menu="nzDropdownMenu"> diff --git a/core/gui/src/app/workspace/component/workflow-editor/workflow-editor.component.spec.ts b/core/gui/src/app/workspace/component/workflow-editor/workflow-editor.component.spec.ts index 40574b0f7e..161d217fd8 100644 --- a/core/gui/src/app/workspace/component/workflow-editor/workflow-editor.component.spec.ts +++ b/core/gui/src/app/workspace/component/workflow-editor/workflow-editor.component.spec.ts @@ -897,56 +897,54 @@ describe("WorkflowEditorComponent", () => { expect(jointGraphWrapper.getCurrentHighlightedOperatorIDs()).toContain(mockResultPredicate.operatorID); }); - // Temporarily disabling undo-redo because of a bug that can cause invalid workflow structures. - // TODO: enable after fixing the bug. - // //undo - // it("should undo action when user presses command + Z or control + Z", () => { - // spyOn(workflowVersionService, "getDisplayParticularVersionStream").and.returnValue(of(false)); - // spyOn(undoRedoService, "canUndo").and.returnValue(true); - // let undoSpy = spyOn(undoRedoService, "undoAction"); - // fixture.detectChanges(); - // const commandZEvent = new KeyboardEvent("keydown", { key: "Z", metaKey: true, shiftKey: false }); - // (document.activeElement as HTMLElement)?.blur(); - // document.dispatchEvent(commandZEvent); - // fixture.detectChanges(); - // expect(undoSpy).toHaveBeenCalledTimes(1); - // - // const controlZEvent = new KeyboardEvent("keydown", { key: "Z", ctrlKey: true, shiftKey: false }); - // (document.activeElement as HTMLElement)?.blur(); - // document.dispatchEvent(controlZEvent); - // fixture.detectChanges(); - // expect(undoSpy).toHaveBeenCalledTimes(2); - // }); - // - // //redo - // it("should redo action when user presses command/control + Y or command/control + shift + Z", () => { - // spyOn(workflowVersionService, "getDisplayParticularVersionStream").and.returnValue(of(false)); - // spyOn(undoRedoService, "canRedo").and.returnValue(true); - // let redoSpy = spyOn(undoRedoService, "redoAction"); - // fixture.detectChanges(); - // const commandYEvent = new KeyboardEvent("keydown", { key: "y", metaKey: true, shiftKey: false }); - // (document.activeElement as HTMLElement)?.blur(); - // document.dispatchEvent(commandYEvent); - // fixture.detectChanges(); - // expect(redoSpy).toHaveBeenCalledTimes(1); - // - // const controlYEvent = new KeyboardEvent("keydown", { key: "y", ctrlKey: true, shiftKey: false }); - // (document.activeElement as HTMLElement)?.blur(); - // document.dispatchEvent(controlYEvent); - // fixture.detectChanges(); - // expect(redoSpy).toHaveBeenCalledTimes(2); - // - // const commandShitZEvent = new KeyboardEvent("keydown", { key: "z", metaKey: true, shiftKey: true }); - // (document.activeElement as HTMLElement)?.blur(); - // document.dispatchEvent(commandShitZEvent); - // fixture.detectChanges(); - // expect(redoSpy).toHaveBeenCalledTimes(3); - // - // const controlShitZEvent = new KeyboardEvent("keydown", { key: "z", ctrlKey: true, shiftKey: true }); - // (document.activeElement as HTMLElement)?.blur(); - // document.dispatchEvent(controlShitZEvent); - // fixture.detectChanges(); - // expect(redoSpy).toHaveBeenCalledTimes(4); - // }); + //undo + it("should undo action when user presses command + Z or control + Z", () => { + spyOn(workflowVersionService, "getDisplayParticularVersionStream").and.returnValue(of(false)); + spyOn(undoRedoService, "canUndo").and.returnValue(true); + let undoSpy = spyOn(undoRedoService, "undoAction"); + fixture.detectChanges(); + const commandZEvent = new KeyboardEvent("keydown", { key: "Z", metaKey: true, shiftKey: false }); + (document.activeElement as HTMLElement)?.blur(); + document.dispatchEvent(commandZEvent); + fixture.detectChanges(); + expect(undoSpy).toHaveBeenCalledTimes(1); + + const controlZEvent = new KeyboardEvent("keydown", { key: "Z", ctrlKey: true, shiftKey: false }); + (document.activeElement as HTMLElement)?.blur(); + document.dispatchEvent(controlZEvent); + fixture.detectChanges(); + expect(undoSpy).toHaveBeenCalledTimes(2); + }); + + //redo + it("should redo action when user presses command/control + Y or command/control + shift + Z", () => { + spyOn(workflowVersionService, "getDisplayParticularVersionStream").and.returnValue(of(false)); + spyOn(undoRedoService, "canRedo").and.returnValue(true); + let redoSpy = spyOn(undoRedoService, "redoAction"); + fixture.detectChanges(); + const commandYEvent = new KeyboardEvent("keydown", { key: "y", metaKey: true, shiftKey: false }); + (document.activeElement as HTMLElement)?.blur(); + document.dispatchEvent(commandYEvent); + fixture.detectChanges(); + expect(redoSpy).toHaveBeenCalledTimes(1); + + const controlYEvent = new KeyboardEvent("keydown", { key: "y", ctrlKey: true, shiftKey: false }); + (document.activeElement as HTMLElement)?.blur(); + document.dispatchEvent(controlYEvent); + fixture.detectChanges(); + expect(redoSpy).toHaveBeenCalledTimes(2); + + const commandShitZEvent = new KeyboardEvent("keydown", { key: "z", metaKey: true, shiftKey: true }); + (document.activeElement as HTMLElement)?.blur(); + document.dispatchEvent(commandShitZEvent); + fixture.detectChanges(); + expect(redoSpy).toHaveBeenCalledTimes(3); + + const controlShitZEvent = new KeyboardEvent("keydown", { key: "z", ctrlKey: true, shiftKey: true }); + (document.activeElement as HTMLElement)?.blur(); + document.dispatchEvent(controlShitZEvent); + fixture.detectChanges(); + expect(redoSpy).toHaveBeenCalledTimes(4); + }); }); }); diff --git a/core/gui/src/app/workspace/component/workflow-editor/workflow-editor.component.ts b/core/gui/src/app/workspace/component/workflow-editor/workflow-editor.component.ts index 3f419d0561..6c2cd8c8d7 100644 --- a/core/gui/src/app/workspace/component/workflow-editor/workflow-editor.component.ts +++ b/core/gui/src/app/workspace/component/workflow-editor/workflow-editor.component.ts @@ -190,23 +190,21 @@ export class WorkflowEditorComponent implements OnInit, AfterViewInit, OnDestroy .pipe(takeUntil(this._onProcessKeyboardActionObservable)) .subscribe(displayParticularWorkflowVersion => { if (!displayParticularWorkflowVersion) { - // Temporarily disabling undo-redo because of a bug that can cause invalid workflow structures. - // TODO: enable after fixing the bug. - // // cmd/ctrl+z undo ; ctrl+y or cmd/ctrl + shift+z for redo - // if ((event.metaKey || event.ctrlKey) && !event.shiftKey && event.key.toLowerCase() === "z") { - // // UNDO - // if (this.undoRedoService.canUndo()) { - // this.undoRedoService.undoAction(); - // } - // } else if ( - // ((event.metaKey || event.ctrlKey) && !event.shiftKey && event.key.toLowerCase() === "y") || - // ((event.metaKey || event.ctrlKey) && event.shiftKey && event.key.toLowerCase() === "z") - // ) { - // // redo - // if (this.undoRedoService.canRedo()) { - // this.undoRedoService.redoAction(); - // } - // } + // cmd/ctrl+z undo ; ctrl+y or cmd/ctrl + shift+z for redo + if ((event.metaKey || event.ctrlKey) && !event.shiftKey && event.key.toLowerCase() === "z") { + // UNDO + if (this.undoRedoService.canUndo()) { + this.undoRedoService.undoAction(); + } + } else if ( + ((event.metaKey || event.ctrlKey) && !event.shiftKey && event.key.toLowerCase() === "y") || + ((event.metaKey || event.ctrlKey) && event.shiftKey && event.key.toLowerCase() === "z") + ) { + // redo + if (this.undoRedoService.canRedo()) { + this.undoRedoService.redoAction(); + } + } // below for future hotkeys } this._onProcessKeyboardActionObservable.complete();
