@@ -9,49 +9,18 @@ import DataTable, {
9
9
TableCell ,
10
10
TableToolbar ,
11
11
TableToolbarContent ,
12
+ TableExpandRow ,
13
+ TableExpandHeader ,
12
14
} from 'carbon-components-react/es/components/DataTable' ;
13
15
import DataTableSkeleton from 'carbon-components-react/es/components/DataTableSkeleton' ;
14
16
import Pagination from 'carbon-components-react/es/components/Pagination' ;
15
17
import Search from 'carbon-components-react/es/components/Search' ;
18
+ import { useLayoutType , useConfig , usePagination , ConfigurableLink , ExtensionSlot } from '@openmrs/esm-framework' ;
16
19
import { useTranslation } from 'react-i18next' ;
17
- import { useLayoutType , useConfig , usePagination , ConfigurableLink } from '@openmrs/esm-framework' ;
18
20
import { ActiveVisitRow , fetchActiveVisits } from './active-visits.resource' ;
19
21
import styles from './active-visits.scss' ;
20
22
import dayjs from 'dayjs' ;
21
23
22
- const headerData = [
23
- {
24
- id : 0 ,
25
- header : 'Visit Time' ,
26
- key : 'visitStartTime' ,
27
- } ,
28
- {
29
- id : 1 ,
30
- header : 'ID Number' ,
31
- key : 'IDNumber' ,
32
- } ,
33
- {
34
- id : 2 ,
35
- header : 'Name' ,
36
- key : 'name' ,
37
- } ,
38
- {
39
- id : 3 ,
40
- header : 'Gender' ,
41
- key : 'gender' ,
42
- } ,
43
- {
44
- id : 4 ,
45
- header : 'Age' ,
46
- key : 'age' ,
47
- } ,
48
- {
49
- id : 5 ,
50
- header : 'Visit Type' ,
51
- key : 'visitType' ,
52
- } ,
53
- ] ;
54
-
55
24
function formatDatetime ( startDatetime ) {
56
25
const todayDate = dayjs ( ) ;
57
26
const today =
@@ -65,7 +34,7 @@ function formatDatetime(startDatetime) {
65
34
}
66
35
}
67
36
68
- const ActiveVisitsTable = ( props ) => {
37
+ const ActiveVisitsTable = ( ) => {
69
38
const { t } = useTranslation ( ) ;
70
39
const layout = useLayoutType ( ) ;
71
40
const desktopView = layout === 'desktop' ;
@@ -76,50 +45,95 @@ const ActiveVisitsTable = (props) => {
76
45
const [ activeVisits , setActiveVisits ] = useState < ActiveVisitRow [ ] > ( [ ] ) ;
77
46
const [ searchString , setSearchString ] = useState ( '' ) ;
78
47
79
- const searchResults = useMemo ( ( ) => {
80
- if ( searchString && searchString . trim ( ) !== '' ) {
81
- const search = searchString . toLowerCase ( ) ;
82
- return activeVisits . filter ( ( activeVisitRow ) =>
83
- Object . keys ( activeVisitRow ) . some ( ( header ) => {
84
- if ( header === 'patientUuid' ) {
85
- return false ;
86
- }
87
- return `${ activeVisitRow [ header ] } ` . toLowerCase ( ) . includes ( search ) ;
88
- } ) ,
89
- ) ;
90
- } else {
91
- return activeVisits ;
92
- }
93
- } , [ searchString , activeVisits ] ) ;
94
- const { goTo, currentPage, results } = usePagination ( searchResults , currentPageSize ) ;
48
+ const headerData = useMemo (
49
+ ( ) => [
50
+ {
51
+ id : 0 ,
52
+ header : t ( 'visitStartTime' , 'Visit Time' ) ,
53
+ key : 'visitStartTime' ,
54
+ } ,
55
+ {
56
+ id : 1 ,
57
+ header : t ( 'IDNumber' , 'ID Number' ) ,
58
+ key : 'IDNumber' ,
59
+ } ,
60
+ {
61
+ id : 2 ,
62
+ header : t ( 'name' , 'Name' ) ,
63
+ key : 'name' ,
64
+ } ,
65
+ {
66
+ id : 3 ,
67
+ header : t ( 'gender' , 'Gender' ) ,
68
+ key : 'gender' ,
69
+ } ,
70
+ {
71
+ id : 4 ,
72
+ header : t ( 'age' , 'Age' ) ,
73
+ key : 'age' ,
74
+ } ,
75
+ {
76
+ id : 5 ,
77
+ header : t ( 'visitType' , 'Visit Type' ) ,
78
+ key : 'visitType' ,
79
+ } ,
80
+ ] ,
81
+ [ t ] ,
82
+ ) ;
95
83
96
84
useEffect ( ( ) => {
97
- const activeVisits = fetchActiveVisits ( ) . subscribe ( ( data ) => {
85
+ const abortController = new AbortController ( ) ;
86
+ fetchActiveVisits ( abortController ) . then ( ( { data } ) => {
98
87
const rowData = data . results . map ( ( visit , ind ) => ( {
99
88
id : `${ ind } ` ,
100
89
visitStartTime : formatDatetime ( visit . startDatetime ) ,
101
90
IDNumber : visit ?. patient ?. identifiers [ 0 ] ?. identifier ,
102
91
name : visit ?. patient ?. person ?. display ,
103
92
gender : visit ?. patient ?. person ?. gender ,
104
93
age : visit ?. patient ?. person ?. age ,
105
- visitType : visit ?. visitType . display ,
94
+ visitType : visit ?. visitType ? .display ,
106
95
patientUuid : visit ?. patient ?. uuid ,
96
+ visitUuid : visit ?. uuid ,
107
97
} ) ) ;
108
98
setActiveVisits ( rowData ) ;
109
99
setLoading ( false ) ;
110
100
} ) ;
111
- return ( ) => activeVisits . unsubscribe ( ) ;
101
+
102
+ return ( ) => abortController . abort ( ) ;
112
103
} , [ ] ) ;
113
104
105
+ const searchResults = useMemo ( ( ) => {
106
+ if ( searchString && searchString . trim ( ) !== '' ) {
107
+ const search = searchString . toLowerCase ( ) ;
108
+ return activeVisits . filter ( ( activeVisitRow ) =>
109
+ Object . keys ( activeVisitRow ) . some ( ( header ) => {
110
+ if ( header === 'patientUuid' ) {
111
+ return false ;
112
+ }
113
+ return `${ activeVisitRow [ header ] } ` . toLowerCase ( ) . includes ( search ) ;
114
+ } ) ,
115
+ ) ;
116
+ } else {
117
+ return activeVisits ;
118
+ }
119
+ } , [ searchString , activeVisits ] ) ;
120
+
121
+ const { goTo, results, currentPage } = usePagination ( searchResults , currentPageSize ) ;
114
122
const handleSearch = useCallback ( ( e ) => setSearchString ( e . target . value ) , [ ] ) ;
115
123
124
+ useEffect ( ( ) => {
125
+ if ( currentPage !== 1 ) {
126
+ goTo ( 1 ) ;
127
+ }
128
+ } , [ searchString ] ) ;
129
+
116
130
return ! loading ? (
117
131
< div className = { styles . activeVisitsContainer } >
118
132
< div className = { styles . activeVisitsDetailHeaderContainer } >
119
133
< h4 className = { styles . productiveHeading02 } > { t ( 'activeVisits' , 'Active Visits' ) } </ h4 >
120
134
</ div >
121
135
< DataTable rows = { results } headers = { headerData } isSortable >
122
- { ( { rows, headers, getHeaderProps, getTableProps, getBatchActionProps } ) => (
136
+ { ( { rows, headers, getHeaderProps, getTableProps, getBatchActionProps, getRowProps } ) => (
123
137
< TableContainer title = "" className = { styles . tableContainer } >
124
138
< TableToolbar >
125
139
< TableToolbarContent >
@@ -131,35 +145,52 @@ const ActiveVisitsTable = (props) => {
131
145
/>
132
146
</ TableToolbarContent >
133
147
</ TableToolbar >
134
- < Table { ... getTableProps ( ) } useZebraStyles >
148
+ < Table className = { styles . activeVisitsTable } { ... getTableProps ( ) } size = { desktopView ? 'short' : 'normal' } >
135
149
< TableHead >
136
- < TableRow style = { { height : desktopView ? '2rem' : '3rem' } } >
150
+ < TableRow >
151
+ < TableExpandHeader />
137
152
{ headers . map ( ( header ) => (
138
153
< TableHeader { ...getHeaderProps ( { header } ) } > { header . header } </ TableHeader >
139
154
) ) }
140
155
</ TableRow >
141
156
</ TableHead >
142
157
< TableBody >
143
158
{ rows . map ( ( row , ind ) => (
144
- < TableRow key = { row . id } style = { { height : desktopView ? '2rem' : '3rem' } } >
145
- { row . cells . map ( ( cell ) => (
146
- < TableCell key = { cell . id } >
147
- { cell . info . header === 'name' ? (
148
- < ConfigurableLink to = { `\${openmrsSpaBase}/patient/${ results [ ind ] ?. patientUuid } /chart/` } >
149
- { cell . value }
150
- </ ConfigurableLink >
151
- ) : (
152
- cell . value
153
- ) }
154
- </ TableCell >
155
- ) ) }
156
- </ TableRow >
159
+ < React . Fragment key = { row . id } >
160
+ < TableExpandRow { ...getRowProps ( { row } ) } >
161
+ { row . cells . map ( ( cell ) => (
162
+ < TableCell key = { cell . id } >
163
+ { cell . info . header === 'name' ? (
164
+ < ConfigurableLink to = { `\${openmrsSpaBase}/patient/${ results [ ind ] ?. patientUuid } /chart/` } >
165
+ { cell . value }
166
+ </ ConfigurableLink >
167
+ ) : (
168
+ cell . value
169
+ ) }
170
+ </ TableCell >
171
+ ) ) }
172
+ </ TableExpandRow >
173
+ { row . isExpanded && (
174
+ < TableRow className = { styles . expandedActiveVisitRow } colSpan = { headers . length + 1 } >
175
+ < th colSpan = { headers . length + 2 } >
176
+ < ExtensionSlot
177
+ className = { styles . visitSummaryContainer }
178
+ extensionSlotName = "visit-summary-slot"
179
+ state = { {
180
+ visitUuid : results [ ind ] ?. visitUuid ,
181
+ patientUuid : results [ ind ] ?. patientUuid ,
182
+ } }
183
+ />
184
+ </ th >
185
+ </ TableRow >
186
+ ) }
187
+ </ React . Fragment >
157
188
) ) }
158
189
</ TableBody >
159
190
</ Table >
160
191
{ rows . length === 0 && (
161
192
< p
162
- style = { { height : desktopView ? '2rem' : '3rem' } }
193
+ style = { { height : desktopView ? '2rem' : '3rem' , marginLeft : desktopView ? '2rem' : '3rem' } }
163
194
className = { `${ styles . emptyRow } ${ styles . bodyLong01 } ` } >
164
195
{ t ( 'noVisitsFound' , 'No visits found' ) }
165
196
</ p >
0 commit comments