new branch for frappe v16
This commit is contained in:
parent
e5e7e3b93c
commit
2056a43cce
|
|
@ -1,18 +1,25 @@
|
||||||
|
/* Основной контейнер субтабов */
|
||||||
.sub-tab-container {
|
.sub-tab-container {
|
||||||
margin: 0 !important;
|
margin: 0 !important;
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
display: flex !important;
|
display: flex !important;
|
||||||
justify-content: flex-start !important;
|
justify-content: flex-start !important;
|
||||||
border-bottom: 1px solid #ddd !important;
|
border-bottom: 1px solid #dee2e6 !important;
|
||||||
|
background-color: #fff !important;
|
||||||
|
position: relative !important;
|
||||||
|
z-index: 1 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Отдельные субтабы */
|
||||||
.sub-tab-container .sub-tab {
|
.sub-tab-container .sub-tab {
|
||||||
margin: 0 !important;
|
margin: 0 !important;
|
||||||
background: none !important;
|
background: none !important;
|
||||||
border: none !important;
|
border: none !important;
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
|
position: relative !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ссылки в субтабах */
|
||||||
.sub-tab-container .sub-tab a {
|
.sub-tab-container .sub-tab a {
|
||||||
text-decoration: none !important;
|
text-decoration: none !important;
|
||||||
display: block !important;
|
display: block !important;
|
||||||
|
|
@ -24,16 +31,74 @@
|
||||||
margin: 0 !important;
|
margin: 0 !important;
|
||||||
background: transparent !important;
|
background: transparent !important;
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
transition: color 0.15s ease-in-out !important;
|
||||||
|
position: relative !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sub-tab-container .sub-tab a:hover {
|
.sub-tab-container .sub-tab a:hover {
|
||||||
color: #000 !important; /* Цвет текста при наведении */
|
color: #000 !important; /* Только изменение цвета, без фона */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Активный субтаб */
|
||||||
.sub-tab-container .sub-tab.active a {
|
.sub-tab-container .sub-tab.active a {
|
||||||
color: #000 !important; /* Черный текст для активного таба */
|
color: #000 !important;
|
||||||
font-weight: 600 !important; /* Жирный шрифт */
|
font-weight: 600 !important;
|
||||||
border-bottom: 1px solid #000 !important; /* Черная активная полоска снизу */
|
border-bottom: 2px solid #000 !important;
|
||||||
background-color: transparent !important; /* Без фона */
|
background-color: transparent !important;
|
||||||
border-radius: 0 !important; /* Без скруглений */
|
border-radius: 0 !important;
|
||||||
|
margin-bottom: -1px !important; /* Перекрываем нижнюю границу контейнера */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Интеграция с основными табами ERPNext */
|
||||||
|
.form-tabs + .sub-tab-container {
|
||||||
|
border-top: none !important;
|
||||||
|
margin-top: -1px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Убираем лишние отступы для форм с субтабами */
|
||||||
|
.sub-tab-container + .form-layout,
|
||||||
|
.sub-tab-container ~ .form-layout {
|
||||||
|
margin-top: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Адаптивность */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.sub-tab-container {
|
||||||
|
flex-wrap: wrap !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-tab-container .sub-tab a {
|
||||||
|
padding: 8px 12px !important;
|
||||||
|
font-size: 13px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Убираем конфликтующие стили Bootstrap */
|
||||||
|
.sub-tab-container .nav-link {
|
||||||
|
padding: 0 !important;
|
||||||
|
border: none !important;
|
||||||
|
background: none !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Плавное появление/исчезание */
|
||||||
|
.sub-tab-container {
|
||||||
|
opacity: 1 !important;
|
||||||
|
transition: opacity 0.2s ease-in-out !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-tab-container[style*="display: none"] {
|
||||||
|
opacity: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Убираем лишние границы и тени */
|
||||||
|
.sub-tab-container .sub-tab,
|
||||||
|
.sub-tab-container .sub-tab a,
|
||||||
|
.sub-tab-container .nav-item {
|
||||||
|
box-shadow: none !important;
|
||||||
|
border-left: none !important;
|
||||||
|
border-right: none !important;
|
||||||
|
border-top: none !important;
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,7 @@
|
||||||
frappe.ui.form.Layout.prototype.setup_tab_events = function () {
|
frappe.ui.form.Layout.prototype.setup_tab_events = function () {
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const tabs = this.wrapper.find("ul.form-tabs > li.nav-item");
|
const tabs = this.wrapper.find("ul.form-tabs > li.nav-item");
|
||||||
|
|
||||||
// Получение текущего Doctype в нижнем регистре
|
|
||||||
const currentDoctype = cur_frm.doctype;
|
const currentDoctype = cur_frm.doctype;
|
||||||
|
|
||||||
const hierarchy = frappe.boot.tab_hierarchy[currentDoctype];
|
const hierarchy = frappe.boot.tab_hierarchy[currentDoctype];
|
||||||
|
|
||||||
if (!hierarchy) {
|
if (!hierarchy) {
|
||||||
|
|
@ -30,49 +26,6 @@ frappe.ui.form.Layout.prototype.setup_tab_events = function () {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to handle showing/hiding subtabs and sub-subtabs
|
|
||||||
function findParentAndShowSubtabs(currentTabName) {
|
|
||||||
if (!currentTabName) return;
|
|
||||||
|
|
||||||
let parentTabName = null;
|
|
||||||
|
|
||||||
// Find the parent tab and its subtabs
|
|
||||||
for (const [mainTab, subtabsArray] of Object.entries(subtabs)) {
|
|
||||||
if (subtabsArray.includes(currentTabName)) {
|
|
||||||
parentTabName = mainTab;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!parentTabName) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show the subtabs for the parent tab
|
|
||||||
const parentSubtabs = subtabs[parentTabName] || [];
|
|
||||||
parentSubtabs.forEach((subtabName) => {
|
|
||||||
const subtabElement = $(`.nav-item:contains(${subtabName})`);
|
|
||||||
const subtabContentId = `${currentDoctype.toLowerCase().replace(/\s+/g, '-')}-${subtabName.toLowerCase().replace(/\s+/g, '_')}_tab`;
|
|
||||||
const subtabContent = $(`#${subtabContentId}`);
|
|
||||||
|
|
||||||
if (subtabElement.length) {
|
|
||||||
subtabElement.css("display", "block");
|
|
||||||
|
|
||||||
// If the current tab is the subtab, show its content
|
|
||||||
if (subtabName === currentTabName) {
|
|
||||||
subtabContent.addClass("active show").css("display", "block");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Show the parent tab's content
|
|
||||||
const parentTabContentId = `${currentDoctype.toLowerCase().replace(/\s+/g, '-')}-${parentTabName.toLowerCase().replace(/\s+/g, '_')}_tab`;
|
|
||||||
showTabContent(parentTabContentId);
|
|
||||||
|
|
||||||
// Recursively handle the parent tab
|
|
||||||
findParentAndShowSubtabs(parentTabName);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process subtabs
|
// Process subtabs
|
||||||
tabs.each((index, tab) => {
|
tabs.each((index, tab) => {
|
||||||
const tabLabel = $(tab).text().trim();
|
const tabLabel = $(tab).text().trim();
|
||||||
|
|
@ -85,20 +38,44 @@ frappe.ui.form.Layout.prototype.setup_tab_events = function () {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sectionContainer = tabContent.find(".row.form-section.card-section.visible-section");
|
const possibleSelectors = [
|
||||||
|
".row.form-section.card-section.visible-section",
|
||||||
|
".form-section",
|
||||||
|
".row.form-section",
|
||||||
|
".card-section",
|
||||||
|
".visible-section",
|
||||||
|
".row",
|
||||||
|
".section",
|
||||||
|
"div[class*='section']",
|
||||||
|
"div[class*='form']"
|
||||||
|
];
|
||||||
|
|
||||||
|
let sectionContainer = null;
|
||||||
|
|
||||||
|
possibleSelectors.forEach(selector => {
|
||||||
|
const found = tabContent.find(selector);
|
||||||
|
if (found.length > 0 && !sectionContainer) {
|
||||||
|
sectionContainer = found.first();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (!sectionContainer.length) {
|
if (!sectionContainer || sectionContainer.length === 0) {
|
||||||
return;
|
sectionContainer = tabContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
let subtabContainer = sectionContainer.find('.sub-tab-container');
|
// Ищем контейнер субтабов рядом с основными табами, а не внутри контента
|
||||||
|
const mainTabsContainer = this.wrapper.find("ul.form-tabs");
|
||||||
|
let subtabContainer = mainTabsContainer.siblings('.sub-tab-container[data-parent-id="' + tabContentId + '"]');
|
||||||
|
|
||||||
if (!subtabContainer.length) {
|
if (!subtabContainer.length) {
|
||||||
subtabContainer = $("<div class='sub-tab-container nav' data-parent-id='" + tabContentId + "'></div>");
|
// Создаем контейнер субтабов после основных табов
|
||||||
sectionContainer.append(subtabContainer);
|
subtabContainer = $("<div class='sub-tab-container nav' data-parent-id='" + tabContentId + "' style='display: none;'></div>");
|
||||||
|
mainTabsContainer.after(subtabContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
subtabs[tabLabel].forEach((subtab) => {
|
subtabs[tabLabel].forEach((subtab) => {
|
||||||
const subtabElement = tabs.filter((_, el) => $(el).text().trim() === subtab);
|
const subtabElement = tabs.filter((_, el) => $(el).text().trim() === subtab);
|
||||||
|
|
||||||
if (subtabElement.length) {
|
if (subtabElement.length) {
|
||||||
const subtabClone = subtabElement.clone();
|
const subtabClone = subtabElement.clone();
|
||||||
subtabClone.addClass("sub-tab");
|
subtabClone.addClass("sub-tab");
|
||||||
|
|
@ -112,8 +89,8 @@ frappe.ui.form.Layout.prototype.setup_tab_events = function () {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle main tab activation
|
// Handle main tab activation (исключаем субтабы)
|
||||||
$(".nav-item").on("click", function () {
|
$(".nav-item:not(.sub-tab)").off("click.subtabs").on("click.subtabs", function () {
|
||||||
const clickedTab = $(this);
|
const clickedTab = $(this);
|
||||||
const tabId = clickedTab.find("a").attr("aria-controls");
|
const tabId = clickedTab.find("a").attr("aria-controls");
|
||||||
|
|
||||||
|
|
@ -127,51 +104,91 @@ frappe.ui.form.Layout.prototype.setup_tab_events = function () {
|
||||||
$(".nav-item").removeClass("active");
|
$(".nav-item").removeClass("active");
|
||||||
clickedTab.addClass("active");
|
clickedTab.addClass("active");
|
||||||
|
|
||||||
|
// Скрываем все контейнеры субтабов
|
||||||
|
$(".sub-tab-container").css("display", "none");
|
||||||
|
|
||||||
|
// Показываем контейнер субтабов для активного таба
|
||||||
$(".sub-tab-container").each(function () {
|
$(".sub-tab-container").each(function () {
|
||||||
const containerParentId = $(this).attr("data-parent-id");
|
const containerParentId = $(this).attr("data-parent-id");
|
||||||
|
|
||||||
if (containerParentId === tabId) {
|
if (containerParentId === tabId) {
|
||||||
$(this).find(".sub-tab").css("display", "block");
|
$(this).css("display", "flex");
|
||||||
} else {
|
$(this).find(".sub-tab").removeClass("active");
|
||||||
$(this).find(".sub-tab").css("display", "none");
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle subtab activation
|
// Handle subtab activation (упрощенная логика)
|
||||||
$(".sub-tab").on("click", function (event) {
|
$(document).off("click.subtabs", ".sub-tab").on("click.subtabs", ".sub-tab", function (event) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
const clickedSubtab = $(this);
|
const clickedSubtab = $(this);
|
||||||
const subtabId = clickedSubtab.find("a").attr("aria-controls");
|
const subtabId = clickedSubtab.find("a").attr("aria-controls");
|
||||||
const subtabName = clickedSubtab.text().trim();
|
const parentTabId = clickedSubtab.attr("data-parent-id");
|
||||||
|
|
||||||
$(".sub-tab").removeClass("active");
|
// Делаем активным только кликнутый субтаб в этом контейнере
|
||||||
|
clickedSubtab.siblings(".sub-tab").removeClass("active");
|
||||||
clickedSubtab.addClass("active");
|
clickedSubtab.addClass("active");
|
||||||
|
|
||||||
|
// Скрываем все контенты табов
|
||||||
hideAllTabContents();
|
hideAllTabContents();
|
||||||
|
|
||||||
|
// Показываем контент субтаба
|
||||||
const subtabContent = $(`#${subtabId}`);
|
const subtabContent = $(`#${subtabId}`);
|
||||||
|
|
||||||
if (subtabContent.length) {
|
if (subtabContent.length) {
|
||||||
subtabContent.addClass("active show").css("display", "block");
|
subtabContent.addClass("active show").css("display", "block");
|
||||||
}
|
}
|
||||||
|
|
||||||
findParentAndShowSubtabs(subtabName);
|
// Оставляем родительский таб активным и видимым
|
||||||
|
$(".nav-item:not(.sub-tab)").removeClass("active");
|
||||||
|
const parentTab = $(`.nav-item:not(.sub-tab) a[aria-controls="${parentTabId}"]`).closest('.nav-item');
|
||||||
|
if (parentTab.length) {
|
||||||
|
parentTab.addClass("active");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Убеждаемся что контейнер субтабов остается видимым
|
||||||
|
const subtabContainer = clickedSubtab.closest('.sub-tab-container');
|
||||||
|
if (subtabContainer.length) {
|
||||||
|
subtabContainer.css("display", "flex");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Debug log
|
// Проверяем активную вкладку при загрузке страницы
|
||||||
setInterval(() => {
|
let activeTab = $(".nav-item:not(.sub-tab).active");
|
||||||
const activeMainTab = $(".nav-item.active").text().trim();
|
|
||||||
const activeSubTabs = $(".sub-tab.active")
|
// Способ 2: Поиск по активному контенту
|
||||||
.map(function () {
|
if (!activeTab.length) {
|
||||||
return $(this).text().trim();
|
const activeContent = $(".form-tab-content > .tab-pane.active");
|
||||||
})
|
|
||||||
.get();
|
if (activeContent.length) {
|
||||||
const visibleContent = $(".form-tab-content > .tab-pane:visible")
|
const activeContentId = activeContent.attr('id');
|
||||||
.map(function () {
|
activeTab = $(`.nav-item a[aria-controls="${activeContentId}"]`).closest('.nav-item');
|
||||||
return $(this).attr("id");
|
}
|
||||||
})
|
}
|
||||||
.get();
|
|
||||||
|
// Способ 3: Поиск по показанному контенту
|
||||||
}, 2000);
|
if (!activeTab.length) {
|
||||||
|
const visibleContent = $(".form-tab-content > .tab-pane:visible");
|
||||||
|
|
||||||
|
if (visibleContent.length) {
|
||||||
|
const visibleContentId = visibleContent.first().attr('id');
|
||||||
|
activeTab = $(`.nav-item a[aria-controls="${visibleContentId}"]`).closest('.nav-item');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (activeTab.length) {
|
||||||
|
const activeTabId = activeTab.find("a").attr("aria-controls");
|
||||||
|
|
||||||
|
// Проверяем есть ли субтабы у активной вкладки
|
||||||
|
$(".sub-tab-container").each(function () {
|
||||||
|
const containerParentId = $(this).attr("data-parent-id");
|
||||||
|
|
||||||
|
if (containerParentId === activeTabId) {
|
||||||
|
$(this).css("display", "flex");
|
||||||
|
$(this).find(".sub-tab").removeClass("active");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}, 500);
|
}, 500);
|
||||||
};
|
};
|
||||||
Loading…
Reference in New Issue