1
- import React , { useCallback , useEffect } from 'react' ;
1
+ import { useCallback , useEffect , useMemo } from 'react' ;
2
2
import { useDispatch } from 'react-redux' ;
3
3
import { useLocation } from 'react-router' ;
4
4
import block from 'bem-cn-lite' ;
5
5
import qs from 'qs' ;
6
6
7
- import { Link } from '@gravity-ui/uikit' ;
7
+ import { Link , Progress } from '@gravity-ui/uikit' ;
8
8
9
9
import EntityStatus from '../../components/EntityStatus/EntityStatus' ;
10
10
import ProgressViewer from '../../components/ProgressViewer/ProgressViewer' ;
@@ -15,14 +15,19 @@ import {Icon} from '../../components/Icon';
15
15
import { Loader } from '../../components/Loader' ;
16
16
import { ResponseError } from '../../components/Errors/ResponseError' ;
17
17
18
+ import type { AdditionalVersionsProps } from '../../types/additionalProps' ;
18
19
import { hideTooltip , showTooltip } from '../../store/reducers/tooltip' ;
19
20
import { getClusterInfo } from '../../store/reducers/cluster/cluster' ;
21
+ import { getClusterNodes } from '../../store/reducers/clusterNodes/clusterNodes' ;
20
22
import { backend , customBackend } from '../../store' ;
21
23
import { setHeader } from '../../store/reducers/header' ;
22
24
import { formatStorageValues } from '../../utils' ;
23
25
import { useAutofetcher , useTypedSelector } from '../../utils/hooks' ;
26
+ import { parseVersionsToVersionToColorMap , parseNodesToVersionsValues } from '../../utils/versions' ;
24
27
import routes , { CLUSTER_PAGES , createHref } from '../../routes' ;
25
28
29
+ import { Versions } from '../Versions/Versions' ;
30
+
26
31
import { compareTablets } from './utils' ;
27
32
28
33
import './ClusterInfo.scss' ;
@@ -32,9 +37,14 @@ const b = block('cluster-info');
32
37
interface ClusterInfoProps {
33
38
clusterTitle ?: string ;
34
39
additionalClusterInfo ?: InfoViewerItem [ ] ;
40
+ additionalVersionsProps ?: AdditionalVersionsProps ;
35
41
}
36
42
37
- export const ClusterInfo = ( { clusterTitle, additionalClusterInfo = [ ] } : ClusterInfoProps ) => {
43
+ export const ClusterInfo = ( {
44
+ clusterTitle,
45
+ additionalClusterInfo = [ ] ,
46
+ additionalVersionsProps,
47
+ } : ClusterInfoProps ) => {
38
48
const dispatch = useDispatch ( ) ;
39
49
const location = useLocation ( ) ;
40
50
@@ -44,6 +54,12 @@ export const ClusterInfo = ({clusterTitle, additionalClusterInfo = []}: ClusterI
44
54
const { clusterName} = queryParams ;
45
55
46
56
const { data : cluster , loading, wasLoaded, error} = useTypedSelector ( ( state ) => state . cluster ) ;
57
+ const {
58
+ nodes,
59
+ loading : nodesLoading ,
60
+ wasLoaded : nodesWasLoaded ,
61
+ error : nodesError ,
62
+ } = useTypedSelector ( ( state ) => state . clusterNodes ) ;
47
63
const singleClusterMode = useTypedSelector ( ( state ) => state . singleClusterMode ) ;
48
64
49
65
useEffect ( ( ) => {
@@ -59,10 +75,22 @@ export const ClusterInfo = ({clusterTitle, additionalClusterInfo = []}: ClusterI
59
75
60
76
const fetchData = useCallback ( ( ) => {
61
77
dispatch ( getClusterInfo ( clusterName ? String ( clusterName ) : undefined ) ) ;
78
+ dispatch ( getClusterNodes ( ) ) ;
62
79
} , [ dispatch , clusterName ] ) ;
63
80
64
81
useAutofetcher ( fetchData , [ fetchData ] , true ) ;
65
82
83
+ const versionToColor = useMemo ( ( ) => {
84
+ if ( additionalVersionsProps ?. getVersionToColorMap ) {
85
+ return additionalVersionsProps ?. getVersionToColorMap ( ) ;
86
+ }
87
+ return parseVersionsToVersionToColorMap ( cluster ?. Versions ) ;
88
+ } , [ additionalVersionsProps , cluster ] ) ;
89
+
90
+ const versionsValues = useMemo ( ( ) => {
91
+ return parseNodesToVersionsValues ( nodes , versionToColor ) ;
92
+ } , [ nodes , versionToColor ] ) ;
93
+
66
94
const onShowTooltip = ( ...args : Parameters < typeof showTooltip > ) => {
67
95
dispatch ( showTooltip ( ...args ) ) ;
68
96
} ;
@@ -128,39 +156,52 @@ export const ClusterInfo = ({clusterTitle, additionalClusterInfo = []}: ClusterI
128
156
return info ;
129
157
} ;
130
158
131
- if ( loading && ! wasLoaded ) {
159
+ if ( ( loading && ! wasLoaded ) || ( nodesLoading && ! nodesWasLoaded ) ) {
132
160
return < Loader size = "l" /> ;
133
161
}
134
162
135
- if ( error ) {
136
- return < ResponseError error = { error } /> ;
163
+ if ( error || nodesError ) {
164
+ return < ResponseError error = { error || nodesError } /> ;
137
165
}
138
- return (
139
- < React . Fragment >
140
- < div className = { b ( 'common' ) } >
141
- < div className = { b ( 'url' ) } >
142
- < EntityStatus
143
- size = "m"
144
- status = { cluster ?. Overall }
145
- name = { clusterTitle ?? cluster ?. Name ?? 'Unknown cluster' }
146
- />
147
- </ div >
148
-
149
- { cluster ?. DataCenters && < Tags tags = { cluster ?. DataCenters } /> }
150
166
151
- < div className = { b ( 'system-tablets' ) } >
152
- { cluster ?. SystemTablets &&
153
- cluster . SystemTablets . sort ( compareTablets ) . map ( ( tablet , tabletIndex ) => (
154
- < Tablet
155
- onMouseEnter = { onShowTooltip }
156
- onMouseLeave = { onHideTooltip }
157
- key = { tabletIndex }
158
- tablet = { tablet }
167
+ return (
168
+ < div className = { b ( ) } >
169
+ < div className = { b ( 'header' ) } >
170
+ < div className = "info" >
171
+ < div className = { b ( 'common' ) } >
172
+ < div className = { b ( 'url' ) } >
173
+ < EntityStatus
174
+ size = "m"
175
+ status = { cluster ?. Overall }
176
+ name = { clusterTitle ?? cluster ?. Name ?? 'Unknown cluster' }
159
177
/>
160
- ) ) }
178
+ </ div >
179
+
180
+ { cluster ?. DataCenters && < Tags tags = { cluster ?. DataCenters } /> }
181
+
182
+ < div className = { b ( 'system-tablets' ) } >
183
+ { cluster ?. SystemTablets &&
184
+ cluster . SystemTablets . sort ( compareTablets ) . map (
185
+ ( tablet , tabletIndex ) => (
186
+ < Tablet
187
+ onMouseEnter = { onShowTooltip }
188
+ onMouseLeave = { onHideTooltip }
189
+ key = { tabletIndex }
190
+ tablet = { tablet }
191
+ />
192
+ ) ,
193
+ ) }
194
+ </ div >
195
+ </ div >
196
+ < InfoViewer dots = { true } info = { getInfo ( ) } />
197
+ </ div >
198
+ < div className = { b ( 'version-progress' ) } >
199
+ < h3 className = { b ( 'progress-label' ) } > Versions</ h3 >
200
+ < Progress value = { 100 } stack = { versionsValues } />
161
201
</ div >
162
202
</ div >
163
- < InfoViewer dots = { true } info = { getInfo ( ) } />
164
- </ React . Fragment >
203
+
204
+ < Versions nodes = { nodes } versionToColor = { versionToColor } />
205
+ </ div >
165
206
) ;
166
207
} ;
0 commit comments