Files
Inventory/app/composables/useActivityLog.ts
Matthieu 635b8f0461 feat(activity-log) : add global activity log page with filters and pagination
New /activity-log page showing all audit entries across pieces, products
and composants. Includes entity type and action filters, expandable
diffs, clickable entity links and pagination. Navbar link added under
Ressources liées.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 08:54:12 +01:00

71 lines
2.0 KiB
TypeScript

import { ref } from 'vue'
import { useApi } from '~/composables/useApi'
export type ActivityLogActor = {
id: string
label: string
}
export type ActivityLogEntry = {
id: string
entityType: string
entityId: string
entityName: string | null
entityRef: string | null
action: 'create' | 'update' | 'delete' | string
createdAt: string
actor: ActivityLogActor | null
diff: Record<string, { from: unknown; to: unknown }> | null
snapshot: Record<string, unknown> | null
}
interface LoadActivityLogOptions {
page?: number
itemsPerPage?: number
entityType?: string
action?: string
}
export function useActivityLog() {
const { get } = useApi()
const entries = ref<ActivityLogEntry[]>([])
const total = ref(0)
const loading = ref(false)
const error = ref<string | null>(null)
const loadActivityLog = async (options: LoadActivityLogOptions = {}) => {
loading.value = true
error.value = null
try {
const params = new URLSearchParams()
params.set('page', String(options.page ?? 1))
params.set('itemsPerPage', String(options.itemsPerPage ?? 30))
if (options.entityType) params.set('entityType', options.entityType)
if (options.action) params.set('action', options.action)
const result = await get(`/activity-logs?${params.toString()}`)
if (!result.success) {
error.value = result.error ?? 'Impossible de charger le journal d\'activité.'
entries.value = []
return result
}
const data = result.data as any
entries.value = Array.isArray(data?.items) ? data.items : []
total.value = typeof data?.total === 'number' ? data.total : entries.value.length
return { success: true, data: entries.value }
} catch (err: any) {
const message = err?.message ?? 'Erreur inconnue'
error.value = message
entries.value = []
return { success: false, error: message }
} finally {
loading.value = false
}
}
return { entries, total, loading, error, loadActivityLog }
}