diff --git a/spp_change_request_v2/static/src/components/global_shortcuts/global_shortcuts.js b/spp_change_request_v2/static/src/components/global_shortcuts/global_shortcuts.js deleted file mode 100644 index 14c550d0..00000000 --- a/spp_change_request_v2/static/src/components/global_shortcuts/global_shortcuts.js +++ /dev/null @@ -1,163 +0,0 @@ -/** @odoo-module **/ - -import {registry} from "@web/core/registry"; - -/** - * Global keyboard shortcut service for Change Requests - * - * Registers global shortcuts: - * - Alt+N: Open New Change Request wizard - * - A: Approve (when viewing pending CR) - * - R: Request Changes (when viewing pending CR) - * - D: Decline (when viewing pending CR) - */ -const globalShortcutsService = { - dependencies: ["action", "hotkey", "orm", "notification"], - - start(env, {action, hotkey, orm, notification}) { - /** - * Check if we're currently viewing a pending change request - * Returns the CR id if yes, null otherwise - */ - function getCurrentPendingCRId() { - // Get the current controller - const controller = env.services.action?.currentController; - if (!controller) return null; - - // Check if it's a form view for spp.change.request - const resModel = controller.props?.resModel; - const resId = controller.props?.resId; - if (resModel !== "spp.change.request" || !resId) return null; - - // We'll check approval_state in the action handlers - return resId; - } - - /** - * Check if the CR is in pending state before executing action - */ - async function executeCRAction(actionName) { - const crId = getCurrentPendingCRId(); - if (!crId) return; - - try { - // Read the CR state first - const [cr] = await orm.read( - "spp.change.request", - [crId], - ["approval_state", "can_approve", "can_reject"] - ); - - if (cr.approval_state !== "pending") { - // Not in pending state, ignore shortcut - return; - } - - if (actionName === "approve" && !cr.can_approve) { - notification.add( - "You don't have permission to approve this request", - { - type: "warning", - } - ); - return; - } - - if ( - (actionName === "reject" || actionName === "revision") && - !cr.can_reject - ) { - notification.add( - "You don't have permission to reject this request", - { - type: "warning", - } - ); - return; - } - - // Execute the action - if (actionName === "approve") { - await orm.call("spp.change.request", "action_approve", [[crId]]); - notification.add("Request approved", {type: "success"}); - // Reload the view - action.doAction({type: "ir.actions.act_window_close"}); - } else if (actionName === "revision") { - // Open the revision dialog - action.doAction({ - type: "ir.actions.act_window", - name: "Request Changes", - res_model: "spp.approval.revision.wizard", - view_mode: "form", - views: [[false, "form"]], - target: "new", - context: { - default_res_model: "spp.change.request", - default_res_id: crId, - }, - }); - } else if (actionName === "reject") { - // Open the rejection dialog - action.doAction({ - type: "ir.actions.act_window", - name: "Decline Request", - res_model: "spp.approval.rejection.wizard", - view_mode: "form", - views: [[false, "form"]], - target: "new", - context: { - default_res_model: "spp.change.request", - default_res_id: crId, - }, - }); - } - } catch (error) { - notification.add(error.message || `Error executing ${actionName}`, { - type: "danger", - }); - } - } - - // Register Alt+N shortcut for New Change Request - hotkey.add( - "alt+n", - () => { - action.doAction({ - type: "ir.actions.act_window", - name: "New Change Request", - res_model: "spp.cr.create.wizard", - view_mode: "form", - views: [[false, "form"]], - target: "new", - context: {}, - }); - }, - { - global: true, - bypassEditableProtection: false, - } - ); - - // Register A shortcut for Approve (only active on CR form views) - hotkey.add("a", () => executeCRAction("approve"), { - global: true, - bypassEditableProtection: false, - }); - - // Register R shortcut for Request Changes - hotkey.add("r", () => executeCRAction("revision"), { - global: true, - bypassEditableProtection: false, - }); - - // Register D shortcut for Decline - hotkey.add("d", () => executeCRAction("reject"), { - global: true, - bypassEditableProtection: false, - }); - - return {}; - }, -}; - -registry.category("services").add("cr_global_shortcuts", globalShortcutsService); diff --git a/spp_change_request_v2/static/src/components/review_panel/review_panel.js b/spp_change_request_v2/static/src/components/review_panel/review_panel.js index 7f0aa8fa..7fb7517a 100644 --- a/spp_change_request_v2/static/src/components/review_panel/review_panel.js +++ b/spp_change_request_v2/static/src/components/review_panel/review_panel.js @@ -1,6 +1,6 @@ /** @odoo-module **/ -import {Component, onMounted, onWillUnmount, useRef, useState} from "@odoo/owl"; +import {Component, onMounted, useRef, useState} from "@odoo/owl"; import {useService} from "@web/core/utils/hooks"; import {_t} from "@web/core/l10n/translation"; @@ -10,14 +10,6 @@ import {_t} from "@web/core/l10n/translation"; * Provides a side-by-side view of: * - Left: Current registrant data * - Right: Proposed changes - * - * Keyboard shortcuts: - * - A: Approve - * - R: Request changes - * - D: Decline - * - N: Next in queue - * - P: Previous in queue - * - Escape: Close panel */ export class CRReviewPanel extends Component { static template = "spp_change_request_v2.CRReviewPanel"; @@ -54,11 +46,6 @@ export class CRReviewPanel extends Component { onMounted(() => { this.loadData(); - document.addEventListener("keydown", this.onKeydown.bind(this)); - }); - - onWillUnmount(() => { - document.removeEventListener("keydown", this.onKeydown.bind(this)); }); } @@ -163,47 +150,6 @@ export class CRReviewPanel extends Component { } } - // Keyboard handler - onKeydown(event) { - // Don't handle if we're in an input - if (event.target.tagName === "INPUT" || event.target.tagName === "TEXTAREA") { - return; - } - - switch (event.key.toLowerCase()) { - case "a": - if (this.state.canApprove) { - event.preventDefault(); - this.onApprove(); - } - break; - case "r": - if (this.state.canReject) { - event.preventDefault(); - this.onRequestChanges(); - } - break; - case "d": - if (this.state.canReject) { - event.preventDefault(); - this.onDecline(); - } - break; - case "n": - event.preventDefault(); - this.onNext(); - break; - case "p": - event.preventDefault(); - this.onPrevious(); - break; - case "escape": - event.preventDefault(); - this.onClose(); - break; - } - } - // Action handlers async onApprove() { if (this.state.showApproveComment) {