Fit the audit-log table; drop the collector token preset button
Audit Logs now uses a fixed table layout with tuned column widths: every column fits the card without horizontal scrolling, long entity names truncate with a hover tooltip, timestamps show a compact no-seconds form (full value on hover), and the 9-digit user SSO renders fully. Removed the Collector service token quick-preset from the create modal per user preference - the collector.ingest checkbox in the scope grid is the path now. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -125,18 +125,6 @@
|
|||||||
<small class="form-hint">Leave blank for a token that never expires.</small>
|
<small class="form-hint">Leave blank for a token that never expires.</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="canCollectorPreset" class="form-group preset-group">
|
|
||||||
<button type="button" class="btn btn-secondary btn-sm"
|
|
||||||
@click="applyCollectorPreset">
|
|
||||||
Collector service token
|
|
||||||
</button>
|
|
||||||
<small class="form-hint">
|
|
||||||
For GE-Enforce / fleet reporting. Pre-selects only
|
|
||||||
<code>collector.ingest</code>; the token works only on the
|
|
||||||
collector API and nothing else.
|
|
||||||
</small>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="checkbox-label">
|
<label class="checkbox-label">
|
||||||
<input type="checkbox" v-model="form.restrict" />
|
<input type="checkbox" v-model="form.restrict" />
|
||||||
@@ -320,17 +308,6 @@ const availableGrouped = computed(() => {
|
|||||||
return result
|
return result
|
||||||
})
|
})
|
||||||
|
|
||||||
// The collector preset is offered only when the caller can actually mint a
|
|
||||||
// collector.ingest token (admins hold everything; others must hold the perm).
|
|
||||||
const COLLECTOR_SCOPE = 'collector.ingest'
|
|
||||||
const canCollectorPreset = computed(
|
|
||||||
() => isAdmin.value || myPermissions.value.includes(COLLECTOR_SCOPE))
|
|
||||||
|
|
||||||
function applyCollectorPreset() {
|
|
||||||
form.value.restrict = true
|
|
||||||
form.value.scopes = [COLLECTOR_SCOPE]
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => loadData())
|
onMounted(() => loadData())
|
||||||
|
|
||||||
async function loadData() {
|
async function loadData() {
|
||||||
@@ -522,17 +499,6 @@ async function revokeToken() {
|
|||||||
color: var(--text-light);
|
color: var(--text-light);
|
||||||
margin-top: 0.25rem;
|
margin-top: 0.25rem;
|
||||||
}
|
}
|
||||||
.preset-group {
|
|
||||||
padding: 0.5rem;
|
|
||||||
border: 1px solid var(--border);
|
|
||||||
border-radius: 4px;
|
|
||||||
background: var(--bg);
|
|
||||||
}
|
|
||||||
.preset-group code {
|
|
||||||
background: var(--bg-card);
|
|
||||||
padding: 0.1rem 0.3rem;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
.secret-warning {
|
.secret-warning {
|
||||||
color: var(--danger);
|
color: var(--danger);
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
|
|||||||
@@ -27,13 +27,13 @@
|
|||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="width: 160px">Timestamp</th>
|
<th style="width: 180px">Timestamp</th>
|
||||||
<th style="width: 100px">Action</th>
|
<th style="width: 90px">Action</th>
|
||||||
<th style="width: 100px">Entity</th>
|
<th style="width: 110px">Entity</th>
|
||||||
<th>Name/ID</th>
|
<th>Name/ID</th>
|
||||||
<th style="width: 120px">User</th>
|
<th style="width: 118px">User</th>
|
||||||
<th style="width: 130px">IP Address</th>
|
<th style="width: 108px">IP Address</th>
|
||||||
<th>Changes</th>
|
<th style="width: 80px">Changes</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -44,14 +44,14 @@
|
|||||||
<td colspan="7" class="empty">No audit logs found</td>
|
<td colspan="7" class="empty">No audit logs found</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-for="log in logs" :key="log.auditlogid">
|
<tr v-for="log in logs" :key="log.auditlogid">
|
||||||
<td class="timestamp">{{ formatDate(log.timestamp) }}</td>
|
<td class="timestamp" :title="formatDateFull(log.timestamp)">{{ formatDate(log.timestamp) }}</td>
|
||||||
<td>
|
<td>
|
||||||
<span class="badge" :class="actionClass(log.action)">
|
<span class="badge" :class="actionClass(log.action)">
|
||||||
{{ log.action }}
|
{{ log.action }}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td>{{ log.entitytype }}</td>
|
<td>{{ log.entitytype }}</td>
|
||||||
<td>
|
<td class="name-cell" :title="log.entityname || `#${log.entityid}`">
|
||||||
<router-link
|
<router-link
|
||||||
v-if="getEntityLink(log)"
|
v-if="getEntityLink(log)"
|
||||||
:to="getEntityLink(log)"
|
:to="getEntityLink(log)"
|
||||||
@@ -165,7 +165,16 @@ async function loadLogs() {
|
|||||||
function formatDate(isoString) {
|
function formatDate(isoString) {
|
||||||
if (!isoString) return '-'
|
if (!isoString) return '-'
|
||||||
const d = new Date(isoString)
|
const d = new Date(isoString)
|
||||||
return d.toLocaleString()
|
// compact for the fixed-width column; the cell title carries the full form
|
||||||
|
return d.toLocaleString(undefined, {
|
||||||
|
year: 'numeric', month: 'numeric', day: 'numeric',
|
||||||
|
hour: 'numeric', minute: '2-digit'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatDateFull(isoString) {
|
||||||
|
if (!isoString) return ''
|
||||||
|
return new Date(isoString).toLocaleString()
|
||||||
}
|
}
|
||||||
|
|
||||||
function actionClass(action) {
|
function actionClass(action) {
|
||||||
@@ -271,6 +280,19 @@ onMounted(loadLogs)
|
|||||||
background: var(--primary-dark);
|
background: var(--primary-dark);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.table-container > table {
|
||||||
|
table-layout: fixed;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.table-container > table td {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
.name-cell {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
.no-changes {
|
.no-changes {
|
||||||
color: var(--text-light);
|
color: var(--text-light);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user