Fix Mail settings tabs regression and user menu coloring

This commit is contained in:
johnnyq
2026-08-15 12:29:39 -04:00
parent 8c0e5246b4
commit c44fa30792
4 changed files with 28 additions and 22 deletions

View File

@@ -3,7 +3,7 @@
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed"); defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
// Saves and tests return to the tab they were submitted from (see settings_mail.php) // Saves and tests return to the tab they were submitted from (see settings_mail.php)
$mail_tabs = ['smtp', 'imap', 'oauth', 'from', 'tests']; $mail_tabs = ['sending', 'receiving', 'oauth', 'from', 'tests'];
$mail_tab_redirect = 'settings_mail.php'; $mail_tab_redirect = 'settings_mail.php';
if (isset($_POST['tab']) && in_array($_POST['tab'], $mail_tabs, true)) { if (isset($_POST['tab']) && in_array($_POST['tab'], $mail_tabs, true)) {
$mail_tab_redirect .= '?tab=' . $_POST['tab']; $mail_tab_redirect .= '?tab=' . $_POST['tab'];

View File

@@ -14,10 +14,10 @@ $oauth_needed = in_array($config_smtp_provider, ['google_oauth', 'microsoft_oaut
|| in_array($config_imap_provider, ['google_oauth', 'microsoft_oauth'], true); || in_array($config_imap_provider, ['google_oauth', 'microsoft_oauth'], true);
// ---- Active tab ------------------------------------------------------------- // ---- Active tab -------------------------------------------------------------
// The tab lives in the URL (?tab=imap) so it can be linked, bookmarked, survives a // The tab lives in the URL (?tab=receiving) so it can be linked, bookmarked, survives a
// reload, and lets the POST handlers send you back to the tab you saved from // reload, and lets the POST handlers send you back to the tab you saved from
$mail_tabs = ['smtp', 'imap', 'oauth', 'from', 'tests']; $mail_tabs = ['sending', 'receiving', 'oauth', 'from', 'tests'];
$active_tab = isset($_GET['tab']) && in_array($_GET['tab'], $mail_tabs, true) ? $_GET['tab'] : 'smtp'; $active_tab = isset($_GET['tab']) && in_array($_GET['tab'], $mail_tabs, true) ? $_GET['tab'] : 'sending';
// A direct link to the OAuth tab reveals it even when no OAuth provider is selected yet // A direct link to the OAuth tab reveals it even when no OAuth provider is selected yet
if ($active_tab === 'oauth') { if ($active_tab === 'oauth') {
@@ -74,12 +74,12 @@ $imap_ready = $imap_standard_ready || $imap_oauth_ready;
<ul class="nav nav-tabs" id="mailTabs" role="tablist"> <ul class="nav nav-tabs" id="mailTabs" role="tablist">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link <?php if ($active_tab === 'smtp') { echo 'active'; } ?>" href="?tab=smtp" data-bs-target="#tab-smtp"> <a class="nav-link <?php if ($active_tab === 'sending') { echo 'active'; } ?>" href="?tab=sending" data-bs-target="#tab-sending">
<i class="fas fa-fw fa-paper-plane me-1"></i>Sending<?= renderMailStatusDot($smtp_on) ?> <i class="fas fa-fw fa-paper-plane me-1"></i>Sending<?= renderMailStatusDot($smtp_on) ?>
</a> </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link <?php if ($active_tab === 'imap') { echo 'active'; } ?>" href="?tab=imap" data-bs-target="#tab-imap"> <a class="nav-link <?php if ($active_tab === 'receiving') { echo 'active'; } ?>" href="?tab=receiving" data-bs-target="#tab-receiving">
<i class="fas fa-fw fa-inbox me-1"></i>Receiving<?= renderMailStatusDot($imap_on) ?> <i class="fas fa-fw fa-inbox me-1"></i>Receiving<?= renderMailStatusDot($imap_on) ?>
</a> </a>
</li> </li>
@@ -103,10 +103,10 @@ $imap_ready = $imap_standard_ready || $imap_oauth_ready;
<div class="tab-content pt-4"> <div class="tab-content pt-4">
<!-- ============================ SENDING / SMTP ============================ --> <!-- ============================ SENDING / SMTP ============================ -->
<div class="tab-pane fade <?php if ($active_tab === 'smtp') { echo 'show active'; } ?>" id="tab-smtp" role="tabpanel"> <div class="tab-pane fade <?php if ($active_tab === 'sending') { echo 'show active'; } ?>" id="tab-sending" role="tabpanel">
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="tab" value="smtp"> <input type="hidden" name="tab" value="sending">
<div class="mb-3"> <div class="mb-3">
<label>SMTP Provider <small class="text-muted">— outbound</small></label> <label>SMTP Provider <small class="text-muted">— outbound</small></label>
@@ -177,10 +177,10 @@ $imap_ready = $imap_standard_ready || $imap_oauth_ready;
</div> </div>
<!-- ============================ RECEIVING / IMAP ============================ --> <!-- ============================ RECEIVING / IMAP ============================ -->
<div class="tab-pane fade <?php if ($active_tab === 'imap') { echo 'show active'; } ?>" id="tab-imap" role="tabpanel"> <div class="tab-pane fade <?php if ($active_tab === 'receiving') { echo 'show active'; } ?>" id="tab-receiving" role="tabpanel">
<form action="post.php" method="post" autocomplete="off"> <form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>"> <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="tab" value="imap"> <input type="hidden" name="tab" value="receiving">
<div class="mb-3"> <div class="mb-3">
<label>IMAP Provider <small class="text-muted">— inbound ticket inbox</small></label> <label>IMAP Provider <small class="text-muted">— inbound ticket inbox</small></label>
@@ -432,29 +432,36 @@ $imap_ready = $imap_standard_ready || $imap_oauth_ready;
// Set when the page was opened directly on the OAuth tab - stops the provider pass hiding it // Set when the page was opened directly on the OAuth tab - stops the provider pass hiding it
const forcedOauthTab = <?= $active_tab === 'oauth' ? 'true' : 'false' ?>; const forcedOauthTab = <?= $active_tab === 'oauth' ? 'true' : 'false' ?>;
const navLinks = Array.from(document.querySelectorAll('#mailTabs .nav-link')); const navLinks = Array.from(document.querySelectorAll('#mailTabs .nav-link'));
const panes = ['tab-smtp', 'tab-imap', 'tab-oauth', 'tab-from', 'tab-tests'] const panes = ['tab-sending', 'tab-receiving', 'tab-oauth', 'tab-from', 'tab-tests']
.map(id => document.getElementById(id)).filter(Boolean); .map(id => document.getElementById(id)).filter(Boolean);
// Server rendered the initial tab; keep the URL honest as the user clicks around // Server rendered the initial tab; keep the URL honest as the user clicks around
function syncTabUrl(target) { function syncTabUrl(target, push) {
const tab = target.replace('#tab-', ''); const tab = target.replace('#tab-', '');
const url = new URL(window.location.href); const url = new URL(window.location.href);
url.searchParams.set('tab', tab); url.searchParams.set('tab', tab);
history.replaceState(null, '', url); // pushState, not replaceState, so back/forward step through the tabs
// instead of jumping straight off the settings page
history[push ? 'pushState' : 'replaceState']({ tab: tab }, '', url);
} }
function activateTab(target) { function activateTab(target, push) {
syncTabUrl(target); syncTabUrl(target, push !== false);
navLinks.forEach(l => l.classList.toggle('active', l.getAttribute('data-target') === target)); navLinks.forEach(l => l.classList.toggle('active', l.getAttribute('data-bs-target') === target));
panes.forEach(p => { panes.forEach(p => {
const on = ('#' + p.id) === target; const on = ('#' + p.id) === target;
p.classList.toggle('active', on); p.classList.toggle('active', on);
p.classList.toggle('show', on); p.classList.toggle('show', on);
}); });
} }
window.addEventListener('popstate', function () {
const tab = new URL(window.location.href).searchParams.get('tab') || 'sending';
activateTab('#tab-' + tab, false);
});
navLinks.forEach(l => l.addEventListener('click', function (e) { navLinks.forEach(l => l.addEventListener('click', function (e) {
e.preventDefault(); e.preventDefault();
activateTab(l.getAttribute('data-target')); activateTab(l.getAttribute('data-bs-target'), true);
})); }));
// ---- Provider-driven field visibility ---- // ---- Provider-driven field visibility ----
@@ -528,7 +535,7 @@ $imap_ready = $imap_standard_ready || $imap_oauth_ready;
if (!anyOauth && !forcedOauthTab) { if (!anyOauth && !forcedOauthTab) {
const oauthLink = document.querySelector('#mailTabs .nav-link[data-bs-target="#tab-oauth"]'); const oauthLink = document.querySelector('#mailTabs .nav-link[data-bs-target="#tab-oauth"]');
if (oauthLink && oauthLink.classList.contains('active')) activateTab('#tab-smtp'); if (oauthLink && oauthLink.classList.contains('active')) activateTab('#tab-sending');
} }
} }

View File

@@ -21,7 +21,7 @@ if ($total_found_rows > 5) {
<div class="col-sm"> <div class="col-sm">
<form action="post.php" method="post"> <form action="post.php" method="post">
<div class="mb-3"> <div class="mb-3">
<select onchange="this.form.submit()" class="form-select select2 col-12 col-sm-3" name="change_records_per_page"> <select onchange="this.form.submit()" class="form-select col-12 col-sm-3" name="change_records_per_page">
<option <?php if ($user_config_records_per_page == 5) { echo "selected"; } ?> >5</option> <option <?php if ($user_config_records_per_page == 5) { echo "selected"; } ?> >5</option>
<option <?php if ($user_config_records_per_page == 10) { echo "selected"; } ?> >10</option> <option <?php if ($user_config_records_per_page == 10) { echo "selected"; } ?> >10</option>
<option <?php if ($user_config_records_per_page == 20) { echo "selected"; } ?> >20</option> <option <?php if ($user_config_records_per_page == 20) { echo "selected"; } ?> >20</option>

View File

@@ -80,8 +80,7 @@
<img src="<?= "/uploads/users/$session_user_id/$session_avatar" ?>" <img src="<?= "/uploads/users/$session_user_id/$session_avatar" ?>"
class="user-image rounded-circle"> class="user-image rounded-circle">
<?php } ?> <?php } ?>
<span <span class="d-none d-md-inline dropdown-toggle"><?= stripslashes(escapeHtml($session_name)) ?></span>
class="d-none d-md-inline dropdown-toggle"><?= stripslashes(escapeHtml($session_name)) ?></span>
</a> </a>
<ul class="dropdown-menu dropdown-menu-lg dropdown-menu-end"> <ul class="dropdown-menu dropdown-menu-lg dropdown-menu-end">
<!-- User image --> <!-- User image -->
@@ -98,7 +97,7 @@
</p> </p>
</li> </li>
<!-- Menu Footer--> <!-- Menu Footer-->
<li class="user-footer"> <li class="user-footer bg-light">
<?php if ($session_is_admin) { ?> <?php if ($session_is_admin) { ?>
<a href="/admin" class="btn btn-default w-100 btn-flat mb-2"><i class="fas fa-user-shield me-2"></i>Administration</a> <a href="/admin" class="btn btn-default w-100 btn-flat mb-2"><i class="fas fa-user-shield me-2"></i>Administration</a>
<?php } ?> <?php } ?>