diff --git a/lxc-frontend/app/static/app.js b/lxc-frontend/app/static/app.js index 719bd9d..d4e9d55 100644 --- a/lxc-frontend/app/static/app.js +++ b/lxc-frontend/app/static/app.js @@ -37,6 +37,10 @@ const defaultProfileName = document.getElementById("default-profile-name"); const headerProfileWrap = document.getElementById("header-profile-wrap"); const headerProfile = document.getElementById("header-profile"); +const jobsCards = document.getElementById("jobs-cards"); +const adminToggle = document.getElementById("admin-toggle"); +const adminCollapsible = document.getElementById("admin-card"); + const recordToggle = document.getElementById("record-toggle"); const recordToggleLabel = document.getElementById("record-toggle-label"); const recordPane = document.getElementById("record-pane"); @@ -302,6 +306,43 @@ function row(job) { return tr; } +function card(job) { + const div = document.createElement("div"); + div.className = "jc"; + const title = job.title || job.original_name; + const showProfileTag = availableProfiles.length > 1 || (job.profile && job.profile !== "meeting"); + const profileTag = showProfileTag + ? `${escapeHtml(profileLabelOf(job.profile || "meeting"))}` + : ""; + const ownerLine = currentUser?.is_admin && job.owner_username + ? `
von ${escapeHtml(job.owner_username)}
` : ""; + + const dlButtons = DOWNLOADS.map(({ kind, label, title: tip }) => { + const dis = !job.has[kind]; + const href = dis ? "" : `href="/api/jobs/${job.id}/download/${kind}"`; + return `${label}`; + }).join(""); + + div.innerHTML = ` +
+
+
${escapeHtml(title)} ${profileTag}
+
${escapeHtml(job.original_name)} · #${job.id}
+ ${ownerLine} +
+ ${escapeHtml(job.status)} +
+
+
+ ${job.progress}% +
+ ${job.error ? `
${escapeHtml(job.error)}
` : ""} +
aktualisiert: ${escapeHtml(fmtDate(job.updated_at))}
+
${dlButtons}
+ `; + return div; +} + async function loadJobs() { if (!currentUser) return; try { @@ -309,11 +350,16 @@ async function loadJobs() { if (r.status === 401) { showAuth("login"); return; } const jobs = await r.json(); jobsBody.innerHTML = ""; + jobsCards.innerHTML = ""; if (!jobs.length) { jobsBody.innerHTML = 'Noch keine Jobs.'; + jobsCards.innerHTML = '
Noch keine Jobs.
'; return; } - jobs.forEach((j) => jobsBody.appendChild(row(j))); + jobs.forEach((j) => { + jobsBody.appendChild(row(j)); + jobsCards.appendChild(card(j)); + }); } catch (e) { console.error(e); } @@ -613,6 +659,13 @@ recPauseBtn.addEventListener("click", pauseRecording); recStopBtn.addEventListener("click", stopRecording); recordDiscardBtn.addEventListener("click", discardRecording); +// Admin-Toggle (klappbar auf Mobile, immer offen auf Desktop) +adminToggle.addEventListener("click", () => { + if (window.matchMedia("(max-width: 700px)").matches) { + adminCollapsible.classList.toggle("open"); + } +}); + // ─── Init ────────────────────────────────────────────────────────────────── bootstrap(); checkMac(); diff --git a/lxc-frontend/app/static/index.html b/lxc-frontend/app/static/index.html index 58eeb39..0bf8f40 100644 --- a/lxc-frontend/app/static/index.html +++ b/lxc-frontend/app/static/index.html @@ -19,17 +19,17 @@

Voice-Agent

-

Sitzungsaufnahmen automatisch transkribieren und protokollieren

+

Sitzungsaufnahmen automatisch transkribieren und protokollieren

-
Mac-Backend: prüfe …
+
Mac-Backend: prüfe …
-
-

Neue Aufnahme hochladen

+
+

Neue Aufnahme hochladen

- - -
- -
— oder —
- -
+ + +
+ + +
+ + +
+ + +
+ Lieber eine vorhandene Audio-Datei hochladen? + +
+