Zeitleiste: Karte je Eintrag mit Bearbeiten, Pausieren/Fortsetzen, Loeschen
Ein Klick auf einen Eintrag oeffnete bisher gleich den Editor - pausieren und loeschen ging nur in der Liste. Jetzt oeffnet sich eine kleine Karte: was die Automatik tut, wann, wie sie heute steht, die Bedingung, und die Knoepfe Bearbeiten, Pausieren bzw. Fortsetzen und Loeschen. Auch die Eintraege in den Baendern "Jederzeit" und "Pausiert" oeffnen sie. Pausieren und Loeschen gehen ueber toggleAutomation und deleteAutomation aus autoActionFuncs.js - dieselben Wege wie in der Liste, samt Rueckfrage bei abhaengigen Automatiken. Die Karte schliesst per Kreuz, Esc oder Klick daneben; solange sie offen ist, leuchtet die Kette des Eintrags. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -3100,6 +3100,64 @@ input[type='range']::-webkit-slider-runnable-track {
|
||||
.zl-l-balken { width: 22px; height: 7px; border-radius: 4px; background: rgba(95, 176, 220, .22); border: 1px solid rgba(95, 176, 220, .4); }
|
||||
.zl-l-kette { width: 22px; border-top: 1.2px dashed rgba(154, 166, 173, .7); }
|
||||
|
||||
/* Karte zu einem Eintrag: schwebt ueber der Zeitleiste, Akzent der Bahn. */
|
||||
.zl { position: relative; }
|
||||
.zl-karte {
|
||||
position: absolute;
|
||||
z-index: 20;
|
||||
width: min(22rem, 100%);
|
||||
padding: .7rem .85rem .75rem;
|
||||
border-radius: var(--ton-radius-klein, .5rem);
|
||||
border: 1px solid rgba(var(--zl-farbe-rgb), .45);
|
||||
border-top: 3px solid var(--zl-farbe);
|
||||
background: var(--ton-flaeche-2, #2b3237);
|
||||
box-shadow: 0 10px 28px rgba(0, 0, 0, .45);
|
||||
font-size: .8rem;
|
||||
}
|
||||
.zl-karte-kopf {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: .45rem;
|
||||
margin-bottom: .45rem;
|
||||
}
|
||||
.zl-karte-kopf .bi { color: var(--zl-farbe); }
|
||||
.zl-karte-name {
|
||||
flex: 1 1 auto;
|
||||
font: 500 .92rem var(--font-anzeige, inherit);
|
||||
color: var(--ton-schrift, #e8ede9);
|
||||
}
|
||||
.zl-karte .btn-close.zl-karte-zu { font-size: .6rem; opacity: .6; }
|
||||
.zl-karte-zeile {
|
||||
display: flex;
|
||||
gap: .5rem;
|
||||
align-items: baseline;
|
||||
padding: .12rem 0;
|
||||
color: var(--ton-schrift, #e8ede9);
|
||||
}
|
||||
.zl-karte-zeile .bi { color: var(--ton-schrift-3, #6f7a81); flex: none; }
|
||||
.zl-karte-stand.gut, .zl-karte-stand.gut .bi { color: var(--ton-gut, #4caf7d); }
|
||||
.zl-karte-stand.leise { color: var(--ton-schrift-2, #9aa6ad); }
|
||||
.zl-karte-wenn {
|
||||
margin-top: .35rem;
|
||||
padding-top: .35rem;
|
||||
border-top: 1px solid var(--zl-linie);
|
||||
color: var(--ton-schrift-3, #6f7a81);
|
||||
font-size: .72rem;
|
||||
line-height: 1.4;
|
||||
max-height: 5.6em;
|
||||
overflow: auto;
|
||||
}
|
||||
.zl-karte-knoepfe {
|
||||
display: flex;
|
||||
gap: .35rem;
|
||||
margin-top: .65rem;
|
||||
}
|
||||
.zl-karte-knoepfe .btn.zl-karte-weg {
|
||||
margin-left: auto;
|
||||
color: var(--ton-schrift-3, #6f7a81);
|
||||
}
|
||||
.zl-karte-knoepfe .btn.zl-karte-weg:hover { color: var(--ton-schlecht, #e06060); }
|
||||
|
||||
/* Ansicht umschalten: eine Klasse mehr als Bootstrap (solar.css laedt vorher). */
|
||||
.zl-ansicht .btn.active {
|
||||
background: rgba(0, 120, 143, .25);
|
||||
|
||||
+103
-1
@@ -438,6 +438,94 @@ function zlKetteHervorheben(id, an) {
|
||||
.forEach(el => el.classList.toggle("hell", an));
|
||||
}
|
||||
|
||||
/* --- Karte zu einem Eintrag ---------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Ein Klick auf einen Eintrag öffnet eine kleine Karte statt gleich den
|
||||
* Editor: was die Automatik tut, wann, wie sie heute steht - und die drei
|
||||
* Dinge, die man damit tun will. Pausieren und Löschen gab es vorher nur in
|
||||
* der Liste.
|
||||
*
|
||||
* Pausieren und Löschen gehen über dieselben Funktionen wie dort
|
||||
* (toggleAutomation, deleteAutomation in autoActionFuncs.js) - samt der
|
||||
* Rückfrage, was mit abhängigen Automatiken geschieht. Beide rufen danach
|
||||
* refreshAutomations(), und das lädt die Zeitleiste mit.
|
||||
*/
|
||||
function zlKarteOeffnen(anker, id) {
|
||||
const ziel = document.getElementById("zeitleiste");
|
||||
const d = zeitleiste.daten;
|
||||
const a = d && d.automatiken.find(x => x.id === Number(id));
|
||||
if (!ziel || !a) return;
|
||||
zlKarteSchliessen();
|
||||
|
||||
const zustand = a.enabled ? zlZustand(a, d) : "pausiert";
|
||||
const bahn = d.bahnen[a.bahn] || d.bahnen.sonstiges;
|
||||
const wann = a.art === "fenster"
|
||||
? zlUhr(a.von) + "–" + zlUhr(a.bis) + (a.punkt !== null && a.punkt > a.von ? ", frühestens " + zlUhr(a.punkt) : "")
|
||||
: a.art === "jederzeit" ? "jederzeit, wenn die Bedingung eintritt"
|
||||
: (a.art === "kette" || a.wartet ? "frühestens " : "um ") + zlUhr(a.punkt) + (a.sonne ? " (Sonnenstand)" : "");
|
||||
const stand = {
|
||||
gelaufen: ["bi-check2-circle", "gut", "gelaufen um " + a.laeufe.join(", ")],
|
||||
nichtdran: ["bi-calendar-x", "leise", "nicht dran: " + a.grund],
|
||||
vorbei: ["bi-dash-circle", "leise", "nicht gelaufen" + (a.wartet ? " – Bedingung war nicht erfüllt" : "")],
|
||||
aktiv: ["bi-hourglass-split", "", a.wartet ? "wartet auf die Bedingung" : "steht an"],
|
||||
kommt: ["bi-clock", "", "kommt noch"],
|
||||
pausiert: ["bi-pause-circle", "leise", "pausiert"],
|
||||
}[zustand];
|
||||
|
||||
const karte = document.createElement("div");
|
||||
karte.className = "zl-karte zl-bahn-" + a.bahn;
|
||||
karte.setAttribute("role", "dialog");
|
||||
karte.innerHTML =
|
||||
'<div class="zl-karte-kopf"><i class="bi ' + bahn.symbol + '"></i>'
|
||||
+ '<span class="zl-karte-name">' + zlText(a.name) + "</span>"
|
||||
+ '<span class="zl-band-etage">' + zlText(a.floor) + "</span>"
|
||||
+ '<button type="button" class="btn-close btn-close-white zl-karte-zu" aria-label="Schließen"></button></div>'
|
||||
+ '<div class="zl-karte-zeile"><i class="bi bi-lightning-charge"></i>' + zlText(a.satz) + "</div>"
|
||||
+ '<div class="zl-karte-zeile"><i class="bi bi-clock-history"></i>' + zlText(wann) + "</div>"
|
||||
+ '<div class="zl-karte-zeile zl-karte-stand ' + stand[1] + '"><i class="bi ' + stand[0] + '"></i>' + zlText(stand[2]) + "</div>"
|
||||
+ (a.wenn ? '<div class="zl-karte-wenn">Wenn: ' + zlText(a.wenn) + "</div>" : "")
|
||||
+ '<div class="zl-karte-knoepfe">'
|
||||
+ '<button type="button" class="btn btn-sm btn-outline-secondary" data-tun="bearbeiten"><i class="bi bi-pencil-square me-1"></i>Bearbeiten</button>'
|
||||
+ (a.enabled
|
||||
? '<button type="button" class="btn btn-sm btn-outline-secondary" data-tun="umschalten"><i class="bi bi-pause-fill me-1"></i>Pausieren</button>'
|
||||
: '<button type="button" class="btn btn-sm btn-success" data-tun="umschalten"><i class="bi bi-play-fill me-1"></i>Fortsetzen</button>')
|
||||
+ '<button type="button" class="btn btn-sm zl-karte-weg" data-tun="loeschen" title="Löschen"><i class="bi bi-trash3"></i></button>'
|
||||
+ "</div>";
|
||||
karte.dataset.id = a.id;
|
||||
ziel.appendChild(karte);
|
||||
|
||||
// Unter den Eintrag, sonst darüber; waagerecht in der Karte der Zeitleiste halten.
|
||||
const hoch = ziel.getBoundingClientRect();
|
||||
const r = anker.getBoundingClientRect();
|
||||
const breit = karte.offsetWidth, hoehe = karte.offsetHeight;
|
||||
let links = r.left - hoch.left;
|
||||
links = Math.max(0, Math.min(links, ziel.clientWidth - breit));
|
||||
let oben = r.bottom - hoch.top + 6;
|
||||
if (r.bottom + hoehe + 12 > window.innerHeight && r.top - hoehe - 6 > 0) oben = r.top - hoch.top - hoehe - 6;
|
||||
karte.style.left = links + "px";
|
||||
karte.style.top = oben + "px";
|
||||
zlKetteHervorheben(a.id, true);
|
||||
|
||||
karte.addEventListener("click", function (ereignis) {
|
||||
const knopf = ereignis.target.closest("[data-tun]");
|
||||
if (ereignis.target.closest(".zl-karte-zu")) { zlKarteSchliessen(); return; }
|
||||
if (!knopf) return;
|
||||
const tun = knopf.dataset.tun;
|
||||
zlKarteSchliessen();
|
||||
if (tun === "bearbeiten") openAutoActionModal("?action=editor&id=" + a.id);
|
||||
if (tun === "umschalten") toggleAutomation(a.id);
|
||||
if (tun === "loeschen") deleteAutomation(a.id, a.name);
|
||||
});
|
||||
}
|
||||
|
||||
function zlKarteSchliessen() {
|
||||
document.querySelectorAll("#zeitleiste .zl-karte").forEach(k => {
|
||||
zlKetteHervorheben(k.dataset.id, false);
|
||||
k.remove();
|
||||
});
|
||||
}
|
||||
|
||||
/* --- Laden und Bedienen -------------------------------------------------- */
|
||||
|
||||
async function zeitleisteLaden() {
|
||||
@@ -510,11 +598,15 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
|
||||
ziel.addEventListener("click", function (ereignis) {
|
||||
const t = ereignis.target;
|
||||
if (t.closest(".zl-karte")) return; // die Karte bedient sich selbst
|
||||
const ding = t.closest("[data-id]");
|
||||
if (ding) {
|
||||
openAutoActionModal("?action=editor&id=" + ding.dataset.id);
|
||||
const offen = ziel.querySelector(".zl-karte");
|
||||
if (offen && offen.dataset.id === ding.dataset.id) { zlKarteSchliessen(); return; }
|
||||
zlKarteOeffnen(ding, ding.dataset.id);
|
||||
return;
|
||||
}
|
||||
zlKarteSchliessen();
|
||||
const tag = t.closest("[data-tag]");
|
||||
if (tag) {
|
||||
const schritt = Number(tag.dataset.tag);
|
||||
@@ -550,9 +642,19 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
["mouseover", "mouseout"].forEach(typ => ziel.addEventListener(typ, function (ereignis) {
|
||||
const ding = ereignis.target.closest(".zl-ding");
|
||||
if (!ding || (ereignis.relatedTarget && ding.contains(ereignis.relatedTarget))) return;
|
||||
const offen = ziel.querySelector(".zl-karte");
|
||||
if (offen && offen.dataset.id === ding.dataset.id) return; // die offene Karte haelt ihre Kette hell
|
||||
zlKetteHervorheben(ding.dataset.id, typ === "mouseover");
|
||||
}));
|
||||
|
||||
// Ausserhalb der Zeitleiste geklickt oder Esc: Karte zu.
|
||||
document.addEventListener("click", function (ereignis) {
|
||||
if (!ziel.contains(ereignis.target)) zlKarteSchliessen();
|
||||
});
|
||||
document.addEventListener("keydown", function (ereignis) {
|
||||
if (ereignis.key === "Escape") zlKarteSchliessen();
|
||||
});
|
||||
|
||||
// Neu zeichnen, wenn sich die Breite ändert - Stapeln und Ketten hängen daran.
|
||||
let warte = null;
|
||||
if (typeof ResizeObserver !== "undefined") {
|
||||
|
||||
Reference in New Issue
Block a user