@@ -3,15 +3,20 @@ import React from 'react';
3
3
import { Flex } from '@gravity-ui/uikit' ;
4
4
5
5
import { getVDiskPagePath } from '../../routes' ;
6
+ import { EVDiskState } from '../../types/api/vdisk' ;
6
7
import { valueIsDefined } from '../../utils' ;
7
8
import { cn } from '../../utils/cn' ;
8
- import { formatStorageValuesToGb } from '../../utils/dataFormatters/dataFormatters' ;
9
+ import {
10
+ formatStorageValuesToGb ,
11
+ formatUptimeInSeconds ,
12
+ } from '../../utils/dataFormatters/dataFormatters' ;
9
13
import { createVDiskDeveloperUILink } from '../../utils/developerUI/developerUI' ;
10
14
import { getSeverityColor } from '../../utils/disks/helpers' ;
11
15
import type { PreparedVDisk } from '../../utils/disks/types' ;
12
16
import { useIsUserAllowedToMakeChanges } from '../../utils/hooks/useIsUserAllowedToMakeChanges' ;
13
17
import { bytesToSpeed } from '../../utils/utils' ;
14
18
import { InfoViewer } from '../InfoViewer' ;
19
+ import { InternalLink } from '../InternalLink' ;
15
20
import { LinkWithIcon } from '../LinkWithIcon/LinkWithIcon' ;
16
21
import { ProgressViewer } from '../ProgressViewer/ProgressViewer' ;
17
22
import { StatusIcon } from '../StatusIcon/StatusIcon' ;
@@ -46,6 +51,9 @@ export function VDiskInfo<T extends PreparedVDisk>({
46
51
FrontQueues,
47
52
Guid,
48
53
Replicated,
54
+ ReplicationProgress,
55
+ ReplicationSecondsRemaining,
56
+ Donors,
49
57
VDiskState,
50
58
VDiskSlotId,
51
59
Kind,
@@ -130,6 +138,31 @@ export function VDiskInfo<T extends PreparedVDisk>({
130
138
value : Replicated ? vDiskInfoKeyset ( 'yes' ) : vDiskInfoKeyset ( 'no' ) ,
131
139
} ) ;
132
140
}
141
+ // Only show replication progress and time remaining when disk is not replicated and state is OK
142
+ if ( Replicated === false && VDiskState === EVDiskState . OK ) {
143
+ if ( valueIsDefined ( ReplicationProgress ) ) {
144
+ rightColumn . push ( {
145
+ label : vDiskInfoKeyset ( 'replication-progress' ) ,
146
+ value : (
147
+ < ProgressViewer
148
+ value = { Math . round ( ReplicationProgress * 100 ) }
149
+ percents
150
+ colorizeProgress = { true }
151
+ capacity = { 100 }
152
+ />
153
+ ) ,
154
+ } ) ;
155
+ }
156
+ if ( valueIsDefined ( ReplicationSecondsRemaining ) ) {
157
+ const timeRemaining = formatUptimeInSeconds ( ReplicationSecondsRemaining ) ;
158
+ if ( timeRemaining ) {
159
+ rightColumn . push ( {
160
+ label : vDiskInfoKeyset ( 'replication-time-remaining' ) ,
161
+ value : timeRemaining ,
162
+ } ) ;
163
+ }
164
+ }
165
+ }
133
166
if ( valueIsDefined ( VDiskSlotId ) ) {
134
167
rightColumn . push ( { label : vDiskInfoKeyset ( 'slot-id' ) , value : VDiskSlotId } ) ;
135
168
}
@@ -153,6 +186,45 @@ export function VDiskInfo<T extends PreparedVDisk>({
153
186
} ) ;
154
187
}
155
188
189
+ // Show donors list when replication is in progress
190
+ if ( Replicated === false && VDiskState === EVDiskState . OK && Donors ?. length ) {
191
+ const donorLinks = Donors . map ( ( donor , index ) => {
192
+ const {
193
+ StringifiedId : id ,
194
+ NodeId : dNodeId ,
195
+ PDiskId : dPDiskId ,
196
+ VDiskSlotId : dVSlotId ,
197
+ } = donor ;
198
+
199
+ if ( ! id || ! dVSlotId || ! dNodeId || ! dPDiskId ) {
200
+ return null ;
201
+ }
202
+
203
+ const vDiskPath = getVDiskPagePath ( {
204
+ nodeId : dNodeId ,
205
+ pDiskId : dPDiskId ,
206
+ vDiskSlotId : dVSlotId ,
207
+ } ) ;
208
+
209
+ return (
210
+ < InternalLink key = { index } to = { vDiskPath } >
211
+ { id }
212
+ </ InternalLink >
213
+ ) ;
214
+ } ) . filter ( Boolean ) ;
215
+
216
+ if ( donorLinks . length ) {
217
+ rightColumn . push ( {
218
+ label : vDiskInfoKeyset ( 'donors' ) ,
219
+ value : (
220
+ < Flex direction = "column" gap = { 1 } >
221
+ { donorLinks }
222
+ </ Flex >
223
+ ) ,
224
+ } ) ;
225
+ }
226
+ }
227
+
156
228
const diskParamsDefined =
157
229
valueIsDefined ( PDiskId ) && valueIsDefined ( NodeId ) && valueIsDefined ( VDiskSlotId ) ;
158
230
0 commit comments