refactor: Consolidate tab initialization logic using shared utility function

This commit is contained in:
Jokob @NetAlertX
2026-02-27 10:07:55 +00:00
parent 9d64665599
commit 4c0d5c7376
5 changed files with 116 additions and 87 deletions

View File

@@ -384,25 +384,9 @@ $(document).on('input', 'input:text', function() {
// -----------------------------------------------------------------------------
function initializeTabs () {
key ="activeDevicesTab"
// Activate panel
if(!emptyArr.includes(getCache(key)))
{
selectedTab = getCache(key);
}
$('.nav-tabs a[id='+ selectedTab +']').tab('show');
// When changed save new current tab
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
setCache(key, $(e.target).attr('id'))
});
// events on tab change
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
var target = $(e.target).attr("href") // activated tab
initializeTabsShared({
cacheKey: 'activeDevicesTab',
defaultTab: 'tabDetails'
});
}

View File

@@ -8,6 +8,100 @@
----------------------------------------------------------------------------- */
// -------------------------------------------------------------------
// Shared tab initialization utility.
// Resolves the active tab from URL hash, query param, or cache, then activates it.
//
// Options:
// cacheKey (string) - localStorage key for persisting the active tab (required)
// defaultTab (string) - fallback tab ID if nothing is found in URL or cache. Optional, defaults to ''.
// urlParamName (string) - query-string parameter name to read (e.g. 'tab'). Optional.
// useHash (boolean) - if true, reads window.location.hash as a tab target. Optional.
// idSuffix (string) - suffix appended to URL-derived targets to form the tab <a> id (e.g. '_id'). Optional.
// onTabChange (function) - callback(targetHref) invoked when a tab is shown. Optional.
// delay (number) - ms to delay initialization (wraps in setTimeout). Optional. 0 = immediate.
// tabContainer (string) - CSS selector to scope tab lookups and event binding. Optional. null = whole document.
//
// Returns nothing. Activates the resolved tab and binds cache persistence.
// -------------------------------------------------------------------
function initializeTabsShared(options) {
const {
cacheKey,
defaultTab = '',
urlParamName = null,
useHash = false,
idSuffix = '',
onTabChange = null,
delay = 0,
tabContainer = null // CSS selector to scope tab lookups (e.g. '#tabs-location')
} = options;
function run() {
let selectedTab = defaultTab;
// 1. URL hash (e.g. maintenance.php#tab_Logging)
if (useHash) {
let hashTarget = window.location.hash.substring(1);
if (hashTarget.includes('?')) {
hashTarget = hashTarget.split('?')[0];
}
if (hashTarget) {
selectedTab = hashTarget.endsWith(idSuffix) ? hashTarget : hashTarget + idSuffix;
setCache(cacheKey, selectedTab);
}
}
// 2. URL query parameter (e.g. ?tab=WEBMON)
if (urlParamName) {
const urlParams = new URLSearchParams(window.location.search);
const paramVal = urlParams.get(urlParamName);
if (paramVal) {
selectedTab = paramVal.endsWith(idSuffix) ? paramVal : paramVal + idSuffix;
setCache(cacheKey, selectedTab);
}
}
// 3. Cached value (may already have been overridden above)
const cached = getCache(cacheKey);
if (cached && !emptyArr.includes(cached)) {
selectedTab = cached;
}
// Resolve scoped vs global selectors
const $scope = tabContainer ? $(tabContainer) : $(document);
// Activate the resolved tab (no-op if selectedTab is empty or not found)
if (selectedTab) {
$scope.find('a[id="' + selectedTab + '"]').tab('show');
}
// Fire callback for initial tab
if (onTabChange && selectedTab) {
const initialHref = $scope.find('a[id="' + selectedTab + '"]').attr('href');
if (initialHref) {
onTabChange(initialHref);
}
}
// Persist future tab changes to cache and invoke callback
$scope.find('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
const newTabId = $(e.target).attr('id');
setCache(cacheKey, newTabId);
if (onTabChange) {
const newHref = $(e.target).attr('href');
onTabChange(newHref);
}
});
}
if (delay > 0) {
setTimeout(run, delay);
} else {
run();
}
}
// -------------------------------------------------------------------
// Utility function to generate a random API token in the format t_<random string of specified length>

View File

@@ -778,50 +778,14 @@ function scrollDown() {
// General initialization
// --------------------------------------------------------
function initializeTabs() {
setTimeout(() => {
const key = "activeMaintenanceTab";
// default selection
let selectedTab = "tab_DBTools_id";
// the #target from the URL
let target = window.location.hash.substr(1);
console.log(selectedTab);
// get only the part between #...?
if (target.includes('?')) {
target = target.split('?')[0];
}
// update cookie if target specified
if (target) {
selectedTab = target.endsWith("_id") ? target : `${target}_id`;
setCache(key, selectedTab); // _id is added so it doesn't conflict with AdminLTE tab behavior
}
// get the tab id from the cookie (already overridden by the target)
const cachedTab = getCache(key);
if (cachedTab && !emptyArr.includes(cachedTab)) {
selectedTab = cachedTab;
}
// Activate panel
$('.nav-tabs a[id='+ selectedTab +']').tab('show');
// When changed save new current tab
$('a[data-toggle="tab"]').on('shown.bs.tab', (e) => {
const newTabId = $(e.target).attr('id');
setCache(key, newTabId);
});
// events on tab change
$('a[data-toggle="tab"]').on('shown.bs.tab', (e) => {
const newTarget = $(e.target).attr("href"); // activated tab
});
hideSpinner();
}, 50);
initializeTabsShared({
cacheKey: 'activeMaintenanceTab',
defaultTab: 'tab_DBTools_id',
useHash: true,
idSuffix: '_id',
delay: 50
});
setTimeout(() => hideSpinner(), 50);
}
//------------------------------------------------------------------------------

View File

@@ -330,7 +330,13 @@ function generateTabs() {
}
});
// Auto-select tab from ?tab= URL param or cache (scoped to plugin nav only)
initializeTabsShared({
cacheKey: 'activePluginsTab',
urlParamName: 'tab',
idSuffix: '_id',
tabContainer: '#tabs-location'
});
hideSpinner()
}

View File

@@ -118,29 +118,10 @@ function loadTabContent(target) {
}
function initializeTabs() {
const key = "activeSysinfoTab";
let selectedTab = "tabServer"; // fallback default
const cached = getCache(key);
if (!emptyArr.includes(cached)) {
selectedTab = cached;
}
// Activate the correct tab
const $tabLink = $('.nav-tabs a[id="' + selectedTab + '"]');
$tabLink.tab('show');
// Get the pane's ID from the tab's href attribute
const targetSelector = $tabLink.attr("href");
loadTabContent(targetSelector);
// On tab change
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
const newTabId = $(e.target).attr('id');
setCache(key, newTabId);
const newTarget = $(e.target).attr("href");
loadTabContent(newTarget);
initializeTabsShared({
cacheKey: 'activeSysinfoTab',
defaultTab: 'tabServer',
onTabChange: loadTabContent
});
}