Refactor activity log UI
This commit is contained in:
@ -327,29 +327,51 @@ code {
|
|||||||
.badge-activity-app_change { background: var(--badge-in-progress-bg); color: var(--badge-in-progress-fg); }
|
.badge-activity-app_change { background: var(--badge-in-progress-bg); color: var(--badge-in-progress-fg); }
|
||||||
.badge-activity-web_change { background: var(--badge-supervisor-bg); color: var(--badge-supervisor-fg); }
|
.badge-activity-web_change { background: var(--badge-supervisor-bg); color: var(--badge-supervisor-fg); }
|
||||||
.badge-activity-web_export { background: var(--badge-admin-bg); color: var(--badge-admin-fg); }
|
.badge-activity-web_export { background: var(--badge-admin-bg); color: var(--badge-admin-fg); }
|
||||||
|
.badge-activity-api_error { background: var(--badge-archived-bg); color: var(--badge-archived-fg); }
|
||||||
.activity-log-card .table-wrapper { max-height: 420px; overflow: auto; }
|
.activity-log-card .table-wrapper { max-height: 420px; overflow: auto; }
|
||||||
|
.activity-log-card .filter-bar label {
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
.activity-log-detail {
|
.activity-log-detail {
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
max-width: 280px;
|
max-width: 280px;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
|
table.data-table.activity-log-table th,
|
||||||
|
table.data-table.activity-log-table td {
|
||||||
|
vertical-align: top;
|
||||||
|
line-height: 1.45;
|
||||||
|
}
|
||||||
|
table.data-table.activity-log-table .activity-log-col-time,
|
||||||
|
table.data-table.activity-log-table .activity-log-col-meta {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
table.data-table.activity-log-table .activity-log-col-kind {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
table.data-table.activity-log-table .activity-log-col-route code {
|
||||||
|
display: inline-block;
|
||||||
|
max-width: 12rem;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
table.data-table.activity-log-table code {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
line-height: 1.45;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
table.data-table.activity-log-table .badge {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
.activity-log-changes-cell {
|
.activity-log-changes-cell {
|
||||||
min-width: 220px;
|
min-width: 220px;
|
||||||
max-width: 420px;
|
max-width: 420px;
|
||||||
vertical-align: top;
|
|
||||||
}
|
}
|
||||||
.activity-log-subject,
|
.activity-log-subject,
|
||||||
.activity-log-actor {
|
.activity-log-actor {
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
.activity-log-ip {
|
|
||||||
font-size: 0.8rem;
|
|
||||||
white-space: nowrap;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
.activity-log-ip code {
|
|
||||||
font-size: 0.78rem;
|
|
||||||
}
|
}
|
||||||
.activity-log-subject strong,
|
.activity-log-subject strong,
|
||||||
.activity-log-actor strong {
|
.activity-log-actor strong {
|
||||||
@ -360,6 +382,12 @@ code {
|
|||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
font-size: 0.78rem;
|
font-size: 0.78rem;
|
||||||
}
|
}
|
||||||
|
.activity-log-error {
|
||||||
|
margin-top: 6px;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: var(--danger);
|
||||||
|
line-height: 1.35;
|
||||||
|
}
|
||||||
.activity-change-raw {
|
.activity-change-raw {
|
||||||
font-size: 0.72rem;
|
font-size: 0.72rem;
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
@ -376,14 +404,17 @@ code {
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
padding: 2px 10px 2px 0;
|
padding: 3px 10px 3px 0;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
line-height: 1.45;
|
||||||
}
|
}
|
||||||
.activity-changes-table td {
|
.activity-changes-table td {
|
||||||
padding: 2px 0;
|
padding: 3px 0;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
|
vertical-align: top;
|
||||||
|
line-height: 1.45;
|
||||||
}
|
}
|
||||||
.activity-changes-table tr + tr th,
|
.activity-changes-table tr + tr th,
|
||||||
.activity-changes-table tr + tr td {
|
.activity-changes-table tr + tr td {
|
||||||
|
|||||||
@ -91,7 +91,6 @@ export function devPage() {
|
|||||||
<th>Subject</th>
|
<th>Subject</th>
|
||||||
<th>Method</th>
|
<th>Method</th>
|
||||||
<th>Route</th>
|
<th>Route</th>
|
||||||
<th>IP</th>
|
|
||||||
<th>Status</th>
|
<th>Status</th>
|
||||||
<th>Duration</th>
|
<th>Duration</th>
|
||||||
<th>Values</th>
|
<th>Values</th>
|
||||||
@ -99,7 +98,7 @@ export function devPage() {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="activityLogBody">
|
<tbody id="activityLogBody">
|
||||||
<tr><td colspan="10" style="text-align:center;color:var(--text-secondary);padding:20px">Loading…</td></tr>
|
<tr><td colspan="9" style="text-align:center;color:var(--text-secondary);padding:20px">Loading…</td></tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@ -297,7 +296,7 @@ async function loadActivityLog() {
|
|||||||
|
|
||||||
const date = document.getElementById('activityLogDate')?.value || new Date().toISOString().slice(0, 10);
|
const date = document.getElementById('activityLogDate')?.value || new Date().toISOString().slice(0, 10);
|
||||||
const activity = document.getElementById('activityLogKind')?.value || '';
|
const activity = document.getElementById('activityLogKind')?.value || '';
|
||||||
tbody.innerHTML = '<tr><td colspan="10" style="text-align:center;padding:20px">Loading…</td></tr>';
|
tbody.innerHTML = '<tr><td colspan="9" style="text-align:center;padding:20px">Loading…</td></tr>';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const q = new URLSearchParams({ date, limit: '300' });
|
const q = new URLSearchParams({ date, limit: '300' });
|
||||||
@ -317,7 +316,7 @@ async function loadActivityLog() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!entries.length) {
|
if (!entries.length) {
|
||||||
tbody.innerHTML = '<tr><td colspan="10" style="text-align:center;color:var(--text-secondary);padding:24px">No activity recorded</td></tr>';
|
tbody.innerHTML = '<tr><td colspan="9" style="text-align:center;color:var(--text-secondary);padding:24px">No activity recorded</td></tr>';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,26 +331,24 @@ async function loadActivityLog() {
|
|||||||
const dur = e.duration_ms != null ? `${e.duration_ms} ms` : '—';
|
const dur = e.duration_ms != null ? `${e.duration_ms} ms` : '—';
|
||||||
const subject = formatActivitySubject(e);
|
const subject = formatActivitySubject(e);
|
||||||
const performedBy = formatActivityPerformer(e);
|
const performedBy = formatActivityPerformer(e);
|
||||||
const ip = (e.ip && String(e.ip).trim()) ? String(e.ip).trim() : '—';
|
|
||||||
const errPart = e.error
|
const errPart = e.error
|
||||||
? `<div class="error-text" style="margin-top:6px;font-size:.8rem">${escHtml(e.error)}</div>`
|
? `<div class="activity-log-error">${escHtml(e.error)}</div>`
|
||||||
: '';
|
: '';
|
||||||
return `<tr>
|
return `<tr>
|
||||||
<td>${escHtml(time)}</td>
|
<td class="activity-log-col-time">${escHtml(time)}</td>
|
||||||
<td><span class="badge ${badgeClass}">${escHtml(label)}</span></td>
|
<td class="activity-log-col-kind"><span class="badge ${badgeClass}">${escHtml(label)}</span></td>
|
||||||
<td class="activity-log-subject">${subject}</td>
|
<td class="activity-log-subject">${subject}</td>
|
||||||
<td><code>${escHtml(e.method || '')}</code></td>
|
<td class="activity-log-col-meta"><code>${escHtml(e.method || '')}</code></td>
|
||||||
<td><code>${escHtml(e.route || '')}</code></td>
|
<td class="activity-log-col-route"><code>${escHtml(e.route || '')}</code></td>
|
||||||
<td class="activity-log-ip"><code>${escHtml(ip)}</code></td>
|
<td class="activity-log-col-meta ${statusClass}">${escHtml(status)}</td>
|
||||||
<td class="${statusClass}">${escHtml(status)}</td>
|
<td class="activity-log-col-meta">${escHtml(dur)}</td>
|
||||||
<td>${escHtml(dur)}</td>
|
|
||||||
<td class="activity-log-changes-cell">${renderActivityChanges(e.changes)}</td>
|
<td class="activity-log-changes-cell">${renderActivityChanges(e.changes)}</td>
|
||||||
<td class="activity-log-actor">${performedBy}${errPart}</td>
|
<td class="activity-log-actor">${performedBy}${errPart}</td>
|
||||||
</tr>`;
|
</tr>`;
|
||||||
}).join('');
|
}).join('');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (meta) meta.textContent = '';
|
if (meta) meta.textContent = '';
|
||||||
tbody.innerHTML = `<tr><td colspan="10" class="error-text" style="padding:16px">${escHtml(err.message)}</td></tr>`;
|
tbody.innerHTML = `<tr><td colspan="9" class="error-text" style="padding:16px">${escHtml(err.message)}</td></tr>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user