Files
qlockify-frontend-deployment/src/api/logs.ts

140 lines
3.3 KiB
TypeScript

import { authFetch } from "./client";
export type WorkspaceLogSection =
| "workspace"
| "workspace_members"
| "clients"
| "projects"
| "tags"
| "time_entries"
| "rates"
| "report_exports";
export type WorkspaceLogEvent =
| "create"
| "update"
| "delete"
| "restore"
| "archive"
| "unarchive"
| "activate"
| "deactivate";
export interface WorkspaceLogActor {
id: string;
full_name: string;
mobile?: string | null;
profile_picture?: string | null;
}
export interface WorkspaceLogTarget {
id: string;
name: string;
section: WorkspaceLogSection;
workspace_id: string;
}
export interface WorkspaceLogPreviewChange {
field: string;
label: string;
summary: string;
}
export interface WorkspaceLogItem {
id: number;
timestamp: string;
section: WorkspaceLogSection;
model: string | null;
event: WorkspaceLogEvent;
audit_action: string;
actor: WorkspaceLogActor | null;
target: WorkspaceLogTarget;
changed_fields: string[];
preview_changes: WorkspaceLogPreviewChange[];
}
export interface WorkspaceLogChangeRow {
field: string;
label: string;
change_type: "field" | "m2m";
operation: string;
old_value: string | null;
new_value: string | null;
summary: string;
}
export interface WorkspaceLogDetail extends WorkspaceLogItem {
remote_addr?: string | null;
changes: WorkspaceLogChangeRow[];
raw_changes: Record<string, unknown>;
serialized_snapshot?: unknown;
additional_data: Record<string, unknown>;
}
export interface WorkspaceLogFilters {
workspace: string;
section?: WorkspaceLogSection | "";
actor?: string;
event?: WorkspaceLogEvent | "";
search?: string;
from?: string;
to?: string;
ordering?: "-timestamp" | "timestamp";
}
interface PaginatedResponse<T> {
count: number;
next: string | null;
previous: string | null;
results: T[];
}
const toQueryString = (params: Record<string, string | number | undefined>) => {
const query = new URLSearchParams();
Object.entries(params).forEach(([key, value]) => {
if (value !== undefined && value !== null && value !== "") {
query.set(key, String(value));
}
});
return query.toString();
};
export const listWorkspaceLogs = async (
filters: WorkspaceLogFilters,
pagination?: { limit?: number; offset?: number },
): Promise<PaginatedResponse<WorkspaceLogItem>> => {
const query = toQueryString({
workspace: filters.workspace,
section: filters.section || undefined,
actor: filters.actor || undefined,
event: filters.event || undefined,
search: filters.search || undefined,
from: filters.from || undefined,
to: filters.to || undefined,
ordering: filters.ordering || "-timestamp",
limit: pagination?.limit,
offset: pagination?.offset,
});
const response = await authFetch(`/api/logs/${query ? `?${query}` : ""}`);
if (!response.ok) {
throw new Error("Failed to fetch workspace logs.");
}
const data = await response.json();
return {
count: data.count || 0,
next: data.next || null,
previous: data.previous || null,
results: data.results || [],
};
};
export const getWorkspaceLogDetail = async (id: number): Promise<WorkspaceLogDetail> => {
const response = await authFetch(`/api/logs/${id}/`);
if (!response.ok) {
throw new Error("Failed to fetch workspace log detail.");
}
return await response.json();
};