service detail change - md docs and toggable sections.

This commit is contained in:
JiriUhlir
2026-08-03 11:47:38 +02:00
parent f67a3fc993
commit eb7ee612c3
4 changed files with 613 additions and 105 deletions
+81
View File
@@ -126,6 +126,87 @@ document.addEventListener("click", (event) => {
}
});
// Sbalitelné sekce detailu služby: odkaz s kotvou (#metadata) musí cílovou sekci i otevřít,
// jinak by prohlížeč skočil na zavřený <details> a uživatel by neviděl žádný obsah.
function openHashSection() {
let hash = window.location.hash.slice(1);
if (!hash) {
return;
}
try {
hash = decodeURIComponent(hash);
} catch (error) {
return;
}
const target = document.getElementById(hash);
if (!target) {
return;
}
let node = target;
while (node) {
if (node.tagName === "DETAILS") {
node.open = true;
}
node = node.parentElement;
}
target.scrollIntoView();
}
window.addEventListener("hashchange", openHashSection);
document.addEventListener("DOMContentLoaded", openHashSection);
// Obsah načítaný až při rozbalení (seznam .md souborů a jejich náhledy). Načte se jen jednou;
// při chybě se příznak vrátí, aby šlo zkusit znovu dalším rozbalením.
function loadLazyPanel(panel) {
if (panel.dataset.lazyLoaded === "1") {
return;
}
panel.dataset.lazyLoaded = "1";
const url = panel.dataset.lazySrc;
panel.innerHTML = '<p class="muted">Načítám obsah</p>';
fetch(url, { headers: { "X-Requested-With": "fetch" } })
.then((response) => {
if (!response.ok) {
throw new Error("HTTP " + response.status);
}
return response.text();
})
.then((text) => {
panel.innerHTML = text;
})
.catch((error) => {
panel.dataset.lazyLoaded = "";
const message = document.createElement("p");
message.className = "alert alert-danger";
message.textContent = "Obsah se nepodařilo načíst: " + (error.message || error);
panel.replaceChildren(message);
});
}
// Událost toggle nebublá, proto ji odchytáváme v capture fázi na dokumentu.
document.addEventListener(
"toggle",
(event) => {
const details = event.target;
if (typeof HTMLDetailsElement === "undefined" || !(details instanceof HTMLDetailsElement) || !details.open) {
return;
}
// Jen panely patřící přímo této sekci - vnořené soubory se načtou až po svém rozbalení.
for (const panel of details.querySelectorAll("[data-lazy-src]")) {
if (panel.closest("details") === details) {
loadLazyPanel(panel);
}
}
},
true
);
function setFormDisabled(form, disabled) {
for (const field of form.querySelectorAll("input, select, textarea, button")) {
field.disabled = disabled;
+109
View File
@@ -679,6 +679,115 @@ textarea:disabled {
margin: 0 0 18px;
}
/* Sbalitelné sekce detailu služby (<details class="card card-section">). */
.card-section > summary.card-section-summary {
display: flex;
align-items: center;
gap: 12px;
cursor: pointer;
list-style: none;
}
.card-section > summary.card-section-summary::-webkit-details-marker {
display: none;
}
.card-section > summary.card-section-summary h2 {
margin: 0;
flex: 1;
}
.card-section-chevron {
color: var(--secondary);
font-size: 14px;
transition: transform 0.15s ease;
}
.card-section[open] > summary .card-section-chevron {
transform: rotate(180deg);
}
.card-section-body {
margin-top: 18px;
}
/* Dokumentace: seznam *.md souborů s náhledem obsahu. */
.docs-subtitle {
margin: 18px 0 6px;
color: var(--secondary);
}
.doc-file {
border-top: 1px solid var(--border);
padding: 10px 2px;
}
.doc-file > summary {
display: flex;
align-items: center;
gap: 8px;
font-weight: 600;
list-style: none;
}
.doc-file > summary::-webkit-details-marker {
display: none;
}
.doc-file > summary .fa-solid {
color: var(--primary);
}
.doc-file-size {
margin-left: auto;
font-size: 12px;
white-space: nowrap;
}
.doc-file-body {
margin: 10px 0 4px;
}
.md-body {
overflow-x: auto;
line-height: 1.55;
}
.md-body h1,
.md-body h2,
.md-body h3,
.md-body h4 {
color: var(--secondary);
margin: 18px 0 8px;
}
.md-body img {
max-width: 100%;
}
.md-body table {
width: auto;
}
.md-body code {
background: #eef6f9;
border-radius: 4px;
padding: 1px 5px;
font-family: Consolas, "Liberation Mono", Menlo, monospace;
font-size: 13px;
}
.md-body pre code {
background: transparent;
padding: 0;
color: inherit;
}
.md-raw {
font-size: 13px;
line-height: 1.5;
}
.add-variable-form {
margin-top: 18px;
}