111 lines
2.9 KiB
TypeScript

import { useState, useCallback, useEffect } from 'react';
import apiService from '../services/apiService';
// ============== INTERFACES ==============
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;
}
// ============== HOOK ==============
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: [], changed: [], removed: [], row_changed: [] };
try {
parsedData = JSON.parse(version.data || '{}');
} catch (e) {
console.error('Error parsing version data:', e);
}
const changes: VersionChange[] = (parsedData.changed || []).map((change: any[]) => ({
field: change[0] || '',
oldValue: change[1],
newValue: change[2],
}));
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]);
// Initial fetch
useEffect(() => {
fetchAuditLogs();
}, [fetchAuditLogs]);
return {
auditLogs,
loading,
error,
refetch: fetchAuditLogs,
};
};
export default useAuditLogs;