Add sync action dropdowns
This commit is contained in:
parent
f612454e5b
commit
181a91c660
3 changed files with 102 additions and 18 deletions
|
|
@ -128,8 +128,8 @@ func renderStartPage(w http.ResponseWriter, r *http.Request) {
|
|||
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Mail-Graveyard</title>
|
||||
<link rel="stylesheet" href="/static/style.css?v=20260713-13">
|
||||
<script src="/static/app.js?v=20260713-13" defer></script></head>
|
||||
<link rel="stylesheet" href="/static/style.css?v=20260713-14">
|
||||
<script src="/static/app.js?v=20260713-14" defer></script></head>
|
||||
<body class="ol2013">
|
||||
<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>
|
||||
|
|
@ -176,9 +176,9 @@ func renderShell(w http.ResponseWriter, r *http.Request, active, readingPane str
|
|||
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Mail-Graveyard</title>
|
||||
<link rel="stylesheet" href="/static/style.css?v=20260713-13">
|
||||
<link rel="stylesheet" href="/static/style.css?v=20260713-14">
|
||||
<script src="/static/htmx.min.js"></script>
|
||||
<script src="/static/app.js?v=20260713-13" defer></script></head>
|
||||
<script src="/static/app.js?v=20260713-14" defer></script></head>
|
||||
<body class="ol2013">
|
||||
<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>
|
||||
|
|
@ -752,9 +752,9 @@ func renderAccountsPage(w http.ResponseWriter, r *http.Request, accounts []Accou
|
|||
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Konten-Verwaltung - Mail-Graveyard</title>
|
||||
<link rel="stylesheet" href="/static/style.css?v=20260713-13">
|
||||
<link rel="stylesheet" href="/static/style.css?v=20260713-14">
|
||||
<script src="/static/htmx.min.js"></script>
|
||||
<script src="/static/app.js?v=20260713-13" defer></script></head>
|
||||
<script src="/static/app.js?v=20260713-14" defer></script></head>
|
||||
<body class="ol2013">
|
||||
<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>
|
||||
|
|
@ -798,9 +798,9 @@ func renderArchivesPage(w http.ResponseWriter, r *http.Request, archives []strin
|
|||
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Archiv-mbox Verwaltung - Mail-Graveyard</title>
|
||||
<link rel="stylesheet" href="/static/style.css?v=20260713-13">
|
||||
<link rel="stylesheet" href="/static/style.css?v=20260713-14">
|
||||
<script src="/static/htmx.min.js"></script>
|
||||
<script src="/static/app.js?v=20260713-13" defer></script></head>
|
||||
<script src="/static/app.js?v=20260713-14" defer></script></head>
|
||||
<body class="ol2013">
|
||||
<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>
|
||||
|
|
@ -846,9 +846,9 @@ func renderUsersPage(w http.ResponseWriter, r *http.Request, users []AppUser, ed
|
|||
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Benutzerverwaltung - Mail-Graveyard</title>
|
||||
<link rel="stylesheet" href="/static/style.css?v=20260713-13">
|
||||
<link rel="stylesheet" href="/static/style.css?v=20260713-14">
|
||||
<script src="/static/htmx.min.js"></script>
|
||||
<script src="/static/app.js?v=20260713-13" defer></script></head>
|
||||
<script src="/static/app.js?v=20260713-14" defer></script></head>
|
||||
<body class="ol2013">
|
||||
<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>
|
||||
|
|
@ -920,9 +920,9 @@ func renderTransferPage(w http.ResponseWriter, r *http.Request, mode transferMod
|
|||
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>%s - Mail-Graveyard</title>
|
||||
<link rel="stylesheet" href="/static/style.css?v=20260713-13">
|
||||
<link rel="stylesheet" href="/static/style.css?v=20260713-14">
|
||||
<script src="/static/htmx.min.js"></script>
|
||||
<script src="/static/app.js?v=20260713-13" defer></script></head>
|
||||
<script src="/static/app.js?v=20260713-14" defer></script></head>
|
||||
<body class="ol2013">
|
||||
<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>
|
||||
|
|
@ -1372,9 +1372,9 @@ func renderSourceEmailBoxPage(w http.ResponseWriter, r *http.Request, accounts [
|
|||
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Quell-Postfach - Mail-Graveyard</title>
|
||||
<link rel="stylesheet" href="/static/style.css?v=20260713-13">
|
||||
<link rel="stylesheet" href="/static/style.css?v=20260713-14">
|
||||
<script src="/static/htmx.min.js"></script>
|
||||
<script src="/static/app.js?v=20260713-13" defer></script></head>
|
||||
<script src="/static/app.js?v=20260713-14" defer></script></head>
|
||||
<body class="ol2013">
|
||||
<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>
|
||||
|
|
@ -1416,9 +1416,9 @@ func renderTargetEmailBoxPage(w http.ResponseWriter, r *http.Request, accounts [
|
|||
fmt.Fprintf(w, `<!doctype html><html lang="de"><head><meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Ziel-Postfach - Mail-Graveyard</title>
|
||||
<link rel="stylesheet" href="/static/style.css?v=20260713-13">
|
||||
<link rel="stylesheet" href="/static/style.css?v=20260713-14">
|
||||
<script src="/static/htmx.min.js"></script>
|
||||
<script src="/static/app.js?v=20260713-13" defer></script></head>
|
||||
<script src="/static/app.js?v=20260713-14" defer></script></head>
|
||||
<body class="ol2013">
|
||||
<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>
|
||||
|
|
|
|||
41
frontend-js/dist/app.js
vendored
41
frontend-js/dist/app.js
vendored
|
|
@ -17,8 +17,22 @@
|
|||
<button class="action-btn" type="button" data-action-forward><span aria-hidden="true">↪</span> Weiterleiten</button>
|
||||
<button class="action-btn muted" type="button" disabled><span aria-hidden="true">⌫</span> Loeschen</button>
|
||||
<span class="action-separator"></span>
|
||||
<button class="action-btn muted" type="button" disabled><span aria-hidden="true">⇄</span> Ordner Sync</button>
|
||||
<button class="action-btn muted" type="button" disabled><span aria-hidden="true">✉</span> Email-Sync</button>
|
||||
<div class="action-menu">
|
||||
<button class="action-btn action-menu-button" type="button" aria-expanded="false" data-action-menu-toggle><span aria-hidden="true">⇄</span> Ordner Sync</button>
|
||||
<div class="action-dropdown">
|
||||
<button type="button" class="action-dropdown-item" data-sync-kind="folder" data-sync-direction="push">Ordner --> Ordner</button>
|
||||
<button type="button" class="action-dropdown-item" data-sync-kind="folder" data-sync-direction="both">Ordner <--> Ordner</button>
|
||||
<button type="button" class="action-dropdown-item" data-sync-kind="folder" data-sync-direction="pull">Ordner <-- Ordner</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="action-menu">
|
||||
<button class="action-btn action-menu-button" type="button" aria-expanded="false" data-action-menu-toggle><span aria-hidden="true">✉</span> Email-Sync</button>
|
||||
<div class="action-dropdown">
|
||||
<button type="button" class="action-dropdown-item" data-sync-kind="email" data-sync-direction="push">Email --> Email</button>
|
||||
<button type="button" class="action-dropdown-item" data-sync-kind="email" data-sync-direction="both">Email <--> Email</button>
|
||||
<button type="button" class="action-dropdown-item" data-sync-kind="email" data-sync-direction="pull">Email <-- Email</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
ribbon.insertAdjacentElement("afterend", bar);
|
||||
}
|
||||
|
|
@ -113,6 +127,13 @@
|
|||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", ensureActionBar);
|
||||
function closeActionMenus() {
|
||||
document.querySelectorAll(".action-menu.open").forEach((menu) => {
|
||||
menu.classList.remove("open");
|
||||
menu.querySelector("[data-action-menu-toggle]")?.setAttribute("aria-expanded", "false");
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("click", (event) => {
|
||||
const row = event.target.closest(".msg-row");
|
||||
if (!row) return;
|
||||
|
|
@ -120,6 +141,22 @@
|
|||
row.classList.add("active");
|
||||
});
|
||||
document.addEventListener("click", (event) => {
|
||||
const menuButton = event.target.closest("[data-action-menu-toggle]");
|
||||
if (menuButton) {
|
||||
const menu = menuButton.closest(".action-menu");
|
||||
const willOpen = !menu.classList.contains("open");
|
||||
closeActionMenus();
|
||||
menu.classList.toggle("open", willOpen);
|
||||
menuButton.setAttribute("aria-expanded", willOpen ? "true" : "false");
|
||||
return;
|
||||
}
|
||||
if (!event.target.closest(".action-menu")) closeActionMenus();
|
||||
const syncItem = event.target.closest("[data-sync-kind]");
|
||||
if (syncItem) {
|
||||
closeActionMenus();
|
||||
window.alert("Sync-Funktion ist vorbereitet, aber noch nicht aktiv.");
|
||||
return;
|
||||
}
|
||||
if (event.target.closest("[data-action-new]")) {
|
||||
openCompose({ to: "", subject: "", body: "" });
|
||||
}
|
||||
|
|
|
|||
47
frontend-js/dist/style.css
vendored
47
frontend-js/dist/style.css
vendored
|
|
@ -239,6 +239,53 @@ body.ol2013 {
|
|||
background: transparent;
|
||||
border-color: transparent;
|
||||
}
|
||||
.action-menu {
|
||||
position: relative;
|
||||
height: 30px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
.action-menu-button::after {
|
||||
content: "";
|
||||
width: 0;
|
||||
height: 0;
|
||||
margin-left: 2px;
|
||||
border-left: 4px solid transparent;
|
||||
border-right: 4px solid transparent;
|
||||
border-top: 5px solid currentColor;
|
||||
}
|
||||
.action-menu.open .action-menu-button {
|
||||
background: var(--ol-blue-dark);
|
||||
border-color: #4f94ca;
|
||||
}
|
||||
.action-dropdown {
|
||||
position: absolute;
|
||||
top: 34px;
|
||||
left: 0;
|
||||
min-width: 190px;
|
||||
display: none;
|
||||
padding: 4px 0;
|
||||
background: #fff;
|
||||
color: var(--ol-text);
|
||||
border: 1px solid var(--ol-border);
|
||||
box-shadow: 0 8px 20px rgba(0, 0, 0, .22);
|
||||
z-index: 45;
|
||||
}
|
||||
.action-menu.open .action-dropdown { display: block; }
|
||||
.action-dropdown-item {
|
||||
width: 100%;
|
||||
display: block;
|
||||
padding: 8px 12px;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: var(--ol-text);
|
||||
font: inherit;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
.action-dropdown-item:hover {
|
||||
background: #eef6fd;
|
||||
color: var(--ol-blue-dark);
|
||||
}
|
||||
.action-separator {
|
||||
width: 1px;
|
||||
height: 26px;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue