refactor: implement audit fetch trigger in OrganizationSettings to enhance data loading efficiency and improve filter responsiveness
This commit is contained in:
@@ -84,6 +84,7 @@ export default function OrganizationSettings() {
|
||||
const [auditTotal, setAuditTotal] = useState(0)
|
||||
const [isLoadingAudit, setIsLoadingAudit] = useState(false)
|
||||
const [auditPage, setAuditPage] = useState(0)
|
||||
const [auditFetchTrigger, setAuditFetchTrigger] = useState(0)
|
||||
const auditPageSize = 20
|
||||
const [auditActionFilter, setAuditActionFilter] = useState('')
|
||||
const [auditLogIdFilter, setAuditLogIdFilter] = useState('')
|
||||
@@ -213,16 +214,16 @@ export default function OrganizationSettings() {
|
||||
|
||||
const timer = setTimeout(() => {
|
||||
setAuditPage(0) // Reset page on filter change
|
||||
loadAudit()
|
||||
setAuditFetchTrigger(prev => prev + 1) // Trigger fetch
|
||||
}, 500)
|
||||
return () => clearTimeout(timer)
|
||||
}, [auditActionFilter, auditLogIdFilter, auditStartDate, auditEndDate, loadAudit])
|
||||
}, [auditActionFilter, auditLogIdFilter, auditStartDate, auditEndDate, activeTab])
|
||||
|
||||
useEffect(() => {
|
||||
if (activeTab === 'audit' && currentOrgId) {
|
||||
loadAudit()
|
||||
}
|
||||
}, [activeTab, currentOrgId, loadAudit])
|
||||
}, [activeTab, currentOrgId, loadAudit, auditFetchTrigger])
|
||||
|
||||
// If no org ID, we are in personal workspace, so don't show org settings
|
||||
if (!currentOrgId) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Audit log API client (org-scoped; requires org admin role)
|
||||
*/
|
||||
|
||||
import { API_URL } from './client'
|
||||
import apiRequest from './client'
|
||||
|
||||
export interface AuditLogEntry {
|
||||
id: string
|
||||
@@ -29,35 +29,6 @@ export interface GetAuditLogResponse {
|
||||
total: number
|
||||
}
|
||||
|
||||
async function auditFetch<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
|
||||
const url = `${API_URL}${endpoint}`
|
||||
|
||||
const headers: HeadersInit = {
|
||||
'Content-Type': 'application/json',
|
||||
...options.headers,
|
||||
}
|
||||
|
||||
const response = await fetch(url, {
|
||||
...options,
|
||||
headers,
|
||||
credentials: 'include',
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const errorBody = await response.json().catch(() => ({
|
||||
error: 'Unknown error',
|
||||
message: `HTTP ${response.status}: ${response.statusText}`,
|
||||
}))
|
||||
throw new Error(errorBody.message || errorBody.error || 'Request failed')
|
||||
}
|
||||
|
||||
return response.json()
|
||||
}
|
||||
|
||||
/**
|
||||
* 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> {
|
||||
const search = new URLSearchParams()
|
||||
if (params.limit != null) search.set('limit', String(params.limit))
|
||||
@@ -68,7 +39,7 @@ export async function getAuditLog(params: GetAuditLogParams = {}): Promise<GetAu
|
||||
if (params.end_date) search.set('end_date', params.end_date)
|
||||
const qs = search.toString()
|
||||
const url = qs ? `/api/audit?${qs}` : '/api/audit'
|
||||
const data = await auditFetch<GetAuditLogResponse>(url, { method: 'GET' })
|
||||
const data = await apiRequest<GetAuditLogResponse>(url, { method: 'GET' })
|
||||
return {
|
||||
entries: Array.isArray(data?.entries) ? data.entries : [],
|
||||
total: typeof data?.total === 'number' ? data.total : 0,
|
||||
|
||||
@@ -68,7 +68,11 @@ async function apiRequest<T>(
|
||||
// * Determine base URL
|
||||
const isAuthRequest = endpoint.startsWith('/auth')
|
||||
const baseUrl = isAuthRequest ? AUTH_API_URL : API_URL
|
||||
const url = `${baseUrl}/api/v1${endpoint}`
|
||||
|
||||
// * Handle legacy endpoints that already include /api/ prefix
|
||||
const url = endpoint.startsWith('/api/')
|
||||
? `${baseUrl}${endpoint}`
|
||||
: `${baseUrl}/api/v1${endpoint}`
|
||||
|
||||
const headers: HeadersInit = {
|
||||
'Content-Type': 'application/json',
|
||||
|
||||
Reference in New Issue
Block a user