1
1
// Copyright (c) Jupyter Development Team.
2
2
// Distributed under the terms of the Modified BSD License.
3
3
4
- import { ReactWidget } from '@jupyterlab/apputils' ;
4
+ import { Dialog , ReactWidget , showDialog } from '@jupyterlab/apputils' ;
5
5
6
- import { User } from '@jupyterlab/services' ;
6
+ import { ServerConnection , User } from '@jupyterlab/services' ;
7
+
8
+ import { URLExt } from '@jupyterlab/coreutils' ;
9
+
10
+ import { IRenderMime } from '@jupyterlab/rendermime-interfaces' ;
7
11
8
12
import { Panel } from '@lumino/widgets' ;
9
13
10
14
import * as React from 'react' ;
11
15
12
- import { UserIconComponent } from './components' ;
16
+ import { UserDetailsBody , UserIconComponent } from './components' ;
17
+
18
+ /**
19
+ * The properties for the UserInfoBody.
20
+ */
21
+ type UserInfoProps = {
22
+ userManager : User . IManager ;
23
+ trans : IRenderMime . TranslationBundle ;
24
+ } ;
13
25
14
26
export class UserInfoPanel extends Panel {
15
27
private _profile : User . IManager ;
16
28
private _body : UserInfoBody | null ;
17
29
18
- constructor ( user : User . IManager ) {
30
+ constructor ( options : UserInfoProps ) {
19
31
super ( { } ) ;
20
32
this . addClass ( 'jp-UserInfoPanel' ) ;
21
-
22
- this . _profile = user ;
33
+ this . _profile = options . userManager ;
23
34
this . _body = null ;
24
35
25
36
if ( this . _profile . isReady ) {
26
- this . _body = new UserInfoBody ( this . _profile . identity ! ) ;
37
+ this . _body = new UserInfoBody ( {
38
+ userManager : this . _profile ,
39
+ trans : options . trans
40
+ } ) ;
27
41
this . addWidget ( this . _body ) ;
28
42
this . update ( ) ;
29
43
} else {
30
44
this . _profile . ready
31
45
. then ( ( ) => {
32
- this . _body = new UserInfoBody ( this . _profile . identity ! ) ;
46
+ this . _body = new UserInfoBody ( {
47
+ userManager : this . _profile ,
48
+ trans : options . trans
49
+ } ) ;
33
50
this . addWidget ( this . _body ) ;
34
51
this . update ( ) ;
35
52
} )
@@ -41,27 +58,79 @@ export class UserInfoPanel extends Panel {
41
58
/**
42
59
* A SettingsWidget for the user.
43
60
*/
44
- export class UserInfoBody extends ReactWidget {
45
- private _user : User . IIdentity ;
46
-
61
+ export class UserInfoBody
62
+ extends ReactWidget
63
+ implements Dialog . IBodyWidget < User . IManager >
64
+ {
65
+ private _userManager : User . IManager ;
66
+ private _trans : IRenderMime . TranslationBundle ;
47
67
/**
48
68
* Constructs a new settings widget.
49
69
*/
50
- constructor ( user : User . IIdentity ) {
70
+ constructor ( props : UserInfoProps ) {
51
71
super ( ) ;
52
- this . _user = user ;
72
+ this . _userManager = props . userManager ;
73
+ this . _trans = props . trans ;
53
74
}
54
75
55
- get user ( ) : User . IIdentity {
56
- return this . _user ;
76
+ get user ( ) : User . IManager {
77
+ return this . _userManager ;
57
78
}
58
79
59
- set user ( user : User . IIdentity ) {
60
- this . _user = user ;
80
+ set user ( user : User . IManager ) {
81
+ this . _userManager = user ;
61
82
this . update ( ) ;
62
83
}
63
84
85
+ private onClick = ( ) => {
86
+ if ( ! this . _userManager . identity ) {
87
+ return ;
88
+ }
89
+ showDialog ( {
90
+ body : new UserDetailsBody ( {
91
+ userManager : this . _userManager
92
+ } ) ,
93
+ title : this . _trans . __ ( 'User Details' )
94
+ } ) . then ( async result => {
95
+ if ( result . button . accept ) {
96
+ // Call the Jupyter Server API to update the user field
97
+ try {
98
+ const settings = ServerConnection . makeSettings ( ) ;
99
+ const url = URLExt . join ( settings . baseUrl , '/api/me' ) ;
100
+ const body = {
101
+ method : 'PATCH' ,
102
+ body : JSON . stringify ( result . value )
103
+ } ;
104
+
105
+ let response : Response ;
106
+ try {
107
+ response = await ServerConnection . makeRequest ( url , body , settings ) ;
108
+ } catch ( error ) {
109
+ throw new ServerConnection . NetworkError ( error as Error ) ;
110
+ }
111
+
112
+ if ( ! response . ok ) {
113
+ const errorMsg = this . _trans . __ ( 'Failed to update user data' ) ;
114
+ throw new Error ( errorMsg ) ;
115
+ }
116
+
117
+ // Refresh user information
118
+ this . _userManager . refreshUser ( ) ;
119
+ } catch ( error ) {
120
+ console . error ( error ) ;
121
+ }
122
+ }
123
+ } ) ;
124
+ } ;
125
+
64
126
render ( ) : JSX . Element {
65
- return < UserIconComponent user = { this . _user } /> ;
127
+ return (
128
+ < div className = "jp-UserInfo-Container" >
129
+ < UserIconComponent
130
+ userManager = { this . _userManager }
131
+ onClick = { this . onClick }
132
+ />
133
+ </ div >
134
+ ) ;
66
135
}
67
136
}
0 commit comments