11import { getPDiskPagePath } from '../../routes' ;
22import { valueIsDefined } from '../../utils' ;
3+ import { formatBytes } from '../../utils/bytesParsers' ;
34import { cn } from '../../utils/cn' ;
4- import { EMPTY_DATA_PLACEHOLDER } from '../../utils/constants' ;
55import { formatStorageValuesToGb } from '../../utils/dataFormatters/dataFormatters' ;
66import { createPDiskDeveloperUILink } from '../../utils/developerUI/developerUI' ;
77import type { PreparedPDisk } from '../../utils/disks/types' ;
8+ import { useTypedSelector } from '../../utils/hooks' ;
89import { EntityStatus } from '../EntityStatus/EntityStatus' ;
910import type { InfoViewerItem } from '../InfoViewer' ;
1011import { InfoViewer } from '../InfoViewer/InfoViewer' ;
11- import type { InfoViewerProps } from '../InfoViewer/InfoViewer' ;
1212import { LinkWithIcon } from '../LinkWithIcon/LinkWithIcon' ;
1313import { ProgressViewer } from '../ProgressViewer/ProgressViewer' ;
1414
@@ -18,18 +18,20 @@ import './PDiskInfo.scss';
1818
1919const b = cn ( 'ydb-pdisk-info' ) ;
2020
21- interface PDiskInfoProps < T extends PreparedPDisk > extends Omit < InfoViewerProps , 'info' > {
21+ interface GetPDiskInfoOptions < T extends PreparedPDisk > {
2222 pDisk ?: T ;
2323 nodeId ?: number | string | null ;
2424 isPDiskPage ?: boolean ;
25+ isUserAllowedToMakeChanges ?: boolean ;
2526}
2627
27- export function PDiskInfo < T extends PreparedPDisk > ( {
28+ // eslint-disable-next-line complexity
29+ function getPDiskInfo < T extends PreparedPDisk > ( {
2830 pDisk,
2931 nodeId,
3032 isPDiskPage = false ,
31- ... infoViewerProps
32- } : PDiskInfoProps < T > ) {
33+ isUserAllowedToMakeChanges ,
34+ } : GetPDiskInfoOptions < T > ) {
3335 const {
3436 PDiskId,
3537 Path,
@@ -42,22 +44,72 @@ export function PDiskInfo<T extends PreparedPDisk>({
4244 SerialNumber,
4345 TotalSize,
4446 AllocatedSize,
47+ DecommitStatus,
48+ StatusV2,
49+ NumActiveSlots,
50+ ExpectedSlotCount,
51+ LogUsedSize,
52+ LogTotalSize,
53+ SystemSize,
54+ SharedWithOs,
4555 } = pDisk || { } ;
4656
47- const pdiskInfo : InfoViewerItem [ ] = [ ] ;
57+ const generalInfo : InfoViewerItem [ ] = [ ] ;
4858
59+ if ( valueIsDefined ( DecommitStatus ) ) {
60+ generalInfo . push ( {
61+ label : pDiskInfoKeyset ( 'decomission-status' ) ,
62+ value : DecommitStatus . replace ( 'DECOMMIT_' , '' ) ,
63+ } ) ;
64+ }
65+ if ( valueIsDefined ( Category ) ) {
66+ generalInfo . push ( { label : pDiskInfoKeyset ( 'type' ) , value : Type } ) ;
67+ }
4968 if ( valueIsDefined ( Path ) ) {
50- pdiskInfo . push ( { label : pDiskInfoKeyset ( 'path' ) , value : Path } ) ;
69+ generalInfo . push ( { label : pDiskInfoKeyset ( 'path' ) , value : Path } ) ;
5170 }
5271 if ( valueIsDefined ( Guid ) ) {
53- pdiskInfo . push ( { label : pDiskInfoKeyset ( 'guid' ) , value : Guid } ) ;
72+ generalInfo . push ( { label : pDiskInfoKeyset ( 'guid' ) , value : Guid } ) ;
5473 }
55- if ( valueIsDefined ( Category ) ) {
56- pdiskInfo . push ( { label : pDiskInfoKeyset ( 'category' ) , value : Category } ) ;
57- pdiskInfo . push ( { label : pDiskInfoKeyset ( 'type' ) , value : Type } ) ;
74+ // SerialNumber could be an empty string ""
75+ if ( SerialNumber ) {
76+ generalInfo . push ( {
77+ label : pDiskInfoKeyset ( 'serial-number' ) ,
78+ value : SerialNumber ,
79+ } ) ;
80+ }
81+ if ( valueIsDefined ( SharedWithOs ) ) {
82+ generalInfo . push ( {
83+ label : pDiskInfoKeyset ( 'shared-with-os' ) ,
84+ value : pDiskInfoKeyset ( 'yes' ) ,
85+ } ) ;
86+ }
87+
88+ const statusInfo : InfoViewerItem [ ] = [ ] ;
89+
90+ if ( valueIsDefined ( StatusV2 ) ) {
91+ statusInfo . push ( { label : pDiskInfoKeyset ( 'drive-status' ) , value : StatusV2 } ) ;
5892 }
59- pdiskInfo . push ( {
60- label : pDiskInfoKeyset ( 'size' ) ,
93+ if ( valueIsDefined ( State ) ) {
94+ statusInfo . push ( { label : pDiskInfoKeyset ( 'state' ) , value : State } ) ;
95+ }
96+ if ( valueIsDefined ( Device ) ) {
97+ statusInfo . push ( {
98+ label : pDiskInfoKeyset ( 'device' ) ,
99+ value : < EntityStatus status = { Device } /> ,
100+ } ) ;
101+ }
102+ if ( valueIsDefined ( Realtime ) ) {
103+ statusInfo . push ( {
104+ label : pDiskInfoKeyset ( 'realtime' ) ,
105+ value : < EntityStatus status = { Realtime } /> ,
106+ } ) ;
107+ }
108+
109+ const spaceInfo : InfoViewerItem [ ] = [ ] ;
110+
111+ spaceInfo . push ( {
112+ label : pDiskInfoKeyset ( 'space' ) ,
61113 value : (
62114 < ProgressViewer
63115 value = { AllocatedSize }
@@ -67,36 +119,46 @@ export function PDiskInfo<T extends PreparedPDisk>({
67119 />
68120 ) ,
69121 } ) ;
70- if ( valueIsDefined ( State ) ) {
71- pdiskInfo . push ( { label : pDiskInfoKeyset ( 'state' ) , value : State } ) ;
72- }
73- if ( valueIsDefined ( Device ) ) {
74- pdiskInfo . push ( {
75- label : pDiskInfoKeyset ( 'device' ) ,
76- value : < EntityStatus status = { Device } /> ,
122+ if ( valueIsDefined ( NumActiveSlots ) && valueIsDefined ( ExpectedSlotCount ) ) {
123+ spaceInfo . push ( {
124+ label : pDiskInfoKeyset ( 'slots' ) ,
125+ value : < ProgressViewer value = { NumActiveSlots } capacity = { ExpectedSlotCount } /> ,
77126 } ) ;
78127 }
79- if ( valueIsDefined ( Realtime ) ) {
80- pdiskInfo . push ( {
81- label : pDiskInfoKeyset ( 'realtime' ) ,
82- value : < EntityStatus status = { Realtime } /> ,
128+ if ( valueIsDefined ( LogUsedSize ) && valueIsDefined ( LogTotalSize ) ) {
129+ spaceInfo . push ( {
130+ label : pDiskInfoKeyset ( 'log-size' ) ,
131+ value : (
132+ < ProgressViewer
133+ value = { LogUsedSize }
134+ capacity = { LogTotalSize }
135+ formatValues = { formatStorageValuesToGb }
136+ />
137+ ) ,
83138 } ) ;
84139 }
85- if ( valueIsDefined ( SerialNumber ) ) {
86- pdiskInfo . push ( {
87- label : pDiskInfoKeyset ( 'serial-number ' ) ,
88- value : SerialNumber || EMPTY_DATA_PLACEHOLDER ,
140+ if ( valueIsDefined ( SystemSize ) ) {
141+ spaceInfo . push ( {
142+ label : pDiskInfoKeyset ( 'system-size ' ) ,
143+ value : formatBytes ( { value : SystemSize } ) ,
89144 } ) ;
90145 }
91146
92- if ( valueIsDefined ( PDiskId ) && valueIsDefined ( nodeId ) ) {
147+ const additionalInfo : InfoViewerItem [ ] = [ ] ;
148+
149+ const shouldDisplayLinks =
150+ ( ! isPDiskPage || isUserAllowedToMakeChanges ) &&
151+ valueIsDefined ( PDiskId ) &&
152+ valueIsDefined ( nodeId ) ;
153+
154+ if ( shouldDisplayLinks ) {
93155 const pDiskPagePath = getPDiskPagePath ( PDiskId , nodeId ) ;
94156 const pDiskInternalViewerPath = createPDiskDeveloperUILink ( {
95157 nodeId,
96158 pDiskId : PDiskId ,
97159 } ) ;
98160
99- pdiskInfo . push ( {
161+ additionalInfo . push ( {
100162 label : pDiskInfoKeyset ( 'links' ) ,
101163 value : (
102164 < span className = { b ( 'links' ) } >
@@ -107,14 +169,49 @@ export function PDiskInfo<T extends PreparedPDisk>({
107169 external = { false }
108170 />
109171 ) }
110- < LinkWithIcon
111- title = { pDiskInfoKeyset ( 'developer-ui' ) }
112- url = { pDiskInternalViewerPath }
113- />
172+ { isUserAllowedToMakeChanges && (
173+ < LinkWithIcon
174+ title = { pDiskInfoKeyset ( 'developer-ui' ) }
175+ url = { pDiskInternalViewerPath }
176+ />
177+ ) }
114178 </ span >
115179 ) ,
116180 } ) ;
117181 }
118182
119- return < InfoViewer info = { pdiskInfo } { ...infoViewerProps } /> ;
183+ return [ generalInfo , statusInfo , spaceInfo , additionalInfo ] ;
184+ }
185+
186+ interface PDiskInfoProps < T extends PreparedPDisk > extends GetPDiskInfoOptions < T > {
187+ className ?: string ;
188+ }
189+
190+ export function PDiskInfo < T extends PreparedPDisk > ( {
191+ pDisk,
192+ nodeId,
193+ isPDiskPage = false ,
194+ className,
195+ } : PDiskInfoProps < T > ) {
196+ const { isUserAllowedToMakeChanges} = useTypedSelector ( ( state ) => state . authentication ) ;
197+
198+ const [ generalInfo , statusInfo , spaceInfo , additionalInfo ] = getPDiskInfo ( {
199+ pDisk,
200+ nodeId,
201+ isPDiskPage,
202+ isUserAllowedToMakeChanges,
203+ } ) ;
204+
205+ return (
206+ < div className = { b ( 'wrapper' , className ) } >
207+ < div className = { b ( 'col' ) } >
208+ < InfoViewer info = { generalInfo } renderEmptyState = { ( ) => null } />
209+ < InfoViewer info = { spaceInfo } renderEmptyState = { ( ) => null } />
210+ </ div >
211+ < div className = { b ( 'col' ) } >
212+ < InfoViewer info = { statusInfo } renderEmptyState = { ( ) => null } />
213+ < InfoViewer info = { additionalInfo } renderEmptyState = { ( ) => null } />
214+ </ div >
215+ </ div >
216+ ) ;
120217}
0 commit comments