Show the build id, tame long table cells, and add purposeful motion
The build identifier now sits in the sidebar footer. "Is my deploy actually live?" was only answerable by opening Session & Security, which is the wrong place for the first question asked after every deploy. Error-log rows carry stack traces and full URLs. They stretched their row far past the viewport and pushed the other columns out of view, which is exactly where the console is least usable. Values over 70 characters truncate and expand on click. Motion is limited to two things that mean something: content arriving (staggered, so a grid resolves instead of snapping), and a fetch being in flight — the refresh control spins and the status pill pulses, so a section that legitimately returns nothing still shows that it tried. All of it is disabled under prefers-reduced-motion. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
f9110a7d92
commit
3fb7bc5190
@@ -560,6 +560,8 @@
|
||||
applyLanguage();
|
||||
deviceFingerprint = await resolveFingerprint();
|
||||
if (el.fpPreview) el.fpPreview.textContent = deviceFingerprint.slice(0, 12) + '…';
|
||||
const stamp = $('buildStamp');
|
||||
if (stamp) stamp.textContent = `build ${BUILD}`;
|
||||
|
||||
buildModules();
|
||||
setupNavigation();
|
||||
@@ -3149,13 +3151,23 @@
|
||||
return wrap;
|
||||
}
|
||||
|
||||
const LONG_CELL = 70;
|
||||
|
||||
function cellHtml(column, value) {
|
||||
if (value === null || value === undefined || value === '') return '<span class="stamp">—</span>';
|
||||
if (typeof value === 'object') return `<span class="stamp">${esc(JSON.stringify(value).slice(0, 60))}</span>`;
|
||||
if (/status|type|state|result/i.test(column)) {
|
||||
return `<span class="badge ${badgeClass(value)}">${esc(labelStatus(value))}</span>`;
|
||||
}
|
||||
return esc(formatValue(value, column));
|
||||
|
||||
const text = formatValue(value, column);
|
||||
// Stack traces and URLs would otherwise stretch the row far past the
|
||||
// viewport and push every other column out of view.
|
||||
if (String(text).length > LONG_CELL) {
|
||||
return `<span class="cell-long" title="click to expand">${esc(String(text).slice(0, LONG_CELL))}…</span>
|
||||
<span class="cell-full" hidden>${esc(String(text))}</span>`;
|
||||
}
|
||||
return esc(text);
|
||||
}
|
||||
|
||||
function formatValue(value, column = '') {
|
||||
@@ -3667,6 +3679,11 @@
|
||||
};
|
||||
|
||||
function refreshView(viewId, moduleId) {
|
||||
setConnection('loading', t('Loading live data…'));
|
||||
setTimeout(() => {
|
||||
if (el.connectionPill?.dataset.state === 'loading') setConnection('live', t('Live database'));
|
||||
}, 900);
|
||||
|
||||
const mod = MODULES.find((m) => m.id === moduleId);
|
||||
if (mod) {
|
||||
loadModule(mod, true); // force: bypass the loaded-once cache
|
||||
@@ -3711,6 +3728,15 @@
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener('click', (e) => {
|
||||
const cell = e.target.closest('.cell-long');
|
||||
if (!cell) return;
|
||||
const full = cell.nextElementSibling;
|
||||
if (!full?.classList.contains('cell-full')) return;
|
||||
cell.hidden = true;
|
||||
full.hidden = false;
|
||||
});
|
||||
|
||||
let resizeTimer;
|
||||
window.addEventListener('resize', () => {
|
||||
clearTimeout(resizeTimer);
|
||||
@@ -3748,6 +3774,9 @@
|
||||
if (!el.connectionPill) return;
|
||||
el.connectionPill.dataset.state = state;
|
||||
el.connectionText.textContent = text;
|
||||
// Visible feedback that a fetch is running: a section with no data still
|
||||
// needs to show that it tried.
|
||||
el.refreshBtn?.classList.toggle('is-busy', state === 'loading');
|
||||
}
|
||||
|
||||
function busy(btn, isBusy, label) {
|
||||
|
||||
Reference in New Issue
Block a user