feat: activity screen in the SPA, route /activity

This commit is contained in:
fsylvain committed 2026-10-07 01:48:21 +02:00
1 parent e37a46a027
commit 35db442cd3
47 files changed
+7582 -11

No files matched your search

+69
View File
@@ -0,0 +1,69 @@
import { useApi } from '@/composables/useApi'
import {
exportQuery,
listQuery,
summaryQuery,
type ActivityFilters,
type ActivityPage,
type ActivitySummary,
} from '@/lib/activity'
import type { UserListItem } from '@/composables/useUsers'
import type { ApiKey } from '@/composables/useApiKeys'
export interface PersonOptions {
users: { id: number; name: string }[]
keys: { id: number; name: string }[]
}
export const ACTIVITY_SKELETON_ROWS = 9
export const ACTIVITY_SKELETON_CARDS = 5
export const EXPORT_FILE_NAME = 'activity.csv'
export function useActivity() {
const { request, requestBlob } = useApi()
function listActivity(
filters: ActivityFilters,
page: number,
size: number,
withActor = true,
): Promise<ActivityPage> {
return request<ActivityPage>(`/v1/activity?${listQuery(filters, page, size, withActor)}`)
}
function getSummary(filters: ActivityFilters): Promise<ActivitySummary> {
return request<ActivitySummary>(`/v1/activity/summary?${summaryQuery(filters)}`)
}
function exportActivity(filters: ActivityFilters): Promise<Blob> {
return requestBlob(`/v1/activity/export?${exportQuery(filters)}`)
}
async function listPeople(): Promise<PersonOptions> {
const [users, keys] = await Promise.all([
request<UserListItem[]>('/v1/user/'),
request<ApiKey[]>('/v1/api-key/'),
])
return {
users: users.flatMap((item) =>
item.kind === 'user'
? [{ id: item.id, name: item.display_name || item.username }]
: [],
),
keys: keys.map((key) => ({ id: key.id, name: key.name })),
}
}
return { listActivity, getSummary, exportActivity, listPeople }
}
export function downloadBlob(blob: Blob, fileName: string) {
const url = URL.createObjectURL(blob)
const anchor = document.createElement('a')
anchor.href = url
anchor.download = fileName
document.body.appendChild(anchor)
anchor.click()
anchor.remove()
URL.revokeObjectURL(url)
}