140 lines
3.3 KiB
TypeScript
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();
|
|
};
|