1
+ import React , { useEffect , useState } from 'react'
2
+ import { deleteDB } from 'idb'
3
+ import { useD2 } from '@dhis2/app-runtime-adapter-d2'
4
+ import { Button , Card } from '@dhis2/ui-core'
5
+ import { Radio , RadioGroup , FormControlLabel , Stepper , Step , StepLabel , StepContent } from '@material-ui/core'
6
+ import StorageIcon from '@material-ui/icons/Storage'
7
+ import DoneIcon from '@material-ui/icons/Done'
8
+ import { mergeAll } from 'ramda'
9
+ import _ from 'lodash'
10
+ import DHIS2API from 'dhis2-api-wrapper'
11
+ import GoDataAPI from 'godata-api-wrapper'
12
+ import { copyLocations , fullTransferDHIS2 , copyTrackedEntities } from 'dhis2-godata-interoperability'
13
+ import '../styles/Actions.css'
14
+ import { getFullSteps , getFullStepContent , getSteps , getStepContent } from '../utils/dhis2Labels'
15
+
16
+ const Dhis2Actions = ( ) => {
17
+ const [ config , setConfig ] = useState ( { } )
18
+ const [ dhis2 , setDhis2 ] = useState ( null )
19
+ const [ godata , setGoData ] = useState ( null )
20
+
21
+ const [ full , setFull ] = useState ( true )
22
+ const fullTransferSteps = getFullSteps ( )
23
+ const [ activeStep , setActiveStep ] = useState ( 0 )
24
+ const transferSteps = getSteps ( )
25
+
26
+ const [ skipped , setSkipped ] = useState ( new Set ( ) )
27
+ const [ completed , setCompleted ] = useState ( new Set ( ) )
28
+
29
+ const [ done , setDone ] = useState ( false )
30
+ const [ messages , setMessages ] = useState ( [ ] )
31
+
32
+ const { d2 } = useD2 ( )
33
+
34
+ useEffect ( ( ) => {
35
+ async function initInstances ( ) {
36
+ const generalNamespace = await d2 . dataStore . get ( "dhis-godata-interoperability" )
37
+ const userNamespace = await d2 . currentUser . dataStore . get ( "dhis-godata-interoperability" )
38
+ const baseConf = await generalNamespace . get ( "base-config" )
39
+ const credConf = await userNamespace . get ( "cred-config" )
40
+ const password = await userNamespace . get ( "password" )
41
+ credConf . GoDataAPIConfig . credentials . password = password . password
42
+ const conf = mergeAll ( [ baseConf , credConf ] )
43
+ setConfig ( conf )
44
+ setDhis2 ( new DHIS2API ( conf . DHIS2APIConfig ) )
45
+ setGoData ( new GoDataAPI ( conf . GoDataAPIConfig ) )
46
+
47
+ }
48
+ if ( d2 ) {
49
+ initInstances ( )
50
+ }
51
+ } , [ d2 ] )
52
+
53
+ const logAction = ( message ) => setMessages ( prevArray => [ ...prevArray , { text : message , done : false } ] )
54
+ const logDone = ( ) => setMessages ( prevArray => {
55
+ const newArray = [ ...prevArray ]
56
+ newArray [ newArray . length - 1 ] . done = true
57
+ return newArray
58
+ } )
59
+
60
+ const cleanCache = async ( ) => {
61
+ if ( indexedDB !== undefined ) {
62
+ await deleteDB ( 'dhis2tc' )
63
+ }
64
+ }
65
+
66
+ const handleSkip = ( ) => {
67
+ setActiveStep ( prev => prev + 1 )
68
+ setSkipped ( prevSkipped => {
69
+ const newSkipped = new Set ( prevSkipped . values ( ) )
70
+ const length = full ? fullTransferSteps . length : transferSteps . length
71
+ newSkipped . add ( activeStep )
72
+ if ( newSkipped . size + completed . size === length ) { setDone ( true ) }
73
+ return newSkipped
74
+ } )
75
+ }
76
+
77
+ const isStepSkipped = ( step ) => {
78
+ return skipped . has ( step )
79
+ }
80
+
81
+ const handleFullNext = ( ) => {
82
+ async function action ( ) {
83
+ switch ( activeStep ) {
84
+ case 0 :
85
+ await godata . login ( )
86
+ await fullTransferDHIS2 ( dhis2 , godata , config , { logAction, logDone, cleanCache } ) ( )
87
+ setDone ( true )
88
+ break
89
+ default : break
90
+ }
91
+ }
92
+ setMessages ( [ ] )
93
+ action ( )
94
+ setActiveStep ( prev => prev + 1 )
95
+ setCompleted ( prev => {
96
+ const newCompleted = new Set ( prev . values ( ) )
97
+ newCompleted . add ( activeStep )
98
+ return newCompleted
99
+ } )
100
+ }
101
+ const handleNext = ( ) => {
102
+ async function action ( ) {
103
+ switch ( activeStep ) {
104
+ case 0 :
105
+ await godata . login ( )
106
+ await copyLocations ( dhis2 , godata , config , { logAction, logDone, cleanCache } ) ( )
107
+ break
108
+ case 1 :
109
+ await copyTrackedEntities ( dhis2 , godata , config , { logAction, logDone } ) ( )
110
+ setDone ( true )
111
+ break
112
+ default : break
113
+ }
114
+ }
115
+ setMessages ( [ ] )
116
+ action ( )
117
+ setActiveStep ( prev => prev + 1 )
118
+ setCompleted ( prev => {
119
+ const newCompleted = new Set ( prev . values ( ) )
120
+ newCompleted . add ( activeStep )
121
+ return newCompleted
122
+ } )
123
+ }
124
+
125
+ return (
126
+ < div className = "container" >
127
+ < div className = "card" >
128
+ < Card className = "card" dataTest = "dhis2-uicore-card" >
129
+ < div className = "title-icon" >
130
+ < StorageIcon />
131
+ < h3 > Import data and metadata to DHIS2</ h3 >
132
+ </ div >
133
+ < div className = "content" >
134
+ < p className = "p" > Choose export sequence</ p >
135
+ < RadioGroup
136
+ className = "radio-group"
137
+ name = "fullTransfer"
138
+ value = { full }
139
+ onChange = { ( ) => setFull ( prev => ! prev ) }
140
+ >
141
+ < FormControlLabel
142
+ value = { true }
143
+ control = { < Radio disabled = { activeStep !== 0 & ! full } className = "radio" /> }
144
+ label = "Full transfer"
145
+ />
146
+ < FormControlLabel
147
+ value = { false }
148
+ control = { < Radio disabled = { activeStep !== 0 & full } className = "radio" /> }
149
+ label = "Step-by-step transfer"
150
+ />
151
+ </ RadioGroup >
152
+ { full &&
153
+ < Stepper activeStep = { activeStep } orientation = "vertical" >
154
+ { fullTransferSteps . map ( ( label , index ) => {
155
+ const stepProps = { }
156
+ if ( isStepSkipped ( index ) ) {
157
+ stepProps . completed = false
158
+ }
159
+ return (
160
+ < Step key = { label } { ...stepProps } >
161
+ < StepLabel > { label } </ StepLabel >
162
+ < StepContent >
163
+ < div className = "helper" > { getFullStepContent ( index ) } </ div >
164
+ < div className = "import" >
165
+ < Button
166
+ dataTest = "dhis2-uicore-button"
167
+ name = "button"
168
+ type = "button"
169
+ onClick = { handleFullNext }
170
+ >
171
+ Complete
172
+ </ Button >
173
+ < Button
174
+ dataTest = "dhis2-uicore-button"
175
+ name = "button"
176
+ type = "button"
177
+ onClick = { handleSkip }
178
+ >
179
+ Skip
180
+ </ Button >
181
+ </ div >
182
+ </ StepContent >
183
+ </ Step >
184
+ )
185
+ } ) }
186
+ </ Stepper >
187
+ }
188
+ { ! full &&
189
+ < Stepper activeStep = { activeStep } orientation = "vertical" >
190
+ { transferSteps . map ( ( label , index ) => {
191
+ const stepProps = { }
192
+ if ( isStepSkipped ( index ) ) {
193
+ stepProps . completed = false
194
+ }
195
+ return (
196
+ < Step key = { label } { ...stepProps } >
197
+ < StepLabel > { label } </ StepLabel >
198
+ < StepContent >
199
+ < div className = "helper" > { getStepContent ( index ) } </ div >
200
+ < div className = "import" >
201
+ < Button
202
+ dataTest = "dhis2-uicore-button"
203
+ name = "button"
204
+ type = "button"
205
+ onClick = { handleNext }
206
+ >
207
+ Complete
208
+ </ Button >
209
+ < Button
210
+ dataTest = "dhis2-uicore-button"
211
+ name = "button"
212
+ type = "button"
213
+ onClick = { handleSkip }
214
+ >
215
+ Skip
216
+ </ Button >
217
+ </ div >
218
+ </ StepContent >
219
+ </ Step >
220
+ )
221
+ } ) }
222
+ </ Stepper >
223
+ }
224
+ </ div >
225
+ </ Card >
226
+ < div >
227
+ { messages . map ( message => (
228
+ < Card className = "log" >
229
+ < div className = "title-icon" key = { message } >
230
+ < div className = "logAction" > { message . text + "..." } </ div >
231
+ { message . done && < DoneIcon /> }
232
+ </ div >
233
+ </ Card >
234
+ ) ) }
235
+
236
+ </ div >
237
+
238
+ { done &&
239
+ < Card className = "log" >
240
+ < p className = "title-icon" >
241
+ < span className = "p" > All steps completed - you're finished</ span >
242
+ </ p >
243
+ </ Card >
244
+ }
245
+ </ div >
246
+ </ div >
247
+
248
+ )
249
+ }
250
+
251
+ export default Dhis2Actions
0 commit comments