Files
My-KOPKB/fe/src/modules/activity-log/pages/ActivityLogList.vue
T
ismailmasseran d06c4701a4
Build Docker Image / build-backend (push) Successful in 1m56s
Build Docker Image / build-frontend (push) Successful in 1m55s
Dev/v1.2 (#4)
Co-authored-by: ISMAIL MASSERAN <topaz@Mac.dlinkrouter.local>
Reviewed-on: #4
2026-07-06 12:50:55 +08:00

106 lines
3.2 KiB
Vue

<script lang="ts" setup>
import dayjs from 'dayjs'
import { Search } from '@lucide/vue'
import { AlertRoot, AlertTitle, AlertDescription } from '@/components/ui/alert'
import { Input } from '@/components/ui/input'
import DataTable from '@/components/ui/usage/DataTable.vue'
import type { TableHeader } from '@/components/ui/usage/DataTable.vue'
import { useActivityLogList } from '../composables/useActivityLogList'
import { formatModelType } from '../utils/activity-log.utils'
const {
activityLogs,
loading,
error,
search,
page,
itemsPerPage,
pagination,
} = useActivityLogList()
function formatDateTime(value: string | null | undefined): string {
if (!value) return '-'
return dayjs(value).format('DD MMM YYYY, HH:mm')
}
function formatCauserName(item: { causer?: { name?: string } | null }): string {
return item.causer?.name ?? '-'
}
const headers: TableHeader[] = [
{ title: 'Bil.', key: '#', sortable: false },
{
title: 'Tarikh',
key: 'created_at',
sortable: false,
exportValue: (item) => formatDateTime(item.created_at),
},
{
title: 'Pengguna',
key: 'causer.name',
sortable: false,
exportValue: (item) => formatCauserName(item),
},
{
title: 'Emel',
key: 'causer.email',
sortable: false,
exportValue: (item) => item.causer?.email ?? '-',
},
{ title: 'Keterangan', key: 'description', sortable: false },
{
title: 'Subjek',
key: 'subject_type',
sortable: false,
exportValue: (item) => formatModelType(item.subject_type),
},
{ title: 'Peristiwa', key: 'event', sortable: false },
]
</script>
<template>
<div class="w-full space-y-6">
<div>
<h2 class="text-lg font-medium">Log Aktiviti</h2>
<p class="mt-1 text-sm opacity-70">Semak rekod aktiviti pengguna dalam sistem.</p>
</div>
<AlertRoot v-if="error" variant="danger">
<AlertTitle>Error</AlertTitle>
<AlertDescription>{{ error }}</AlertDescription>
</AlertRoot>
<DataTable :headers="headers" :items="activityLogs" :loading="loading" :pagination="pagination" show-pagination
exportable export-file-name="activity-logs" v-model:page="page" v-model:items-per-page="itemsPerPage">
<template #toolbar>
<div class="relative w-full max-w-md flex-1">
<Search class="pointer-events-none absolute top-1/2 left-3 z-10 size-4 -translate-y-1/2 text-foreground/50"
aria-hidden="true" />
<Input v-model="search" type="search" placeholder="Cari keterangan, subjek, peristiwa, pengguna..."
class="w-full pl-9" aria-label="Cari log aktiviti" />
</div>
</template>
<template #item.created_at="{ item }">
{{ formatDateTime(item.created_at) }}
</template>
<template #item.causer.name="{ item }">
{{ formatCauserName(item) }}
</template>
<template #item.causer.email="{ item }">
<span class="lowercase">{{ item.causer?.email ?? '-' }}</span>
</template>
<template #item.subject_type="{ item }">
{{ formatModelType(item.subject_type) }}
</template>
<template #item.event="{ item }">
{{ item.event ?? '-' }}
</template>
</DataTable>
</div>
</template>