11let connection = null ;
22
3- const drLib = {
4- showLoginButton
5-
3+ const patientLib = {
4+ showLoginButton,
5+ handleFormSubmit,
6+ getFormContent,
67}
78
89function showLoginButton ( loginSpanId , stateChangeCallBack ) {
@@ -14,15 +15,41 @@ function showLoginButton (loginSpanId, stateChangeCallBack) {
1415 requestingAppId : 'demo-dr-form-patient' , // to customize for your own app
1516 requestedPermissions : [
1617 {
17- streamId : '*' ,
18+ streamId : 'profile' ,
19+ defaultName : 'Profile' ,
20+ level : 'manage'
21+ } ,
22+ {
23+ streamId : 'family' ,
24+ defaultName : 'Family' ,
25+ level : 'manage'
26+ } ,
27+ {
28+ streamId : 'fertility' ,
29+ defaultName : 'Fertility' ,
30+ level : 'manage'
31+ } ,
32+ {
33+ streamId : 'body-height' ,
34+ defaultName : 'Body height' ,
35+ level : 'manage'
36+ } ,
37+ {
38+ streamId : 'body-weight' ,
39+ defaultName : 'Body weight' ,
1840 level : 'manage'
1941 }
2042 ] ,
2143 clientData : {
2244 'app-web-auth:description' : {
2345 'type' : 'note/txt' ,
2446 'content' : 'This app allows to fill a form and share information with your doctor.'
25- }
47+ } ,
48+ 'app-web-auth:ensureBaseStreams' : [
49+ { id : 'body' , name : 'Body metrics' } ,
50+ { id : 'body-height' , name : 'Body height' , parentId : 'body' } ,
51+ { id : 'body-weight' , name : 'Body weight' , parentId : 'body' }
52+ ]
2653 } ,
2754 }
2855 } ;
@@ -45,7 +72,146 @@ function showLoginButton (loginSpanId, stateChangeCallBack) {
4572 }
4673}
4774
75+ // Creates the streams structure for the patient account after the user has logged in
4876async function initPatientAccount ( connection ) {
49-
77+ const patientBaseStreams = [
78+ // profile
79+ { id : 'profile-name' , name : 'Name' , parentId : 'profile' } ,
80+ { id : 'profile-nationality' , name : 'Nationality' , parentId : 'profile' } ,
81+ { id : 'profile-date-of-birth' , name : 'Date of Birth' , parentId : 'profile' } ,
82+ { id : 'profile-location' , name : 'Location' , parentId : 'profile' } ,
83+ { id : 'profile-sex' , name : 'Sex' , parentId : 'profile' } ,
84+ // family
85+ { id : 'family-children' , name : 'Children' , parentId : 'family' } ,
86+ // fertility
87+ { id : 'fertility-miscarriages' , name : 'Miscarriages' , parentId : 'fertility' } ,
88+ { id : 'fertility-traings' , name : 'Trainings' , parentId : 'fertility' } ,
89+ { id : 'fertility-cycles' , name : 'Cycles' , parentId : 'fertility' } ,
90+ { id : 'fertility-cycles-charted-extimation' , name : 'Cycles charted estimation' , parentId : 'fertility' } ,
91+ { id : 'fertility-ttc-tta' , name : 'Trying to conceive / Avoiding pregnancy' , parentId : 'fertility' } ,
92+ ] ;
93+ const apiCalls = patientBaseStreams . map ( stream => ( {
94+ method : 'streams.create' ,
95+ params : {
96+ id : stream . id ,
97+ name : stream . name ,
98+ parentId : stream . parentId
99+ }
100+ } ) ) ;
101+ // create stream structure (even if already exists)
102+ const res = await connection . api ( apiCalls ) ;
103+ console . log ( '## Patient account streams created' , res ) ;
50104 console . log ( '## Patient account initialized' )
105+ }
106+
107+ // ---------------- form content ---------------- //
108+
109+ const formContent = [
110+ {
111+ streamId : 'profile-name' ,
112+ eventType : 'contact/name' ,
113+ contentField : 'name' ,
114+ type : 'text' ,
115+ label : 'Name' ,
116+ } ,
117+ {
118+ streamId : 'profile-name' ,
119+ eventType : 'contact/surname' ,
120+ contentField : 'surname' ,
121+ type : 'text' ,
122+ label : 'Surname' ,
123+ } ,
124+ {
125+ streamId : 'profile-nationality' ,
126+ eventType : 'contact/nationality' ,
127+ type : 'text' ,
128+ label : 'Nationality' ,
129+ } ,
130+ ] ;
131+
132+ let formInitialized = null ;
133+ async function getFormContent ( ) {
134+ if ( formInitialized ) { return formContent ; }
135+ formInitialized = true ; // prevent multiple calls to this function
136+
137+ // get the values from the API
138+ const apiCalls = formContent . map ( field => ( {
139+ method : 'events.get' ,
140+ params : {
141+ streams : [ field . streamId ] ,
142+ types : [ field . eventType ] ,
143+ limit : 1 ,
144+ }
145+ } ) ) ;
146+
147+ const res = await connection . api ( apiCalls ) ;
148+ for ( let i = 0 ; i < res . length ; i ++ ) {
149+ const e = res [ i ] ;
150+ const field = formContent [ i ] ;
151+ field . id = 'field-' + i ; // generate a unique id for the field
152+ console . log ( '## getFormContent ' + i , e ) ;
153+ if ( e . events && e . events . length > 0 ) {
154+ const event = e . events [ 0 ] ;
155+ field . value = event . content ;
156+ field . eventId = event . id ; // will allow t track if the event is to be updated
157+ }
158+ }
159+ return formContent ;
160+ } ;
161+
162+ // ---------------- create / update data ---------------- //
163+ async function handleFormSubmit ( values ) {
164+ const apiCalls = [ ] ;
165+ for ( const field of formContent ) {
166+ const streamId = field . streamId ;
167+ const eventType = field . eventType ;
168+ const eventId = field . eventId ;
169+ const value = values [ field . id ] ;
170+
171+ if ( value === '' && eventId ) {
172+ // delete the event
173+ apiCalls . push ( {
174+ method : 'events.delete' ,
175+ params : {
176+ id : eventId ,
177+ }
178+ } ) ;
179+ continue ;
180+ }
181+
182+ if ( value === field . value || value === '' ) {
183+ // no change
184+ continue ;
185+ }
186+
187+ if ( eventId ) {
188+ // update the event
189+ apiCalls . push ( {
190+ method : 'events.update' ,
191+ params : {
192+ id : eventId ,
193+ update : {
194+ content : value
195+ }
196+ }
197+ } ) ;
198+ continue ;
199+ }
200+ // create a new event
201+ apiCalls . push ( {
202+ method : 'events.create' ,
203+ params : {
204+ streamId : streamId ,
205+ type : eventType ,
206+ content : value ,
207+ }
208+ } ) ;
209+ }
210+ if ( apiCalls . length === 0 ) {
211+ console . log ( '## No changes to submit' ) ;
212+ return ;
213+ }
214+ // send the API calls
215+ const res = await connection . api ( apiCalls ) ;
216+ console . log ( '## Form submitted' , res ) ;
51217}
0 commit comments