Webapp redesign phase 2: Overview and imaging floor
Imaging floor (/imaging, /imaging/tiles): - One line per PC: status chip, serial with machine number, hostname and IP, stage text with a segmented stage track, one action plus a '...' menu. Everything else (description, error, timestamps, Intune ID + QR, Set category / ARTS links, LAPS QR, log tail) is in the row's expandable body. - Order: failed, needs action (stage 7), in progress, done; log-only bays fold into one collapsed group. imaging_status.floor_state() and floor_order() compute this. - Status filter buttons with live counts next to the text filter. SSE refresh, expanded-row memory and LAPS handling are unchanged. - Stage text is never truncated; BIOS updates and erasing are bold. Overview (/): - Services popover, technician to-do line, the six most urgent floor rows (?limit=6 partial, refreshed every 15 s), and image cards with lint warnings, map errors and missing zips as separate chips. New, clone, delete and unattend stay on the cards' menus. Copy buttons are now handled once in static/app.js, with a fallback for plain-http pages where navigator.clipboard is unavailable.
This commit is contained in:
@@ -467,3 +467,30 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
|
||||
});
|
||||
|
||||
|
||||
// Copy buttons: any .copy-btn[data-copy-text], on every page. The LAN is
|
||||
// plain http, so navigator.clipboard is often unavailable; fall back to a
|
||||
// hidden textarea + execCommand. The button briefly reads "Copied".
|
||||
document.addEventListener('click', function (e) {
|
||||
var btn = e.target.closest && e.target.closest('.copy-btn');
|
||||
if (!btn) return;
|
||||
var text = btn.getAttribute('data-copy-text') || '';
|
||||
if (!text) return;
|
||||
var done = function (ok) {
|
||||
var orig = btn.getAttribute('data-orig-label') || btn.textContent;
|
||||
btn.setAttribute('data-orig-label', orig);
|
||||
btn.textContent = ok ? 'Copied' : 'Copy failed';
|
||||
setTimeout(function () { btn.textContent = orig; }, 1400);
|
||||
};
|
||||
if (navigator.clipboard && window.isSecureContext) {
|
||||
navigator.clipboard.writeText(text).then(function () { done(true); }, function () { done(false); });
|
||||
return;
|
||||
}
|
||||
var ta = document.createElement('textarea');
|
||||
ta.value = text; ta.setAttribute('readonly', ''); ta.style.position = 'fixed'; ta.style.opacity = '0';
|
||||
document.body.appendChild(ta); ta.select();
|
||||
var ok = false;
|
||||
try { ok = document.execCommand('copy'); } catch (err) { ok = false; }
|
||||
document.body.removeChild(ta);
|
||||
done(ok);
|
||||
});
|
||||
|
||||
@@ -237,3 +237,43 @@ details.more .menu form { margin: 0; }
|
||||
|
||||
/* Flash messages restyled to the token palette (Bootstrap markup kept). */
|
||||
.ui-main > .alert { border-radius: 10px; border: 0; box-shadow: 0 1px 2px var(--shadow); }
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
Imaging floor rows (_imaging_tiles.html), used by /imaging and Overview.
|
||||
-------------------------------------------------------------------------- */
|
||||
.floor { container-type: inline-size; }
|
||||
.frow, .fhead {
|
||||
display: grid; grid-template-columns: 118px minmax(160px, 270px) minmax(0, 1fr);
|
||||
grid-template-areas: "st pc stage"; align-items: center; gap: 0 20px; padding: 14px 230px 14px 24px;
|
||||
}
|
||||
.fhead { padding-top: 6px; padding-bottom: 6px; font-size: 12px; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
|
||||
.g-st { grid-area: st; } .g-pc { grid-area: pc; min-width: 0; display: flex; flex-direction: column; } .g-stage { grid-area: stage; min-width: 0; }
|
||||
.floor-row .g-act { position: absolute; right: 20px; top: 16px; width: 190px; justify-content: flex-end; }
|
||||
.floor-row .serial { font-size: 15px; }
|
||||
.stageline { display: flex; align-items: center; gap: 12px; font-size: 13px; min-height: 24px; }
|
||||
.stageline .txt { flex: 1 1 auto; min-width: 0; white-space: normal; }
|
||||
.stageline .warnline { font-weight: 600; }
|
||||
.stageline .kind { flex: none; font-size: 12px; color: var(--muted); max-width: 40%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.stageline .step { flex: none; color: var(--muted); font-size: 12px; }
|
||||
.fbody { display: flex; gap: 24px; align-items: flex-start; padding: 0 24px 16px 162px; font-size: 13px; }
|
||||
.fbody-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 10px; }
|
||||
.fbody-qr { flex: none; line-height: 0; background: #FFFFFF; padding: 6px; border-radius: 6px; }
|
||||
.fmeta { display: flex; flex-wrap: wrap; gap: 4px 16px; }
|
||||
.fline { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
|
||||
.imaging-log-pre { max-height: 14rem; overflow-y: auto; margin: 6px 0 0; padding: 8px 10px; background: var(--surface-2); border: 1px solid var(--line); border-radius: 6px; font-size: 12px; white-space: pre-wrap; }
|
||||
.floor-logs { border-top: 1px solid var(--line); }
|
||||
.floor-logs > summary { padding: 0 24px; min-height: 44px; color: var(--text-2); font-weight: 400; }
|
||||
.floor-empty { padding: 28px 24px; text-align: center; border-top: 1px solid var(--line); }
|
||||
@container (max-width: 820px) {
|
||||
.fhead { display: none; }
|
||||
.frow { grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "st pc" "stage stage"; gap: 10px 14px; padding: 14px 18px; }
|
||||
.floor-row .g-act { position: static; width: auto; display: flex; justify-content: flex-end; padding: 0 18px 12px; }
|
||||
.fbody { padding: 0 18px 14px; flex-direction: column; }
|
||||
}
|
||||
|
||||
/* Overview image cards */
|
||||
.img-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr)); gap: 16px; }
|
||||
.img-card { padding: 16px 18px; display: flex; flex-direction: column; gap: 8px; min-width: 0; }
|
||||
.img-top { display: flex; align-items: center; gap: 8px; }
|
||||
.img-name { font-weight: 600; font-size: 16px; color: var(--text); text-decoration: none; margin-right: auto; }
|
||||
.img-name:hover { color: var(--accent); }
|
||||
|
||||
Reference in New Issue
Block a user