1
+ import { HttpClient } from "@angular/common/http" ;
1
2
import { Injectable } from "@angular/core" ;
2
3
import { Device } from "@capacitor/device" ;
4
+ import { firstValueFrom } from "rxjs" ;
5
+
3
6
import { AsyncServiceBase } from "../asyncService.base" ;
4
7
import { DbService } from "../db/db.service" ;
8
+ import { TemplateActionRegistry } from "../../components/template/services/instance/template-action.registry" ;
9
+ import { TemplateFieldService } from "../../components/template/services/template-field.service" ;
5
10
6
11
@Injectable ( { providedIn : "root" } )
7
12
export class UserMetaService extends AsyncServiceBase {
8
13
/** keep an in-memory copy of user to provide synchronously */
9
14
public userMeta : IUserMeta ;
10
- constructor ( private dbService : DbService ) {
11
- super ( "UsesrMetaService" ) ;
15
+ constructor (
16
+ private dbService : DbService ,
17
+ private templateActionRegistry : TemplateActionRegistry ,
18
+ private http : HttpClient ,
19
+ private fieldService : TemplateFieldService
20
+ ) {
21
+ super ( "UserMetaService" ) ;
12
22
this . registerInitFunction ( this . initialise ) ;
13
23
}
14
24
15
25
/** When first initialising ensure a default profile created and any newer defaults are merged with older user profiles */
16
26
private async initialise ( ) {
17
- await this . ensureAsyncServicesReady ( [ this . dbService ] ) ;
27
+ await this . ensureAsyncServicesReady ( [ this . dbService , this . fieldService ] ) ;
28
+ this . registerUserActions ( ) ;
18
29
const userMetaValues = await this . dbService . table < IUserMetaEntry > ( "user_meta" ) . toArray ( ) ;
19
30
const userMeta : IUserMeta = USER_DEFAULTS ;
20
31
userMetaValues . forEach ( ( v ) => {
@@ -27,6 +38,8 @@ export class UserMetaService extends AsyncServiceBase {
27
38
}
28
39
userMeta . uuid = uuid ;
29
40
this . userMeta = userMeta ;
41
+ // populate user id contact field
42
+ this . fieldService . setField ( "_app_user_id" , uuid ) ;
30
43
}
31
44
32
45
getUserMeta ( key : keyof IUserMeta ) {
@@ -38,6 +51,49 @@ export class UserMetaService extends AsyncServiceBase {
38
51
await this . dbService . table < IUserMetaEntry > ( "user_meta" ) . bulkPut ( entries as any ) ;
39
52
this . userMeta = { ...this . userMeta , ...meta } ;
40
53
}
54
+
55
+ /** Import existing user contact fields and replace current user */
56
+ private async importUserFields ( id : string ) {
57
+ try {
58
+ // TODO - get type-safe return types using openapi http client
59
+ const profile = await firstValueFrom (
60
+ this . http . get ( `/app_users/${ id } ` , { responseType : "json" } )
61
+ ) ;
62
+ if ( ! profile ) {
63
+ console . error ( "[User Import] not found:" + id ) ;
64
+ return ;
65
+ }
66
+ const { contact_fields } = profile as any ;
67
+ for ( const [ key , value ] of Object . entries ( contact_fields ) ) {
68
+ const fieldName = key . replace ( `${ this . fieldService . prefix } .` , "" ) ;
69
+ // TODO - handle special contact fields as required (e.g. _app_skin, _app_theme)
70
+ if ( ! fieldName . startsWith ( "_" ) ) {
71
+ await this . fieldService . setField ( fieldName , value as string ) ;
72
+ }
73
+ }
74
+ } catch ( error ) {
75
+ console . error ( "[User Import] failed" , error ) ;
76
+ }
77
+ }
78
+
79
+ private registerUserActions ( ) {
80
+ const childActions = {
81
+ import : this . importUserFields . bind ( this ) ,
82
+ } ;
83
+ const childActionNames = Object . keys ( childActions ) . join ( "," ) ;
84
+ this . templateActionRegistry . register ( {
85
+ user : async ( { args } ) => {
86
+ const [ actionId , ...childArgs ] = args ;
87
+ if ( ! childActions [ actionId ] ) {
88
+ console . error (
89
+ `[${ actionId } ] user action not defined. Available actions:\n${ childActionNames } `
90
+ ) ;
91
+ return ;
92
+ }
93
+ return childActions [ actionId ] ( childArgs ) ;
94
+ } ,
95
+ } ) ;
96
+ }
41
97
}
42
98
43
99
interface IUserMetaEntry {
0 commit comments