@@ -3,15 +3,20 @@ import React from 'react';
33import { Flex } from '@gravity-ui/uikit' ;
44
55import { getVDiskPagePath } from '../../routes' ;
6+ import { EVDiskState } from '../../types/api/vdisk' ;
67import { valueIsDefined } from '../../utils' ;
78import { cn } from '../../utils/cn' ;
8- import { formatStorageValuesToGb } from '../../utils/dataFormatters/dataFormatters' ;
9+ import {
10+ formatStorageValuesToGb ,
11+ formatUptimeInSeconds ,
12+ } from '../../utils/dataFormatters/dataFormatters' ;
913import { createVDiskDeveloperUILink } from '../../utils/developerUI/developerUI' ;
1014import { getSeverityColor } from '../../utils/disks/helpers' ;
1115import type { PreparedVDisk } from '../../utils/disks/types' ;
1216import { useIsUserAllowedToMakeChanges } from '../../utils/hooks/useIsUserAllowedToMakeChanges' ;
1317import { bytesToSpeed } from '../../utils/utils' ;
1418import { InfoViewer } from '../InfoViewer' ;
19+ import { InternalLink } from '../InternalLink' ;
1520import { LinkWithIcon } from '../LinkWithIcon/LinkWithIcon' ;
1621import { ProgressViewer } from '../ProgressViewer/ProgressViewer' ;
1722import { StatusIcon } from '../StatusIcon/StatusIcon' ;
@@ -46,6 +51,9 @@ export function VDiskInfo<T extends PreparedVDisk>({
4651 FrontQueues,
4752 Guid,
4853 Replicated,
54+ ReplicationProgress,
55+ ReplicationSecondsRemaining,
56+ Donors,
4957 VDiskState,
5058 VDiskSlotId,
5159 Kind,
@@ -130,6 +138,31 @@ export function VDiskInfo<T extends PreparedVDisk>({
130138 value : Replicated ? vDiskInfoKeyset ( 'yes' ) : vDiskInfoKeyset ( 'no' ) ,
131139 } ) ;
132140 }
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+ }
133166 if ( valueIsDefined ( VDiskSlotId ) ) {
134167 rightColumn . push ( { label : vDiskInfoKeyset ( 'slot-id' ) , value : VDiskSlotId } ) ;
135168 }
@@ -153,6 +186,45 @@ export function VDiskInfo<T extends PreparedVDisk>({
153186 } ) ;
154187 }
155188
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+
156228 const diskParamsDefined =
157229 valueIsDefined ( PDiskId ) && valueIsDefined ( NodeId ) && valueIsDefined ( VDiskSlotId ) ;
158230
0 commit comments