Add mail menu sidebar
This commit is contained in:
parent
4616d725f2
commit
c26389e65f
3 changed files with 104 additions and 8 deletions
|
|
@ -54,13 +54,14 @@ func renderShell(w http.ResponseWriter, active, readingPane string) {
|
||||||
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
|
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
<title>Mail-Graveyard</title>
|
<title>Mail-Graveyard</title>
|
||||||
<link rel="stylesheet" href="/static/style.css?v=20260712-4">
|
<link rel="stylesheet" href="/static/style.css?v=20260712-6">
|
||||||
<script src="/static/htmx.min.js"></script>
|
<script src="/static/htmx.min.js"></script>
|
||||||
<script src="/static/app.js?v=20260712-4" defer></script></head>
|
<script src="/static/app.js?v=20260712-6" defer></script></head>
|
||||||
<body class="ol2013">
|
<body class="ol2013">
|
||||||
<header class="ribbon">
|
<header class="ribbon">
|
||||||
|
<button class="app-menu-button" type="button" aria-label="Mail-Graveyard-Menue" aria-expanded="false" data-backstage-toggle><span class="mail-logo" aria-hidden="true"></span></button>
|
||||||
<nav class="ribbon-tabs">
|
<nav class="ribbon-tabs">
|
||||||
<a class="tab %s" href="/view"><span class="mail-logo" aria-hidden="true"></span><span>Archiv-Boxen</span></a>
|
<a class="tab %s" href="/view">Archiv-Boxen</a>
|
||||||
<a class="tab" href="/view">Import/Export</a>
|
<a class="tab" href="/view">Import/Export</a>
|
||||||
<a class="tab" href="/accounts">Postfach-Verwaltung</a>
|
<a class="tab" href="/accounts">Postfach-Verwaltung</a>
|
||||||
<a class="tab" href="/view">Mail-Transfer</a>
|
<a class="tab" href="/view">Mail-Transfer</a>
|
||||||
|
|
@ -68,6 +69,14 @@ func renderShell(w http.ResponseWriter, active, readingPane string) {
|
||||||
</nav>
|
</nav>
|
||||||
<div class="ribbon-title">Mail-Graveyard</div>
|
<div class="ribbon-title">Mail-Graveyard</div>
|
||||||
</header>
|
</header>
|
||||||
|
<aside class="backstage-menu" aria-label="Mail-Graveyard-Menue">
|
||||||
|
<a class="backstage-item active" href="/view">Archiv-Boxen</a>
|
||||||
|
<a class="backstage-item" href="/view">Import/Export</a>
|
||||||
|
<a class="backstage-item" href="/accounts">Postfach-Verwaltung</a>
|
||||||
|
<a class="backstage-item" href="/view">Mail-Transfer</a>
|
||||||
|
<a class="backstage-item" href="/accounts">Einstellungen</a>
|
||||||
|
</aside>
|
||||||
|
<button class="backstage-shade" type="button" aria-label="Menue schliessen" data-backstage-close></button>
|
||||||
<div class="three-pane">
|
<div class="three-pane">
|
||||||
<aside class="pane pane-tree" id="tree"
|
<aside class="pane pane-tree" id="tree"
|
||||||
hx-get="/view" hx-trigger="load" hx-target="#tree" hx-swap="innerHTML">
|
hx-get="/view" hx-trigger="load" hx-target="#tree" hx-swap="innerHTML">
|
||||||
|
|
@ -275,13 +284,14 @@ func renderAccountsPage(w http.ResponseWriter, accounts []Account, edit Account,
|
||||||
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
|
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
<title>Postfach-Verwaltung - Mail-Graveyard</title>
|
<title>Postfach-Verwaltung - Mail-Graveyard</title>
|
||||||
<link rel="stylesheet" href="/static/style.css?v=20260712-5">
|
<link rel="stylesheet" href="/static/style.css?v=20260712-6">
|
||||||
<script src="/static/htmx.min.js"></script>
|
<script src="/static/htmx.min.js"></script>
|
||||||
<script src="/static/app.js?v=20260712-5" defer></script></head>
|
<script src="/static/app.js?v=20260712-6" defer></script></head>
|
||||||
<body class="ol2013">
|
<body class="ol2013">
|
||||||
<header class="ribbon">
|
<header class="ribbon">
|
||||||
|
<button class="app-menu-button" type="button" aria-label="Mail-Graveyard-Menue" aria-expanded="false" data-backstage-toggle><span class="mail-logo" aria-hidden="true"></span></button>
|
||||||
<nav class="ribbon-tabs">
|
<nav class="ribbon-tabs">
|
||||||
<a class="tab" href="/view"><span class="mail-logo" aria-hidden="true"></span><span>Archiv-Boxen</span></a>
|
<a class="tab" href="/view">Archiv-Boxen</a>
|
||||||
<a class="tab" href="/view">Import/Export</a>
|
<a class="tab" href="/view">Import/Export</a>
|
||||||
<a class="tab active" href="/accounts">Postfach-Verwaltung</a>
|
<a class="tab active" href="/accounts">Postfach-Verwaltung</a>
|
||||||
<a class="tab" href="/view">Mail-Transfer</a>
|
<a class="tab" href="/view">Mail-Transfer</a>
|
||||||
|
|
@ -289,6 +299,14 @@ func renderAccountsPage(w http.ResponseWriter, accounts []Account, edit Account,
|
||||||
</nav>
|
</nav>
|
||||||
<div class="ribbon-title">Mail-Graveyard</div>
|
<div class="ribbon-title">Mail-Graveyard</div>
|
||||||
</header>
|
</header>
|
||||||
|
<aside class="backstage-menu" aria-label="Mail-Graveyard-Menue">
|
||||||
|
<a class="backstage-item" href="/view">Archiv-Boxen</a>
|
||||||
|
<a class="backstage-item" href="/view">Import/Export</a>
|
||||||
|
<a class="backstage-item active" href="/accounts">Postfach-Verwaltung</a>
|
||||||
|
<a class="backstage-item" href="/view">Mail-Transfer</a>
|
||||||
|
<a class="backstage-item" href="/accounts">Einstellungen</a>
|
||||||
|
</aside>
|
||||||
|
<button class="backstage-shade" type="button" aria-label="Menue schliessen" data-backstage-close></button>
|
||||||
<main class="accounts-page">`)
|
<main class="accounts-page">`)
|
||||||
if msg != "" {
|
if msg != "" {
|
||||||
fmt.Fprintf(w, `<div class="notice ok">%s</div>`, html.EscapeString(msg))
|
fmt.Fprintf(w, `<div class="notice ok">%s</div>`, html.EscapeString(msg))
|
||||||
|
|
|
||||||
24
frontend-js/dist/app.js
vendored
24
frontend-js/dist/app.js
vendored
|
|
@ -93,6 +93,30 @@
|
||||||
window.addEventListener("DOMContentLoaded", () => bind(document.querySelector(".three-pane")));
|
window.addEventListener("DOMContentLoaded", () => bind(document.querySelector(".three-pane")));
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
function setOpen(open) {
|
||||||
|
document.body.classList.toggle("backstage-open", open);
|
||||||
|
document.querySelectorAll("[data-backstage-toggle]").forEach((button) => {
|
||||||
|
button.setAttribute("aria-expanded", open ? "true" : "false");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("click", (event) => {
|
||||||
|
const toggle = event.target.closest("[data-backstage-toggle]");
|
||||||
|
if (toggle) {
|
||||||
|
setOpen(!document.body.classList.contains("backstage-open"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (event.target.closest("[data-backstage-close]")) {
|
||||||
|
setOpen(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener("keydown", (event) => {
|
||||||
|
if (event.key === "Escape") setOpen(false);
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
function rowPayload(row) {
|
function rowPayload(row) {
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
58
frontend-js/dist/style.css
vendored
58
frontend-js/dist/style.css
vendored
|
|
@ -32,13 +32,28 @@ body.ol2013 {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 24px;
|
gap: 12px;
|
||||||
padding: 0 16px;
|
padding: 0 16px 0 0;
|
||||||
height: 44px;
|
height: 44px;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
|
position: relative;
|
||||||
|
z-index: 20;
|
||||||
}
|
}
|
||||||
.ribbon-title { margin-left: auto; font-weight: 700; font-size: 15px; letter-spacing: .2px; }
|
.ribbon-title { margin-left: auto; font-weight: 700; font-size: 15px; letter-spacing: .2px; }
|
||||||
.ribbon-tabs { display: flex; gap: 2px; height: 100%; }
|
.ribbon-tabs { display: flex; gap: 2px; height: 100%; }
|
||||||
|
.app-menu-button {
|
||||||
|
width: 54px;
|
||||||
|
height: 44px;
|
||||||
|
border: 0;
|
||||||
|
background: var(--ol-blue-dark);
|
||||||
|
color: #fff;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.app-menu-button:hover,
|
||||||
|
.app-menu-button[aria-expanded="true"] { background: #00365f; }
|
||||||
.tab {
|
.tab {
|
||||||
display: flex; align-items: center;
|
display: flex; align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
|
@ -77,6 +92,45 @@ body.ol2013 {
|
||||||
transform-origin: right center;
|
transform-origin: right center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.backstage-menu {
|
||||||
|
position: fixed;
|
||||||
|
top: 44px;
|
||||||
|
left: 0;
|
||||||
|
bottom: 22px;
|
||||||
|
width: 216px;
|
||||||
|
z-index: 18;
|
||||||
|
background: var(--ol-blue);
|
||||||
|
color: #fff;
|
||||||
|
padding: 10px 0;
|
||||||
|
transform: translateX(-100%);
|
||||||
|
transition: transform .16s ease-out;
|
||||||
|
box-shadow: 8px 0 18px rgba(0, 0, 0, .16);
|
||||||
|
}
|
||||||
|
.backstage-open .backstage-menu { transform: translateX(0); }
|
||||||
|
.backstage-item {
|
||||||
|
display: block;
|
||||||
|
padding: 11px 22px;
|
||||||
|
color: #fff;
|
||||||
|
text-decoration: none;
|
||||||
|
border-left: 3px solid transparent;
|
||||||
|
}
|
||||||
|
.backstage-item:hover { background: var(--ol-blue-dark); }
|
||||||
|
.backstage-item.active {
|
||||||
|
background: #fff;
|
||||||
|
color: var(--ol-blue);
|
||||||
|
border-left-color: #fff;
|
||||||
|
}
|
||||||
|
.backstage-shade {
|
||||||
|
position: fixed;
|
||||||
|
inset: 44px 0 22px 0;
|
||||||
|
z-index: 17;
|
||||||
|
border: 0;
|
||||||
|
background: transparent;
|
||||||
|
display: none;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
.backstage-open .backstage-shade { display: block; }
|
||||||
|
|
||||||
/* Viewer */
|
/* Viewer */
|
||||||
.three-pane,
|
.three-pane,
|
||||||
.four-pane {
|
.four-pane {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue