fix: normalize audit log response to ensure entries are always an array and total is a number, improving data handling in OrganizationSettings
This commit is contained in:
@@ -177,8 +177,8 @@ export default function OrganizationSettings() {
|
|||||||
if (auditStartDate) params.start_date = auditStartDate
|
if (auditStartDate) params.start_date = auditStartDate
|
||||||
if (auditEndDate) params.end_date = auditEndDate
|
if (auditEndDate) params.end_date = auditEndDate
|
||||||
const { entries, total } = await getAuditLog(params)
|
const { entries, total } = await getAuditLog(params)
|
||||||
setAuditEntries(entries)
|
setAuditEntries(Array.isArray(entries) ? entries : [])
|
||||||
setAuditTotal(total)
|
setAuditTotal(typeof total === 'number' ? total : 0)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to load audit log', error)
|
console.error('Failed to load audit log', error)
|
||||||
toast.error(getAuthErrorMessage(error as Error) || 'Failed to load audit log')
|
toast.error(getAuthErrorMessage(error as Error) || 'Failed to load audit log')
|
||||||
@@ -842,7 +842,7 @@ export default function OrganizationSettings() {
|
|||||||
<div className="animate-spin w-6 h-6 border-2 border-neutral-400 border-t-transparent rounded-full mx-auto mb-3"></div>
|
<div className="animate-spin w-6 h-6 border-2 border-neutral-400 border-t-transparent rounded-full mx-auto mb-3"></div>
|
||||||
Loading audit log...
|
Loading audit log...
|
||||||
</div>
|
</div>
|
||||||
) : auditEntries.length === 0 ? (
|
) : (auditEntries ?? []).length === 0 ? (
|
||||||
<div className="p-8 text-center text-neutral-500">No audit events found.</div>
|
<div className="p-8 text-center text-neutral-500">No audit events found.</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="overflow-x-auto">
|
<div className="overflow-x-auto">
|
||||||
@@ -857,7 +857,7 @@ export default function OrganizationSettings() {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{auditEntries.map((entry) => (
|
{(auditEntries ?? []).map((entry) => (
|
||||||
<tr key={entry.id} className="border-b border-neutral-100 dark:border-neutral-800 hover:bg-neutral-50 dark:hover:bg-neutral-800/30">
|
<tr key={entry.id} className="border-b border-neutral-100 dark:border-neutral-800 hover:bg-neutral-50 dark:hover:bg-neutral-800/30">
|
||||||
<td className="px-4 py-3 text-neutral-600 dark:text-neutral-400 whitespace-nowrap">
|
<td className="px-4 py-3 text-neutral-600 dark:text-neutral-400 whitespace-nowrap">
|
||||||
{new Date(entry.occurred_at).toLocaleString()}
|
{new Date(entry.occurred_at).toLocaleString()}
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ async function auditFetch<T>(endpoint: string, options: RequestInit = {}): Promi
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches paginated audit log entries for the current org (org from JWT; admin-only on backend).
|
* Fetches paginated audit log entries for the current org (org from JWT; admin-only on backend).
|
||||||
|
* Normalizes response so entries is always an array (backend may return null when empty).
|
||||||
*/
|
*/
|
||||||
export async function getAuditLog(params: GetAuditLogParams = {}): Promise<GetAuditLogResponse> {
|
export async function getAuditLog(params: GetAuditLogParams = {}): Promise<GetAuditLogResponse> {
|
||||||
const search = new URLSearchParams()
|
const search = new URLSearchParams()
|
||||||
@@ -65,5 +66,9 @@ export async function getAuditLog(params: GetAuditLogParams = {}): Promise<GetAu
|
|||||||
if (params.end_date) search.set('end_date', params.end_date)
|
if (params.end_date) search.set('end_date', params.end_date)
|
||||||
const qs = search.toString()
|
const qs = search.toString()
|
||||||
const url = qs ? `/api/audit?${qs}` : '/api/audit'
|
const url = qs ? `/api/audit?${qs}` : '/api/audit'
|
||||||
return await auditFetch<GetAuditLogResponse>(url, { method: 'GET' })
|
const data = await auditFetch<GetAuditLogResponse>(url, { method: 'GET' })
|
||||||
|
return {
|
||||||
|
entries: Array.isArray(data?.entries) ? data.entries : [],
|
||||||
|
total: typeof data?.total === 'number' ? data.total : 0,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user