Fix right-click transfer behaviour. (#7827)

When using the right-click transfer option, the wrong leg was transferred.
This commit is contained in:
frytimo
2026-04-01 12:34:41 -03:00
committed by GitHub
parent dc198642bd
commit 0c92eb5c0a
@@ -1829,6 +1829,43 @@ function on_ext_contextmenu(event, ext_num) {
show_context_menu(event, items);
}
/**
* Infer the local extension for a call UUID (used for leg-aware actions).
* Prefers channel presence and then CID/destination fields when they map to known extensions.
* @param {string} uuid
* @returns {string}
*/
function get_call_source_extension(uuid) {
if (!uuid) return '';
const ch = calls_map.get(uuid);
if (!ch) return '';
const presence = (((ch.channel_presence_id || '').split('@')[0]) || '').trim();
if (presence && extensions_map.has(presence)) return presence;
const dest = ((ch.caller_destination_number || '') + '').trim();
if (dest && extensions_map.has(dest)) return dest;
const cid = ((ch.caller_caller_id_number || ch.caller_id_number || '') + '').trim();
if (cid && extensions_map.has(cid)) return cid;
return '';
}
/**
* Derive normalized panel call state for a single call row.
* @param {object|null} ch
* @returns {string}
*/
function get_call_row_state(ch) {
if (!ch) return 'unknown';
const cs = ((ch.channel_call_state || '') + '').toUpperCase();
const as = ((ch.answer_state || '') + '').toUpperCase();
if (cs === 'HELD' || as === 'HELD') return 'held';
if (cs.indexOf('RING') !== -1 || as.indexOf('RING') !== -1 || as === 'EARLY') return 'ringing';
return 'active';
}
/**
* Right-click handler for call rows in the Calls tab.
* @param {MouseEvent} event
@@ -1837,29 +1874,65 @@ function on_ext_contextmenu(event, ext_num) {
function on_call_contextmenu(event, uuid) {
if (!uuid) return;
const items = [];
const call_info = calls_map.get(uuid) || null;
const source_ext = get_call_source_extension(uuid);
const is_mine = !!(source_ext && Array.isArray(user_own_extensions) && user_own_extensions.includes(source_ext));
const state = get_call_row_state(call_info);
if (permissions.operator_panel_manage) {
items.push({ label: text['label-transfer'] || 'Transfer', icon_class: 'fa-solid fa-arrow-right-from-bracket',
fn: function () { open_transfer_modal(uuid); } });
if (state === 'ringing' && source_ext) {
const call_dest = ((call_info || {}).caller_destination_number || '').trim();
const call_cid = ((call_info || {}).caller_caller_id_number || (call_info || {}).caller_id_number || '').trim();
let direction_raw = '';
if (call_dest === source_ext && call_cid !== source_ext) direction_raw = 'inbound';
else if (call_cid === source_ext && call_dest !== source_ext) direction_raw = 'outbound';
else direction_raw = (((call_info || {}).call_direction || (call_info || {}).variable_call_direction || '') + '').toLowerCase();
const is_outbound = direction_raw === 'outbound';
if (is_mine) {
if (permissions.operator_panel_hangup) {
if (!is_outbound) {
items.push({ label: text['button-reject'] || 'Reject', icon_class: 'fa-solid fa-phone-slash',
fn: function () { action_reject(uuid); } });
}
items.push({ label: text['button-hangup_caller'] || 'Hangup Caller', icon_class: 'fa-solid fa-xmark',
fn: function () { action_hangup_caller(uuid); }, danger: true });
}
} else {
if (permissions.operator_panel_manage) {
items.push({ label: text['button-intercept'] || 'Intercept', icon_class: 'fa-solid fa-phone-volume',
fn: function () { action_intercept_icon(uuid, source_ext); } });
}
if (permissions.operator_panel_hangup) {
items.push({ label: text['button-hangup_caller'] || 'Hangup Caller', icon_class: 'fa-solid fa-xmark',
fn: function () { action_hangup_caller(uuid); }, danger: true });
}
}
}
if (permissions.operator_panel_eavesdrop) {
items.push({ label: text['button-eavesdrop'] || 'Eavesdrop', icon_class: 'fa-solid fa-ear-listen',
fn: function () { action_eavesdrop(uuid); } });
}
if (permissions.operator_panel_coach) {
items.push({ label: text['button-whisper'] || 'Whisper', icon_class: 'fa-solid fa-comment-dots',
fn: function () { action_whisper(uuid); } });
items.push({ label: text['button-barge'] || 'Barge', icon_class: 'fa-solid fa-volume-high',
fn: function () { action_barge(uuid); } });
}
if (permissions.operator_panel_record) {
items.push({ label: text['button-record'] || 'Record', icon_class: 'fa-solid fa-circle-dot',
fn: function () { action_record(uuid); } });
}
if (permissions.operator_panel_hangup) {
if (items.length) items.push({ separator: true });
items.push({ label: text['label-hangup'] || 'Hangup', icon_class: 'fa-solid fa-phone-slash',
fn: function () { action_hangup(uuid); }, danger: true });
if (!items.length) {
if (permissions.operator_panel_manage) {
items.push({ label: text['label-transfer'] || 'Transfer', icon_class: 'fa-solid fa-arrow-right-from-bracket',
fn: function () { open_transfer_modal(uuid, source_ext); } });
}
if (permissions.operator_panel_eavesdrop) {
items.push({ label: text['button-eavesdrop'] || 'Eavesdrop', icon_class: 'fa-solid fa-ear-listen',
fn: function () { action_eavesdrop(uuid); } });
}
if (permissions.operator_panel_coach) {
items.push({ label: text['button-whisper'] || 'Whisper', icon_class: 'fa-solid fa-comment-dots',
fn: function () { action_whisper(uuid); } });
items.push({ label: text['button-barge'] || 'Barge', icon_class: 'fa-solid fa-volume-high',
fn: function () { action_barge(uuid); } });
}
if (permissions.operator_panel_record) {
items.push({ label: text['button-record'] || 'Record', icon_class: 'fa-solid fa-circle-dot',
fn: function () { action_record(uuid); } });
}
if (permissions.operator_panel_hangup) {
if (items.length) items.push({ separator: true });
items.push({ label: text['label-hangup'] || 'Hangup', icon_class: 'fa-solid fa-phone-slash',
fn: function () { action_hangup(uuid); }, danger: true });
}
}
if (!items.length) return;
@@ -1957,6 +2030,7 @@ function confirm_transfer() {
context: domain_name,
source_extension: source_ext,
};
if (source_ext) payload.bleg = true;
console.debug('[OP] confirm_transfer', { action, transfer_mode: selected_mode, payload });
send_action(action, payload).catch(console.error);