1- import React , { useState , useMemo , useEffect } from 'react' ;
1+ import React , { useState , useMemo } from 'react' ;
22import { useTranslation } from 'react-i18next' ;
33import {
44 DataTable ,
@@ -16,16 +16,15 @@ import {
1616 Button ,
1717 DatePicker ,
1818 DatePickerInput ,
19- Tile ,
2019 Pagination ,
20+ Select ,
21+ SelectItem ,
2122} from '@carbon/react' ;
2223import {
2324 ErrorState ,
24- useLayoutType ,
2525 usePagination ,
2626} from '@openmrs/esm-framework' ;
2727import {
28- Renew ,
2928 Checkmark ,
3029 Warning ,
3130 Time ,
@@ -38,8 +37,6 @@ import styles from './sync-logs.scss';
3837const SyncLogsContent : React . FC = ( ) => {
3938 const { t } = useTranslation ( ) ;
4039 const { logs, isLoading, isError } = useSyncLogs ( ) ;
41- const isTablet = useLayoutType ( ) === 'tablet' ;
42- const responsiveSize = isTablet ? 'lg' : 'sm' ;
4340
4441 const [ searchQuery , setSearchQuery ] = useState ( '' ) ;
4542 const [ selectedSyncType , setSelectedSyncType ] = useState ( '' ) ;
@@ -51,6 +48,17 @@ const SyncLogsContent: React.FC = () => {
5148 const pageSizes = [ 10 , 20 , 30 , 40 , 50 ] ;
5249 const [ currentPageSize , setPageSize ] = useState ( 10 ) ;
5350
51+ // Extract unique sync task types for the filter dropdown
52+ const syncTaskTypes = useMemo ( ( ) => {
53+ const types = new Set < string > ( ) ;
54+ logs . forEach ( ( log ) => {
55+ if ( log . syncTaskType ?. name ) {
56+ types . add ( log . syncTaskType . name ) ;
57+ }
58+ } ) ;
59+ return Array . from ( types ) . sort ( ) ;
60+ } , [ logs ] ) ;
61+
5462 const filteredLogs = useMemo ( ( ) => {
5563 return logs . filter ( ( log ) => {
5664 const matchesSearch =
@@ -91,8 +99,6 @@ const SyncLogsContent: React.FC = () => {
9199 return < Checkmark size = { 16 } className = { styles . statusSuccess } /> ;
92100 case 'failed' :
93101 return < Warning size = { 16 } className = { styles . statusFailed } /> ;
94- case 'in_progress' :
95- return < Renew size = { 16 } className = { styles . statusInProgress } /> ;
96102 default :
97103 return < Time size = { 16 } className = { styles . statusPending } /> ;
98104 }
@@ -133,13 +139,26 @@ const SyncLogsContent: React.FC = () => {
133139 [ t ]
134140 ) ;
135141
142+ const getStatusClass = ( status ?: string ) => {
143+ switch ( status ) {
144+ case 'success' :
145+ return styles . statusSuccess ;
146+ case 'failed' :
147+ return styles . statusFailed ;
148+ case 'in_progress' :
149+ return styles . statusInProgress ;
150+ default :
151+ return styles . statusPending ;
152+ }
153+ } ;
154+
136155 const tableRows = useMemo (
137156 ( ) =>
138157 paginatedList . map ( ( log : SyncTaskLog , index : number ) => ( {
139158 id : log . uuid || String ( index ) ,
140159 syncTaskType : log . syncTaskType ?. name || '-' ,
141160 status : (
142- < div className = { `${ styles . statusIndicator } ${ styles [ 'status_' + log . status ] } ` } >
161+ < div className = { `${ styles . statusIndicator } ${ getStatusClass ( log . status ) } ` } >
143162 { getStatusIcon ( log . status ) }
144163 < span > { t ( log . status || 'unknown' , log . status || 'Unknown' ) } </ span >
145164 </ div >
@@ -176,13 +195,8 @@ const SyncLogsContent: React.FC = () => {
176195 </ p >
177196 </ div >
178197 ) : (
179- < DataTable
180- rows = { tableRows }
181- headers = { tableHeaders }
182- size = { isTablet ? 'lg' : 'sm' }
183- useZebraStyles
184- >
185- { ( { rows, headers, getTableProps, getHeaderProps } ) => (
198+ < DataTable rows = { tableRows } headers = { tableHeaders } >
199+ { ( { rows, headers, getTableProps, getHeaderProps, getRowProps } ) => (
186200 < TableContainer className = { styles . syncTable } >
187201 < TableToolbar >
188202 < TableToolbarContent className = { styles . toolbarContent } >
@@ -191,6 +205,22 @@ const SyncLogsContent: React.FC = () => {
191205 onChange = { ( event ) => setSearchQuery ( event ? event . toString ( ) : '' ) }
192206 placeholder = { t ( 'searchLogs' , 'Search logs...' ) }
193207 />
208+ < Select
209+ id = "sync-task-type-filter"
210+ labelText = ""
211+ defaultValue = ""
212+ onChange = { ( event ) => setSelectedSyncType ( event . target . value ) }
213+ className = { styles . syncTypeFilter }
214+ >
215+ < SelectItem value = "" text = { t ( 'allTaskTypes' , 'All Task Types' ) } >
216+ { t ( 'allTaskTypes' , 'All Task Types' ) }
217+ </ SelectItem >
218+ { syncTaskTypes . map ( ( type ) => (
219+ < SelectItem key = { type } value = { type } text = { type } >
220+ { type }
221+ </ SelectItem >
222+ ) ) }
223+ </ Select >
194224 < div className = { styles . datePicker } >
195225 < DatePicker
196226 datePickerType = "range"
@@ -238,28 +268,14 @@ const SyncLogsContent: React.FC = () => {
238268 </ TableHead >
239269 < TableBody >
240270 { rows . map ( ( row ) => (
241- < TableRow key = { row . id } >
271+ < TableRow { ... getRowProps ( { row } ) } >
242272 { row . cells . map ( ( cell ) => (
243273 < TableCell key = { cell . id } > { cell . value } </ TableCell >
244274 ) ) }
245275 </ TableRow >
246276 ) ) }
247277 </ TableBody >
248278 </ Table >
249- { rows . length === 0 ? (
250- < div className = { styles . tileContainer } >
251- < Tile className = { styles . tile } >
252- < div className = { styles . tileContent } >
253- < p className = { styles . content } >
254- { t ( 'noLogsToDisplay' , 'No logs to display' ) }
255- </ p >
256- < p className = { styles . helper } >
257- { t ( 'checkFilter' , 'Check the filter above' ) }
258- </ p >
259- </ div >
260- </ Tile >
261- </ div >
262- ) : null }
263279 < Pagination
264280 forwardText = "Next page"
265281 backwardText = "Previous page"
0 commit comments