@@ -56,77 +56,6 @@ qx.Class.define("osparc.po.UsersPending", {
5656 return form ;
5757 } ,
5858
59- createApproveButton : function ( email ) {
60- const button = new qx . ui . form . Button ( qx . locale . Manager . tr ( "Approve" ) ) ;
61- button . addListener ( "execute" , ( ) => {
62- const form = this . createInvitationForm ( false ) ;
63- const approveBtn = new osparc . ui . form . FetchButton ( qx . locale . Manager . tr ( "Approve" ) ) ;
64- approveBtn . set ( {
65- appearance : "form-button"
66- } ) ;
67- form . addButton ( approveBtn ) ;
68- const layout = new qx . ui . container . Composite ( new qx . ui . layout . VBox ( 10 ) ) ;
69- const invitationForm = new qx . ui . form . renderer . Single ( form ) ;
70- layout . add ( invitationForm ) ;
71- const win = osparc . ui . window . Window . popUpInWindow ( layout , email , 350 , 150 ) . set ( {
72- clickAwayClose : false ,
73- resizable : false ,
74- showClose : true
75- } ) ;
76- win . open ( ) ;
77- approveBtn . addListener ( "execute" , ( ) => {
78- if ( ! osparc . data . Permissions . getInstance ( ) . canDo ( "user.invitation.generate" , true ) ) {
79- return ;
80- }
81- if ( form . validate ( ) ) {
82- approveBtn . setFetching ( true ) ;
83- const params = {
84- data : {
85- email,
86- } ,
87- } ;
88- params . data [ "invitation" ] = { } ;
89- const extraCreditsInUsd = form . getItems ( ) [ "credits" ] . getValue ( ) ;
90- if ( extraCreditsInUsd > 0 ) {
91- params . data [ "invitation" ] [ "extraCreditsInUsd" ] = extraCreditsInUsd ;
92- }
93- if ( form . getItems ( ) [ "withExpiration" ] . getValue ( ) ) {
94- params . data [ "invitation" ] [ "trialAccountDays" ] = form . getItems ( ) [ "trialDays" ] . getValue ( ) ;
95- }
96- osparc . data . Resources . fetch ( "poUsers" , "approveUser" , params )
97- . then ( ( ) => {
98- osparc . FlashMessenger . logAs ( qx . locale . Manager . tr ( "User approved" ) , "INFO" ) ;
99- } )
100- . catch ( err => osparc . FlashMessenger . logError ( err ) )
101- . finally ( ( ) => {
102- approveBtn . setFetching ( false ) ;
103- win . close ( ) ;
104- } ) ;
105- }
106- } ) ;
107- } ) ;
108- return button ;
109- } ,
110-
111- createRejectButton : function ( email ) {
112- const button = new osparc . ui . form . FetchButton ( qx . locale . Manager . tr ( "Reject" ) ) ;
113- button . addListener ( "execute" , ( ) => {
114- button . setFetching ( true ) ;
115- const params = {
116- data : {
117- email,
118- } ,
119- } ;
120- osparc . data . Resources . fetch ( "poUsers" , "rejectUser" , params )
121- . then ( ( ) => {
122- osparc . FlashMessenger . logAs ( qx . locale . Manager . tr ( "User denied" ) , "INFO" ) ;
123- } )
124- . catch ( err => osparc . FlashMessenger . logError ( err ) )
125- . finally ( ( ) => button . setFetching ( false ) ) ;
126- } ) ;
127- return button ;
128- } ,
129-
13059 createResendEmailButton : function ( email ) {
13160 const button = new osparc . ui . form . FetchButton ( qx . locale . Manager . tr ( "Resend Email" ) ) ;
13261 button . addListener ( "execute" , ( ) => {
@@ -147,7 +76,7 @@ qx.Class.define("osparc.po.UsersPending", {
14776 } ,
14877
14978 createInfoButton : function ( infoMetadata ) {
150- const infoButton = new qx . ui . form . Button ( null , "@MaterialIcons/info_outline/16 " ) ;
79+ const infoButton = new qx . ui . form . Button ( null , "@MaterialIcons/info_outline/14 " ) ;
15180 infoButton . addListener ( "execute" , ( ) => {
15281 const container = new qx . ui . container . Scroll ( ) ;
15382 container . add ( new osparc . ui . basic . JsonTreeWidget ( infoMetadata , "pendingUserInfo" ) ) ;
@@ -165,10 +94,7 @@ qx.Class.define("osparc.po.UsersPending", {
16594 control = new qx . ui . form . Button ( this . tr ( "Reload" ) ) . set ( {
16695 allowGrowX : false ,
16796 } ) ;
168- control . addListener ( "execute" , ( ) => {
169- this . getChildControl ( "pending-users-layout" ) . removeAll ( ) ;
170- this . __populatePendingUsersLayout ( ) ;
171- } ) ;
97+ control . addListener ( "execute" , ( ) => this . __reload ( ) ) ;
17298 this . _add ( control ) ;
17399 break ;
174100 case "pending-users-container" :
@@ -190,7 +116,7 @@ qx.Class.define("osparc.po.UsersPending", {
190116 _buildLayout : function ( ) {
191117 this . getChildControl ( "reload-button" ) ;
192118 this . getChildControl ( "pending-users-container" ) ;
193-
119+ this . __addHeader ( ) ;
194120 this . __populatePendingUsersLayout ( ) ;
195121 } ,
196122
@@ -217,34 +143,16 @@ qx.Class.define("osparc.po.UsersPending", {
217143 row : 0 ,
218144 column : 2 ,
219145 } ) ;
220-
221- pendingUsersLayout . add ( new qx . ui . basic . Label ( this . tr ( "Status" ) ) . set ( {
222- font : "text-14"
223- } ) , {
224- row : 0 ,
225- column : 3 ,
226- } ) ;
227-
228- pendingUsersLayout . add ( new qx . ui . basic . Label ( this . tr ( "Info" ) ) . set ( {
229- font : "text-14"
230- } ) , {
231- row : 0 ,
232- column : 4 ,
233- } ) ;
234-
235- pendingUsersLayout . add ( new qx . ui . basic . Label ( this . tr ( "Action" ) ) . set ( {
236- font : "text-14"
237- } ) , {
238- row : 0 ,
239- column : 5 ,
240- } ) ;
241146 } ,
242147
243148 __addRows : function ( pendingUsers ) {
244149 const pendingUsersLayout = this . getChildControl ( "pending-users-layout" ) ;
150+ const grid = pendingUsersLayout . getLayout ( ) ;
245151
246152 let row = 1 ;
247153 pendingUsers . forEach ( pendingUser => {
154+ grid . setRowAlign ( row , "left" , "middle" ) ;
155+
248156 pendingUsersLayout . add ( new qx . ui . basic . Label ( pendingUser . firstName + " " + pendingUser . lastName ) , {
249157 row,
250158 column : 0 ,
@@ -253,44 +161,62 @@ qx.Class.define("osparc.po.UsersPending", {
253161 row,
254162 column : 1 ,
255163 } ) ;
256- pendingUsersLayout . add ( new qx . ui . basic . Label ( pendingUser . date ? osparc . utils . Utils . formatDateAndTime ( new Date ( pendingUser . date ) ) : "-" ) , {
164+ pendingUsersLayout . add ( new qx . ui . basic . Label ( pendingUser . accountRequestReviewedAt ? osparc . utils . Utils . formatDateAndTime ( new Date ( pendingUser . accountRequestReviewedAt ) ) : "-" ) , {
257165 row,
258166 column : 2 ,
259167 } ) ;
260- pendingUsersLayout . add ( new qx . ui . basic . Label ( pendingUser . accountRequestStatus . toLowerCase ( ) ) , {
168+ const statusImage = new qx . ui . basic . Image ( ) ;
169+ pendingUsersLayout . add ( statusImage , {
261170 row,
262171 column : 3 ,
263172 } ) ;
173+ pendingUsersLayout . add ( new qx . ui . basic . Label ( pendingUser . accountRequestStatus . toLowerCase ( ) ) , {
174+ row,
175+ column : 4 ,
176+ } ) ;
264177 const infoButton = this . self ( ) . createInfoButton ( pendingUser ) ;
265178 pendingUsersLayout . add ( infoButton , {
266179 row,
267- column : 4 ,
180+ column : 5 ,
268181 } ) ;
269182 const buttonsLayout = new qx . ui . container . Composite ( new qx . ui . layout . HBox ( 5 ) ) ;
270183 pendingUsersLayout . add ( buttonsLayout , {
271184 row,
272- column : 5 ,
185+ column : 6 ,
273186 } ) ;
274187
275188 switch ( pendingUser . accountRequestStatus ) {
276189 case "PENDING" : {
277- const approveButton = this . self ( ) . createApproveButton ( pendingUser . email ) ;
190+ statusImage . set ( {
191+ source : "@FontAwesome5Solid/hourglass-end/14" ,
192+ textColor : "warning-yellow" ,
193+ } ) ;
194+ const approveButton = this . __createApproveButton ( pendingUser . email ) ;
278195 buttonsLayout . add ( approveButton ) ;
279- const rejectButton = this . self ( ) . createRejectButton ( pendingUser . email ) ;
196+ const rejectButton = this . __createRejectButton ( pendingUser . email ) ;
280197 buttonsLayout . add ( rejectButton ) ;
281198 break ;
282199 }
283200 case "REJECTED" : {
284- const approveButton = this . self ( ) . createApproveButton ( pendingUser . email ) ;
201+ statusImage . set ( {
202+ source : "@FontAwesome5Solid/times/14" ,
203+ textColor : "danger-red" ,
204+ } ) ;
205+ const approveButton = this . __createApproveButton ( pendingUser . email ) ;
206+ approveButton . setEnabled ( false ) ; // avoid changing decision for now
285207 buttonsLayout . add ( approveButton ) ;
286208 break ;
287209 }
288210 case "APPROVED" : {
289- /*
211+ statusImage . set ( {
212+ source : "@FontAwesome5Solid/check/14" ,
213+ textColor : "product-color" ,
214+ } ) ;
290215 const resendEmailButton = this . self ( ) . createResendEmailButton ( pendingUser . email ) ;
216+ resendEmailButton . setEnabled ( false ) ;
291217 buttonsLayout . add ( resendEmailButton ) ;
292- */
293- const rejectButton = this . self ( ) . createRejectButton ( pendingUser . email ) ;
218+ const rejectButton = this . __createRejectButton ( pendingUser . email ) ;
219+ rejectButton . setEnabled ( false ) ; // avoid changing decision for now
294220 buttonsLayout . add ( rejectButton ) ;
295221 break ;
296222 }
@@ -307,12 +233,139 @@ qx.Class.define("osparc.po.UsersPending", {
307233 . then ( resps => {
308234 const pendingUsers = resps [ 0 ] ;
309235 const reviewedUsers = resps [ 1 ] ;
310- const pendingUsersLayout = this . getChildControl ( "pending-users-layout" ) ;
311- pendingUsersLayout . removeAll ( ) ;
312- this . __addHeader ( ) ;
236+ const sortByDate = ( a , b ) => {
237+ const dateA = a . accountRequestReviewedAt ? new Date ( a . accountRequestReviewedAt ) : new Date ( 0 ) ;
238+ const dateB = b . accountRequestReviewedAt ? new Date ( b . accountRequestReviewedAt ) : new Date ( 0 ) ;
239+ return dateB - dateA ; // sort by most recent first
240+ } ;
241+ pendingUsers . sort ( sortByDate ) ;
242+ reviewedUsers . sort ( sortByDate ) ;
313243 this . __addRows ( pendingUsers . concat ( reviewedUsers ) ) ;
314244 } )
315245 . catch ( err => osparc . FlashMessenger . logError ( err ) ) ;
316- }
246+ } ,
247+
248+ __reload : function ( ) {
249+ this . getChildControl ( "pending-users-layout" ) . removeAll ( ) ;
250+ this . __addHeader ( ) ;
251+ this . __populatePendingUsersLayout ( ) ;
252+ } ,
253+
254+ __createApproveButton : function ( email ) {
255+ const button = new qx . ui . form . Button ( qx . locale . Manager . tr ( "Approve" ) ) ;
256+ button . addListener ( "execute" , ( ) => {
257+ const form = this . self ( ) . createInvitationForm ( false ) ;
258+ const approveBtn = new osparc . ui . form . FetchButton ( qx . locale . Manager . tr ( "Approve" ) ) ;
259+ approveBtn . set ( {
260+ appearance : "form-button"
261+ } ) ;
262+ form . addButton ( approveBtn ) ;
263+ const layout = new qx . ui . container . Composite ( new qx . ui . layout . VBox ( 10 ) ) ;
264+ const invitationForm = new qx . ui . form . renderer . Single ( form ) ;
265+ layout . add ( invitationForm ) ;
266+ const win = osparc . ui . window . Window . popUpInWindow ( layout , email , 350 , 150 ) . set ( {
267+ clickAwayClose : false ,
268+ resizable : false ,
269+ showClose : true
270+ } ) ;
271+ win . open ( ) ;
272+ approveBtn . addListener ( "execute" , ( ) => {
273+ if ( osparc . data . Permissions . getInstance ( ) . canDo ( "user.invitation.generate" , true ) ) {
274+ if ( form . validate ( ) ) {
275+ const extraCreditsInUsd = form . getItems ( ) [ "credits" ] . getValue ( ) ;
276+ let trialAccountDays = 0 ;
277+ if ( form . getItems ( ) [ "withExpiration" ] . getValue ( ) ) {
278+ trialAccountDays = form . getItems ( ) [ "trialDays" ] . getValue ( ) ;
279+ }
280+
281+ let msg = `Are you sure you want to approve ${ email } ` ;
282+ if ( extraCreditsInUsd ) {
283+ msg += ` with ${ extraCreditsInUsd } $ worth credits` ;
284+ }
285+ if ( trialAccountDays > 0 ) {
286+ msg += ` and ${ trialAccountDays } days of trial` ;
287+ }
288+ msg += "?" ;
289+ const confWin = new osparc . ui . window . Confirmation ( msg ) . set ( {
290+ caption : "Approve User" ,
291+ confirmText : "Approve" ,
292+ confirmAction : "create"
293+ } ) ;
294+ confWin . center ( ) ;
295+ confWin . open ( ) ;
296+ confWin . addListener ( "close" , ( ) => {
297+ if ( confWin . getConfirmed ( ) ) {
298+ approveBtn . setFetching ( true ) ;
299+ this . __approveUser ( email , form )
300+ . then ( ( ) => {
301+ osparc . FlashMessenger . logAs ( "User approved" , "INFO" ) ;
302+ this . __reload ( ) ;
303+ } )
304+ . catch ( err => osparc . FlashMessenger . logError ( err ) )
305+ . finally ( ( ) => {
306+ approveBtn . setFetching ( false ) ;
307+ win . close ( ) ;
308+ } ) ;
309+ }
310+ } ) ;
311+ }
312+ }
313+ } ) ;
314+ } ) ;
315+ return button ;
316+ } ,
317+
318+ __createRejectButton : function ( email ) {
319+ const button = new osparc . ui . form . FetchButton ( "Reject" ) ;
320+ button . addListener ( "execute" , ( ) => {
321+ const msg = `Are you sure you want to reject ${ email } .<br>The operation cannot be reverted"` ;
322+ const win = new osparc . ui . window . Confirmation ( msg ) . set ( {
323+ caption : "Reject User" ,
324+ confirmText : "Reject" ,
325+ confirmAction : "delete" ,
326+ } ) ;
327+ win . center ( ) ;
328+ win . open ( ) ;
329+ win . addListener ( "close" , ( ) => {
330+ if ( win . getConfirmed ( ) ) {
331+ button . setFetching ( true ) ;
332+ this . __rejectUser ( email )
333+ . then ( ( ) => {
334+ osparc . FlashMessenger . logAs ( qx . locale . Manager . tr ( "User denied" ) , "INFO" ) ;
335+ this . __reload ( ) ;
336+ } )
337+ . catch ( err => osparc . FlashMessenger . logError ( err ) )
338+ . finally ( ( ) => button . setFetching ( false ) ) ;
339+ }
340+ } ) ;
341+ } ) ;
342+ return button ;
343+ } ,
344+
345+ __approveUser : function ( email , form ) {
346+ const params = {
347+ data : {
348+ email,
349+ } ,
350+ } ;
351+ params . data [ "invitation" ] = { } ;
352+ const extraCreditsInUsd = form . getItems ( ) [ "credits" ] . getValue ( ) ;
353+ if ( extraCreditsInUsd > 0 ) {
354+ params . data [ "invitation" ] [ "extraCreditsInUsd" ] = extraCreditsInUsd ;
355+ }
356+ if ( form . getItems ( ) [ "withExpiration" ] . getValue ( ) ) {
357+ params . data [ "invitation" ] [ "trialAccountDays" ] = form . getItems ( ) [ "trialDays" ] . getValue ( ) ;
358+ }
359+ return osparc . data . Resources . fetch ( "poUsers" , "approveUser" , params ) ;
360+ } ,
361+
362+ __rejectUser : function ( email ) {
363+ const params = {
364+ data : {
365+ email,
366+ } ,
367+ } ;
368+ return osparc . data . Resources . fetch ( "poUsers" , "rejectUser" , params ) ;
369+ } ,
317370 }
318371} ) ;
0 commit comments