Add UI improvements: date formatting, breadcrumbs, clickable rows, and structured menu
- Format dates as YYYY-MM-DD with full timestamp on hover - Add breadcrumb navigation with hospital icon (🏥) across all pages - Restructure main menu with grouped dropdowns: * Hardware (Assets, Components) * Health (Tickets, Failures, Analytics) * Settings (Ingest) - Make table rows clickable on Dashboard, Assets, and Components pages - Add new Customers page with list view - Improve dropdown menu stability with JS hover delay Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -64,15 +64,77 @@
|
||||
letter-spacing: 0.08em;
|
||||
font-weight: 600;
|
||||
}
|
||||
.nav a {
|
||||
.nav-item {
|
||||
position: relative;
|
||||
}
|
||||
.nav a, .nav-group-label {
|
||||
text-decoration: none;
|
||||
color: var(--ink);
|
||||
opacity: 0.7;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
}
|
||||
.nav a.active {
|
||||
.nav a.active, .nav-group-label.active {
|
||||
opacity: 1;
|
||||
color: var(--accent);
|
||||
}
|
||||
.nav-group {
|
||||
position: relative;
|
||||
}
|
||||
.nav-group-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
.nav-group-label::after {
|
||||
content: '▾';
|
||||
font-size: 10px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
.nav-submenu {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
background: white;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
box-shadow: var(--shadow);
|
||||
margin-top: 4px;
|
||||
min-width: 160px;
|
||||
z-index: 100;
|
||||
padding: 8px 0;
|
||||
}
|
||||
.nav-submenu::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -4px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 4px;
|
||||
background: transparent;
|
||||
}
|
||||
.nav-group:hover .nav-submenu,
|
||||
.nav-submenu:hover {
|
||||
display: block;
|
||||
}
|
||||
.nav-submenu a {
|
||||
padding: 8px 16px;
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
opacity: 0.7;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.nav-submenu a:hover {
|
||||
opacity: 1;
|
||||
background: var(--accent-soft);
|
||||
}
|
||||
.nav-submenu a.active {
|
||||
opacity: 1;
|
||||
color: var(--accent);
|
||||
background: var(--accent-soft);
|
||||
}
|
||||
.container {
|
||||
max-width: 1100px;
|
||||
margin: 28px auto;
|
||||
@@ -137,6 +199,13 @@
|
||||
.table tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
.table tr.clickable {
|
||||
cursor: pointer;
|
||||
transition: background-color 0.15s;
|
||||
}
|
||||
.table tr.clickable:hover {
|
||||
background: var(--accent-soft);
|
||||
}
|
||||
.meta {
|
||||
color: var(--muted);
|
||||
font-size: 12px;
|
||||
@@ -261,6 +330,36 @@
|
||||
font-weight: 600;
|
||||
color: #0f172a;
|
||||
}
|
||||
.breadcrumbs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 12px 32px;
|
||||
background: white;
|
||||
border-bottom: 1px solid var(--border);
|
||||
font-size: 13px;
|
||||
}
|
||||
.breadcrumbs a {
|
||||
text-decoration: none;
|
||||
color: var(--muted);
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.breadcrumbs a:hover {
|
||||
color: var(--accent);
|
||||
}
|
||||
.breadcrumbs .home-icon {
|
||||
font-size: 16px;
|
||||
line-height: 1;
|
||||
}
|
||||
.breadcrumbs .separator {
|
||||
color: var(--muted);
|
||||
opacity: 0.5;
|
||||
font-size: 11px;
|
||||
}
|
||||
.breadcrumbs .current {
|
||||
color: var(--ink);
|
||||
font-weight: 600;
|
||||
}
|
||||
@media (max-width: 720px) {
|
||||
.topbar {
|
||||
flex-direction: column;
|
||||
@@ -275,6 +374,31 @@
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function navigateToRow(url) {
|
||||
window.location.href = url;
|
||||
}
|
||||
|
||||
// Улучшенная работа выпадающих меню
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const navGroups = document.querySelectorAll('.nav-group');
|
||||
navGroups.forEach(group => {
|
||||
let hideTimer;
|
||||
|
||||
group.addEventListener('mouseenter', function() {
|
||||
clearTimeout(hideTimer);
|
||||
this.querySelector('.nav-submenu').style.display = 'block';
|
||||
});
|
||||
|
||||
group.addEventListener('mouseleave', function() {
|
||||
const submenu = this.querySelector('.nav-submenu');
|
||||
hideTimer = setTimeout(() => {
|
||||
submenu.style.display = 'none';
|
||||
}, 150);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
{{end}}
|
||||
|
||||
@@ -288,12 +412,48 @@
|
||||
{{if .HeroTag}}<div class="pill">{{.HeroTag}}</div>{{end}}
|
||||
</header>
|
||||
<nav class="nav">
|
||||
<a href="/ui" class="{{if eq .ActiveNav "dashboard"}}active{{end}}">Dashboard</a>
|
||||
<a href="/ui/assets" class="{{if eq .ActiveNav "assets"}}active{{end}}">Assets</a>
|
||||
<a href="/ui/components" class="{{if eq .ActiveNav "components"}}active{{end}}">Components</a>
|
||||
<a href="/ui/tickets" class="{{if eq .ActiveNav "tickets"}}active{{end}}">Tickets</a>
|
||||
<a href="/ui/failures" class="{{if eq .ActiveNav "failures"}}active{{end}}">Failures</a>
|
||||
<a href="/ui/ingest" class="{{if eq .ActiveNav "ingest"}}active{{end}}">Ingest</a>
|
||||
<a href="/ui/analytics" class="{{if eq .ActiveNav "analytics"}}active{{end}}">Analytics</a>
|
||||
<div class="nav-item">
|
||||
<a href="/ui" class="{{if eq .ActiveNav "dashboard"}}active{{end}}">Dashboard</a>
|
||||
</div>
|
||||
<div class="nav-item">
|
||||
<a href="/ui/customers" class="{{if eq .ActiveNav "customers"}}active{{end}}">Customers</a>
|
||||
</div>
|
||||
<div class="nav-item nav-group">
|
||||
<span class="nav-group-label {{if or (eq .ActiveNav "assets") (eq .ActiveNav "components")}}active{{end}}">Hardware</span>
|
||||
<div class="nav-submenu">
|
||||
<a href="/ui/assets" class="{{if eq .ActiveNav "assets"}}active{{end}}">Assets</a>
|
||||
<a href="/ui/components" class="{{if eq .ActiveNav "components"}}active{{end}}">Components</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="nav-item nav-group">
|
||||
<span class="nav-group-label {{if or (eq .ActiveNav "tickets") (eq .ActiveNav "failures") (eq .ActiveNav "analytics")}}active{{end}}">Health</span>
|
||||
<div class="nav-submenu">
|
||||
<a href="/ui/tickets" class="{{if eq .ActiveNav "tickets"}}active{{end}}">Tickets</a>
|
||||
<a href="/ui/failures" class="{{if eq .ActiveNav "failures"}}active{{end}}">Failures</a>
|
||||
<a href="/ui/analytics" class="{{if eq .ActiveNav "analytics"}}active{{end}}">Analytics</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="nav-item nav-group">
|
||||
<span class="nav-group-label {{if eq .ActiveNav "ingest"}}active{{end}}">Settings</span>
|
||||
<div class="nav-submenu">
|
||||
<a href="/ui/ingest" class="{{if eq .ActiveNav "ingest"}}active{{end}}">Ingest</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
{{end}}
|
||||
|
||||
{{define "breadcrumbs"}}
|
||||
{{if .Breadcrumbs}}
|
||||
<nav class="breadcrumbs">
|
||||
<a href="/ui" class="home-icon">🏥</a>
|
||||
{{range $i, $crumb := .Breadcrumbs}}
|
||||
<span class="separator">›</span>
|
||||
{{if $crumb.URL}}
|
||||
<a href="{{$crumb.URL}}">{{$crumb.Label}}</a>
|
||||
{{else}}
|
||||
<span class="current">{{$crumb.Label}}</span>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</nav>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
Reference in New Issue
Block a user