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) <noreply@anthropic.com>
This commit is contained in:
Ali 2026-06-16 09:29:37 +00:00
parent 174fbe8f29
commit a915f82aed
1 changed files with 16 additions and 3 deletions

View File

@ -17,6 +17,13 @@ function setup_custom_subtabs(wrapper, currentDoctype) {
return; 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 // Helper function to find tab link element
function getTabLink(tabElement) { function getTabLink(tabElement) {
const $tab = $(tabElement); const $tab = $(tabElement);
@ -44,7 +51,11 @@ function setup_custom_subtabs(wrapper, currentDoctype) {
tabs.each((index, tab) => { tabs.each((index, tab) => {
const tabLabel = $(tab).text().trim(); 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 tabLink = getTabLink(tab);
const tabContentId = tabLink.attr("aria-controls"); const tabContentId = tabLink.attr("aria-controls");
const tabContent = $(`#${tabContentId}`); const tabContent = $(`#${tabContentId}`);
@ -71,11 +82,13 @@ function setup_custom_subtabs(wrapper, currentDoctype) {
sectionContainer.prepend(subtabContainer); sectionContainer.prepend(subtabContainer);
} }
subtabs[tabLabel].forEach((subtab) => { subtabs[parentKey].forEach((subtab) => {
const subtabElement = tabs.filter((_, el) => $(el).text().trim() === subtab); // subtab — английский; в DOM ищем по его переводу.
const subtabElement = tabs.filter((_, el) => $(el).text().trim() === tr(subtab));
if (subtabElement.length) { if (subtabElement.length) {
const subtabClone = subtabElement.clone(true); const subtabClone = subtabElement.clone(true);
subtabClone.addClass("sub-tab"); subtabClone.addClass("sub-tab");
// data-subtab-name держим английским — childToParentMap/ensureParentChainVisible на нём.
subtabClone.attr("data-subtab-name", subtab); subtabClone.attr("data-subtab-name", subtab);
const clonedLink = getTabLink(subtabClone); const clonedLink = getTabLink(subtabClone);
clonedLink.removeAttr("href"); clonedLink.removeAttr("href");