From a915f82aed8485bce7d895245a51d2c987f598a4 Mon Sep 17 00:00:00 2001 From: Ali <010109ali@gmail.com> Date: Tue, 16 Jun 2026 09:29:37 +0000 Subject: [PATCH] fix: match subtabs by translated label, not raw English key tab_hierarchy stores raw (English) Tab Break labels, but Frappe renders tab text through __(), so under AZ/RU the DOM text never equals the hierarchy key and subtabs silently stay flat (e.g. E-Taxes Settings, Bank Integration Profile). Doctypes with native-AZ labels were unaffected. Compare DOM tab text against tr(key) at the matching boundary; keep all internal bookkeeping (childToParentMap, data-subtab-name) in English so clicks and parent-chain reveal stay consistent across languages. Co-Authored-By: Claude Opus 4.8 (1M context) --- custom_subtabs/public/js/custom_subtabs.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/custom_subtabs/public/js/custom_subtabs.js b/custom_subtabs/public/js/custom_subtabs.js index 1cbe177..9516207 100644 --- a/custom_subtabs/public/js/custom_subtabs.js +++ b/custom_subtabs/public/js/custom_subtabs.js @@ -17,6 +17,13 @@ function setup_custom_subtabs(wrapper, currentDoctype) { return; } + // tab_hierarchy хранит СЫРЫЕ (английские) label'ы, а Frappe рисует вкладки + // через __(), т.е. в DOM текст уже переведён (AZ/RU). Поэтому сопоставлять + // вкладку из DOM с ключом иерархии нужно через перевод этого ключа. + // Внутренние структуры (childToParentMap, data-subtab-name) оставляем на + // английском — переводим только на границе сравнения с DOM. + const tr = (s) => (typeof __ === 'function' ? __(s) : s); + // Helper function to find tab link element function getTabLink(tabElement) { const $tab = $(tabElement); @@ -44,7 +51,11 @@ function setup_custom_subtabs(wrapper, currentDoctype) { tabs.each((index, tab) => { const tabLabel = $(tab).text().trim(); - if (subtabs[tabLabel]) { + // tabLabel — переведённый текст из DOM; ключ иерархии — английский. + // Находим английский ключ-родитель, чей перевод совпал с DOM. + const parentKey = Object.keys(subtabs).find((k) => tr(k) === tabLabel); + + if (parentKey) { const tabLink = getTabLink(tab); const tabContentId = tabLink.attr("aria-controls"); const tabContent = $(`#${tabContentId}`); @@ -71,11 +82,13 @@ function setup_custom_subtabs(wrapper, currentDoctype) { sectionContainer.prepend(subtabContainer); } - subtabs[tabLabel].forEach((subtab) => { - const subtabElement = tabs.filter((_, el) => $(el).text().trim() === subtab); + subtabs[parentKey].forEach((subtab) => { + // subtab — английский; в DOM ищем по его переводу. + const subtabElement = tabs.filter((_, el) => $(el).text().trim() === tr(subtab)); if (subtabElement.length) { const subtabClone = subtabElement.clone(true); subtabClone.addClass("sub-tab"); + // data-subtab-name держим английским — childToParentMap/ensureParentChainVisible на нём. subtabClone.attr("data-subtab-name", subtab); const clonedLink = getTabLink(subtabClone); clonedLink.removeAttr("href");