Iman_AMS/asm_app/src/hooks/useAuditLogs.ts

121 lines
3.3 KiB
TypeScript

import { useState, useCallback, useEffect } from 'react';
import apiService from '../services/apiService';
export interface VersionChange {
field: string;
oldValue: any;
newValue: any;
}
export interface AuditLogEntry {
name: string;
owner: string;
creation: string;
changes: VersionChange[];
added: any[];
removed: any[];
rowChanged: any[];
}
interface UseAuditLogsOptions {
doctype: string;
docname: string | null;
limit?: number;
enabled?: boolean;
}
interface UseAuditLogsReturn {
auditLogs: AuditLogEntry[];
loading: boolean;
error: string | null;
refetch: () => void;
}
export const useAuditLogs = ({
doctype,
docname,
limit = 50,
enabled = true,
}: UseAuditLogsOptions): UseAuditLogsReturn => {
const [auditLogs, setAuditLogs] = useState<AuditLogEntry[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const fetchAuditLogs = useCallback(async () => {
if (!enabled || !doctype || !docname) return;
setLoading(true);
setError(null);
try {
const response = await apiService.apiCall<any>(
`/api/resource/Version?filters=[["ref_doctype","=","${encodeURIComponent(doctype)}"],["docname","=","${encodeURIComponent(docname)}"]]&fields=["name","owner","creation","data"]&order_by=creation desc&limit=${limit}`
);
if (response?.data && response.data.length > 0) {
const parsedLogs: AuditLogEntry[] = response.data.map((version: any) => {
let parsedData: {
added: any[];
changed: any[];
removed: any[];
row_changed: any[];
} = { added: [], changed: [], removed: [], row_changed: [] };
try {
parsedData = JSON.parse(version.data || '{}');
} catch (e) {
console.error('Error parsing version data:', e);
}
let changes: VersionChange[] = [];
if (Array.isArray(parsedData.changed)) {
changes = parsedData.changed.map((change: any[]) => ({
field: change[0] || '',
oldValue: change[1],
newValue: change[2],
}));
} else if (parsedData.changed && typeof parsedData.changed === 'object') {
changes = Object.entries(parsedData.changed).map(([field, values]) => {
const [oldValue, newValue] = values as [any, any];
return { field, oldValue, newValue };
});
}
return {
name: version.name,
owner: version.owner,
creation: version.creation,
changes,
added: parsedData.added || [],
removed: parsedData.removed || [],
rowChanged: parsedData.row_changed || [],
};
});
setAuditLogs(parsedLogs);
} else {
setAuditLogs([]);
}
} catch (err) {
console.error(`Error fetching audit logs for ${doctype}/${docname}:`, err);
setError(err instanceof Error ? err.message : 'Failed to load activity log');
setAuditLogs([]);
} finally {
setLoading(false);
}
}, [doctype, docname, limit, enabled]);
useEffect(() => {
fetchAuditLogs();
}, [fetchAuditLogs]);
return {
auditLogs,
loading,
error,
refetch: fetchAuditLogs,
};
};
export default useAuditLogs;