Files
08d16f894a fix(ui): only add the theme search filter icon when the filter input is visible (#8583)
The theme main.js files appended a search icon after any #filter/#filterd/#rfilter
input whenever it existed in the DOM, even while it was hidden, leaving a stray
icon on the page. Gate the decoration on the input being :visible, and defer it
with setTimeout(0) so it runs after applySkin()/cactiReady() reveal #main and
#navigation_right. The :visible check then skips only intentionally hidden filters,
while ordinary filters -- including after AJAX refreshes -- still receive their
icon, placeholder and autocomplete settings.

Also make cacti_trusted_proxy_match() IP-family aware so an IPv4-mapped IPv6
address (::ffff:a.b.c.d) never matches a bare IPv4 proxy entry. Newer Symfony
IpUtils releases normalize the mapped form inside checkIp(), which broke the
native dependency test matrix; gating on IP family keeps the match deterministic.
A coverage case keeps lib/client_address.php at 100%.

Co-authored-by: TheWitness <copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-11-04 14:40:24 -05:00

215 lines
9.5 KiB
JavaScript

/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
| |
| This program is free software; you can redistribute it and/or |
| modify it under the terms of the GNU General Public License |
| as published by the Free Software Foundation; either version 2 |
| of the License, or (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDTool-based Graphing Solution |
+-------------------------------------------------------------------------+
| This code is designed, written, and maintained by the Cacti Group. See |
| about.php and/or the AUTHORS file for specific developer information. |
+-------------------------------------------------------------------------+
| http://www.cacti.net/ |
+-------------------------------------------------------------------------+
*/
function themeReady() {
// Setup the navigation menu
setMenuVisibility();
// Add the search filter icon once the filter inputs are visible
setTimeout(function() {
if ($('input[id="filter"]').length > 0 && $('input[id="filter"]').is(':visible') && $('input[id="filter"]').next('i[class="ti ti-search filter"]').length < 1) {
$('input[id="filter"]').after("<i class='ti ti-search filter'/>").attr('autocomplete', 'off').attr('placeholder', searchFilter).parent('td').css('white-space', 'nowrap');
}
if ($('input[id="filterd"]').length > 0 && $('input[id="filterd"]').is(':visible') && $('input[id="filterd"]').next('i[class="ti ti-search filter"]').length < 1) {
$('input[id="filterd"]').after("<i class='ti ti-search filter'/>").attr('autocomplete', 'off').attr('placeholder', searchFilter).parent('td').css('white-space', 'nowrap');
}
if ($('input[id="rfilter"]').length > 0 && $('input[id="rfilter"]').is(':visible') && $('input[id="rfilter"]').next('i[class="ti ti-search filter"]').length < 1 && $('input[id="rfilter"]').closest('.cactiFilterEditTable').length < 1) {
$('input[id="rfilter"]').after("<i class='ti ti-search filter'/>").attr('autocomplete', 'off').attr('placeholder', searchRFilter).parent('td').css('white-space', 'nowrap');
}
}, 0);
$('input#filter, input#rfilter').addClass('ui-state-default ui-corner-all');
$('input[type="text"], input[type="password"], input[type="checkbox"], textarea').not('image').addClass('ui-state-default ui-corner-all');
/* Start clean up */
//login page
$('.cactiLoginLogo').html("<i class='ti ti-pawti ti-send'/>");
$('.cactiLogoutLogo').html("<i class='ti ti-pawti ti-send'/>");
/* clean up the navigation menu */
$('.cactiConsoleNavigationArea').find('#menu').appendTo($('.cactiConsoleNavigationArea').find('#navigation'));
$('.cactiConsoleNavigationArea').find('#navigation > table').remove();
if ($('#cactiPageBottom').length == 0) {
$('<div id="cactiPageBottom" class="cactiPageBottom"><a class="bottom_scroll_up action-icon-user" href="#"><i class="ti ti-circle-arrow-up"></i></a></div>').insertAfter('#cactiContent');
}
$('.maintabs nav ul li a.lefttab').each( function() {
id = $(this).attr('id');
if (id == 'tab-graphs' && $(this).parent().hasClass('maintabs-has-submenu') == 0) {
$(this).parent().addClass('maintabs-has-submenu');
$('<div class="dropdownMenu">'
+'<ul id="submenu-tab-graphs" class="submenuoptions" style="display:none;">'
+'<li><a id="tab-graphs-tree-view" href="'+urlPath+'graph_view.php?action=tree"><span>'+treeView+'</span></a></li>'
+'<li><a id="tab-graphs-list-view" href="'+urlPath+'graph_view.php?action=list"><span>'+listView+'</span></a></li>'
+'<li><a id="tab-graphs-pre_view" href="'+urlPath+'graph_view.php?action=preview"><span>'+previewView+'</span></a></li>'
+'</ul>'
+'</div>').appendTo('body');
} else {
/* plugin stuff here ? */
}
});
/* user menu on the right ... */
if ($('.usertabs').length == 0) {
$('.loggedInAs').show();
$('#userDocumentation').remove();
$('#userCommunity').remove();
$('.menuHr').remove();
$('<div class="maintabs usertabs">'
+'<nav><ul>'
+'<li><a id="menu-user-help" class="usertabs-submenu" href="#"><i class="ti ti-question-mark"></i></a></li>'
+'<li class="action-icon-user"><a class="pic" href="#"><i class="ti ti-user"></i></a></li>'
+'</ul></nav>'
+'</div>').insertAfter('.maintabs');
$('<div class="dropdownMenu">'
+'<ul id="submenu-user-help" class="submenuoptions right" style="display:none;">'
+'<li><a href="https://www.cacti.net" target="_blank" rel="noopener"><span>'+cactiHome+'</span></a></li>'
+'<li><a href="https://github.com/cacti" target="_blank" rel="noopener"><span>'+cactiProjectPage+'</span></a></li>'
+'<li><hr class="menu"></li>'
+'<li><a href="https://forums.cacti.net/" target="_blank" rel="noopener"><span>'+cactiCommunityForum+'</span></a></li>'
+'<li><a href="https://github.com/Cacti/documentation/blob/develop/README.md" target="_blank" rel="noopener"><span>'+cactiDocumentation+'</span></a></li>'
+'<li><hr class="menu"></li>'
+'<li><a href="https://github.com/Cacti/cacti/issues/new" target="_blank" rel="noopener"><span>'+reportABug+'</span></a></li>'
+'<li><a href="'+urlPath+'about.php"><span>'+aboutCacti+'</span></a></li>'
+'</ul>'
+'</div>').appendTo('body');
}
ajaxAnchors();
/* User Menu */
$('.menuoptions').parent().appendTo('body');
$('.action-icon-user').rebind('click', function(event) {
event.preventDefault();
if ($('.menuoptions').is(':visible') === false) {
$('.submenuoptions').stop().slideUp(120);
$('.menuoptions').stop().slideDown(120);
} else {
$('.menuoptions').stop().slideUp(120);
}
return false;
});
$('.bottom_scroll_up').rebind('click', function(event) {
event.preventDefault();
$('#navigation_right').animate({ scrollLeft:0, scrollTop: 0 }, 1000, 'easeInOutQuart');
});
/* Highlight sortable table columns */
$('.tableHeader th').has('i.fa-sort').removeClass('tableHeaderColumnHover tableHeaderColumnSelected');
$('.tableHeader th').has('i.fa-sort-up').addClass('tableHeaderColumnSelected');
$('.tableHeader th').has('i.fa-sort-down').addClass('tableHeaderColumnSelected');
$('.tableHeader th').has('i.fa-sort').on('mouseenter', function() {
$(this).addClass("tableHeaderColumnHover");
}).on('mouseleave', function() {
$(this).removeClass( "tableHeaderColumnHover");
});
$('input#filter, input#rfilter').addClass('ui-state-default ui-corner-all');
$('input[type="text"], input[type="password"], input[type="checkbox"], textarea').not('image').addClass('ui-state-default ui-corner-all');
// Turn file buttons into jQueryUI buttons
$('.import_label').button();
$('.import_button').on('change', function() {
text=this.value;
setImportFile(text);
});
setImportFile(noFileSelected);
function setImportFile(fileText) {
$('.import_text').text(fileText);
}
setNavigationScroll();
}
function setMenuVisibility() {
const storage = Storages.sessionStorage;
// Initialize the navigation settings
// This will setup the initial visibility of the menu
$('li.menuitem').each(function() {
const id = $(this).attr('id');
const active = storage.isSet(id) ? storage.get(id) : null;
if (active != null && active == 'active') {
$(this).find('ul').attr('aria-hidden', 'false').attr('aria-expanded', 'true').show();
$(this).next('a').show();
} else {
$(this).find('ul').attr('aria-hidden', 'true').attr('aria-expanded', 'false').hide();
$(this).next('a').hide();
}
if ($(this).find('a.selected').length == 0) {
//console.log('hiding1:'+$(this).closest('.menuitem').attr('id'));
$(this).find('ul').attr('aria-hidden', 'true').attr('aria-expanded', 'false').hide();
$(this).next('a').hide();
storage.set($(this).closest('.menuitem').attr('id'), 'collapsed');
} else {
$(this).find('ul').attr('aria-hidden', 'false').attr('aria-expanded', 'true').show();
$(this).next('a').show();
storage.set($(this).closest('.menuitem').attr('id'), 'active');
}
});
// Function to give life to the Navigation pane
$('#nav li:has(ul) a.active').rebind('click', function(event) {
event.preventDefault();
const id = $(this).closest('.menuitem').attr('id');
if ($(this).next().is(':visible')) {
$(this).next('ul').attr('aria-hidden', 'true').attr('aria-expanded', 'false');
$(this).next().slideUp( { duration: 200, easing: 'swing' } );
storage.set(id, 'collapsed');
} else {
$(this).next('ul').attr('aria-hidden', 'false').attr('aria-expanded', 'true');
$(this).next().slideToggle( { duration: 200, easing: 'swing' } );
if ($(this).next().is(':visible')) {
storage.set($(this).closest('.menuitem').attr('id'), 'active');
} else {
storage.set(id, 'collapsed');
}
}
$('li.menuitem').not('#'+id).each(function() {
$(this).find('ul').attr('aria-hidden', 'true').attr('aria-expanded', 'false');
$(this).find('ul').slideUp( { duration: 200, easing: 'swing' } );
storage.set($(this).attr('id'), 'collapsed');
});
});
}