Implement routes and transitions

This commit is contained in:
2025-07-14 12:08:09 +02:00
parent 736dad748b
commit 5ac4c987d3
27 changed files with 860 additions and 376 deletions

View File

@ -1,182 +1,190 @@
<template>
<table v-if="auditEntries" class="min-w-full divide-y divide-gray-200 dark:divide-gray-600">
<thead class="bg-gray-50 dark:bg-gray-700">
<tr>
<th
scope="col"
class="p-4 text-xs font-medium tracking-wider text-left text-gray-500 uppercase dark:text-white"
>
&nbsp;
</th>
<th
scope="col"
class="p-4 text-xs font-medium tracking-wider text-left text-gray-500 uppercase dark:text-white"
>
Timestamp
</th>
<th
scope="col"
class="p-4 text-xs font-medium tracking-wider text-left text-gray-500 uppercase dark:text-white"
>
Subsystem
</th>
<th
scope="col"
class="p-4 text-xs font-medium tracking-wider text-left text-gray-500 uppercase dark:text-white"
>
Operation
</th>
<th
scope="col"
class="p-4 text-xs font-medium tracking-wider text-left text-gray-500 uppercase dark:text-white"
>
Client
</th>
<th
scope="col"
class="p-4 text-xs font-medium tracking-wider text-left text-gray-500 uppercase dark:text-white"
>
Secret
</th>
<th
scope="col"
class="p-4 text-xs font-medium tracking-wider text-left text-gray-500 uppercase dark:text-white"
>
Message
</th>
<th
scope="col"
class="p-4 text-xs font-medium tracking-wider text-left text-gray-500 uppercase dark:text-white"
>
Origin
</th>
</tr>
</thead>
<tbody class="bg-white dark:bg-gray-800">
<template v-for="entry in auditEntries" :key="entry.id">
<tr class="auditRow hover:bg-gray-100 dark:hover:bg-gray-700">
<td>
<sl-icon-button
name="chevron-right"
@click="toggle(entry.id)"
:class="{ 'rotate-90': isExpanded(entry.id) }"
></sl-icon-button>
</td>
<td class="p-4 text-sm font-normal text-gray-900 whitespace-nowrap dark:text-white">
{{ entry.timestamp }}
</td>
<td class="p-4 text-sm font-normal text-gray-900 whitespace-nowrap dark:text-white">
{{ entry.subsystem }}
</td>
<td class="p-4 text-sm font-normal text-gray-900 whitespace-nowrap dark:text-white">
{{ entry.operation }}
</td>
<td class="p-4 text-sm font-normal text-gray-900 whitespace-nowrap dark:text-white">
<abbr :title="entry.client_id" v-if="entry.client_name">{{ entry.client_name }}</abbr>
</td>
<td class="p-4 text-sm font-normal text-gray-900 whitespace-nowrap dark:text-white">
<abbr :title="entry.secret_id" v-if="entry.secret_name">{{ entry.secret_name }}</abbr>
</td>
<td class="p-4 text-sm font-normal text-gray-500 whitespace-nowrap dark:text-gray-400">
{{ entry.message }}
</td>
<td class="p-4 text-sm font-normal text-gray-500 whitespace-nowrap dark:text-gray-400">
{{ entry.origin }}
</td>
<template v-if="auditEntries">
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-600">
<thead class="bg-gray-50 dark:bg-gray-700">
<tr>
<th
scope="col"
class="p-4 text-xs font-medium tracking-wider text-left text-gray-500 uppercase dark:text-white"
>
&nbsp;
</th>
<th
scope="col"
class="p-4 text-xs font-medium tracking-wider text-left text-gray-500 uppercase dark:text-white"
>
Timestamp
</th>
<th
scope="col"
class="p-4 text-xs font-medium tracking-wider text-left text-gray-500 uppercase dark:text-white"
>
Subsystem
</th>
<th
scope="col"
class="p-4 text-xs font-medium tracking-wider text-left text-gray-500 uppercase dark:text-white"
>
Operation
</th>
<th
scope="col"
class="p-4 text-xs font-medium tracking-wider text-left text-gray-500 uppercase dark:text-white"
>
Client
</th>
<th
scope="col"
class="p-4 text-xs font-medium tracking-wider text-left text-gray-500 uppercase dark:text-white"
>
Secret
</th>
<th
scope="col"
class="p-4 text-xs font-medium tracking-wider text-left text-gray-500 uppercase dark:text-white"
>
Message
</th>
<th
scope="col"
class="p-4 text-xs font-medium tracking-wider text-left text-gray-500 uppercase dark:text-white"
>
Origin
</th>
</tr>
<tr v-if="isExpanded(entry.id)" class="auditRow">
<td></td>
<td colspan="8">
<dl
class="max-w-md text-gray-900 divide-y divide-gray-200 dark:text-white dark:divide-gray-700 px-2 py-2"
>
<div class="flex flex-col pb-3">
<dt class="mb-1 text-gray-500 md:text-xs dark:text-gray-400">ID</dt>
<dd class="text-xs font-semibold">{{ entry.id }}</dd>
</div>
<div class="flex flex-col pb-3">
<dt class="mb-1 text-gray-500 md:text-xs dark:text-gray-400">Subsystem</dt>
<dd class="text-xs font-semibold">{{ entry.subsystem }}</dd>
</div>
<div class="flex flex-col pb-3">
<dt class="mb-1 text-gray-500 md:text-xs dark:text-gray-400">Timestamp</dt>
<dd class="text-xs font-semibold">{{ entry.timestamp }}</dd>
</div>
<div class="flex flex-col pb-3">
<dt class="mb-1 text-gray-500 md:text-xs dark:text-gray-400">Operation</dt>
<dd class="text-xs font-semibold">{{ entry.operation }}</dd>
</div>
<div class="flex flex-col pb-3">
<dt class="mb-1 text-gray-500 md:text-xs dark:text-gray-400">Client ID</dt>
<dd class="text-xs font-semibold">{{ entry.client_id }}</dd>
</div>
<div class="flex flex-col pb-3">
<dt class="mb-1 text-gray-500 md:text-xs dark:text-gray-400">Client Name</dt>
<dd class="text-xs font-semibold">{{ entry.client_name }}</dd>
</div>
<div class="flex flex-col pb-3">
<dt class="mb-1 text-gray-500 md:text-xs dark:text-gray-400">Secret ID</dt>
<dd class="text-xs font-semibold">{{ entry.secret_id }}</dd>
</div>
<div class="flex flex-col pb-3">
<dt class="mb-1 text-gray-500 md:text-xs dark:text-gray-400">Secret Name</dt>
<dd class="text-xs font-semibold">{{ entry.secret_name }}</dd>
</div>
<div class="flex flex-col pb-3">
<dt class="mb-1 text-gray-500 md:text-xs dark:text-gray-400">Message</dt>
<dd class="text-xs font-semibold">{{ entry.message }}</dd>
</div>
<div class="flex flex-col pb-3">
<dt class="mb-1 text-gray-500 md:text-xs dark:text-gray-400">Origin</dt>
<dd class="text-xs font-semibold">{{ entry.origin }}</dd>
</div>
<template v-if="entry.data">
<template v-for="(value, key) in entry.data">
<div class="flex flex-col pb-3">
<dt class="mb-1 text-gray-500 md:text-xs dark:text-gray-400">{{ key }}</dt>
<dd class="text-xs font-semibold">{{ value }}</dd>
</div>
</thead>
<tbody class="bg-white dark:bg-gray-800">
<template v-for="entry in auditEntries" :key="entry.id">
<tr class="auditRow hover:bg-gray-100 dark:hover:bg-gray-700">
<td>
<sl-icon-button
name="chevron-right"
@click="toggle(entry.id)"
:class="{ 'rotate-90': isExpanded(entry.id) }"
></sl-icon-button>
</td>
<td class="p-4 text-sm font-normal text-gray-900 whitespace-nowrap dark:text-white">
{{ entry.timestamp }}
</td>
<td class="p-4 text-sm font-normal text-gray-900 whitespace-nowrap dark:text-white">
{{ entry.subsystem }}
</td>
<td class="p-4 text-sm font-normal text-gray-900 whitespace-nowrap dark:text-white">
{{ entry.operation }}
</td>
<td class="p-4 text-sm font-normal text-gray-900 whitespace-nowrap dark:text-white">
<abbr :title="entry.client_id" v-if="entry.client_name">{{ entry.client_name }}</abbr>
</td>
<td class="p-4 text-sm font-normal text-gray-900 whitespace-nowrap dark:text-white">
<abbr :title="entry.secret_id" v-if="entry.secret_name">{{ entry.secret_name }}</abbr>
</td>
<td class="p-4 text-sm font-normal text-gray-500 whitespace-nowrap dark:text-gray-400">
{{ entry.message }}
</td>
<td class="p-4 text-sm font-normal text-gray-500 whitespace-nowrap dark:text-gray-400">
{{ entry.origin }}
</td>
</tr>
<tr v-if="isExpanded(entry.id)" class="auditRow">
<td></td>
<td colspan="8">
<dl
class="max-w-md text-gray-900 divide-y divide-gray-200 dark:text-white dark:divide-gray-700 px-2 py-2"
>
<div class="flex flex-col pb-3">
<dt class="mb-1 text-gray-500 md:text-xs dark:text-gray-400">ID</dt>
<dd class="text-xs font-semibold">{{ entry.id }}</dd>
</div>
<div class="flex flex-col pb-3">
<dt class="mb-1 text-gray-500 md:text-xs dark:text-gray-400">Subsystem</dt>
<dd class="text-xs font-semibold">{{ entry.subsystem }}</dd>
</div>
<div class="flex flex-col pb-3">
<dt class="mb-1 text-gray-500 md:text-xs dark:text-gray-400">Timestamp</dt>
<dd class="text-xs font-semibold">{{ entry.timestamp }}</dd>
</div>
<div class="flex flex-col pb-3">
<dt class="mb-1 text-gray-500 md:text-xs dark:text-gray-400">Operation</dt>
<dd class="text-xs font-semibold">{{ entry.operation }}</dd>
</div>
<div class="flex flex-col pb-3">
<dt class="mb-1 text-gray-500 md:text-xs dark:text-gray-400">Client ID</dt>
<dd class="text-xs font-semibold">{{ entry.client_id }}</dd>
</div>
<div class="flex flex-col pb-3">
<dt class="mb-1 text-gray-500 md:text-xs dark:text-gray-400">Client Name</dt>
<dd class="text-xs font-semibold">{{ entry.client_name }}</dd>
</div>
<div class="flex flex-col pb-3">
<dt class="mb-1 text-gray-500 md:text-xs dark:text-gray-400">Secret ID</dt>
<dd class="text-xs font-semibold">{{ entry.secret_id }}</dd>
</div>
<div class="flex flex-col pb-3">
<dt class="mb-1 text-gray-500 md:text-xs dark:text-gray-400">Secret Name</dt>
<dd class="text-xs font-semibold">{{ entry.secret_name }}</dd>
</div>
<div class="flex flex-col pb-3">
<dt class="mb-1 text-gray-500 md:text-xs dark:text-gray-400">Message</dt>
<dd class="text-xs font-semibold">{{ entry.message }}</dd>
</div>
<div class="flex flex-col pb-3">
<dt class="mb-1 text-gray-500 md:text-xs dark:text-gray-400">Origin</dt>
<dd class="text-xs font-semibold">{{ entry.origin }}</dd>
</div>
<template v-if="entry.data">
<template v-for="(value, key) in entry.data">
<div class="flex flex-col pb-3">
<dt class="mb-1 text-gray-500 md:text-xs dark:text-gray-400">{{ key }}</dt>
<dd class="text-xs font-semibold">{{ value }}</dd>
</div>
</template>
</template>
</template>
</dl>
</td>
</tr>
</template>
</tbody>
</table>
<div
class="sticky bottom-0 right-0 items-center w-full p-4 bg-white border-t border-gray-200 sm:flex sm:justify-between dark:bg-gray-800 dark:border-gray-700"
v-if="totalPages > 0"
>
<div class="flex items-center mb-4 sm:mb-0">
<span class="text-sm font-normal text-gray-500 dark:text-gray-400">
Showing
<span class="font-semibold text-gray-900 dark:text-white" v-if="totalEntries < lastResult">
{{ firstResult }}-{{ TotalEntries }}
</dl>
</td>
</tr>
</template>
</tbody>
</table>
<div
class="sticky bottom-0 right-0 items-center w-full p-4 bg-white border-t border-gray-200 sm:flex sm:justify-between dark:bg-gray-800 dark:border-gray-700"
v-if="totalPages > 0"
>
<div class="flex items-center mb-4 sm:mb-0">
<span class="text-sm font-normal text-gray-500 dark:text-gray-400">
Showing
<span
class="font-semibold text-gray-900 dark:text-white"
v-if="totalEntries < lastResult"
>
{{ firstResult }}-{{ TotalEntries }}
</span>
<span class="font-semibold text-gray-900 dark:text-white" v-else>
{{ firstResult }}-{{ lastResult }}
</span>
of
<span class="font-semibold text-gray-900 dark:text-white">
{{ totalEntries }}
</span>
</span>
<span class="font-semibold text-gray-900 dark:text-white" v-else>
{{ firstResult }}-{{ lastResult }}
</span>
of
<span class="font-semibold text-gray-900 dark:text-white">
{{ totalEntries }}
</span>
</span>
</div>
<div class="flex items-center space-x-3">
<div class="flex space-x-1">
<PageNumbers
@next="nextPage"
@previous="prevPage"
@goto="goToPage"
:pageNum="pageNum"
:totalPages="totalPages"
/>
</div>
<div class="flex items-center space-x-3">
<div class="flex space-x-1">
<PageNumbers
@next="nextPage"
@previous="prevPage"
@goto="goToPage"
:pageNum="pageNum"
:totalPages="totalPages"
/>
</div>
</div>
</div>
</div>
</template>
<template v-else>
<AuditSkeleton />
</template>
</template>
<script setup lang="ts">
import { computed, ref, reactive, onMounted, watch, toRef } from 'vue'
@ -186,6 +194,7 @@ import { SshecretAdmin, GetAuditLogApiV1AuditGetData } from '@/client'
import type { AuditListResult } from '@/client'
import type { AuditFilter } from '@/api/types'
import PageNumbers from '@/components/common/PageNumbers.vue'
import AuditSkeleton from '@/components/audit/AuditSkeleton.vue'
const props = defineProps<{ auditFilter: AuditFilter }>()