mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-09-28 15:31:11 -04:00
119 lines
4.0 KiB
Vue
119 lines
4.0 KiB
Vue
<template>
|
|
<Page wide>
|
|
<NotFound v-if="!$isGranted('*')" />
|
|
<div v-else>
|
|
<p>
|
|
<nuxt-link to="/admin">
|
|
<Icon v="user-cog" />
|
|
<T>admin.header</T>
|
|
</nuxt-link>
|
|
</p>
|
|
<h2>
|
|
<Icon v="file-search" />
|
|
Audit log
|
|
<br>
|
|
<small class="text-muted">
|
|
(username: {{ username }}, id: {{ userId }})
|
|
</small>
|
|
</h2>
|
|
|
|
<div v-if="categories.size > 0" class="btn-group">
|
|
<button
|
|
v-for="category in categories"
|
|
:class="['btn', category === categoryFilter ? 'btn-primary' : 'btn-outline-primary']"
|
|
@click="categoryFilter = categoryFilter === category ? null : category"
|
|
>
|
|
{{ category }}
|
|
</button>
|
|
</div>
|
|
|
|
<div class="table-responsive mt-4">
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th>Event time</th>
|
|
<th>Username</th>
|
|
<th>User ID</th>
|
|
<th>Event</th>
|
|
<th>Payload</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr v-for="logEntry in visibleLogEntries">
|
|
<th>
|
|
{{ $datetime($ulidTime(logEntry.id)) }}
|
|
</th>
|
|
<td>
|
|
{{ logEntry.username }}
|
|
<template v-if="logEntry.username !== username">
|
|
<br>
|
|
<span class="badge bg-warning">Username mismatch</span>
|
|
</template>
|
|
</td>
|
|
<td>
|
|
{{ logEntry.userId }}
|
|
<template v-if="logEntry.userId !== userId">
|
|
<br>
|
|
<span class="badge bg-warning">ID mismatch</span>
|
|
</template>
|
|
</td>
|
|
<td>
|
|
<strong>{{ logEntry.event.split('/')[0] }}</strong>/{{ logEntry.event.split('/')[1] }}
|
|
</td>
|
|
<td>
|
|
<pre v-if="logEntry.payload">{{ JSON.stringify(JSON.parse(logEntry.payload), null, 4) }}</pre>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</Page>
|
|
</template>
|
|
|
|
<script>
|
|
import { useNuxtApp, useRoute, useFetch } from 'nuxt/app';
|
|
import useSimpleHead from '~/composables/useSimpleHead.ts';
|
|
|
|
export default {
|
|
async setup() {
|
|
const { $translator: translator } = useNuxtApp();
|
|
useSimpleHead({
|
|
title: `${translator.translate('admin.header')} • Audit log`,
|
|
}, translator);
|
|
|
|
const route = useRoute();
|
|
const { data: logEntries } = await useFetch(`/api/admin/audit-log/${route.params.username}/${route.params.id}`);
|
|
|
|
return {
|
|
username: route.params.username,
|
|
userId: route.params.id,
|
|
logEntries,
|
|
};
|
|
},
|
|
data() {
|
|
return {
|
|
categoryFilter: null,
|
|
};
|
|
},
|
|
computed: {
|
|
visibleLogEntries() {
|
|
return this.logEntries.filter((logEntry) => {
|
|
return this.categoryFilter === null || logEntry.event.startsWith(`${this.categoryFilter}/`);
|
|
});
|
|
},
|
|
categories() {
|
|
return new Set(this.logEntries.map((e) => e.event.split('/')[0]));
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
pre {
|
|
max-height: 300px;
|
|
max-width: 400px;
|
|
overflow: auto;
|
|
}
|
|
</style>
|