fix: make layout templates generic — remove app-specific nav and config
Lint / JS (eslint) (push) Successful in 10s

php/layout.php: nav is now data-driven via $navLinks array (supports
  top-level links, dropdowns, adminOnly flag); removed tinker_tickets
  hardcoded nav items; moved APP_CONFIG note to comment
python/base.html: nav driven by nav_links list from context; removed
  gandalf-specific routes (links_page, inspector, suppressions_page);
  removed APP_CONFIG.ticketWebUrl from shared script block; added
  nav_links format documentation in header comment

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-18 13:53:29 -04:00
parent f61705afb8
commit 75c57092f8
2 changed files with 73 additions and 44 deletions
+36 -21
View File
@@ -17,8 +17,14 @@
* $nonce string CSP nonce from SecurityHeadersMiddleware::getNonce()
* $currentUser array ['username', 'name', 'is_admin', 'groups']
* $pageTitle string Page <title> suffix
* $activeNav string Which nav link is active ('dashboard','tickets',etc.)
* $activeNav string Which nav key is active — must match a $navLinks entry
* $config array From config/config.php
* $navLinks array Navigation items:
* [['href' => '/path', 'key' => 'mykey', 'label' => 'My Page'], ...]
* Nested (dropdown):
* ['label' => 'Admin', 'key' => 'admin', 'adminOnly' => true, 'children' => [
* ['href' => '/admin/users', 'label' => 'Users'],
* ]]
*/
// Defensive defaults
@@ -27,6 +33,7 @@ $currentUser = $currentUser ?? [];
$pageTitle = $pageTitle ?? 'Dashboard';
$activeNav = $activeNav ?? '';
$config = $config ?? [];
$navLinks = $navLinks ?? [];
$isAdmin = $currentUser['is_admin'] ?? false;
?>
<!DOCTYPE html>
@@ -40,7 +47,7 @@ $isAdmin = $currentUser['is_admin'] ?? false;
<!-- Unified design system CSS -->
<link rel="stylesheet" href="/web_template/base.css">
<!-- App-specific CSS (extends base, never overrides variables without good reason) -->
<link rel="stylesheet" href="/assets/css/app.css?v=<?php echo $config['CSS_VERSION'] ?? '20260314'; ?>">
<link rel="stylesheet" href="/assets/css/app.css?v=<?php echo $config['CSS_VERSION'] ?? '1'; ?>">
<link rel="icon" href="/assets/images/favicon.png" type="image/png">
</head>
@@ -67,25 +74,31 @@ $isAdmin = $currentUser['is_admin'] ?? false;
</div>
<nav class="lt-nav" aria-label="Main navigation">
<a href="/" class="lt-nav-link <?php echo $activeNav === 'dashboard' ? 'active' : ''; ?>">Dashboard</a>
<a href="/tickets" class="lt-nav-link <?php echo $activeNav === 'tickets' ? 'active' : ''; ?>">Tickets</a>
<?php foreach ($navLinks as $link): ?>
<?php
$skipAdminOnly = !empty($link['adminOnly']) && !$isAdmin;
if ($skipAdminOnly) continue;
?>
<?php if ($isAdmin): ?>
<div class="lt-nav-dropdown">
<a href="#" class="lt-nav-link <?php echo str_starts_with($activeNav, 'admin') ? 'active' : ''; ?>">
Admin ▾
</a>
<ul class="lt-nav-dropdown-menu">
<li><a href="/admin/templates">Templates</a></li>
<li><a href="/admin/workflow">Workflow</a></li>
<li><a href="/admin/recurring-tickets">Recurring</a></li>
<li><a href="/admin/custom-fields">Custom Fields</a></li>
<li><a href="/admin/user-activity">User Activity</a></li>
<li><a href="/admin/audit-log">Audit Log</a></li>
<li><a href="/admin/api-keys">API Keys</a></li>
</ul>
</div>
<?php endif; ?>
<?php if (!empty($link['children'])): ?>
<?php $parentActive = str_starts_with($activeNav, $link['key']); ?>
<div class="lt-nav-dropdown">
<a href="#" class="lt-nav-link <?php echo $parentActive ? 'active' : ''; ?>">
<?php echo htmlspecialchars($link['label']); ?> ▾
</a>
<ul class="lt-nav-dropdown-menu">
<?php foreach ($link['children'] as $child): ?>
<li><a href="<?php echo htmlspecialchars($child['href']); ?>"><?php echo htmlspecialchars($child['label']); ?></a></li>
<?php endforeach; ?>
</ul>
</div>
<?php else: ?>
<a href="<?php echo htmlspecialchars($link['href']); ?>"
class="lt-nav-link <?php echo $activeNav === $link['key'] ? 'active' : ''; ?>">
<?php echo htmlspecialchars($link['label']); ?>
</a>
<?php endif; ?>
<?php endforeach; ?>
</nav>
</div>
@@ -130,6 +143,8 @@ $isAdmin = $currentUser['is_admin'] ?? false;
username: <?php echo json_encode($currentUser['username'] ?? ''); ?>,
isAdmin: <?php echo $isAdmin ? 'true' : 'false'; ?>,
};
// App-specific config: set window.APP_CONFIG in your app's own <script> block,
// not here. This file is shared across all apps.
</script>
<!-- Unified design system JS -->
@@ -137,7 +152,7 @@ $isAdmin = $currentUser['is_admin'] ?? false;
<!-- App-specific JS (cache-busted) -->
<script nonce="<?php echo $nonce; ?>"
src="/assets/js/app.js?v=<?php echo $config['JS_VERSION'] ?? '20260314'; ?>">
src="/assets/js/app.js?v=<?php echo $config['JS_VERSION'] ?? '1'; ?>">
</script>
<!-- Per-page inline JS goes here in the including view, e.g.: -->