diff --git a/assets/javascripts/discourse/connectors/after-d-editor/ai-helper-context-menu.js b/assets/javascripts/discourse/connectors/after-d-editor/ai-helper-context-menu.js index 5b55b326..c86fe5f9 100644 --- a/assets/javascripts/discourse/connectors/after-d-editor/ai-helper-context-menu.js +++ b/assets/javascripts/discourse/connectors/after-d-editor/ai-helper-context-menu.js @@ -60,6 +60,7 @@ export default class AiHelperContextMenu extends Component { willDestroy() { super.willDestroy(...arguments); document.removeEventListener("selectionchange", this.selectionChanged); + document.removeEventListener("keydown", this.onKeyDown); this._popper?.destroy(); } @@ -124,6 +125,19 @@ export default class AiHelperContextMenu extends Component { this.positionContextMenu(); } + @bind + onKeyDown(event) { + const cmdOrCtrl = event.ctrlKey || event.metaKey; + + if (cmdOrCtrl && event.key === "z" && this.oldEditorValue) { + return this.undoAIAction(); + } + + if (event.key === "Escape") { + return this.closeContextMenu(); + } + } + @debounce(INPUT_DELAY) _onSelectionChanged() { this.positionContextMenu(); @@ -189,6 +203,7 @@ export default class AiHelperContextMenu extends Component { @action setupContextMenu() { document.addEventListener("selectionchange", this.selectionChanged); + document.addEventListener("keydown", this.onKeyDown); this._dEditorInput = document.querySelector(".d-editor-input"); diff --git a/spec/system/ai_helper/ai_composer_helper_spec.rb b/spec/system/ai_helper/ai_composer_helper_spec.rb index 54f686ae..8bab3966 100644 --- a/spec/system/ai_helper/ai_composer_helper_spec.rb +++ b/spec/system/ai_helper/ai_composer_helper_spec.rb @@ -157,6 +157,28 @@ RSpec.describe "AI Composer helper", type: :system, js: true do ai_helper_context_menu.click_undo_button expect(composer.composer_input.value).to eq(OpenAiCompletionsInferenceStubs.spanish_text) end + + it "reverts results when Ctrl/Cmd + Z is pressed on the keyboard" do + trigger_context_menu(OpenAiCompletionsInferenceStubs.spanish_text) + ai_helper_context_menu.click_ai_button + ai_helper_context_menu.select_helper_model( + OpenAiCompletionsInferenceStubs.text_mode_to_id(mode), + ) + + wait_for do + composer.composer_input.value == OpenAiCompletionsInferenceStubs.translated_response.strip + end + + ai_helper_context_menu.press_undo_keys + expect(composer.composer_input.value).to eq(OpenAiCompletionsInferenceStubs.spanish_text) + end + + it "hides the context menu when pressing Escape on the keyboard" do + trigger_context_menu(OpenAiCompletionsInferenceStubs.spanish_text) + ai_helper_context_menu.click_ai_button + ai_helper_context_menu.press_escape_key + expect(ai_helper_context_menu).to have_no_context_menu + end end context "when using the proofreading mode" do diff --git a/spec/system/page_objects/components/ai_helper_context_menu.rb b/spec/system/page_objects/components/ai_helper_context_menu.rb index 525df55f..26a59f09 100644 --- a/spec/system/page_objects/components/ai_helper_context_menu.rb +++ b/spec/system/page_objects/components/ai_helper_context_menu.rb @@ -3,6 +3,7 @@ module PageObjects module Components class AIHelperContextMenu < PageObjects::Components::Base + COMPOSER_EDITOR_SELECTOR = ".d-editor-input" CONTEXT_MENU_SELECTOR = ".ai-helper-context-menu" TRIGGER_STATE_SELECTOR = "#{CONTEXT_MENU_SELECTOR}__trigger" OPTIONS_STATE_SELECTOR = "#{CONTEXT_MENU_SELECTOR}__options" @@ -26,10 +27,22 @@ module PageObjects find("#{RESETS_STATE_SELECTOR} .undo").click end + def press_undo_keys + find(COMPOSER_EDITOR_SELECTOR).send_keys([:control, "z"]) + end + + def press_escape_key + find("body").send_keys(:escape) + end + def has_context_menu? page.has_css?(CONTEXT_MENU_SELECTOR) end + def has_no_context_menu? + page.has_no_css?(CONTEXT_MENU_SELECTOR) + end + def showing_triggers? page.has_css?(TRIGGER_STATE_SELECTOR) end