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();

Reply via email to