6
6
*/
7
7
8
8
import { useSelector } from 'react-redux' ;
9
- import { useCallback , useEffect , useRef , useState } from 'react' ;
9
+ import { useRef , useEffect , useCallback , useState , useMemo } from 'react' ;
10
10
import { ElementAttributes , fetchElementsInfos , useSnackMessage } from '@gridsuite/commons-ui' ;
11
11
import { UUID } from 'crypto' ;
12
+ import { UsersIdentities , UsersIdentitiesMap } from 'utils/user-identities.type' ;
13
+ import { fetchUsersIdentities } from '../utils/rest-api' ;
12
14
import { AppState } from '../redux/types' ;
13
15
16
+ const getName = ( userId : string , data : UsersIdentitiesMap ) : string => {
17
+ const firstName = data ?. [ userId ] ?. firstName ;
18
+ const lastName = data ?. [ userId ] ?. lastName ;
19
+ if ( firstName && lastName ) {
20
+ return `${ firstName } ${ lastName } ` ;
21
+ }
22
+ if ( firstName ) {
23
+ return firstName ;
24
+ }
25
+ if ( lastName ) {
26
+ return lastName ;
27
+ }
28
+ // fallback to id
29
+ return userId ;
30
+ } ;
31
+
14
32
export const useDirectoryContent = ( ) => {
15
33
const currentChildren = useSelector ( ( state : AppState ) => state . currentChildren ) ;
16
34
const [ childrenMetadata , setChildrenMetadata ] = useState < Record < UUID , ElementAttributes > > ( { } ) ;
@@ -40,12 +58,35 @@ export const useDirectoryContent = () => {
40
58
41
59
const metadata : Record < UUID , ElementAttributes > = { } ;
42
60
const childrenToFetchElementsInfos = Object . values ( currentChildren ) . map ( ( e ) => e . elementUuid ) ;
61
+
62
+ const fetchUsersIdentitiesPromise = fetchUsersIdentities ( childrenToFetchElementsInfos ) . catch ( ( ) => {
63
+ // Last resort, server down, error 500, fallback to subs as users Identities
64
+ // We write this code to have the same behavior as when there are partial results,
65
+ // (missing users identities), see getName()
66
+ const fallbackUsersIdentities : UsersIdentities = {
67
+ data : Object . fromEntries (
68
+ [ ...new Set ( currentChildren . flatMap ( ( e ) => [ e . owner , e . lastModifiedBy ] ) ) ] . map ( ( sub ) => [
69
+ sub ,
70
+ { sub, firstName : '' , lastName : '' } ,
71
+ ] )
72
+ ) ,
73
+ errors : { } ,
74
+ } ;
75
+
76
+ return fallbackUsersIdentities ;
77
+ } ) ;
78
+
43
79
if ( childrenToFetchElementsInfos . length > 0 ) {
44
- fetchElementsInfos ( childrenToFetchElementsInfos )
80
+ Promise . all ( [
81
+ fetchUsersIdentitiesPromise , // TODO cache user identities across elements
82
+ fetchElementsInfos ( childrenToFetchElementsInfos ) ,
83
+ ] )
45
84
. then ( ( res ) => {
46
85
// discarding request for older directory
47
86
if ( previousData . current === currentChildren ) {
48
- res . forEach ( ( e ) => {
87
+ res [ 1 ] . forEach ( ( e ) => {
88
+ e . owner = getName ( e . owner , res [ 0 ] . data ) ;
89
+ e . lastModifiedBy = getName ( e . lastModifiedBy , res [ 0 ] . data ) ;
49
90
metadata [ e . elementUuid ] = e ;
50
91
} ) ;
51
92
setChildrenMetadata ( metadata ) ;
@@ -59,5 +100,17 @@ export const useDirectoryContent = () => {
59
100
}
60
101
} , [ handleError , currentChildren ] ) ;
61
102
62
- return [ currentChildren , childrenMetadata ] as const ;
103
+ // TODO remove this when global user identity caching is implemented
104
+ const currentChildrenWithOwnerNames = useMemo ( ( ) => {
105
+ if ( ! currentChildren ) {
106
+ return currentChildren ;
107
+ }
108
+ return currentChildren . map ( ( x ) => ( {
109
+ ...x ,
110
+ owner : childrenMetadata ?. [ x . elementUuid ] ?. owner ,
111
+ lastModifiedBy : childrenMetadata ?. [ x . elementUuid ] ?. lastModifiedBy ,
112
+ } ) ) ;
113
+ } , [ currentChildren , childrenMetadata ] ) ;
114
+
115
+ return [ currentChildrenWithOwnerNames , childrenMetadata ] as const ;
63
116
} ;
0 commit comments