11// Copyright (c) Jupyter Development Team.
22// Distributed under the terms of the Modified BSD License.
33
4- import { ReactWidget } from '@jupyterlab/apputils' ;
4+ import { Dialog , ReactWidget , showDialog } from '@jupyterlab/apputils' ;
55
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' ;
711
812import { Panel } from '@lumino/widgets' ;
913
1014import * as React from 'react' ;
1115
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+ } ;
1325
1426export class UserInfoPanel extends Panel {
1527 private _profile : User . IManager ;
1628 private _body : UserInfoBody | null ;
1729
18- constructor ( user : User . IManager ) {
30+ constructor ( options : UserInfoProps ) {
1931 super ( { } ) ;
2032 this . addClass ( 'jp-UserInfoPanel' ) ;
21-
22- this . _profile = user ;
33+ this . _profile = options . userManager ;
2334 this . _body = null ;
2435
2536 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+ } ) ;
2741 this . addWidget ( this . _body ) ;
2842 this . update ( ) ;
2943 } else {
3044 this . _profile . ready
3145 . then ( ( ) => {
32- this . _body = new UserInfoBody ( this . _profile . identity ! ) ;
46+ this . _body = new UserInfoBody ( {
47+ userManager : this . _profile ,
48+ trans : options . trans
49+ } ) ;
3350 this . addWidget ( this . _body ) ;
3451 this . update ( ) ;
3552 } )
@@ -41,27 +58,79 @@ export class UserInfoPanel extends Panel {
4158/**
4259 * A SettingsWidget for the user.
4360 */
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 ;
4767 /**
4868 * Constructs a new settings widget.
4969 */
50- constructor ( user : User . IIdentity ) {
70+ constructor ( props : UserInfoProps ) {
5171 super ( ) ;
52- this . _user = user ;
72+ this . _userManager = props . userManager ;
73+ this . _trans = props . trans ;
5374 }
5475
55- get user ( ) : User . IIdentity {
56- return this . _user ;
76+ get user ( ) : User . IManager {
77+ return this . _userManager ;
5778 }
5879
59- set user ( user : User . IIdentity ) {
60- this . _user = user ;
80+ set user ( user : User . IManager ) {
81+ this . _userManager = user ;
6182 this . update ( ) ;
6283 }
6384
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+
64126 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+ ) ;
66135 }
67136}
0 commit comments