Conversation
…filters and loading states for improved organization activity tracking
…ay and total is a number, improving data handling in OrganizationSettings
… ID and improving actor identification with email fallback
…ng filtering capabilities for improved data retrieval
… streamline audit log structure
…r improved clarity and consistency
Greptile OverviewGreptile SummaryAdded a comprehensive audit log feature to Organization Settings with filtering and pagination capabilities. The implementation uses a trigger-based approach to coordinate filter changes and pagination, ensuring proper data fetching without loops. All previously identified issues have been addressed:
The audit log displays actor, action, resource type, and timestamp for each entry with support for filtering by Log ID, action type, and date range. Confidence Score: 4/5
|
| Filename | Overview |
|---|---|
| components/settings/OrganizationSettings.tsx | Added audit log tab with filter UI and pagination; refactored state management using refs and trigger mechanism |
| lib/api/audit.ts | New API client for audit log with proper defensive handling of response data |
| lib/api/client.ts | Modified to support legacy /api/ endpoints alongside /api/v1 endpoints |
Sequence Diagram
sequenceDiagram
participant User
participant UI as OrganizationSettings
participant Filter as Filter State
participant Trigger as auditFetchTrigger
participant API as lib/api/audit
participant Client as lib/api/client
participant Backend as /api/audit
User->>UI: Navigate to Audit log tab
UI->>API: getAuditLog(params)
API->>Client: apiRequest('/api/audit?...')
Client->>Backend: GET /api/audit (with cookies)
Backend-->>Client: { entries: [...], total: N }
Client-->>API: Response data
API-->>UI: { entries, total }
UI->>UI: Display audit table
User->>Filter: Change filter (action/logId/date)
Filter->>Filter: Update filter state
Note over Filter: 500ms debounce timer
Filter->>Trigger: setAuditPage(0)
Filter->>Trigger: setAuditFetchTrigger(prev + 1)
Trigger->>UI: Trigger useEffect
UI->>API: getAuditLog(params with filters)
API->>Client: apiRequest('/api/audit?...')
Client->>Backend: GET /api/audit?action=X&log_id=Y (with cookies)
Backend-->>Client: Filtered results
Client-->>API: Response data
API-->>UI: { entries, total }
UI->>UI: Display filtered results
User->>UI: Click pagination (Next/Previous)
UI->>UI: setAuditPage(newPage)
UI->>API: getAuditLog(params with new offset)
API->>Client: apiRequest('/api/audit?offset=...')
Client->>Backend: GET /api/audit (with cookies)
alt Token expired (401)
Backend-->>Client: 401 Unauthorized
Client->>Client: Detect 401, start refresh
Client->>Backend: POST /api/auth/refresh (via /api/auth/refresh route)
Backend-->>Client: New tokens (HttpOnly cookies)
Client->>Backend: Retry GET /api/audit (with new cookies)
Backend-->>Client: { entries: [...], total: N }
else Token valid
Backend-->>Client: { entries: [...], total: N }
end
Client-->>API: Response data
API-->>UI: { entries, total }
UI->>UI: Display paginated results
User->>UI: Click Clear Filters
UI->>Filter: Reset all filters to ''
UI->>Trigger: setAuditPage(0)
UI->>Trigger: setAuditFetchTrigger(prev + 1)
Trigger->>UI: Trigger useEffect
UI->>API: getAuditLog(params without filters)
API->>Client: apiRequest('/api/audit')
Client->>Backend: GET /api/audit (with cookies)
Backend-->>Client: All entries (unfiltered)
Client-->>API: Response data
API-->>UI: { entries, total }
UI->>UI: Display all results
…ng refs to stabilize state updates and improve performance
Additional Comments (2)
Sidebar tab buttons call Also appears at: components/settings/OrganizationSettings.tsx:333-356 (members/billing/audit buttons). Prompt To Fix With AIThis is a comment left during a code review.
Path: components/settings/OrganizationSettings.tsx
Line: 321:323
Comment:
**URL tab state desync**
Sidebar tab buttons call `setActiveTab(...)` directly (e.g. `onClick={() => setActiveTab('general')}`), but nothing updates the `?tab=` query param. Since `activeTab` is initialized/synced from `useSearchParams()` (`components/settings/OrganizationSettings.tsx:44-47` and `:155-160`), the URL and UI can drift (refresh/back/forward can land on a different tab than the one last clicked). You likely want a single tab-change handler that updates both state and the URL, and use it for all tab buttons.
Also appears at: components/settings/OrganizationSettings.tsx:333-356 (members/billing/audit buttons).
How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix With AIThis is a comment left during a code review.
Path: components/settings/OrganizationSettings.tsx
Line: 169:176
Comment:
**Filter + pagination inconsistency**
`loadAudit()` computes `offset` from `auditPage` (`offset: auditPage * auditPageSize`). When a user changes filters while on a later page, `auditPage` is not reset to 0, so the request can legitimately return an empty page even though matching results exist on earlier pages. This will happen in normal use (e.g., go to page 3 then narrow `Action`). Consider resetting `auditPage` to 0 on any filter change (not just when clicking “Clear Filters”).
How can I resolve this? If you propose a fix, please make it concise. |
…hance data loading efficiency and improve filter responsiveness
…unnecessary useEffect for filters
Work Item
PULSE-13
Summary
Changes
OrganizationSettings.tsx: Added the Audit Log tab, data table, and filter grid logic.lib/api/audit.ts: Created API client for fetching and filtering audit logs.Test Plan
[ ] Navigate to Organization Settings -> Audit log.
[ ] Verify the table loads with recent events.
[ ] Test the "Log ID" filter with a known ID (e.g.,
8a2b3c).[ ] Test the "Action" filter (e.g.,
site_created) and Date Range inputs.[ ] Verify that pagination works correctly.