@@ -45,10 +45,37 @@ interface AuditLogFilters {
45
45
user_email ?: string ;
46
46
from_date ?: string ;
47
47
to_date ?: string ;
48
+ status_code ?: string [ ] ;
48
49
}
49
50
50
51
const ITEMS_PER_PAGE = 20 ;
51
52
53
+ const getStatusCodeDescription = ( code : number ) : string => {
54
+ const descriptions : Record < number , string > = {
55
+ 200 : 'OK' ,
56
+ 201 : 'Created' ,
57
+ 204 : 'No Content' ,
58
+ 301 : 'Moved Permanently' ,
59
+ 302 : 'Found' ,
60
+ 304 : 'Not Modified' ,
61
+ 307 : 'Temporary Redirect' ,
62
+ 308 : 'Permanent Redirect' ,
63
+ 400 : 'Bad Request' ,
64
+ 401 : 'Unauthorized' ,
65
+ 403 : 'Forbidden' ,
66
+ 404 : 'Not Found' ,
67
+ 405 : 'Method Not Allowed' ,
68
+ 409 : 'Conflict' ,
69
+ 422 : 'Unprocessable Entity' ,
70
+ 429 : 'Too Many Requests' ,
71
+ 500 : 'Internal Server Error' ,
72
+ 502 : 'Bad Gateway' ,
73
+ 503 : 'Service Unavailable' ,
74
+ 504 : 'Gateway Timeout' ,
75
+ } ;
76
+ return descriptions [ code ] || 'Unknown' ;
77
+ } ;
78
+
52
79
export default function AuditLogsPage ( ) {
53
80
const { toast } = useToast ( ) ;
54
81
const [ filters , setFilters ] = useState < AuditLogFilters > ( {
@@ -61,6 +88,7 @@ export default function AuditLogsPage() {
61
88
const [ itemsPerPage ] = useState < number > ( ITEMS_PER_PAGE ) ;
62
89
const [ eventTypeOptions , setEventTypeOptions ] = useState < { value : string ; label : string } [ ] > ( [ ] ) ;
63
90
const [ resourceTypeOptions , setResourceTypeOptions ] = useState < { value : string ; label : string } [ ] > ( [ ] ) ;
91
+ const [ statusCodeOptions , setStatusCodeOptions ] = useState < { value : string ; label : string } [ ] > ( [ ] ) ;
64
92
65
93
const fetchMetadata = useCallback ( async ( ) => {
66
94
try {
@@ -85,6 +113,15 @@ export default function AuditLogsPage() {
85
113
label : type . charAt ( 0 ) . toUpperCase ( ) + type . slice ( 1 ) . toLowerCase ( ) ,
86
114
} ) )
87
115
) ;
116
+
117
+ setStatusCodeOptions (
118
+ ( data . status_codes || [ ] )
119
+ . filter ( Boolean )
120
+ . map ( ( code : string ) => ( {
121
+ value : code ,
122
+ label : `${ code } - ${ getStatusCodeDescription ( parseInt ( code ) ) } ` ,
123
+ } ) )
124
+ ) ;
88
125
} catch ( error ) {
89
126
console . error ( 'Error fetching audit logs metadata:' , error ) ;
90
127
toast ( {
@@ -107,6 +144,7 @@ export default function AuditLogsPage() {
107
144
...( filters . event_type ?. length && { event_type : filters . event_type . join ( ',' ) } ) ,
108
145
...( filters . resource_type ?. length && { resource_type : filters . resource_type . join ( ',' ) } ) ,
109
146
...( filters . user_email && { user_email : filters . user_email } ) ,
147
+ ...( filters . status_code ?. length && { status_code : filters . status_code . join ( ',' ) } ) ,
110
148
} ) . toString ( ) ;
111
149
112
150
const response = await get ( `audit/logs?${ queryParams } ` , { credentials : 'include' } ) ;
@@ -179,7 +217,7 @@ export default function AuditLogsPage() {
179
217
< CardTitle > Filters</ CardTitle >
180
218
</ CardHeader >
181
219
< CardContent >
182
- < div className = "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-4" >
220
+ < div className = "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-6 gap-4" >
183
221
< div className = "space-y-2" >
184
222
< label className = "text-sm font-medium" > Event Type</ label >
185
223
< MultiSelect
@@ -197,6 +235,18 @@ export default function AuditLogsPage() {
197
235
onValueChange = { ( value ) => handleFilterChange ( 'resource_type' , value ) }
198
236
defaultValue = { filters . resource_type || [ ] }
199
237
placeholder = "Select Resources"
238
+ variant = "default"
239
+ />
240
+ </ div >
241
+
242
+ < div className = "space-y-2" >
243
+ < label className = "text-sm font-medium" > Status Code</ label >
244
+ < MultiSelect
245
+ options = { statusCodeOptions }
246
+ onValueChange = { ( value ) => handleFilterChange ( 'status_code' , value ) }
247
+ defaultValue = { filters . status_code || [ ] }
248
+ placeholder = "Select Status Codes"
249
+ variant = "default"
200
250
/>
201
251
</ div >
202
252
0 commit comments